Skip to content

Commit 39162b2

Browse files
committed
Fix failure to enforce partitioning contraint for internal partitions.
When a tuple is inherited into a partitioning root, no partition constraints need to be enforced; when it is inserted into a leaf, the parent's partitioning quals needed to be enforced. The previous coding got both of those cases right. When a tuple is inserted into an intermediate level of the partitioning hierarchy (i.e. a table which is both a partition itself and in turn partitioned), it must enforce the partitioning qual inherited from its parent. That case got overlooked; repair. Amit Langote
1 parent bec96c8 commit 39162b2

File tree

6 files changed

+44
-12
lines changed

6 files changed

+44
-12
lines changed

src/backend/commands/copy.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2432,7 +2432,6 @@ CopyFrom(CopyState cstate)
24322432
InitResultRelInfo(resultRelInfo,
24332433
cstate->rel,
24342434
1, /* dummy rangetable index */
2435-
true, /* do load partition check expression */
24362435
NULL,
24372436
0);
24382437

src/backend/commands/tablecmds.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,6 @@ ExecuteTruncate(TruncateStmt *stmt)
13241324
InitResultRelInfo(resultRelInfo,
13251325
rel,
13261326
0, /* dummy rangetable index */
1327-
false,
13281327
NULL,
13291328
0);
13301329
resultRelInfo++;

src/backend/executor/execMain.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -824,10 +824,10 @@ InitPlan(QueryDesc *queryDesc, int eflags)
824824

825825
resultRelationOid = getrelid(resultRelationIndex, rangeTable);
826826
resultRelation = heap_open(resultRelationOid, RowExclusiveLock);
827+
827828
InitResultRelInfo(resultRelInfo,
828829
resultRelation,
829830
resultRelationIndex,
830-
true,
831831
NULL,
832832
estate->es_instrument);
833833
resultRelInfo++;
@@ -1218,10 +1218,11 @@ void
12181218
InitResultRelInfo(ResultRelInfo *resultRelInfo,
12191219
Relation resultRelationDesc,
12201220
Index resultRelationIndex,
1221-
bool load_partition_check,
12221221
Relation partition_root,
12231222
int instrument_options)
12241223
{
1224+
List *partition_check = NIL;
1225+
12251226
MemSet(resultRelInfo, 0, sizeof(ResultRelInfo));
12261227
resultRelInfo->type = T_ResultRelInfo;
12271228
resultRelInfo->ri_RangeTableIndex = resultRelationIndex;
@@ -1257,13 +1258,38 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
12571258
resultRelInfo->ri_ConstraintExprs = NULL;
12581259
resultRelInfo->ri_junkFilter = NULL;
12591260
resultRelInfo->ri_projectReturning = NULL;
1260-
if (load_partition_check)
1261-
resultRelInfo->ri_PartitionCheck =
1262-
RelationGetPartitionQual(resultRelationDesc);
1261+
12631262
/*
1264-
* The following gets set to NULL unless we are initializing leaf
1265-
* partitions for tuple-routing.
1263+
* If partition_root has been specified, that means we are builiding the
1264+
* ResultRelationInfo for one of its leaf partitions. In that case, we
1265+
* need *not* initialize the leaf partition's constraint, but rather the
1266+
* the partition_root's (if any). We must do that explicitly like this,
1267+
* because implicit partition constraints are not inherited like user-
1268+
* defined constraints and would fail to be enforced by ExecConstraints()
1269+
* after a tuple is routed to a leaf partition.
12661270
*/
1271+
if (partition_root)
1272+
{
1273+
/*
1274+
* Root table itself may or may not be a partition; partition_check
1275+
* would be NIL in the latter case.
1276+
*/
1277+
partition_check = RelationGetPartitionQual(partition_root);
1278+
1279+
/*
1280+
* This is not our own partition constraint, but rather an ancestor's.
1281+
* So any Vars in it bear the ancestor's attribute numbers. We must
1282+
* switch them to our own.
1283+
*/
1284+
if (partition_check != NIL)
1285+
partition_check = map_partition_varattnos(partition_check,
1286+
resultRelationDesc,
1287+
partition_root);
1288+
}
1289+
else
1290+
partition_check = RelationGetPartitionQual(resultRelationDesc);
1291+
1292+
resultRelInfo->ri_PartitionCheck = partition_check;
12671293
resultRelInfo->ri_PartitionRoot = partition_root;
12681294
}
12691295

@@ -1327,7 +1353,6 @@ ExecGetTriggerResultRel(EState *estate, Oid relid)
13271353
InitResultRelInfo(rInfo,
13281354
rel,
13291355
0, /* dummy rangetable index */
1330-
true,
13311356
NULL,
13321357
estate->es_instrument);
13331358
estate->es_trig_target_relations =
@@ -3132,7 +3157,6 @@ ExecSetupPartitionTupleRouting(Relation rel,
31323157
InitResultRelInfo(leaf_part_rri,
31333158
partrel,
31343159
1, /* dummy */
3135-
false,
31363160
rel,
31373161
0);
31383162

src/include/executor/executor.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ extern void CheckValidResultRel(Relation resultRel, CmdType operation);
189189
extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
190190
Relation resultRelationDesc,
191191
Index resultRelationIndex,
192-
bool load_partition_check,
193192
Relation partition_root,
194193
int instrument_options);
195194
extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);

src/test/regress/expected/insert.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,5 +358,11 @@ alter table p add constraint check_b check (b = 3);
358358
insert into p values (1, 2);
359359
ERROR: new row for relation "p11" violates check constraint "check_b"
360360
DETAIL: Failing row contains (1, 2).
361+
-- check that inserting into an internal partition successfully results in
362+
-- checking its partition constraint before inserting into the leaf partition
363+
-- selected by tuple-routing
364+
insert into p1 (a, b) values (2, 3);
365+
ERROR: new row for relation "p11" violates partition constraint
366+
DETAIL: Failing row contains (3, 2).
361367
-- cleanup
362368
drop table p, p1, p11;

src/test/regress/sql/insert.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,5 +221,10 @@ alter table p add constraint check_b check (b = 3);
221221
-- after "(1, 2)" is routed to it
222222
insert into p values (1, 2);
223223

224+
-- check that inserting into an internal partition successfully results in
225+
-- checking its partition constraint before inserting into the leaf partition
226+
-- selected by tuple-routing
227+
insert into p1 (a, b) values (2, 3);
228+
224229
-- cleanup
225230
drop table p, p1, p11;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy