Skip to content

Commit 2e2120b

Browse files
authored
Fix create_graph failing when ag_catalog is not in search_path (#2505)
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 #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.
1 parent 0e30566 commit 2e2120b

3 files changed

Lines changed: 72 additions & 1 deletion

File tree

‎regress/expected/catalog.out‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,3 +607,55 @@ NOTICE: graph "graph" has been dropped
607607

608608
(1 row)
609609

610+
--
611+
-- create_label() must not resolve graphid_ops through the search_path
612+
--
613+
-- Every AGE object is referenced with an ag_catalog qualified name here, so
614+
-- these statements have to work with ag_catalog off the search_path.
615+
--
616+
SET search_path TO public;
617+
SELECT ag_catalog.create_graph('graphid_ops_search_path');
618+
NOTICE: graph "graphid_ops_search_path" has been created
619+
create_graph
620+
--------------
621+
622+
(1 row)
623+
624+
-- vertex labels index id, edge labels index start_id and end_id
625+
SELECT ag_catalog.create_vlabel('graphid_ops_search_path', 'v');
626+
NOTICE: VLabel "v" has been created
627+
create_vlabel
628+
---------------
629+
630+
(1 row)
631+
632+
SELECT ag_catalog.create_elabel('graphid_ops_search_path', 'e');
633+
NOTICE: ELabel "e" has been created
634+
create_elabel
635+
---------------
636+
637+
(1 row)
638+
639+
-- label creation at query time goes through the same path
640+
SELECT * FROM ag_catalog.cypher('graphid_ops_search_path',
641+
$$CREATE (:query_time_v)-[:query_time_e]->(:query_time_v)$$)
642+
AS (result ag_catalog.agtype);
643+
result
644+
--------
645+
(0 rows)
646+
647+
SELECT ag_catalog.drop_graph('graphid_ops_search_path', true);
648+
NOTICE: drop cascades to 6 other objects
649+
DETAIL: drop cascades to table graphid_ops_search_path._ag_label_vertex
650+
drop cascades to table graphid_ops_search_path._ag_label_edge
651+
drop cascades to table graphid_ops_search_path.v
652+
drop cascades to table graphid_ops_search_path.e
653+
drop cascades to table graphid_ops_search_path.query_time_v
654+
drop cascades to table graphid_ops_search_path.query_time_e
655+
NOTICE: graph "graphid_ops_search_path" has been dropped
656+
drop_graph
657+
------------
658+
659+
(1 row)
660+
661+
SET search_path TO ag_catalog;

‎regress/sql/catalog.sql‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,21 @@ SELECT count(*) FROM ag_label;
235235
-- dropping the graphs
236236
SELECT drop_graph('issue_2245', true);
237237
SELECT drop_graph('graph', true);
238+
239+
--
240+
-- create_label() must not resolve graphid_ops through the search_path
241+
--
242+
-- Every AGE object is referenced with an ag_catalog qualified name here, so
243+
-- these statements have to work with ag_catalog off the search_path.
244+
--
245+
SET search_path TO public;
246+
SELECT ag_catalog.create_graph('graphid_ops_search_path');
247+
-- vertex labels index id, edge labels index start_id and end_id
248+
SELECT ag_catalog.create_vlabel('graphid_ops_search_path', 'v');
249+
SELECT ag_catalog.create_elabel('graphid_ops_search_path', 'e');
250+
-- label creation at query time goes through the same path
251+
SELECT * FROM ag_catalog.cypher('graphid_ops_search_path',
252+
$$CREATE (:query_time_v)-[:query_time_e]->(:query_time_v)$$)
253+
AS (result ag_catalog.agtype);
254+
SELECT ag_catalog.drop_graph('graphid_ops_search_path', true);
255+
SET search_path TO ag_catalog;

‎src/backend/commands/label_commands.c‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,8 @@ static void create_index_on_column(char *schema_name,
509509
index_col->expr = NULL;
510510
index_col->indexcolname = NULL;
511511
index_col->collation = NIL;
512-
index_col->opclass = list_make1(makeString("graphid_ops"));
512+
index_col->opclass = list_make2(makeString("ag_catalog"),
513+
makeString("graphid_ops"));
513514
index_col->opclassopts = NIL;
514515
index_col->ordering = SORTBY_DEFAULT;
515516
index_col->nulls_ordering = SORTBY_NULLS_DEFAULT;

0 commit comments

Comments
 (0)