@@ -53,3 +53,100 @@ CREATE FUNCTION ag_catalog._ag_enforce_edge_uniqueness4(graphid, graphid, graphi
5353 STABLE
5454PARALLEL SAFE
5555as ' MODULE_PATHNAME' ;
56+
57+ -- Create indexes on id columns for existing labels
58+ -- Vertex labels get PRIMARY KEY on id, Edge labels get indexes on start_id/end_id
59+ DO $$
60+ DECLARE
61+ label_rec record;
62+ schema_name text ;
63+ table_name text ;
64+ idx_exists boolean ;
65+ pk_exists boolean ;
66+ idx_name text ;
67+ BEGIN
68+ FOR label_rec IN
69+ SELECT l .relation , l .kind
70+ FROM ag_catalog .ag_label l
71+ LOOP
72+ SELECT n .nspname , c .relname INTO schema_name, table_name
73+ FROM pg_class c
74+ JOIN pg_namespace n ON c .relnamespace = n .oid
75+ WHERE c .oid = label_rec .relation ;
76+
77+ IF label_rec .kind = ' e' THEN
78+ -- Edge: check/create index on start_id
79+ SELECT EXISTS (
80+ SELECT 1 FROM pg_index i
81+ JOIN pg_class c ON c .oid = i .indexrelid
82+ JOIN pg_am am ON am .oid = c .relam
83+ JOIN pg_attribute a ON a .attrelid = i .indrelid AND a .attnum = i .indkey [0 ]
84+ WHERE i .indrelid = label_rec .relation
85+ AND a .attname = ' start_id'
86+ AND i .indpred IS NULL -- not a partial index
87+ AND i .indexprs IS NULL -- not an expression index
88+ AND am .amname = ' btree' -- btree access method
89+ ) INTO idx_exists;
90+
91+ IF NOT idx_exists THEN
92+ EXECUTE format(' CREATE INDEX %I ON %I.%I USING btree (start_id)' ,
93+ table_name || ' _start_id_idx' , schema_name, table_name);
94+ END IF;
95+
96+ -- Edge: check/create index on end_id
97+ SELECT EXISTS (
98+ SELECT 1 FROM pg_index i
99+ JOIN pg_class c ON c .oid = i .indexrelid
100+ JOIN pg_am am ON am .oid = c .relam
101+ JOIN pg_attribute a ON a .attrelid = i .indrelid AND a .attnum = i .indkey [0 ]
102+ WHERE i .indrelid = label_rec .relation
103+ AND a .attname = ' end_id'
104+ AND i .indpred IS NULL -- not a partial index
105+ AND i .indexprs IS NULL -- not an expression index
106+ AND am .amname = ' btree' -- btree access method
107+ ) INTO idx_exists;
108+
109+ IF NOT idx_exists THEN
110+ EXECUTE format(' CREATE INDEX %I ON %I.%I USING btree (end_id)' ,
111+ table_name || ' _end_id_idx' , schema_name, table_name);
112+ END IF;
113+ ELSE
114+ -- Vertex: check/create PRIMARY KEY on id
115+ SELECT EXISTS (
116+ SELECT 1 FROM pg_constraint
117+ WHERE conrelid = label_rec .relation AND contype = ' p'
118+ ) INTO pk_exists;
119+
120+ IF NOT pk_exists THEN
121+ -- Check if a usable unique index on id already exists
122+ SELECT c .relname INTO idx_name
123+ FROM pg_index i
124+ JOIN pg_class c ON c .oid = i .indexrelid
125+ JOIN pg_am am ON am .oid = c .relam
126+ WHERE i .indrelid = label_rec .relation
127+ AND i .indisunique = true
128+ AND i .indpred IS NULL -- not a partial index
129+ AND i .indexprs IS NULL -- not an expression index
130+ AND am .amname = ' btree' -- btree access method
131+ AND i .indnkeyatts = 1 -- single column index
132+ AND EXISTS (
133+ SELECT 1 FROM pg_attribute a
134+ WHERE a .attrelid = i .indrelid
135+ AND a .attnum = i .indkey [0 ]
136+ AND a .attname = ' id'
137+ )
138+ LIMIT 1 ;
139+
140+ IF idx_name IS NOT NULL THEN
141+ -- Reuse existing unique index for primary key
142+ EXECUTE format(' ALTER TABLE %I.%I ADD CONSTRAINT %I PRIMARY KEY USING INDEX %I' ,
143+ schema_name, table_name, table_name || ' _pkey' , idx_name);
144+ ELSE
145+ -- Create new primary key
146+ EXECUTE format(' ALTER TABLE %I.%I ADD PRIMARY KEY (id)' ,
147+ schema_name, table_name);
148+ END IF;
149+ END IF;
150+ END IF;
151+ END LOOP;
152+ END $$;
0 commit comments