Skip to content

Commit 1bf9ff5

Browse files
committed
Make age extension usable from shared_preload_libraries
When AGE is loaded via shared_preload_libraries, its hooks (post_parse_analyze, set_rel_pathlist, object_access) are active before CREATE EXTENSION age is run. This causes errors when non-Cypher queries trigger those hooks and ag_catalog does not yet exist. Changes: - Add is_age_extension_exist() with a relcache callback cache so that checking pg_extension is not repeated on every hook invocation. - Guard post_parse_analyze, set_rel_pathlist, and object_access hooks with is_age_extension_exist() so they become no-ops when the extension is not installed. - Refactor ag_ProcessUtility_hook to detect CREATE/DROP EXTENSION age and broadcast a relcache invalidation via CacheInvalidateRelcacheByRelid(ExtensionRelationId) so other backends update their cached extension state. - Wrap DROP EXTENSION processing in PG_TRY/PG_CATCH to restore object_access_hook if the drop fails (e.g. dependent objects). - Skip _PG_init during pg_upgrade (IsBinaryUpgrade) to avoid hook registration when the binary-upgrade machinery is running. - Add regression tests that verify hooks do not error when ag_catalog schema is absent.
1 parent 23cbe57 commit 1bf9ff5

9 files changed

Lines changed: 208 additions & 42 deletions

File tree

regress/expected/cypher_vle.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,8 @@ NOTICE: graph "cypher_vle" has been dropped
12191219

12201220
(1 row)
12211221

1222+
DROP FUNCTION prepend_node(text, text);
1223+
DROP FUNCTION create_list(text);
12221224
--
12231225
-- End
12241226
--

regress/expected/drop.out

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'ag_catalog';
4040
-----------
4141
(0 rows)
4242

43+
-- When ag_catalog is missing extension hooks shouldn't fail with the
44+
-- ERROR schema "ag_catalog" does not exist.
45+
-- It might happen when 'age' is loaded but extension isn't created yet.
46+
DROP SCHEMA ag_catalog;
47+
CREATE SCHEMA _regress_drop;
48+
DROP SCHEMA _regress_drop; -- shouldn't produce the ERROR
4349
-- Recreate the extension and validate we can recreate a graph
4450
CREATE EXTENSION age;
4551
SELECT create_graph('drop');
@@ -115,7 +121,7 @@ NOTICE: label "issue_1305"."r" has been dropped
115121
(1 row)
116122

117123
SELECT drop_label('issue_1305', 'r');
118-
ERROR: rel_name not found for label "r"
124+
ERROR: label "r" does not exist
119125
SELECT drop_label('issue_1305', 'n', false);
120126
NOTICE: label "issue_1305"."n" has been dropped
121127
drop_label
@@ -124,7 +130,20 @@ NOTICE: label "issue_1305"."n" has been dropped
124130
(1 row)
125131

126132
SELECT drop_label('issue_1305', 'n');
127-
ERROR: rel_name not found for label "n"
133+
ERROR: label "n" does not exist
134+
-- Validate that labels are removed and tables are dropped
135+
select COUNT(*) FROM ag_label WHERE name IN ('n', 'r');
136+
count
137+
-------
138+
0
139+
(1 row)
140+
141+
SELECT COUNT(*) FROM pg_catalog.pg_tables WHERE schemaname = 'issue_1305' AND tablename IN ('n', 'r');
142+
count
143+
-------
144+
0
145+
(1 row)
146+
128147
SELECT * FROM drop_graph('issue_1305', true);
129148
NOTICE: drop cascades to 2 other objects
130149
DETAIL: drop cascades to table issue_1305._ag_label_vertex

regress/sql/cypher_vle.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@ DROP TABLE start_and_end_points;
418418

419419
SELECT drop_graph('cypher_vle', true);
420420

421+
DROP FUNCTION prepend_node(text, text);
422+
DROP FUNCTION create_list(text);
421423
--
422424
-- End
423425
--

regress/sql/drop.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ SELECT nspname FROM pg_catalog.pg_namespace WHERE nspname = 'drop';
2828

2929
SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'ag_catalog';
3030

31+
-- When ag_catalog is missing extension hooks shouldn't fail with the
32+
-- ERROR schema "ag_catalog" does not exist.
33+
-- It might happen when 'age' is loaded but extension isn't created yet.
34+
DROP SCHEMA ag_catalog;
35+
CREATE SCHEMA _regress_drop;
36+
DROP SCHEMA _regress_drop; -- shouldn't produce the ERROR
37+
3138
-- Recreate the extension and validate we can recreate a graph
3239
CREATE EXTENSION age;
3340

@@ -61,6 +68,11 @@ SELECT drop_label('issue_1305', 'r', false);
6168
SELECT drop_label('issue_1305', 'r');
6269
SELECT drop_label('issue_1305', 'n', false);
6370
SELECT drop_label('issue_1305', 'n');
71+
72+
-- Validate that labels are removed and tables are dropped
73+
select COUNT(*) FROM ag_label WHERE name IN ('n', 'r');
74+
SELECT COUNT(*) FROM pg_catalog.pg_tables WHERE schemaname = 'issue_1305' AND tablename IN ('n', 'r');
75+
6476
SELECT * FROM drop_graph('issue_1305', true);
6577

6678
-- END

src/backend/age.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
* under the License.
1818
*/
1919

20+
#include "postgres.h"
21+
#include "miscadmin.h"
22+
2023
#include "catalog/ag_catalog.h"
2124
#include "nodes/ag_nodes.h"
2225
#include "optimizer/cypher_paths.h"
@@ -25,7 +28,6 @@
2528
#include "utils/age_global_graph.h"
2629

2730
#if PG_VERSION_NUM < 170000
28-
#include "miscadmin.h"
2931

3032
/* saved hook pointers for PG < 17 shmem path */
3133
static shmem_request_hook_type prev_shmem_request_hook = NULL;
@@ -56,6 +58,9 @@ void _PG_init(void);
5658

5759
void _PG_init(void)
5860
{
61+
if (IsBinaryUpgrade)
62+
return;
63+
5964
register_ag_nodes();
6065
set_rel_pathlist_init();
6166
object_access_hook_init();

0 commit comments

Comments
 (0)