From f81a91db4d1c2032632aa5df9fc14be24f5fe5ec Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 17 Jul 2017 21:29:45 -0400 Subject: [PATCH] Use a real RT index when setting up partition tuple routing. Before, we always used a dummy value of 1, but that's not right when the partitioned table being modified is inside of a WITH clause rather than part of the main query. Amit Langote, reported and reviewd by Etsuro Fujita, with a comment change by me. Discussion: http://postgr.es/m/ee12f648-8907-77b5-afc0-2980bcb0aa37@lab.ntt.co.jp --- src/backend/commands/copy.c | 1 + src/backend/executor/execMain.c | 3 ++- src/backend/executor/nodeModifyTable.c | 1 + src/include/executor/executor.h | 1 + src/test/regress/expected/insert.out | 18 ++++++++++++++++++ src/test/regress/sql/insert.sql | 18 ++++++++++++++++++ 6 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index fc5f4f66ea..53e296559a 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -1433,6 +1433,7 @@ BeginCopy(ParseState *pstate, num_partitions; ExecSetupPartitionTupleRouting(rel, + 1, &partition_dispatch_info, &partitions, &partition_tupconv_maps, diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 0f08283f81..df9302896c 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -3213,6 +3213,7 @@ EvalPlanQualEnd(EPQState *epqstate) */ void ExecSetupPartitionTupleRouting(Relation rel, + Index resultRTindex, PartitionDispatch **pd, ResultRelInfo **partitions, TupleConversionMap ***tup_conv_maps, @@ -3271,7 +3272,7 @@ ExecSetupPartitionTupleRouting(Relation rel, InitResultRelInfo(leaf_part_rri, partrel, - 1, /* dummy */ + resultRTindex, rel, 0); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 8d17425abe..77ba15dd90 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1914,6 +1914,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) num_partitions; ExecSetupPartitionTupleRouting(rel, + node->nominalRelation, &partition_dispatch_info, &partitions, &partition_tupconv_maps, diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index e25cfa3aba..59c28b709e 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -207,6 +207,7 @@ extern void EvalPlanQualSetTuple(EPQState *epqstate, Index rti, HeapTuple tuple); extern HeapTuple EvalPlanQualGetTuple(EPQState *epqstate, Index rti); extern void ExecSetupPartitionTupleRouting(Relation rel, + Index resultRTindex, PartitionDispatch **pd, ResultRelInfo **partitions, TupleConversionMap ***tup_conv_maps, diff --git a/src/test/regress/expected/insert.out b/src/test/regress/expected/insert.out index d1153f410b..dd5dddb20c 100644 --- a/src/test/regress/expected/insert.out +++ b/src/test/regress/expected/insert.out @@ -506,5 +506,23 @@ DETAIL: Failing row contains (2, hi there). insert into brtrigpartcon1 values (1, 'hi there'); ERROR: new row for relation "brtrigpartcon1" violates partition constraint DETAIL: Failing row contains (2, hi there). +-- check that the message shows the appropriate column description in a +-- situation where the partitioned table is not the primary ModifyTable node +create table inserttest3 (f1 text default 'foo', f2 text default 'bar', f3 int); +create role regress_coldesc_role; +grant insert on inserttest3 to regress_coldesc_role; +grant insert on brtrigpartcon to regress_coldesc_role; +revoke select on brtrigpartcon from regress_coldesc_role; +set role regress_coldesc_role; +with result as (insert into brtrigpartcon values (1, 'hi there') returning 1) + insert into inserttest3 (f3) select * from result; +ERROR: new row for relation "brtrigpartcon1" violates partition constraint +DETAIL: Failing row contains (a, b) = (2, hi there). +reset role; +-- cleanup +revoke all on inserttest3 from regress_coldesc_role; +revoke all on brtrigpartcon from regress_coldesc_role; +drop role regress_coldesc_role; +drop table inserttest3; drop table brtrigpartcon; drop function brtrigpartcon1trigf(); diff --git a/src/test/regress/sql/insert.sql b/src/test/regress/sql/insert.sql index 83c3ad8f53..fe63020768 100644 --- a/src/test/regress/sql/insert.sql +++ b/src/test/regress/sql/insert.sql @@ -340,5 +340,23 @@ create or replace function brtrigpartcon1trigf() returns trigger as $$begin new. create trigger brtrigpartcon1trig before insert on brtrigpartcon1 for each row execute procedure brtrigpartcon1trigf(); insert into brtrigpartcon values (1, 'hi there'); insert into brtrigpartcon1 values (1, 'hi there'); + +-- check that the message shows the appropriate column description in a +-- situation where the partitioned table is not the primary ModifyTable node +create table inserttest3 (f1 text default 'foo', f2 text default 'bar', f3 int); +create role regress_coldesc_role; +grant insert on inserttest3 to regress_coldesc_role; +grant insert on brtrigpartcon to regress_coldesc_role; +revoke select on brtrigpartcon from regress_coldesc_role; +set role regress_coldesc_role; +with result as (insert into brtrigpartcon values (1, 'hi there') returning 1) + insert into inserttest3 (f3) select * from result; +reset role; + +-- cleanup +revoke all on inserttest3 from regress_coldesc_role; +revoke all on brtrigpartcon from regress_coldesc_role; +drop role regress_coldesc_role; +drop table inserttest3; drop table brtrigpartcon; drop function brtrigpartcon1trigf(); -- 2.40.0