Skip to content

Make age extension usable from shared_preload_libraries#2438

Open
serdarmumcu wants to merge 1 commit into
apache:masterfrom
serdarmumcu:feature/shared-preload-libraries-support
Open

Make age extension usable from shared_preload_libraries#2438
serdarmumcu wants to merge 1 commit into
apache:masterfrom
serdarmumcu:feature/shared-preload-libraries-support

Conversation

@serdarmumcu

Copy link
Copy Markdown
Contributor

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.

@jrgemignani

jrgemignani commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

@serdarmumcu The build has an error -

image

This needs to be fixed.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the AGE shared library safe to load via shared_preload_libraries by ensuring its hooks become no-ops until the age extension is actually installed, avoiding failures when ag_catalog doesn’t exist yet.

Changes:

  • Adds a cached pg_extension existence check and uses it to guard key hooks (post_parse_analyze, set_rel_pathlist, object_access).
  • Updates ProcessUtility hook logic to detect CREATE/DROP EXTENSION age, invalidate the cached state across backends, and safely restore hooks on failure.
  • Extends regression coverage to validate hook behavior when ag_catalog is absent and improves cleanup in VLE regression SQL.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/include/catalog/ag_catalog.h Exposes the new AGE-extension existence check API.
src/backend/parser/cypher_analyze.c Guards post-parse analysis hook when AGE extension isn’t installed.
src/backend/optimizer/cypher_paths.c Guards planner hook when AGE extension isn’t installed.
src/backend/catalog/ag_catalog.c Implements extension-existence caching, hook guarding, and cross-backend invalidation on create/drop.
src/backend/age.c Skips _PG_init during binary upgrade to avoid hook registration during pg_upgrade.
regress/sql/drop.sql Adds regression coverage for hook safety when ag_catalog is missing.
regress/sql/cypher_vle.sql Adds missing cleanup for helper functions created during the test.
regress/expected/drop.out / regress/expected/cypher_vle.out Updates expected outputs to match the new regression behavior.
Comments suppressed due to low confidence (1)

src/backend/catalog/ag_catalog.c:272

  • drop_age_extension() is now unused (no remaining call sites). With the project building with COPT=-Werror in CI, an unused static function is likely to trigger -Wunused-function and fail the build; the forward declaration at the top should be removed as well.
static void drop_age_extension(DropStmt *stmt)
{
    /* Remove all graphs */
    drop_graphs(get_graphnames());

    /* Remove the object access hook */
    object_access_hook_fini();

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +57 to +62
static void
invalidate_extension_cache_callback(Datum argument, Oid relationId)
{
if (relationId == ExtensionRelationId)
extension_cache_is_valid = false;
}

#include "utils/agtype.h"

bool is_age_extension_exist(void);
Comment thread regress/sql/drop.sql
-- When ag_catalog is missing extension hooks shouldn't fail with the
-- ERROR schema "ag_catalog" does not exist.
-- It might happen when 'age' is loaded but extension isn't created yet.
DROP SCHEMA ag_catalog;
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.
@serdarmumcu serdarmumcu force-pushed the feature/shared-preload-libraries-support branch from 1bf9ff5 to bc56b00 Compare June 12, 2026 12:29
@serdarmumcu

Copy link
Copy Markdown
Contributor Author

@serdarmumcu The build has an error -

image This needs to be fixed.

@jrgemignani Fixed — removed the dead drop_age_extension() function and also cleaned up unrelated changes from internal branches that had leaked into the PR. The commit now only contains changes related to shared_preload_libraries support. Ready for re-review.

@serdarmumcu serdarmumcu reopened this Jun 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants