Skip to content

Commit ceef151

Browse files
committed
feat(cysql): switch to flat ID carry-throughs to ensure index compatibility - the pg query planner is blind to composite types in certain situations
1 parent 734be68 commit ceef151

27 files changed

Lines changed: 383 additions & 1686 deletions

Makefile

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,25 @@ format:
1717
test:
1818
@for pkg in $(MAIN_PACKAGES) ; do \
1919
$(GO_CMD) test -cover $$pkg -parallel=20 ; \
20-
done
20+
done
21+
22+
test_neo4j:
23+
@for pkg in $(MAIN_PACKAGES) ; do \
24+
$(GO_CMD) test -tags neo4j_integration -cover $$pkg -parallel=1 ; \
25+
done
26+
27+
test_pg:
28+
@for pkg in $(MAIN_PACKAGES) ; do \
29+
$(GO_CMD) test -tags pg_integration -cover $$pkg -parallel=1 ; \
30+
done
31+
32+
test_update:
33+
@for pkg in $(MAIN_PACKAGES) ; do \
34+
CYSQL_UPDATE_CASES=true $(GO_CMD) test -cover $$pkg -parallel=20 >>/dev/null 2>&1; \
35+
done
36+
37+
cp -fv cypher/analyzer/updated_cases/* cypher/test/cases
38+
rm -rf cypher/analyzer/updated_cases/
39+
40+
cp -fv cypher/models/pgsql/test/updated_cases/* cypher/models/pgsql/test/translation_cases
41+
rm -rf cypher/models/pgsql/test/updated_cases

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,46 @@ development processes.
3333
```bash
3434
make
3535
```
36+
37+
#### Integration Tests
38+
39+
Integration tests are excluded from the default `make` target and require a running database instance. They are
40+
selected via Go build tags and configured through environment variables.
41+
42+
##### PostgreSQL Integration Tests
43+
44+
The following tests require a live PostgreSQL instance:
45+
46+
- `cypher/models/pgsql/test/translation_integration_test.go`
47+
- `cypher/models/pgsql/test/semantic_integration_test.go`
48+
49+
Set the `PG_CONNECTION_STRING` environment variable to a valid PostgreSQL connection string (e.g. `user=postgres dbname=bhe password=bhe4eva host=localhost`), then run:
50+
51+
```bash
52+
PG_CONNECTION_STRING="<connection-string>" make test_pg
53+
```
54+
55+
To run a specific test directly:
56+
57+
```bash
58+
PG_CONNECTION_STRING="<connection-string>" go test -tags pg_integration ./cypher/models/pgsql/test/...
59+
```
60+
61+
##### Neo4j Integration Tests
62+
63+
The following test requires a live Neo4j instance:
64+
65+
- `drivers/neo4j/batch_integration_test.go`
66+
67+
Set the `NEO4J_CONNECTION_STRING` environment variable to a valid Neo4j connection string (e.g.
68+
`neo4j://user:password@host:port`), then run:
69+
70+
```bash
71+
NEO4J_CONNECTION_STRING="<connection-string>" make test_neo4j
72+
```
73+
74+
To run the batch integration test directly:
75+
76+
```bash
77+
NEO4J_CONNECTION_STRING="<connection-string>" go test -tags neo4j_integration ./drivers/neo4j/...
78+
```

cypher/models/pgsql/test/fixture.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ import (
2222
"github.com/specterops/dawgs/graph"
2323
)
2424

25+
const (
26+
PGConnectionStringEV = "PG_CONNECTION_STRING"
27+
)
28+
2529
var (
2630
// Node and edge kinds to keep queries consistent
2731
NodeKind1 = graph.StringKind("NodeKind1")

cypher/models/pgsql/test/semantic_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build manual_integration
1+
//go:build pg_integration
22

33
// Copyright 2026 Specter Ops, Inc.
44
//

cypher/models/pgsql/test/translation_cases/delete.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
-- SPDX-License-Identifier: Apache-2.0
1616

1717
-- case: match (s:NodeKind1) detach delete s
18-
with s0 as (select (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0 from node n0 where n0.kind_ids operator (pg_catalog.@>) array [1]::int2[]), s1 as (delete from node n1 using s0 where (s0.n0).id = n1.id) select 1;
18+
with s0 as (select (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, n0.id as n0_id from node n0 where n0.kind_ids operator (pg_catalog.@>) array [1]::int2[]), s1 as (delete from node n1 using s0 where s0.n0_id = n1.id) select 1;
1919

2020
-- case: match ()-[r:EdgeKind1]->() delete r
21-
with s0 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id where e0.kind_id = any (array [3]::int2[])), s1 as (delete from edge e1 using s0 where (s0.e0).id = e1.id) select 1;
21+
with s0 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, n0.id as n0_id, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1, n1.id as n1_id from edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id where e0.kind_id = any (array [3]::int2[])), s1 as (delete from edge e1 using s0 where (s0.e0).id = e1.id) select 1;
2222

2323
-- case: match ()-[]->()-[r:EdgeKind1]->() delete r
24-
with s0 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id), s1 as (select s0.e0 as e0, (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s0.n0 as n0, s0.n1 as n1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s0 join edge e1 on (s0.n1).id = e1.start_id join node n2 on n2.id = e1.end_id where e1.kind_id = any (array [3]::int2[])), s2 as (delete from edge e2 using s1 where (s1.e1).id = e2.id) select 1;
24+
with s0 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, n0.id as n0_id, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1, n1.id as n1_id from edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id), s1 as (select s0.e0 as e0, (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s0.n0 as n0, s0.n0_id as n0_id, s0.n1 as n1, s0.n1_id as n1_id, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2, n2.id as n2_id from s0 join edge e1 on s0.n1_id = e1.start_id join node n2 on n2.id = e1.end_id where e1.kind_id = any (array [3]::int2[])), s2 as (delete from edge e2 using s1 where (s1.e1).id = e2.id) select 1;
2525

cypher/models/pgsql/test/translation_cases/multipart.sql

Lines changed: 24 additions & 24 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)