Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5b0c7e2

Browse files
committed
Don't needlessly check the partition contraint twice
Starting with commitf0e4475, ExecConstraints was in charge ofrunning the partition constraint; commit19c47e7 modified that sothat caller could request to skip that checking depending on someconditions, but that commit and15ce775 together introduced a smallbug there which caused ExecInsert to request skipping the constraintcheck but have this not be honored -- in effect doing the check twice.This could have been fixed in a very small patch, but on furtheranalysis of the involved function and its callsites, it turns out to besimpler to give the responsibility of checking the partition constraintfully to the caller, and return ExecConstraints to its original(pre-partitioning) shape where it only checked tuple descriptor-relatedconstraints. Each caller must do partition constraint checking on itsown schedule, which is more convenient after commit2f17844 anyway.Reported-by: David RowleyAuthor: David Rowley, Álvaro HerreraReviewed-by: Amit Langote, Amit Khandekar, Simon RiggsDiscussion:https://postgr.es/m/CAKJS1f8w8+awsxgea8wt7_UX8qzOQ=Tm1LD+U1fHqBAkXxkW2w@mail.gmail.com
1 parent85dd744 commit5b0c7e2

File tree

6 files changed

+56
-62
lines changed

6 files changed

+56
-62
lines changed

‎src/backend/commands/copy.c

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2725,30 +2725,25 @@ CopyFrom(CopyState cstate)
27252725
}
27262726
else
27272727
{
2728-
/*
2729-
* We always check the partition constraint, including when
2730-
* the tuple got here via tuple-routing. However we don't
2731-
* need to in the latter case if no BR trigger is defined on
2732-
* the partition. Note that a BR trigger might modify the
2733-
* tuple such that the partition constraint is no longer
2734-
* satisfied, so we need to check in that case.
2735-
*/
2736-
boolcheck_partition_constr=
2737-
(resultRelInfo->ri_PartitionCheck!=NIL);
2738-
2739-
if (saved_resultRelInfo!=NULL&&
2740-
!(resultRelInfo->ri_TrigDesc&&
2741-
resultRelInfo->ri_TrigDesc->trig_insert_before_row))
2742-
check_partition_constr= false;
2743-
27442728
/*
27452729
* If the target is a plain table, check the constraints of
27462730
* the tuple.
27472731
*/
27482732
if (resultRelInfo->ri_FdwRoutine==NULL&&
2749-
(resultRelInfo->ri_RelationDesc->rd_att->constr||
2750-
check_partition_constr))
2751-
ExecConstraints(resultRelInfo,slot,estate, true);
2733+
resultRelInfo->ri_RelationDesc->rd_att->constr)
2734+
ExecConstraints(resultRelInfo,slot,estate);
2735+
2736+
/*
2737+
* Also check the tuple against the partition constraint, if
2738+
* there is one; except that if we got here via tuple-routing,
2739+
* we don't need to if there's no BR trigger defined on the
2740+
* partition.
2741+
*/
2742+
if (resultRelInfo->ri_PartitionCheck&&
2743+
(saved_resultRelInfo==NULL||
2744+
(resultRelInfo->ri_TrigDesc&&
2745+
resultRelInfo->ri_TrigDesc->trig_insert_before_row)))
2746+
ExecPartitionCheck(resultRelInfo,slot,estate, true);
27522747

