diff --git a/Makefile b/Makefile index 3e73f3e68..8c0cd8ac0 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,8 @@ REGRESS = scan \ name_validation \ jsonb_operators \ list_comprehension \ - map_projection + map_projection \ + unified_vertex_table ifneq ($(EXTRA_TESTS),) REGRESS += $(EXTRA_TESTS) diff --git a/regress/expected/age_global_graph.out b/regress/expected/age_global_graph.out index f2d9b059f..f8b2d9434 100644 --- a/regress/expected/age_global_graph.out +++ b/regress/expected/age_global_graph.out @@ -203,9 +203,9 @@ SELECT * FROM cypher('ag_graph_2', $$ MATCH (a:Person), (b:Person) WHERE a.name SELECT * FROM cypher('ag_graph_1', $$ MATCH (n) RETURN vertex_stats(n) $$) AS (result agtype); result ----------------------------------------------------------------------------------------------- + {"id": 844424930131969, "label": "vertex1", "in_degree": 0, "out_degree": 0, "self_loops": 0} {"id": 281474976710657, "label": "", "in_degree": 0, "out_degree": 0, "self_loops": 0} {"id": 281474976710658, "label": "", "in_degree": 0, "out_degree": 0, "self_loops": 0} - {"id": 844424930131969, "label": "vertex1", "in_degree": 0, "out_degree": 0, "self_loops": 0} (3 rows) --should return 1 vertice and 1 label @@ -288,14 +288,14 @@ SELECT * FROM cypher('ag_graph_1', $$ MATCH (u)-[]->(v) MERGE (v)-[:stalks]->(u) SELECT * FROM cypher('ag_graph_1', $$ MATCH (u)-[e]->(v) RETURN u, e, v $$) AS (u agtype, e agtype, v agtype); u | e | v --------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------- - {"id": 281474976710660, "label": "", "properties": {"id": 281474976710660, "name": "v"}}::vertex | {"id": 1407374883553281, "label": "stalks", "end_id": 281474976710659, "start_id": 281474976710660, "properties": {}}::edge | {"id": 281474976710659, "label": "", "properties": {"id": 281474976710659, "name": "u"}}::vertex {"id": 281474976710659, "label": "", "properties": {"id": 281474976710659, "name": "u"}}::vertex | {"id": 1125899906842625, "label": "knows", "end_id": 281474976710660, "start_id": 281474976710659, "properties": {}}::edge | {"id": 281474976710660, "label": "", "properties": {"id": 281474976710660, "name": "v"}}::vertex - {"id": 281474976710662, "label": "", "properties": {"id": 281474976710662, "name": "v"}}::vertex | {"id": 1407374883553282, "label": "stalks", "end_id": 281474976710661, "start_id": 281474976710662, "properties": {}}::edge | {"id": 281474976710661, "label": "", "properties": {"id": 281474976710661, "name": "u"}}::vertex {"id": 281474976710661, "label": "", "properties": {"id": 281474976710661, "name": "u"}}::vertex | {"id": 1125899906842626, "label": "knows", "end_id": 281474976710662, "start_id": 281474976710661, "properties": {}}::edge | {"id": 281474976710662, "label": "", "properties": {"id": 281474976710662, "name": "v"}}::vertex - {"id": 281474976710664, "label": "", "properties": {"id": 281474976710664, "name": "v"}}::vertex | {"id": 1407374883553283, "label": "stalks", "end_id": 281474976710663, "start_id": 281474976710664, "properties": {}}::edge | {"id": 281474976710663, "label": "", "properties": {"id": 281474976710663, "name": "u"}}::vertex {"id": 281474976710663, "label": "", "properties": {"id": 281474976710663, "name": "u"}}::vertex | {"id": 1125899906842627, "label": "knows", "end_id": 281474976710664, "start_id": 281474976710663, "properties": {}}::edge | {"id": 281474976710664, "label": "", "properties": {"id": 281474976710664, "name": "v"}}::vertex - {"id": 281474976710666, "label": "", "properties": {"id": 281474976710666, "name": "v"}}::vertex | {"id": 1407374883553284, "label": "stalks", "end_id": 281474976710665, "start_id": 281474976710666, "properties": {}}::edge | {"id": 281474976710665, "label": "", "properties": {"id": 281474976710665, "name": "u"}}::vertex {"id": 281474976710665, "label": "", "properties": {"id": 281474976710665, "name": "u"}}::vertex | {"id": 1125899906842628, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710665, "properties": {}}::edge | {"id": 281474976710666, "label": "", "properties": {"id": 281474976710666, "name": "v"}}::vertex + {"id": 281474976710662, "label": "", "properties": {"id": 281474976710662, "name": "v"}}::vertex | {"id": 1407374883553281, "label": "stalks", "end_id": 281474976710661, "start_id": 281474976710662, "properties": {}}::edge | {"id": 281474976710661, "label": "", "properties": {"id": 281474976710661, "name": "u"}}::vertex + {"id": 281474976710660, "label": "", "properties": {"id": 281474976710660, "name": "v"}}::vertex | {"id": 1407374883553282, "label": "stalks", "end_id": 281474976710659, "start_id": 281474976710660, "properties": {}}::edge | {"id": 281474976710659, "label": "", "properties": {"id": 281474976710659, "name": "u"}}::vertex + {"id": 281474976710664, "label": "", "properties": {"id": 281474976710664, "name": "v"}}::vertex | {"id": 1407374883553283, "label": "stalks", "end_id": 281474976710663, "start_id": 281474976710664, "properties": {}}::edge | {"id": 281474976710663, "label": "", "properties": {"id": 281474976710663, "name": "u"}}::vertex + {"id": 281474976710666, "label": "", "properties": {"id": 281474976710666, "name": "v"}}::vertex | {"id": 1407374883553284, "label": "stalks", "end_id": 281474976710665, "start_id": 281474976710666, "properties": {}}::edge | {"id": 281474976710665, "label": "", "properties": {"id": 281474976710665, "name": "u"}}::vertex (8 rows) -- what is there now? @@ -306,7 +306,7 @@ SELECT * FROM cypher('ag_graph_1', $$ RETURN graph_stats('ag_graph_1') $$) AS (r (1 row) -- remove some vertices -SELECT * FROM ag_graph_1._ag_label_vertex; +SELECT id, properties FROM ag_graph_1._ag_label_vertex order by id; id | properties -----------------+-------------------------------------- 281474976710657 | {} @@ -325,7 +325,7 @@ SELECT * FROM ag_graph_1._ag_label_vertex; DELETE FROM ag_graph_1._ag_label_vertex WHERE id::text = '281474976710661'; DELETE FROM ag_graph_1._ag_label_vertex WHERE id::text = '281474976710662'; DELETE FROM ag_graph_1._ag_label_vertex WHERE id::text = '281474976710664'; -SELECT * FROM ag_graph_1._ag_label_vertex; +SELECT id, properties FROM ag_graph_1._ag_label_vertex order by id; id | properties -----------------+-------------------------------------- 281474976710657 | {} @@ -345,8 +345,8 @@ SELECT * FROM ag_graph_1._ag_label_edge; 1125899906842626 | 281474976710661 | 281474976710662 | {} 1125899906842627 | 281474976710663 | 281474976710664 | {} 1125899906842628 | 281474976710665 | 281474976710666 | {} - 1407374883553281 | 281474976710660 | 281474976710659 | {} - 1407374883553282 | 281474976710662 | 281474976710661 | {} + 1407374883553281 | 281474976710662 | 281474976710661 | {} + 1407374883553282 | 281474976710660 | 281474976710659 | {} 1407374883553283 | 281474976710664 | 281474976710663 | {} 1407374883553284 | 281474976710666 | 281474976710665 | {} (8 rows) @@ -357,7 +357,7 @@ WARNING: edge: [id: 1125899906842626, start: 281474976710661, end: 281474976710 WARNING: ignored malformed or dangling edge WARNING: edge: [id: 1125899906842627, start: 281474976710663, end: 281474976710664, label: knows] end vertex not found WARNING: ignored malformed or dangling edge -WARNING: edge: [id: 1407374883553282, start: 281474976710662, end: 281474976710661, label: stalks] start and end vertices not found +WARNING: edge: [id: 1407374883553281, start: 281474976710662, end: 281474976710661, label: stalks] start and end vertices not found WARNING: ignored malformed or dangling edge WARNING: edge: [id: 1407374883553283, start: 281474976710664, end: 281474976710663, label: stalks] start vertex not found WARNING: ignored malformed or dangling edge diff --git a/regress/expected/age_load.out b/regress/expected/age_load.out index 55d1ff1d6..69368aaa5 100644 --- a/regress/expected/age_load.out +++ b/regress/expected/age_load.out @@ -125,13 +125,15 @@ WHERE table_schema = 'agload_test_graph' ORDER BY table_name ASC; contrib_regression | agload_test_graph | has_city | BASE TABLE (5 rows) -SELECT COUNT(*) FROM agload_test_graph."Country"; +SELECT COUNT(*) FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."Country"'::regclass::oid; count ------- 54 (1 row) -SELECT COUNT(*) FROM agload_test_graph."City"; +SELECT COUNT(*) FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."City"'::regclass::oid; count ------- 72485 @@ -194,19 +196,22 @@ SELECT load_labels_from_file('agload_test_graph', 'City2', (1 row) -SELECT COUNT(*) FROM agload_test_graph."Country2"; +SELECT COUNT(*) FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."Country2"'::regclass::oid; count ------- 53 (1 row) -SELECT COUNT(*) FROM agload_test_graph."City2"; +SELECT COUNT(*) FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."City2"'::regclass::oid; count ------- 72485 (1 row) -SELECT id FROM agload_test_graph."Country" LIMIT 10; +SELECT id FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."Country"'::regclass::oid LIMIT 10; id ----------------- 844424930131969 @@ -221,7 +226,8 @@ SELECT id FROM agload_test_graph."Country" LIMIT 10; 844424930132023 (10 rows) -SELECT id FROM agload_test_graph."Country2" LIMIT 10; +SELECT id FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."Country2"'::regclass::oid LIMIT 10; id ------------------ 1688849860263937 @@ -238,7 +244,7 @@ SELECT id FROM agload_test_graph."Country2" LIMIT 10; -- Should return 2 rows for Country with same properties, but different ids SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country {iso2 : 'BE'}) - RETURN id(n), n.name, n.iso2 $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); + RETURN id(n), n.name, n.iso2 ORDER BY id(n) $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); id(n) | n.name | n.iso2 -----------------+-----------+-------- 844424930131990 | "Belgium" | "BE" @@ -247,7 +253,7 @@ SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country {iso2 : 'BE'}) -- Should return 1 row SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country2 {iso2 : 'BE'}) - RETURN id(n), n.name, n.iso2 $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); + RETURN id(n), n.name, n.iso2 ORDER BY id(n) $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); id(n) | n.name | n.iso2 ------------------+-----------+-------- 1688849860263942 | "Belgium" | "BE" @@ -255,7 +261,7 @@ SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country2 {iso2 : 'BE'}) -- Should return 2 rows for Country with same properties, but different ids SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country {iso2 : 'AT'}) - RETURN id(n), n.name, n.iso2 $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); + RETURN id(n), n.name, n.iso2 ORDER BY id(n) $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); id(n) | n.name | n.iso2 -----------------+-----------+-------- 844424930131983 | "Austria" | "AT" @@ -264,7 +270,7 @@ SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country {iso2 : 'AT'}) -- Should return 1 row SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country2 {iso2 : 'AT'}) - RETURN id(n), n.name, n.iso2 $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); + RETURN id(n), n.name, n.iso2 ORDER BY id(n) $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); id(n) | n.name | n.iso2 ------------------+-----------+-------- 1688849860263940 | "Austria" | "AT" @@ -275,6 +281,7 @@ SELECT * FROM cypher('agload_test_graph', $$ MATCH (u:Country {region : "Europe"}) WHERE u.name =~ 'Cro.*' RETURN id(u), u.name, u.region + ORDER BY id(u) $$) AS ("id(u)" agtype, result_1 agtype, result_2 agtype); id(u) | result_1 | result_2 -----------------+-----------+---------- diff --git a/regress/expected/cypher_create.out b/regress/expected/cypher_create.out index 2388af8a0..1aa7af2cf 100644 --- a/regress/expected/cypher_create.out +++ b/regress/expected/cypher_create.out @@ -133,7 +133,8 @@ SELECT * FROM cypher_create.e; 1125899906842634 | 844424930131987 | 844424930131988 | {"id": "paths, edge two"} (10 rows) -SELECT * FROM cypher_create.v; +SELECT id, properties FROM cypher_create._ag_label_vertex +WHERE labels = 'cypher_create.v'::regclass::oid; id | properties -----------------+------------------------------------ 844424930131969 | {} @@ -331,7 +332,8 @@ $$) as (a agtype); --- (0 rows) -SELECT * FROM cypher_create.n_var; +SELECT id, properties FROM cypher_create._ag_label_vertex +WHERE labels = 'cypher_create.n_var'::regclass::oid; id | properties ------------------+-------------------- 1407374883553281 | {"name": "Node A"} @@ -393,25 +395,6 @@ SELECT * FROM cypher('cypher_create', $$MATCH (n) RETURN n$$) AS (n agtype); n ------------------------------------------------------------------------------------------------- {"id": 281474976710657, "label": "", "properties": {}}::vertex - {"id": 281474976710658, "label": "", "properties": {}}::vertex - {"id": 281474976710659, "label": "", "properties": {}}::vertex - {"id": 281474976710660, "label": "", "properties": {}}::vertex - {"id": 281474976710661, "label": "", "properties": {}}::vertex - {"id": 281474976710662, "label": "", "properties": {}}::vertex - {"id": 281474976710663, "label": "", "properties": {}}::vertex - {"id": 281474976710664, "label": "", "properties": {}}::vertex - {"id": 281474976710665, "label": "", "properties": {}}::vertex - {"id": 281474976710666, "label": "", "properties": {}}::vertex - {"id": 281474976710667, "label": "", "properties": {}}::vertex - {"id": 281474976710668, "label": "", "properties": {}}::vertex - {"id": 281474976710669, "label": "", "properties": {}}::vertex - {"id": 281474976710670, "label": "", "properties": {}}::vertex - {"id": 281474976710671, "label": "", "properties": {}}::vertex - {"id": 281474976710672, "label": "", "properties": {}}::vertex - {"id": 281474976710673, "label": "", "properties": {}}::vertex - {"id": 281474976710674, "label": "", "properties": {"id": 0}}::vertex - {"id": 281474976710675, "label": "", "properties": {}}::vertex - {"id": 281474976710676, "label": "", "properties": {}}::vertex {"id": 844424930131969, "label": "v", "properties": {}}::vertex {"id": 844424930131970, "label": "v", "properties": {}}::vertex {"id": 844424930131971, "label": "v", "properties": {"key": "value"}}::vertex @@ -438,6 +421,25 @@ SELECT * FROM cypher('cypher_create', $$MATCH (n) RETURN n$$) AS (n agtype); {"id": 1970324836974593, "label": "n_other_node", "properties": {}}::vertex {"id": 1970324836974594, "label": "n_other_node", "properties": {}}::vertex {"id": 1970324836974595, "label": "n_other_node", "properties": {}}::vertex + {"id": 281474976710658, "label": "", "properties": {}}::vertex + {"id": 281474976710659, "label": "", "properties": {}}::vertex + {"id": 281474976710660, "label": "", "properties": {}}::vertex + {"id": 281474976710661, "label": "", "properties": {}}::vertex + {"id": 281474976710662, "label": "", "properties": {}}::vertex + {"id": 281474976710663, "label": "", "properties": {}}::vertex + {"id": 281474976710664, "label": "", "properties": {}}::vertex + {"id": 281474976710665, "label": "", "properties": {}}::vertex + {"id": 281474976710666, "label": "", "properties": {}}::vertex + {"id": 281474976710667, "label": "", "properties": {}}::vertex + {"id": 281474976710668, "label": "", "properties": {}}::vertex + {"id": 281474976710669, "label": "", "properties": {}}::vertex + {"id": 281474976710670, "label": "", "properties": {}}::vertex + {"id": 281474976710671, "label": "", "properties": {}}::vertex + {"id": 281474976710672, "label": "", "properties": {}}::vertex + {"id": 281474976710673, "label": "", "properties": {}}::vertex + {"id": 281474976710674, "label": "", "properties": {"id": 0}}::vertex + {"id": 281474976710675, "label": "", "properties": {}}::vertex + {"id": 281474976710676, "label": "", "properties": {}}::vertex (46 rows) -- prepared statements diff --git a/regress/expected/cypher_delete.out b/regress/expected/cypher_delete.out index 3cdbbf8bb..cabc6af14 100644 --- a/regress/expected/cypher_delete.out +++ b/regress/expected/cypher_delete.out @@ -535,10 +535,10 @@ SELECT * FROM cypher('cypher_delete', $$MATCH p=()-[]->() RETURN p$$) AS (a agty SELECT * FROM cypher('cypher_delete', $$MATCH(n) DELETE n RETURN n$$) AS (a agtype); a ----------------------------------------------------------------- - {"id": 281474976710657, "label": "", "properties": {}}::vertex - {"id": 281474976710658, "label": "", "properties": {}}::vertex {"id": 844424930132012, "label": "v", "properties": {}}::vertex + {"id": 281474976710657, "label": "", "properties": {}}::vertex {"id": 844424930132013, "label": "v", "properties": {}}::vertex + {"id": 281474976710658, "label": "", "properties": {}}::vertex (4 rows) --Test 24 @@ -710,8 +710,8 @@ SELECT * FROM cypher('detach_delete', $$ MATCH ()-[e]->() RETURN e.name $$) as ( ------- "ab" "cd" - "am" "nm" + "am" "pq" (5 rows) diff --git a/regress/expected/cypher_match.out b/regress/expected/cypher_match.out index a0e284beb..1c83c6934 100644 --- a/regress/expected/cypher_match.out +++ b/regress/expected/cypher_match.out @@ -115,8 +115,8 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (a agtype); a --------------------------------------------------------------------------------------------------------------------------- - {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge + {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge (2 rows) SELECT * FROM cypher('cypher_match', $$ @@ -250,8 +250,8 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (a agtype); a --------------------------------------------------------------------------------------------------------------------------- - {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge + {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge (2 rows) --Left Path Test @@ -308,8 +308,8 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (a agtype); a --------------------------------------------------------------------------------------------------------------------------- - {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge + {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge (2 rows) --Divergent Path Tests @@ -336,10 +336,10 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (i agtype); i ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex]::path [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex]::path + [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path (4 rows) SELECT * FROM cypher('cypher_match', $$ @@ -348,10 +348,10 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (i agtype); i ---------------------------------------------------------------------------------- - {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex - {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex + {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex + {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex (4 rows) SELECT * FROM cypher('cypher_match', $$ @@ -361,14 +361,14 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (i agtype); i ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex]::path - [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex]::path - [{"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge, {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex]::path [{"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge, {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex]::path - [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path - [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path + [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex]::path [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex]::path + [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path + [{"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge, {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex]::path + [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex]::path [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex]::path + [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path (8 rows) SELECT * FROM cypher('cypher_match', $$ @@ -378,14 +378,14 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (i agtype); i ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex]::path [{"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge, {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex]::path - [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path - [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex]::path - [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex]::path [{"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex, {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge, {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex]::path - [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path + [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex]::path + [{"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex, {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge, {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex]::path + [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex]::path [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex]::path + [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path + [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path (8 rows) --Convergent Path Tests @@ -402,8 +402,8 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (i agtype); i --------------------------------------------------------------------------------------------------------------------------- - {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge + {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge (2 rows) SELECT * FROM cypher('cypher_match', $$ @@ -412,8 +412,8 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (i agtype); i --------------------------------------------------------------------------------------------------------------------------- - {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge + {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge (2 rows) SELECT * FROM cypher('cypher_match', $$ @@ -537,18 +537,18 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (i agtype, b agtype, c agtype); i | b | c ---+-----------+----------- - | "end" | "middle" - 0 | "end" | "middle" - 1 | "end" | "middle" | "middle" | "end" + | "end" | "middle" 0 | "middle" | "end" + 0 | "end" | "middle" 1 | "middle" | "end" - | "middle" | "initial" - 0 | "middle" | "initial" - 1 | "middle" | "initial" + 1 | "end" | "middle" | "initial" | "middle" + | "middle" | "initial" 0 | "initial" | "middle" + 0 | "middle" | "initial" 1 | "initial" | "middle" + 1 | "middle" | "initial" (12 rows) SELECT * FROM cypher('cypher_match', $$ @@ -558,18 +558,18 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (i agtype, c agtype); i | c ---+----------- - | "middle" - 0 | "middle" - 1 | "middle" | "end" + | "middle" 0 | "end" + 0 | "middle" 1 | "end" - | "initial" - 0 | "initial" - 1 | "initial" + 1 | "middle" | "middle" + | "initial" 0 | "middle" + 0 | "initial" 1 | "middle" + 1 | "initial" (12 rows) -- @@ -708,10 +708,10 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (r0 agtype); r0 --------------------------------------------------------------------------------------------------------------------------- - {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge - {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge + {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge + {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge (6 rows) @@ -721,8 +721,8 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (r0 agtype); r0 --------------------------------------------------------------------------------------------------------------------------- - {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge + {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge (2 rows) SELECT * FROM cypher('cypher_match', $$ @@ -730,8 +730,8 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (r0 agtype); r0 --------------------------------------------------------------------------------------------------------------------------- - {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge + {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge (2 rows) SELECT * FROM cypher('cypher_match', $$ @@ -747,10 +747,10 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (p1 agtype); p1 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path - [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex]::path + [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex]::path + [{"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex, {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge, {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex]::path (4 rows) SELECT * FROM cypher('cypher_match', $$ @@ -785,10 +785,10 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (r0 agtype, r1 agtype); r0 | r1 ---------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------- - {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge - {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge + {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge | {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge + {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge (4 rows) -- valid variable reuse for vertex labels across clauses @@ -804,8 +804,6 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (r1 agtype); r1 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex - {"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex {"id": 844424930131969, "label": "v", "properties": {}}::vertex {"id": 844424930131970, "label": "v", "properties": {"i": 0}}::vertex {"id": 844424930131971, "label": "v", "properties": {"i": 1}}::vertex @@ -818,6 +816,8 @@ $$) AS (r1 agtype); {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex + {"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex + {"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex (14 rows) SELECT * FROM cypher('cypher_match', $$ @@ -860,8 +860,8 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (r0 agtype); r0 --------------------------------------------------------------------------------------------------------------------------- - {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge + {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge (2 rows) -- invalid variable reuse for vertex @@ -1028,8 +1028,6 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (p agtype); p --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - [{"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex]::path - [{"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex]::path [{"id": 844424930131969, "label": "v", "properties": {}}::vertex]::path [{"id": 844424930131970, "label": "v", "properties": {"i": 0}}::vertex]::path [{"id": 844424930131971, "label": "v", "properties": {"i": 1}}::vertex]::path @@ -1042,6 +1040,8 @@ $$) AS (p agtype); [{"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex]::path [{"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex]::path [{"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex]::path + [{"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex]::path + [{"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex]::path (14 rows) -- @@ -1051,10 +1051,10 @@ SELECT * FROM cypher('cypher_match', $$MATCH (u)-[e]->(v) RETURN u, e, v $$) AS (u agtype, e agtype, v agtype); u | e | v ----------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------- - {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex | {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex | {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex - {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex + {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex | {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex + {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex | {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex (6 rows) @@ -1064,10 +1064,10 @@ SELECT * FROM cypher('cypher_match', AS (u agtype, e agtype, v agtype); u | e | v ----------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------- - {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex | {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex | {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex - {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex + {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex | {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex + {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex | {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex (6 rows) @@ -1119,10 +1119,10 @@ SELECT * FROM cypher('cypher_match', AS (u agtype, e agtype, v agtype); u | e | v ------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------ - {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex | {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex | {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex - {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex + {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex | {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex + {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex | {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex | {"id": 3096224743817217, "label": "self", "end_id": 2814749767106561, "start_id": 2814749767106561, "properties": {}}::edge | {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex @@ -1152,10 +1152,10 @@ SELECT * FROM cypher('cypher_match', AS (u agtype, e agtype, v agtype); u | e | v ------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------ - {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex | {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex | {"id": 1407374883553281, "label": "e1", "end_id": 1125899906842627, "start_id": 1125899906842626, "properties": {}}::edge | {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex - {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex + {"id": 1125899906842625, "label": "v1", "properties": {"id": "initial"}}::vertex | {"id": 1407374883553282, "label": "e1", "end_id": 1125899906842626, "start_id": 1125899906842625, "properties": {}}::edge | {"id": 1125899906842626, "label": "v1", "properties": {"id": "middle"}}::vertex {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974593, "label": "e2", "end_id": 1688849860263939, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex + {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex | {"id": 1970324836974594, "label": "e2", "end_id": 1688849860263937, "start_id": 1688849860263938, "properties": {}}::edge | {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex | {"id": 2533274790395905, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685251, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex | {"id": 2533274790395906, "label": "e3", "end_id": 2251799813685250, "start_id": 2251799813685249, "properties": {}}::edge | {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex | {"id": 3096224743817217, "label": "self", "end_id": 2814749767106561, "start_id": 2814749767106561, "properties": {}}::edge | {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex @@ -1175,8 +1175,6 @@ SELECT * FROM cypher('cypher_match', AS (exists agtype); exists -------- - false - false false false false @@ -1189,6 +1187,8 @@ AS (exists agtype); true false true + false + false true (15 rows) @@ -1235,8 +1235,6 @@ LINE 2: $$MATCH p=(u)-[e]->(v) RETURN EXISTS((p)) $$) SELECT * FROM cypher('cypher_match', $$MATCH (u) RETURN u $$) AS (u agtype); u ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex - {"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex {"id": 844424930131969, "label": "v", "properties": {}}::vertex {"id": 844424930131970, "label": "v", "properties": {"i": 0}}::vertex {"id": 844424930131971, "label": "v", "properties": {"i": 1}}::vertex @@ -1249,6 +1247,8 @@ SELECT * FROM cypher('cypher_match', $$MATCH (u) RETURN u $$) AS (u agtype); {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex + {"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex + {"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex (15 rows) @@ -1276,11 +1276,11 @@ SELECT * FROM cypher('cypher_match', AS (u agtype); u ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex - {"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex {"id": 844424930131969, "label": "v", "properties": {}}::vertex {"id": 844424930131970, "label": "v", "properties": {"i": 0}}::vertex {"id": 844424930131971, "label": "v", "properties": {"i": 1}}::vertex + {"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex + {"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex (5 rows) -- select vertices without id as a property but with a property i @@ -1308,8 +1308,6 @@ SELECT * FROM cypher('cypher_match', AS (exists agtype, properties agtype); exists | properties --------+------------------------------------------------------------------------------------------------------------- - false | {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"} - false | {"lst": [1, null, 3.14, "string", {"key": "value"}, []]} false | {} false | {"i": 0} false | {"i": 1} @@ -1322,6 +1320,8 @@ AS (exists agtype, properties agtype); true | {"id": "initial"} true | {"id": "middle"} true | {"id": "end"} + false | {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"} + false | {"lst": [1, null, 3.14, "string", {"key": "value"}, []]} true | {"id": "initial"} (15 rows) @@ -1330,8 +1330,6 @@ SELECT * FROM cypher('cypher_match', AS (exists agtype, properties agtype); exists | properties --------+------------------------------------------------------------------------------------------------------------- - false | {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"} - false | {"lst": [1, null, 3.14, "string", {"key": "value"}, []]} false | {} false | {"i": 0} false | {"i": 1} @@ -1344,6 +1342,8 @@ AS (exists agtype, properties agtype); false | {"id": "initial"} false | {"id": "middle"} false | {"id": "end"} + false | {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"} + false | {"lst": [1, null, 3.14, "string", {"key": "value"}, []]} false | {"id": "initial"} (15 rows) @@ -1572,8 +1572,6 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (i agtype); i ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex - {"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex {"id": 844424930131969, "label": "v", "properties": {}}::vertex {"id": 844424930131970, "label": "v", "properties": {"i": 0}}::vertex {"id": 844424930131971, "label": "v", "properties": {"i": 1}}::vertex @@ -1586,6 +1584,8 @@ $$) AS (i agtype); {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex + {"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex + {"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex {"id": 3377699720527873, "label": "duplicate", "properties": {}}::vertex {"id": 3940649673949185, "label": "other_v", "properties": {}}::vertex @@ -1596,11 +1596,11 @@ SELECT * FROM cypher('cypher_match', $$ MATCH (u) RETURN u LIMIT 3 $$) AS (i agtype); - i -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex - {"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex + i +----------------------------------------------------------------------- {"id": 844424930131969, "label": "v", "properties": {}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"i": 0}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": 1}}::vertex (3 rows) -- @@ -1610,15 +1610,15 @@ SELECT * FROM cypher('cypher_match', $$ MATCH (u) RETURN u SKIP 7 $$) AS (i agtype); - i ------------------------------------------------------------------------------------- - {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex - {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex + i +------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex {"id": 2251799813685250, "label": "v3", "properties": {"id": "middle"}}::vertex {"id": 2251799813685251, "label": "v3", "properties": {"id": "end"}}::vertex + {"id": 281474976710657, "label": "", "properties": {"int_key": 1, "map_key": {"key": "value"}, "list_key": [1, 2, 3], "float_key": 3.14, "string_key": "test"}}::vertex + {"id": 281474976710658, "label": "", "properties": {"lst": [1, null, 3.14, "string", {"key": "value"}, []]}}::vertex {"id": 2814749767106561, "label": "loop", "properties": {"id": "initial"}}::vertex {"id": 3377699720527873, "label": "duplicate", "properties": {}}::vertex {"id": 3940649673949185, "label": "other_v", "properties": {}}::vertex @@ -1631,9 +1631,9 @@ SELECT * FROM cypher('cypher_match', $$ $$) AS (i agtype); i ---------------------------------------------------------------------------------- - {"id": 1125899906842627, "label": "v1", "properties": {"id": "end"}}::vertex - {"id": 1688849860263937, "label": "v2", "properties": {"id": "initial"}}::vertex {"id": 1688849860263938, "label": "v2", "properties": {"id": "middle"}}::vertex + {"id": 1688849860263939, "label": "v2", "properties": {"id": "end"}}::vertex + {"id": 2251799813685249, "label": "v3", "properties": {"id": "initial"}}::vertex (3 rows) -- @@ -2421,8 +2421,8 @@ SELECT * FROM cypher('cypher_match', $$ MATCH p=(a)-[u {relationship: u.relation SELECT * FROM cypher('cypher_match', $$ MATCH p=(a {name:a.name})-[u {relationship: u.relationship}]->(b {age:b.age}) RETURN p $$) as (a agtype); a ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - [{"id": 281474976710659, "label": "", "properties": {"age": 3, "name": "orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710659, "properties": {"years": 4, "relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path [{"id": 281474976710661, "label": "", "properties": {"age": 4, "name": "T"}}::vertex, {"id": 4785074604081153, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710661, "properties": {"years": 3, "relationship": "friends"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path + [{"id": 281474976710659, "label": "", "properties": {"age": 3, "name": "orphan"}}::vertex, {"id": 4785074604081154, "label": "knows", "end_id": 281474976710666, "start_id": 281474976710659, "properties": {"years": 4, "relationship": "enemies"}}::edge, {"id": 281474976710666, "label": "", "properties": {"age": 6}}::vertex]::path (2 rows) SELECT * FROM cypher('cypher_match', $$ CREATE () WITH * MATCH (x{n0:x.n1}) RETURN 0 $$) as (a agtype); @@ -2534,10 +2534,10 @@ SELECT count(*) FROM cypher('test_enable_containment', $$ MATCH (x:Customer {pho (1 row) SELECT * FROM cypher('test_enable_containment', $$ EXPLAIN (COSTS OFF) MATCH (x:Customer {school:{name:'XYZ',program:{degree:'BSc'}},phone:[987654321],parents:{}}) RETURN x $$) as (a agtype); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------- - Seq Scan on "Customer" x - Filter: (properties @> '{"phone": [987654321], "school": {"name": "XYZ", "program": {"degree": "BSc"}}, "parents": {}}'::agtype) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Seq Scan on _ag_label_vertex x + Filter: ((labels = '20188'::oid) AND (properties @> '{"phone": [987654321], "school": {"name": "XYZ", "program": {"degree": "BSc"}}, "parents": {}}'::agtype)) (2 rows) -- Previous set of queries, with enable_containment off @@ -2597,10 +2597,10 @@ SELECT count(*) FROM cypher('test_enable_containment', $$ MATCH (x:Customer {pho (1 row) SELECT * FROM cypher('test_enable_containment', $$ EXPLAIN (COSTS OFF) MATCH (x:Customer {school:{name:'XYZ',program:{degree:'BSc'}},phone:[987654321],parents:{}}) RETURN x $$) as (a agtype); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Seq Scan on "Customer" x - Filter: ((agtype_access_operator(VARIADIC ARRAY[properties, '"school"'::agtype, '"name"'::agtype]) = '"XYZ"'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"school"'::agtype, '"program"'::agtype, '"degree"'::agtype]) = '"BSc"'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"phone"'::agtype]) @> '[987654321]'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"parents"'::agtype]) @> '{}'::agtype)) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Seq Scan on _ag_label_vertex x + Filter: ((labels = '20188'::oid) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"school"'::agtype, '"name"'::agtype]) = '"XYZ"'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"school"'::agtype, '"program"'::agtype, '"degree"'::agtype]) = '"BSc"'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"phone"'::agtype]) @> '[987654321]'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"parents"'::agtype]) @> '{}'::agtype)) (2 rows) -- @@ -3113,10 +3113,10 @@ $$) AS (n1 agtype, n2 agtype); n1 | n2 ----------------------------------------------------------------------+---------------------------------------------------------------------- {"id": 844424930131969, "label": "Object", "properties": {}}::vertex | {"id": 844424930131969, "label": "Object", "properties": {}}::vertex - {"id": 844424930131971, "label": "Object", "properties": {}}::vertex | {"id": 844424930131969, "label": "Object", "properties": {}}::vertex {"id": 844424930131969, "label": "Object", "properties": {}}::vertex | {"id": 844424930131970, "label": "Object", "properties": {}}::vertex - {"id": 844424930131971, "label": "Object", "properties": {}}::vertex | {"id": 844424930131970, "label": "Object", "properties": {}}::vertex {"id": 844424930131969, "label": "Object", "properties": {}}::vertex | {"id": 844424930131971, "label": "Object", "properties": {}}::vertex + {"id": 844424930131971, "label": "Object", "properties": {}}::vertex | {"id": 844424930131969, "label": "Object", "properties": {}}::vertex + {"id": 844424930131971, "label": "Object", "properties": {}}::vertex | {"id": 844424930131970, "label": "Object", "properties": {}}::vertex {"id": 844424930131971, "label": "Object", "properties": {}}::vertex | {"id": 844424930131971, "label": "Object", "properties": {}}::vertex (6 rows) @@ -3136,10 +3136,10 @@ $$) AS (n1 agtype, n2 agtype); n1 | n2 ----------------------------------------------------------------------+---------------------------------------------------------------------- {"id": 844424930131969, "label": "Object", "properties": {}}::vertex | {"id": 844424930131969, "label": "Object", "properties": {}}::vertex - {"id": 844424930131971, "label": "Object", "properties": {}}::vertex | {"id": 844424930131969, "label": "Object", "properties": {}}::vertex {"id": 844424930131969, "label": "Object", "properties": {}}::vertex | {"id": 844424930131970, "label": "Object", "properties": {}}::vertex - {"id": 844424930131971, "label": "Object", "properties": {}}::vertex | {"id": 844424930131970, "label": "Object", "properties": {}}::vertex {"id": 844424930131969, "label": "Object", "properties": {}}::vertex | {"id": 844424930131971, "label": "Object", "properties": {}}::vertex + {"id": 844424930131971, "label": "Object", "properties": {}}::vertex | {"id": 844424930131969, "label": "Object", "properties": {}}::vertex + {"id": 844424930131971, "label": "Object", "properties": {}}::vertex | {"id": 844424930131970, "label": "Object", "properties": {}}::vertex {"id": 844424930131971, "label": "Object", "properties": {}}::vertex | {"id": 844424930131971, "label": "Object", "properties": {}}::vertex (6 rows) @@ -3398,25 +3398,27 @@ SELECT count(*) FROM cypher('test_enable_containment', $$ MATCH p=(x:Customer)-[ (1 row) SELECT * FROM cypher('test_enable_containment', $$ EXPLAIN (costs off) MATCH (x:Customer)-[:bought ={store: 'Amazon', addr:{city: 'Vancouver', street: 30}}]->(y:Product) RETURN 0 $$) as (a agtype); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- - Hash Join - Hash Cond: (y.id = _age_default_alias_0.end_id) - -> Seq Scan on "Product" y - -> Hash - -> Hash Join - Hash Cond: (x.id = _age_default_alias_0.start_id) - -> Seq Scan on "Customer" x - -> Hash - -> Seq Scan on bought _age_default_alias_0 - Filter: (properties @>> '{"addr": {"city": "Vancouver", "street": 30}, "store": "Amazon"}'::agtype) -(10 rows) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Nested Loop + Join Filter: (_age_default_alias_0.end_id = y.id) + -> Nested Loop + -> Seq Scan on _ag_label_vertex x + Filter: (labels = '20188'::oid) + -> Bitmap Heap Scan on bought _age_default_alias_0 + Recheck Cond: (start_id = x.id) + Filter: (properties @>> '{"addr": {"city": "Vancouver", "street": 30}, "store": "Amazon"}'::agtype) + -> Bitmap Index Scan on bought_start_id_idx + Index Cond: (start_id = x.id) + -> Seq Scan on _ag_label_vertex y + Filter: (labels = '20326'::oid) +(12 rows) SELECT * FROM cypher('test_enable_containment', $$ EXPLAIN (costs off) MATCH (x:Customer ={school: { name: 'XYZ College',program: { major: 'Psyc', degree: 'BSc'} },phone: [ 123456789, 987654321, 456987123 ]}) RETURN 0 $$) as (a agtype); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Seq Scan on "Customer" x - Filter: (properties @>> '{"phone": [123456789, 987654321, 456987123], "school": {"name": "XYZ College", "program": {"major": "Psyc", "degree": "BSc"}}}'::agtype) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Seq Scan on _ag_label_vertex x + Filter: ((labels = '20188'::oid) AND (properties @>> '{"phone": [123456789, 987654321, 456987123], "school": {"name": "XYZ College", "program": {"major": "Psyc", "degree": "BSc"}}}'::agtype)) (2 rows) -- With enable_containment off @@ -3517,20 +3519,24 @@ SELECT * FROM cypher('test_enable_containment', $$ EXPLAIN (costs off) MATCH (x: QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop + Join Filter: (_age_default_alias_0.end_id = y.id) -> Nested Loop - -> Seq Scan on bought _age_default_alias_0 + -> Seq Scan on _ag_label_vertex x + Filter: (labels = '20188'::oid) + -> Bitmap Heap Scan on bought _age_default_alias_0 + Recheck Cond: (start_id = x.id) Filter: ((agtype_access_operator(VARIADIC ARRAY[properties, '"store"'::agtype]) = '"Amazon"'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"addr"'::agtype]) = '{"city": "Vancouver", "street": 30}'::agtype)) - -> Index Only Scan using "Customer_pkey" on "Customer" x - Index Cond: (id = _age_default_alias_0.start_id) - -> Index Only Scan using "Product_pkey" on "Product" y - Index Cond: (id = _age_default_alias_0.end_id) -(8 rows) + -> Bitmap Index Scan on bought_start_id_idx + Index Cond: (start_id = x.id) + -> Seq Scan on _ag_label_vertex y + Filter: (labels = '20326'::oid) +(12 rows) SELECT * FROM cypher('test_enable_containment', $$ EXPLAIN (costs off) MATCH (x:Customer ={school: { name: 'XYZ College',program: { major: 'Psyc', degree: 'BSc'} },phone: [ 123456789, 987654321, 456987123 ]}) RETURN 0 $$) as (a agtype); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Seq Scan on "Customer" x - Filter: ((agtype_access_operator(VARIADIC ARRAY[properties, '"school"'::agtype]) = '{"name": "XYZ College", "program": {"major": "Psyc", "degree": "BSc"}}'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"phone"'::agtype]) = '[123456789, 987654321, 456987123]'::agtype)) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Seq Scan on _ag_label_vertex x + Filter: ((labels = '20188'::oid) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"school"'::agtype]) = '{"name": "XYZ College", "program": {"major": "Psyc", "degree": "BSc"}}'::agtype) AND (agtype_access_operator(VARIADIC ARRAY[properties, '"phone"'::agtype]) = '[123456789, 987654321, 456987123]'::agtype)) (2 rows) -- diff --git a/regress/expected/cypher_merge.out b/regress/expected/cypher_merge.out index 56a23f513..80d4f4f90 100644 --- a/regress/expected/cypher_merge.out +++ b/regress/expected/cypher_merge.out @@ -1158,10 +1158,10 @@ SELECT * FROM cypher('issue_1219', $$ MATCH (x) RETURN x $$) as (result agtype); result ---------------------------------------------------------------------------------------------------------------------------------------------------------- {"id": 844424930131969, "label": "Label1", "properties": {"arr": [1, 2, 3, 4]}}::vertex - {"id": 844424930131970, "label": "Label1", "properties": {"name": "John"}}::vertex - {"id": 844424930131971, "label": "Label1", "properties": {"name": "Jane"}}::vertex {"id": 1125899906842625, "label": "Label2", "properties": {"key1": 2, "key2": [1, 2, 3, 4], "key3": 3}}::vertex {"id": 1125899906842626, "label": "Label2", "properties": {"key2": 844424930131969}}::vertex + {"id": 844424930131970, "label": "Label1", "properties": {"name": "John"}}::vertex + {"id": 844424930131971, "label": "Label1", "properties": {"name": "Jane"}}::vertex {"id": 1125899906842627, "label": "Label2", "properties": {"end_id": 844424930131971, "edge_id": 1407374883553281, "start_id": 844424930131970}}::vertex (6 rows) diff --git a/regress/expected/cypher_remove.out b/regress/expected/cypher_remove.out index ca2b94ae6..6aaeeea8f 100644 --- a/regress/expected/cypher_remove.out +++ b/regress/expected/cypher_remove.out @@ -204,11 +204,8 @@ SELECT * FROM cypher('cypher_remove', $$CREATE ( {i : 1 })$$) AS (a agtype); SELECT * FROM cypher('cypher_remove', $$MATCH (n) REMOVE n.i RETURN n$$) AS (a agtype); a ------------------------------------------------------------------------------------ - {"id": 281474976710657, "label": "", "properties": {}}::vertex - {"id": 281474976710658, "label": "", "properties": {}}::vertex {"id": 844424930131969, "label": "test_1", "properties": {}}::vertex {"id": 844424930131971, "label": "test_1", "properties": {}}::vertex - {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 1125899906842625, "label": "test_2", "properties": {}}::vertex {"id": 1125899906842626, "label": "test_2", "properties": {"a": 0}}::vertex {"id": 1125899906842627, "label": "test_2", "properties": {}}::vertex @@ -217,18 +214,18 @@ SELECT * FROM cypher('cypher_remove', $$MATCH (n) REMOVE n.i RETURN n$$) AS (a a {"id": 1970324836974593, "label": "test_4", "properties": {}}::vertex {"id": 1970324836974594, "label": "test_4", "properties": {}}::vertex {"id": 2533274790395905, "label": "test_5", "properties": {"k": 3}}::vertex + {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 2814749767106561, "label": "test_6", "properties": {"j": 5}}::vertex + {"id": 281474976710657, "label": "", "properties": {}}::vertex {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex + {"id": 281474976710658, "label": "", "properties": {}}::vertex (15 rows) SELECT * FROM cypher('cypher_remove', $$MATCH (n) RETURN n$$) AS (a agtype); a ------------------------------------------------------------------------------------ - {"id": 281474976710657, "label": "", "properties": {}}::vertex - {"id": 281474976710658, "label": "", "properties": {}}::vertex {"id": 844424930131969, "label": "test_1", "properties": {}}::vertex {"id": 844424930131971, "label": "test_1", "properties": {}}::vertex - {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 1125899906842625, "label": "test_2", "properties": {}}::vertex {"id": 1125899906842626, "label": "test_2", "properties": {"a": 0}}::vertex {"id": 1125899906842627, "label": "test_2", "properties": {}}::vertex @@ -237,8 +234,11 @@ SELECT * FROM cypher('cypher_remove', $$MATCH (n) RETURN n$$) AS (a agtype); {"id": 1970324836974593, "label": "test_4", "properties": {}}::vertex {"id": 1970324836974594, "label": "test_4", "properties": {}}::vertex {"id": 2533274790395905, "label": "test_5", "properties": {"k": 3}}::vertex + {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 2814749767106561, "label": "test_6", "properties": {"j": 5}}::vertex + {"id": 281474976710657, "label": "", "properties": {}}::vertex {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex + {"id": 281474976710658, "label": "", "properties": {}}::vertex (15 rows) -- prepared statements @@ -251,12 +251,8 @@ PREPARE p_1 AS SELECT * FROM cypher('cypher_remove', $$MATCH (n) REMOVE n.i RETU EXECUTE p_1; a ------------------------------------------------------------------------------------ - {"id": 281474976710657, "label": "", "properties": {}}::vertex - {"id": 281474976710658, "label": "", "properties": {}}::vertex - {"id": 281474976710659, "label": "", "properties": {}}::vertex {"id": 844424930131969, "label": "test_1", "properties": {}}::vertex {"id": 844424930131971, "label": "test_1", "properties": {}}::vertex - {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 1125899906842625, "label": "test_2", "properties": {}}::vertex {"id": 1125899906842626, "label": "test_2", "properties": {"a": 0}}::vertex {"id": 1125899906842627, "label": "test_2", "properties": {}}::vertex @@ -265,8 +261,12 @@ EXECUTE p_1; {"id": 1970324836974593, "label": "test_4", "properties": {}}::vertex {"id": 1970324836974594, "label": "test_4", "properties": {}}::vertex {"id": 2533274790395905, "label": "test_5", "properties": {"k": 3}}::vertex + {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 2814749767106561, "label": "test_6", "properties": {"j": 5}}::vertex + {"id": 281474976710657, "label": "", "properties": {}}::vertex {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex + {"id": 281474976710658, "label": "", "properties": {}}::vertex + {"id": 281474976710659, "label": "", "properties": {}}::vertex (16 rows) SELECT * FROM cypher('cypher_remove', $$CREATE ( {i : 1 })$$) AS (a agtype); @@ -277,13 +277,8 @@ SELECT * FROM cypher('cypher_remove', $$CREATE ( {i : 1 })$$) AS (a agtype); EXECUTE p_1; a ------------------------------------------------------------------------------------ - {"id": 281474976710657, "label": "", "properties": {}}::vertex - {"id": 281474976710658, "label": "", "properties": {}}::vertex - {"id": 281474976710659, "label": "", "properties": {}}::vertex - {"id": 281474976710660, "label": "", "properties": {}}::vertex {"id": 844424930131969, "label": "test_1", "properties": {}}::vertex {"id": 844424930131971, "label": "test_1", "properties": {}}::vertex - {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 1125899906842625, "label": "test_2", "properties": {}}::vertex {"id": 1125899906842626, "label": "test_2", "properties": {"a": 0}}::vertex {"id": 1125899906842627, "label": "test_2", "properties": {}}::vertex @@ -292,8 +287,13 @@ EXECUTE p_1; {"id": 1970324836974593, "label": "test_4", "properties": {}}::vertex {"id": 1970324836974594, "label": "test_4", "properties": {}}::vertex {"id": 2533274790395905, "label": "test_5", "properties": {"k": 3}}::vertex + {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 2814749767106561, "label": "test_6", "properties": {"j": 5}}::vertex + {"id": 281474976710657, "label": "", "properties": {}}::vertex {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex + {"id": 281474976710658, "label": "", "properties": {}}::vertex + {"id": 281474976710659, "label": "", "properties": {}}::vertex + {"id": 281474976710660, "label": "", "properties": {}}::vertex (17 rows) -- pl/pgsql @@ -314,14 +314,8 @@ $BODY$; SELECT remove_test(); remove_test ------------------------------------------------------------------------------------ - {"id": 281474976710657, "label": "", "properties": {}}::vertex - {"id": 281474976710658, "label": "", "properties": {}}::vertex - {"id": 281474976710659, "label": "", "properties": {}}::vertex - {"id": 281474976710660, "label": "", "properties": {}}::vertex - {"id": 281474976710661, "label": "", "properties": {}}::vertex {"id": 844424930131969, "label": "test_1", "properties": {}}::vertex {"id": 844424930131971, "label": "test_1", "properties": {}}::vertex - {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 1125899906842625, "label": "test_2", "properties": {}}::vertex {"id": 1125899906842626, "label": "test_2", "properties": {"a": 0}}::vertex {"id": 1125899906842627, "label": "test_2", "properties": {}}::vertex @@ -330,8 +324,14 @@ SELECT remove_test(); {"id": 1970324836974593, "label": "test_4", "properties": {}}::vertex {"id": 1970324836974594, "label": "test_4", "properties": {}}::vertex {"id": 2533274790395905, "label": "test_5", "properties": {"k": 3}}::vertex + {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 2814749767106561, "label": "test_6", "properties": {"j": 5}}::vertex + {"id": 281474976710657, "label": "", "properties": {}}::vertex {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex + {"id": 281474976710658, "label": "", "properties": {}}::vertex + {"id": 281474976710659, "label": "", "properties": {}}::vertex + {"id": 281474976710660, "label": "", "properties": {}}::vertex + {"id": 281474976710661, "label": "", "properties": {}}::vertex (18 rows) SELECT * FROM cypher('cypher_remove', $$CREATE ( {i : 1 })$$) AS (a agtype); @@ -342,15 +342,8 @@ SELECT * FROM cypher('cypher_remove', $$CREATE ( {i : 1 })$$) AS (a agtype); SELECT remove_test(); remove_test ------------------------------------------------------------------------------------ - {"id": 281474976710657, "label": "", "properties": {}}::vertex - {"id": 281474976710658, "label": "", "properties": {}}::vertex - {"id": 281474976710659, "label": "", "properties": {}}::vertex - {"id": 281474976710660, "label": "", "properties": {}}::vertex - {"id": 281474976710661, "label": "", "properties": {}}::vertex - {"id": 281474976710662, "label": "", "properties": {}}::vertex {"id": 844424930131969, "label": "test_1", "properties": {}}::vertex {"id": 844424930131971, "label": "test_1", "properties": {}}::vertex - {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 1125899906842625, "label": "test_2", "properties": {}}::vertex {"id": 1125899906842626, "label": "test_2", "properties": {"a": 0}}::vertex {"id": 1125899906842627, "label": "test_2", "properties": {}}::vertex @@ -359,8 +352,15 @@ SELECT remove_test(); {"id": 1970324836974593, "label": "test_4", "properties": {}}::vertex {"id": 1970324836974594, "label": "test_4", "properties": {}}::vertex {"id": 2533274790395905, "label": "test_5", "properties": {"k": 3}}::vertex + {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 2814749767106561, "label": "test_6", "properties": {"j": 5}}::vertex + {"id": 281474976710657, "label": "", "properties": {}}::vertex {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex + {"id": 281474976710658, "label": "", "properties": {}}::vertex + {"id": 281474976710659, "label": "", "properties": {}}::vertex + {"id": 281474976710660, "label": "", "properties": {}}::vertex + {"id": 281474976710661, "label": "", "properties": {}}::vertex + {"id": 281474976710662, "label": "", "properties": {}}::vertex (19 rows) -- @@ -369,15 +369,8 @@ SELECT remove_test(); SELECT * FROM cypher('cypher_remove', $$MATCH (n) RETURN n$$) AS (a agtype); a ------------------------------------------------------------------------------------ - {"id": 281474976710657, "label": "", "properties": {}}::vertex - {"id": 281474976710658, "label": "", "properties": {}}::vertex - {"id": 281474976710659, "label": "", "properties": {}}::vertex - {"id": 281474976710660, "label": "", "properties": {}}::vertex - {"id": 281474976710661, "label": "", "properties": {}}::vertex - {"id": 281474976710662, "label": "", "properties": {}}::vertex {"id": 844424930131969, "label": "test_1", "properties": {}}::vertex {"id": 844424930131971, "label": "test_1", "properties": {}}::vertex - {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 1125899906842625, "label": "test_2", "properties": {}}::vertex {"id": 1125899906842626, "label": "test_2", "properties": {"a": 0}}::vertex {"id": 1125899906842627, "label": "test_2", "properties": {}}::vertex @@ -386,22 +379,22 @@ SELECT * FROM cypher('cypher_remove', $$MATCH (n) RETURN n$$) AS (a agtype); {"id": 1970324836974593, "label": "test_4", "properties": {}}::vertex {"id": 1970324836974594, "label": "test_4", "properties": {}}::vertex {"id": 2533274790395905, "label": "test_5", "properties": {"k": 3}}::vertex + {"id": 844424930131970, "label": "test_1", "properties": {"a": 0, "j": 5}}::vertex {"id": 2814749767106561, "label": "test_6", "properties": {"j": 5}}::vertex - {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex -(19 rows) - -SELECT * FROM cypher('cypher_remove', $$MATCH (n) REMOVE n.i, n.j, n.k RETURN n$$) AS (a agtype); - a ------------------------------------------------------------------------------ {"id": 281474976710657, "label": "", "properties": {}}::vertex + {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex {"id": 281474976710658, "label": "", "properties": {}}::vertex {"id": 281474976710659, "label": "", "properties": {}}::vertex {"id": 281474976710660, "label": "", "properties": {}}::vertex {"id": 281474976710661, "label": "", "properties": {}}::vertex {"id": 281474976710662, "label": "", "properties": {}}::vertex +(19 rows) + +SELECT * FROM cypher('cypher_remove', $$MATCH (n) REMOVE n.i, n.j, n.k RETURN n$$) AS (a agtype); + a +----------------------------------------------------------------------------- {"id": 844424930131969, "label": "test_1", "properties": {}}::vertex {"id": 844424930131971, "label": "test_1", "properties": {}}::vertex - {"id": 844424930131970, "label": "test_1", "properties": {"a": 0}}::vertex {"id": 1125899906842625, "label": "test_2", "properties": {}}::vertex {"id": 1125899906842626, "label": "test_2", "properties": {"a": 0}}::vertex {"id": 1125899906842627, "label": "test_2", "properties": {}}::vertex @@ -410,22 +403,22 @@ SELECT * FROM cypher('cypher_remove', $$MATCH (n) REMOVE n.i, n.j, n.k RETURN n$ {"id": 1970324836974593, "label": "test_4", "properties": {}}::vertex {"id": 1970324836974594, "label": "test_4", "properties": {}}::vertex {"id": 2533274790395905, "label": "test_5", "properties": {}}::vertex + {"id": 844424930131970, "label": "test_1", "properties": {"a": 0}}::vertex {"id": 2814749767106561, "label": "test_6", "properties": {}}::vertex - {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex -(19 rows) - -SELECT * FROM cypher('cypher_remove', $$MATCH (n) RETURN n$$) AS (a agtype); - a ------------------------------------------------------------------------------ {"id": 281474976710657, "label": "", "properties": {}}::vertex + {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex {"id": 281474976710658, "label": "", "properties": {}}::vertex {"id": 281474976710659, "label": "", "properties": {}}::vertex {"id": 281474976710660, "label": "", "properties": {}}::vertex {"id": 281474976710661, "label": "", "properties": {}}::vertex {"id": 281474976710662, "label": "", "properties": {}}::vertex +(19 rows) + +SELECT * FROM cypher('cypher_remove', $$MATCH (n) RETURN n$$) AS (a agtype); + a +----------------------------------------------------------------------------- {"id": 844424930131969, "label": "test_1", "properties": {}}::vertex {"id": 844424930131971, "label": "test_1", "properties": {}}::vertex - {"id": 844424930131970, "label": "test_1", "properties": {"a": 0}}::vertex {"id": 1125899906842625, "label": "test_2", "properties": {}}::vertex {"id": 1125899906842626, "label": "test_2", "properties": {"a": 0}}::vertex {"id": 1125899906842627, "label": "test_2", "properties": {}}::vertex @@ -434,8 +427,15 @@ SELECT * FROM cypher('cypher_remove', $$MATCH (n) RETURN n$$) AS (a agtype); {"id": 1970324836974593, "label": "test_4", "properties": {}}::vertex {"id": 1970324836974594, "label": "test_4", "properties": {}}::vertex {"id": 2533274790395905, "label": "test_5", "properties": {}}::vertex + {"id": 844424930131970, "label": "test_1", "properties": {"a": 0}}::vertex {"id": 2814749767106561, "label": "test_6", "properties": {}}::vertex + {"id": 281474976710657, "label": "", "properties": {}}::vertex {"id": 3377699720527873, "label": "test_7", "properties": {}}::vertex + {"id": 281474976710658, "label": "", "properties": {}}::vertex + {"id": 281474976710659, "label": "", "properties": {}}::vertex + {"id": 281474976710660, "label": "", "properties": {}}::vertex + {"id": 281474976710661, "label": "", "properties": {}}::vertex + {"id": 281474976710662, "label": "", "properties": {}}::vertex (19 rows) SELECT * FROM cypher('cypher_remove', $$CREATE ()-[:edge_multi_property { i: 5, j: 20}]->()$$) AS (a agtype); diff --git a/regress/expected/cypher_set.out b/regress/expected/cypher_set.out index 1d24a7f9b..f73093509 100644 --- a/regress/expected/cypher_set.out +++ b/regress/expected/cypher_set.out @@ -118,57 +118,57 @@ SELECT * FROM cypher('cypher_set', $$CREATE ()$$) AS (a agtype); SELECT * FROM cypher('cypher_set', $$MATCH (n) SET n.i = 3 RETURN n$$) AS (a agtype); a --------------------------------------------------------------------------------------- - {"id": 281474976710657, "label": "", "properties": {"i": 3}}::vertex {"id": 844424930131969, "label": "v", "properties": {"i": 3}}::vertex {"id": 844424930131971, "label": "v", "properties": {"i": 3}}::vertex {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 3, "j": 5}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 3}}::vertex (4 rows) SELECT * FROM cypher('cypher_set', $$MATCH (n) RETURN n$$) AS (a agtype); a --------------------------------------------------------------------------------------- - {"id": 281474976710657, "label": "", "properties": {"i": 3}}::vertex {"id": 844424930131969, "label": "v", "properties": {"i": 3}}::vertex {"id": 844424930131971, "label": "v", "properties": {"i": 3}}::vertex {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 3, "j": 5}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 3}}::vertex (4 rows) --Validate Paths are updated SELECT * FROM cypher('cypher_set', $$MATCH (n) CREATE (n)-[:e {j:20}]->(:other_v {k:10}) RETURN n$$) AS (a agtype); a --------------------------------------------------------------------------------------- - {"id": 281474976710657, "label": "", "properties": {"i": 3}}::vertex {"id": 844424930131969, "label": "v", "properties": {"i": 3}}::vertex {"id": 844424930131971, "label": "v", "properties": {"i": 3}}::vertex {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 3, "j": 5}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 3}}::vertex (4 rows) SELECT * FROM cypher('cypher_set', $$MATCH p=(n)-[]->() SET n.i = 50 RETURN p$$) AS (a agtype); a --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - [{"id": 281474976710657, "label": "", "properties": {"i": 50}}::vertex, {"id": 1125899906842625, "label": "e", "end_id": 1407374883553281, "start_id": 281474976710657, "properties": {"j": 20}}::edge, {"id": 1407374883553281, "label": "other_v", "properties": {"k": 10}}::vertex]::path - [{"id": 844424930131969, "label": "v", "properties": {"i": 50}}::vertex, {"id": 1125899906842626, "label": "e", "end_id": 1407374883553282, "start_id": 844424930131969, "properties": {"j": 20}}::edge, {"id": 1407374883553282, "label": "other_v", "properties": {"k": 10}}::vertex]::path - [{"id": 844424930131971, "label": "v", "properties": {"i": 50}}::vertex, {"id": 1125899906842627, "label": "e", "end_id": 1407374883553283, "start_id": 844424930131971, "properties": {"j": 20}}::edge, {"id": 1407374883553283, "label": "other_v", "properties": {"k": 10}}::vertex]::path - [{"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 50, "j": 5}}::vertex, {"id": 1125899906842628, "label": "e", "end_id": 1407374883553284, "start_id": 844424930131970, "properties": {"j": 20}}::edge, {"id": 1407374883553284, "label": "other_v", "properties": {"k": 10}}::vertex]::path + [{"id": 844424930131969, "label": "v", "properties": {"i": 50}}::vertex, {"id": 1125899906842625, "label": "e", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"j": 20}}::edge, {"id": 1407374883553281, "label": "other_v", "properties": {"k": 10}}::vertex]::path + [{"id": 844424930131971, "label": "v", "properties": {"i": 50}}::vertex, {"id": 1125899906842626, "label": "e", "end_id": 1407374883553282, "start_id": 844424930131971, "properties": {"j": 20}}::edge, {"id": 1407374883553282, "label": "other_v", "properties": {"k": 10}}::vertex]::path + [{"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 50, "j": 5}}::vertex, {"id": 1125899906842627, "label": "e", "end_id": 1407374883553283, "start_id": 844424930131970, "properties": {"j": 20}}::edge, {"id": 1407374883553283, "label": "other_v", "properties": {"k": 10}}::vertex]::path + [{"id": 281474976710657, "label": "", "properties": {"i": 50}}::vertex, {"id": 1125899906842628, "label": "e", "end_id": 1407374883553284, "start_id": 281474976710657, "properties": {"j": 20}}::edge, {"id": 1407374883553284, "label": "other_v", "properties": {"k": 10}}::vertex]::path (4 rows) --Edges SELECT * FROM cypher('cypher_set', $$MATCH ()-[n]-(:other_v) SET n.i = 3 RETURN n$$) AS (a agtype); a ---------------------------------------------------------------------------------------------------------------------------------------- - {"id": 1125899906842625, "label": "e", "end_id": 1407374883553281, "start_id": 281474976710657, "properties": {"i": 3, "j": 20}}::edge - {"id": 1125899906842626, "label": "e", "end_id": 1407374883553282, "start_id": 844424930131969, "properties": {"i": 3, "j": 20}}::edge - {"id": 1125899906842627, "label": "e", "end_id": 1407374883553283, "start_id": 844424930131971, "properties": {"i": 3, "j": 20}}::edge - {"id": 1125899906842628, "label": "e", "end_id": 1407374883553284, "start_id": 844424930131970, "properties": {"i": 3, "j": 20}}::edge + {"id": 1125899906842625, "label": "e", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"i": 3, "j": 20}}::edge + {"id": 1125899906842626, "label": "e", "end_id": 1407374883553282, "start_id": 844424930131971, "properties": {"i": 3, "j": 20}}::edge + {"id": 1125899906842627, "label": "e", "end_id": 1407374883553283, "start_id": 844424930131970, "properties": {"i": 3, "j": 20}}::edge + {"id": 1125899906842628, "label": "e", "end_id": 1407374883553284, "start_id": 281474976710657, "properties": {"i": 3, "j": 20}}::edge (4 rows) SELECT * FROM cypher('cypher_set', $$MATCH ()-[n]->(:other_v) RETURN n$$) AS (a agtype); a ---------------------------------------------------------------------------------------------------------------------------------------- - {"id": 1125899906842625, "label": "e", "end_id": 1407374883553281, "start_id": 281474976710657, "properties": {"i": 3, "j": 20}}::edge - {"id": 1125899906842626, "label": "e", "end_id": 1407374883553282, "start_id": 844424930131969, "properties": {"i": 3, "j": 20}}::edge - {"id": 1125899906842628, "label": "e", "end_id": 1407374883553284, "start_id": 844424930131970, "properties": {"i": 3, "j": 20}}::edge - {"id": 1125899906842627, "label": "e", "end_id": 1407374883553283, "start_id": 844424930131971, "properties": {"i": 3, "j": 20}}::edge + {"id": 1125899906842625, "label": "e", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"i": 3, "j": 20}}::edge + {"id": 1125899906842626, "label": "e", "end_id": 1407374883553282, "start_id": 844424930131971, "properties": {"i": 3, "j": 20}}::edge + {"id": 1125899906842627, "label": "e", "end_id": 1407374883553283, "start_id": 844424930131970, "properties": {"i": 3, "j": 20}}::edge + {"id": 1125899906842628, "label": "e", "end_id": 1407374883553284, "start_id": 281474976710657, "properties": {"i": 3, "j": 20}}::edge (4 rows) SELECT * FROM cypher('cypher_set', $$ @@ -245,8 +245,8 @@ SELECT * FROM cypher('cypher_set', $$ $$) AS (a agtype); a --------------------------------------------------------------------------------------------------------- - {"id": 281474976710658, "label": "", "properties": {"y": 1}}::vertex {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 50, "j": 5, "y": 1, "z": 99}}::vertex + {"id": 281474976710658, "label": "", "properties": {"y": 1}}::vertex (2 rows) SELECT * FROM cypher('cypher_set', $$ @@ -310,12 +310,12 @@ SELECT * FROM cypher('cypher_set', $$MATCH (n)-[]->(n) SET n.y = 99 RETURN n$$) SELECT * FROM cypher('cypher_set', $$MATCH (n) MATCH (n)-[]->(m) SET n.t = 150 RETURN n$$) AS (a agtype); a -------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710658, "label": "", "properties": {"t": 150, "y": 1}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 50, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": 50, "t": 150}}::vertex {"id": 844424930131969, "label": "v", "properties": {"i": 50, "t": 150}}::vertex {"id": 844424930131971, "label": "v", "properties": {"i": 50, "t": 150}}::vertex {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 50, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 50, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 50, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex (6 rows) -- prepared statements @@ -323,62 +323,62 @@ PREPARE p_1 AS SELECT * FROM cypher('cypher_set', $$MATCH (n) SET n.i = 3 RETURN EXECUTE p_1; a ------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": 3, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": 3, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": 3, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": 3, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": 3, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 3, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": 3, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": 3, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": 3, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": 3, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": 3, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": 3, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": 3, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 3, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": 3, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 3, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex (10 rows) EXECUTE p_1; a ------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": 3, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": 3, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": 3, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": 3, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": 3, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 3, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": 3, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": 3, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": 3, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": 3, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": 3, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": 3, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": 3, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 3, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": 3, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 3, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex (10 rows) PREPARE p_2 AS SELECT * FROM cypher('cypher_set', $$MATCH (n) SET n.i = $var_name RETURN n $$, $1) AS (a agtype); EXECUTE p_2('{"var_name": 4}'); a ------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": 4, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": 4, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": 4, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": 4, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": 4, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 4, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": 4, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": 4, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": 4, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": 4, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": 4, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": 4, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": 4, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 4, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": 4, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 4, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex (10 rows) EXECUTE p_2('{"var_name": 6}'); a ------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": 6, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": 6, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": 6, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": 6, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": 6, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 6, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": 6, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": 6, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": 6, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": 6, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": 6, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": 6, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": 6, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 6, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": 6, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 6, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex (10 rows) CREATE FUNCTION set_test() @@ -393,31 +393,31 @@ $BODY$; SELECT set_test(); set_test ------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": 7, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": 7, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": 7, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": 7, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": 7, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 7, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": 7, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": 7, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": 7, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": 7, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": 7, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": 7, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": 7, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 7, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": 7, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 7, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex (10 rows) SELECT set_test(); set_test ------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": 7, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": 7, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": 7, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": 7, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": 7, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 7, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": 7, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": 7, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": 7, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": 7, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": 7, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": 7, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": 7, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 7, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": 7, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 7, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex (10 rows) -- @@ -426,16 +426,16 @@ SELECT set_test(); SELECT * FROM cypher('cypher_set', $$MATCH (n) SET n.i = 3, n.j = 5 RETURN n $$) AS (a agtype); a ------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": 3, "j": 5, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": 3, "j": 5, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": 3, "j": 5, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": 3, "j": 5, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": 3, "j": 5, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 3, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": 3, "j": 5, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": 3, "j": 5, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": 3, "j": 5, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": 3, "j": 5, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": 3, "j": 5, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": 3, "j": 5, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": 3, "j": 5, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": 3, "j": 5, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": 3, "j": 5, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": 3, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex (10 rows) SELECT * FROM cypher('cypher_set', $$MATCH (n)-[m]->(n) SET m.y = n.y RETURN n, m$$) AS (a agtype, b agtype); @@ -577,16 +577,16 @@ SELECT * FROM cypher('cypher_set', $$MATCH (u:begin)-[:edge]->(v:end) return u, SELECT * FROM cypher('cypher_set', $$MATCH (n) SET n.i = [3, 'test', [1, 2, 3], {id: 1}, 1.0, 1.0::numeric] RETURN n$$) AS (a agtype); a -------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1688849860263937, "label": "vertices", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 6, "k": 9}}::vertex {"id": 1970324836974593, "label": "begin", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 4}}::vertex {"id": 2533274790395905, "label": "end", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 3}}::vertex @@ -595,16 +595,16 @@ SELECT * FROM cypher('cypher_set', $$MATCH (n) SET n.i = [3, 'test', [1, 2, 3], SELECT * FROM cypher('cypher_set', $$MATCH (n) RETURN n$$) AS (a agtype); a -------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1688849860263937, "label": "vertices", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 6, "k": 9}}::vertex {"id": 1970324836974593, "label": "begin", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 4}}::vertex {"id": 2533274790395905, "label": "end", "properties": {"i": [3, "test", [1, 2, 3], {"id": 1}, 1.0, 1::numeric], "j": 3}}::vertex @@ -627,74 +627,74 @@ SELECT * FROM cypher('cypher_set', $$MATCH p=(u:begin)-[:edge]->(v:end) return u SELECT * FROM cypher('cypher_set', $$MATCH (n) SET n.i = [] RETURN n$$) AS (a agtype); a -------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": [], "j": 5, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": [], "j": 5, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": [], "j": 5, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": [], "j": 5, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": [], "j": 5, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": [], "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": [], "j": 5, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": [], "j": 5, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": [], "j": 5, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": [], "j": 5, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": [], "j": 5, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": [], "j": 5, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": [], "j": 5, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": [], "j": 5, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": [], "j": 5, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": [], "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1688849860263937, "label": "vertices", "properties": {"i": [], "j": 6, "k": 9}}::vertex - {"id": 1970324836974593, "label": "begin", "properties": {"i": [], "j": 4}}::vertex {"id": 2533274790395905, "label": "end", "properties": {"i": [], "j": 3}}::vertex + {"id": 1970324836974593, "label": "begin", "properties": {"i": [], "j": 4}}::vertex (13 rows) SELECT * FROM cypher('cypher_set', $$MATCH (n) RETURN n$$) AS (a agtype); a -------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": [], "j": 5, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": [], "j": 5, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": [], "j": 5, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": [], "j": 5, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": [], "j": 5, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": [], "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": [], "j": 5, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": [], "j": 5, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": [], "j": 5, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": [], "j": 5, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": [], "j": 5, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": [], "j": 5, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": [], "j": 5, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": [], "j": 5, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": [], "j": 5, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": [], "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1688849860263937, "label": "vertices", "properties": {"i": [], "j": 6, "k": 9}}::vertex - {"id": 1970324836974593, "label": "begin", "properties": {"i": [], "j": 4}}::vertex {"id": 2533274790395905, "label": "end", "properties": {"i": [], "j": 3}}::vertex + {"id": 1970324836974593, "label": "begin", "properties": {"i": [], "j": 4}}::vertex (13 rows) -- test maps SELECT * FROM cypher('cypher_set', $$MATCH (n) SET n.i = {prop1: 3, prop2:'test', prop3: [1, 2, 3], prop4: {id: 1}, prop5: 1.0, prop6:1.0::numeric} RETURN n$$) AS (a agtype); a -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1688849860263937, "label": "vertices", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 6, "k": 9}}::vertex - {"id": 1970324836974593, "label": "begin", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 4}}::vertex {"id": 2533274790395905, "label": "end", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 3}}::vertex + {"id": 1970324836974593, "label": "begin", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 4}}::vertex (13 rows) SELECT * FROM cypher('cypher_set', $$MATCH (n) RETURN n$$) AS (a agtype); a -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1688849860263937, "label": "vertices", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 6, "k": 9}}::vertex - {"id": 1970324836974593, "label": "begin", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 4}}::vertex {"id": 2533274790395905, "label": "end", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 3}}::vertex + {"id": 1970324836974593, "label": "begin", "properties": {"i": {"prop1": 3, "prop2": "test", "prop3": [1, 2, 3], "prop4": {"id": 1}, "prop5": 1.0, "prop6": 1::numeric}, "j": 4}}::vertex (13 rows) -- test maps in paths @@ -714,37 +714,37 @@ SELECT * FROM cypher('cypher_set', $$MATCH p=(u:begin)-[:edge]->(v:end) return u SELECT * FROM cypher('cypher_set', $$MATCH (n) SET n.i = {} RETURN n$$) AS (a agtype); a -------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": {}, "j": 5, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": {}, "j": 5, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": {}, "j": 5, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": {}, "j": 5, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": {}, "j": 5, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": {}, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": {}, "j": 5, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": {}, "j": 5, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": {}, "j": 5, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": {}, "j": 5, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": {}, "j": 5, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": {}, "j": 5, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": {}, "j": 5, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": {}, "j": 5, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": {}, "j": 5, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": {}, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1688849860263937, "label": "vertices", "properties": {"i": {}, "j": 6, "k": 9}}::vertex - {"id": 1970324836974593, "label": "begin", "properties": {"i": {}, "j": 4}}::vertex {"id": 2533274790395905, "label": "end", "properties": {"i": {}, "j": 3}}::vertex + {"id": 1970324836974593, "label": "begin", "properties": {"i": {}, "j": 4}}::vertex (13 rows) SELECT * FROM cypher('cypher_set', $$MATCH (n) RETURN n$$) AS (a agtype); a -------------------------------------------------------------------------------------------------------------------- - {"id": 281474976710659, "label": "", "properties": {"i": {}, "j": 5, "y": 2}}::vertex - {"id": 281474976710658, "label": "", "properties": {"i": {}, "j": 5, "t": 150, "y": 1}}::vertex - {"id": 281474976710657, "label": "", "properties": {"i": {}, "j": 5, "t": 150}}::vertex - {"id": 844424930131969, "label": "v", "properties": {"i": {}, "j": 5, "t": 150}}::vertex - {"id": 844424930131971, "label": "v", "properties": {"i": {}, "j": 5, "t": 150}}::vertex - {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": {}, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1407374883553281, "label": "other_v", "properties": {"i": {}, "j": 5, "k": 10}}::vertex {"id": 1407374883553282, "label": "other_v", "properties": {"i": {}, "j": 5, "k": 10}}::vertex {"id": 1407374883553283, "label": "other_v", "properties": {"i": {}, "j": 5, "k": 10}}::vertex {"id": 1407374883553284, "label": "other_v", "properties": {"i": {}, "j": 5, "k": 10}}::vertex + {"id": 281474976710659, "label": "", "properties": {"i": {}, "j": 5, "y": 2}}::vertex + {"id": 844424930131969, "label": "v", "properties": {"i": {}, "j": 5, "t": 150}}::vertex + {"id": 844424930131971, "label": "v", "properties": {"i": {}, "j": 5, "t": 150}}::vertex + {"id": 281474976710657, "label": "", "properties": {"i": {}, "j": 5, "t": 150}}::vertex + {"id": 281474976710658, "label": "", "properties": {"i": {}, "j": 5, "t": 150, "y": 1}}::vertex + {"id": 844424930131970, "label": "v", "properties": {"a": 0, "i": {}, "j": 5, "t": 150, "y": 99, "z": 99}}::vertex {"id": 1688849860263937, "label": "vertices", "properties": {"i": {}, "j": 6, "k": 9}}::vertex - {"id": 1970324836974593, "label": "begin", "properties": {"i": {}, "j": 4}}::vertex {"id": 2533274790395905, "label": "end", "properties": {"i": {}, "j": 3}}::vertex + {"id": 1970324836974593, "label": "begin", "properties": {"i": {}, "j": 4}}::vertex (13 rows) -- @@ -821,8 +821,8 @@ SELECT * FROM cypher('cypher_set_1', $$ $$) AS (m agtype); m ----------------------------------------------------------------------------------------------------------------------- - {"id": 1407374883553281, "label": "Kevin", "properties": {"name": "Peter Smith", "position": "Entrepreneur"}}::vertex {"id": 1688849860263937, "label": "Matt", "properties": {"name": "Peter Smith", "position": "Entrepreneur"}}::vertex + {"id": 1407374883553281, "label": "Kevin", "properties": {"name": "Peter Smith", "position": "Entrepreneur"}}::vertex (2 rows) -- test removing all properties using an empty map and = @@ -947,12 +947,12 @@ NOTICE: graph "issue_1634" has been created -- this did not work and was fixed SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map - MERGE (v:PERSION {id: '1'}) + MERGE (v:PERSON {id: '1'}) SET v=map RETURN v,map $$) as (v agtype, map agtype); - v | map ------------------------------------------------------------------------------------------------------+---------------------------------- - {"id": 844424930131969, "label": "PERSION", "properties": {"last": "snow", "first": "jon"}}::vertex | {"last": "snow", "first": "jon"} + v | map +----------------------------------------------------------------------------------------------------+---------------------------------- + {"id": 844424930131969, "label": "PERSON", "properties": {"last": "snow", "first": "jon"}}::vertex | {"last": "snow", "first": "jon"} (1 row) -- these 2 did work and are added as extra tests @@ -962,12 +962,12 @@ SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype); (0 rows) SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map - MERGE (v:PERSION {id: '1'}) + MERGE (v:PERSON {id: '1'}) SET v.first=map.first, v.last=map.last RETURN v,map $$) as (v agtype, map agtype); - v | map -----------------------------------------------------------------------------------------------------------------+---------------------------------- - {"id": 844424930131970, "label": "PERSION", "properties": {"id": "1", "last": "snow", "first": "jon"}}::vertex | {"last": "snow", "first": "jon"} + v | map +---------------------------------------------------------------------------------------------------------------+---------------------------------- + {"id": 844424930131970, "label": "PERSON", "properties": {"id": "1", "last": "snow", "first": "jon"}}::vertex | {"last": "snow", "first": "jon"} (1 row) SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype); @@ -975,12 +975,12 @@ SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype); --- (0 rows) -SELECT * FROM cypher('issue_1634', $$ MERGE (v:PERSION {id: '1'}) +SELECT * FROM cypher('issue_1634', $$ MERGE (v:PERSON {id: '1'}) SET v={first: 'jon', last: 'snow'} RETURN v $$) as (v agtype); - v ------------------------------------------------------------------------------------------------------ - {"id": 844424930131971, "label": "PERSION", "properties": {"last": "snow", "first": "jon"}}::vertex + v +---------------------------------------------------------------------------------------------------- + {"id": 844424930131971, "label": "PERSON", "properties": {"last": "snow", "first": "jon"}}::vertex (1 row) SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype); @@ -1031,7 +1031,7 @@ SELECT drop_graph('issue_1634', true); NOTICE: drop cascades to 3 other objects DETAIL: drop cascades to table issue_1634._ag_label_vertex drop cascades to table issue_1634._ag_label_edge -drop cascades to table issue_1634."PERSION" +drop cascades to table issue_1634."PERSON" NOTICE: graph "issue_1634" has been dropped drop_graph ------------ diff --git a/regress/expected/cypher_subquery.out b/regress/expected/cypher_subquery.out index 456b3a2c9..69511da17 100644 --- a/regress/expected/cypher_subquery.out +++ b/regress/expected/cypher_subquery.out @@ -29,12 +29,12 @@ SELECT * FROM cypher('subquery', $$ MATCH (a) RETURN (a) $$) AS (result agtype); {"id": 844424930131973, "label": "person", "properties": {"age": 34, "name": "Tony"}}::vertex {"id": 844424930131974, "label": "person", "properties": {"age": 33, "name": "Valerie"}}::vertex {"id": 844424930131975, "label": "person", "properties": {"age": 6, "name": "Calvin"}}::vertex + {"id": 1688849860263937, "label": "pet", "properties": {"name": "Hobbes"}}::vertex {"id": 844424930131976, "label": "person", "properties": {"age": 8, "name": "Lucy"}}::vertex {"id": 844424930131977, "label": "person", "properties": {"age": 8, "name": "Charlie"}}::vertex - {"id": 844424930131978, "label": "person", "properties": {"age": 29, "name": "Jon"}}::vertex - {"id": 1688849860263937, "label": "pet", "properties": {"name": "Hobbes"}}::vertex {"id": 1688849860263938, "label": "pet", "properties": {"name": "Snoopy"}}::vertex {"id": 1688849860263939, "label": "pet", "properties": {"name": "Odie"}}::vertex + {"id": 844424930131978, "label": "person", "properties": {"age": 29, "name": "Jon"}}::vertex {"id": 1688849860263940, "label": "pet", "properties": {"name": "Garfield"}}::vertex (14 rows) @@ -239,12 +239,12 @@ SELECT * FROM cypher('subquery', $$ MATCH (a) {"id": 844424930131973, "label": "person", "properties": {"age": 34, "name": "Tony"}}::vertex {"id": 844424930131974, "label": "person", "properties": {"age": 33, "name": "Valerie"}}::vertex {"id": 844424930131975, "label": "person", "properties": {"age": 6, "name": "Calvin"}}::vertex + {"id": 1688849860263937, "label": "pet", "properties": {"name": "Hobbes"}}::vertex {"id": 844424930131976, "label": "person", "properties": {"age": 8, "name": "Lucy"}}::vertex {"id": 844424930131977, "label": "person", "properties": {"age": 8, "name": "Charlie"}}::vertex - {"id": 844424930131978, "label": "person", "properties": {"age": 29, "name": "Jon"}}::vertex - {"id": 1688849860263937, "label": "pet", "properties": {"name": "Hobbes"}}::vertex {"id": 1688849860263938, "label": "pet", "properties": {"name": "Snoopy"}}::vertex {"id": 1688849860263939, "label": "pet", "properties": {"name": "Odie"}}::vertex + {"id": 844424930131978, "label": "person", "properties": {"age": 29, "name": "Jon"}}::vertex {"id": 1688849860263940, "label": "pet", "properties": {"name": "Garfield"}}::vertex (14 rows) @@ -626,14 +626,14 @@ SELECT * FROM cypher('subquery', $$ MATCH (a:person)-[]->(b) a | b | c ------------+------------+--------------------------- "Briggite" | "Takeshi" | "There is a relationship" - "Faye" | "Chan" | "There is a relationship" "Faye" | "Tony" | "There is a relationship" + "Faye" | "Chan" | "There is a relationship" "Tony" | "Valerie" | "There is LOVE!!!!!!" - "Charlie" | "Lucy" | "There is a relationship" "Calvin" | "Hobbes" | "There is a relationship" "Charlie" | "Snoopy" | "There is a relationship" - "Jon" | "Odie" | "There is a relationship" + "Charlie" | "Lucy" | "There is a relationship" "Jon" | "Garfield" | "There is a relationship" + "Jon" | "Odie" | "There is a relationship" (9 rows) -- subqueries in THEN, WHERE @@ -672,9 +672,9 @@ SELECT * FROM cypher('subquery', $$ MATCH (a:person)-[]->(b) RETURN a $$) AS (result agtype); result ------------------------------------------------------------------------------------------------- - {"id": 844424930131977, "label": "person", "properties": {"age": 8, "name": "Charlie"}}::vertex {"id": 844424930131975, "label": "person", "properties": {"age": 6, "name": "Calvin"}}::vertex {"id": 844424930131977, "label": "person", "properties": {"age": 8, "name": "Charlie"}}::vertex + {"id": 844424930131977, "label": "person", "properties": {"age": 8, "name": "Charlie"}}::vertex (3 rows) --coalesce, nested in return @@ -715,12 +715,12 @@ SELECT * FROM cypher('subquery', $$MATCH (a) {"id": 844424930131973, "label": "person", "properties": {"age": 34, "name": "Tony"}}::vertex | false {"id": 844424930131974, "label": "person", "properties": {"age": 33, "name": "Valerie"}}::vertex | false {"id": 844424930131975, "label": "person", "properties": {"age": 6, "name": "Calvin"}}::vertex | false + {"id": 1688849860263937, "label": "pet", "properties": {"name": "Hobbes"}}::vertex | true {"id": 844424930131976, "label": "person", "properties": {"age": 8, "name": "Lucy"}}::vertex | false {"id": 844424930131977, "label": "person", "properties": {"age": 8, "name": "Charlie"}}::vertex | false - {"id": 844424930131978, "label": "person", "properties": {"age": 29, "name": "Jon"}}::vertex | false - {"id": 1688849860263937, "label": "pet", "properties": {"name": "Hobbes"}}::vertex | true {"id": 1688849860263938, "label": "pet", "properties": {"name": "Snoopy"}}::vertex | true {"id": 1688849860263939, "label": "pet", "properties": {"name": "Odie"}}::vertex | true + {"id": 844424930131978, "label": "person", "properties": {"age": 29, "name": "Jon"}}::vertex | false {"id": 1688849860263940, "label": "pet", "properties": {"name": "Garfield"}}::vertex | true (14 rows) @@ -748,12 +748,12 @@ SELECT * FROM cypher('subquery', $$MATCH (a) "Tony" | {"a": false} "Valerie" | {"a": false} "Calvin" | {"a": false} + "Hobbes" | {"a": false} "Lucy" | {"a": false} "Charlie" | {"a": false} - "Jon" | {"a": false} - "Hobbes" | {"a": false} "Snoopy" | {"a": false} "Odie" | {"a": false} + "Jon" | {"a": false} "Garfield" | {"a": false} (14 rows) diff --git a/regress/expected/cypher_vle.out b/regress/expected/cypher_vle.out index 57f930d98..a8e59c09e 100644 --- a/regress/expected/cypher_vle.out +++ b/regress/expected/cypher_vle.out @@ -357,8 +357,8 @@ SELECT * FROM cypher('cypher_vle', $$MATCH p=(u:begin)<-[e*]-(v:end) RETURN e $$ SELECT * FROM cypher('cypher_vle', $$MATCH p=(:begin)<-[*]-()<-[]-(:end) RETURN p $$) AS (e agtype); e ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685252, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1688849860263937, "properties": {"name": "backup edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685252, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1688849860263937, "properties": {"name": "backup edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 1970324836974594, "label": "self_loop", "end_id": 1688849860263937, "start_id": 1688849860263937, "properties": {"name": "self loop", "number": 2, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path + [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685252, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1688849860263937, "properties": {"name": "backup edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path (2 rows) -- Each should return 31 @@ -508,37 +508,37 @@ SELECT * FROM cypher('cypher_vle', $$MATCH p=(u)-[e*0..0]->(v) RETURN id(u), p, SELECT * FROM cypher('cypher_vle', $$MATCH p=()-[*0..0]->()-[]->() RETURN p $$) AS (p agtype); p ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 844424930131969, "label": "begin", "properties": {}}::vertex]::path [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 1125899906842628, "label": "edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "main edge", "number": 1, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path - [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1970324836974593, "label": "self_loop", "end_id": 1407374883553281, "start_id": 1407374883553281, "properties": {"name": "self loop", "number": 1, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 2251799813685249, "label": "alternate_edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "alternate edge", "number": 1, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path - [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842627, "label": "edge", "end_id": 1407374883553282, "start_id": 1407374883553281, "properties": {"name": "main edge", "number": 2, "packages": [2, 4, 6], "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path + [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1970324836974593, "label": "self_loop", "end_id": 1407374883553281, "start_id": 1407374883553281, "properties": {"name": "self loop", "number": 1, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842626, "label": "edge", "end_id": 1407374883553283, "start_id": 1407374883553282, "properties": {"name": "main edge", "number": 3, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685250, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1407374883553282, "properties": {"name": "alternate edge", "number": 2, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path - [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 2251799813685252, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1688849860263937, "properties": {"name": "backup edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path - [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685251, "label": "alternate_edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "alternate edge", "number": 3, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395905, "label": "bypass_edge", "end_id": 1688849860263937, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path - [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 1970324836974594, "label": "self_loop", "end_id": 1688849860263937, "start_id": 1688849860263937, "properties": {"name": "self loop", "number": 2, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path + [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 844424930131969, "label": "begin", "properties": {}}::vertex]::path [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842625, "label": "edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "main edge", "number": 4, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path + [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685251, "label": "alternate_edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "alternate edge", "number": 3, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path + [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path + [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 1970324836974594, "label": "self_loop", "end_id": 1688849860263937, "start_id": 1688849860263937, "properties": {"name": "self loop", "number": 2, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path + [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 2251799813685252, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1688849860263937, "properties": {"name": "backup edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path (13 rows) SELECT * FROM cypher('cypher_vle', $$MATCH p=()-[]->()-[*0..0]->() RETURN p $$) AS (p agtype); p ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842625, "label": "edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "main edge", "number": 4, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path + [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842626, "label": "edge", "end_id": 1407374883553283, "start_id": 1407374883553282, "properties": {"name": "main edge", "number": 3, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path + [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842627, "label": "edge", "end_id": 1407374883553282, "start_id": 1407374883553281, "properties": {"name": "main edge", "number": 2, "packages": [2, 4, 6], "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 1125899906842628, "label": "edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "main edge", "number": 1, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path - [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 2251799813685249, "label": "alternate_edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "alternate edge", "number": 1, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1970324836974593, "label": "self_loop", "end_id": 1407374883553281, "start_id": 1407374883553281, "properties": {"name": "self loop", "number": 1, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path - [{"id": 1407374883553281, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842627, "label": "edge", "end_id": 1407374883553282, "start_id": 1407374883553281, "properties": {"name": "main edge", "number": 2, "packages": [2, 4, 6], "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path - [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842626, "label": "edge", "end_id": 1407374883553283, "start_id": 1407374883553282, "properties": {"name": "main edge", "number": 3, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path + [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 1970324836974594, "label": "self_loop", "end_id": 1688849860263937, "start_id": 1688849860263937, "properties": {"name": "self loop", "number": 2, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path + [{"id": 844424930131969, "label": "begin", "properties": {}}::vertex, {"id": 2251799813685249, "label": "alternate_edge", "end_id": 1407374883553281, "start_id": 844424930131969, "properties": {"name": "alternate edge", "number": 1, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553281, "label": "middle", "properties": {}}::vertex]::path [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685250, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1407374883553282, "properties": {"name": "alternate edge", "number": 2, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path - [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395905, "label": "bypass_edge", "end_id": 1688849860263937, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path - [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 844424930131969, "label": "begin", "properties": {}}::vertex]::path - [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 1125899906842625, "label": "edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "main edge", "number": 4, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685251, "label": "alternate_edge", "end_id": 1688849860263937, "start_id": 1407374883553283, "properties": {"name": "alternate edge", "number": 3, "packages": [2, 4, 6], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path - [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 2251799813685252, "label": "alternate_edge", "end_id": 1407374883553283, "start_id": 1688849860263937, "properties": {"name": "backup edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553283, "label": "middle", "properties": {}}::vertex]::path - [{"id": 1688849860263937, "label": "end", "properties": {}}::vertex, {"id": 1970324836974594, "label": "self_loop", "end_id": 1688849860263937, "start_id": 1688849860263937, "properties": {"name": "self loop", "number": 2, "dangerous": {"type": "all", "level": "all"}}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path + [{"id": 1407374883553283, "label": "middle", "properties": {}}::vertex, {"id": 2251799813685253, "label": "alternate_edge", "end_id": 1407374883553282, "start_id": 1407374883553283, "properties": {"name": "backup edge", "number": 2, "packages": [1, 3, 5, 7]}}::edge, {"id": 1407374883553282, "label": "middle", "properties": {}}::vertex]::path + [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395905, "label": "bypass_edge", "end_id": 1688849860263937, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 1, "packages": [1, 3, 5, 7]}}::edge, {"id": 1688849860263937, "label": "end", "properties": {}}::vertex]::path + [{"id": 1407374883553282, "label": "middle", "properties": {}}::vertex, {"id": 2533274790395906, "label": "bypass_edge", "end_id": 844424930131969, "start_id": 1407374883553282, "properties": {"name": "bypass edge", "number": 2, "packages": [1, 3, 5, 7], "dangerous": {"type": "poisons", "level": "all"}}}::edge, {"id": 844424930131969, "label": "begin", "properties": {}}::vertex]::path (13 rows) -- @@ -726,8 +726,8 @@ SELECT prepend_node('list01', 'b'); SELECT * FROM show_list_use_vle('list01'); node ----------------------------------------------------------------------------------- - {"id": 1407374883553282, "label": "node", "properties": {"content": "b"}}::vertex {"id": 1407374883553281, "label": "node", "properties": {"content": "a"}}::vertex + {"id": 1407374883553282, "label": "node", "properties": {"content": "b"}}::vertex (2 rows) -- prepend a node 'c' @@ -741,9 +741,9 @@ SELECT prepend_node('list01', 'c'); SELECT * FROM show_list_use_vle('list01'); node ----------------------------------------------------------------------------------- - {"id": 1407374883553283, "label": "node", "properties": {"content": "c"}}::vertex - {"id": 1407374883553282, "label": "node", "properties": {"content": "b"}}::vertex {"id": 1407374883553281, "label": "node", "properties": {"content": "a"}}::vertex + {"id": 1407374883553282, "label": "node", "properties": {"content": "b"}}::vertex + {"id": 1407374883553283, "label": "node", "properties": {"content": "c"}}::vertex (3 rows) DROP FUNCTION show_list_use_vle; diff --git a/regress/expected/expr.out b/regress/expected/expr.out index 926a958d6..6c2fe17c6 100644 --- a/regress/expected/expr.out +++ b/regress/expected/expr.out @@ -6788,8 +6788,8 @@ SELECT * FROM cypher('group_by', $$MATCH (u:row) RETURN u.i, u.j, sum(u.k)$$) AS i | j | sumk ---+---+------ 1 | 2 | 7 - 2 | 3 | 6 1 | 3 | 5 + 2 | 3 | 6 (3 rows) SELECT * FROM cypher('group_by', $$CREATE (:L {a: 1, b: 2, c:3})$$) AS (result agtype); @@ -6811,9 +6811,9 @@ SELECT * FROM cypher('group_by', $$MATCH (x:L) RETURN x.a, x.b, x.c, x.a + count AS (a agtype, b agtype, c agtype, result agtype); a | b | c | result ---+---+---+-------- - 3 | 1 | 2 | 8 - 2 | 3 | 1 | 8 1 | 2 | 3 | 8 + 2 | 3 | 1 | 8 + 3 | 1 | 2 | 8 (3 rows) SELECT * FROM cypher('group_by', $$MATCH (x:L) RETURN x.a + x.b + x.c, x.a + x.b + x.c + count(*) + count(*) $$) diff --git a/regress/expected/graph_generation.out b/regress/expected/graph_generation.out index ca511eafa..3cf837fc1 100644 --- a/regress/expected/graph_generation.out +++ b/regress/expected/graph_generation.out @@ -33,7 +33,8 @@ SELECT COUNT(*) FROM gp1."edges"; 10 (1 row) -SELECT COUNT(*) FROM gp1."vertices"; +SELECT COUNT(*) FROM gp1._ag_label_vertex +WHERE labels = 'gp1."vertices"'::regclass::oid; count ------- 5 @@ -44,12 +45,12 @@ SELECT * FROM cypher('gp1', $$MATCH (a)-[e]->(b) RETURN e$$) as (n agtype); ---------------------------------------------------------------------------------------------------------------------------- {"id": 1125899906842625, "label": "edges", "end_id": 844424930131970, "start_id": 844424930131969, "properties": {}}::edge {"id": 1125899906842626, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131969, "properties": {}}::edge - {"id": 1125899906842629, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131970, "properties": {}}::edge {"id": 1125899906842627, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131969, "properties": {}}::edge - {"id": 1125899906842630, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131970, "properties": {}}::edge - {"id": 1125899906842632, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131971, "properties": {}}::edge {"id": 1125899906842628, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131969, "properties": {}}::edge + {"id": 1125899906842629, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131970, "properties": {}}::edge + {"id": 1125899906842630, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131970, "properties": {}}::edge {"id": 1125899906842631, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131970, "properties": {}}::edge + {"id": 1125899906842632, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131971, "properties": {}}::edge {"id": 1125899906842633, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131971, "properties": {}}::edge {"id": 1125899906842634, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131972, "properties": {}}::edge (10 rows) @@ -66,7 +67,8 @@ SELECT COUNT(*) FROM gp1."edges"; 20 (1 row) -SELECT COUNT(*) FROM gp1."vertices"; +SELECT COUNT(*) FROM gp1._ag_label_vertex +WHERE labels = 'gp1."vertices"'::regclass::oid; count ------- 10 @@ -130,7 +132,8 @@ SELECT COUNT(*) FROM gp1."edges"; 21 (1 row) -SELECT COUNT(*) FROM gp1."vertices"; +SELECT COUNT(*) FROM gp1._ag_label_vertex +WHERE labels = 'gp1."vertices"'::regclass::oid; count ------- 10 @@ -141,22 +144,22 @@ SELECT * FROM cypher('gp1', $$MATCH (a)-[e]->(b) RETURN e$$) as (n agtype); ---------------------------------------------------------------------------------------------------------------------------- {"id": 1125899906842625, "label": "edges", "end_id": 844424930131970, "start_id": 844424930131969, "properties": {}}::edge {"id": 1125899906842626, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131969, "properties": {}}::edge - {"id": 1125899906842629, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131970, "properties": {}}::edge {"id": 1125899906842627, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131969, "properties": {}}::edge - {"id": 1125899906842630, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131970, "properties": {}}::edge - {"id": 1125899906842632, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131971, "properties": {}}::edge {"id": 1125899906842628, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131969, "properties": {}}::edge + {"id": 1125899906842629, "label": "edges", "end_id": 844424930131971, "start_id": 844424930131970, "properties": {}}::edge + {"id": 1125899906842630, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131970, "properties": {}}::edge {"id": 1125899906842631, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131970, "properties": {}}::edge + {"id": 1125899906842632, "label": "edges", "end_id": 844424930131972, "start_id": 844424930131971, "properties": {}}::edge {"id": 1125899906842633, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131971, "properties": {}}::edge {"id": 1125899906842634, "label": "edges", "end_id": 844424930131973, "start_id": 844424930131972, "properties": {}}::edge {"id": 1125899906842635, "label": "edges", "end_id": 844424930131975, "start_id": 844424930131974, "properties": {}}::edge {"id": 1125899906842636, "label": "edges", "end_id": 844424930131976, "start_id": 844424930131974, "properties": {}}::edge - {"id": 1125899906842639, "label": "edges", "end_id": 844424930131976, "start_id": 844424930131975, "properties": {}}::edge {"id": 1125899906842637, "label": "edges", "end_id": 844424930131977, "start_id": 844424930131974, "properties": {}}::edge - {"id": 1125899906842640, "label": "edges", "end_id": 844424930131977, "start_id": 844424930131975, "properties": {}}::edge - {"id": 1125899906842642, "label": "edges", "end_id": 844424930131977, "start_id": 844424930131976, "properties": {}}::edge {"id": 1125899906842638, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131974, "properties": {}}::edge + {"id": 1125899906842639, "label": "edges", "end_id": 844424930131976, "start_id": 844424930131975, "properties": {}}::edge + {"id": 1125899906842640, "label": "edges", "end_id": 844424930131977, "start_id": 844424930131975, "properties": {}}::edge {"id": 1125899906842641, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131975, "properties": {}}::edge + {"id": 1125899906842642, "label": "edges", "end_id": 844424930131977, "start_id": 844424930131976, "properties": {}}::edge {"id": 1125899906842643, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131976, "properties": {}}::edge {"id": 1125899906842644, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131977, "properties": {}}::edge {"id": 1125899906842645, "label": "edges", "end_id": 844424930131978, "start_id": 844424930131969, "properties": {}}::edge @@ -174,7 +177,8 @@ SELECT COUNT(*) FROM gp1."edges"; 42 (1 row) -SELECT COUNT(*) FROM gp1."vertices"; +SELECT COUNT(*) FROM gp1._ag_label_vertex +WHERE labels = 'gp1."vertices"'::regclass::oid; count ------- 20 diff --git a/regress/expected/index.out b/regress/expected/index.out index 3ed7b1c33..ae29cc2ae 100644 --- a/regress/expected/index.out +++ b/regress/expected/index.out @@ -41,7 +41,8 @@ NOTICE: VLabel "idx" has been created (1 row) -CREATE UNIQUE INDEX cypher_index_idx_props_uq ON cypher_index.idx(properties); +CREATE UNIQUE INDEX cypher_index_idx_props_uq ON cypher_index._ag_label_vertex(properties) +WHERE labels = 'cypher_index.idx'::regclass::oid; --Test 1 SELECT * FROM cypher('cypher_index', $$ CREATE (:idx {i: 1}) $$) AS (a agtype); a @@ -266,14 +267,14 @@ $$) as (n agtype); -- Verify that the incices are created on id columns SELECT indexname, indexdef FROM pg_indexes WHERE schemaname= 'cypher_index'; - indexname | indexdef ------------------------------+------------------------------------------------------------------------------------------------ + indexname | indexdef +-----------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------- _ag_label_edge_pkey | CREATE UNIQUE INDEX _ag_label_edge_pkey ON cypher_index._ag_label_edge USING btree (id) _ag_label_edge_start_id_idx | CREATE INDEX _ag_label_edge_start_id_idx ON cypher_index._ag_label_edge USING btree (start_id) _ag_label_edge_end_id_idx | CREATE INDEX _ag_label_edge_end_id_idx ON cypher_index._ag_label_edge USING btree (end_id) _ag_label_vertex_pkey | CREATE UNIQUE INDEX _ag_label_vertex_pkey ON cypher_index._ag_label_vertex USING btree (id) + cypher_index_idx_props_uq | CREATE UNIQUE INDEX cypher_index_idx_props_uq ON cypher_index._ag_label_vertex USING btree (properties) WHERE (labels = ('cypher_index.idx'::regclass)::oid) idx_pkey | CREATE UNIQUE INDEX idx_pkey ON cypher_index.idx USING btree (id) - cypher_index_idx_props_uq | CREATE UNIQUE INDEX cypher_index_idx_props_uq ON cypher_index.idx USING btree (properties) Country_pkey | CREATE UNIQUE INDEX "Country_pkey" ON cypher_index."Country" USING btree (id) has_city_start_id_idx | CREATE INDEX has_city_start_id_idx ON cypher_index.has_city USING btree (start_id) has_city_end_id_idx | CREATE INDEX has_city_end_id_idx ON cypher_index.has_city USING btree (end_id) @@ -296,24 +297,20 @@ SELECT COUNT(*) FROM cypher('cypher_index', $$ EXPLAIN (costs off) MATCH (a:Country)<-[e:has_city]-() RETURN e $$) as (n agtype); - QUERY PLAN ----------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------- Aggregate -> Merge Join - Merge Cond: (_age_default_alias_0.id = e.start_id) - -> Merge Append - Sort Key: _age_default_alias_0.id - -> Index Only Scan using _ag_label_vertex_pkey on _ag_label_vertex _age_default_alias_0_1 - -> Index Only Scan using idx_pkey on idx _age_default_alias_0_2 - -> Index Only Scan using "Country_pkey" on "Country" _age_default_alias_0_3 - -> Index Only Scan using "City_pkey" on "City" _age_default_alias_0_4 + Merge Cond: (e.start_id = _age_default_alias_0.id) -> Sort Sort Key: e.start_id -> Merge Join Merge Cond: (a.id = e.end_id) - -> Index Only Scan using "Country_pkey" on "Country" a + -> Index Scan using _ag_label_vertex_pkey on _ag_label_vertex a + Filter: (labels = '22544'::oid) -> Index Scan using has_city_end_id_idx on has_city e -(15 rows) + -> Index Only Scan using _ag_label_vertex_pkey on _ag_label_vertex _age_default_alias_0 +(11 rows) SET enable_mergejoin = OFF; SET enable_hashjoin = ON; @@ -331,23 +328,20 @@ SELECT COUNT(*) FROM cypher('cypher_index', $$ EXPLAIN (costs off) MATCH (a:Country)<-[e:has_city]-() RETURN e $$) as (n agtype); - QUERY PLAN ----------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------- Aggregate -> Hash Join - Hash Cond: (_age_default_alias_0.id = e.start_id) - -> Append - -> Index Only Scan using _ag_label_vertex_pkey on _ag_label_vertex _age_default_alias_0_1 - -> Index Only Scan using idx_pkey on idx _age_default_alias_0_2 - -> Index Only Scan using "Country_pkey" on "Country" _age_default_alias_0_3 - -> Index Only Scan using "City_pkey" on "City" _age_default_alias_0_4 + Hash Cond: (e.start_id = _age_default_alias_0.id) + -> Hash Join + Hash Cond: (e.end_id = a.id) + -> Index Scan using has_city_end_id_idx on has_city e + -> Hash + -> Index Scan using _ag_label_vertex_pkey on _ag_label_vertex a + Filter: (labels = '22544'::oid) -> Hash - -> Hash Join - Hash Cond: (e.end_id = a.id) - -> Index Scan using has_city_end_id_idx on has_city e - -> Hash - -> Index Only Scan using "Country_pkey" on "Country" a -(14 rows) + -> Index Only Scan using _ag_label_vertex_pkey on _ag_label_vertex _age_default_alias_0 +(11 rows) SET enable_mergejoin = OFF; SET enable_hashjoin = OFF; @@ -356,24 +350,20 @@ SELECT COUNT(*) FROM cypher('cypher_index', $$ EXPLAIN (costs off) MATCH (a:Country)<-[e:has_city]-() RETURN e $$) as (n agtype); - QUERY PLAN ----------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------- Aggregate -> Nested Loop -> Nested Loop - -> Index Scan using has_city_start_id_idx on has_city e - -> Index Only Scan using "Country_pkey" on "Country" a - Index Cond: (id = e.end_id) - -> Append - -> Index Only Scan using _ag_label_vertex_pkey on _ag_label_vertex _age_default_alias_0_1 - Index Cond: (id = e.start_id) - -> Index Only Scan using idx_pkey on idx _age_default_alias_0_2 - Index Cond: (id = e.start_id) - -> Index Only Scan using "Country_pkey" on "Country" _age_default_alias_0_3 - Index Cond: (id = e.start_id) - -> Index Only Scan using "City_pkey" on "City" _age_default_alias_0_4 - Index Cond: (id = e.start_id) -(15 rows) + -> Index Scan using _ag_label_vertex_pkey on _ag_label_vertex a + Filter: (labels = '22544'::oid) + -> Bitmap Heap Scan on has_city e + Recheck Cond: (end_id = a.id) + -> Bitmap Index Scan on has_city_end_id_idx + Index Cond: (end_id = a.id) + -> Index Only Scan using _ag_label_vertex_pkey on _ag_label_vertex _age_default_alias_0 + Index Cond: (id = e.start_id) +(11 rows) SET enable_mergejoin = ON; SET enable_hashjoin = ON; @@ -382,9 +372,11 @@ SET enable_nestloop = ON; -- Section 3: Agtype GIN Indices to Improve WHERE clause Performance -- CREATE INDEX load_city_gin_idx -ON cypher_index."City" USING gin (properties); +ON cypher_index._ag_label_vertex USING gin (properties) +WHERE labels = 'cypher_index."City"'::regclass::oid; CREATE INDEX load_country_gin_idx -ON cypher_index."Country" USING gin (properties); +ON cypher_index._ag_label_vertex USING gin (properties) +WHERE labels = 'cypher_index."Country"'::regclass::oid; SELECT * FROM cypher('cypher_index', $$ MATCH (c:City {city_id: 1}) RETURN c @@ -451,8 +443,9 @@ $$) as (n agtype); 0 (1 row) -CREATE INDEX CONCURRENTLY cntry_ode_idx ON cypher_index."City" -(ag_catalog.agtype_access_operator(properties, '"country_code"'::agtype)); +CREATE INDEX CONCURRENTLY cntry_ode_idx ON cypher_index._ag_label_vertex +(ag_catalog.agtype_access_operator(properties, '"country_code"'::agtype)) +WHERE labels = 'cypher_index."City"'::regclass::oid; SELECT COUNT(*) FROM cypher('agload_test_graph', $$ MATCH (a:City) WHERE a.country_code = 'RS' diff --git a/regress/expected/list_comprehension.out b/regress/expected/list_comprehension.out index 5a3756422..2b788c401 100644 --- a/regress/expected/list_comprehension.out +++ b/regress/expected/list_comprehension.out @@ -631,8 +631,8 @@ SELECT * FROM cypher('list_comprehension', $$ MATCH (u) WHERE u.list=[i IN u.lis {"id": 281474976710661, "label": "", "properties": {"list": [6, 8, 10, 12]}}::vertex {"id": 281474976710662, "label": "", "properties": {"list": [25.0, 49.0, 81.0, 121.0, 169.0]}}::vertex {"id": 281474976710663, "label": "", "properties": {"list": [1, 2, 3]}}::vertex - {"id": 281474976710657, "label": "", "properties": {"a": [], "b": [0, 1, 2, 3, 4, 5], "c": [0, 2, 4, 6, 8, 10, 12], "list": [0, 2, 4, 6, 8, 10, 12]}}::vertex {"id": 844424930131969, "label": "csm_match", "properties": {"list": ["abc", "def", "ghi"]}}::vertex + {"id": 281474976710657, "label": "", "properties": {"a": [], "b": [0, 1, 2, 3, 4, 5], "c": [0, 2, 4, 6, 8, 10, 12], "list": [0, 2, 4, 6, 8, 10, 12]}}::vertex (8 rows) SELECT * FROM cypher('list_comprehension', $$ MATCH (u) WHERE u.list=[i IN u.list WHERE i>0] RETURN u $$) AS (result agtype); diff --git a/regress/expected/pgvector.out b/regress/expected/pgvector.out index bbc558349..2171b58f9 100644 --- a/regress/expected/pgvector.out +++ b/regress/expected/pgvector.out @@ -572,11 +572,11 @@ BEGIN WHERE name = 'graph'; EXECUTE format($f$ - CREATE INDEX movie_vector_idx ON graph."Movie" + CREATE INDEX movie_vector_idx ON graph._ag_label_vertex USING hnsw ((( agtype_access_operator( VARIADIC ARRAY[ - _agtype_build_vertex(id, _label_name(%L::oid, id), properties), + _agtype_build_vertex(id, _label_name_from_table_oid(labels), properties), '"embedding"'::agtype ] )::text @@ -650,11 +650,11 @@ BEGIN WHERE name = 'graph'; EXECUTE format($f$ - CREATE INDEX movie_vector_idx ON graph."Movie" + CREATE INDEX movie_vector_idx ON graph._ag_label_vertex USING hnsw (( agtype_access_operator( VARIADIC ARRAY[ - _agtype_build_vertex(id, _label_name(%L::oid, id), properties), + _agtype_build_vertex(id, _label_name_from_table_oid(labels), properties), '"embedding"'::agtype ] )::vector(4)) vector_cosine_ops); diff --git a/regress/expected/unified_vertex_table.out b/regress/expected/unified_vertex_table.out new file mode 100644 index 000000000..38fac52f4 --- /dev/null +++ b/regress/expected/unified_vertex_table.out @@ -0,0 +1,419 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +-- +-- Regression tests for the unified vertex table architecture +-- +-- Tests verify: +-- 1. Labels column correctly stores label table OID +-- 2. Label retrieval from labels column works correctly +-- 3. Multiple labels coexist in single table +-- 4. startNode/endNode correctly retrieve vertex labels +-- 5. VLE correctly handles label retrieval +-- +LOAD 'age'; +SET search_path TO ag_catalog; +-- +-- Test 1: Basic unified table structure verification +-- +SELECT create_graph('unified_test'); +NOTICE: graph "unified_test" has been created + create_graph +-------------- + +(1 row) + +-- Create vertices with different labels +SELECT * FROM cypher('unified_test', $$ + CREATE (:Person {name: 'Alice'}) +$$) AS (v agtype); + v +--- +(0 rows) + +SELECT * FROM cypher('unified_test', $$ + CREATE (:Company {name: 'Acme Corp'}) +$$) AS (v agtype); + v +--- +(0 rows) + +SELECT * FROM cypher('unified_test', $$ + CREATE (:Location {name: 'Seattle'}) +$$) AS (v agtype); + v +--- +(0 rows) + +-- Verify all vertices are in the unified table +SELECT COUNT(*) AS vertex_count FROM unified_test._ag_label_vertex; + vertex_count +-------------- + 3 +(1 row) + +-- Verify labels column contains different OIDs for different labels +SELECT COUNT(DISTINCT labels) AS distinct_label_count FROM unified_test._ag_label_vertex; + distinct_label_count +---------------------- + 3 +(1 row) + +-- Verify we can filter by label using the labels column +SELECT id, properties FROM unified_test._ag_label_vertex +WHERE labels = 'unified_test."Person"'::regclass::oid; + id | properties +-----------------+------------------- + 844424930131969 | {"name": "Alice"} +(1 row) + +SELECT id, properties FROM unified_test._ag_label_vertex +WHERE labels = 'unified_test."Company"'::regclass::oid; + id | properties +------------------+----------------------- + 1125899906842625 | {"name": "Acme Corp"} +(1 row) + +SELECT id, properties FROM unified_test._ag_label_vertex +WHERE labels = 'unified_test."Location"'::regclass::oid; + id | properties +------------------+--------------------- + 1407374883553281 | {"name": "Seattle"} +(1 row) + +-- +-- Test 2: Label retrieval via Cypher MATCH +-- +SELECT * FROM cypher('unified_test', $$ + MATCH (p:Person) RETURN p.name ORDER BY p.name +$$) AS (name agtype); + name +--------- + "Alice" +(1 row) + +SELECT * FROM cypher('unified_test', $$ + MATCH (c:Company) RETURN c.name ORDER BY c.name +$$) AS (name agtype); + name +------------- + "Acme Corp" +(1 row) + +SELECT * FROM cypher('unified_test', $$ + MATCH (n) RETURN labels(n), n.name ORDER BY n.name +$$) AS (label agtype, name agtype); + label | name +--------------+------------- + ["Company"] | "Acme Corp" + ["Person"] | "Alice" + ["Location"] | "Seattle" +(3 rows) + +-- +-- Test 3: startNode/endNode label retrieval +-- +SELECT * FROM cypher('unified_test', $$ + CREATE (:Person {name: 'Bob'})-[:WORKS_AT]->(:Company {name: 'Tech Inc'}) +$$) AS (v agtype); + v +--- +(0 rows) + +SELECT * FROM cypher('unified_test', $$ + CREATE (:Person {name: 'Carol'})-[:LIVES_IN]->(:Location {name: 'Portland'}) +$$) AS (v agtype); + v +--- +(0 rows) + +-- Verify startNode returns correct label +SELECT * FROM cypher('unified_test', $$ + MATCH ()-[e:WORKS_AT]->() + RETURN startNode(e).name AS employee, label(startNode(e)) AS emp_label, + endNode(e).name AS company, label(endNode(e)) AS comp_label +$$) AS (employee agtype, emp_label agtype, company agtype, comp_label agtype); + employee | emp_label | company | comp_label +----------+-----------+------------+------------ + "Bob" | "Person" | "Tech Inc" | "Company" +(1 row) + +SELECT * FROM cypher('unified_test', $$ + MATCH ()-[e:LIVES_IN]->() + RETURN startNode(e).name AS person, label(startNode(e)) AS person_label, + endNode(e).name AS location, label(endNode(e)) AS loc_label +$$) AS (person agtype, person_label agtype, location agtype, loc_label agtype); + person | person_label | location | loc_label +---------+--------------+------------+------------ + "Carol" | "Person" | "Portland" | "Location" +(1 row) + +-- +-- Test 4: Unlabeled vertices (default vertex label) +-- +SELECT * FROM cypher('unified_test', $$ + CREATE ({type: 'unlabeled_1'}) +$$) AS (v agtype); + v +--- +(0 rows) + +SELECT * FROM cypher('unified_test', $$ + CREATE ({type: 'unlabeled_2'}) +$$) AS (v agtype); + v +--- +(0 rows) + +-- Verify unlabeled vertices have empty string label +SELECT * FROM cypher('unified_test', $$ + MATCH (n) WHERE n.type IS NOT NULL + RETURN n.type, label(n) ORDER BY n.type +$$) AS (type agtype, label agtype); + type | label +---------------+------- + "unlabeled_1" | "" + "unlabeled_2" | "" +(2 rows) + +-- Verify labels column for default vertices points to unified table +SELECT COUNT(*) AS unlabeled_count FROM unified_test._ag_label_vertex +WHERE labels = 'unified_test._ag_label_vertex'::regclass::oid; + unlabeled_count +----------------- + 2 +(1 row) + +-- +-- Test 5: Mixed label queries (MATCH without label) +-- +SELECT * FROM cypher('unified_test', $$ + MATCH (n) + RETURN label(n), count(*) AS cnt + ORDER BY label(n) +$$) AS (label agtype, cnt agtype); + label | cnt +------------+----- + "" | 2 + "Company" | 2 + "Location" | 2 + "Person" | 3 +(4 rows) + +-- +-- Test 6: Label with SET operations +-- +SELECT * FROM cypher('unified_test', $$ + MATCH (p:Person {name: 'Alice'}) + SET p.age = 30 + RETURN p.name, p.age, label(p) +$$) AS (name agtype, age agtype, label agtype); + name | age | label +---------+-----+---------- + "Alice" | 30 | "Person" +(1 row) + +-- Verify label is preserved after SET +SELECT * FROM cypher('unified_test', $$ + MATCH (p:Person {name: 'Alice'}) + RETURN label(p) +$$) AS (label agtype); + label +---------- + "Person" +(1 row) + +-- +-- Test 7: MERGE with labels +-- +SELECT * FROM cypher('unified_test', $$ + MERGE (d:Department {name: 'Engineering'}) + RETURN d.name, label(d) +$$) AS (name agtype, label agtype); + name | label +---------------+-------------- + "Engineering" | "Department" +(1 row) + +SELECT * FROM cypher('unified_test', $$ + MERGE (d:Department {name: 'Engineering'}) + RETURN d.name, label(d) +$$) AS (name agtype, label agtype); + name | label +---------------+-------------- + "Engineering" | "Department" +(1 row) + +-- Verify only one Department vertex exists +SELECT * FROM cypher('unified_test', $$ + MATCH (d:Department) + RETURN count(d) +$$) AS (cnt agtype); + cnt +----- + 1 +(1 row) + +-- +-- Test 8: DELETE preserves labels column integrity +-- +SELECT * FROM cypher('unified_test', $$ + CREATE (:Temporary {id: 1}) +$$) AS (v agtype); + v +--- +(0 rows) + +SELECT * FROM cypher('unified_test', $$ + CREATE (:Temporary {id: 2}) +$$) AS (v agtype); + v +--- +(0 rows) + +-- Verify vertices exist +SELECT * FROM cypher('unified_test', $$ + MATCH (t:Temporary) + RETURN t.id ORDER BY t.id +$$) AS (id agtype); + id +---- + 1 + 2 +(2 rows) + +-- Delete one +SELECT * FROM cypher('unified_test', $$ + MATCH (t:Temporary {id: 1}) + DELETE t +$$) AS (v agtype); + v +--- +(0 rows) + +-- Verify remaining vertex still has correct label +SELECT * FROM cypher('unified_test', $$ + MATCH (t:Temporary) + RETURN t.id, label(t) +$$) AS (id agtype, label agtype); + id | label +----+------------- + 2 | "Temporary" +(1 row) + +-- +-- Test 9: VLE with label retrieval +-- +SELECT * FROM cypher('unified_test', $$ + CREATE (:Node {name: 'a'})-[:CONNECTED]->(:Node {name: 'b'})-[:CONNECTED]->(:Node {name: 'c'}) +$$) AS (v agtype); + v +--- +(0 rows) + +-- Test that VLE path returns vertices with correct labels +SELECT * FROM cypher('unified_test', $$ + MATCH p = (n:Node {name: 'a'})-[:CONNECTED*1..2]->(m) + RETURN label(n), label(m) + ORDER BY label(m) +$$) AS (start_label agtype, end_label agtype); + start_label | end_label +-------------+----------- + "Node" | "Node" + "Node" | "Node" +(2 rows) + +-- +-- Test 10: _label_name_from_table_oid function +-- +-- Get a label table OID and verify function works +SELECT ag_catalog._label_name_from_table_oid('unified_test."Person"'::regclass::oid); + _label_name_from_table_oid +---------------------------- + Person +(1 row) + +SELECT ag_catalog._label_name_from_table_oid('unified_test."Company"'::regclass::oid); + _label_name_from_table_oid +---------------------------- + Company +(1 row) + +SELECT ag_catalog._label_name_from_table_oid('unified_test."Location"'::regclass::oid); + _label_name_from_table_oid +---------------------------- + Location +(1 row) + +-- +-- Test 11: Verify all labels coexist in unified table with distinct OIDs +-- +SELECT * FROM cypher('unified_test', $$ + CREATE (:LabelA {val: 1}) +$$) AS (v agtype); + v +--- +(0 rows) + +SELECT * FROM cypher('unified_test', $$ + CREATE (:LabelB {val: 2}) +$$) AS (v agtype); + v +--- +(0 rows) + +SELECT * FROM cypher('unified_test', $$ + CREATE (:LabelC {val: 3}) +$$) AS (v agtype); + v +--- +(0 rows) + +-- Verify all have distinct label OIDs (count should equal 3) +SELECT COUNT(DISTINCT labels) AS distinct_labels FROM unified_test._ag_label_vertex +WHERE properties::text LIKE '%val%'; + distinct_labels +----------------- + 3 +(1 row) + +-- +-- Cleanup +-- +SELECT drop_graph('unified_test', true); +NOTICE: drop cascades to 14 other objects +DETAIL: drop cascades to table unified_test._ag_label_vertex +drop cascades to table unified_test._ag_label_edge +drop cascades to table unified_test."Person" +drop cascades to table unified_test."Company" +drop cascades to table unified_test."Location" +drop cascades to table unified_test."WORKS_AT" +drop cascades to table unified_test."LIVES_IN" +drop cascades to table unified_test."Department" +drop cascades to table unified_test."Temporary" +drop cascades to table unified_test."Node" +drop cascades to table unified_test."CONNECTED" +drop cascades to table unified_test."LabelA" +drop cascades to table unified_test."LabelB" +drop cascades to table unified_test."LabelC" +NOTICE: graph "unified_test" has been dropped + drop_graph +------------ + +(1 row) + diff --git a/regress/sql/age_global_graph.sql b/regress/sql/age_global_graph.sql index acd95fbf0..ea99d713f 100644 --- a/regress/sql/age_global_graph.sql +++ b/regress/sql/age_global_graph.sql @@ -115,11 +115,11 @@ SELECT * FROM cypher('ag_graph_1', $$ MATCH (u)-[e]->(v) RETURN u, e, v $$) AS ( -- what is there now? SELECT * FROM cypher('ag_graph_1', $$ RETURN graph_stats('ag_graph_1') $$) AS (result agtype); -- remove some vertices -SELECT * FROM ag_graph_1._ag_label_vertex; +SELECT id, properties FROM ag_graph_1._ag_label_vertex order by id; DELETE FROM ag_graph_1._ag_label_vertex WHERE id::text = '281474976710661'; DELETE FROM ag_graph_1._ag_label_vertex WHERE id::text = '281474976710662'; DELETE FROM ag_graph_1._ag_label_vertex WHERE id::text = '281474976710664'; -SELECT * FROM ag_graph_1._ag_label_vertex; +SELECT id, properties FROM ag_graph_1._ag_label_vertex order by id; SELECT * FROM ag_graph_1._ag_label_edge; -- there should be warning messages SELECT * FROM cypher('ag_graph_1', $$ RETURN graph_stats('ag_graph_1') $$) AS (result agtype); diff --git a/regress/sql/age_load.sql b/regress/sql/age_load.sql index cefcfb4ca..5dda7c7c0 100644 --- a/regress/sql/age_load.sql +++ b/regress/sql/age_load.sql @@ -81,8 +81,10 @@ SELECT table_catalog, table_schema, lower(table_name) as table_name, table_type FROM information_schema.tables WHERE table_schema = 'agload_test_graph' ORDER BY table_name ASC; -SELECT COUNT(*) FROM agload_test_graph."Country"; -SELECT COUNT(*) FROM agload_test_graph."City"; +SELECT COUNT(*) FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."Country"'::regclass::oid; +SELECT COUNT(*) FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."City"'::regclass::oid; SELECT COUNT(*) FROM agload_test_graph."has_city"; SELECT COUNT(*) FROM cypher('agload_test_graph', $$MATCH(n) RETURN n$$) as (n agtype); @@ -105,31 +107,36 @@ SELECT create_vlabel('agload_test_graph','City2'); SELECT load_labels_from_file('agload_test_graph', 'City2', 'age_load/cities.csv', false); -SELECT COUNT(*) FROM agload_test_graph."Country2"; -SELECT COUNT(*) FROM agload_test_graph."City2"; +SELECT COUNT(*) FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."Country2"'::regclass::oid; +SELECT COUNT(*) FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."City2"'::regclass::oid; -SELECT id FROM agload_test_graph."Country" LIMIT 10; -SELECT id FROM agload_test_graph."Country2" LIMIT 10; +SELECT id FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."Country"'::regclass::oid LIMIT 10; +SELECT id FROM agload_test_graph._ag_label_vertex +WHERE labels = 'agload_test_graph."Country2"'::regclass::oid LIMIT 10; -- Should return 2 rows for Country with same properties, but different ids SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country {iso2 : 'BE'}) - RETURN id(n), n.name, n.iso2 $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); + RETURN id(n), n.name, n.iso2 ORDER BY id(n) $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); -- Should return 1 row SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country2 {iso2 : 'BE'}) - RETURN id(n), n.name, n.iso2 $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); + RETURN id(n), n.name, n.iso2 ORDER BY id(n) $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); -- Should return 2 rows for Country with same properties, but different ids SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country {iso2 : 'AT'}) - RETURN id(n), n.name, n.iso2 $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); + RETURN id(n), n.name, n.iso2 ORDER BY id(n) $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); -- Should return 1 row SELECT * FROM cypher('agload_test_graph', $$MATCH(n:Country2 {iso2 : 'AT'}) - RETURN id(n), n.name, n.iso2 $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); + RETURN id(n), n.name, n.iso2 ORDER BY id(n) $$) as ("id(n)" agtype, "n.name" agtype, "n.iso2" agtype); -- Should return 2 rows for Country with same properties, but different ids SELECT * FROM cypher('agload_test_graph', $$ MATCH (u:Country {region : "Europe"}) WHERE u.name =~ 'Cro.*' RETURN id(u), u.name, u.region + ORDER BY id(u) $$) AS ("id(u)" agtype, result_1 agtype, result_2 agtype); -- There shouldn't be any duplicates diff --git a/regress/sql/cypher_create.sql b/regress/sql/cypher_create.sql index 0093dc449..345e16524 100644 --- a/regress/sql/cypher_create.sql +++ b/regress/sql/cypher_create.sql @@ -75,7 +75,8 @@ SELECT * FROM cypher('cypher_create', $$CREATE (:v)-[]->(:v)$$) AS (a agtype); SELECT * FROM cypher_create.e; -SELECT * FROM cypher_create.v; +SELECT id, properties FROM cypher_create._ag_label_vertex +WHERE labels = 'cypher_create.v'::regclass::oid; SELECT * FROM cypher('cypher_create', $$ CREATE (:n_var {name: 'Node A'}) @@ -176,7 +177,8 @@ SELECT * FROM cypher('cypher_create', $$ RETURN a $$) as (a agtype); -SELECT * FROM cypher_create.n_var; +SELECT id, properties FROM cypher_create._ag_label_vertex +WHERE labels = 'cypher_create.n_var'::regclass::oid; SELECT * FROM cypher_create.e_var; --Check every label has been created diff --git a/regress/sql/cypher_set.sql b/regress/sql/cypher_set.sql index a2667153d..941e7a5c3 100644 --- a/regress/sql/cypher_set.sql +++ b/regress/sql/cypher_set.sql @@ -361,19 +361,19 @@ SELECT * FROM create_graph('issue_1634'); -- this did not work and was fixed SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map - MERGE (v:PERSION {id: '1'}) + MERGE (v:PERSON {id: '1'}) SET v=map RETURN v,map $$) as (v agtype, map agtype); -- these 2 did work and are added as extra tests SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype); SELECT * FROM cypher('issue_1634', $$ WITH {first: 'jon', last: 'snow'} AS map - MERGE (v:PERSION {id: '1'}) + MERGE (v:PERSON {id: '1'}) SET v.first=map.first, v.last=map.last RETURN v,map $$) as (v agtype, map agtype); SELECT * FROM cypher('issue_1634', $$ MATCH (u) DELETE (u) $$) AS (u agtype); -SELECT * FROM cypher('issue_1634', $$ MERGE (v:PERSION {id: '1'}) +SELECT * FROM cypher('issue_1634', $$ MERGE (v:PERSON {id: '1'}) SET v={first: 'jon', last: 'snow'} RETURN v $$) as (v agtype); diff --git a/regress/sql/graph_generation.sql b/regress/sql/graph_generation.sql index e9ee8ea81..e39c32a38 100644 --- a/regress/sql/graph_generation.sql +++ b/regress/sql/graph_generation.sql @@ -25,14 +25,16 @@ SET search_path = ag_catalog; SELECT * FROM create_complete_graph('gp1',5,'edges','vertices'); SELECT COUNT(*) FROM gp1."edges"; -SELECT COUNT(*) FROM gp1."vertices"; +SELECT COUNT(*) FROM gp1._ag_label_vertex +WHERE labels = 'gp1."vertices"'::regclass::oid; SELECT * FROM cypher('gp1', $$MATCH (a)-[e]->(b) RETURN e$$) as (n agtype); SELECT * FROM create_complete_graph('gp1',5,'edges','vertices'); SELECT COUNT(*) FROM gp1."edges"; -SELECT COUNT(*) FROM gp1."vertices"; +SELECT COUNT(*) FROM gp1._ag_label_vertex +WHERE labels = 'gp1."vertices"'::regclass::oid; SELECT * FROM create_complete_graph('gp2',5,'edges'); @@ -55,14 +57,16 @@ SELECT drop_graph('gp2', true); SELECT * FROM age_create_barbell_graph('gp1',5,0,'vertices',NULL,'edges',NULL); SELECT COUNT(*) FROM gp1."edges"; -SELECT COUNT(*) FROM gp1."vertices"; +SELECT COUNT(*) FROM gp1._ag_label_vertex +WHERE labels = 'gp1."vertices"'::regclass::oid; SELECT * FROM cypher('gp1', $$MATCH (a)-[e]->(b) RETURN e$$) as (n agtype); SELECT * FROM age_create_barbell_graph('gp1',5,0,'vertices',NULL,'edges',NULL); SELECT COUNT(*) FROM gp1."edges"; -SELECT COUNT(*) FROM gp1."vertices"; +SELECT COUNT(*) FROM gp1._ag_label_vertex +WHERE labels = 'gp1."vertices"'::regclass::oid; SELECT * FROM age_create_barbell_graph('gp2',5,10,'vertices',NULL,'edges',NULL); diff --git a/regress/sql/index.sql b/regress/sql/index.sql index d9a4331a4..85c8cc126 100644 --- a/regress/sql/index.sql +++ b/regress/sql/index.sql @@ -34,7 +34,8 @@ SELECT create_graph('cypher_index'); */ --Section 1 Setup SELECT create_vlabel('cypher_index', 'idx'); -CREATE UNIQUE INDEX cypher_index_idx_props_uq ON cypher_index.idx(properties); +CREATE UNIQUE INDEX cypher_index_idx_props_uq ON cypher_index._ag_label_vertex(properties) +WHERE labels = 'cypher_index.idx'::regclass::oid; --Test 1 SELECT * FROM cypher('cypher_index', $$ CREATE (:idx {i: 1}) $$) AS (a agtype); @@ -214,10 +215,12 @@ SET enable_nestloop = ON; -- Section 3: Agtype GIN Indices to Improve WHERE clause Performance -- CREATE INDEX load_city_gin_idx -ON cypher_index."City" USING gin (properties); +ON cypher_index._ag_label_vertex USING gin (properties) +WHERE labels = 'cypher_index."City"'::regclass::oid; CREATE INDEX load_country_gin_idx -ON cypher_index."Country" USING gin (properties); +ON cypher_index._ag_label_vertex USING gin (properties) +WHERE labels = 'cypher_index."Country"'::regclass::oid; SELECT * FROM cypher('cypher_index', $$ @@ -256,8 +259,9 @@ SELECT COUNT(*) FROM cypher('cypher_index', $$ RETURN a $$) as (n agtype); -CREATE INDEX CONCURRENTLY cntry_ode_idx ON cypher_index."City" -(ag_catalog.agtype_access_operator(properties, '"country_code"'::agtype)); +CREATE INDEX CONCURRENTLY cntry_ode_idx ON cypher_index._ag_label_vertex +(ag_catalog.agtype_access_operator(properties, '"country_code"'::agtype)) +WHERE labels = 'cypher_index."City"'::regclass::oid; SELECT COUNT(*) FROM cypher('agload_test_graph', $$ MATCH (a:City) diff --git a/regress/sql/pgvector.sql b/regress/sql/pgvector.sql index 677e78586..2189024d6 100644 --- a/regress/sql/pgvector.sql +++ b/regress/sql/pgvector.sql @@ -215,11 +215,11 @@ BEGIN WHERE name = 'graph'; EXECUTE format($f$ - CREATE INDEX movie_vector_idx ON graph."Movie" + CREATE INDEX movie_vector_idx ON graph._ag_label_vertex USING hnsw ((( agtype_access_operator( VARIADIC ARRAY[ - _agtype_build_vertex(id, _label_name(%L::oid, id), properties), + _agtype_build_vertex(id, _label_name_from_table_oid(labels), properties), '"embedding"'::agtype ] )::text @@ -270,11 +270,11 @@ BEGIN WHERE name = 'graph'; EXECUTE format($f$ - CREATE INDEX movie_vector_idx ON graph."Movie" + CREATE INDEX movie_vector_idx ON graph._ag_label_vertex USING hnsw (( agtype_access_operator( VARIADIC ARRAY[ - _agtype_build_vertex(id, _label_name(%L::oid, id), properties), + _agtype_build_vertex(id, _label_name_from_table_oid(labels), properties), '"embedding"'::agtype ] )::vector(4)) vector_cosine_ops); @@ -306,4 +306,4 @@ SET enable_seqscan = on; DROP FUNCTION plan_has_index_scan(text); DROP CAST (agtype AS vector); SELECT drop_graph('graph', true); -DROP EXTENSION vector CASCADE; \ No newline at end of file +DROP EXTENSION vector CASCADE; diff --git a/regress/sql/unified_vertex_table.sql b/regress/sql/unified_vertex_table.sql new file mode 100644 index 000000000..84145e384 --- /dev/null +++ b/regress/sql/unified_vertex_table.sql @@ -0,0 +1,244 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +-- +-- Regression tests for the unified vertex table architecture +-- +-- Tests verify: +-- 1. Labels column correctly stores label table OID +-- 2. Label retrieval from labels column works correctly +-- 3. Multiple labels coexist in single table +-- 4. startNode/endNode correctly retrieve vertex labels +-- 5. VLE correctly handles label retrieval +-- + +LOAD 'age'; +SET search_path TO ag_catalog; + +-- +-- Test 1: Basic unified table structure verification +-- +SELECT create_graph('unified_test'); + +-- Create vertices with different labels +SELECT * FROM cypher('unified_test', $$ + CREATE (:Person {name: 'Alice'}) +$$) AS (v agtype); + +SELECT * FROM cypher('unified_test', $$ + CREATE (:Company {name: 'Acme Corp'}) +$$) AS (v agtype); + +SELECT * FROM cypher('unified_test', $$ + CREATE (:Location {name: 'Seattle'}) +$$) AS (v agtype); + +-- Verify all vertices are in the unified table +SELECT COUNT(*) AS vertex_count FROM unified_test._ag_label_vertex; + +-- Verify labels column contains different OIDs for different labels +SELECT COUNT(DISTINCT labels) AS distinct_label_count FROM unified_test._ag_label_vertex; + +-- Verify we can filter by label using the labels column +SELECT id, properties FROM unified_test._ag_label_vertex +WHERE labels = 'unified_test."Person"'::regclass::oid; + +SELECT id, properties FROM unified_test._ag_label_vertex +WHERE labels = 'unified_test."Company"'::regclass::oid; + +SELECT id, properties FROM unified_test._ag_label_vertex +WHERE labels = 'unified_test."Location"'::regclass::oid; + +-- +-- Test 2: Label retrieval via Cypher MATCH +-- +SELECT * FROM cypher('unified_test', $$ + MATCH (p:Person) RETURN p.name ORDER BY p.name +$$) AS (name agtype); + +SELECT * FROM cypher('unified_test', $$ + MATCH (c:Company) RETURN c.name ORDER BY c.name +$$) AS (name agtype); + +SELECT * FROM cypher('unified_test', $$ + MATCH (n) RETURN labels(n), n.name ORDER BY n.name +$$) AS (label agtype, name agtype); + +-- +-- Test 3: startNode/endNode label retrieval +-- +SELECT * FROM cypher('unified_test', $$ + CREATE (:Person {name: 'Bob'})-[:WORKS_AT]->(:Company {name: 'Tech Inc'}) +$$) AS (v agtype); + +SELECT * FROM cypher('unified_test', $$ + CREATE (:Person {name: 'Carol'})-[:LIVES_IN]->(:Location {name: 'Portland'}) +$$) AS (v agtype); + +-- Verify startNode returns correct label +SELECT * FROM cypher('unified_test', $$ + MATCH ()-[e:WORKS_AT]->() + RETURN startNode(e).name AS employee, label(startNode(e)) AS emp_label, + endNode(e).name AS company, label(endNode(e)) AS comp_label +$$) AS (employee agtype, emp_label agtype, company agtype, comp_label agtype); + +SELECT * FROM cypher('unified_test', $$ + MATCH ()-[e:LIVES_IN]->() + RETURN startNode(e).name AS person, label(startNode(e)) AS person_label, + endNode(e).name AS location, label(endNode(e)) AS loc_label +$$) AS (person agtype, person_label agtype, location agtype, loc_label agtype); + +-- +-- Test 4: Unlabeled vertices (default vertex label) +-- +SELECT * FROM cypher('unified_test', $$ + CREATE ({type: 'unlabeled_1'}) +$$) AS (v agtype); + +SELECT * FROM cypher('unified_test', $$ + CREATE ({type: 'unlabeled_2'}) +$$) AS (v agtype); + +-- Verify unlabeled vertices have empty string label +SELECT * FROM cypher('unified_test', $$ + MATCH (n) WHERE n.type IS NOT NULL + RETURN n.type, label(n) ORDER BY n.type +$$) AS (type agtype, label agtype); + +-- Verify labels column for default vertices points to unified table +SELECT COUNT(*) AS unlabeled_count FROM unified_test._ag_label_vertex +WHERE labels = 'unified_test._ag_label_vertex'::regclass::oid; + +-- +-- Test 5: Mixed label queries (MATCH without label) +-- +SELECT * FROM cypher('unified_test', $$ + MATCH (n) + RETURN label(n), count(*) AS cnt + ORDER BY label(n) +$$) AS (label agtype, cnt agtype); + +-- +-- Test 6: Label with SET operations +-- +SELECT * FROM cypher('unified_test', $$ + MATCH (p:Person {name: 'Alice'}) + SET p.age = 30 + RETURN p.name, p.age, label(p) +$$) AS (name agtype, age agtype, label agtype); + +-- Verify label is preserved after SET +SELECT * FROM cypher('unified_test', $$ + MATCH (p:Person {name: 'Alice'}) + RETURN label(p) +$$) AS (label agtype); + +-- +-- Test 7: MERGE with labels +-- +SELECT * FROM cypher('unified_test', $$ + MERGE (d:Department {name: 'Engineering'}) + RETURN d.name, label(d) +$$) AS (name agtype, label agtype); + +SELECT * FROM cypher('unified_test', $$ + MERGE (d:Department {name: 'Engineering'}) + RETURN d.name, label(d) +$$) AS (name agtype, label agtype); + +-- Verify only one Department vertex exists +SELECT * FROM cypher('unified_test', $$ + MATCH (d:Department) + RETURN count(d) +$$) AS (cnt agtype); + +-- +-- Test 8: DELETE preserves labels column integrity +-- +SELECT * FROM cypher('unified_test', $$ + CREATE (:Temporary {id: 1}) +$$) AS (v agtype); + +SELECT * FROM cypher('unified_test', $$ + CREATE (:Temporary {id: 2}) +$$) AS (v agtype); + +-- Verify vertices exist +SELECT * FROM cypher('unified_test', $$ + MATCH (t:Temporary) + RETURN t.id ORDER BY t.id +$$) AS (id agtype); + +-- Delete one +SELECT * FROM cypher('unified_test', $$ + MATCH (t:Temporary {id: 1}) + DELETE t +$$) AS (v agtype); + +-- Verify remaining vertex still has correct label +SELECT * FROM cypher('unified_test', $$ + MATCH (t:Temporary) + RETURN t.id, label(t) +$$) AS (id agtype, label agtype); + +-- +-- Test 9: VLE with label retrieval +-- +SELECT * FROM cypher('unified_test', $$ + CREATE (:Node {name: 'a'})-[:CONNECTED]->(:Node {name: 'b'})-[:CONNECTED]->(:Node {name: 'c'}) +$$) AS (v agtype); + +-- Test that VLE path returns vertices with correct labels +SELECT * FROM cypher('unified_test', $$ + MATCH p = (n:Node {name: 'a'})-[:CONNECTED*1..2]->(m) + RETURN label(n), label(m) + ORDER BY label(m) +$$) AS (start_label agtype, end_label agtype); + +-- +-- Test 10: _label_name_from_table_oid function +-- +-- Get a label table OID and verify function works +SELECT ag_catalog._label_name_from_table_oid('unified_test."Person"'::regclass::oid); +SELECT ag_catalog._label_name_from_table_oid('unified_test."Company"'::regclass::oid); +SELECT ag_catalog._label_name_from_table_oid('unified_test."Location"'::regclass::oid); + +-- +-- Test 11: Verify all labels coexist in unified table with distinct OIDs +-- +SELECT * FROM cypher('unified_test', $$ + CREATE (:LabelA {val: 1}) +$$) AS (v agtype); + +SELECT * FROM cypher('unified_test', $$ + CREATE (:LabelB {val: 2}) +$$) AS (v agtype); + +SELECT * FROM cypher('unified_test', $$ + CREATE (:LabelC {val: 3}) +$$) AS (v agtype); + +-- Verify all have distinct label OIDs (count should equal 3) +SELECT COUNT(DISTINCT labels) AS distinct_labels FROM unified_test._ag_label_vertex +WHERE properties::text LIKE '%val%'; + +-- +-- Cleanup +-- +SELECT drop_graph('unified_test', true); diff --git a/sql/age_main.sql b/sql/age_main.sql index 59ada0f9f..0cf24eac7 100644 --- a/sql/age_main.sql +++ b/sql/age_main.sql @@ -375,6 +375,13 @@ CREATE FUNCTION ag_catalog._label_name(graph_oid oid, graphid) PARALLEL SAFE AS 'MODULE_PATHNAME'; +CREATE FUNCTION ag_catalog._label_name_from_table_oid(label_table_oid oid) + RETURNS cstring + LANGUAGE c + IMMUTABLE +PARALLEL SAFE +AS 'MODULE_PATHNAME'; + CREATE FUNCTION ag_catalog._extract_label_id(graphid) RETURNS label_id LANGUAGE c diff --git a/src/backend/catalog/ag_label.c b/src/backend/catalog/ag_label.c index b6dcf77a3..9578276d7 100644 --- a/src/backend/catalog/ag_label.c +++ b/src/backend/catalog/ag_label.c @@ -169,8 +169,16 @@ char *get_label_seq_relation_name(const char *label_name) PG_FUNCTION_INFO_V1(_label_name); /* - * Using the graph name and the vertex/edge's graphid, find - * the correct label name from ag_catalog.label + * Using the graph OID and the graphid, find the correct label name from + * ag_catalog.ag_label by extracting the label_id from the graphid. + * + * IMPORTANT: This function extracts the label_id from the graphid's upper + * bits. For EDGES, this is the correct source of label information. For + * VERTICES, the label is stored in the 'labels' column of the unified vertex + * table, so use _label_name_from_table_oid() instead when querying vertices. + * + * This function is primarily used for edges where the label_id in the graphid + * is authoritative. */ Datum _label_name(PG_FUNCTION_ARGS) { @@ -214,6 +222,43 @@ Datum _label_name(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(label_name); } +PG_FUNCTION_INFO_V1(_label_name_from_table_oid); + +/* + * Given a label table OID, return the label name. + * Returns empty string for the default vertex/edge table. + */ +Datum _label_name_from_table_oid(PG_FUNCTION_ARGS) +{ + Oid label_table_oid; + char *label_name; + + if (PG_ARGISNULL(0)) + { + ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("label_table_oid must not be null"))); + } + + label_table_oid = PG_GETARG_OID(0); + + /* Get the relation name from the OID */ + label_name = get_rel_name(label_table_oid); + + if (label_name == NULL) + { + ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("relation with oid %u does not exist", label_table_oid))); + } + + /* Return empty string for default labels */ + if (IS_AG_DEFAULT_LABEL(label_name)) + { + PG_RETURN_CSTRING(""); + } + + PG_RETURN_CSTRING(label_name); +} + PG_FUNCTION_INFO_V1(_label_id); Datum _label_id(PG_FUNCTION_ARGS) diff --git a/src/backend/commands/label_commands.c b/src/backend/commands/label_commands.c index c9fdfad89..b46938015 100644 --- a/src/backend/commands/label_commands.c +++ b/src/backend/commands/label_commands.c @@ -539,6 +539,7 @@ static List *create_vertex_table_elements(char *graph_name, char *label_name, { ColumnDef *id; ColumnDef *props; + ColumnDef *labels; /* "id" graphid PRIMARY KEY DEFAULT "ag_catalog"."_graphid"(...) */ id = makeColumnDef(AG_VERTEX_COLNAME_ID, GRAPHIDOID, -1, InvalidOid); @@ -552,7 +553,11 @@ static List *create_vertex_table_elements(char *graph_name, char *label_name, props->constraints = list_make2(build_not_null_constraint(), build_properties_default()); - return list_make2(id, props); + /* "labels" oid NOT NULL */ + labels = makeColumnDef(AG_VERTEX_COLNAME_LABELS, OIDOID, -1, InvalidOid); + labels->constraints = list_make1(build_not_null_constraint()); + + return list_make3(id, props, labels); } /* CREATE SEQUENCE `seq_range_var` MAXVALUE `LOCAL_ID_MAX` */ diff --git a/src/backend/executor/cypher_create.c b/src/backend/executor/cypher_create.c index 2091ea29c..29b14f496 100644 --- a/src/backend/executor/cypher_create.c +++ b/src/backend/executor/cypher_create.c @@ -491,6 +491,10 @@ static Datum create_vertex(cypher_create_custom_scan_state *css, elemTupleSlot->tts_isnull[vertex_tuple_properties] = scanTupleSlot->tts_isnull[node->prop_attr_num]; + /* set the label table OID in the labels column */ + elemTupleSlot->tts_values[vertex_tuple_labels] = ObjectIdGetDatum(node->label_table_oid); + elemTupleSlot->tts_isnull[vertex_tuple_labels] = false; + /* Insert the new vertex */ insert_entity_tuple(resultRelInfo, elemTupleSlot, estate); @@ -577,7 +581,7 @@ static Datum create_vertex(cypher_create_custom_scan_state *css, */ if (!SAFE_TO_SKIP_EXISTENCE_CHECK(node->flags)) { - if (!entity_exists(estate, css->graph_oid, DATUM_GET_GRAPHID(id))) + if (!vertex_exists(estate, css->graph_oid, DATUM_GET_GRAPHID(id))) { ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), diff --git a/src/backend/executor/cypher_delete.c b/src/backend/executor/cypher_delete.c index 5f9aa561d..ddfed8edb 100644 --- a/src/backend/executor/cypher_delete.c +++ b/src/backend/executor/cypher_delete.c @@ -403,13 +403,14 @@ static void process_delete_list(CustomScanState *node) /* * Setup the scan key to require the id field on-disc to match the - * entity's graphid. + * entity's graphid. For vertices, use F_INT8EQ since the unified + * vertex table stores id as int64. For edges, use F_GRAPHIDEQ. */ if (original_entity_value->type == AGTV_VERTEX) { ScanKeyInit(&scan_keys[0], Anum_ag_label_vertex_table_id, - BTEqualStrategyNumber, F_GRAPHIDEQ, - GRAPHID_GET_DATUM(id->val.int_value)); + BTEqualStrategyNumber, F_INT8EQ, + Int64GetDatum(id->val.int_value)); } else if (original_entity_value->type == AGTV_EDGE) { diff --git a/src/backend/executor/cypher_merge.c b/src/backend/executor/cypher_merge.c index 9136825ab..0fe3e7078 100644 --- a/src/backend/executor/cypher_merge.c +++ b/src/backend/executor/cypher_merge.c @@ -441,7 +441,7 @@ static path_entry **prebuild_path(CustomScanState *node) if (!SAFE_TO_SKIP_EXISTENCE_CHECK(node->flags)) { - if (!entity_exists(estate, css->graph_oid, entry->id)) + if (!vertex_exists(estate, css->graph_oid, entry->id)) { ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), @@ -1062,6 +1062,10 @@ static Datum merge_vertex(cypher_merge_custom_scan_state *css, elemTupleSlot->tts_values[vertex_tuple_properties] = prop; elemTupleSlot->tts_isnull[vertex_tuple_properties] = isNull; + /* set the label table OID in the labels column */ + elemTupleSlot->tts_values[vertex_tuple_labels] = ObjectIdGetDatum(node->label_table_oid); + elemTupleSlot->tts_isnull[vertex_tuple_labels] = false; + /* * Insert the new vertex. * @@ -1225,7 +1229,7 @@ static Datum merge_vertex(cypher_merge_custom_scan_state *css, */ if (!SAFE_TO_SKIP_EXISTENCE_CHECK(node->flags)) { - if (!entity_exists(estate, css->graph_oid, DATUM_GET_GRAPHID(id))) + if (!vertex_exists(estate, css->graph_oid, DATUM_GET_GRAPHID(id))) { ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), diff --git a/src/backend/executor/cypher_set.c b/src/backend/executor/cypher_set.c index d1837fb16..fb2625ba2 100644 --- a/src/backend/executor/cypher_set.c +++ b/src/backend/executor/cypher_set.c @@ -21,8 +21,12 @@ #include "storage/bufmgr.h" +#include "catalog/ag_label.h" +#include "catalog/namespace.h" +#include "commands/label_commands.h" #include "executor/cypher_executor.h" #include "executor/cypher_utils.h" +#include "utils/lsyscache.h" static void begin_cypher_set(CustomScanState *node, EState *estate, int eflags); @@ -498,8 +502,17 @@ static void process_update_list(CustomScanState *node) } } - resultRelInfo = create_entity_result_rel_info( - estate, css->set_list->graph_name, label_name); + /* For vertices, use the unified vertex table */ + if (original_entity_value->type == AGTV_VERTEX) + { + resultRelInfo = create_entity_result_rel_info( + estate, css->set_list->graph_name, AG_DEFAULT_LABEL_VERTEX); + } + else + { + resultRelInfo = create_entity_result_rel_info( + estate, css->set_list->graph_name, label_name); + } slot = ExecInitExtraTupleSlot( estate, RelationGetDescr(resultRelInfo->ri_RelationDesc), @@ -512,11 +525,34 @@ static void process_update_list(CustomScanState *node) */ if (original_entity_value->type == AGTV_VERTEX) { + Oid graph_namespace_oid; + Oid label_table_oid; + new_entity = make_vertex(GRAPHID_GET_DATUM(id->val.int_value), CStringGetDatum(label_name), AGTYPE_P_GET_DATUM(agtype_value_to_agtype(altered_properties))); + /* Get the namespace OID for the graph */ + graph_namespace_oid = get_namespace_oid(css->set_list->graph_name, false); + + /* + * Get the label table OID. If label_name is empty or NULL, use the + * default vertex label. + */ + if (label_name == NULL || strlen(label_name) == 0) + { + label_table_oid = get_relname_relid(AG_DEFAULT_LABEL_VERTEX, graph_namespace_oid); + } + else + { + label_table_oid = get_relname_relid(label_name, graph_namespace_oid); + } + slot = populate_vertex_tts(slot, id, altered_properties); + + /* Set the labels column to the label table OID */ + slot->tts_values[vertex_tuple_labels] = ObjectIdGetDatum(label_table_oid); + slot->tts_isnull[vertex_tuple_labels] = false; } else if (original_entity_value->type == AGTV_EDGE) { @@ -561,10 +597,19 @@ static void process_update_list(CustomScanState *node) { /* * Setup the scan key to require the id field on-disc to match the - * entity's graphid. + * entity's graphid. For vertices, use F_INT8EQ since the unified + * table stores id as int64. For edges, use F_GRAPHIDEQ. */ - ScanKeyInit(&scan_keys[0], 1, BTEqualStrategyNumber, F_GRAPHIDEQ, - GRAPHID_GET_DATUM(id->val.int_value)); + if (original_entity_value->type == AGTV_VERTEX) + { + ScanKeyInit(&scan_keys[0], 1, BTEqualStrategyNumber, F_INT8EQ, + Int64GetDatum(id->val.int_value)); + } + else + { + ScanKeyInit(&scan_keys[0], 1, BTEqualStrategyNumber, F_GRAPHIDEQ, + GRAPHID_GET_DATUM(id->val.int_value)); + } /* * Setup the scan description, with the correct snapshot and scan * keys. diff --git a/src/backend/executor/cypher_utils.c b/src/backend/executor/cypher_utils.c index c8d568831..a2dfc6b65 100644 --- a/src/backend/executor/cypher_utils.c +++ b/src/backend/executor/cypher_utils.c @@ -24,9 +24,12 @@ #include "postgres.h" +#include "catalog/namespace.h" #include "nodes/makefuncs.h" #include "parser/parse_relation.h" +#include "utils/lsyscache.h" +#include "catalog/ag_graph.h" #include "catalog/ag_label.h" #include "commands/label_commands.h" #include "executor/cypher_utils.h" @@ -45,18 +48,31 @@ ResultRelInfo *create_entity_result_rel_info(EState *estate, char *graph_name, ParseState *pstate = NULL; RangeTblEntry *rte = NULL; int pii = 0; + Oid graph_oid; + char relkind; /* create a new parse state for this operation */ pstate = make_parsestate(NULL); resultRelInfo = palloc(sizeof(ResultRelInfo)); - if (strlen(label_name) == 0) + /* For vertices, always use the unified vertex table */ + graph_oid = get_graph_oid(graph_name); + relkind = get_label_kind(label_name, graph_oid); + + if (relkind == LABEL_KIND_VERTEX) { + /* All vertices are in _ag_label_vertex */ + rv = makeRangeVar(graph_name, AG_DEFAULT_LABEL_VERTEX, -1); + } + else if (strlen(label_name) == 0) + { + /* Empty label name means vertex */ rv = makeRangeVar(graph_name, AG_DEFAULT_LABEL_VERTEX, -1); } else { + /* Edges use label-specific tables */ rv = makeRangeVar(graph_name, label_name, -1); } @@ -175,35 +191,36 @@ TupleTableSlot *populate_edge_tts( /* - * Find out if the entity still exists. This is for 'implicit' deletion - * of an entity. + * Find out if the vertex still exists. This is for 'implicit' deletion + * of a vertex - checking if a vertex was deleted by another variable. + * + * NOTE: This function scans the unified _ag_label_vertex table directly. + * No information is extracted from the graphid - the graphid is only used + * as the search key to find the vertex row. */ -bool entity_exists(EState *estate, Oid graph_oid, graphid id) +bool vertex_exists(EState *estate, Oid graph_oid, graphid id) { - label_cache_data *label; ScanKeyData scan_keys[1]; TableScanDesc scan_desc; HeapTuple tuple; Relation rel; bool result = true; + Oid vertex_table_oid; - /* - * Extract the label id from the graph id and get the table name - * the entity is part of. - */ - label = search_label_graph_oid_cache(graph_oid, GET_LABEL_ID(id)); + /* Get the unified vertex table OID directly from graph_oid */ + vertex_table_oid = get_label_relation(AG_DEFAULT_LABEL_VERTEX, graph_oid); - /* Setup the scan key to be the graphid */ + /* Setup the scan key to search by graphid (using INT8 comparison) */ ScanKeyInit(&scan_keys[0], 1, BTEqualStrategyNumber, - F_GRAPHIDEQ, GRAPHID_GET_DATUM(id)); + F_INT8EQ, Int64GetDatum(id)); - rel = table_open(label->relation, RowExclusiveLock); - scan_desc = table_beginscan(rel, estate->es_snapshot, 1, scan_keys); + rel = table_open(vertex_table_oid, RowExclusiveLock); + scan_desc = table_beginscan(rel, estate->es_snapshot, 1, scan_keys); tuple = heap_getnext(scan_desc, ForwardScanDirection); /* - * If a single tuple was returned, the tuple is still valid, otherwise' + * If a single tuple was returned, the tuple is still valid, otherwise * set to false. */ if (!HeapTupleIsValid(tuple)) diff --git a/src/backend/nodes/cypher_copyfuncs.c b/src/backend/nodes/cypher_copyfuncs.c index 56895ee06..db8408b75 100644 --- a/src/backend/nodes/cypher_copyfuncs.c +++ b/src/backend/nodes/cypher_copyfuncs.c @@ -99,6 +99,7 @@ void copy_cypher_target_node(ExtensibleNode *newnode, const ExtensibleNode *from COPY_SCALAR_FIELD(dir); COPY_SCALAR_FIELD(prop_attr_num); COPY_SCALAR_FIELD(relid); + COPY_SCALAR_FIELD(label_table_oid); COPY_SCALAR_FIELD(tuple_position); COPY_STRING_FIELD(label_name); diff --git a/src/backend/nodes/cypher_outfuncs.c b/src/backend/nodes/cypher_outfuncs.c index 4772621c9..a0fa6a4b0 100644 --- a/src/backend/nodes/cypher_outfuncs.c +++ b/src/backend/nodes/cypher_outfuncs.c @@ -398,6 +398,7 @@ void out_cypher_target_node(StringInfo str, const ExtensibleNode *node) WRITE_NODE_FIELD(resultRelInfo); WRITE_NODE_FIELD(elemTupleSlot); WRITE_OID_FIELD(relid); + WRITE_OID_FIELD(label_table_oid); WRITE_STRING_FIELD(label_name); WRITE_STRING_FIELD(variable_name); WRITE_INT32_FIELD(tuple_position); diff --git a/src/backend/nodes/cypher_readfuncs.c b/src/backend/nodes/cypher_readfuncs.c index a58b90cbc..15f5dac7d 100644 --- a/src/backend/nodes/cypher_readfuncs.c +++ b/src/backend/nodes/cypher_readfuncs.c @@ -234,6 +234,7 @@ void read_cypher_target_node(struct ExtensibleNode *node) READ_NODE_FIELD(resultRelInfo); READ_NODE_FIELD(elemTupleSlot); READ_OID_FIELD(relid); + READ_OID_FIELD(label_table_oid); READ_STRING_FIELD(label_name); READ_STRING_FIELD(variable_name); READ_INT_FIELD(tuple_position); diff --git a/src/backend/parser/cypher_clause.c b/src/backend/parser/cypher_clause.c index a5413bdaa..089193292 100644 --- a/src/backend/parser/cypher_clause.c +++ b/src/backend/parser/cypher_clause.c @@ -5490,20 +5490,15 @@ static Expr *transform_cypher_node(cypher_parsestate *cpstate, /* now build a new vertex */ schema_name = get_graph_namespace_name(cpstate->graph_name); - if (valid_label) - { - rel_name = get_label_relation_name(node->label, cpstate->graph_oid); - } - else - { - rel_name = AG_DEFAULT_LABEL_VERTEX; - } + /* Always use the default vertex table for MATCH queries */ + rel_name = AG_DEFAULT_LABEL_VERTEX; label_range_var = makeRangeVar(schema_name, rel_name, -1); alias = makeAlias(node->name, NIL); + /* Don't scan child tables - all vertices are now in _ag_label_vertex */ pnsi = addRangeTableEntry(pstate, label_range_var, alias, - label_range_var->inh, true); + false, true); Assert(pnsi != NULL); @@ -5513,6 +5508,34 @@ static Expr *transform_cypher_node(cypher_parsestate *cpstate, */ addNSItemToQuery(pstate, pnsi, true, true, true); + /* Add label filtering if a specific label is requested */ + if (valid_label && node->label != NULL && strcmp(node->label, AG_DEFAULT_LABEL_VERTEX) != 0) + { + Oid label_table_oid; + Var *labels_var; + Const *label_oid_const; + OpExpr *filter_expr; + + /* Get the label table OID */ + label_table_oid = get_label_relation(node->label, cpstate->graph_oid); + + /* Create a Var for the labels column */ + labels_var = makeVar(pnsi->p_rtindex, Anum_ag_label_vertex_table_labels, + OIDOID, -1, InvalidOid, 0); + + /* Create a Const for the label OID */ + label_oid_const = makeConst(OIDOID, -1, InvalidOid, sizeof(Oid), + ObjectIdGetDatum(label_table_oid), false, true); + + /* Create an equality filter: labels = label_oid */ + filter_expr = (OpExpr *)make_op(pstate, list_make1(makeString("=")), + (Node *)labels_var, (Node *)label_oid_const, + pstate->p_last_srf, -1); + + /* Add the filter to the RTE's quals */ + pnsi->p_rte->securityQuals = lappend(pnsi->p_rte->securityQuals, filter_expr); + } + resno = pstate->p_next_resno++; if (valid_label) @@ -5582,10 +5605,10 @@ static Node *make_vertex_expr(cypher_parsestate *cpstate, ParseNamespaceItem *pnsi) { ParseState *pstate = (ParseState *)cpstate; - Oid label_name_func_oid; + Oid get_rel_name_func_oid; Oid func_oid; Node *id; - Const *graph_oid_const; + Node *labels_oid; Node *props; List *args, *label_name_args; FuncExpr *func_expr; @@ -5598,16 +5621,15 @@ static Node *make_vertex_expr(cypher_parsestate *cpstate, id = scanNSItemForColumn(pstate, pnsi, 0, AG_VERTEX_COLNAME_ID, -1); - label_name_func_oid = get_ag_func_oid("_label_name", 2, OIDOID, - GRAPHIDOID); + /* Get the labels column (OID of label table) */ + labels_oid = scanNSItemForColumn(pstate, pnsi, 0, AG_VERTEX_COLNAME_LABELS, -1); - graph_oid_const = makeConst(OIDOID, -1, InvalidOid, sizeof(Oid), - ObjectIdGetDatum(cpstate->graph_oid), false, - true); + /* Use _label_name_from_table_oid() to convert label table OID to label name */ + get_rel_name_func_oid = get_ag_func_oid("_label_name_from_table_oid", 1, OIDOID); - label_name_args = list_make2(graph_oid_const, id); + label_name_args = list_make1(labels_oid); - label_name_func_expr = makeFuncExpr(label_name_func_oid, CSTRINGOID, + label_name_func_expr = makeFuncExpr(get_rel_name_func_oid, CSTRINGOID, label_name_args, InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL); label_name_func_expr->location = -1; @@ -6158,6 +6180,7 @@ transform_create_cypher_new_node(cypher_parsestate *cpstate, ParseState *pstate = (ParseState *)cpstate; cypher_target_node *rel = make_ag_node(cypher_target_node); Relation label_relation; + Relation default_vertex_relation; RangeVar *rv; RTEPermissionInfo *rte_pi; TargetEntry *te; @@ -6204,16 +6227,23 @@ transform_create_cypher_new_node(cypher_parsestate *cpstate, rv = makeRangeVar(cpstate->graph_name, node->label, -1); label_relation = parserOpenTable(&cpstate->pstate, rv, RowExclusiveLock); - /* Store the relid */ - rel->relid = RelationGetRelid(label_relation); + /* Store the label table OID (for labels column) */ + rel->label_table_oid = RelationGetRelid(label_relation); - pnsi = addRangeTableEntryForRelation((ParseState *)cpstate, label_relation, + /* Use the default vertex table for actual storage */ + rv = makeRangeVar(cpstate->graph_name, AG_DEFAULT_LABEL_VERTEX, -1); + default_vertex_relation = parserOpenTable(&cpstate->pstate, rv, RowExclusiveLock); + + /* Store the relid pointing to _ag_label_vertex */ + rel->relid = RelationGetRelid(default_vertex_relation); + + pnsi = addRangeTableEntryForRelation((ParseState *)cpstate, default_vertex_relation, AccessShareLock, NULL, false, false); rte_pi = pnsi->p_perminfo; rte_pi->requiredPerms = ACL_INSERT; - /* id */ + /* id - get from label table for sequence */ rel->id_expr = (Expr *)build_column_default(label_relation, Anum_ag_label_vertex_table_id); @@ -6221,7 +6251,7 @@ transform_create_cypher_new_node(cypher_parsestate *cpstate, alias = get_next_default_alias(cpstate); resno = pstate->p_next_resno++; - props = cypher_create_properties(cpstate, rel, label_relation, node->props, + props = cypher_create_properties(cpstate, rel, default_vertex_relation, node->props, ENT_VERTEX); rel->prop_attr_num = resno - 1; @@ -6229,6 +6259,7 @@ transform_create_cypher_new_node(cypher_parsestate *cpstate, *target_list = lappend(*target_list, te); table_close(label_relation, NoLock); + table_close(default_vertex_relation, NoLock); if (node->name) { @@ -7076,6 +7107,7 @@ static cypher_target_node *get_referenced_variable(ParseState *pstate, _cpy->resultRelInfo = ctn->resultRelInfo; _cpy->elemTupleSlot = ctn->elemTupleSlot; _cpy->relid = ctn->relid; + _cpy->label_table_oid = ctn->label_table_oid; _cpy->label_name = ctn->label_name; _cpy->variable_name = ctn->variable_name; _cpy->tuple_position = ctn->tuple_position; @@ -7333,6 +7365,7 @@ transform_merge_cypher_node(cypher_parsestate *cpstate, List **target_list, ParseState *pstate = (ParseState *)cpstate; cypher_target_node *rel = make_ag_node(cypher_target_node); Relation label_relation; + Relation default_vertex_relation; RangeVar *rv; RTEPermissionInfo *rte_pi; ParseNamespaceItem *pnsi; @@ -7438,10 +7471,17 @@ transform_merge_cypher_node(cypher_parsestate *cpstate, List **target_list, parser_errposition(&cpstate->pstate, node->location))); } - /* Store the relid */ - rel->relid = RelationGetRelid(label_relation); + /* Store the label table OID (for labels column) */ + rel->label_table_oid = RelationGetRelid(label_relation); - pnsi = addRangeTableEntryForRelation((ParseState *)cpstate, label_relation, + /* Use the default vertex table for actual storage */ + rv = makeRangeVar(cpstate->graph_name, AG_DEFAULT_LABEL_VERTEX, -1); + default_vertex_relation = parserOpenTable(&cpstate->pstate, rv, RowExclusiveLock); + + /* Store the relid pointing to _ag_label_vertex */ + rel->relid = RelationGetRelid(default_vertex_relation); + + pnsi = addRangeTableEntryForRelation((ParseState *)cpstate, default_vertex_relation, AccessShareLock, NULL, false, false); rte_pi = pnsi->p_perminfo; @@ -7451,10 +7491,11 @@ transform_merge_cypher_node(cypher_parsestate *cpstate, List **target_list, rel->id_expr = (Expr *)build_column_default(label_relation, Anum_ag_label_vertex_table_id); - rel->prop_expr = cypher_create_properties(cpstate, rel, label_relation, + rel->prop_expr = cypher_create_properties(cpstate, rel, default_vertex_relation, node->props, ENT_VERTEX); table_close(label_relation, NoLock); + table_close(default_vertex_relation, NoLock); return rel; } diff --git a/src/backend/utils/adt/age_global_graph.c b/src/backend/utils/adt/age_global_graph.c index c34e51ee3..feed1542c 100644 --- a/src/backend/utils/adt/age_global_graph.c +++ b/src/backend/utils/adt/age_global_graph.c @@ -463,89 +463,81 @@ static bool insert_vertex_edge(GRAPH_global_context *ggctx, /* helper routine to load all vertices into the GRAPH global vertex hashtable */ static void load_vertex_hashtable(GRAPH_global_context *ggctx) { - Oid graph_oid; Oid graph_namespace_oid; Snapshot snapshot; - List *vertex_label_names = NIL; - ListCell *lc; + Relation graph_vertex_table; + TableScanDesc scan_desc; + HeapTuple tuple; + Oid vertex_table_oid; + TupleDesc tupdesc; - /* get the specific graph OID and namespace (schema) OID */ - graph_oid = ggctx->graph_oid; + /* get the specific graph namespace (schema) OID */ graph_namespace_oid = get_namespace_oid(ggctx->graph_name, false); /* get the active snapshot */ snapshot = GetActiveSnapshot(); - /* get the names of all of the vertex label tables */ - vertex_label_names = get_ag_labels_names(snapshot, graph_oid, - LABEL_TYPE_VERTEX); - /* go through all vertex label tables in list */ - foreach (lc, vertex_label_names) + + /* get the unified vertex table OID */ + vertex_table_oid = get_relname_relid(AG_DEFAULT_LABEL_VERTEX, + graph_namespace_oid); + /* open the unified vertex table and begin the scan */ + graph_vertex_table = table_open(vertex_table_oid, ShareLock); + scan_desc = table_beginscan(graph_vertex_table, snapshot, 0, NULL); + /* get the tupdesc - we don't need to release this one */ + tupdesc = RelationGetDescr(graph_vertex_table); + /* bail if the number of columns differs (should be 3: id, properties, labels) */ + if (tupdesc->natts != 3) { - Relation graph_vertex_label; - TableScanDesc scan_desc; - HeapTuple tuple; - char *vertex_label_name; - Oid vertex_label_table_oid; - TupleDesc tupdesc; + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("Invalid number of attributes for %s.%s", + ggctx->graph_name, AG_DEFAULT_LABEL_VERTEX))); + } - /* get the vertex label name */ - vertex_label_name = lfirst(lc); - /* get the vertex label name's OID */ - vertex_label_table_oid = get_relname_relid(vertex_label_name, - graph_namespace_oid); - /* open the relation (table) and begin the scan */ - graph_vertex_label = table_open(vertex_label_table_oid, ShareLock); - scan_desc = table_beginscan(graph_vertex_label, snapshot, 0, NULL); - /* get the tupdesc - we don't need to release this one */ - tupdesc = RelationGetDescr(graph_vertex_label); - /* bail if the number of columns differs */ - if (tupdesc->natts != 2) + /* get all tuples in table and insert them into graph hashtables */ + while((tuple = heap_getnext(scan_desc, ForwardScanDirection)) != NULL) + { + graphid vertex_id; + Datum vertex_properties; + Oid label_table_oid; + bool inserted = false; + + /* something is wrong if this isn't true */ + if (!HeapTupleIsValid(tuple)) { - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("Invalid number of attributes for %s.%s", - ggctx->graph_name, vertex_label_name))); + elog(ERROR, "load_vertex_hashtable: !HeapTupleIsValid"); } - /* get all tuples in table and insert them into graph hashtables */ - while((tuple = heap_getnext(scan_desc, ForwardScanDirection)) != NULL) - { - graphid vertex_id; - Datum vertex_properties; - bool inserted = false; - - /* something is wrong if this isn't true */ - if (!HeapTupleIsValid(tuple)) - { - elog(ERROR, "load_vertex_hashtable: !HeapTupleIsValid"); - } - Assert(HeapTupleIsValid(tuple)); - - /* get the vertex id */ - vertex_id = DatumGetInt64(column_get_datum(tupdesc, tuple, 0, "id", - GRAPHIDOID, true)); - /* get the vertex properties datum */ - vertex_properties = column_get_datum(tupdesc, tuple, 1, - "properties", AGTYPEOID, true); - /* we need to make a copy of the properties datum */ - vertex_properties = datumCopy(vertex_properties, false, -1); - - /* insert vertex into vertex hashtable */ - inserted = insert_vertex_entry(ggctx, vertex_id, - vertex_label_table_oid, - vertex_properties); + Assert(HeapTupleIsValid(tuple)); - /* warn if there is a duplicate */ - if (!inserted) - { - ereport(WARNING, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("ignored duplicate vertex"))); - } + /* get the vertex id (column 0) */ + vertex_id = DatumGetInt64(column_get_datum(tupdesc, tuple, 0, "id", + GRAPHIDOID, true)); + /* get the vertex properties datum (column 1) */ + vertex_properties = column_get_datum(tupdesc, tuple, 1, + "properties", AGTYPEOID, true); + /* get the label table OID (column 2) */ + label_table_oid = DatumGetObjectId(column_get_datum(tupdesc, tuple, 2, + "labels", OIDOID, true)); + + /* we need to make a copy of the properties datum */ + vertex_properties = datumCopy(vertex_properties, false, -1); + + /* insert vertex into vertex hashtable */ + inserted = insert_vertex_entry(ggctx, vertex_id, + label_table_oid, + vertex_properties); + + /* warn if there is a duplicate */ + if (!inserted) + { + ereport(WARNING, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("ignored duplicate vertex"))); } - - /* end the scan and close the relation */ - table_endscan(scan_desc); - table_close(graph_vertex_label, ShareLock); } + + /* end the scan and close the relation */ + table_endscan(scan_desc); + table_close(graph_vertex_table, ShareLock); } /* diff --git a/src/backend/utils/adt/age_vle.c b/src/backend/utils/adt/age_vle.c index f9e4c70b8..ecc082012 100644 --- a/src/backend/utils/adt/age_vle.c +++ b/src/backend/utils/adt/age_vle.c @@ -27,6 +27,7 @@ #include "utils/age_vle.h" #include "catalog/ag_graph.h" #include "catalog/ag_label.h" +#include "commands/label_commands.h" #include "nodes/cypher_nodes.h" /* defines */ @@ -1617,11 +1618,26 @@ static agtype_value *build_path(VLE_path_container *vpc) edge_entry *ee = NULL; agtype_value *agtv_vertex = NULL; agtype_value *agtv_edge = NULL; + Oid label_table_oid; /* get the vertex entry from the hashtable */ ve = get_vertex_entry(ggctx, graphid_array[index]); - /* get the label name from the oid */ - label_name = get_rel_name(get_vertex_entry_label_table_oid(ve)); + /* get the label table OID */ + label_table_oid = get_vertex_entry_label_table_oid(ve); + + /* + * Get the label name from the oid. If label_table_oid is 0 or InvalidOid, + * use the default vertex label name. + */ + if (label_table_oid == InvalidOid || label_table_oid == 0) + { + label_name = AG_DEFAULT_LABEL_VERTEX; + } + else + { + label_name = get_rel_name(label_table_oid); + } + /* reconstruct the vertex */ agtv_vertex = agtype_value_build_vertex(get_vertex_entry_id(ve), label_name, diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c index 02fc3221c..20ccdcd35 100644 --- a/src/backend/utils/adt/agtype.c +++ b/src/backend/utils/adt/agtype.c @@ -55,6 +55,8 @@ #include "utils/agtype_raw.h" #include "catalog/ag_graph.h" #include "catalog/ag_label.h" +#include "commands/label_commands.h" +#include "utils/ag_cache.h" /* State structure for Percentile aggregate functions */ typedef struct PercentileGroupAggState @@ -155,9 +157,7 @@ static bool is_object_vertex(agtype_value *agtv); static bool is_object_edge(agtype_value *agtv); static bool is_array_path(agtype_value *agtv); /* graph entity retrieval */ -static Datum get_vertex(const char *graph, const char *vertex_label, - int64 graphid); -static char *get_label_name(const char *graph_name, graphid element_graphid); +static Datum get_vertex(const char *graph, int64 graphid); static float8 get_float_compatible_arg(Datum arg, Oid type, char *funcname, bool *is_null); static Numeric get_numeric_compatible_arg(Datum arg, Oid type, char *funcname, @@ -5540,91 +5540,34 @@ Datum column_get_datum(TupleDesc tupdesc, HeapTuple tuple, int column, return result; } -/* - * Function to retrieve a label name, given the graph name and graphid of the - * node or edge. The function returns a pointer to a duplicated string that - * needs to be freed when you are finished using it. - */ -static char *get_label_name(const char *graph_name, graphid element_graphid) -{ - ScanKeyData scan_keys[2]; - Relation ag_label; - SysScanDesc scan_desc; - HeapTuple tuple; - TupleDesc tupdesc; - char *result = NULL; - bool column_is_null = false; - Oid graph_oid = get_graph_oid(graph_name); - int32 label_id = get_graphid_label_id(element_graphid); - - /* scankey for first match in ag_label, column 2, graphoid, BTEQ, OidEQ */ - ScanKeyInit(&scan_keys[0], Anum_ag_label_graph, BTEqualStrategyNumber, - F_OIDEQ, ObjectIdGetDatum(graph_oid)); - /* scankey for second match in ag_label, column 3, label id, BTEQ, Int4EQ */ - ScanKeyInit(&scan_keys[1], Anum_ag_label_id, BTEqualStrategyNumber, - F_INT4EQ, Int32GetDatum(label_id)); - - ag_label = table_open(ag_label_relation_id(), ShareLock); - scan_desc = systable_beginscan(ag_label, ag_label_graph_oid_index_id(), true, - NULL, 2, scan_keys); - - tuple = systable_getnext(scan_desc); - if (!HeapTupleIsValid(tuple)) - { - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_SCHEMA), - errmsg("graphid %lu does not exist", element_graphid))); - } - - /* get the tupdesc - we don't need to release this one */ - tupdesc = RelationGetDescr(ag_label); - - /* bail if the number of columns differs */ - if (tupdesc->natts != Natts_ag_label) - { - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("Invalid number of attributes for ag_catalog.ag_label"))); - } - - /* get the label name */ - result = NameStr(*DatumGetName(heap_getattr(tuple, Anum_ag_label_name, - tupdesc, &column_is_null))); - /* duplicate it */ - result = pstrdup(result); - - /* end the scan and close the relation */ - systable_endscan(scan_desc); - table_close(ag_label, ShareLock); - - return result; -} - -static Datum get_vertex(const char *graph, const char *vertex_label, - int64 graphid) +static Datum get_vertex(const char *graph, int64 graphid) { ScanKeyData scan_keys[1]; - Relation graph_vertex_label; + Relation graph_vertex_table; TableScanDesc scan_desc; HeapTuple tuple; TupleDesc tupdesc; - Datum id, properties, result; + Datum id, properties, labels_oid_datum; + Datum result; + Oid label_table_oid; + label_cache_data *label_cache; + char *label_name; /* get the specific graph namespace (schema) */ Oid graph_namespace_oid = get_namespace_oid(graph, false); - /* get the specific vertex label table (schema.vertex_label) */ - Oid vertex_label_table_oid = get_relname_relid(vertex_label, - graph_namespace_oid); + /* get the unified vertex table (schema._ag_label_vertex) */ + Oid vertex_table_oid = get_relname_relid(AG_DEFAULT_LABEL_VERTEX, + graph_namespace_oid); /* get the active snapshot */ Snapshot snapshot = GetActiveSnapshot(); - /* initialize the scan key */ - ScanKeyInit(&scan_keys[0], 1, BTEqualStrategyNumber, F_OIDEQ, + /* initialize the scan key to search by id */ + ScanKeyInit(&scan_keys[0], 1, BTEqualStrategyNumber, F_INT8EQ, Int64GetDatum(graphid)); - /* open the relation (table), begin the scan, and get the tuple */ - graph_vertex_label = table_open(vertex_label_table_oid, ShareLock); - scan_desc = table_beginscan(graph_vertex_label, snapshot, 1, scan_keys); + /* open the unified vertex table, begin the scan, and get the tuple */ + graph_vertex_table = table_open(vertex_table_oid, ShareLock); + scan_desc = table_beginscan(graph_vertex_table, snapshot, 1, scan_keys); tuple = heap_getnext(scan_desc, ForwardScanDirection); /* bail if the tuple isn't valid */ @@ -5636,25 +5579,43 @@ static Datum get_vertex(const char *graph, const char *vertex_label, } /* get the tupdesc - we don't need to release this one */ - tupdesc = RelationGetDescr(graph_vertex_label); - /* bail if the number of columns differs */ - if (tupdesc->natts != 2) + tupdesc = RelationGetDescr(graph_vertex_table); + /* bail if the number of columns differs (should be 3: id, properties, labels) */ + if (tupdesc->natts != 3) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("Invalid number of attributes for %s.%s", graph, - vertex_label ))); + AG_DEFAULT_LABEL_VERTEX))); - /* get the id */ + /* get the id (column 0) */ id = column_get_datum(tupdesc, tuple, 0, "id", GRAPHIDOID, true); - /* get the properties */ + /* get the properties (column 1) */ properties = column_get_datum(tupdesc, tuple, 1, "properties", AGTYPEOID, true); + /* get the labels column (column 2) - contains label table OID */ + labels_oid_datum = column_get_datum(tupdesc, tuple, 2, "labels", OIDOID, true); + label_table_oid = DatumGetObjectId(labels_oid_datum); + + /* look up the label name from the label table OID using the cache */ + label_cache = search_label_relation_cache(label_table_oid); + if (label_cache == NULL) + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("label with relation oid %u does not exist", label_table_oid))); + } + + /* get the label name - return empty string for default labels */ + label_name = NameStr(label_cache->name); + if (IS_AG_DEFAULT_LABEL(label_name)) + label_name = ""; + /* reconstruct the vertex */ result = DirectFunctionCall3(_agtype_build_vertex, id, - CStringGetDatum(vertex_label), properties); + CStringGetDatum(label_name), properties); /* end the scan and close the relation */ table_endscan(scan_desc); - table_close(graph_vertex_label, ShareLock); + table_close(graph_vertex_table, ShareLock); /* return the vertex datum */ return result; } @@ -5667,7 +5628,6 @@ Datum age_startnode(PG_FUNCTION_ARGS) agtype_value *agtv_object = NULL; agtype_value *agtv_value = NULL; char *graph_name = NULL; - char *label_name = NULL; graphid start_id; Datum result; @@ -5712,12 +5672,8 @@ Datum age_startnode(PG_FUNCTION_ARGS) Assert(agtv_value->type = AGTV_INTEGER); start_id = agtv_value->val.int_value; - /* get the label */ - label_name = get_label_name(graph_name, start_id); - /* it must not be null and must be a string */ - Assert(label_name != NULL); - - result = get_vertex(graph_name, label_name, start_id); + /* get the vertex - label is read from the labels column */ + result = get_vertex(graph_name, start_id); return result; } @@ -5730,7 +5686,6 @@ Datum age_endnode(PG_FUNCTION_ARGS) agtype_value *agtv_object = NULL; agtype_value *agtv_value = NULL; char *graph_name = NULL; - char *label_name = NULL; graphid end_id; Datum result; @@ -5775,12 +5730,8 @@ Datum age_endnode(PG_FUNCTION_ARGS) Assert(agtv_value->type = AGTV_INTEGER); end_id = agtv_value->val.int_value; - /* get the label */ - label_name = get_label_name(graph_name, end_id); - /* it must not be null and must be a string */ - Assert(label_name != NULL); - - result = get_vertex(graph_name, label_name, end_id); + /* get the vertex - label is read from the labels column */ + result = get_vertex(graph_name, end_id); return result; } diff --git a/src/backend/utils/load/ag_load_labels.c b/src/backend/utils/load/ag_load_labels.c index 1e86bbda4..e79b6ec16 100644 --- a/src/backend/utils/load/ag_load_labels.c +++ b/src/backend/utils/load/ag_load_labels.c @@ -111,8 +111,11 @@ void vertex_row_cb(int delim __attribute__((unused)), void *data) create_agtype_from_list(cr->header, cr->fields, n_fields, entry_id, cr->load_as_agtype)); + /* Set the labels column to the label table OID */ + slot->tts_values[2] = ObjectIdGetDatum(get_label_relation(cr->label_name, cr->graph_oid)); slot->tts_isnull[0] = false; slot->tts_isnull[1] = false; + slot->tts_isnull[2] = false; /* Make the slot as containing virtual tuple */ ExecStoreVirtualTuple(slot); diff --git a/src/backend/utils/load/age_load.c b/src/backend/utils/load/age_load.c index c7cf0677f..d33a6b5c0 100644 --- a/src/backend/utils/load/age_load.c +++ b/src/backend/utils/load/age_load.c @@ -313,10 +313,11 @@ void insert_vertex_simple(Oid graph_oid, char *label_name, graphid vertex_id, agtype *vertex_properties) { - Datum values[2]; - bool nulls[2] = {false, false}; + Datum values[3]; + bool nulls[3] = {false, false, false}; Relation label_relation; HeapTuple tuple; + Oid label_table_oid; /* Check if label provided exists as edge label, then throw error */ if (get_label_kind(label_name, graph_oid) == LABEL_KIND_EDGE) @@ -326,13 +327,17 @@ void insert_vertex_simple(Oid graph_oid, char *label_name, graphid vertex_id, label_name))); } - /* Open the relation */ - label_relation = table_open(get_label_relation(label_name, graph_oid), + /* Get the label table OID for the labels column */ + label_table_oid = get_label_relation(label_name, graph_oid); + + /* Open the unified vertex table */ + label_relation = table_open(get_label_relation(AG_DEFAULT_LABEL_VERTEX, graph_oid), RowExclusiveLock); - /* Form the tuple */ + /* Form the tuple with all 3 columns: id, properties, labels */ values[0] = GRAPHID_GET_DATUM(vertex_id); values[1] = AGTYPE_P_GET_DATUM((vertex_properties)); + values[2] = ObjectIdGetDatum(label_table_oid); tuple = heap_form_tuple(RelationGetDescr(label_relation), values, nulls); @@ -598,9 +603,20 @@ void init_batch_insert(batch_insert_state **batch_state, EState *estate; ResultRelInfo *resultRelInfo; int i; + char label_kind; - /* Open the relation */ - relid = get_label_relation(label_name, graph_oid); + /* Check if this is a vertex or edge label */ + label_kind = get_label_kind(label_name, graph_oid); + + /* For vertices, use the unified vertex table; for edges, use label-specific table */ + if (label_kind == LABEL_KIND_VERTEX) + { + relid = get_label_relation(AG_DEFAULT_LABEL_VERTEX, graph_oid); + } + else + { + relid = get_label_relation(label_name, graph_oid); + } relation = table_open(relid, RowExclusiveLock); /* Initialize executor state */ diff --git a/src/include/catalog/ag_label.h b/src/include/catalog/ag_label.h index 0a8480b1a..f05889df9 100644 --- a/src/include/catalog/ag_label.h +++ b/src/include/catalog/ag_label.h @@ -24,6 +24,7 @@ #define Anum_ag_label_vertex_table_id 1 #define Anum_ag_label_vertex_table_properties 2 +#define Anum_ag_label_vertex_table_labels 3 #define Anum_ag_label_edge_table_id 1 #define Anum_ag_label_edge_table_start_id 2 @@ -32,6 +33,7 @@ #define vertex_tuple_id Anum_ag_label_vertex_table_id - 1 #define vertex_tuple_properties Anum_ag_label_vertex_table_properties - 1 +#define vertex_tuple_labels Anum_ag_label_vertex_table_labels - 1 #define edge_tuple_id Anum_ag_label_edge_table_id - 1 #define edge_tuple_start_id Anum_ag_label_edge_table_start_id - 1 diff --git a/src/include/commands/label_commands.h b/src/include/commands/label_commands.h index cfbbdb336..9fb8a0721 100644 --- a/src/include/commands/label_commands.h +++ b/src/include/commands/label_commands.h @@ -28,6 +28,7 @@ #define AG_VERTEX_COLNAME_ID "id" #define AG_VERTEX_COLNAME_PROPERTIES "properties" +#define AG_VERTEX_COLNAME_LABELS "labels" #define AG_ACCESS_FUNCTION_ID "age_id" diff --git a/src/include/executor/cypher_utils.h b/src/include/executor/cypher_utils.h index 0798f153c..4c008abe6 100644 --- a/src/include/executor/cypher_utils.h +++ b/src/include/executor/cypher_utils.h @@ -119,7 +119,7 @@ ResultRelInfo *create_entity_result_rel_info(EState *estate, char *graph_name, char *label_name); void destroy_entity_result_rel_info(ResultRelInfo *result_rel_info); -bool entity_exists(EState *estate, Oid graph_oid, graphid id); +bool vertex_exists(EState *estate, Oid graph_oid, graphid id); HeapTuple insert_entity_tuple(ResultRelInfo *resultRelInfo, TupleTableSlot *elemTupleSlot, EState *estate); diff --git a/src/include/nodes/cypher_nodes.h b/src/include/nodes/cypher_nodes.h index db47eb313..0a0987157 100644 --- a/src/include/nodes/cypher_nodes.h +++ b/src/include/nodes/cypher_nodes.h @@ -379,6 +379,8 @@ typedef struct cypher_target_node TupleTableSlot *elemTupleSlot; /* relid that the label stores its entity */ Oid relid; + /* label table OID for the labels column in unified vertex table */ + Oid label_table_oid; /* label this entity belongs to. */ char *label_name; /* variable name for this entity */