167 bool is_borrowed_rel);
197 int n_total_subplans);
296 while (dispatch != NULL)
321 if (partdesc->
nparts == 0 ||
330 (
errcode(ERRCODE_CHECK_VIOLATION),
331 errmsg(
"no partition of relation \"%s\" found for row",
334 errdetail(
"Partition key of the failing row contains %s.",
339 is_leaf = partdesc->
is_leaf[partidx];
360 partdesc->
oids[partidx],
379 rootResultRelInfo, partidx);
403 dispatch = pd[dispatch->
indexes[partidx]];
416 partdesc->
oids[partidx],
423 dispatch = subdispatch;
438 if (tempslot != NULL)
513 bool found_whole_row;
539 if (partrel->rd_rel->relhasindex &&
540 leaf_part_rri->ri_IndexRelationDescs == NULL)
605 wcoExprs =
lappend(wcoExprs, wcoExpr);
608 leaf_part_rri->ri_WithCheckOptions = wcoList;
609 leaf_part_rri->ri_WithCheckOptionExprs = wcoExprs;
647 if (part_attmap == NULL)
652 returningList = (
List *)
660 leaf_part_rri->ri_returningList = returningList;
672 leaf_part_rri->ri_projectReturning =
679 leaf_part_rri, partidx,
false);
703 foreach(lc, childIdxs)
713 arbiterIndexes =
lappend_oid(arbiterIndexes, childIdx);
726 elog(
ERROR,
"invalid arbiter index list");
727 leaf_part_rri->ri_onConflictArbiterIndexes = arbiterIndexes;
742 leaf_part_rri->ri_onConflict = onconfl;
789 if (part_attmap == NULL)
794 onconflset = (
List *)
801 onconflset = (
List *)
889 if (part_attmap == NULL)
895 if (
unlikely(!leaf_part_rri->ri_projectNewInfoValid))
906 leaf_part_rri->ri_MergeJoinCondition =
909 foreach(lc, firstMergeActionList)
920 leaf_part_rri->ri_MergeActions[
action->matchKind] =
924 switch (
action->commandType)
935 leaf_part_rri->ri_newTupleSlot,
955 leaf_part_rri->ri_newTupleSlot,
964 elog(
ERROR,
"unknown action in MERGE WHEN clause");
980 return leaf_part_rri;
996 bool is_borrowed_rel)
1083 dispatch->
indexes[partidx] = rri_index;
1136 partdesc->
nparts *
sizeof(int));
1141 if (parent_pd != NULL)
1222 parent_pd->
indexes[partidx] = dispatchidx;
1332 if (partexpr_item == NULL)
1333 elog(
ERROR,
"wrong number of partition key expressions");
1343 if (partexpr_item != NULL)
1344 elog(
ERROR,
"wrong number of partition key expressions");
1352#define PARTITION_CACHED_FIND_THRESHOLD 16
1397 int bound_offset = -1;
1398 int part_index = -1;
1416 switch (
key->strategy)
1461 Datum lastDatum = boundinfo->
datums[last_datum_offset][0];
1466 key->partcollation[0],
1471 return boundinfo->
indexes[last_datum_offset];
1480 if (bound_offset >= 0 &&
equal)
1481 part_index = boundinfo->
indexes[bound_offset];
1488 range_partkey_has_null =
false;
1495 for (
i = 0;
i <
key->partnatts;
i++)
1499 range_partkey_has_null =
true;
1505 if (range_partkey_has_null)
1511 Datum *lastDatums = boundinfo->
datums[last_datum_offset];
1528 return boundinfo->
indexes[last_datum_offset + 1];
1530 if (cmpval < 0 && last_datum_offset + 1 < boundinfo->
ndatums)
1533 lastDatums = boundinfo->
datums[last_datum_offset + 1];
1534 kind = boundinfo->
kind[last_datum_offset + 1];
1543 return boundinfo->
indexes[last_datum_offset + 1];
1561 part_index = boundinfo->
indexes[bound_offset + 1];
1566 elog(
ERROR,
"unexpected partition strategy: %d",
1567 (
int)
key->strategy);
1585 Assert(bound_offset >= 0);
1638 for (
i = 0;
i < partnatts;
i++)
1658 for (
i = 0;
i < partnatts;
i++)
1671 &foutoid, &typisvarlena);
1679 vallen = strlen(
val);
1680 if (vallen <= maxfieldlen)
1731 if (parentattrno <= 0 ||
1732 parentattrno > attrMap->
maplen ||
1733 attrMap->
attnums[parentattrno - 1] == 0)
1734 elog(
ERROR,
"unexpected attno %d in target column list",
1737 attrMap->
attnums[parentattrno - 1]);
1838 &all_leafpart_rtis);
1848 &validsubplan_rtis);
1850 validsubplan_rtis = all_leafpart_rtis;
1862 rte->rellockmode !=
NoLock);
1864 locked_relids =
lappend_int(locked_relids, rtindex);
1886 foreach(lc,
stmt->firstResultRels)
1896 locked_relids =
lappend_int(locked_relids, firstResultRel);
1907 foreach(lc, locked_relids)
1938 int n_total_subplans,
1939 int part_prune_index,
1953 elog(
ERROR,
"wrong pruneinfo with relids=%s found at part_prune_index=%d contained in plan node with relids=%s",
1963 Assert(prunestate != NULL);
1973 Assert(n_total_subplans > 0);
1975 n_total_subplans - 1);
1992 *initially_valid_subplans,
2035 int n_part_hierarchies;
2051 Assert(n_part_hierarchies > 0);
2084 int npartrelpruneinfos =
list_length(partrelpruneinfos);
2096 foreach(lc2, partrelpruneinfos)
2141 memcmp(partdesc->
oids, pinfo->relid_map,
2142 sizeof(
int) * partdesc->
nparts) == 0)
2147 sizeof(
int) * pinfo->
nparts);
2168 for (pp_idx = 0; pp_idx < partdesc->
nparts; pp_idx++)
2171 while (pd_idx < pinfo->nparts &&
2176 if (pd_idx < pinfo->nparts &&
2177 pinfo->relid_map[pd_idx] == partdesc->
oids[pp_idx])
2181 pinfo->subplan_map[pd_idx];
2183 pinfo->subpart_map[pd_idx];
2185 pinfo->leafpart_rti_map[pd_idx];
2210 for (
int pd_idx2 = pd_idx + 1; pd_idx2 < pinfo->
nparts; pd_idx2++)
2212 if (pd_idx2 >= pinfo->
nparts)
2214 if (pinfo->relid_map[pd_idx2] == partdesc->
oids[pp_idx])
2245 partdesc, partkey, NULL,
2271 int part_index = -1;
2297 List *pruning_steps,
2327 foreach(lc, pruning_steps)
2339 for (keyno = 0; keyno < partnatts; keyno++)
2362 if (planstate == NULL)
2401 int n_total_subplans)
2404 int *new_subplan_indexes = NULL;
2408 bool fix_subplan_map =
false;
2411 Assert(parent_plan != NULL);
2412 estate = parent_plan->
state;
2420 fix_subplan_map =
true;
2427 new_subplan_indexes = (
int *)
palloc0(
sizeof(
int) * n_total_subplans);
2433 new_subplan_indexes[
i] = newidx++;
2456 int nparts = pprune->
nparts;
2475 partdesc, partkey, parent_plan,
2479 if (!fix_subplan_map)
2486 for (k = 0; k < nparts; k++)
2501 Assert(oldidx < n_total_subplans);
2502 pprune->
subplan_map[k] = new_subplan_indexes[oldidx] - 1;
2504 if (new_subplan_indexes[oldidx] > 0)
2526 if (fix_subplan_map)
2528 new_other_subplans = NULL;
2532 new_subplan_indexes[
i] - 1);
2537 pfree(new_subplan_indexes);
2569 Assert(validsubplan_rtis != NULL || !initial_prune);
2593 &result, validsubplan_rtis);
2611 if (validsubplan_rtis)
2612 *validsubplan_rtis =
bms_copy(*validsubplan_rtis);
2678 initial_prune, validsubplans,
AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
AttrMap * build_attrmap_by_name(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)
AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)
#define InvalidAttrNumber
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
int bms_next_member(const Bitmapset *a, int prevbit)
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
void bms_free(Bitmapset *a)
int bms_num_members(const Bitmapset *a)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_copy(const Bitmapset *a)
static Datum values[MAXATTR]
#define FLEXIBLE_ARRAY_MEMBER
#define OidIsValid(objectId)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool equal(const void *a, const void *b)
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
ExprState * ExecInitQual(List *qual, PlanState *parent)
ExprState * ExecInitExprWithParams(Expr *node, ParamListInfo ext_params)
ProjectionInfo * ExecBuildUpdateProjection(List *targetList, bool evalTargetList, List *targetColnos, TupleDesc relDesc, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent)
List * ExecPrepareExprList(List *nodes, EState *estate)
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)
void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation, List *mergeActions)
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, ResultRelInfo *partition_root_rri, int instrument_options)
static PartitionDispatch ExecInitPartitionDispatchInfo(EState *estate, PartitionTupleRouting *proute, Oid partoid, PartitionDispatch parent_pd, int partidx, ResultRelInfo *rootResultRelInfo)
void ExecDoInitialPruning(EState *estate)
static ResultRelInfo * ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, PartitionDispatch dispatch, ResultRelInfo *rootResultRelInfo, int partidx)
PartitionPruneState * ExecInitPartitionExecPruning(PlanState *planstate, int n_total_subplans, int part_prune_index, Bitmapset *relids, Bitmapset **initially_valid_subplans)
static void InitExecPartitionPruneContexts(PartitionPruneState *prunstate, PlanState *parent_plan, Bitmapset *initially_valid_subplans, int n_total_subplans)
Bitmapset * ExecFindMatchingSubPlans(PartitionPruneState *prunestate, bool initial_prune, Bitmapset **validsubplan_rtis)
static void ExecInitRoutingInfo(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, PartitionDispatch dispatch, ResultRelInfo *partRelInfo, int partidx, bool is_borrowed_rel)
static char * ExecBuildSlotPartitionKeyDescription(Relation rel, Datum *values, bool *isnull, int maxfieldlen)
static void FormPartitionKeyDatum(PartitionDispatch pd, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
#define PARTITION_CACHED_FIND_THRESHOLD
PartitionTupleRouting * ExecSetupPartitionTupleRouting(EState *estate, Relation rel)
static List * adjust_partition_colnos(List *colnos, ResultRelInfo *leaf_part_rri)
static List * adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap)
ResultRelInfo * ExecFindPartition(ModifyTableState *mtstate, ResultRelInfo *rootResultRelInfo, PartitionTupleRouting *proute, TupleTableSlot *slot, EState *estate)
static void InitPartitionPruneContext(PartitionPruneContext *context, List *pruning_steps, PartitionDesc partdesc, PartitionKey partkey, PlanState *planstate, ExprContext *econtext)
struct PartitionDispatchData PartitionDispatchData
static int get_partition_for_tuple(PartitionDispatch pd, Datum *values, bool *isnull)
static void find_matching_subplans_recurse(PartitionPruningData *prunedata, PartitionedRelPruningData *pprune, bool initial_prune, Bitmapset **validsubplans, Bitmapset **validsubplan_rtis)
static PartitionPruneState * CreatePartitionPruneState(EState *estate, PartitionPruneInfo *pruneinfo, Bitmapset **all_leafpart_rtis)
void ExecCleanupTupleRouting(ModifyTableState *mtstate, PartitionTupleRouting *proute)
struct PartitionDispatchData * PartitionDispatch
struct PartitionedRelPruningData PartitionedRelPruningData
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsVirtual
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Relation ExecGetRangeTableRelation(EState *estate, Index rti, bool isResultRel)
TupleConversionMap * ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate)
ExprContext * CreateExprContext(EState *estate)
TupleConversionMap * ExecGetChildToRootMap(ResultRelInfo *resultRelInfo)
#define GetPerTupleExprContext(estate)
static bool ExecShouldLockRelations(EState *estate)
#define EXEC_FLAG_EXPLAIN_GENERIC
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
#define ResetExprContext(econtext)
#define GetPerTupleMemoryContext(estate)
static bool ExecPlanStillValid(EState *estate)
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
char * OidOutputFunctionCall(Oid functionId, Datum val)
Assert(PointerIsAligned(start, uint64))
List * lappend(List *list, void *datum)
List * lappend_int(List *list, int datum)
List * lappend_oid(List *list, Oid datum)
void list_free(List *list)
bool list_member_oid(const List *list, Oid datum)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
int pg_mbcliplen(const char *mbstr, int len, int limit)
void MemoryContextReset(MemoryContext context)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define CHECK_FOR_INTERRUPTS()
ResultRelInfo * ExecLookupResultRelByOid(ModifyTableState *node, Oid resultoid, bool missing_ok, bool update_cache)
void ExecInitMergeTupleSlots(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
char * bmsToString(const Bitmapset *bms)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
@ PARTITION_STRATEGY_HASH
@ PARTITION_STRATEGY_LIST
@ PARTITION_STRATEGY_RANGE
int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation, Datum *rb_datums, PartitionRangeDatumKind *rb_kind, Datum *tuple_datums, int n_tuple_datums)
uint64 compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc, const Oid *partcollation, const Datum *values, const bool *isnull)
int partition_range_datum_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, int nvalues, Datum *values, bool *is_equal)
int partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, Datum value, bool *is_equal)
#define partition_bound_accepts_nulls(bi)
PartitionKey RelationGetPartitionKey(Relation rel)
static int16 get_partition_col_attnum(PartitionKey key, int col)
static int get_partition_natts(PartitionKey key)
static Oid get_partition_col_typid(PartitionKey key, int col)
PartitionDirectory CreatePartitionDirectory(MemoryContext mcxt, bool omit_detached)
PartitionDesc PartitionDirectoryLookup(PartitionDirectory pdir, Relation rel)
List * get_partition_ancestors(Oid relid)
Bitmapset * get_matching_partitions(PartitionPruneContext *context, List *pruning_steps)
#define PruneCxtStateIdx(partnatts, step_id, keyno)
#define PARTITION_MAX_KEYS
#define lfirst_node(type, lc)
static int list_length(const List *l)
static void * list_nth(const List *list, int n)
static ListCell * list_head(const List *l)
#define list_nth_node(type, list, n)
static ListCell * lnext(const List *l, const ListCell *c)
static int32 DatumGetInt32(Datum X)
#define RelationGetForm(relation)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
List * RelationGetIndexList(Relation relation)
int errtable(Relation rel)
Node * map_variable_attnos(Node *node, int target_varno, int sublevels_up, const AttrMap *attno_map, Oid to_rowtype, bool *found_whole_row)
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
char * pg_get_partkeydef_columns(Oid relid, bool pretty)
void check_stack_depth(void)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
List * es_part_prune_infos
List * es_tuple_routing_result_relations
PlannedStmt * es_plannedstmt
Bitmapset * es_unpruned_relids
List * es_part_prune_states
MemoryContext es_query_cxt
PartitionDirectory es_partition_directory
List * es_part_prune_results
ParamListInfo ecxt_param_list_info
TupleTableSlot * ecxt_scantuple
struct EState * ecxt_estate
EndForeignInsert_function EndForeignInsert
BeginForeignInsert_function BeginForeignInsert
ExecForeignBatchInsert_function ExecForeignBatchInsert
GetForeignModifyBatchSize_function GetForeignModifyBatchSize
ProjectionInfo * mas_proj
ResultRelInfo * resultRelInfo
ResultRelInfo * rootResultRelInfo
List * mergeJoinConditions
List * withCheckOptionLists
OnConflictAction onConflictAction
TupleTableSlot * oc_ProjSlot
TupleTableSlot * oc_Existing
ExprState * oc_WhereClause
ProjectionInfo * oc_ProjInfo
PartitionRangeDatumKind ** kind
int last_found_datum_index
PartitionBoundInfo boundinfo
int last_found_part_index
int indexes[FLEXIBLE_ARRAY_MEMBER]
PartitionStrategy strategy
ExprContext * exprcontext
PartitionBoundInfo boundinfo
Bitmapset * other_subplans
PartitionPruningData * partprunedata[FLEXIBLE_ARRAY_MEMBER]
Bitmapset * other_subplans
MemoryContext prune_context
PartitionedRelPruningData partrelprunedata[FLEXIBLE_ARRAY_MEMBER]
PartitionDispatch * partition_dispatch_info
ResultRelInfo ** partitions
ResultRelInfo ** nonleaf_partitions
Bitmapset * present_parts
List * initial_pruning_steps
List * exec_pruning_steps
List * exec_pruning_steps
PartitionPruneContext exec_context
PartitionPruneContext initial_context
Bitmapset * present_parts
List * initial_pruning_steps
ExprContext * ps_ExprContext
TupleTableSlot * ps_ResultTupleSlot
TupleTableSlot * ri_PartitionTupleSlot
OnConflictSetState * ri_onConflict
List * ri_onConflictArbiterIndexes
struct CopyMultiInsertBuffer * ri_CopyMultiInsertBuffer
struct FdwRoutine * ri_FdwRoutine
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
static Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
#define IsolationUsesXactSnapshot()