From 9e046fbebf69e7cc40419fe7b33ab5e933c958f4 Mon Sep 17 00:00:00 2001 From: Devansh Saxena Date: Mon, 22 Jul 2024 22:23:37 +0530 Subject: [PATCH] [#23163] YSQL: pg_partman: make 'inherit_template_properties' idempotent Summary: Currently transactional DDL is not supported in YugabyteDB . Due to which if any procedure or function which is performing multiple DDLs in a transactional context can lead to issue of some DDLs getting executed and committed even if stored procedure failed due to some exception while running stored procedure or Postgres backend process or tserver process kill. This diff makes `inherit_template_properties` function idempotent such that multiple calls to don't have any additional consequences. - This function is used to inherit the properties of the template table to newly created child tables. - For PG11, it is used to inherit non-partition-key unique indexes & primary keys. - Changes Done - Before creating a new index on the child table check if that index is already present for the child table to avoid duplicate index creation. Jira: DB-12101 Test Plan: jenkins: compile only Reviewers: skumar, jason, hsunder Reviewed By: jason Subscribers: yql Differential Revision: https://phorge.dev.yugabyte.com/D36676 --- .../functions/inherit_template_properties.sql | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/postgres/third-party-extensions/pg_partman/sql/functions/inherit_template_properties.sql b/src/postgres/third-party-extensions/pg_partman/sql/functions/inherit_template_properties.sql index a0183abf88c2..a1fc4362d636 100644 --- a/src/postgres/third-party-extensions/pg_partman/sql/functions/inherit_template_properties.sql +++ b/src/postgres/third-party-extensions/pg_partman/sql/functions/inherit_template_properties.sql @@ -22,6 +22,8 @@ v_template_table text; v_template_tablename name; v_template_tablespace name; v_template_unlogged char; +yb_v_child_index_found boolean := false; +yb_v_child_index_list record; BEGIN /* @@ -100,6 +102,7 @@ IF current_setting('server_version_num')::int >= 100000 THEN ORDER BY 1 LOOP v_dupe_found := false; + yb_v_child_index_found := false; IF current_setting('server_version_num')::int >= 110000 THEN FOR v_parent_index_list IN @@ -140,6 +143,43 @@ IF current_setting('server_version_num')::int >= 100000 THEN CONTINUE; END IF; + -- YB: Check for existing index on child table + FOR yb_v_child_index_list IN + SELECT + array_to_string(regexp_matches(pg_get_indexdef(indexrelid), ' USING .*'),',') AS statement + , i.indisprimary + , ( SELECT array_agg(a.attname ORDER by x.r) + FROM pg_catalog.pg_attribute a + JOIN ( SELECT k, row_number() over () as r + FROM unnest(i.indkey) k ) as x + ON a.attnum = x.k AND a.attrelid = i.indrelid + ) AS indkey_names + FROM pg_catalog.pg_index i + WHERE i.indrelid = ( SELECT oid FROM pg_catalog.pg_class WHERE relname = p_child_tablename AND relnamespace = ( SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = p_child_schema )) + AND i.indisvalid + ORDER BY 1 + LOOP + IF yb_v_child_index_list.indisprimary = v_index_list.indisprimary THEN + IF yb_v_child_index_list.indisprimary THEN + IF yb_v_child_index_list.indkey_names = v_index_list.indkey_names THEN + RAISE DEBUG 'inherit_template_properties: Duplicate primary key found on child table: %', v_index_list.indkey_names; + yb_v_child_index_found := true; + CONTINUE; -- skip creating this index + END IF; + END IF; + END IF; + + IF yb_v_child_index_list.statement = v_index_list.statement THEN + RAISE DEBUG 'inherit_template_properties: Duplicate index found on child table: %', v_index_list.statement; + yb_v_child_index_found := true; + CONTINUE; -- skip creating this index + END IF; + END LOOP; + + IF yb_v_child_index_found THEN + CONTINUE; + END IF; + IF v_index_list.indisprimary THEN v_sql := format('ALTER TABLE %I.%I ADD PRIMARY KEY (%s)' , v_child_schema