27532748
if (useHeapMultiInsert)
27542749
{

‎src/backend/executor/execMain.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,14 +1856,16 @@ ExecRelCheck(ResultRelInfo *resultRelInfo,
18561856
/*
18571857
* ExecPartitionCheck --- check that tuple meets the partition constraint.
18581858
*
1859-
* Exported in executor.h for outside use.
1860-
* Returns true if it meets the partition constraint, else returns false.
1859+
* Returns true if it meets the partition constraint. If the constraint
1860+
* fails and we're asked to emit to error, do so and don't return; otherwise
1861+
* return false.
18611862
*/
18621863
bool
18631864
ExecPartitionCheck(ResultRelInfo*resultRelInfo,TupleTableSlot*slot,
1864-
EState*estate)
1865+
EState*estate,boolemitError)
18651866
{
18661867
ExprContext*econtext;
1868+
boolsuccess;
18671869

18681870
/*
18691871
* If first time through, build expression state tree for the partition
@@ -1890,7 +1892,13 @@ ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
18901892
* As in case of the catalogued constraints, we treat a NULL result as
18911893
* success here, not a failure.
18921894
*/
1893-
returnExecCheck(resultRelInfo->ri_PartitionCheckExpr,econtext);
1895+
success=ExecCheck(resultRelInfo->ri_PartitionCheckExpr,econtext);
1896+
1897+
/* if asked to emit error, don't actually return on failure */
1898+
if (!success&&emitError)
1899+
ExecPartitionCheckEmitError(resultRelInfo,slot,estate);
1900+
1901+
returnsuccess;
18941902
}
18951903

18961904
/*
@@ -1951,17 +1959,17 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo,
19511959
/*
19521960
* ExecConstraints - check constraints of the tuple in 'slot'
19531961
*
1954-
* This checks the traditional NOT NULL and check constraints, and if
1955-
* requested, checks the partition constraint.
1962+
* This checks the traditional NOT NULL and check constraints.
1963+
*
1964+
* The partition constraint is *NOT* checked.
19561965
*
19571966
* Note: 'slot' contains the tuple to check the constraints of, which may
19581967
* have been converted from the original input tuple after tuple routing.
1959-
* 'resultRelInfo' is theoriginal result relation,before tuple routing.
1968+
* 'resultRelInfo' is thefinal result relation,after tuple routing.
19601969
*/
19611970
void
19621971
ExecConstraints(ResultRelInfo*resultRelInfo,
1963-
TupleTableSlot*slot,EState*estate,
1964-
boolcheck_partition_constraint)
1972+
TupleTableSlot*slot,EState*estate)
19651973
{
19661974
Relationrel=resultRelInfo->ri_RelationDesc;
19671975
TupleDesctupdesc=RelationGetDescr(rel);
@@ -2076,13 +2084,8 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
20762084
errtableconstraint(orig_rel,failed)));
20772085
}
20782086
}
2079-
2080-
if (check_partition_constraint&&resultRelInfo->ri_PartitionCheck&&
2081-
!ExecPartitionCheck(resultRelInfo,slot,estate))
2082-
ExecPartitionCheckEmitError(resultRelInfo,slot,estate);
20832087
}
20842088

2085-
20862089
/*
20872090
* ExecWithCheckOptions -- check that tuple satisfies any WITH CHECK OPTIONs
20882091
* of the specified kind.

‎src/backend/executor/execPartition.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,8 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
201201
* First check the root table's partition constraint, if any. No point in
202202
* routing the tuple if it doesn't belong in the root table itself.
203203
*/
204-
if (resultRelInfo->ri_PartitionCheck&&
205-
!ExecPartitionCheck(resultRelInfo,slot,estate))
206-
ExecPartitionCheckEmitError(resultRelInfo,slot,estate);
204+
if (resultRelInfo->ri_PartitionCheck)
205+
ExecPartitionCheck(resultRelInfo,slot,estate, true);
207206

208207
/* start with the root partitioned table */
209208
parent=pd[0];

‎src/backend/executor/execReplication.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,9 @@ ExecSimpleRelationInsert(EState *estate, TupleTableSlot *slot)
413413

414414
/* Check the constraints of the tuple */
415415
if (rel->rd_att->constr)
416-
ExecConstraints(resultRelInfo,slot,estate, true);
416+
ExecConstraints(resultRelInfo,slot,estate);
417+
if (resultRelInfo->ri_PartitionCheck)
418+
ExecPartitionCheck(resultRelInfo,slot,estate, true);
417419

418420
/* Store the slot into tuple that we can inspect. */
419421
tuple=ExecMaterializeSlot(slot);
@@ -478,7 +480,9 @@ ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate,
478480

479481
/* Check the constraints of the tuple */
480482
if (rel->rd_att->constr)
481-
ExecConstraints(resultRelInfo,slot,estate, true);
483+
ExecConstraints(resultRelInfo,slot,estate);
484+
if (resultRelInfo->ri_PartitionCheck)
485+
ExecPartitionCheck(resultRelInfo,slot,estate, true);
482486

483487
/* Store the slot into tuple that we can write. */
484488
tuple=ExecMaterializeSlot(slot);

