Skip to content

Fix create_graph failing when ag_catalog is not in search_path - #1

Merged
NotHimmel merged 1 commit into
IvorySQL:release/PG18/1.7.0from
NotHimmel:fix/qualify-graphid-ops-PG18
Aug 18, 2026
Merged

Fix create_graph failing when ag_catalog is not in search_path#1
NotHimmel merged 1 commit into
IvorySQL:release/PG18/1.7.0from
NotHimmel:fix/qualify-graphid-ops-PG18

Conversation

@NotHimmel

Copy link
Copy Markdown
Collaborator

Backport of a fix for the 1.7.0 line. Upstream: apache#2505 (PR), apache#2504 (issue).

Problem

With ag_catalog absent from search_path, creating a graph fails even for a
fully schema qualified call:

LOAD 'age';
SHOW search_path;          --  "$user", public

SELECT ag_catalog.create_graph('g');
-- ERROR:  operator class "graphid_ops" does not exist for access method "btree"

Same failure for create_vlabel(), create_elabel(), the CSV loader, and a
CREATE/MERGE clause that mentions a label for the first time — the last one
fails in the middle of a running query. GRANT USAGE ON SCHEMA ag_catalog and
GRANT EXECUTE do not help, because the operator class exists and is simply
not visible.

Root cause

create_index_on_column() passed the operator class as an unqualified name, so
ResolveOpClass() resolved it through the caller's search_path:

index_col->opclass = list_make1(makeString("graphid_ops"));

This was the only unqualified name on that code path. Column types are reached
by OID (GRAPHIDOID, AGTYPEOID), and _graphid(), agtype_build_map() and
_label_id() are already built with list_make2(makeString("ag_catalog"), ...).

The unqualified name arrived with the id column indexes in apache#2117, so
this is a regression against 1.6.0, where create_label() built no index and
resolved no name through search_path.

Testing

PostgreSQL 18.4, built from source: # All 31 tests passed.

Reverting the change and re-running reproduces the error above, so the
one-line change is what fixes it.

Note this does not remove the documented search_path requirement for
querying a graph — some names in the query path are still resolved
unqualified. It only restores create_graph() to not depending on it.

create_index_on_column() passed "graphid_ops" as an unqualified operator
class name, so it was resolved against the caller's search_path. Whenever
ag_catalog was not on the search_path, creating a label failed with

  ERROR:  operator class "graphid_ops" does not exist for access method "btree"

even for a fully qualified call such as

  SELECT ag_catalog.create_graph('g');

The error is misleading: the operator class does exist, it is simply not
visible. This affected create_graph(), create_vlabel(), create_elabel(),
the CSV loader, and label creation from a CREATE or MERGE clause at query
time, since all of them reach create_label().

The unqualified name arrived with the id column indexes in apache#2117, so this
is a regression. Before that commit create_label() built no index and
resolved no name through the search_path. Every other object referenced by
the DDL that create_label() generates is already reached either by OID or
by an ag_catalog qualified name, so qualifying this one restores the
previous behaviour.
@NotHimmel
NotHimmel merged commit 9886b35 into IvorySQL:release/PG18/1.7.0 Aug 18, 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.

1 participant