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