This is an automated email from the ASF dual-hosted git repository.
muhammadshoaib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/age.git
The following commit(s) were added to refs/heads/master by this push:
new 34483efa age_global_graph: stabilize regression tests (#2431)
34483efa is described below
commit 34483efaf1eb0724bf92adda18f06973a1f4a3e1
Author: John Gemignani <[email protected]>
AuthorDate: Sat Jun 20 09:57:33 2026 -0700
age_global_graph: stabilize regression tests (#2431)
age_global_graph: stabilize regression tests under concurrent xid load
Wrap both vertex_stats() context-building phases in a single
BEGIN ISOLATION LEVEL REPEATABLE READ; ... COMMIT; transaction so the
three calls share one snapshot. This prevents the snapshot-fallback path
in is_ggctx_invalid() from purging an already-built graph context when
concurrent xid activity (autovacuum, parallel installcheck, replication,
shared CI) advances the snapshot between calls, which would otherwise
make the targeted delete_global_graphs(name) checks return false instead
of the expected true. Read Committed is insufficient because it acquires
a fresh snapshot per statement; REPEATABLE READ pins one snapshot for the
whole transaction.
Also add explicit ORDER BY id to the three direct-SQL label-table SELECTs
(_ag_label_vertex x2, _ag_label_edge) that return multiple rows, so their
output no longer depends on heap scan order.
This is a test-only change (regress/sql/age_global_graph.sql and
regress/expected/age_global_graph.out); no extension C code or SQL is
modified.
All 37 regression tests pass (installcheck) on PostgreSQL 18.3.
Co-authored-by: GitHub Copilot <[email protected]>
modified: regress/expected/age_global_graph.out
modified: regress/sql/age_global_graph.sql
---
regress/expected/age_global_graph.out | 19 ++++++++++++++++---
regress/sql/age_global_graph.sql | 19 ++++++++++++++++---
2 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/regress/expected/age_global_graph.out
b/regress/expected/age_global_graph.out
index cbfeb6f3..4833511a 100644
--- a/regress/expected/age_global_graph.out
+++ b/regress/expected/age_global_graph.out
@@ -44,6 +44,14 @@ SELECT * FROM cypher('ag_graph_3', $$ CREATE (v:vertex3)
RETURN v $$) AS (v agt
(1 row)
-- load contexts using the vertex_stats command
+-- Build all three graph contexts under one snapshot. The vertex_stats()
+-- calls are wrapped in a single REPEATABLE READ transaction so they share
+-- one snapshot; this keeps the snapshot-fallback path in is_ggctx_invalid()
+-- from purging an already-built context when concurrent xid activity
+-- (autovacuum, parallel installcheck, replication) advances the snapshot
+-- between calls. Read Committed is insufficient: it takes a fresh snapshot
+-- per statement.
+BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT * FROM cypher('ag_graph_3', $$ MATCH (u) RETURN vertex_stats(u) ORDER
BY id(u) $$) AS (result agtype);
result
-----------------------------------------------------------------------------------------------
@@ -62,6 +70,7 @@ SELECT * FROM cypher('ag_graph_1', $$ MATCH (u) RETURN
vertex_stats(u) ORDER BY
{"id": 844424930131969, "label": "vertex1", "in_degree": 0, "out_degree": 0,
"self_loops": 0}
(1 row)
+COMMIT;
--- loading undefined contexts
--- should throw exception - graph "ag_graph_4" does not exist
SELECT * FROM cypher('ag_graph_4', $$ MATCH (u) RETURN vertex_stats(u) ORDER
BY id(u) $$) AS (result agtype);
@@ -130,6 +139,9 @@ LINE 1: SELECT * FROM cypher('ag_graph_4', $$ RETURN
delete_global_g...
-- delete_GRAPH_global_contexts
--
-- load contexts again
+-- Same REPEATABLE READ wrap as the first build phase above, for the same
+-- snapshot-stability reason.
+BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT * FROM cypher('ag_graph_3', $$ MATCH (u) RETURN vertex_stats(u) ORDER
BY id(u) $$) AS (result agtype);
result
-----------------------------------------------------------------------------------------------
@@ -148,6 +160,7 @@ SELECT * FROM cypher('ag_graph_1', $$ MATCH (u) RETURN
vertex_stats(u) ORDER BY
{"id": 844424930131969, "label": "vertex1", "in_degree": 0, "out_degree": 0,
"self_loops": 0}
(1 row)
+COMMIT;
-- delete all graph contexts
-- should return true
SELECT * FROM cypher('ag_graph_1', $$ RETURN delete_global_graphs(NULL) $$) AS
(result agtype);
@@ -306,7 +319,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 * FROM ag_graph_1._ag_label_vertex ORDER BY id;
id | properties
-----------------+--------------------------------------
281474976710657 | {}
@@ -325,7 +338,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 * FROM ag_graph_1._ag_label_vertex ORDER BY id;
id | properties
-----------------+--------------------------------------
281474976710657 | {}
@@ -338,7 +351,7 @@ SELECT * FROM ag_graph_1._ag_label_vertex;
844424930131969 | {}
(8 rows)
-SELECT * FROM ag_graph_1._ag_label_edge;
+SELECT * FROM ag_graph_1._ag_label_edge ORDER BY id;
id | start_id | end_id | properties
------------------+-----------------+-----------------+------------
1125899906842625 | 281474976710659 | 281474976710660 | {}
diff --git a/regress/sql/age_global_graph.sql b/regress/sql/age_global_graph.sql
index 6ee25e1f..9f4a1ce2 100644
--- a/regress/sql/age_global_graph.sql
+++ b/regress/sql/age_global_graph.sql
@@ -16,9 +16,18 @@ SELECT * FROM create_graph('ag_graph_3');
SELECT * FROM cypher('ag_graph_3', $$ CREATE (v:vertex3) RETURN v $$) AS (v
agtype);
-- load contexts using the vertex_stats command
+-- Build all three graph contexts under one snapshot. The vertex_stats()
+-- calls are wrapped in a single REPEATABLE READ transaction so they share
+-- one snapshot; this keeps the snapshot-fallback path in is_ggctx_invalid()
+-- from purging an already-built context when concurrent xid activity
+-- (autovacuum, parallel installcheck, replication) advances the snapshot
+-- between calls. Read Committed is insufficient: it takes a fresh snapshot
+-- per statement.
+BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT * FROM cypher('ag_graph_3', $$ MATCH (u) RETURN vertex_stats(u) ORDER
BY id(u) $$) AS (result agtype);
SELECT * FROM cypher('ag_graph_2', $$ MATCH (u) RETURN vertex_stats(u) ORDER
BY id(u) $$) AS (result agtype);
SELECT * FROM cypher('ag_graph_1', $$ MATCH (u) RETURN vertex_stats(u) ORDER
BY id(u) $$) AS (result agtype);
+COMMIT;
--- loading undefined contexts
--- should throw exception - graph "ag_graph_4" does not exist
@@ -55,9 +64,13 @@ SELECT * FROM cypher('ag_graph_4', $$ RETURN
delete_global_graphs('ag_graph_4')
--
-- load contexts again
+-- Same REPEATABLE READ wrap as the first build phase above, for the same
+-- snapshot-stability reason.
+BEGIN ISOLATION LEVEL REPEATABLE READ;
SELECT * FROM cypher('ag_graph_3', $$ MATCH (u) RETURN vertex_stats(u) ORDER
BY id(u) $$) AS (result agtype);
SELECT * FROM cypher('ag_graph_2', $$ MATCH (u) RETURN vertex_stats(u) ORDER
BY id(u) $$) AS (result agtype);
SELECT * FROM cypher('ag_graph_1', $$ MATCH (u) RETURN vertex_stats(u) ORDER
BY id(u) $$) AS (result agtype);
+COMMIT;
-- delete all graph contexts
-- should return true
@@ -115,12 +128,12 @@ SELECT * FROM cypher('ag_graph_1', $$ MATCH (u)-[e]->(v)
RETURN u, e, v ORDER BY
-- 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 * 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 * FROM ag_graph_1._ag_label_edge;
+SELECT * FROM ag_graph_1._ag_label_vertex ORDER BY id;
+SELECT * FROM ag_graph_1._ag_label_edge ORDER BY id;
-- The graph_stats query below will produce warnings for the dangling edges
-- created by the DELETE commands above. The warnings appear in
nondeterministic
-- order because they come from iterating edge label tables (knows, stalks),