Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 475be5e

Browse files
committed
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
1 parent c6f28af commit 475be5e

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

src/backend/commands/indexcmds.c

+25
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,32 @@ DefineIndex(Oid relationId,
993993
{
994994
IndexStmt *childStmt = copyObject(stmt);
995995
bool found_whole_row;
996+
ListCell *lc;
997+
998+
/*
999+
* Adjust any Vars (both in expressions and in the index's
1000+
* WHERE clause) to match the partition's column numbering
1001+
* in case it's different from the parent's.
1002+
*/
1003+
foreach(lc, childStmt->indexParams)
1004+
{
1005+
IndexElem *ielem = lfirst(lc);
9961006

1007+
/*
1008+
* If the index parameter is an expression, we must
1009+
* translate it to contain child Vars.
1010+
*/
1011+
if (ielem->expr)
1012+
{
1013+
ielem->expr =
1014+
map_variable_attnos((Node *) ielem->expr,
1015+
1, 0, attmap, maplen,
1016+
InvalidOid,
1017+
&found_whole_row);
1018+
if (found_whole_row)
1019+
elog(ERROR, "cannot convert whole-row table reference");
1020+
}
1021+
}
9971022
childStmt->whereClause =
9981023
map_variable_attnos(stmt->whereClause, 1, 0,
9991024
attmap, maplen,

src/test/regress/expected/indexing.out

+10-6
Original file line numberDiff line numberDiff line change
@@ -631,17 +631,21 @@ alter table idxpart2 drop column col1, drop column col2;
631631
create index on idxpart2 (abs(b));
632632
alter table idxpart attach partition idxpart2 for values from (0) to (1);
633633
create index on idxpart (abs(b));
634+
create index on idxpart ((b + 1));
634635
alter table idxpart attach partition idxpart1 for values from (1) to (2);
635636
select c.relname, pg_get_indexdef(indexrelid)
636637
from pg_class c join pg_index i on c.oid = i.indexrelid
637638
where indrelid::regclass::text like 'idxpart%'
638639
order by indexrelid::regclass::text collate "C";
639-
relname | pg_get_indexdef
640-
------------------+--------------------------------------------------------------------------
641-
idxpart1_abs_idx | CREATE INDEX idxpart1_abs_idx ON public.idxpart1 USING btree (abs(b))
642-
idxpart2_abs_idx | CREATE INDEX idxpart2_abs_idx ON public.idxpart2 USING btree (abs(b))
643-
idxpart_abs_idx | CREATE INDEX idxpart_abs_idx ON ONLY public.idxpart USING btree (abs(b))
644-
(3 rows)
640+
relname | pg_get_indexdef
641+
-------------------+------------------------------------------------------------------------------
642+
idxpart1_abs_idx | CREATE INDEX idxpart1_abs_idx ON public.idxpart1 USING btree (abs(b))
643+
idxpart1_expr_idx | CREATE INDEX idxpart1_expr_idx ON public.idxpart1 USING btree (((b + 1)))
644+
idxpart2_abs_idx | CREATE INDEX idxpart2_abs_idx ON public.idxpart2 USING btree (abs(b))
645+
idxpart2_expr_idx | CREATE INDEX idxpart2_expr_idx ON public.idxpart2 USING btree (((b + 1)))
646+
idxpart_abs_idx | CREATE INDEX idxpart_abs_idx ON ONLY public.idxpart USING btree (abs(b))
647+
idxpart_expr_idx | CREATE INDEX idxpart_expr_idx ON ONLY public.idxpart USING btree (((b + 1)))
648+
(6 rows)
645649

646650
drop table idxpart;
647651
-- Verify that columns are mapped correctly for WHERE in a partial index

src/test/regress/sql/indexing.sql

+1
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ alter table idxpart2 drop column col1, drop column col2;
326326
create index on idxpart2 (abs(b));
327327
alter table idxpart attach partition idxpart2 for values from (0) to (1);
328328
create index on idxpart (abs(b));
329+
create index on idxpart ((b + 1));
329330
alter table idxpart attach partition idxpart1 for values from (1) to (2);
330331
select c.relname, pg_get_indexdef(indexrelid)
331332
from pg_class c join pg_index i on c.oid = i.indexrelid

0 commit comments

Comments
 (0)