Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PGQL implementation on TiDB #23

Draft
wants to merge 24 commits into
base: v6.0.0
Choose a base branch
from
Draft

Conversation

sleepymole
Copy link
Contributor

Motivation

This PR aims to implement all PGQL features except graph modification on TiDB.

Status

  • Graph DDL
    • Parser
    • DDL Executor
  • Graph Show
    • SHOW GRAPHS
    • SHOW CREATE PROPERTY GRAPH `xxx`
  • Graph Query
    • Parser
    • Simple Path Matching (Complete Subgraph Matching)
    • Variable-Length Paths
      • Any Path
      • Shortest Path
      • Cheapest Path
    • Subquery Compatible
    • Path Pattern Macro
    • Vertex and Edge functions
      • ID
      • LABEL
      • LABELS (function)
      • HAS_LABEL
      • ALL_DIFFERENT
      • IN_DEGREE
      • OUT_DEGREE

Try it out now

Prerequisites

  • Go (1.18+)

Run a standalone tidb-server from current branch.

git clone https://github.com/gozssky/tidb.git
cd tidb && git checkout graph
go run tidb-server/main.go --path=/tmp/tigraph

Create a property graph

Underlying tables
CREATE TABLE `Persons` (
  `id` bigint(20) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `company_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */
);
INSERT INTO Persons VALUES (1, 'Nikita', NULL);
INSERT INTO Persons VALUES (2, 'Camille', 1);
INSERT INTO Persons VALUES (3, 'Liam', NULL);

CREATE TABLE `Companies` (
  `id` bigint(20) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */
);
INSERT INTO Companies VALUES (1, 'Oracle');

CREATE TABLE `Accounts` (
  `number` bigint(20) NOT NULL,
  `account_type` int(11) DEFAULT NULL,
  `person_id` bigint(20) DEFAULT NULL,
  `company_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`number`) /*T![clustered_index] CLUSTERED */
);
INSERT INTO Accounts VALUES (10039, 100, 2, NULL);
INSERT INTO Accounts VALUES (2090, 100, 3, NULL);
INSERT INTO Accounts VALUES (8021, 100, 1, NULL);
INSERT INTO Accounts VALUES (1001, 200, NULL, 1);

CREATE TABLE `Transactions` (
  `id` bigint(20) NOT NULL,
  `from_account` bigint(20) DEFAULT NULL,
  `to_account` bigint(20) DEFAULT NULL,
  `date` datetime DEFAULT NULL,
  `amount` double DEFAULT NULL,
  PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */
);
INSERT INTO Transactions VALUES (1, 2090, 10039, '2022-03-12 14:53:32', 9900.00);
INSERT INTO Transactions VALUES (2, 10039, 8021, '2022-03-12 14:56:05', 1000.00);
INSERT INTO Transactions VALUES (3, 1001, 2090, '2022-03-12 14:55:46', 9999.50);
INSERT INTO Transactions VALUES (4, 8021, 1001, '2022-03-12 14:53:14', 1500.30);
INSERT INTO Transactions VALUES (5, 8021, 1001, '2022-03-12 14:54:05', 3000.70);
Graph financial_transactions
CREATE PROPERTY GRAPH financial_transactions
  VERTEX TABLES (
    Persons KEY ( id ) LABEL Person PROPERTIES ( name ),
    Companies KEY ( id ) LABEL Company PROPERTIES ( name ),
    Accounts KEY ( number ) LABEL Account PROPERTIES ( number )
  )
  EDGE TABLES (
    Transactions KEY ( from_account, to_account, date )
      SOURCE KEY ( from_account ) REFERENCES Accounts
      DESTINATION KEY ( to_account ) REFERENCES Accounts
      LABEL transaction PROPERTIES ( amount ),
    Accounts AS PersonOwner KEY ( number )
      SOURCE KEY ( number ) REFERENCES Accounts
      DESTINATION KEY ( person_id ) REFERENCES Persons
      LABEL owner NO PROPERTIES,
    Accounts AS CompanyOwner KEY ( number )
      SOURCE KEY ( number ) REFERENCES Accounts
      DESTINATION KEY ( company_id ) REFERENCES Companies
      LABEL owner NO PROPERTIES,
    Persons AS worksFor KEY ( id )
      SOURCE KEY ( id ) REFERENCES Persons
      DESTINATION KEY ( company_id ) REFERENCES Companies
      NO PROPERTIES
  );

Graph query

An example in spec.

SELECT label(owner),
       COUNT(*) AS numTransactions,
       SUM(out.amount) AS totalOutgoing,
       GROUP_CONCAT(out.amount) AS amounts
FROM MATCH (a:Account) -[:owner]-> (owner:Person|Company) ON financial_transactions
     , MATCH (a) -[out:transaction]-> (:Account) ON financial_transactions
GROUP BY label(owner)
ORDER BY label(owner);

Output

+--------------+-----------------+---------------+-------------------------+
| label(owner) | numTransactions | totalOutgoing | amounts                 |
+--------------+-----------------+---------------+-------------------------+
| Company      |               1 |        9999.5 | 9999.5                  |
| Person       |               4 |         15401 | 9900,3000.7,1500.3,1000 |
+--------------+-----------------+---------------+-------------------------+
2 rows in set (0.00 sec)

@sleepymole sleepymole changed the base branch from master to v6.0.0 April 14, 2022 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant