diff --git a/src/backend/executor/nodeDML.c b/src/backend/executor/nodeDML.c index 33b2edf5387f..b27df25f0e0d 100644 --- a/src/backend/executor/nodeDML.c +++ b/src/backend/executor/nodeDML.c @@ -57,20 +57,19 @@ ExecDML(DMLState *node) { return NULL; } + EvalPlanQualSetSlot(&node->mt_epqstate, slot); bool isnull = false; - int action = DatumGetUInt32(slot_getattr(slot, plannode->actionColIdx, &isnull)); - Assert(!isnull); + int action = -1; + bool isUpdate = node->ps.state->es_plannedstmt->commandType == CMD_UPDATE; - bool isUpdate = false; - if (node->ps.state->es_plannedstmt->commandType == CMD_UPDATE) + // if it's not in place update + if(plannode->actionColIdx) { - isUpdate = true; + action = DatumGetUInt32(slot_getattr(slot, plannode->actionColIdx, &isnull)); + Assert(!isnull); } - Assert(action == DML_INSERT || action == DML_DELETE); - - /* * Reset per-tuple memory context to free any expression evaluation * storage allocated in the previous tuple cycle. @@ -123,7 +122,7 @@ ExecDML(DMLState *node) isUpdate, InvalidOid); } - else /* DML_DELETE */ + else if(DML_DELETE == action) { int32 segid = GpIdentity.segindex; Datum ctid = slot_getattr(slot, plannode->ctidColIdx, &isnull); @@ -151,6 +150,26 @@ ExecDML(DMLState *node) PLANGEN_OPTIMIZER /* Plan origin */, isUpdate); } + else /* in place update */ + { + int32 segid = GpIdentity.segindex; + + Datum ctid = slot_getattr(slot, plannode->ctidColIdx, &isnull); + + ItemPointer tupleid = (ItemPointer) DatumGetPointer(ctid); + ItemPointerData tuple_ctid = *tupleid; + tupleid = &tuple_ctid; + + ExecUpdate( + tupleid, + segid, + NULL, //oldtuple + node->cleanedUpSlot, + NULL, //planSlot + &node->mt_epqstate, + node->ps.state, + true); + } return slot; } @@ -186,6 +205,8 @@ ExecInitDML(DML *node, EState *estate, int eflags) Plan *outerPlan = outerPlan(node); outerPlanState(dmlstate) = ExecInitNode(outerPlan, estate, eflags); + EvalPlanQualInit(&dmlstate->mt_epqstate, estate, outerPlan, NIL, 0); + /* * ORCA Plan does not seem to set junk attribute for "gp_segment_id", else we * could call the simple code below. @@ -229,7 +250,7 @@ ExecInitDML(DML *node, EState *estate, int eflags) dmlstate->junkfilter = ExecInitJunkFilter(node->plan.targetlist, dmlstate->ps.state->es_result_relation_info->ri_RelationDesc->rd_att->tdhasoid, dmlstate->cleanedUpSlot); - + estate->es_result_relation_info->ri_junkFilter = dmlstate->junkfilter; /* * We don't maintain typmod in the targetlist, so we should fixup the * junkfilter to use the same tuple descriptor as the result relation. @@ -279,6 +300,7 @@ ExecEndDML(DMLState *node) ExecFreeExprContext(&node->ps); ExecClearTuple(node->ps.ps_ResultTupleSlot); ExecClearTuple(node->cleanedUpSlot); + EvalPlanQualEnd(&node->mt_epqstate); ExecEndNode(outerPlanState(node)); EndPlanStateGpmonPkt(&node->ps); } diff --git a/src/backend/gpopt/gpopt.mk b/src/backend/gpopt/gpopt.mk index 2d5bb258b26b..dfb291c4b3d6 100644 --- a/src/backend/gpopt/gpopt.mk +++ b/src/backend/gpopt/gpopt.mk @@ -1,4 +1,3 @@ -override CPPFLAGS := -std=c++98 $(CPPFLAGS) override CPPFLAGS := -I$(top_builddir)/src/backend/gporca/libgpos/include $(CPPFLAGS) override CPPFLAGS := -I$(top_builddir)/src/backend/gporca/libgpopt/include $(CPPFLAGS) override CPPFLAGS := -I$(top_builddir)/src/backend/gporca/libnaucrates/include $(CPPFLAGS) diff --git a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp index 13d594aa70fd..56f454571bad 100644 --- a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp +++ b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp @@ -4084,6 +4084,7 @@ CTranslatorDXLToPlStmt::TranslateDXLDml( DML *dml = MakeNode(DML); Plan *plan = &(dml->plan); AclMode acl_mode = ACL_NO_RIGHTS; + BOOL isSplit = phy_dml_dxlop->FSplit(); switch (phy_dml_dxlop->GetDmlOpType()) { @@ -4170,14 +4171,26 @@ CTranslatorDXLToPlStmt::TranslateDXLDml( dml_target_list = target_list_with_dropped_cols; } - // Extract column numbers of the action and ctid columns from the - // target list. - dml->actionColIdx = AddTargetEntryForColId(&dml_target_list, &child_context, - phy_dml_dxlop->ActionColId(), - true /*is_resjunk*/); + dml->ctidColIdx = AddTargetEntryForColId(&dml_target_list, &child_context, phy_dml_dxlop->GetCtIdColId(), true /*is_resjunk*/); + + // Doesn't needed for in place update + if (isSplit || CMD_UPDATE != m_cmd_type) + { + // Extract column numbers of the action and ctid columns from the + // target list. + dml->actionColIdx = AddTargetEntryForColId( + &dml_target_list, &child_context, phy_dml_dxlop->ActionColId(), + true /*is_resjunk*/); + GPOS_ASSERT(0 != dml->actionColIdx); + } + else + { + dml->actionColIdx = 0; + } + if (phy_dml_dxlop->IsOidsPreserved()) { dml->tupleoidColIdx = AddTargetEntryForColId( @@ -4189,8 +4202,6 @@ CTranslatorDXLToPlStmt::TranslateDXLDml( dml->tupleoidColIdx = 0; } - GPOS_ASSERT(0 != dml->actionColIdx); - plan->targetlist = dml_target_list; plan->lefttree = child_plan; diff --git a/src/backend/gporca/data/dxl/minidump/SelfUpdate.mdp b/src/backend/gporca/data/dxl/minidump/SelfUpdate.mdp index 756de4a8498b..0f25dec726e7 100644 --- a/src/backend/gporca/data/dxl/minidump/SelfUpdate.mdp +++ b/src/backend/gporca/data/dxl/minidump/SelfUpdate.mdp @@ -216,17 +216,17 @@ update t1 set b = c; </dxl:LogicalUpdate> </dxl:Query> <dxl:Plan Id="0" SpaceSize="1"> - <dxl:DMLUpdate Columns="0,2,2" ActionCol="10" CtidCol="3" SegmentIdCol="9" IsSplitUpdate="false" PreserveOids="false"> + <dxl:DMLUpdate Columns="0,1,2" ActionCol="10" CtidCol="3" SegmentIdCol="9" IsSplitUpdate="true"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.023462" Rows="1.000000" Width="1"/> + <dxl:Cost StartupCost="0" TotalCost="431.067764" Rows="1.000000" Width="1"/> </dxl:Properties> <dxl:DirectDispatchInfo/> <dxl:ProjList> <dxl:ProjElem ColId="0" Alias="a"> <dxl:Ident ColId="0" ColName="a" TypeMdid="0.23.1.0"/> </dxl:ProjElem> - <dxl:ProjElem ColId="2" Alias="c"> - <dxl:Ident ColId="2" ColName="c" TypeMdid="0.23.1.0"/> + <dxl:ProjElem ColId="1" Alias="b"> + <dxl:Ident ColId="1" ColName="b" TypeMdid="0.23.1.0"/> </dxl:ProjElem> <dxl:ProjElem ColId="2" Alias="c"> <dxl:Ident ColId="2" ColName="c" TypeMdid="0.23.1.0"/> @@ -248,14 +248,14 @@ update t1 set b = c; </dxl:TableDescriptor> <dxl:Assert ErrorCode="23502"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.000025" Rows="1.000000" Width="18"/> + <dxl:Cost StartupCost="0" TotalCost="431.000056" Rows="2.000000" Width="26"/> </dxl:Properties> <dxl:ProjList> <dxl:ProjElem ColId="0" Alias="a"> <dxl:Ident ColId="0" ColName="a" TypeMdid="0.23.1.0"/> </dxl:ProjElem> - <dxl:ProjElem ColId="2" Alias="c"> - <dxl:Ident ColId="2" ColName="c" TypeMdid="0.23.1.0"/> + <dxl:ProjElem ColId="1" Alias="b"> + <dxl:Ident ColId="1" ColName="b" TypeMdid="0.23.1.0"/> </dxl:ProjElem> <dxl:ProjElem ColId="2" Alias="c"> <dxl:Ident ColId="2" ColName="c" TypeMdid="0.23.1.0"/> @@ -266,6 +266,9 @@ update t1 set b = c; <dxl:ProjElem ColId="9" Alias="gp_segment_id"> <dxl:Ident ColId="9" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> </dxl:ProjElem> + <dxl:ProjElem ColId="10" Alias="ColRef_0010"> + <dxl:Ident ColId="10" ColName="ColRef_0010" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> </dxl:ProjList> <dxl:AssertConstraintList> <dxl:AssertConstraint ErrorMessage="Not null constraint for column b of table t1 was violated"> @@ -276,14 +279,17 @@ update t1 set b = c; </dxl:Not> </dxl:AssertConstraint> </dxl:AssertConstraintList> - <dxl:TableScan> + <dxl:Split DeleteColumns="0,1,2" InsertColumns="0,2,2" ActionCol="10" CtidCol="3" SegmentIdCol="9" PreserveOids="false"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.000008" Rows="1.000000" Width="18"/> + <dxl:Cost StartupCost="0" TotalCost="431.000039" Rows="2.000000" Width="26"/> </dxl:Properties> <dxl:ProjList> <dxl:ProjElem ColId="0" Alias="a"> <dxl:Ident ColId="0" ColName="a" TypeMdid="0.23.1.0"/> </dxl:ProjElem> + <dxl:ProjElem ColId="1" Alias="b"> + <dxl:Ident ColId="1" ColName="b" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> <dxl:ProjElem ColId="2" Alias="c"> <dxl:Ident ColId="2" ColName="c" TypeMdid="0.23.1.0"/> </dxl:ProjElem> @@ -293,23 +299,48 @@ update t1 set b = c; <dxl:ProjElem ColId="9" Alias="gp_segment_id"> <dxl:Ident ColId="9" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> </dxl:ProjElem> + <dxl:ProjElem ColId="10" Alias="ColRef_0010"> + <dxl:DMLAction/> + </dxl:ProjElem> </dxl:ProjList> - <dxl:Filter/> - <dxl:TableDescriptor Mdid="6.47297780.1.1" TableName="t1"> - <dxl:Columns> - <dxl:Column ColId="0" Attno="1" ColName="a" TypeMdid="0.23.1.0"/> - <dxl:Column ColId="1" Attno="2" ColName="b" TypeMdid="0.23.1.0"/> - <dxl:Column ColId="2" Attno="3" ColName="c" TypeMdid="0.23.1.0"/> - <dxl:Column ColId="3" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0"/> - <dxl:Column ColId="4" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0"/> - <dxl:Column ColId="5" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0"/> - <dxl:Column ColId="6" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0"/> - <dxl:Column ColId="7" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0"/> - <dxl:Column ColId="8" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0"/> - <dxl:Column ColId="9" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> - </dxl:Columns> - </dxl:TableDescriptor> - </dxl:TableScan> + <dxl:TableScan> + <dxl:Properties> + <dxl:Cost StartupCost="0" TotalCost="431.000008" Rows="1.000000" Width="22"/> + </dxl:Properties> + <dxl:ProjList> + <dxl:ProjElem ColId="0" Alias="a"> + <dxl:Ident ColId="0" ColName="a" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="1" Alias="b"> + <dxl:Ident ColId="1" ColName="b" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="2" Alias="c"> + <dxl:Ident ColId="2" ColName="c" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="3" Alias="ctid"> + <dxl:Ident ColId="3" ColName="ctid" TypeMdid="0.27.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="9" Alias="gp_segment_id"> + <dxl:Ident ColId="9" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + </dxl:ProjList> + <dxl:Filter/> + <dxl:TableDescriptor Mdid="6.47297780.1.1" TableName="t1"> + <dxl:Columns> + <dxl:Column ColId="0" Attno="1" ColName="a" TypeMdid="0.23.1.0"/> + <dxl:Column ColId="1" Attno="2" ColName="b" TypeMdid="0.23.1.0"/> + <dxl:Column ColId="2" Attno="3" ColName="c" TypeMdid="0.23.1.0"/> + <dxl:Column ColId="3" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0"/> + <dxl:Column ColId="4" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0"/> + <dxl:Column ColId="5" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0"/> + <dxl:Column ColId="6" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0"/> + <dxl:Column ColId="7" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0"/> + <dxl:Column ColId="8" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0"/> + <dxl:Column ColId="9" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> + </dxl:Columns> + </dxl:TableDescriptor> + </dxl:TableScan> + </dxl:Split> </dxl:Assert> </dxl:DMLUpdate> </dxl:Plan> diff --git a/src/backend/gporca/data/dxl/minidump/UpdateRandomDistr.mdp b/src/backend/gporca/data/dxl/minidump/UpdateRandomDistr.mdp index 2f06ffe77147..48b35e85f9db 100644 --- a/src/backend/gporca/data/dxl/minidump/UpdateRandomDistr.mdp +++ b/src/backend/gporca/data/dxl/minidump/UpdateRandomDistr.mdp @@ -195,15 +195,15 @@ </dxl:LogicalProject> </dxl:LogicalUpdate> </dxl:Query> - <dxl:Plan Id="0" SpaceSize="2"> - <dxl:DMLUpdate Columns="9,1" ActionCol="10" CtidCol="2" SegmentIdCol="8" IsSplitUpdate="false" PreserveOids="false"> + <dxl:Plan Id="0" SpaceSize="1"> + <dxl:DMLUpdate Columns="0,1" ActionCol="10" CtidCol="2" SegmentIdCol="8" IsSplitUpdate="true"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.035189" Rows="1.000000" Width="1"/> + <dxl:Cost StartupCost="0" TotalCost="431.085998" Rows="1.000000" Width="1"/> </dxl:Properties> <dxl:DirectDispatchInfo/> <dxl:ProjList> - <dxl:ProjElem ColId="9" Alias="a"> - <dxl:Ident ColId="9" ColName="a" TypeMdid="0.23.1.0"/> + <dxl:ProjElem ColId="0" Alias="a"> + <dxl:Ident ColId="0" ColName="a" TypeMdid="0.23.1.0"/> </dxl:ProjElem> <dxl:ProjElem ColId="1" Alias="b"> <dxl:Ident ColId="1" ColName="b" TypeMdid="0.23.1.0"/> @@ -222,13 +222,13 @@ <dxl:Column ColId="19" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> </dxl:Columns> </dxl:TableDescriptor> - <dxl:Result> + <dxl:Split DeleteColumns="0,1" InsertColumns="9,1" ActionCol="10" CtidCol="2" SegmentIdCol="8" PreserveOids="false"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.000032" Rows="1.000000" Width="18"/> + <dxl:Cost StartupCost="0" TotalCost="431.000060" Rows="2.000000" Width="22"/> </dxl:Properties> <dxl:ProjList> - <dxl:ProjElem ColId="9" Alias="a"> - <dxl:ConstValue TypeMdid="0.23.1.0" Value="5"/> + <dxl:ProjElem ColId="0" Alias="a"> + <dxl:Ident ColId="0" ColName="a" TypeMdid="0.23.1.0"/> </dxl:ProjElem> <dxl:ProjElem ColId="1" Alias="b"> <dxl:Ident ColId="1" ColName="b" TypeMdid="0.23.1.0"/> @@ -239,17 +239,24 @@ <dxl:ProjElem ColId="8" Alias="gp_segment_id"> <dxl:Ident ColId="8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> </dxl:ProjElem> + <dxl:ProjElem ColId="10" Alias="ColRef_0010"> + <dxl:DMLAction/> + </dxl:ProjElem> </dxl:ProjList> - <dxl:Filter/> - <dxl:OneTimeFilter/> - <dxl:TableScan> + <dxl:Result> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.000010" Rows="1.000000" Width="14"/> + <dxl:Cost StartupCost="0" TotalCost="431.000038" Rows="1.000000" Width="22"/> </dxl:Properties> <dxl:ProjList> + <dxl:ProjElem ColId="0" Alias="a"> + <dxl:Ident ColId="0" ColName="a" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> <dxl:ProjElem ColId="1" Alias="b"> <dxl:Ident ColId="1" ColName="b" TypeMdid="0.23.1.0"/> </dxl:ProjElem> + <dxl:ProjElem ColId="9" Alias="a"> + <dxl:ConstValue TypeMdid="0.23.1.0" Value="5"/> + </dxl:ProjElem> <dxl:ProjElem ColId="2" Alias="ctid"> <dxl:Ident ColId="2" ColName="ctid" TypeMdid="0.27.1.0"/> </dxl:ProjElem> @@ -258,21 +265,42 @@ </dxl:ProjElem> </dxl:ProjList> <dxl:Filter/> - <dxl:TableDescriptor Mdid="6.17027.1.1" TableName="rr"> - <dxl:Columns> - <dxl:Column ColId="0" Attno="1" ColName="a" TypeMdid="0.23.1.0"/> - <dxl:Column ColId="1" Attno="2" ColName="b" TypeMdid="0.23.1.0"/> - <dxl:Column ColId="2" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0"/> - <dxl:Column ColId="3" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0"/> - <dxl:Column ColId="4" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0"/> - <dxl:Column ColId="5" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0"/> - <dxl:Column ColId="6" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0"/> - <dxl:Column ColId="7" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0"/> - <dxl:Column ColId="8" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> - </dxl:Columns> - </dxl:TableDescriptor> - </dxl:TableScan> - </dxl:Result> + <dxl:OneTimeFilter/> + <dxl:TableScan> + <dxl:Properties> + <dxl:Cost StartupCost="0" TotalCost="431.000010" Rows="1.000000" Width="18"/> + </dxl:Properties> + <dxl:ProjList> + <dxl:ProjElem ColId="0" Alias="a"> + <dxl:Ident ColId="0" ColName="a" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="1" Alias="b"> + <dxl:Ident ColId="1" ColName="b" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="2" Alias="ctid"> + <dxl:Ident ColId="2" ColName="ctid" TypeMdid="0.27.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="8" Alias="gp_segment_id"> + <dxl:Ident ColId="8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + </dxl:ProjList> + <dxl:Filter/> + <dxl:TableDescriptor Mdid="6.17027.1.1" TableName="rr"> + <dxl:Columns> + <dxl:Column ColId="0" Attno="1" ColName="a" TypeMdid="0.23.1.0"/> + <dxl:Column ColId="1" Attno="2" ColName="b" TypeMdid="0.23.1.0"/> + <dxl:Column ColId="2" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0"/> + <dxl:Column ColId="3" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0"/> + <dxl:Column ColId="4" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0"/> + <dxl:Column ColId="5" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0"/> + <dxl:Column ColId="6" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0"/> + <dxl:Column ColId="7" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0"/> + <dxl:Column ColId="8" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> + </dxl:Columns> + </dxl:TableDescriptor> + </dxl:TableScan> + </dxl:Result> + </dxl:Split> </dxl:DMLUpdate> </dxl:Plan> </dxl:Thread> diff --git a/src/backend/gporca/data/dxl/minidump/UpdateWindowGatherMerge.mdp b/src/backend/gporca/data/dxl/minidump/UpdateWindowGatherMerge.mdp index 40e5ae7a755a..d650c5cb9502 100644 --- a/src/backend/gporca/data/dxl/minidump/UpdateWindowGatherMerge.mdp +++ b/src/backend/gporca/data/dxl/minidump/UpdateWindowGatherMerge.mdp @@ -708,15 +708,15 @@ </dxl:LogicalJoin> </dxl:LogicalUpdate> </dxl:Query> - <dxl:Plan Id="0" SpaceSize="20"> - <dxl:DMLUpdate Columns="18,1" ActionCol="19" CtidCol="2" SegmentIdCol="8" IsSplitUpdate="false" PreserveOids="false"> + <dxl:Plan Id="0" SpaceSize="18"> + <dxl:DMLUpdate Columns="0,1" ActionCol="19" CtidCol="2" SegmentIdCol="8" IsSplitUpdate="true"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="864.385336" Rows="100.000001" Width="1"/> + <dxl:Cost StartupCost="0" TotalCost="867.779091" Rows="100.000001" Width="1"/> </dxl:Properties> <dxl:DirectDispatchInfo/> <dxl:ProjList> - <dxl:ProjElem ColId="18" Alias="i"> - <dxl:Ident ColId="18" ColName="i" TypeMdid="0.23.1.0"/> + <dxl:ProjElem ColId="0" Alias="i"> + <dxl:Ident ColId="0" ColName="i" TypeMdid="0.23.1.0"/> </dxl:ProjElem> <dxl:ProjElem ColId="1" Alias="j"> <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> @@ -737,11 +737,11 @@ </dxl:TableDescriptor> <dxl:RoutedDistributeMotion SegmentIdCol="8" InputSegments="0,1,2" OutputSegments="0,1,2"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="862.041586" Rows="100.000001" Width="18"/> + <dxl:Cost StartupCost="0" TotalCost="862.049924" Rows="200.000002" Width="22"/> </dxl:Properties> <dxl:ProjList> - <dxl:ProjElem ColId="18" Alias="i"> - <dxl:Ident ColId="18" ColName="i" TypeMdid="0.23.1.0"/> + <dxl:ProjElem ColId="0" Alias="i"> + <dxl:Ident ColId="0" ColName="i" TypeMdid="0.23.1.0"/> </dxl:ProjElem> <dxl:ProjElem ColId="1" Alias="j"> <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> @@ -752,16 +752,19 @@ <dxl:ProjElem ColId="8" Alias="gp_segment_id"> <dxl:Ident ColId="8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> </dxl:ProjElem> + <dxl:ProjElem ColId="19" Alias="ColRef_0019"> + <dxl:Ident ColId="19" ColName="ColRef_0019" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> </dxl:ProjList> <dxl:Filter/> <dxl:SortingColumnList/> - <dxl:HashJoin JoinType="Inner"> + <dxl:Split DeleteColumns="0,1" InsertColumns="18,1" ActionCol="19" CtidCol="2" SegmentIdCol="8" PreserveOids="false"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="862.039708" Rows="100.000001" Width="18"/> + <dxl:Cost StartupCost="0" TotalCost="862.045333" Rows="200.000002" Width="22"/> </dxl:Properties> <dxl:ProjList> - <dxl:ProjElem ColId="18" Alias="i"> - <dxl:Ident ColId="18" ColName="i" TypeMdid="0.23.1.0"/> + <dxl:ProjElem ColId="0" Alias="i"> + <dxl:Ident ColId="0" ColName="i" TypeMdid="0.23.1.0"/> </dxl:ProjElem> <dxl:ProjElem ColId="1" Alias="j"> <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> @@ -772,37 +775,42 @@ <dxl:ProjElem ColId="8" Alias="gp_segment_id"> <dxl:Ident ColId="8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> </dxl:ProjElem> + <dxl:ProjElem ColId="19" Alias="ColRef_0019"> + <dxl:DMLAction/> + </dxl:ProjElem> </dxl:ProjList> - <dxl:Filter/> - <dxl:JoinFilter/> - <dxl:HashCondList> - <dxl:Comparison ComparisonOperator="=" OperatorMdid="0.96.1.0"> - <dxl:Ident ColId="10" ColName="j" TypeMdid="0.23.1.0"/> - <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> - </dxl:Comparison> - </dxl:HashCondList> - <dxl:RedistributeMotion InputSegments="0" OutputSegments="0,1,2"> + <dxl:HashJoin JoinType="Inner"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.014700" Rows="100.000000" Width="8"/> + <dxl:Cost StartupCost="0" TotalCost="862.043867" Rows="100.000001" Width="22"/> </dxl:Properties> <dxl:ProjList> - <dxl:ProjElem ColId="10" Alias="j"> - <dxl:Ident ColId="10" ColName="j" TypeMdid="0.23.1.0"/> + <dxl:ProjElem ColId="0" Alias="i"> + <dxl:Ident ColId="0" ColName="i" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="1" Alias="j"> + <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> </dxl:ProjElem> <dxl:ProjElem ColId="18" Alias="i"> <dxl:Ident ColId="18" ColName="i" TypeMdid="0.23.1.0"/> </dxl:ProjElem> + <dxl:ProjElem ColId="2" Alias="ctid"> + <dxl:Ident ColId="2" ColName="ctid" TypeMdid="0.27.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="8" Alias="gp_segment_id"> + <dxl:Ident ColId="8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> </dxl:ProjList> <dxl:Filter/> - <dxl:SortingColumnList/> - <dxl:HashExprList> - <dxl:HashExpr Opfamily="0.1977.1.0"> + <dxl:JoinFilter/> + <dxl:HashCondList> + <dxl:Comparison ComparisonOperator="=" OperatorMdid="0.96.1.0"> <dxl:Ident ColId="10" ColName="j" TypeMdid="0.23.1.0"/> - </dxl:HashExpr> - </dxl:HashExprList> - <dxl:Result> + <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> + </dxl:Comparison> + </dxl:HashCondList> + <dxl:RedistributeMotion InputSegments="0" OutputSegments="0,1,2"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.012623" Rows="100.000000" Width="8"/> + <dxl:Cost StartupCost="0" TotalCost="431.014700" Rows="100.000000" Width="8"/> </dxl:Properties> <dxl:ProjList> <dxl:ProjElem ColId="10" Alias="j"> @@ -813,41 +821,44 @@ </dxl:ProjElem> </dxl:ProjList> <dxl:Filter/> - <dxl:OneTimeFilter/> - <dxl:Window PartitionColumns=""> + <dxl:SortingColumnList/> + <dxl:HashExprList> + <dxl:HashExpr Opfamily="0.1977.1.0"> + <dxl:Ident ColId="10" ColName="j" TypeMdid="0.23.1.0"/> + </dxl:HashExpr> + </dxl:HashExprList> + <dxl:Result> <dxl:Properties> <dxl:Cost StartupCost="0" TotalCost="431.012623" Rows="100.000000" Width="8"/> </dxl:Properties> <dxl:ProjList> - <dxl:ProjElem ColId="18" Alias="i"> - <dxl:WindowFunc Mdid="0.2132.1.0" TypeMdid="0.23.1.0" Distinct="false" WindowStarArg="false" WindowSimpleAgg="true" WindowStrategy="Immediate" WinSpecPos="0"> - <dxl:Ident ColId="9" ColName="i" TypeMdid="0.23.1.0"/> - </dxl:WindowFunc> - </dxl:ProjElem> <dxl:ProjElem ColId="10" Alias="j"> <dxl:Ident ColId="10" ColName="j" TypeMdid="0.23.1.0"/> </dxl:ProjElem> + <dxl:ProjElem ColId="18" Alias="i"> + <dxl:Ident ColId="18" ColName="i" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> </dxl:ProjList> <dxl:Filter/> - <dxl:GatherMotion InputSegments="0,1,2" OutputSegments="0"> + <dxl:OneTimeFilter/> + <dxl:Window PartitionColumns=""> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.011823" Rows="100.000000" Width="8"/> + <dxl:Cost StartupCost="0" TotalCost="431.012623" Rows="100.000000" Width="8"/> </dxl:Properties> <dxl:ProjList> - <dxl:ProjElem ColId="9" Alias="i"> - <dxl:Ident ColId="9" ColName="i" TypeMdid="0.23.1.0"/> + <dxl:ProjElem ColId="18" Alias="i"> + <dxl:WindowFunc Mdid="0.2132.1.0" TypeMdid="0.23.1.0" Distinct="false" WindowStarArg="false" WindowSimpleAgg="true" WindowStrategy="Immediate" WinSpecPos="0"> + <dxl:Ident ColId="9" ColName="i" TypeMdid="0.23.1.0"/> + </dxl:WindowFunc> </dxl:ProjElem> <dxl:ProjElem ColId="10" Alias="j"> <dxl:Ident ColId="10" ColName="j" TypeMdid="0.23.1.0"/> </dxl:ProjElem> </dxl:ProjList> <dxl:Filter/> - <dxl:SortingColumnList> - <dxl:SortingColumn ColId="10" SortOperatorMdid="0.97.1.0" SortOperatorName="<" SortNullsFirst="false"/> - </dxl:SortingColumnList> - <dxl:Sort SortDiscardDuplicates="false"> + <dxl:GatherMotion InputSegments="0,1,2" OutputSegments="0"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.008842" Rows="100.000000" Width="8"/> + <dxl:Cost StartupCost="0" TotalCost="431.011823" Rows="100.000000" Width="8"/> </dxl:Properties> <dxl:ProjList> <dxl:ProjElem ColId="9" Alias="i"> @@ -861,11 +872,9 @@ <dxl:SortingColumnList> <dxl:SortingColumn ColId="10" SortOperatorMdid="0.97.1.0" SortOperatorName="<" SortNullsFirst="false"/> </dxl:SortingColumnList> - <dxl:LimitCount/> - <dxl:LimitOffset/> - <dxl:TableScan> + <dxl:Sort SortDiscardDuplicates="false"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.000697" Rows="100.000000" Width="8"/> + <dxl:Cost StartupCost="0" TotalCost="431.008842" Rows="100.000000" Width="8"/> </dxl:Properties> <dxl:ProjList> <dxl:ProjElem ColId="9" Alias="i"> @@ -876,63 +885,62 @@ </dxl:ProjElem> </dxl:ProjList> <dxl:Filter/> - <dxl:TableDescriptor Mdid="6.251337.1.0" TableName="window_agg_test"> - <dxl:Columns> - <dxl:Column ColId="9" Attno="1" ColName="i" TypeMdid="0.23.1.0" ColWidth="4"/> - <dxl:Column ColId="10" Attno="2" ColName="j" TypeMdid="0.23.1.0" ColWidth="4"/> - <dxl:Column ColId="11" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0" ColWidth="6"/> - <dxl:Column ColId="12" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0" ColWidth="4"/> - <dxl:Column ColId="13" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0" ColWidth="4"/> - <dxl:Column ColId="14" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0" ColWidth="4"/> - <dxl:Column ColId="15" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0" ColWidth="4"/> - <dxl:Column ColId="16" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0" ColWidth="4"/> - <dxl:Column ColId="17" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0" ColWidth="4"/> - </dxl:Columns> - </dxl:TableDescriptor> - </dxl:TableScan> - </dxl:Sort> - </dxl:GatherMotion> - <dxl:WindowKeyList> - <dxl:WindowKey> - <dxl:SortingColumnList> - <dxl:SortingColumn ColId="10" SortOperatorMdid="0.97.1.0" SortOperatorName="<" SortNullsFirst="false"/> - </dxl:SortingColumnList> - <dxl:WindowFrame FrameSpec="Range" ExclusionStrategy="Nulls"> - <dxl:TrailingEdge TrailingBoundary="UnboundedPreceding"/> - <dxl:LeadingEdge LeadingBoundary="CurrentRow"/> - </dxl:WindowFrame> - </dxl:WindowKey> - </dxl:WindowKeyList> - </dxl:Window> - </dxl:Result> - </dxl:RedistributeMotion> - <dxl:RedistributeMotion InputSegments="0,1,2" OutputSegments="0,1,2"> - <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.003025" Rows="100.000000" Width="14"/> - </dxl:Properties> - <dxl:ProjList> - <dxl:ProjElem ColId="1" Alias="j"> - <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> - </dxl:ProjElem> - <dxl:ProjElem ColId="2" Alias="ctid"> - <dxl:Ident ColId="2" ColName="ctid" TypeMdid="0.27.1.0"/> - </dxl:ProjElem> - <dxl:ProjElem ColId="8" Alias="gp_segment_id"> - <dxl:Ident ColId="8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> - </dxl:ProjElem> - </dxl:ProjList> - <dxl:Filter/> - <dxl:SortingColumnList/> - <dxl:HashExprList> - <dxl:HashExpr Opfamily="0.1977.1.0"> - <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> - </dxl:HashExpr> - </dxl:HashExprList> - <dxl:TableScan> + <dxl:SortingColumnList> + <dxl:SortingColumn ColId="10" SortOperatorMdid="0.97.1.0" SortOperatorName="<" SortNullsFirst="false"/> + </dxl:SortingColumnList> + <dxl:LimitCount/> + <dxl:LimitOffset/> + <dxl:TableScan> + <dxl:Properties> + <dxl:Cost StartupCost="0" TotalCost="431.000697" Rows="100.000000" Width="8"/> + </dxl:Properties> + <dxl:ProjList> + <dxl:ProjElem ColId="9" Alias="i"> + <dxl:Ident ColId="9" ColName="i" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="10" Alias="j"> + <dxl:Ident ColId="10" ColName="j" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + </dxl:ProjList> + <dxl:Filter/> + <dxl:TableDescriptor Mdid="6.251337.1.0" TableName="window_agg_test"> + <dxl:Columns> + <dxl:Column ColId="9" Attno="1" ColName="i" TypeMdid="0.23.1.0" ColWidth="4"/> + <dxl:Column ColId="10" Attno="2" ColName="j" TypeMdid="0.23.1.0" ColWidth="4"/> + <dxl:Column ColId="11" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0" ColWidth="6"/> + <dxl:Column ColId="12" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0" ColWidth="4"/> + <dxl:Column ColId="13" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0" ColWidth="4"/> + <dxl:Column ColId="14" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0" ColWidth="4"/> + <dxl:Column ColId="15" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0" ColWidth="4"/> + <dxl:Column ColId="16" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0" ColWidth="4"/> + <dxl:Column ColId="17" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0" ColWidth="4"/> + </dxl:Columns> + </dxl:TableDescriptor> + </dxl:TableScan> + </dxl:Sort> + </dxl:GatherMotion> + <dxl:WindowKeyList> + <dxl:WindowKey> + <dxl:SortingColumnList> + <dxl:SortingColumn ColId="10" SortOperatorMdid="0.97.1.0" SortOperatorName="<" SortNullsFirst="false"/> + </dxl:SortingColumnList> + <dxl:WindowFrame FrameSpec="Range" ExclusionStrategy="Nulls"> + <dxl:TrailingEdge TrailingBoundary="UnboundedPreceding"/> + <dxl:LeadingEdge LeadingBoundary="CurrentRow"/> + </dxl:WindowFrame> + </dxl:WindowKey> + </dxl:WindowKeyList> + </dxl:Window> + </dxl:Result> + </dxl:RedistributeMotion> + <dxl:RedistributeMotion InputSegments="0,1,2" OutputSegments="0,1,2"> <dxl:Properties> - <dxl:Cost StartupCost="0" TotalCost="431.000697" Rows="100.000000" Width="14"/> + <dxl:Cost StartupCost="0" TotalCost="431.003691" Rows="100.000000" Width="18"/> </dxl:Properties> <dxl:ProjList> + <dxl:ProjElem ColId="0" Alias="i"> + <dxl:Ident ColId="0" ColName="i" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> <dxl:ProjElem ColId="1" Alias="j"> <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> </dxl:ProjElem> @@ -944,22 +952,48 @@ </dxl:ProjElem> </dxl:ProjList> <dxl:Filter/> - <dxl:TableDescriptor Mdid="6.251337.1.0" TableName="window_agg_test"> - <dxl:Columns> - <dxl:Column ColId="0" Attno="1" ColName="i" TypeMdid="0.23.1.0" ColWidth="4"/> - <dxl:Column ColId="1" Attno="2" ColName="j" TypeMdid="0.23.1.0" ColWidth="4"/> - <dxl:Column ColId="2" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0" ColWidth="6"/> - <dxl:Column ColId="3" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0" ColWidth="4"/> - <dxl:Column ColId="4" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0" ColWidth="4"/> - <dxl:Column ColId="5" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0" ColWidth="4"/> - <dxl:Column ColId="6" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0" ColWidth="4"/> - <dxl:Column ColId="7" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0" ColWidth="4"/> - <dxl:Column ColId="8" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0" ColWidth="4"/> - </dxl:Columns> - </dxl:TableDescriptor> - </dxl:TableScan> - </dxl:RedistributeMotion> - </dxl:HashJoin> + <dxl:SortingColumnList/> + <dxl:HashExprList> + <dxl:HashExpr Opfamily="0.1977.1.0"> + <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> + </dxl:HashExpr> + </dxl:HashExprList> + <dxl:TableScan> + <dxl:Properties> + <dxl:Cost StartupCost="0" TotalCost="431.000697" Rows="100.000000" Width="18"/> + </dxl:Properties> + <dxl:ProjList> + <dxl:ProjElem ColId="0" Alias="i"> + <dxl:Ident ColId="0" ColName="i" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="1" Alias="j"> + <dxl:Ident ColId="1" ColName="j" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="2" Alias="ctid"> + <dxl:Ident ColId="2" ColName="ctid" TypeMdid="0.27.1.0"/> + </dxl:ProjElem> + <dxl:ProjElem ColId="8" Alias="gp_segment_id"> + <dxl:Ident ColId="8" ColName="gp_segment_id" TypeMdid="0.23.1.0"/> + </dxl:ProjElem> + </dxl:ProjList> + <dxl:Filter/> + <dxl:TableDescriptor Mdid="6.251337.1.0" TableName="window_agg_test"> + <dxl:Columns> + <dxl:Column ColId="0" Attno="1" ColName="i" TypeMdid="0.23.1.0" ColWidth="4"/> + <dxl:Column ColId="1" Attno="2" ColName="j" TypeMdid="0.23.1.0" ColWidth="4"/> + <dxl:Column ColId="2" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0" ColWidth="6"/> + <dxl:Column ColId="3" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0" ColWidth="4"/> + <dxl:Column ColId="4" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0" ColWidth="4"/> + <dxl:Column ColId="5" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0" ColWidth="4"/> + <dxl:Column ColId="6" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0" ColWidth="4"/> + <dxl:Column ColId="7" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0" ColWidth="4"/> + <dxl:Column ColId="8" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0" ColWidth="4"/> + </dxl:Columns> + </dxl:TableDescriptor> + </dxl:TableScan> + </dxl:RedistributeMotion> + </dxl:HashJoin> + </dxl:Split> </dxl:RoutedDistributeMotion> </dxl:DMLUpdate> </dxl:Plan> diff --git a/src/backend/gporca/gporca.mk b/src/backend/gporca/gporca.mk index 0bbedd33396b..d5f49e648b7f 100644 --- a/src/backend/gporca/gporca.mk +++ b/src/backend/gporca/gporca.mk @@ -5,4 +5,3 @@ override CPPFLAGS := -I$(top_builddir)/src/backend/gporca/libgpdbcost/include $( # Do not omit frame pointer. Even with RELEASE builds, it is used for # backtracing. override CPPFLAGS := -Werror -Wextra -Wpedantic -Wno-variadic-macros -fno-omit-frame-pointer $(CPPFLAGS) -override CPPFLAGS := -std=gnu++98 $(CPPFLAGS) diff --git a/src/backend/gporca/libgpopt/src/operators/CExpressionPreprocessor.cpp b/src/backend/gporca/libgpopt/src/operators/CExpressionPreprocessor.cpp index 727b6ba161a0..8e828757fc80 100644 --- a/src/backend/gporca/libgpopt/src/operators/CExpressionPreprocessor.cpp +++ b/src/backend/gporca/libgpopt/src/operators/CExpressionPreprocessor.cpp @@ -3300,6 +3300,12 @@ CExpressionPreprocessor::ConvertSplitUpdateToInPlaceUpdate(CMemoryPool *mp, const ULongPtrArray *pdrgpulPart = tabdesc->PdrgpulPart(); const ULONG ulPartKeys = pdrgpulPart->Size(); + if (tabdesc->GetRelDistribution() == + IMDRelation::Ereldistrpolicy::EreldistrRandom) + { + split_update = true; + } + // Uses split update if any of the modified columns are either // distribution or partition keys. // FIXME: Tested on distribution columns. Validate this after DML on @@ -3315,9 +3321,10 @@ CExpressionPreprocessor::ConvertSplitUpdateToInPlaceUpdate(CMemoryPool *mp, { CColRef *pcrInsert = (*pdrgpcrInsert)[ul]; CColRef *pcrDelete = (*pdrgpcrDelete)[ul]; + // Checking if column is either distribution or partition key. - if (pcrInsert != pcrDelete && - (pcrDelete->IsDistCol() || ppartColRefs->Find(pcrInsert) != NULL)) + if ((pcrInsert != pcrDelete && pcrDelete->IsDistCol()) || + (ppartColRefs->Find(pcrInsert) != NULL)) { split_update = true; break; diff --git a/src/backend/gporca/libgpopt/src/xforms/CXformUpdate2DML.cpp b/src/backend/gporca/libgpopt/src/xforms/CXformUpdate2DML.cpp index 522928472c01..80249bf2f82e 100644 --- a/src/backend/gporca/libgpopt/src/xforms/CXformUpdate2DML.cpp +++ b/src/backend/gporca/libgpopt/src/xforms/CXformUpdate2DML.cpp @@ -151,26 +151,6 @@ CXformUpdate2DML::Transform(CXformContext *pxfctxt, CXformResult *pxfres, pexprAssertConstraints = pexprSplit; } - // generate oid column and project operator - CExpression *pexprProject = NULL; - if (ptabdesc->IsPartitioned()) - { - // generate a partition selector - pexprProject = CXformUtils::PexprLogicalPartitionSelector( - mp, ptabdesc, pdrgpcrInsert, pexprAssertConstraints); - } - else - { - // generate a project operator - IMDId *pmdidTable = ptabdesc->MDId(); - - OID oidTable = CMDIdGPDB::CastMdid(pmdidTable)->Oid(); - CExpression *pexprOid = CUtils::PexprScalarConstOid(mp, oidTable); - - pexprProject = - CUtils::PexprAddProjection(mp, pexprAssertConstraints, pexprOid); - } - const ULONG num_cols = pdrgpcrInsert->Size(); CExpression *pexprDML = NULL; @@ -199,7 +179,7 @@ CXformUpdate2DML::Transform(CXformContext *pxfctxt, CXformResult *pxfres, CLogicalDML(mp, CLogicalDML::EdmlUpdate, ptabdesc, pdrgpcrDelete, pbsModified, pcrAction, pcrCtid, pcrSegmentId, pcrTupleOid, fSplit), - pexprProject); + pexprAssertConstraints); } else { @@ -210,7 +190,7 @@ CXformUpdate2DML::Transform(CXformContext *pxfctxt, CXformResult *pxfres, CLogicalDML(mp, CLogicalDML::EdmlUpdate, ptabdesc, pdrgpcrInsert, GPOS_NEW(mp) CBitSet(mp), pcrAction, pcrCtid, pcrSegmentId, NULL, fSplit), - pexprProject); + pexprAssertConstraints); } // TODO: - Oct 30, 2012; detect and handle AFTER triggers on update diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 0c6692e9eac9..cfb9238304c7 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -2831,6 +2831,7 @@ typedef struct DMLState JunkFilter *junkfilter; /* filter that removes junk and dropped attributes */ TupleTableSlot *cleanedUpSlot; /* holds 'final' tuple which matches the target relation schema */ AttrNumber segid_attno; /* attribute number of "gp_segment_id" */ + EPQState mt_epqstate; /* for evaluating EvalPlanQual rechecks */ } DMLState; /* diff --git a/src/test/isolation2/expected/gdd/concurrent_update_optimizer.out b/src/test/isolation2/expected/gdd/concurrent_update_optimizer.out index da71357fdba3..097f3fe7f8ea 100644 --- a/src/test/isolation2/expected/gdd/concurrent_update_optimizer.out +++ b/src/test/isolation2/expected/gdd/concurrent_update_optimizer.out @@ -353,29 +353,28 @@ UPDATE 1 -- make sure planner will contain InitPlan -- NOTE: orca does not generate InitPlan. 2: explain update t_epq_subplans set b = b + 1 where a > -1.5 * (select max(a) from t_epq_subplans); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ - Update (cost=0.00..1324032.68 rows=1 width=1) - -> Split (cost=0.00..1324032.61 rows=1 width=22) - -> Result (cost=0.00..1324032.61 rows=1 width=22) - -> Seq Scan on t_epq_subplans (cost=0.00..1324032.61 rows=1 width=18) - Filter: ((a)::numeric > ((-1.5) * ((SubPlan 1))::numeric)) - SubPlan 1 (slice0; segments: 3) - -> Materialize (cost=0.00..431.00 rows=1 width=4) - -> Broadcast Motion 1:3 (slice2; segments: 1) (cost=0.00..431.00 rows=3 width=4) - -> Aggregate (cost=0.00..431.00 rows=1 width=4) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=4) - -> Aggregate (cost=0.00..431.00 rows=1 width=4) - -> Seq Scan on t_epq_subplans t_epq_subplans_1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) -(14 rows) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Update (cost=0.00..1324032.63 rows=1 width=1) + -> Result (cost=0.00..1324032.61 rows=1 width=18) + -> Seq Scan on t_epq_subplans (cost=0.00..1324032.61 rows=1 width=18) + Filter: ((a)::numeric > ('-1.5'::numeric * ((SubPlan 1))::numeric)) + SubPlan 1 (slice0; segments: 3) + -> Materialize (cost=0.00..431.00 rows=1 width=4) + -> Broadcast Motion 1:3 (slice2; segments: 1) (cost=0.00..431.00 rows=3 width=4) + -> Aggregate (cost=0.00..431.00 rows=1 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=4) + -> Aggregate (cost=0.00..431.00 rows=1 width=4) + -> Seq Scan on t_epq_subplans t_epq_subplans_1 (cost=0.00..431.00 rows=1 width=4) + Optimizer: Pivotal Optimizer (GPORCA) +(12 rows) 2&: update t_epq_subplans set b = b + 1 where a > -1.5 * (select max(a) from t_epq_subplans); <waiting ...> 1: end; END -- session 2 should throw error and not PANIC 2<: <... completed> -ERROR: tuple to be updated was already moved to another segment due to concurrent update (seg1 127.0.1.1:6003 pid=116712) +ERROR: EvalPlanQual can not handle subPlan with Motion node (seg1 172.17.0.2:7003 pid=808) 1: drop table t_epq_subplans; DROP diff --git a/src/test/isolation2/expected/modify_table_data_corrupt_optimizer.out b/src/test/isolation2/expected/modify_table_data_corrupt_optimizer.out index b313e608b524..b07e3a4f0cff 100644 --- a/src/test/isolation2/expected/modify_table_data_corrupt_optimizer.out +++ b/src/test/isolation2/expected/modify_table_data_corrupt_optimizer.out @@ -107,25 +107,24 @@ ABORT -- TODO: this case is for planner, it will not error out on 6X now, -- because 6x does not remove explicit motion yet. explain (costs off) update tab1 set a = 999 from tab2, tab3 where tab1.a = tab2.a and tab1.b = tab3.b; - QUERY PLAN ---------------------------------------------------------------------------------- - Update - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: tab1.b - -> Split - -> Result - -> Hash Join - Hash Cond: (tab2.a = tab1.a) - -> Seq Scan on tab2 - -> Hash - -> Broadcast Motion 3:3 (slice1; segments: 3) - -> Hash Join - Hash Cond: (tab3.b = tab1.b) - -> Seq Scan on tab3 - -> Hash - -> Seq Scan on tab1 - Optimizer: Pivotal Optimizer (GPORCA) -(16 rows) + QUERY PLAN +--------------------------------------------------------------------------- + Update + -> Result + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: tab1.b + -> Hash Join + Hash Cond: (tab2.a = tab1.a) + -> Seq Scan on tab2 + -> Hash + -> Broadcast Motion 3:3 (slice1; segments: 3) + -> Hash Join + Hash Cond: (tab3.b = tab1.b) + -> Seq Scan on tab3 + -> Hash + -> Seq Scan on tab1 + Optimizer: Pivotal Optimizer (GPORCA) +(15 rows) begin; BEGIN update tab1 set a = 999 from tab2, tab3 where tab1.a = tab2.a and tab1.b = tab3.b; @@ -163,30 +162,29 @@ ABORT -- For orca, this will error out explain (costs off) update tab1 set a = 999 from tab2, tab3 where tab1.a = tab2.a and tab1.b = tab3.a; - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Update - -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: tab1.b - -> Split - -> Result - -> Hash Join - Hash Cond: (tab3.a = tab1.b) - -> Seq Scan on tab3 - -> Hash - -> Broadcast Motion 3:3 (slice2; segments: 3) - -> Hash Join - Hash Cond: (tab2.a = tab1.a) - -> Seq Scan on tab2 - -> Hash - -> Broadcast Motion 3:3 (slice1; segments: 3) - -> Seq Scan on tab1 - Optimizer: Pivotal Optimizer (GPORCA) -(17 rows) + QUERY PLAN +--------------------------------------------------------------------------------------------- + Update + -> Result + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: tab1.b + -> Hash Join + Hash Cond: (tab3.a = tab1.b) + -> Seq Scan on tab3 + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Hash Join + Hash Cond: (tab2.a = tab1.a) + -> Seq Scan on tab2 + -> Hash + -> Broadcast Motion 3:3 (slice1; segments: 3) + -> Seq Scan on tab1 + Optimizer: Pivotal Optimizer (GPORCA) +(16 rows) begin; BEGIN update tab1 set a = 999 from tab2, tab3 where tab1.a = tab2.a and tab1.b = tab3.a; -ERROR: distribution key of the tuple (0, 1) doesn't belong to current segment (actually from seg0) (nodeModifyTable.c:602) (seg1 127.0.1.1:6003 pid=78344) (nodeModifyTable.c:602) +UPDATE 1 abort; ABORT diff --git a/src/test/regress/expected/bfv_dml_optimizer.out b/src/test/regress/expected/bfv_dml_optimizer.out index 687115e084ea..7fe54476731e 100644 --- a/src/test/regress/expected/bfv_dml_optimizer.out +++ b/src/test/regress/expected/bfv_dml_optimizer.out @@ -595,18 +595,19 @@ create table bar (a int, b int) distributed randomly; insert into foo (a, b) values (1, 2); insert into bar (a, b) values (1, 2); explain update foo set a=4 from bar where foo.a=bar.a; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Update (cost=0.00..862.02 rows=1 width=1) - -> Result (cost=0.00..862.00 rows=1 width=18) - -> Hash Join (cost=0.00..862.00 rows=1 width=14) - Hash Cond: (foo.a = bar.a) - -> Seq Scan on foo (cost=0.00..431.00 rows=1 width=18) - -> Hash (cost=431.00..431.00 rows=1 width=4) - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=4) - -> Seq Scan on bar (cost=0.00..431.00 rows=1 width=4) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Update (cost=0.00..862.06 rows=1 width=1) + -> Split (cost=0.00..862.00 rows=1 width=22) + -> Result (cost=0.00..862.00 rows=1 width=22) + -> Hash Join (cost=0.00..862.00 rows=1 width=18) + Hash Cond: (foo.a = bar.a) + -> Seq Scan on foo (cost=0.00..431.00 rows=1 width=18) + -> Hash (cost=431.00..431.00 rows=1 width=4) + -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=4) + -> Seq Scan on bar (cost=0.00..431.00 rows=1 width=4) Optimizer: Pivotal Optimizer (GPORCA) -(9 rows) +(10 rows) update foo set a=4 from bar where foo.a=bar.a; select * from foo; diff --git a/src/test/regress/expected/gporca_optimizer.out b/src/test/regress/expected/gporca_optimizer.out index e71cfa6996d6..9f47cd9dc7c5 100644 --- a/src/test/regress/expected/gporca_optimizer.out +++ b/src/test/regress/expected/gporca_optimizer.out @@ -13733,7 +13733,7 @@ and first_id in (select first_id from mat_w); Output: share0_ref2.first_id Optimizer: Pivotal Optimizer (GPORCA) Settings: optimizer=on -(30 rows) +(31 rows) with mat_w as ( select first_id @@ -14686,24 +14686,25 @@ update window_agg_test t set i = tt.i from (select (min(i) over (order by j)) as i, j from window_agg_test) tt where t.j = tt.j; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Update (cost=0.00..862.02 rows=1 width=1) - -> Explicit Redistribute Motion 1:3 (slice3; segments: 1) (cost=0.00..862.00 rows=1 width=18) - -> Hash Join (cost=0.00..862.00 rows=1 width=18) - Hash Cond: (window_agg_test.j = window_agg_test_1.j) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=14) - -> Seq Scan on window_agg_test (cost=0.00..431.00 rows=1 width=14) - -> Hash (cost=431.00..431.00 rows=1 width=8) - -> WindowAgg (cost=0.00..431.00 rows=1 width=8) - Order By: window_agg_test_1.j - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) - Merge Key: window_agg_test_1.j - -> Sort (cost=0.00..431.00 rows=1 width=8) - Sort Key: window_agg_test_1.j - -> Seq Scan on window_agg_test window_agg_test_1 (cost=0.00..431.00 rows=1 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Update (cost=0.00..862.06 rows=1 width=1) + -> Explicit Redistribute Motion 1:3 (slice3; segments: 1) (cost=0.00..862.00 rows=2 width=22) + -> Split (cost=0.00..862.00 rows=1 width=22) + -> Hash Join (cost=0.00..862.00 rows=1 width=22) + Hash Cond: (window_agg_test.j = window_agg_test_1.j) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=18) + -> Seq Scan on window_agg_test (cost=0.00..431.00 rows=1 width=18) + -> Hash (cost=431.00..431.00 rows=1 width=8) + -> WindowAgg (cost=0.00..431.00 rows=1 width=8) + Order By: window_agg_test_1.j + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) + Merge Key: window_agg_test_1.j + -> Sort (cost=0.00..431.00 rows=1 width=8) + Sort Key: window_agg_test_1.j + -> Seq Scan on window_agg_test window_agg_test_1 (cost=0.00..431.00 rows=1 width=8) Optimizer: Pivotal Optimizer (GPORCA) -(15 rows) +(16 rows) ---------------------------------- -- Test ORCA support for const TVF diff --git a/src/test/regress/expected/qp_dml_joins_optimizer.out b/src/test/regress/expected/qp_dml_joins_optimizer.out index 5e7a78999d92..586797f887f7 100644 --- a/src/test/regress/expected/qp_dml_joins_optimizer.out +++ b/src/test/regress/expected/qp_dml_joins_optimizer.out @@ -4077,10 +4077,11 @@ SELECT SUM(a) FROM dml_heap_v; (1 row) UPDATE dml_heap_v SET a = dml_heap_u.a FROM dml_heap_u WHERE dml_heap_u.b = dml_heap_v.b; +ERROR: multiple updates to a row by the same query is not allowed (seg2 127.0.1.1:6004 pid=28103) SELECT SUM(a) FROM dml_heap_v; sum ----- - 63 + 55 (1 row) --Update with joins on multiple table diff --git a/src/test/regress/expected/update_gp_optimizer.out b/src/test/regress/expected/update_gp_optimizer.out index ed4ba18c1759..3edebee2b0e1 100644 --- a/src/test/regress/expected/update_gp_optimizer.out +++ b/src/test/regress/expected/update_gp_optimizer.out @@ -123,44 +123,45 @@ EXPLAIN (COSTS OFF) UPDATE keo1 SET user_vie_act_cntr_marg_cum = 234.682 FROM (SELECT min (keo4.keo_para_budget_date) FROM keo4))) ) t1 WHERE t1.user_vie_project_code_pk = keo1.user_vie_project_code_pk; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Update - -> Result - -> Hash Join - Hash Cond: ((keo1_1.user_vie_project_code_pk)::text = (keo2.projects_pk)::text) + -> Split + -> Result -> Hash Join - Hash Cond: ((keo1.user_vie_project_code_pk)::text = (keo1_1.user_vie_project_code_pk)::text) - -> Seq Scan on keo1 + Hash Cond: ((keo1_1.user_vie_project_code_pk)::text = (keo2.projects_pk)::text) + -> Hash Join + Hash Cond: ((keo1.user_vie_project_code_pk)::text = (keo1_1.user_vie_project_code_pk)::text) + -> Seq Scan on keo1 + -> Hash + -> Broadcast Motion 1:3 (slice5; segments: 1) + -> Hash Join + Hash Cond: ((keo1_1.user_vie_fiscal_year_period_sk)::text = (max((keo3.sky_per)::text))) + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on keo1 keo1_1 + -> Hash + -> Aggregate + -> Hash Join + Hash Cond: ((keo3.bky_per)::text = (keo4.keo_para_required_period)::text) + -> Gather Motion 3:1 (slice2; segments: 3) + -> Seq Scan on keo3 + -> Hash + -> Assert + Assert Cond: ((row_number() OVER (?)) = 1) + -> WindowAgg + -> Hash Join + Hash Cond: ((keo4.keo_para_budget_date)::text = (min((keo4_1.keo_para_budget_date)::text))) + -> Gather Motion 3:1 (slice3; segments: 3) + -> Seq Scan on keo4 + -> Hash + -> Aggregate + -> Gather Motion 3:1 (slice4; segments: 3) + -> Seq Scan on keo4 keo4_1 -> Hash - -> Broadcast Motion 1:3 (slice5; segments: 1) - -> Hash Join - Hash Cond: ((keo1_1.user_vie_fiscal_year_period_sk)::text = (max((keo3.sky_per)::text))) - -> Gather Motion 3:1 (slice1; segments: 3) - -> Seq Scan on keo1 keo1_1 - -> Hash - -> Aggregate - -> Hash Join - Hash Cond: ((keo3.bky_per)::text = (keo4.keo_para_required_period)::text) - -> Gather Motion 3:1 (slice2; segments: 3) - -> Seq Scan on keo3 - -> Hash - -> Assert - Assert Cond: ((row_number() OVER (?)) = 1) - -> WindowAgg - -> Hash Join - Hash Cond: ((keo4.keo_para_budget_date)::text = (min((keo4_1.keo_para_budget_date)::text))) - -> Gather Motion 3:1 (slice3; segments: 3) - -> Seq Scan on keo4 - -> Hash - -> Aggregate - -> Gather Motion 3:1 (slice4; segments: 3) - -> Seq Scan on keo4 keo4_1 - -> Hash - -> Broadcast Motion 3:3 (slice6; segments: 3) - -> Seq Scan on keo2 + -> Broadcast Motion 3:3 (slice6; segments: 3) + -> Seq Scan on keo2 Optimizer: Pivotal Optimizer (GPORCA) -(35 rows) +(36 rows) UPDATE keo1 SET user_vie_act_cntr_marg_cum = 234.682 FROM ( SELECT a.user_vie_project_code_pk FROM keo1 a INNER JOIN keo2 b