Skip to content

Commit be27246

Browse files
dylanbstoreyDylan Storey
andauthored
Feature/backlog work (#2)
* Add Dijkstra shortest path and degree centrality graph algorithms - dijkstra(source, target) finds shortest path between nodes - degreeCentrality() calculates in/out/total degree for all nodes - Modularize graph algorithm code into separate files for maintainability - Add Python and Rust bindings with full test coverage * Add Leiden community detection to Python bindings - leiden_communities() method uses graspologic for high-quality community detection - to_rustworkx() method exports graph to rustworkx PyDiGraph format - Optional dependencies: pip install graphqlite[leiden] or graphqlite[rustworkx] * Add graph algorithms, fix OPTIONAL MATCH transformation, add modulo operator Graph Algorithms: - Eigenvector centrality with power iteration - Betweenness centrality - Closeness centrality - Triangle counting and clustering coefficient - Connected components (weak and strong) - All-pairs shortest path (Floyd-Warshall) - A* pathfinding with heuristics - K-nearest neighbors - Louvain community detection - Graph similarity (Jaccard, cosine, overlap) - BFS/DFS traversal Bug Fixes: - Fix OPTIONAL MATCH transformation generating duplicate LEFT JOINs by checking sql_builder.from_clause and join_clauses in addition to sql_buffer - Fix eigenvector centrality test using symmetric graph that produces uniform scores New Features: - Add modulo operator (%) support to Cypher expressions Bindings: - Refactor Python bindings into modular graph/ and algorithms/ packages - Refactor Rust bindings into modular graph/ and algorithms/ modules - Add comprehensive test coverage for new algorithms * Implement REMOVE clause for property and label removal Add executor support for REMOVE clause operations: - Remove node properties (REMOVE n.prop) - Remove multiple properties (REMOVE n.a, n.b) - Remove node labels (REMOVE n:Label) - Remove edge properties (REMOVE r.prop) Includes schema functions for property/label deletion and comprehensive tests across CUnit, functional SQL, Rust, and Python bindings. * Return empty array for zero-row MATCH results MATCH queries with no matching rows now return [] instead of a success message, aligning with standard Cypher semantics. Modification queries (CREATE, DELETE, etc.) without RETURN clauses continue to show statistics. Also fixes REMOVE tests to check for null string values rather than NULL pointers. * Implement IN membership operator for list checking Add support for `expr IN [list]` syntax to check if a value exists in a list: - `5 IN [1, 2, 5, 10]` returns true - `'x' IN ['a', 'b', 'c']` returns false - `MATCH (n) WHERE n.status IN ['active', 'pending'] RETURN n` Uses %dprec to disambiguate between IN operator in list literals vs list comprehension syntax `[x IN list]`. Includes tests for Python and Rust bindings. * Implement STARTS WITH, ENDS WITH, CONTAINS string operators Add infix string matching operators as specified by OpenCypher: - STARTS WITH: checks if string begins with prefix - ENDS WITH: checks if string ends with suffix - CONTAINS: checks if string contains substring Transform to SQL: - STARTS WITH → str LIKE prefix || '%' - ENDS WITH → str LIKE '%' || suffix - CONTAINS → INSTR(str, substr) > 0 Also supports function call syntax (contains(), startsWith(), endsWith()) for backward compatibility. * Fix OPTIONAL MATCH, UNWIND+CREATE, and array index bugs - OPTIONAL MATCH now correctly uses LEFT JOIN semantics instead of producing cartesian products. Routes multi-MATCH queries through the transform pipeline to properly process all clauses. - UNWIND+CREATE now iterates correctly over list elements instead of only creating a single node. - Array index syntax (list[0]) now supported in expressions via new subscript operator handling in the parser and transform. - Added comprehensive test files for expanded Cypher coverage (expressions, clauses, patterns, functions, predicates). * Bump version to 0.1.0-beta.4 --------- Co-authored-by: Dylan Storey <dstorey@gmail.com>
1 parent b6c9dd7 commit be27246

File tree

152 files changed

+20497
-2113
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

152 files changed

+20497
-2113
lines changed

.metis/backlog/bugs/GQLITE-T-0003.md renamed to .metis/archived/backlog/bugs/GQLITE-T-0003.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-24T01:49:48.647722+00:00
77
updated_at: 2025-12-24T02:07:01.517901+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
@@ -44,6 +44,8 @@ Fix parameter binding (`$param`) support in WHERE clauses and other expressions.
4444

4545
## Acceptance Criteria
4646

47+
## Acceptance Criteria
48+
4749
- [ ] `MATCH (n) WHERE n.name = $name RETURN n` parses and transforms successfully
4850
- [ ] Parameters work in WHERE clause comparisons
4951
- [ ] Parameters work in property maps: `CREATE (n:Person {name: $name})`

.metis/backlog/bugs/GQLITE-T-0011.md renamed to .metis/archived/backlog/bugs/GQLITE-T-0011.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-24T14:16:05.505777+00:00
77
updated_at: 2025-12-24T14:38:27.912817+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
@@ -68,6 +68,8 @@ Fix the Cypher executor to return node objects as separate rows instead of seria
6868

6969
## Acceptance Criteria
7070

71+
## Acceptance Criteria
72+
7173
## Acceptance Criteria **[REQUIRED]**
7274

7375
- [ ] `MATCH (n) RETURN n` returns each node as a separate row

.metis/backlog/features/GQLITE-T-0001.md renamed to .metis/archived/backlog/features/GQLITE-T-0001.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-24T01:49:48.401416+00:00
77
updated_at: 2025-12-24T02:26:57.086473+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
@@ -42,6 +42,8 @@ Add support for UNION and UNION ALL operators to combine results from multiple q
4242

4343
## Acceptance Criteria
4444

45+
## Acceptance Criteria
46+
4547
- [ ] `RETURN 1 AS x UNION RETURN 2 AS x` returns two rows
4648
- [ ] `RETURN 1 AS x UNION ALL RETURN 1 AS x` returns two identical rows
4749
- [ ] UNION removes duplicates, UNION ALL keeps all rows

.metis/backlog/features/GQLITE-T-0002.md renamed to .metis/archived/backlog/features/GQLITE-T-0002.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-24T01:49:48.522655+00:00
77
updated_at: 2025-12-24T02:41:12.493315+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
@@ -42,6 +42,8 @@ Support multiple labels on nodes using the `(:Label1:Label2)` syntax, allowing n
4242

4343
## Acceptance Criteria
4444

45+
## Acceptance Criteria
46+
4547
- [ ] `CREATE (n:Person:Employee {name: "Alice"})` creates node with both labels
4648
- [ ] `MATCH (n:Person:Employee)` matches only nodes with BOTH labels
4749
- [ ] `MATCH (n:Person)` matches nodes that have Person label (even if they have others)

.metis/backlog/features/GQLITE-T-0004.md renamed to .metis/archived/backlog/features/GQLITE-T-0004.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-24T01:49:48.772403+00:00
77
updated_at: 2025-12-24T02:49:08.449297+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
@@ -42,6 +42,8 @@ Implement the REMOVE clause for deleting properties from nodes and relationships
4242

4343
## Acceptance Criteria
4444

45+
## Acceptance Criteria
46+
4547
- [ ] `MATCH (n) REMOVE n.property RETURN n` removes the property
4648
- [ ] `MATCH (n) REMOVE n:Label RETURN n` removes the label from the node
4749
- [ ] Multiple removes in one clause: `REMOVE n.a, n.b, n:Label`

.metis/backlog/features/GQLITE-T-0005.md renamed to .metis/archived/backlog/features/GQLITE-T-0005.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-24T01:49:48.904017+00:00
77
updated_at: 2025-12-24T02:54:59.590287+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
@@ -42,6 +42,8 @@ Add the regex matching operator (`=~`) for pattern matching on string properties
4242

4343
## Acceptance Criteria
4444

45+
## Acceptance Criteria
46+
4547
- [ ] `MATCH (n) WHERE n.name =~ "A.*" RETURN n` matches names starting with A
4648
- [ ] `MATCH (n) WHERE n.email =~ ".*@gmail.com" RETURN n` matches Gmail addresses
4749
- [ ] Case-sensitive matching by default

.metis/backlog/features/GQLITE-T-0006.md renamed to .metis/archived/backlog/features/GQLITE-T-0006.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-24T01:49:49.042048+00:00
77
updated_at: 2025-12-24T15:02:17.022679+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
@@ -42,6 +42,8 @@ Implement the FOREACH clause for iterating over a list and performing update ope
4242

4343
## Acceptance Criteria
4444

45+
## Acceptance Criteria
46+
4547
- [ ] `FOREACH (x IN [1,2,3] | CREATE (n {val: x}))` creates 3 nodes
4648
- [ ] `FOREACH (n IN nodes | SET n.updated = true)` updates all nodes in list
4749
- [ ] Nested FOREACH supported

.metis/backlog/features/GQLITE-T-0007.md renamed to .metis/archived/backlog/features/GQLITE-T-0007.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-24T01:49:49.189917+00:00
77
updated_at: 2025-12-24T03:14:18.058281+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
@@ -42,6 +42,8 @@ Implement LOAD CSV clause for importing data from CSV files into the graph datab
4242

4343
## Acceptance Criteria
4444

45+
## Acceptance Criteria
46+
4547
- [ ] `LOAD CSV FROM "file.csv" AS row CREATE (n {name: row[0]})`
4648
- [ ] `LOAD CSV WITH HEADERS FROM "file.csv" AS row CREATE (n {name: row.name})`
4749
- [ ] Support for local file paths

.metis/backlog/features/GQLITE-T-0010.md renamed to .metis/archived/backlog/features/GQLITE-T-0010.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-24T05:18:53.733240+00:00
77
updated_at: 2025-12-24T15:06:43.265133+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
@@ -72,6 +72,8 @@ Graph algorithms (PageRank, Label Propagation, Betweenness Centrality) currently
7272

7373
## Acceptance Criteria
7474

75+
## Acceptance Criteria
76+
7577
## Acceptance Criteria **[REQUIRED]**
7678

7779
- [ ] `pagerank()` returns both `node_id` (rowid) and `user_id` (property) columns

.metis/backlog/features/GQLITE-T-0012.md renamed to .metis/archived/backlog/features/GQLITE-T-0012.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-24T14:18:38.677564+00:00
77
updated_at: 2025-12-24T15:02:39.854072+00:00
88
parent:
99
blocked_by: [GQLITE-T-0011]
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
@@ -58,6 +58,8 @@ Complete the nanographrag demo to showcase GraphQLite + sqlite-vec for knowledge
5858

5959
## Acceptance Criteria
6060

61+
## Acceptance Criteria
62+
6163
## Acceptance Criteria **[REQUIRED]**
6264

6365
- [x] Entity extraction with spaCy NER (181 entities, 266 relationships from 19 docs)

0 commit comments

Comments
 (0)