Skip to content

Commit

Permalink
[#23163] YSQL: pg_partman: make 'inherit_template_properties' idempotent
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Devansh Saxena committed Jul 23, 2024
1 parent 5ac65eb commit 9e046fb
Showing 1 changed file with 40 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
/*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 9e046fb

Please sign in to comment.