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
This commit is contained in:
parent
bec96c82f8
commit
39162b2030
|
@ -2432,7 +2432,6 @@ CopyFrom(CopyState cstate)
|
|||
InitResultRelInfo(resultRelInfo,
|
||||
cstate->rel,
|
||||
1, /* dummy rangetable index */
|
||||
true, /* do load partition check expression */
|
||||
NULL,
|
||||
0);
|
||||
|
||||
|
|
|
@ -1324,7 +1324,6 @@ ExecuteTruncate(TruncateStmt *stmt)
|
|||
InitResultRelInfo(resultRelInfo,
|
||||
rel,
|
||||
0, /* dummy rangetable index */
|
||||
false,
|
||||
NULL,
|
||||
0);
|
||||
resultRelInfo++;
|
||||
|
|
|
@ -824,10 +824,10 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
|||
|
||||
resultRelationOid = getrelid(resultRelationIndex, rangeTable);
|
||||
resultRelation = heap_open(resultRelationOid, RowExclusiveLock);
|
||||
|
||||
InitResultRelInfo(resultRelInfo,
|
||||
resultRelation,
|
||||
resultRelationIndex,
|
||||
true,
|
||||
NULL,
|
||||
estate->es_instrument);
|
||||
resultRelInfo++;
|
||||
|
@ -1218,10 +1218,11 @@ void
|
|||
InitResultRelInfo(ResultRelInfo *resultRelInfo,
|
||||
Relation resultRelationDesc,
|
||||
Index resultRelationIndex,
|
||||
bool load_partition_check,
|
||||
Relation partition_root,
|
||||
int instrument_options)
|
||||
{
|
||||
List *partition_check = NIL;
|
||||
|
||||
MemSet(resultRelInfo, 0, sizeof(ResultRelInfo));
|
||||
resultRelInfo->type = T_ResultRelInfo;
|
||||
resultRelInfo->ri_RangeTableIndex = resultRelationIndex;
|
||||
|
@ -1257,13 +1258,38 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
|
|||
resultRelInfo->ri_ConstraintExprs = NULL;
|
||||
resultRelInfo->ri_junkFilter = NULL;
|
||||
resultRelInfo->ri_projectReturning = NULL;
|
||||
if (load_partition_check)
|
||||
resultRelInfo->ri_PartitionCheck =
|
||||
RelationGetPartitionQual(resultRelationDesc);
|
||||
|
||||
/*
|
||||
* The following gets set to NULL unless we are initializing leaf
|
||||
* partitions for tuple-routing.
|
||||
* If partition_root has been specified, that means we are builiding the
|
||||
* ResultRelationInfo for one of its leaf partitions. In that case, we
|
||||
* need *not* initialize the leaf partition's constraint, but rather the
|
||||
* the partition_root's (if any). We must do that explicitly like this,
|
||||
* because implicit partition constraints are not inherited like user-
|
||||
* defined constraints and would fail to be enforced by ExecConstraints()
|
||||
* after a tuple is routed to a leaf partition.
|
||||
*/
|
||||
if (partition_root)
|
||||
{
|
||||
/*
|
||||
* Root table itself may or may not be a partition; partition_check
|
||||
* would be NIL in the latter case.
|
||||
*/
|
||||
partition_check = RelationGetPartitionQual(partition_root);
|
||||
|
||||
/*
|
||||
* This is not our own partition constraint, but rather an ancestor's.
|
||||
* So any Vars in it bear the ancestor's attribute numbers. We must
|
||||
* switch them to our own.
|
||||
*/
|
||||
if (partition_check != NIL)
|
||||
partition_check = map_partition_varattnos(partition_check,
|
||||
resultRelationDesc,
|
||||
partition_root);
|
||||
}
|
||||
else
|
||||
partition_check = RelationGetPartitionQual(resultRelationDesc);
|
||||
|
||||
resultRelInfo->ri_PartitionCheck = partition_check;
|
||||
resultRelInfo->ri_PartitionRoot = partition_root;
|
||||
}
|
||||
|
||||
|
@ -1327,7 +1353,6 @@ ExecGetTriggerResultRel(EState *estate, Oid relid)
|
|||
InitResultRelInfo(rInfo,
|
||||
rel,
|
||||
0, /* dummy rangetable index */
|
||||
true,
|
||||
NULL,
|
||||
estate->es_instrument);
|
||||
estate->es_trig_target_relations =
|
||||
|
@ -3132,7 +3157,6 @@ ExecSetupPartitionTupleRouting(Relation rel,
|
|||
InitResultRelInfo(leaf_part_rri,
|
||||
partrel,
|
||||
1, /* dummy */
|
||||
false,
|
||||
rel,
|
||||
0);
|
||||
|
||||
|
|
|
@ -189,7 +189,6 @@ extern void CheckValidResultRel(Relation resultRel, CmdType operation);
|
|||
extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
|
||||
Relation resultRelationDesc,
|
||||
Index resultRelationIndex,
|
||||
bool load_partition_check,
|
||||
Relation partition_root,
|
||||
int instrument_options);
|
||||
extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
|
||||
|
|
|
@ -358,5 +358,11 @@ alter table p add constraint check_b check (b = 3);
|
|||
insert into p values (1, 2);
|
||||
ERROR: new row for relation "p11" violates check constraint "check_b"
|
||||
DETAIL: Failing row contains (1, 2).
|
||||
-- check that inserting into an internal partition successfully results in
|
||||
-- checking its partition constraint before inserting into the leaf partition
|
||||
-- selected by tuple-routing
|
||||
insert into p1 (a, b) values (2, 3);
|
||||
ERROR: new row for relation "p11" violates partition constraint
|
||||
DETAIL: Failing row contains (3, 2).
|
||||
-- cleanup
|
||||
drop table p, p1, p11;
|
||||
|
|
|
@ -221,5 +221,10 @@ alter table p add constraint check_b check (b = 3);
|
|||
-- after "(1, 2)" is routed to it
|
||||
insert into p values (1, 2);
|
||||
|
||||
-- check that inserting into an internal partition successfully results in
|
||||
-- checking its partition constraint before inserting into the leaf partition
|
||||
-- selected by tuple-routing
|
||||
insert into p1 (a, b) values (2, 3);
|
||||
|
||||
-- cleanup
|
||||
drop table p, p1, p11;
|
||||
|
|
Loading…
Reference in New Issue