diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execIndexing.c | 13 | ||||
-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 | 86 | ||||
-rw-r--r-- | src/backend/executor/nodeModifyTable.c | 4 |
5 files changed, 146 insertions, 77 deletions
diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c index 1f0fe145ce8..afe7ce87d4c 100644 --- a/src/backend/executor/execIndexing.c +++ b/src/backend/executor/execIndexing.c @@ -124,15 +124,6 @@ typedef enum CEOUC_LIVELOCK_PREVENTING_WAIT } CEOUC_WAIT_MODE; -/* - * The authoritative version of these macro are in executor/execMain.c. Be - * sure to keep everything in sync. - */ -#define GetUpdatedColumns(relinfo, estate) \ - (exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols) -#define GetExtraUpdatedColumns(relinfo, estate) \ - (exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->extraUpdatedCols) - static bool check_exclusion_or_unique_constraint(Relation heap, Relation index, IndexInfo *indexInfo, ItemPointer tupleid, @@ -944,8 +935,8 @@ static bool index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate, IndexInfo *indexInfo, Relation indexRelation) { - Bitmapset *updatedCols = GetUpdatedColumns(resultRelInfo, estate); - Bitmapset *extraUpdatedCols = GetExtraUpdatedColumns(resultRelInfo, estate); + Bitmapset *updatedCols = ExecGetUpdatedCols(resultRelInfo, estate); + Bitmapset *extraUpdatedCols = ExecGetExtraUpdatedCols(resultRelInfo, estate); Bitmapset *allUpdatedCols; bool hasexpression = false; List *idxExprs; diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index f4dd47acc76..c74ce36ffba 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 variants of these macros exists in commands/trigger.c and in - * execIndexing.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 keep everything in sync. - */ -#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 */ @@ -1196,7 +1182,7 @@ void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, - Relation partition_root, + ResultRelInfo *partition_root_rri, int instrument_options) { MemSet(resultRelInfo, 0, sizeof(ResultRelInfo)); @@ -1242,7 +1228,7 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo, resultRelInfo->ri_ReturningSlot = NULL; resultRelInfo->ri_TrigOldSlot = NULL; resultRelInfo->ri_TrigNewSlot = NULL; - resultRelInfo->ri_PartitionRoot = partition_root; + resultRelInfo->ri_RootResultRelInfo = partition_root_rri; resultRelInfo->ri_RootToPartitionMap = NULL; /* set by * ExecInitRoutingInfo */ resultRelInfo->ri_PartitionTupleSlot = NULL; /* ditto */ @@ -1744,13 +1730,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; AttrMap *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 */ @@ -1763,16 +1750,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, @@ -1805,8 +1793,6 @@ ExecConstraints(ResultRelInfo *resultRelInfo, TupleDesc tupdesc = RelationGetDescr(rel); TupleConstr *constr = tupdesc->constr; Bitmapset *modifiedCols; - Bitmapset *insertedCols; - Bitmapset *updatedCols; Assert(constr); /* we should not be called otherwise */ @@ -1832,12 +1818,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; AttrMap *map; - rel = resultRelInfo->ri_PartitionRoot; - tupdesc = RelationGetDescr(rel); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = build_attrmap_by_name_if_req(orig_tupdesc, tupdesc); @@ -1849,11 +1835,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, @@ -1881,13 +1869,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); AttrMap *map; - rel = resultRelInfo->ri_PartitionRoot; - tupdesc = RelationGetDescr(rel); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = build_attrmap_by_name_if_req(old_tupdesc, tupdesc); @@ -1899,11 +1887,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, @@ -1972,8 +1962,6 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, { char *val_desc; Bitmapset *modifiedCols; - Bitmapset *insertedCols; - Bitmapset *updatedCols; switch (wco->kind) { @@ -1988,13 +1976,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); AttrMap *map; - rel = resultRelInfo->ri_PartitionRoot; - tupdesc = RelationGetDescr(rel); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = build_attrmap_by_name_if_req(old_tupdesc, tupdesc); @@ -2006,11 +1994,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, @@ -2224,7 +2215,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 746cd1e9d7a..b9e4f2d80b1 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 @@ -432,10 +433,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); @@ -547,7 +549,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; } } @@ -567,8 +569,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; @@ -582,8 +584,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); /* @@ -617,7 +619,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 @@ -681,7 +682,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; @@ -917,7 +916,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, if (mtstate->mt_transition_capture || mtstate->mt_oc_transition_capture) leaf_part_rri->ri_ChildToRootMap = convert_tuples_by_name(RelationGetDescr(leaf_part_rri->ri_RelationDesc), - RelationGetDescr(leaf_part_rri->ri_PartitionRoot)); + RelationGetDescr(rootResultRelInfo->ri_RelationDesc)); /* * Since we've just initialized this ResultRelInfo, it's not in any list @@ -951,6 +950,7 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, ResultRelInfo *partRelInfo, int partidx) { + ResultRelInfo *rootRelInfo = partRelInfo->ri_RootResultRelInfo; MemoryContext oldcxt; int rri_index; @@ -961,7 +961,7 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, * partition from the parent's type to the partition's. */ partRelInfo->ri_RootToPartitionMap = - convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_PartitionRoot), + convert_tuples_by_name(RelationGetDescr(rootRelInfo->ri_RelationDesc), RelationGetDescr(partRelInfo->ri_RelationDesc)); /* @@ -1055,7 +1055,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 d84fbaded96..c734283bfe9 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 "miscadmin.h" @@ -1223,3 +1224,88 @@ 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); + + if (relinfo->ri_RootToPartitionMap != NULL) + return execute_attr_map_cols(relinfo->ri_RootToPartitionMap->attrMap, + rte->insertedCols); + 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); + + if (relinfo->ri_RootToPartitionMap != NULL) + return execute_attr_map_cols(relinfo->ri_RootToPartitionMap->attrMap, + rte->updatedCols); + 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); + + if (relinfo->ri_RootToPartitionMap != NULL) + return execute_attr_map_cols(relinfo->ri_RootToPartitionMap->attrMap, + rte->extraUpdatedCols); + 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 5d903374983..2993ba43e32 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -291,7 +291,7 @@ ExecComputeStoredGenerated(ResultRelInfo *resultRelInfo, if (cmdtype == CMD_UPDATE && !(rel->trigdesc && rel->trigdesc->trig_update_before_row) && !bms_is_member(i + 1 - FirstLowInvalidHeapAttributeNumber, - exec_rt_fetch(resultRelInfo->ri_RangeTableIndex, estate)->extraUpdatedCols)) + ExecGetExtraUpdatedCols(resultRelInfo, estate))) { resultRelInfo->ri_GeneratedExprs[i] = NULL; continue; @@ -565,7 +565,7 @@ ExecInsert(ModifyTableState *mtstate, * if there's no BR trigger defined on the partition. */ if (resultRelationDesc->rd_rel->relispartition && - (resultRelInfo->ri_PartitionRoot == NULL || + (resultRelInfo->ri_RootResultRelInfo == NULL || (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->trig_insert_before_row))) ExecPartitionCheck(resultRelInfo, slot, estate, true); |