v2-0001-Convert-indexParams-to-partition-s-attnos-before-.patch

text/plain

Filename: v2-0001-Convert-indexParams-to-partition-s-attnos-before-.patch
Type: text/plain
Part: 0
Message: Re: bug with expression index on partition

Patch

Format: format-patch
Series: patch v2-0001
Subject: Convert indexParams to partition's attnos before recursing
File+
src/backend/commands/indexcmds.c 21 0
src/test/regress/expected/indexing.out 54 0
src/test/regress/sql/indexing.sql 34 0
From f28b5e4ab8aa2c41486ef9f64b2f52220cfbfcbf Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Thu, 21 Jun 2018 14:50:20 +0900
Subject: [PATCH v2] Convert indexParams to partition's attnos before recursing

---
 src/backend/commands/indexcmds.c       | 21 +++++++++++++
 src/test/regress/expected/indexing.out | 54 ++++++++++++++++++++++++++++++++++
 src/test/regress/sql/indexing.sql      | 34 +++++++++++++++++++++
 3 files changed, 109 insertions(+)

diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 3a3223bffb..7bbdeb9e66 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -993,7 +993,28 @@ DefineIndex(Oid relationId,
 				{
 					IndexStmt  *childStmt = copyObject(stmt);
 					bool		found_whole_row;
+					ListCell   *lc;
 
+					/* Adjust Vars to match new table's column numbering */
+					foreach(lc, childStmt->indexParams)
+					{
+						IndexElem *ielem = lfirst(lc);
+
+						/*
+						 * If the index parameter is an expression, we must
+						 * translate it to contain child Vars.
+						 */
+						if (ielem->expr)
+						{
+							ielem->expr =
+									map_variable_attnos((Node *) ielem->expr,
+														1, 0, attmap, maplen,
+														InvalidOid,
+														&found_whole_row);
+							if (found_whole_row)
+								elog(ERROR, "cannot convert whole-row table reference");
+						}
+					}
 					childStmt->whereClause =
 						map_variable_attnos(stmt->whereClause, 1, 0,
 											attmap, maplen,
diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out
index 2c2bf44aa8..02c5a8e5ed 100644
--- a/src/test/regress/expected/indexing.out
+++ b/src/test/regress/expected/indexing.out
@@ -1337,3 +1337,57 @@ insert into covidxpart values (4, 1);
 insert into covidxpart values (4, 1);
 ERROR:  duplicate key value violates unique constraint "covidxpart4_a_b_idx"
 DETAIL:  Key (a)=(4) already exists.
+-- tests covering expression indexes in a partition tree with differing attributes
+create table idx_part (a int) partition by hash (a);
+create table idx_part1 partition of idx_part for values with (modulus 2, remainder 0);
+create table idx_part2 partition of idx_part for values with (modulus 2, remainder 1);
+alter table idx_part detach partition idx_part2;
+alter table idx_part2 drop a, add a int;
+alter table idx_part attach partition idx_part2 for values with (modulus 2, remainder 1);
+create index idx_part_expr on idx_part ((a + 1));
+\d idx_part2
+             Table "public.idx_part2"
+ Column |  Type   | Collation | Nullable | Default 
+--------+---------+-----------+----------+---------
+ a      | integer |           |          | 
+Partition of: idx_part FOR VALUES WITH (modulus 2, remainder 1)
+Indexes:
+    "idx_part2_expr_idx" btree ((a + 1))
+
+drop index idx_part_expr;
+alter table idx_part detach partition idx_part2;
+create index idx_part2_expr on idx_part2 ((a + 1));
+alter table idx_part attach partition idx_part2 for values with (modulus 2, remainder 1);
+create index idx_part_expr on idx_part ((a + 1));
+\d idx_part2
+             Table "public.idx_part2"
+ Column |  Type   | Collation | Nullable | Default 
+--------+---------+-----------+----------+---------
+ a      | integer |           |          | 
+Partition of: idx_part FOR VALUES WITH (modulus 2, remainder 1)
+Indexes:
+    "idx_part2_expr" btree ((a + 1))
+
+drop table idx_part2;
+create table idx_part2 (b int, a int);
+alter table idx_part2 drop b;
+alter table idx_part attach partition idx_part2 for values with (modulus 2, remainder 1);
+\d idx_part2;
+             Table "public.idx_part2"
+ Column |  Type   | Collation | Nullable | Default 
+--------+---------+-----------+----------+---------
+ a      | integer |           |          | 
+Partition of: idx_part FOR VALUES WITH (modulus 2, remainder 1)
+Indexes:
+    "idx_part2_expr_idx" btree ((a + 1))
+
+-- whole-row Vars in expressions are detected when converting and reported as unsupported
+drop table idx_part;
+create table idx_part (a int) partition by hash (a);
+create table idx_part1 (a int);
+create index idx_part_wholerow on idx_part ((idx_part));
+alter table idx_part attach partition idx_part1 for values with (modulus 2, remainder 0); -- error
+ERROR:  cannot convert whole-row table reference
+DETAIL:  Index "idx_part_wholerow" contains a whole-row table reference.
+drop table idx_part1;
+drop table idx_part;
diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql
index 29333b31ef..1b1b0af029 100644
--- a/src/test/regress/sql/indexing.sql
+++ b/src/test/regress/sql/indexing.sql
@@ -720,3 +720,37 @@ create unique index on covidxpart4 (a);
 alter table covidxpart attach partition covidxpart4 for values in (4);
 insert into covidxpart values (4, 1);
 insert into covidxpart values (4, 1);
+
+-- tests covering expression indexes in a partition tree with differing attributes
+create table idx_part (a int) partition by hash (a);
+create table idx_part1 partition of idx_part for values with (modulus 2, remainder 0);
+create table idx_part2 partition of idx_part for values with (modulus 2, remainder 1);
+
+alter table idx_part detach partition idx_part2;
+alter table idx_part2 drop a, add a int;
+alter table idx_part attach partition idx_part2 for values with (modulus 2, remainder 1);
+create index idx_part_expr on idx_part ((a + 1));
+\d idx_part2
+
+drop index idx_part_expr;
+alter table idx_part detach partition idx_part2;
+create index idx_part2_expr on idx_part2 ((a + 1));
+alter table idx_part attach partition idx_part2 for values with (modulus 2, remainder 1);
+create index idx_part_expr on idx_part ((a + 1));
+\d idx_part2
+
+drop table idx_part2;
+create table idx_part2 (b int, a int);
+alter table idx_part2 drop b;
+alter table idx_part attach partition idx_part2 for values with (modulus 2, remainder 1);
+\d idx_part2;
+
+-- whole-row Vars in expressions are detected when converting and reported as unsupported
+drop table idx_part;
+create table idx_part (a int) partition by hash (a);
+create table idx_part1 (a int);
+create index idx_part_wholerow on idx_part ((idx_part));
+alter table idx_part attach partition idx_part1 for values with (modulus 2, remainder 0); -- error
+drop table idx_part1;
+
+drop table idx_part;
-- 
2.11.0