diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2018-06-22 15:12:53 -0400 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2018-06-22 16:45:48 -0400 |
commit | 475be5e790e2db4c5c18a2d378c4498ffccb6289 (patch) | |
tree | fdb4e794350c714d72b9153808cb1af4109009a1 /src | |
parent | c6f28af5d7af87d7370e5f169251d91437f100a2 (diff) | |
download | postgresql-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.c | 25 | ||||
-rw-r--r-- | src/test/regress/expected/indexing.out | 16 | ||||
-rw-r--r-- | src/test/regress/sql/indexing.sql | 1 |
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 |