aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/commands/indexcmds.c31
-rw-r--r--src/test/regress/expected/indexing.out35
-rw-r--r--src/test/regress/sql/indexing.sql26
3 files changed, 85 insertions, 7 deletions
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 9bc97e1fc21..403f5fc143f 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -1416,6 +1416,7 @@ DefineIndex(Oid relationId,
IndexStmt *childStmt = copyObject(stmt);
bool found_whole_row;
ListCell *lc;
+ ObjectAddress childAddr;
/*
* We can't use the same index name for the child index,
@@ -1469,15 +1470,25 @@ DefineIndex(Oid relationId,
Assert(GetUserId() == child_save_userid);
SetUserIdAndSecContext(root_save_userid,
root_save_sec_context);
- DefineIndex(childRelid, childStmt,
- InvalidOid, /* no predefined OID */
- indexRelationId, /* this is our child */
- createdConstraintId,
- -1,
- is_alter_table, check_rights, check_not_in_use,
- skip_build, quiet);
+ childAddr =
+ DefineIndex(childRelid, childStmt,
+ InvalidOid, /* no predefined OID */
+ indexRelationId, /* this is our child */
+ createdConstraintId,
+ -1,
+ is_alter_table, check_rights,
+ check_not_in_use,
+ skip_build, quiet);
SetUserIdAndSecContext(child_save_userid,
child_save_sec_context);
+
+ /*
+ * Check if the index just created is valid or not, as it
+ * could be possible that it has been switched as invalid
+ * when recursing across multiple partition levels.
+ */
+ if (!get_index_isvalid(childAddr.objectId))
+ invalidate_parent = true;
}
free_attrmap(attmap);
@@ -1507,6 +1518,12 @@ DefineIndex(Oid relationId,
ReleaseSysCache(tup);
table_close(pg_index, RowExclusiveLock);
heap_freetuple(newtup);
+
+ /*
+ * CCI here to make this update visible, in case this recurses
+ * across multiple partition levels.
+ */
+ CommandCounterIncrement();
}
}
diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out
index 64edc16a61a..3e5645c2ab6 100644
--- a/src/test/regress/expected/indexing.out
+++ b/src/test/regress/expected/indexing.out
@@ -1451,3 +1451,38 @@ select indexrelid::regclass, indisvalid,
(5 rows)
drop table parted_inval_tab;
+-- Check setup of indisvalid across a complex partition tree on index
+-- creation. If one index in a partition index is invalid, so should its
+-- partitioned index.
+create table parted_isvalid_tab (a int, b int) partition by range (a);
+create table parted_isvalid_tab_1 partition of parted_isvalid_tab
+ for values from (1) to (10) partition by range (a);
+create table parted_isvalid_tab_2 partition of parted_isvalid_tab
+ for values from (10) to (20) partition by range (a);
+create table parted_isvalid_tab_11 partition of parted_isvalid_tab_1
+ for values from (1) to (5);
+create table parted_isvalid_tab_12 partition of parted_isvalid_tab_1
+ for values from (5) to (10);
+-- create an invalid index on one of the partitions.
+insert into parted_isvalid_tab_11 values (1, 0);
+create index concurrently parted_isvalid_idx_11 on parted_isvalid_tab_11 ((a/b));
+ERROR: division by zero
+-- The previous invalid index is selected, invalidating all the indexes up to
+-- the top-most parent.
+create index parted_isvalid_idx on parted_isvalid_tab ((a/b));
+select indexrelid::regclass, indisvalid,
+ indrelid::regclass, inhparent::regclass
+ from pg_index idx left join
+ pg_inherits inh on (idx.indexrelid = inh.inhrelid)
+ where indexrelid::regclass::text like 'parted_isvalid%'
+ order by indexrelid::regclass::text collate "C";
+ indexrelid | indisvalid | indrelid | inhparent
+--------------------------------+------------+-----------------------+-------------------------------
+ parted_isvalid_idx | f | parted_isvalid_tab |
+ parted_isvalid_idx_11 | f | parted_isvalid_tab_11 | parted_isvalid_tab_1_expr_idx
+ parted_isvalid_tab_12_expr_idx | t | parted_isvalid_tab_12 | parted_isvalid_tab_1_expr_idx
+ parted_isvalid_tab_1_expr_idx | f | parted_isvalid_tab_1 | parted_isvalid_idx
+ parted_isvalid_tab_2_expr_idx | t | parted_isvalid_tab_2 | parted_isvalid_idx
+(5 rows)
+
+drop table parted_isvalid_tab;
diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql
index e0b4e130379..d6e5a06d95a 100644
--- a/src/test/regress/sql/indexing.sql
+++ b/src/test/regress/sql/indexing.sql
@@ -782,3 +782,29 @@ select indexrelid::regclass, indisvalid,
where indexrelid::regclass::text like 'parted_inval%'
order by indexrelid::regclass::text collate "C";
drop table parted_inval_tab;
+
+-- Check setup of indisvalid across a complex partition tree on index
+-- creation. If one index in a partition index is invalid, so should its
+-- partitioned index.
+create table parted_isvalid_tab (a int, b int) partition by range (a);
+create table parted_isvalid_tab_1 partition of parted_isvalid_tab
+ for values from (1) to (10) partition by range (a);
+create table parted_isvalid_tab_2 partition of parted_isvalid_tab
+ for values from (10) to (20) partition by range (a);
+create table parted_isvalid_tab_11 partition of parted_isvalid_tab_1
+ for values from (1) to (5);
+create table parted_isvalid_tab_12 partition of parted_isvalid_tab_1
+ for values from (5) to (10);
+-- create an invalid index on one of the partitions.
+insert into parted_isvalid_tab_11 values (1, 0);
+create index concurrently parted_isvalid_idx_11 on parted_isvalid_tab_11 ((a/b));
+-- The previous invalid index is selected, invalidating all the indexes up to
+-- the top-most parent.
+create index parted_isvalid_idx on parted_isvalid_tab ((a/b));
+select indexrelid::regclass, indisvalid,
+ indrelid::regclass, inhparent::regclass
+ from pg_index idx left join
+ pg_inherits inh on (idx.indexrelid = inh.inhrelid)
+ where indexrelid::regclass::text like 'parted_isvalid%'
+ order by indexrelid::regclass::text collate "C";
+drop table parted_isvalid_tab;