Skip to content

Commit f1f8624

Browse files
committed
fix: BP-1396, BED-5464: support additional query components; rework translate with to support better group by logic
1 parent 95f2d5f commit f1f8624

19 files changed

+732
-450
lines changed

packages/go/cypher/models/pgsql/pgtypes.go

+11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ const (
4343
)
4444

4545
var (
46+
Columns = []Identifier{
47+
ColumnID,
48+
ColumnPath,
49+
ColumnProperties,
50+
ColumnKindIDs,
51+
ColumnKindID,
52+
ColumnGraphID,
53+
ColumnStartID,
54+
ColumnEndID,
55+
}
56+
4657
NodeTableColumns = []Identifier{
4758
ColumnID,
4859
ColumnKindIDs,

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

+19-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ with s0 as (select '1' as i0), s1 as (select s0.i0 as i0, (n0.id, n0.kind_ids, n
2121
with s0 as (with s1 as (select (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0 from node n0 where (n0.properties ->> 'value')::int8 = 1 and n0.kind_ids operator (pg_catalog.&&) array [1]::int2[]) select s1.n0 as n0 from s1), s2 as (select s0.n0 as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s0, node n1 where n1.id = (s0.n0).id) select s2.n1 as b from s2;
2222

2323
-- case: match (n:NodeKind1) where n.value = 1 with n match (f) where f.name = 'me' with f match (b) where id(b) = id(f) return b
24-
with s0 as (with s1 as (select (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0 from node n0 where (n0.properties ->> 'value')::int8 = 1 and n0.kind_ids operator (pg_catalog.&&) array [1]::int2[]) select s1.n0 as n0 from s1), s2 as (with s3 as (select s0.n0 as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from node n1 where n1.properties ->> 'name' = 'me') select s3.n1 as n1 from s3), s4 as (select s2.n1 as n1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s2, node n2 where n2.id = (s2.n1).id) select s4.n2 as b from s4;
24+
with s0 as (with s1 as (select (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0 from node n0 where (n0.properties ->> 'value')::int8 = 1 and n0.kind_ids operator (pg_catalog.&&) array [1]::int2[]) select s1.n0 as n0 from s1), s2 as (with s3 as (select s0.n0 as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s0, node n1 where n1.properties ->> 'name' = 'me') select s3.n1 as n1 from s3), s4 as (select s2.n1 as n1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s2, node n2 where n2.id = (s2.n1).id) select s4.n2 as b from s4;
2525

2626
-- case: match (n:NodeKind1)-[:EdgeKind1*1..]->(:NodeKind2)-[:EdgeKind2]->(m:NodeKind1) where (n:NodeKind1 or n:NodeKind2) and n.enabled = true with m, collect(distinct(n)) as p where size(p) >= 10 return m
2727
with s0 as (with s1 as (with recursive s2(root_id, next_id, depth, satisfied, is_cycle, path) as (select e0.start_id, e0.end_id, 1, n1.kind_ids operator (pg_catalog.&&) array [2]::int2[], e0.start_id = e0.end_id, array [e0.id] from edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id where (n0.kind_ids operator (pg_catalog.&&) array [1]::int2[] or n0.kind_ids operator (pg_catalog.&&) array [2]::int2[]) and (n0.properties ->> 'enabled')::bool = true and n0.kind_ids operator (pg_catalog.&&) array [1]::int2[] and e0.kind_id = any (array [3]::int2[]) union select s2.root_id, e0.end_id, s2.depth + 1, n1.kind_ids operator (pg_catalog.&&) array [2]::int2[], e0.id = any (s2.path), s2.path || e0.id from s2 join edge e0 on e0.start_id = s2.next_id join node n1 on n1.id = e0.end_id where e0.kind_id = any (array [3]::int2[]) and s2.depth < 10 and not s2.is_cycle) select (select array_agg((e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite) from edge e0 where e0.id = any (s2.path)) as e0, s2.path as ep0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s2 join node n0 on n0.id = s2.root_id join node n1 on n1.id = s2.next_id where s2.satisfied), s3 as (select s1.e0 as e0, (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s1.ep0 as ep0, s1.n0 as n0, s1.n1 as n1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s1 join edge e1 on (s1.n1).id = e1.start_id join node n2 on n2.id = e1.end_id where n2.kind_ids operator (pg_catalog.&&) array [1]::int2[] and e1.kind_id = any (array [4]::int2[])) select s3.n2 as n2, array_agg(distinct (n0))::nodecomposite[] as i0 from s3 group by n2) select s0.n2 as m from s0 where array_length(s0.i0, 1)::int >= 10;
@@ -47,3 +47,21 @@ with s0 as (select 'a' as i0), s1 as (select s0.i0 as i0, (n0.id, n0.kind_ids, n
4747
-- case: match (dc)-[r:EdgeKind1*0..]->(g:NodeKind1) where g.objectid ends with '-516' with collect(dc) as exclude match p = (c:NodeKind2)-[n:EdgeKind2]->(u:NodeKind2)-[:EdgeKind2*1..]->(g:NodeKind1) where g.objectid ends with '-512' and not c in exclude return p limit 100
4848
with s0 as (with s1 as (with recursive s2(root_id, next_id, depth, satisfied, is_cycle, path) as (select e0.end_id, e0.start_id, 1, false, e0.end_id = e0.start_id, array [e0.id] from edge e0 join node n1 on n1.id = e0.end_id join node n0 on n0.id = e0.start_id where n1.properties ->> 'objectid' like '%-516' and n1.kind_ids operator (pg_catalog.&&) array [1]::int2[] and e0.kind_id = any (array [3]::int2[]) union select s2.root_id, e0.start_id, s2.depth + 1, false, e0.id = any (s2.path), s2.path || e0.id from s2 join edge e0 on e0.end_id = s2.next_id join node n0 on n0.id = e0.start_id where e0.kind_id = any (array [3]::int2[]) and s2.depth < 10 and not s2.is_cycle) select (select array_agg((e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite) from edge e0 where e0.id = any (s2.path)) as e0, s2.path as ep0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s2 join node n1 on n1.id = s2.root_id join node n0 on n0.id = s2.next_id) select array_agg(s1.n0)::nodecomposite[] as i0 from s1), s3 as (select (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s0.i0 as i0, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2, (n3.id, n3.kind_ids, n3.properties)::nodecomposite as n3 from s0, edge e1 join node n2 on n2.id = e1.start_id join node n3 on n3.id = e1.end_id where n3.kind_ids operator (pg_catalog.&&) array [2]::int2[] and e1.kind_id = any (array [4]::int2[]) and not n2.id = any (i0.id) and n2.kind_ids operator (pg_catalog.&&) array [2]::int2[]), s4 as (with recursive s5(root_id, next_id, depth, satisfied, is_cycle, path) as (select e2.start_id, e2.end_id, 1, false, e2.start_id = e2.end_id, array [e2.id] from s3 join edge e2 on e2.kind_id = any (array [4]::int2[]) join node n4 on n4.id = e2.end_id union select s5.root_id, e2.end_id, s5.depth + 1, n4.properties ->> 'objectid' like '%-512' and n4.kind_ids operator (pg_catalog.&&) array [1]::int2[], e2.id = any (s5.path), s5.path || e2.id from s5 join edge e2 on e2.end_id = s5.next_id join node n4 on n4.id = e2.end_id where e2.kind_id = any (array [4]::int2[]) and s5.depth < 10 and not s5.is_cycle) select s3.e1 as e1, (select array_agg((e2.id, e2.start_id, e2.end_id, e2.kind_id, e2.properties)::edgecomposite) from edge e2 where e2.id = any (s5.path)) as e2, s5.path as ep1, s3.i0 as i0, s3.n2 as n2, (n3.id, n3.kind_ids, n3.properties)::nodecomposite as n3, (n4.id, n4.kind_ids, n4.properties)::nodecomposite as n4 from s3, s5 join node n3 on n3.id = s5.root_id join node n4 on n4.id = s5.next_id) select edges_to_path(variadic array [(s4.e1).id]::int8[] || s4.ep1)::pathcomposite as p from s4 limit 100;
4949

50+
-- case: match (n:NodeKind1)<-[:EdgeKind1]-(:NodeKind2) where n.objectid ends with '-516' with n, count(n) as dc_count where dc_count = 1 return n
51+
with s0 as (with s1 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.end_id join node n1 on n1.id = e0.start_id where n1.kind_ids operator (pg_catalog.&&) array [2]::int2[] and e0.kind_id = any (array [3]::int2[]) and n0.properties ->> 'objectid' like '%-516' and n0.kind_ids operator (pg_catalog.&&) array [1]::int2[]) select s1.n0 as n0, count(s1.n0)::int8 as i0 from s1 group by n0) select s0.n0 as n from s0 where s0.i0 = 1;
52+
53+
-- case: match (n:NodeKind1)-[:EdgeKind1]->(m:NodeKind2) where n.enabled = true with n, collect(distinct(n)) as p where size(p) >= 100 match p = (n)-[:EdgeKind1]->(m) return p limit 10
54+
with s0 as (with s1 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 n1.kind_ids operator (pg_catalog.&&) array [2]::int2[] and e0.kind_id = any (array [3]::int2[]) and (n0.properties ->> 'enabled')::bool = true and n0.kind_ids operator (pg_catalog.&&) array [1]::int2[]) select s1.n0 as n0, array_agg(distinct (n0))::nodecomposite[] as i0 from s1 group by n0), s2 as (select (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s0.i0 as i0, s0.n0 as n0, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2 from s0 join edge e1 on (s0.n0).id = e1.start_id join node n2 on n2.id = e1.end_id where array_length(s0.i0, 1)::int >= 100 and e1.kind_id = any (array [3]::int2[])) select edges_to_path(variadic array [(s2.e1).id]::int8[])::pathcomposite as p from s2 limit 10;
55+
56+
-- case: with "a" as check, "b" as ref match p = (u)-[:EdgeKind1]->(g:NodeKind1) where u.name starts with check and u.domain = ref with collect(tolower(g.samaccountname)) as refmembership, tolower(u.samaccountname) as samname return refmembership, samname
57+
with s0 as (select 'a' as i0, 'b' as i1), s1 as (with s2 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, s0.i0 as i0, s0.i1 as i1, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s0, edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id where n1.kind_ids operator (pg_catalog.&&) array [1]::int2[] and e0.kind_id = any (array [3]::int2[]) and n0.properties ->> 'domain' = s0.i1 and n0.properties ->> 'name' like s0.i0 || '%') select array_agg(lower((s2.n1).properties ->> 'samaccountname')::text)::anyarray as i2, lower((s2.n0).properties ->> 'samaccountname')::text as i3 from s2 group by s2.n0) select s1.i2 as refmembership, s1.i3 as samname from s1;
58+
59+
-- case: with "a" as check, "b" as ref match p = (u)-[:EdgeKind1]->(g:NodeKind1) where u.name starts with check and u.domain = ref with collect(tolower(g.samaccountname)) as refmembership, tolower(u.samaccountname) as samname match (u)-[:EdgeKind2]-(g:NodeKind1) where tolower(u.samaccountname) = samname and not tolower(g.samaccountname) IN refmembership return g
60+
with s0 as (select 'a' as i0, 'b' as i1), s1 as (with s2 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, s0.i0 as i0, s0.i1 as i1, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s0, edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id where n1.kind_ids operator (pg_catalog.&&) array [1]::int2[] and e0.kind_id = any (array [3]::int2[]) and n0.properties ->> 'domain' = s0.i1 and n0.properties ->> 'name' like s0.i0 || '%') select array_agg(lower((s2.n1).properties ->> 'samaccountname')::text)::anyarray as i2, lower((s2.n0).properties ->> 'samaccountname')::text as i3 from s2 group by s2.n0), s3 as (select (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s1.i2 as i2, s1.i3 as i3, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2, (n3.id, n3.kind_ids, n3.properties)::nodecomposite as n3 from s1, edge e1 join node n2 on n2.id = e1.end_id or n2.id = e1.start_id join node n3 on n3.id = e1.end_id or n3.id = e1.start_id where e1.kind_id = any (array [4]::int2[]) and lower(n2.properties ->> 'samaccountname')::text = s1.i3) select s3.n3 as g from s3;
61+
62+
-- case: with "a" as check, "b" as ref match p = (u)-[:EdgeKind1]->(g:NodeKind1) where u.name starts with check and u.domain = ref with collect(tolower(g.samaccountname)) as refmembership, tolower(u.samaccountname) as samname match (u)-[:EdgeKind2]->(g:NodeKind1) where tolower(u.samaccountname) = samname and not tolower(g.samaccountname) IN refmembership return g
63+
with s0 as (select 'a' as i0, 'b' as i1), s1 as (with s2 as (select (e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite as e0, s0.i0 as i0, s0.i1 as i1, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s0, edge e0 join node n0 on n0.id = e0.start_id join node n1 on n1.id = e0.end_id where n1.kind_ids operator (pg_catalog.&&) array [1]::int2[] and e0.kind_id = any (array [3]::int2[]) and n0.properties ->> 'domain' = s0.i1 and n0.properties ->> 'name' like s0.i0 || '%') select array_agg(lower((s2.n1).properties ->> 'samaccountname')::text)::anyarray as i2, lower((s2.n0).properties ->> 'samaccountname')::text as i3 from s2 group by s2.n0), s3 as (select (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s1.i2 as i2, s1.i3 as i3, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2, (n3.id, n3.kind_ids, n3.properties)::nodecomposite as n3 from s1, edge e1 join node n2 on n2.id = e1.start_id join node n3 on n3.id = e1.end_id where n3.kind_ids operator (pg_catalog.&&) array [1]::int2[] and not lower(n3.properties ->> 'samaccountname')::text = any (i2) and e1.kind_id = any (array [4]::int2[]) and lower(n2.properties ->> 'samaccountname')::text = s1.i3) select s3.n3 as g from s3;
64+
65+
-- case: match p =(n:NodeKind1)<-[r:EdgeKind1|EdgeKind2*..3]-(u:NodeKind1) where n.domain = 'test' with n, count(r) as incomingCount where incomingCount > 90 with collect(n) as lotsOfAdmins match p =(n:NodeKind1)<-[:EdgeKind1]-() where n in lotsOfAdmins return p
66+
with s0 as (with s1 as (with recursive s2(root_id, next_id, depth, satisfied, is_cycle, path) as (select e0.end_id, e0.start_id, 1, n1.kind_ids operator (pg_catalog.&&) array [1]::int2[], e0.end_id = e0.start_id, array [e0.id] from edge e0 join node n0 on n0.id = e0.end_id join node n1 on n1.id = e0.start_id where n0.properties ->> 'domain' = 'test' and n0.kind_ids operator (pg_catalog.&&) array [1]::int2[] and e0.kind_id = any (array [3, 4]::int2[]) union select s2.root_id, e0.start_id, s2.depth + 1, n1.kind_ids operator (pg_catalog.&&) array [1]::int2[], e0.id = any (s2.path), s2.path || e0.id from s2 join edge e0 on e0.end_id = s2.next_id join node n1 on n1.id = e0.start_id where e0.kind_id = any (array [3, 4]::int2[]) and s2.depth < 3 and not s2.is_cycle) select (select array_agg((e0.id, e0.start_id, e0.end_id, e0.kind_id, e0.properties)::edgecomposite) from edge e0 where e0.id = any (s2.path)) as e0, s2.path as ep0, (n0.id, n0.kind_ids, n0.properties)::nodecomposite as n0, (n1.id, n1.kind_ids, n1.properties)::nodecomposite as n1 from s2 join node n0 on n0.id = s2.root_id join node n1 on n1.id = s2.next_id where s2.satisfied) select s1.n0 as n0, count(s1.e0)::int8 as i0 from s1 group by n0), s3 as (select array_agg(s0.n0)::nodecomposite[] as i1 from s0 where s0.i0 > 90), s4 as (select (e1.id, e1.start_id, e1.end_id, e1.kind_id, e1.properties)::edgecomposite as e1, s3.i1 as i1, (n2.id, n2.kind_ids, n2.properties)::nodecomposite as n2, (n3.id, n3.kind_ids, n3.properties)::nodecomposite as n3 from s3, edge e1 join node n2 on n2.id = e1.end_id join node n3 on n3.id = e1.start_id where e1.kind_id = any (array [3]::int2[]) and n2.id = any (i1.id) and n2.kind_ids operator (pg_catalog.&&) array [1]::int2[]) select edges_to_path(variadic array [(s4.e1).id]::int8[])::pathcomposite as p from s4;
67+

0 commit comments

Comments
 (0)