aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2018-06-22 15:12:53 -0400
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2018-06-22 16:45:48 -0400
commit475be5e790e2db4c5c18a2d378c4498ffccb6289 (patch)
treefdb4e794350c714d72b9153808cb1af4109009a1 /src
parentc6f28af5d7af87d7370e5f169251d91437f100a2 (diff)
downloadpostgresql-475be5e790e2db4c5c18a2d378c4498ffccb6289.tar.gz
postgresql-475be5e790e2db4c5c18a2d378c4498ffccb6289.zip
When index recurses to a partition, map columns numbers
Two out of three code paths were mapping column numbers correctly if a partition had different column numbers than parent table, but the most commonly used one (recursing in CREATE INDEX to a new index on a partition) failed to map attribute numbers in expressions. Oddly enough, attnums in WHERE clauses are already handled correctly everywhere. Reported-by: Amit Langote Author: Amit Langote Discussion: https://postgr.es/m/dce1fda4-e0f0-94c9-6abb-f5956a98c057@lab.ntt.co.jp Reviewed-by: Álvaro Herrera
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/indexcmds.c25
-rw-r--r--src/test/regress/expected/indexing.out16
-rw-r--r--src/test/regress/sql/indexing.sql1
3 files changed, 36 insertions, 6 deletions
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 3a3223bffb5..3b82876c909 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -993,7 +993,32 @@ DefineIndex(Oid relationId,
{
IndexStmt *childStmt = copyObject(stmt);
bool found_whole_row;
+ ListCell *lc;
+
+ /*
+ * Adjust any Vars (both in expressions and in the index's
+ * WHERE clause) to match the partition's column numbering
+ * in case it's different from the parent's.
+ */
+ 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 2c2bf44aa87..f183317fbe8 100644
--- a/src/test/regress/expected/indexing.out
+++ b/src/test/regress/expected/indexing.out
@@ -631,17 +631,21 @@ alter table idxpart2 drop column col1, drop column col2;
create index on idxpart2 (abs(b));
alter table idxpart attach partition idxpart2 for values from (0) to (1);
create index on idxpart (abs(b));
+create index on idxpart ((b + 1));
alter table idxpart attach partition idxpart1 for values from (1) to (2);
select c.relname, pg_get_indexdef(indexrelid)
from pg_class c join pg_index i on c.oid = i.indexrelid
where indrelid::regclass::text like 'idxpart%'
order by indexrelid::regclass::text collate "C";
- relname | pg_get_indexdef
-------------------+--------------------------------------------------------------------------
- idxpart1_abs_idx | CREATE INDEX idxpart1_abs_idx ON public.idxpart1 USING btree (abs(b))
- idxpart2_abs_idx | CREATE INDEX idxpart2_abs_idx ON public.idxpart2 USING btree (abs(b))
- idxpart_abs_idx | CREATE INDEX idxpart_abs_idx ON ONLY public.idxpart USING btree (abs(b))
-(3 rows)
+ relname | pg_get_indexdef
+-------------------+------------------------------------------------------------------------------
+ idxpart1_abs_idx | CREATE INDEX idxpart1_abs_idx ON public.idxpart1 USING btree (abs(b))
+ idxpart1_expr_idx | CREATE INDEX idxpart1_expr_idx ON public.idxpart1 USING btree (((b + 1)))
+ idxpart2_abs_idx | CREATE INDEX idxpart2_abs_idx ON public.idxpart2 USING btree (abs(b))
+ idxpart2_expr_idx | CREATE INDEX idxpart2_expr_idx ON public.idxpart2 USING btree (((b + 1)))
+ idxpart_abs_idx | CREATE INDEX idxpart_abs_idx ON ONLY public.idxpart USING btree (abs(b))
+ idxpart_expr_idx | CREATE INDEX idxpart_expr_idx ON ONLY public.idxpart USING btree (((b + 1)))
+(6 rows)
drop table idxpart;
-- Verify that columns are mapped correctly for WHERE in a partial index
diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql
index 29333b31ef2..1731fb4d5c3 100644
--- a/src/test/regress/sql/indexing.sql
+++ b/src/test/regress/sql/indexing.sql
@@ -326,6 +326,7 @@ alter table idxpart2 drop column col1, drop column col2;
create index on idxpart2 (abs(b));
alter table idxpart attach partition idxpart2 for values from (0) to (1);
create index on idxpart (abs(b));
+create index on idxpart ((b + 1));
alter table idxpart attach partition idxpart1 for values from (1) to (2);
select c.relname, pg_get_indexdef(indexrelid)
from pg_class c join pg_index i on c.oid = i.indexrelid