mirror of
https://github.com/postgres/postgres.git
synced 2025-05-06 19:59:18 +03:00
Set ecxt_scantuple correctly for tuple routing.
In 2ac3ef7a01df859c62d0a02333b646d65eaec5ff, we changed things so that it's possible for a different TupleTableSlot to be used for partitioned tables at successively lower levels. If we do end up changing the slot from the original, we must update ecxt_scantuple to point to the new one for partition key of the tuple to be computed correctly. Reported by Rajkumar Raghuwanshi. Patch by Amit Langote. Discussion: http://postgr.es/m/CAKcux6%3Dm1qyqB2k6cjniuMMrYXb75O-MB4qGQMu8zg-iGGLjDw%40mail.gmail.com
This commit is contained in:
parent
27cdb3414b
commit
132488bfee
@ -1679,7 +1679,10 @@ get_partition_for_tuple(PartitionDispatch *pd,
|
|||||||
bool isnull[PARTITION_MAX_KEYS];
|
bool isnull[PARTITION_MAX_KEYS];
|
||||||
int cur_offset,
|
int cur_offset,
|
||||||
cur_index;
|
cur_index;
|
||||||
int i;
|
int i,
|
||||||
|
result;
|
||||||
|
ExprContext *ecxt = GetPerTupleExprContext(estate);
|
||||||
|
TupleTableSlot *ecxt_scantuple_old = ecxt->ecxt_scantuple;
|
||||||
|
|
||||||
/* start with the root partitioned table */
|
/* start with the root partitioned table */
|
||||||
parent = pd[0];
|
parent = pd[0];
|
||||||
@ -1708,7 +1711,15 @@ get_partition_for_tuple(PartitionDispatch *pd,
|
|||||||
slot = myslot;
|
slot = myslot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract partition key from tuple */
|
/*
|
||||||
|
* Extract partition key from tuple. Expression evaluation machinery
|
||||||
|
* that FormPartitionKeyDatum() invokes expects ecxt_scantuple to
|
||||||
|
* point to the correct tuple slot. The slot might have changed from
|
||||||
|
* what was used for the parent table if the table of the current
|
||||||
|
* partitioning level has different tuple descriptor from the parent.
|
||||||
|
* So update ecxt_scantuple accordingly.
|
||||||
|
*/
|
||||||
|
ecxt->ecxt_scantuple = slot;
|
||||||
FormPartitionKeyDatum(parent, slot, estate, values, isnull);
|
FormPartitionKeyDatum(parent, slot, estate, values, isnull);
|
||||||
|
|
||||||
if (key->strategy == PARTITION_STRATEGY_RANGE)
|
if (key->strategy == PARTITION_STRATEGY_RANGE)
|
||||||
@ -1763,16 +1774,21 @@ get_partition_for_tuple(PartitionDispatch *pd,
|
|||||||
*/
|
*/
|
||||||
if (cur_index < 0)
|
if (cur_index < 0)
|
||||||
{
|
{
|
||||||
|
result = -1;
|
||||||
*failed_at = RelationGetRelid(parent->reldesc);
|
*failed_at = RelationGetRelid(parent->reldesc);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (parent->indexes[cur_index] < 0)
|
|
||||||
parent = pd[-parent->indexes[cur_index]];
|
|
||||||
else
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
else if (parent->indexes[cur_index] >= 0)
|
||||||
|
{
|
||||||
|
result = parent->indexes[cur_index];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
parent = pd[-parent->indexes[cur_index]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent->indexes[cur_index];
|
ecxt->ecxt_scantuple = ecxt_scantuple_old;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3192,9 +3192,7 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
Oid failed_at;
|
Oid failed_at;
|
||||||
ExprContext *econtext = GetPerTupleExprContext(estate);
|
|
||||||
|
|
||||||
econtext->ecxt_scantuple = slot;
|
|
||||||
result = get_partition_for_tuple(pd, slot, estate, &failed_at);
|
result = get_partition_for_tuple(pd, slot, estate, &failed_at);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
{
|
{
|
||||||
|
@ -320,7 +320,7 @@ drop table part_ee_ff, part_gg2_2, part_gg2_1, part_gg2, part_gg1, part_gg;
|
|||||||
drop table part_aa_bb, part_cc_dd, part_null, list_parted;
|
drop table part_aa_bb, part_cc_dd, part_null, list_parted;
|
||||||
-- more tests for certain multi-level partitioning scenarios
|
-- more tests for certain multi-level partitioning scenarios
|
||||||
create table p (a int, b int) partition by range (a, b);
|
create table p (a int, b int) partition by range (a, b);
|
||||||
create table p1 (b int, a int not null) partition by range (b);
|
create table p1 (b int not null, a int not null) partition by range ((b+0));
|
||||||
create table p11 (like p1);
|
create table p11 (like p1);
|
||||||
alter table p11 drop a;
|
alter table p11 drop a;
|
||||||
alter table p11 add a int;
|
alter table p11 add a int;
|
||||||
|
@ -193,7 +193,7 @@ drop table part_aa_bb, part_cc_dd, part_null, list_parted;
|
|||||||
|
|
||||||
-- more tests for certain multi-level partitioning scenarios
|
-- more tests for certain multi-level partitioning scenarios
|
||||||
create table p (a int, b int) partition by range (a, b);
|
create table p (a int, b int) partition by range (a, b);
|
||||||
create table p1 (b int, a int not null) partition by range (b);
|
create table p1 (b int not null, a int not null) partition by range ((b+0));
|
||||||
create table p11 (like p1);
|
create table p11 (like p1);
|
||||||
alter table p11 drop a;
|
alter table p11 drop a;
|
||||||
alter table p11 add a int;
|
alter table p11 add a int;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user