remove_needless_additional_partition_check_v3.patch
application/octet-stream
Filename: remove_needless_additional_partition_check_v3.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v3
| File | + | − |
|---|---|---|
| src/backend/commands/copy.c | 20 | 15 |
| src/backend/executor/nodeModifyTable.c | 20 | 16 |
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 770c75fe2c..277e74b173 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -2721,30 +2721,35 @@ CopyFrom(CopyState cstate)
}
else
{
+ bool check_partition_constr;
+
/*
- * We always check the partition constraint, including when
- * the tuple got here via tuple-routing. However we don't
- * need to in the latter case if no BR trigger is defined on
- * the partition. Note that a BR trigger might modify the
- * tuple such that the partition constraint is no longer
- * satisfied, so we need to check in that case.
+ * We must validate the partition constraint when copying
+ * directly into a partition, or when the tuple has been
+ * routed here and a BR trigger exists. Such a trigger could
+ * have changed the tuple so that it violates the partition
+ * constraint. If no such trigger exists then the correct
+ * partition has already been selected, so we can skip the
+ * check.
*/
- bool check_partition_constr =
- (resultRelInfo->ri_PartitionCheck != NIL);
-
- if (saved_resultRelInfo != NULL &&
- !(resultRelInfo->ri_TrigDesc &&
- resultRelInfo->ri_TrigDesc->trig_insert_before_row))
+ if (resultRelInfo->ri_PartitionCheck != NIL &&
+ saved_resultRelInfo == NULL)
+ check_partition_constr = true;
+ else if (saved_resultRelInfo && resultRelInfo->ri_TrigDesc &&
+ resultRelInfo->ri_TrigDesc->trig_insert_before_row)
+ check_partition_constr = true;
+ else
check_partition_constr = false;
/*
- * If the target is a plain table, check the constraints of
- * the tuple.
+ * Check the tuple is valid against all constraints, and the
+ * partition constraint, if required.
*/
if (resultRelInfo->ri_FdwRoutine == NULL &&
(resultRelInfo->ri_RelationDesc->rd_att->constr ||
check_partition_constr))
- ExecConstraints(resultRelInfo, slot, estate, true);
+ ExecConstraints(resultRelInfo, slot, estate,
+ check_partition_constr);
if (useHeapMultiInsert)
{
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index c4c841cdd7..555116c07f 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -367,15 +367,6 @@ ExecInsert(ModifyTableState *mtstate,
WCOKind wco_kind;
bool check_partition_constr;
- /*
- * We always check the partition constraint, including when the tuple
- * got here via tuple-routing. However we don't need to in the latter
- * case if no BR trigger is defined on the partition. Note that a BR
- * trigger might modify the tuple such that the partition constraint
- * is no longer satisfied, so we need to check in that case.
- */
- check_partition_constr = (resultRelInfo->ri_PartitionCheck != NIL);
-
/*
* Constraints might reference the tableoid column, so initialize
* t_tableOid before evaluating them.
@@ -402,17 +393,30 @@ ExecInsert(ModifyTableState *mtstate,
ExecWithCheckOptions(wco_kind, resultRelInfo, slot, estate);
/*
- * No need though if the tuple has been routed, and a BR trigger
- * doesn't exist.
+ * We must validate the partition constraint when inserting directly
+ * into a partition, or when the tuple has been routed here and a BR
+ * trigger exists. Such a trigger could have changed the tuple so
+ * that it violates the partition constraint. If no such trigger
+ * exists then the correct partition has already been selected, so we
+ * can skip the check.
*/
- if (resultRelInfo->ri_PartitionRoot != NULL &&
- !(resultRelInfo->ri_TrigDesc &&
- resultRelInfo->ri_TrigDesc->trig_insert_before_row))
+ if (resultRelInfo->ri_PartitionCheck != NIL &&
+ !resultRelInfo->ri_PartitionRoot)
+ check_partition_constr = true;
+ else if (resultRelInfo->ri_PartitionRoot &&
+ resultRelInfo->ri_TrigDesc &&
+ resultRelInfo->ri_TrigDesc->trig_insert_before_row)
+ check_partition_constr = true;
+ else
check_partition_constr = false;
- /* Check the constraints of the tuple */
+ /*
+ * Check the tuple is valid against all constraints, and the partition
+ * constraint, if required.
+ */
if (resultRelationDesc->rd_att->constr || check_partition_constr)
- ExecConstraints(resultRelInfo, slot, estate, true);
+ ExecConstraints(resultRelInfo, slot, estate,
+ check_partition_constr);
if (onconflict != ONCONFLICT_NONE && resultRelInfo->ri_NumIndices > 0)
{