‎src/backend/executor/nodeModifyTable.c

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -365,16 +365,6 @@ ExecInsert(ModifyTableState *mtstate,
365365
else
366366
{
367367
WCOKindwco_kind;
368-
boolcheck_partition_constr;
369-
370-
/*
371-
* We always check the partition constraint, including when the tuple
372-
* got here via tuple-routing. However we don't need to in the latter
373-
* case if no BR trigger is defined on the partition. Note that a BR
374-
* trigger might modify the tuple such that the partition constraint
375-
* is no longer satisfied, so we need to check in that case.
376-
*/
377-
check_partition_constr= (resultRelInfo->ri_PartitionCheck!=NIL);
378368

379369
/*
380370
* Constraints might reference the tableoid column, so initialize
@@ -402,17 +392,21 @@ ExecInsert(ModifyTableState *mtstate,
402392
ExecWithCheckOptions(wco_kind,resultRelInfo,slot,estate);
403393

404394
/*
405-
* No need though if the tuple has been routed, and a BR trigger
406-
* doesn't exist.
395+
* Check the constraints of the tuple.
407396
*/
408-
if (resultRelInfo->ri_PartitionRoot!=NULL&&
409-
!(resultRelInfo->ri_TrigDesc&&
410-
resultRelInfo->ri_TrigDesc->trig_insert_before_row))
411-
check_partition_constr= false;
397+
if (resultRelationDesc->rd_att->constr)
398+
ExecConstraints(resultRelInfo,slot,estate);
412399

413-
/* Check the constraints of the tuple */
414-
if (resultRelationDesc->rd_att->constr||check_partition_constr)
415-
ExecConstraints(resultRelInfo,slot,estate, true);
400+
/*
401+
* Also check the tuple against the partition constraint, if there is
402+
* one; except that if we got here via tuple-routing, we don't need to
403+
* if there's no BR trigger defined on the partition.
404+
*/
405+
if (resultRelInfo->ri_PartitionCheck&&
406+
(resultRelInfo->ri_PartitionRoot==NULL||
407+
(resultRelInfo->ri_TrigDesc&&
408+
resultRelInfo->ri_TrigDesc->trig_insert_before_row)))
409+
ExecPartitionCheck(resultRelInfo,slot,estate, true);
416410

417411
if (onconflict!=ONCONFLICT_NONE&&resultRelInfo->ri_NumIndices>0)
418412
{
@@ -1037,7 +1031,7 @@ lreplace:;
10371031
*/
10381032
partition_constraint_failed=
10391033
resultRelInfo->ri_PartitionCheck&&
1040-
!ExecPartitionCheck(resultRelInfo,slot,estate);
1034+
!ExecPartitionCheck(resultRelInfo,slot,estate, false);
10411035

10421036
if (!partition_constraint_failed&&
10431037
resultRelInfo->ri_WithCheckOptions!=NIL)
@@ -1168,7 +1162,7 @@ lreplace:;
11681162
* have it validate all remaining checks.
11691163
*/
11701164
if (resultRelationDesc->rd_att->constr)
1171-
ExecConstraints(resultRelInfo,slot,estate, false);
1165+
ExecConstraints(resultRelInfo,slot,estate);
11721166

11731167
/*
11741168
* replace the heap tuple

‎src/include/executor/executor.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,9 @@ extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
180180
externvoidExecCleanUpTriggerState(EState*estate);
181181
externboolExecContextForcesOids(PlanState*planstate,bool*hasoids);
182182
externvoidExecConstraints(ResultRelInfo*resultRelInfo,
183-
TupleTableSlot*slot,EState*estate,
184-
boolcheck_partition_constraint);
183+
TupleTableSlot*slot,EState*estate);
185184
externboolExecPartitionCheck(ResultRelInfo*resultRelInfo,
186-
TupleTableSlot*slot,EState*estate);
185+
TupleTableSlot*slot,EState*estate,boolemitError);
187186
externvoidExecPartitionCheckEmitError(ResultRelInfo*resultRelInfo,
188187
TupleTableSlot*slot,EState*estate);
189188
externvoidExecWithCheckOptions(WCOKindkind,ResultRelInfo*resultRelInfo,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp