diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execMain.c | 87 | ||||
-rw-r--r-- | src/backend/executor/execPartition.c | 33 | ||||
-rw-r--r-- | src/backend/executor/execUtils.c | 89 | ||||
-rw-r--r-- | src/backend/executor/nodeModifyTable.c | 2 |
4 files changed, 146 insertions, 65 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 2275a2988f6..88df1a124e2 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -100,20 +100,6 @@ static char *ExecBuildSlotValueDescription(Oid reloid, int maxfieldlen); static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree); -/* - * Note that GetAllUpdatedColumns() also exists in commands/trigger.c. There does - * not appear to be any good header to put it into, given the structures that - * it uses, so we let them be duplicated. Be sure to update both if one needs - * to be changed, however. - */ -#define GetInsertedColumns(relinfo, estate) \ - (exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->insertedCols) -#define GetUpdatedColumns(relinfo, estate) \ - (exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols) -#define GetAllUpdatedColumns(relinfo, estate) \ - (bms_union(exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols, \ - exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->extraUpdatedCols)) - /* end of local decls */ @@ -1277,7 +1263,7 @@ void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, - Relation partition_root, + ResultRelInfo *partition_root_rri, int instrument_options) { List *partition_check = NIL; @@ -1342,7 +1328,7 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo, partition_check = RelationGetPartitionQual(resultRelationDesc); resultRelInfo->ri_PartitionCheck = partition_check; - resultRelInfo->ri_PartitionRoot = partition_root; + resultRelInfo->ri_RootResultRelInfo = partition_root_rri; resultRelInfo->ri_PartitionInfo = NULL; /* may be set later */ resultRelInfo->ri_CopyMultiInsertBuffer = NULL; } @@ -1840,13 +1826,14 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, * back to the root table's rowtype so that val_desc in the error message * matches the input tuple. */ - if (resultRelInfo->ri_PartitionRoot) + if (resultRelInfo->ri_RootResultRelInfo) { + ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo; TupleDesc old_tupdesc; AttrNumber *map; - root_relid = RelationGetRelid(resultRelInfo->ri_PartitionRoot); - tupdesc = RelationGetDescr(resultRelInfo->ri_PartitionRoot); + root_relid = RelationGetRelid(rootrel->ri_RelationDesc); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); old_tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); /* a reverse map */ @@ -1860,16 +1847,17 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, if (map != NULL) slot = execute_attr_map_slot(map, slot, MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); + modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate), + ExecGetUpdatedCols(rootrel, estate)); } else { root_relid = RelationGetRelid(resultRelInfo->ri_RelationDesc); tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); + modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate), + ExecGetUpdatedCols(resultRelInfo, estate)); } - modifiedCols = bms_union(GetInsertedColumns(resultRelInfo, estate), - GetUpdatedColumns(resultRelInfo, estate)); - val_desc = ExecBuildSlotValueDescription(root_relid, slot, tupdesc, @@ -1901,8 +1889,6 @@ ExecConstraints(ResultRelInfo *resultRelInfo, TupleDesc tupdesc = RelationGetDescr(rel); TupleConstr *constr = tupdesc->constr; Bitmapset *modifiedCols; - Bitmapset *insertedCols; - Bitmapset *updatedCols; Assert(constr || resultRelInfo->ri_PartitionCheck); @@ -1928,12 +1914,12 @@ ExecConstraints(ResultRelInfo *resultRelInfo, * rowtype so that val_desc shown error message matches the * input tuple. */ - if (resultRelInfo->ri_PartitionRoot) + if (resultRelInfo->ri_RootResultRelInfo) { + ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo; AttrNumber *map; - rel = resultRelInfo->ri_PartitionRoot; - tupdesc = RelationGetDescr(rel); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = convert_tuples_by_name_map_if_req(orig_tupdesc, tupdesc, @@ -1946,11 +1932,13 @@ ExecConstraints(ResultRelInfo *resultRelInfo, if (map != NULL) slot = execute_attr_map_slot(map, slot, MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); + modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate), + ExecGetUpdatedCols(rootrel, estate)); + rel = rootrel->ri_RelationDesc; } - - insertedCols = GetInsertedColumns(resultRelInfo, estate); - updatedCols = GetUpdatedColumns(resultRelInfo, estate); - modifiedCols = bms_union(insertedCols, updatedCols); + else + modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate), + ExecGetUpdatedCols(resultRelInfo, estate)); val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel), slot, tupdesc, @@ -1977,13 +1965,13 @@ ExecConstraints(ResultRelInfo *resultRelInfo, Relation orig_rel = rel; /* See the comment above. */ - if (resultRelInfo->ri_PartitionRoot) + if (resultRelInfo->ri_RootResultRelInfo) { + ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo; TupleDesc old_tupdesc = RelationGetDescr(rel); AttrNumber *map; - rel = resultRelInfo->ri_PartitionRoot; - tupdesc = RelationGetDescr(rel); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = convert_tuples_by_name_map_if_req(old_tupdesc, tupdesc, @@ -1996,11 +1984,13 @@ ExecConstraints(ResultRelInfo *resultRelInfo, if (map != NULL) slot = execute_attr_map_slot(map, slot, MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); + modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate), + ExecGetUpdatedCols(rootrel, estate)); + rel = rootrel->ri_RelationDesc; } - - insertedCols = GetInsertedColumns(resultRelInfo, estate); - updatedCols = GetUpdatedColumns(resultRelInfo, estate); - modifiedCols = bms_union(insertedCols, updatedCols); + else + modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate), + ExecGetUpdatedCols(resultRelInfo, estate)); val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel), slot, tupdesc, @@ -2069,8 +2059,6 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, { char *val_desc; Bitmapset *modifiedCols; - Bitmapset *insertedCols; - Bitmapset *updatedCols; switch (wco->kind) { @@ -2085,13 +2073,13 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, */ case WCO_VIEW_CHECK: /* See the comment in ExecConstraints(). */ - if (resultRelInfo->ri_PartitionRoot) + if (resultRelInfo->ri_RootResultRelInfo) { + ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo; TupleDesc old_tupdesc = RelationGetDescr(rel); AttrNumber *map; - rel = resultRelInfo->ri_PartitionRoot; - tupdesc = RelationGetDescr(rel); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = convert_tuples_by_name_map_if_req(old_tupdesc, tupdesc, @@ -2104,11 +2092,14 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, if (map != NULL) slot = execute_attr_map_slot(map, slot, MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); - } - insertedCols = GetInsertedColumns(resultRelInfo, estate); - updatedCols = GetUpdatedColumns(resultRelInfo, estate); - modifiedCols = bms_union(insertedCols, updatedCols); + modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate), + ExecGetUpdatedCols(rootrel, estate)); + rel = rootrel->ri_RelationDesc; + } + else + modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate), + ExecGetUpdatedCols(resultRelInfo, estate)); val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel), slot, tupdesc, @@ -2322,7 +2313,7 @@ ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo) * been modified, then we can use a weaker lock, allowing for better * concurrency. */ - updatedCols = GetAllUpdatedColumns(relinfo, estate); + updatedCols = ExecGetAllUpdatedCols(relinfo, estate); keyCols = RelationGetIndexAttrBitmap(relinfo->ri_RelationDesc, INDEX_ATTR_BITMAP_KEY); diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 93e2cdd0207..8fe4fc57bf6 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -176,7 +176,8 @@ static void ExecInitRoutingInfo(ModifyTableState *mtstate, int partidx); static PartitionDispatch ExecInitPartitionDispatchInfo(EState *estate, PartitionTupleRouting *proute, - Oid partoid, PartitionDispatch parent_pd, int partidx); + Oid partoid, PartitionDispatch parent_pd, + int partidx, ResultRelInfo *rootResultRelInfo); static void FormPartitionKeyDatum(PartitionDispatch pd, TupleTableSlot *slot, EState *estate, @@ -238,7 +239,7 @@ ExecSetupPartitionTupleRouting(EState *estate, ModifyTableState *mtstate, * partitioned table. */ ExecInitPartitionDispatchInfo(estate, proute, RelationGetRelid(rel), - NULL, 0); + NULL, 0, NULL); /* * If performing an UPDATE with tuple routing, we can reuse partition @@ -425,10 +426,11 @@ ExecFindPartition(ModifyTableState *mtstate, * Create the new PartitionDispatch. We pass the current one * in as the parent PartitionDispatch */ - subdispatch = ExecInitPartitionDispatchInfo(mtstate->ps.state, + subdispatch = ExecInitPartitionDispatchInfo(estate, proute, partdesc->oids[partidx], - dispatch, partidx); + dispatch, partidx, + mtstate->rootResultRelInfo); Assert(dispatch->indexes[partidx] >= 0 && dispatch->indexes[partidx] < proute->num_dispatch); @@ -543,7 +545,7 @@ ExecHashSubPlanResultRelsByOid(ModifyTableState *mtstate, * compatible with the root partitioned table's tuple descriptor. When * generating the per-subplan result rels, this was not set. */ - rri->ri_PartitionRoot = proute->partition_root; + rri->ri_RootResultRelInfo = mtstate->rootResultRelInfo; } } @@ -563,8 +565,8 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, int partidx) { ModifyTable *node = (ModifyTable *) mtstate->ps.plan; - Relation rootrel = rootResultRelInfo->ri_RelationDesc, - partrel; + Relation partrel; + int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; Relation firstResultRel = mtstate->resultRelInfo[0].ri_RelationDesc; ResultRelInfo *leaf_part_rri; MemoryContext oldcxt; @@ -578,8 +580,8 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, leaf_part_rri = makeNode(ResultRelInfo); InitResultRelInfo(leaf_part_rri, partrel, - node ? node->rootRelation : 1, - rootrel, + 0, + rootResultRelInfo, estate->es_instrument); /* @@ -613,7 +615,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, List *wcoList; List *wcoExprs = NIL; ListCell *ll; - int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; /* * In the case of INSERT on a partitioned table, there is only one @@ -679,7 +680,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, TupleTableSlot *slot; ExprContext *econtext; List *returningList; - int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; /* See the comment above for WCO lists. */ Assert((node->operation == CMD_INSERT && @@ -740,7 +740,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, */ if (node && node->onConflictAction != ONCONFLICT_NONE) { - int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; TupleDesc partrelDesc = RelationGetDescr(partrel); ExprContext *econtext = mtstate->ps.ps_ExprContext; ListCell *lc; @@ -947,6 +946,7 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, ResultRelInfo *partRelInfo, int partidx) { + ResultRelInfo *rootRelInfo = partRelInfo->ri_RootResultRelInfo; MemoryContext oldcxt; PartitionRoutingInfo *partrouteinfo; int rri_index; @@ -960,7 +960,7 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, * partition from the parent's type to the partition's. */ partrouteinfo->pi_RootToPartitionMap = - convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_PartitionRoot), + convert_tuples_by_name(RelationGetDescr(rootRelInfo->ri_RelationDesc), RelationGetDescr(partRelInfo->ri_RelationDesc), gettext_noop("could not convert row type")); @@ -994,7 +994,7 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, { partrouteinfo->pi_PartitionToRootMap = convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_RelationDesc), - RelationGetDescr(partRelInfo->ri_PartitionRoot), + RelationGetDescr(rootRelInfo->ri_RelationDesc), gettext_noop("could not convert row type")); } else @@ -1054,7 +1054,8 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, static PartitionDispatch ExecInitPartitionDispatchInfo(EState *estate, PartitionTupleRouting *proute, Oid partoid, - PartitionDispatch parent_pd, int partidx) + PartitionDispatch parent_pd, int partidx, + ResultRelInfo *rootResultRelInfo) { Relation rel; PartitionDesc partdesc; @@ -1153,7 +1154,7 @@ ExecInitPartitionDispatchInfo(EState *estate, { ResultRelInfo *rri = makeNode(ResultRelInfo); - InitResultRelInfo(rri, rel, 1, proute->partition_root, 0); + InitResultRelInfo(rri, rel, 0, rootResultRelInfo, 0); proute->nonleaf_partitions[dispatchidx] = rri; } else diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index f0a71e56106..efdec947057 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -51,6 +51,7 @@ #include "access/tableam.h" #include "access/transam.h" #include "executor/executor.h" +#include "executor/execPartition.h" #include "jit/jit.h" #include "mb/pg_wchar.h" #include "nodes/nodeFuncs.h" @@ -1175,3 +1176,91 @@ ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo) return relInfo->ri_ReturningSlot; } + +/* Return a bitmap representing columns being inserted */ +Bitmapset * +ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate) +{ + /* + * The columns are stored in the range table entry. If this ResultRelInfo + * doesn't have an entry in the range table (i.e. if it represents a + * partition routing target), fetch the parent's RTE and map the columns + * to the order they are in the partition. + */ + if (relinfo->ri_RangeTableIndex != 0) + { + RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate); + + return rte->insertedCols; + } + else + { + ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; + RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); + PartitionRoutingInfo *partrouteinfo = relinfo->ri_PartitionInfo; + + if (partrouteinfo->pi_RootToPartitionMap != NULL) + return execute_attr_map_cols(rte->insertedCols, + partrouteinfo->pi_RootToPartitionMap); + else + return rte->insertedCols; + } +} + +/* Return a bitmap representing columns being updated */ +Bitmapset * +ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate) +{ + /* see ExecGetInsertedCols() */ + if (relinfo->ri_RangeTableIndex != 0) + { + RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate); + + return rte->updatedCols; + } + else + { + ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; + RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); + PartitionRoutingInfo *partrouteinfo = relinfo->ri_PartitionInfo; + + if (partrouteinfo->pi_RootToPartitionMap != NULL) + return execute_attr_map_cols(rte->updatedCols, + partrouteinfo->pi_RootToPartitionMap); + else + return rte->updatedCols; + } +} + +/* Return a bitmap representing generated columns being updated */ +Bitmapset * +ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate) +{ + /* see ExecGetInsertedCols() */ + if (relinfo->ri_RangeTableIndex != 0) + { + RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate); + + return rte->extraUpdatedCols; + } + else + { + ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; + RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); + PartitionRoutingInfo *partrouteinfo = relinfo->ri_PartitionInfo; + + if (partrouteinfo->pi_RootToPartitionMap != NULL) + return execute_attr_map_cols(rte->extraUpdatedCols, + partrouteinfo->pi_RootToPartitionMap); + else + return rte->extraUpdatedCols; + } +} + +/* Return columns being updated, including generated columns */ +Bitmapset * +ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate) +{ + return bms_union(ExecGetUpdatedCols(relinfo, estate), + ExecGetExtraUpdatedCols(relinfo, estate)); +} diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index cbf7abafc51..b65fc85a253 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -467,7 +467,7 @@ ExecInsert(ModifyTableState *mtstate, * if there's no BR trigger defined on the partition. */ if (resultRelInfo->ri_PartitionCheck && - (resultRelInfo->ri_PartitionRoot == NULL || + (resultRelInfo->ri_RootResultRelInfo == NULL || (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->trig_insert_before_row))) ExecPartitionCheck(resultRelInfo, slot, estate, true); |