PostgreSQL Source Code  git master
executor.h File Reference
#include "executor/execdesc.h"
#include "fmgr.h"
#include "nodes/lockoptions.h"
#include "nodes/parsenodes.h"
#include "utils/memutils.h"
Include dependency graph for executor.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  TupOutputState
 

Macros

#define EXEC_FLAG_EXPLAIN_ONLY   0x0001 /* EXPLAIN, no ANALYZE */
 
#define EXEC_FLAG_REWIND   0x0002 /* need efficient rescan */
 
#define EXEC_FLAG_BACKWARD   0x0004 /* need backward scan */
 
#define EXEC_FLAG_MARK   0x0008 /* need mark/restore */
 
#define EXEC_FLAG_SKIP_TRIGGERS   0x0010 /* skip AfterTrigger calls */
 
#define EXEC_FLAG_WITH_NO_DATA   0x0020 /* rel scannability doesn't matter */
 
#define EvalPlanQualSetSlot(epqstate, slot)   ((epqstate)->origslot = (slot))
 
#define do_text_output_oneline(tstate, str_to_emit)
 
#define ResetExprContext(econtext)   MemoryContextReset((econtext)->ecxt_per_tuple_memory)
 
#define GetPerTupleExprContext(estate)
 
#define GetPerTupleMemoryContext(estate)   (GetPerTupleExprContext(estate)->ecxt_per_tuple_memory)
 
#define ResetPerTupleExprContext(estate)
 

Typedefs

typedef void(* ExecutorStart_hook_type) (QueryDesc *queryDesc, int eflags)
 
typedef void(* ExecutorRun_hook_type) (QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
 
typedef void(* ExecutorFinish_hook_type) (QueryDesc *queryDesc)
 
typedef void(* ExecutorEnd_hook_type) (QueryDesc *queryDesc)
 
typedef bool(* ExecutorCheckPerms_hook_type) (List *, bool)
 
typedef TupleTableSlot *(* ExecScanAccessMtd) (ScanState *node)
 
typedef bool(* ExecScanRecheckMtd) (ScanState *node, TupleTableSlot *slot)
 
typedef struct TupOutputState TupOutputState
 

Functions

void ExecReScan (PlanState *node)
 
void ExecMarkPos (PlanState *node)
 
void ExecRestrPos (PlanState *node)
 
bool ExecSupportsMarkRestore (struct Path *pathnode)
 
bool ExecSupportsBackwardScan (Plan *node)
 
bool ExecMaterializesOutput (NodeTag plantype)
 
bool execCurrentOf (CurrentOfExpr *cexpr, ExprContext *econtext, Oid table_oid, ItemPointer current_tid)
 
ExprStateexecTuplesMatchPrepare (TupleDesc desc, int numCols, const AttrNumber *keyColIdx, const Oid *eqOperators, const Oid *collations, PlanState *parent)
 
void execTuplesHashPrepare (int numCols, const Oid *eqOperators, Oid **eqFuncOids, FmgrInfo **hashFunctions)
 
TupleHashTable BuildTupleHashTable (PlanState *parent, TupleDesc inputDesc, int numCols, AttrNumber *keyColIdx, const Oid *eqfuncoids, FmgrInfo *hashfunctions, Oid *collations, long nbuckets, Size additionalsize, MemoryContext tablecxt, MemoryContext tempcxt, bool use_variable_hash_iv)
 
TupleHashTable BuildTupleHashTableExt (PlanState *parent, TupleDesc inputDesc, int numCols, AttrNumber *keyColIdx, const Oid *eqfuncoids, FmgrInfo *hashfunctions, Oid *collations, long nbuckets, Size additionalsize, MemoryContext metacxt, MemoryContext tablecxt, MemoryContext tempcxt, bool use_variable_hash_iv)
 
TupleHashEntry LookupTupleHashEntry (TupleHashTable hashtable, TupleTableSlot *slot, bool *isnew, uint32 *hash)
 
uint32 TupleHashTableHash (TupleHashTable hashtable, TupleTableSlot *slot)
 
TupleHashEntry LookupTupleHashEntryHash (TupleHashTable hashtable, TupleTableSlot *slot, bool *isnew, uint32 hash)
 
TupleHashEntry FindTupleHashEntry (TupleHashTable hashtable, TupleTableSlot *slot, ExprState *eqcomp, FmgrInfo *hashfunctions)
 
void ResetTupleHashTable (TupleHashTable hashtable)
 
JunkFilterExecInitJunkFilter (List *targetList, TupleTableSlot *slot)
 
JunkFilterExecInitJunkFilterConversion (List *targetList, TupleDesc cleanTupType, TupleTableSlot *slot)
 
AttrNumber ExecFindJunkAttribute (JunkFilter *junkfilter, const char *attrName)
 
AttrNumber ExecFindJunkAttributeInTlist (List *targetlist, const char *attrName)
 
TupleTableSlotExecFilterJunk (JunkFilter *junkfilter, TupleTableSlot *slot)
 
static Datum ExecGetJunkAttribute (TupleTableSlot *slot, AttrNumber attno, bool *isNull)
 
void ExecutorStart (QueryDesc *queryDesc, int eflags)
 
void standard_ExecutorStart (QueryDesc *queryDesc, int eflags)
 
void ExecutorRun (QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
 
void standard_ExecutorRun (QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
 
void ExecutorFinish (QueryDesc *queryDesc)
 
void standard_ExecutorFinish (QueryDesc *queryDesc)
 
void ExecutorEnd (QueryDesc *queryDesc)
 
void standard_ExecutorEnd (QueryDesc *queryDesc)
 
void ExecutorRewind (QueryDesc *queryDesc)
 
bool ExecCheckRTPerms (List *rangeTable, bool ereport_on_violation)
 
void CheckValidResultRel (ResultRelInfo *resultRelInfo, CmdType operation)
 
void InitResultRelInfo (ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, ResultRelInfo *partition_root_rri, int instrument_options)
 
ResultRelInfoExecGetTriggerResultRel (EState *estate, Oid relid)
 
void ExecConstraints (ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
 
bool ExecPartitionCheck (ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
 
void ExecPartitionCheckEmitError (ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
 
void ExecWithCheckOptions (WCOKind kind, ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
 
LockTupleMode ExecUpdateLockMode (EState *estate, ResultRelInfo *relinfo)
 
ExecRowMarkExecFindRowMark (EState *estate, Index rti, bool missing_ok)
 
ExecAuxRowMarkExecBuildAuxRowMark (ExecRowMark *erm, List *targetlist)
 
TupleTableSlotEvalPlanQual (EPQState *epqstate, Relation relation, Index rti, TupleTableSlot *testslot)
 
void EvalPlanQualInit (EPQState *epqstate, EState *parentestate, Plan *subplan, List *auxrowmarks, int epqParam)
 
void EvalPlanQualSetPlan (EPQState *epqstate, Plan *subplan, List *auxrowmarks)
 
TupleTableSlotEvalPlanQualSlot (EPQState *epqstate, Relation relation, Index rti)
 
bool EvalPlanQualFetchRowMark (EPQState *epqstate, Index rti, TupleTableSlot *slot)
 
TupleTableSlotEvalPlanQualNext (EPQState *epqstate)
 
void EvalPlanQualBegin (EPQState *epqstate)
 
void EvalPlanQualEnd (EPQState *epqstate)
 
PlanStateExecInitNode (Plan *node, EState *estate, int eflags)
 
void ExecSetExecProcNode (PlanState *node, ExecProcNodeMtd function)
 
NodeMultiExecProcNode (PlanState *node)
 
void ExecEndNode (PlanState *node)
 
bool ExecShutdownNode (PlanState *node)
 
void ExecSetTupleBound (int64 tuples_needed, PlanState *child_node)
 
static TupleTableSlotExecProcNode (PlanState *node)
 
ExprStateExecInitExpr (Expr *node, PlanState *parent)
 
ExprStateExecInitExprWithParams (Expr *node, ParamListInfo ext_params)
 
ExprStateExecInitQual (List *qual, PlanState *parent)
 
ExprStateExecInitCheck (List *qual, PlanState *parent)
 
ListExecInitExprList (List *nodes, PlanState *parent)
 
ExprStateExecBuildAggTrans (AggState *aggstate, struct AggStatePerPhaseData *phase, bool doSort, bool doHash, bool nullcheck)
 
ExprStateExecBuildGroupingEqual (TupleDesc ldesc, TupleDesc rdesc, const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, int numCols, const AttrNumber *keyColIdx, const Oid *eqfunctions, const Oid *collations, PlanState *parent)
 
ExprStateExecBuildParamSetEqual (TupleDesc desc, const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, const Oid *eqfunctions, const Oid *collations, const List *param_exprs, PlanState *parent)
 
ProjectionInfoExecBuildProjectionInfo (List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
 
ProjectionInfoExecBuildUpdateProjection (List *targetList, bool evalTargetList, List *targetColnos, TupleDesc relDesc, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent)
 
ExprStateExecPrepareExpr (Expr *node, EState *estate)
 
ExprStateExecPrepareQual (List *qual, EState *estate)
 
ExprStateExecPrepareCheck (List *qual, EState *estate)
 
ListExecPrepareExprList (List *nodes, EState *estate)
 
static Datum ExecEvalExpr (ExprState *state, ExprContext *econtext, bool *isNull)
 
static Datum ExecEvalExprSwitchContext (ExprState *state, ExprContext *econtext, bool *isNull)
 
static TupleTableSlotExecProject (ProjectionInfo *projInfo)
 
static bool ExecQual (ExprState *state, ExprContext *econtext)
 
static bool ExecQualAndReset (ExprState *state, ExprContext *econtext)
 
bool ExecCheck (ExprState *state, ExprContext *context)
 
SetExprStateExecInitTableFunctionResult (Expr *expr, ExprContext *econtext, PlanState *parent)
 
TuplestorestateExecMakeTableFunctionResult (SetExprState *setexpr, ExprContext *econtext, MemoryContext argContext, TupleDesc expectedDesc, bool randomAccess)
 
SetExprStateExecInitFunctionResultSet (Expr *expr, ExprContext *econtext, PlanState *parent)
 
Datum ExecMakeFunctionResultSet (SetExprState *fcache, ExprContext *econtext, MemoryContext argContext, bool *isNull, ExprDoneCond *isDone)
 
TupleTableSlotExecScan (ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
 
void ExecAssignScanProjectionInfo (ScanState *node)
 
void ExecAssignScanProjectionInfoWithVarno (ScanState *node, int varno)
 
void ExecScanReScan (ScanState *node)
 
void ExecInitResultTypeTL (PlanState *planstate)
 
void ExecInitResultSlot (PlanState *planstate, const TupleTableSlotOps *tts_ops)
 
void ExecInitResultTupleSlotTL (PlanState *planstate, const TupleTableSlotOps *tts_ops)
 
void ExecInitScanTupleSlot (EState *estate, ScanState *scanstate, TupleDesc tupleDesc, const TupleTableSlotOps *tts_ops)
 
TupleTableSlotExecInitExtraTupleSlot (EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
 
TupleTableSlotExecInitNullTupleSlot (EState *estate, TupleDesc tupType, const TupleTableSlotOps *tts_ops)
 
TupleDesc ExecTypeFromTL (List *targetList)
 
TupleDesc ExecCleanTypeFromTL (List *targetList)
 
TupleDesc ExecTypeFromExprList (List *exprList)
 
void ExecTypeSetColNames (TupleDesc typeInfo, List *namesList)
 
void UpdateChangedParamSet (PlanState *node, Bitmapset *newchg)
 
TupOutputStatebegin_tup_output_tupdesc (DestReceiver *dest, TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
 
void do_tup_output (TupOutputState *tstate, Datum *values, bool *isnull)
 
void do_text_output_multiline (TupOutputState *tstate, const char *txt)
 
void end_tup_output (TupOutputState *tstate)
 
EStateCreateExecutorState (void)
 
void FreeExecutorState (EState *estate)
 
ExprContextCreateExprContext (EState *estate)
 
ExprContextCreateWorkExprContext (EState *estate)
 
ExprContextCreateStandaloneExprContext (void)
 
void FreeExprContext (ExprContext *econtext, bool isCommit)
 
void ReScanExprContext (ExprContext *econtext)
 
ExprContextMakePerTupleExprContext (EState *estate)
 
void ExecAssignExprContext (EState *estate, PlanState *planstate)
 
TupleDesc ExecGetResultType (PlanState *planstate)
 
const TupleTableSlotOpsExecGetResultSlotOps (PlanState *planstate, bool *isfixed)
 
void ExecAssignProjectionInfo (PlanState *planstate, TupleDesc inputDesc)
 
void ExecConditionalAssignProjectionInfo (PlanState *planstate, TupleDesc inputDesc, int varno)
 
void ExecFreeExprContext (PlanState *planstate)
 
void ExecAssignScanType (ScanState *scanstate, TupleDesc tupDesc)
 
void ExecCreateScanSlotFromOuterPlan (EState *estate, ScanState *scanstate, const TupleTableSlotOps *tts_ops)
 
bool ExecRelationIsTargetRelation (EState *estate, Index scanrelid)
 
Relation ExecOpenScanRelation (EState *estate, Index scanrelid, int eflags)
 
void ExecInitRangeTable (EState *estate, List *rangeTable)
 
void ExecCloseRangeTableRelations (EState *estate)
 
void ExecCloseResultRelations (EState *estate)
 
static RangeTblEntryexec_rt_fetch (Index rti, EState *estate)
 
Relation ExecGetRangeTableRelation (EState *estate, Index rti)
 
void ExecInitResultRelation (EState *estate, ResultRelInfo *resultRelInfo, Index rti)
 
int executor_errposition (EState *estate, int location)
 
void RegisterExprContextCallback (ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
 
void UnregisterExprContextCallback (ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
 
Datum GetAttributeByName (HeapTupleHeader tuple, const char *attname, bool *isNull)
 
Datum GetAttributeByNum (HeapTupleHeader tuple, AttrNumber attrno, bool *isNull)
 
int ExecTargetListLength (List *targetlist)
 
int ExecCleanTargetListLength (List *targetlist)
 
TupleTableSlotExecGetTriggerOldSlot (EState *estate, ResultRelInfo *relInfo)
 
TupleTableSlotExecGetTriggerNewSlot (EState *estate, ResultRelInfo *relInfo)
 
TupleTableSlotExecGetReturningSlot (EState *estate, ResultRelInfo *relInfo)
 
TupleConversionMapExecGetChildToRootMap (ResultRelInfo *resultRelInfo)
 
BitmapsetExecGetInsertedCols (ResultRelInfo *relinfo, EState *estate)
 
BitmapsetExecGetUpdatedCols (ResultRelInfo *relinfo, EState *estate)
 
BitmapsetExecGetExtraUpdatedCols (ResultRelInfo *relinfo, EState *estate)
 
BitmapsetExecGetAllUpdatedCols (ResultRelInfo *relinfo, EState *estate)
 
void ExecOpenIndices (ResultRelInfo *resultRelInfo, bool speculative)
 
void ExecCloseIndices (ResultRelInfo *resultRelInfo)
 
ListExecInsertIndexTuples (ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool update, bool noDupErr, bool *specConflict, List *arbiterIndexes)
 
bool ExecCheckIndexConstraints (ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, ItemPointer conflictTid, List *arbiterIndexes)
 
void check_exclusion_constraint (Relation heap, Relation index, IndexInfo *indexInfo, ItemPointer tupleid, Datum *values, bool *isnull, EState *estate, bool newIndex)
 
bool RelationFindReplTupleByIndex (Relation rel, Oid idxoid, LockTupleMode lockmode, TupleTableSlot *searchslot, TupleTableSlot *outslot)
 
bool RelationFindReplTupleSeq (Relation rel, LockTupleMode lockmode, TupleTableSlot *searchslot, TupleTableSlot *outslot)
 
void ExecSimpleRelationInsert (ResultRelInfo *resultRelInfo, EState *estate, TupleTableSlot *slot)
 
void ExecSimpleRelationUpdate (ResultRelInfo *resultRelInfo, EState *estate, EPQState *epqstate, TupleTableSlot *searchslot, TupleTableSlot *slot)
 
void ExecSimpleRelationDelete (ResultRelInfo *resultRelInfo, EState *estate, EPQState *epqstate, TupleTableSlot *searchslot)
 
void CheckCmdReplicaIdentity (Relation rel, CmdType cmd)
 
void CheckSubscriptionRelkind (char relkind, const char *nspname, const char *relname)
 
TupleTableSlotExecGetUpdateNewTuple (ResultRelInfo *relinfo, TupleTableSlot *planSlot, TupleTableSlot *oldSlot)
 
ResultRelInfoExecLookupResultRelByOid (ModifyTableState *node, Oid resultoid, bool missing_ok, bool update_cache)
 

Variables

PGDLLIMPORT ExecutorStart_hook_type ExecutorStart_hook
 
PGDLLIMPORT ExecutorRun_hook_type ExecutorRun_hook
 
PGDLLIMPORT ExecutorFinish_hook_type ExecutorFinish_hook
 
PGDLLIMPORT ExecutorEnd_hook_type ExecutorEnd_hook
 
PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
 

Macro Definition Documentation

◆ do_text_output_oneline

#define do_text_output_oneline (   tstate,
  str_to_emit 
)
Value:
do { \
Datum values_[1]; \
bool isnull_[1]; \
values_[0] = PointerGetDatum(cstring_to_text(str_to_emit)); \
isnull_[0] = false; \
do_tup_output(tstate, values_, isnull_); \
pfree(DatumGetPointer(values_[0])); \
} while (0)
#define PointerGetDatum(X)
Definition: postgres.h:600
text * cstring_to_text(const char *s)
Definition: varlena.c:189
#define DatumGetPointer(X)
Definition: postgres.h:593

Definition at line 505 of file executor.h.

Referenced by ExplainQuery(), and ShowGUCConfigOption().

◆ EvalPlanQualSetSlot

#define EvalPlanQualSetSlot (   epqstate,
  slot 
)    ((epqstate)->origslot = (slot))

◆ EXEC_FLAG_BACKWARD

◆ EXEC_FLAG_EXPLAIN_ONLY

◆ EXEC_FLAG_MARK

◆ EXEC_FLAG_REWIND

◆ EXEC_FLAG_SKIP_TRIGGERS

#define EXEC_FLAG_SKIP_TRIGGERS   0x0010 /* skip AfterTrigger calls */

◆ EXEC_FLAG_WITH_NO_DATA

#define EXEC_FLAG_WITH_NO_DATA   0x0020 /* rel scannability doesn't matter */

Definition at line 61 of file executor.h.

Referenced by ExecOpenScanRelation(), GetIntoRelEFlags(), and InitPlan().

◆ GetPerTupleExprContext

◆ GetPerTupleMemoryContext

◆ ResetExprContext

◆ ResetPerTupleExprContext

#define ResetPerTupleExprContext (   estate)
Value:
do { \
if ((estate)->es_per_tuple_exprcontext) \
ResetExprContext((estate)->es_per_tuple_exprcontext); \
} while (0)

Definition at line 542 of file executor.h.

Referenced by comparetup_cluster(), CopyFrom(), ExecModifyTable(), ExecPostprocessPlan(), and ExecutePlan().

Typedef Documentation

◆ ExecScanAccessMtd

typedef TupleTableSlot*(* ExecScanAccessMtd) (ScanState *node)

Definition at line 456 of file executor.h.

◆ ExecScanRecheckMtd

typedef bool(* ExecScanRecheckMtd) (ScanState *node, TupleTableSlot *slot)

Definition at line 457 of file executor.h.

◆ ExecutorCheckPerms_hook_type

typedef bool(* ExecutorCheckPerms_hook_type) (List *, bool)

Definition at line 84 of file executor.h.

◆ ExecutorEnd_hook_type

typedef void(* ExecutorEnd_hook_type) (QueryDesc *queryDesc)

Definition at line 80 of file executor.h.

◆ ExecutorFinish_hook_type

typedef void(* ExecutorFinish_hook_type) (QueryDesc *queryDesc)

Definition at line 76 of file executor.h.

◆ ExecutorRun_hook_type

typedef void(* ExecutorRun_hook_type) (QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)

Definition at line 69 of file executor.h.

◆ ExecutorStart_hook_type

typedef void(* ExecutorStart_hook_type) (QueryDesc *queryDesc, int eflags)

Definition at line 65 of file executor.h.

◆ TupOutputState

Function Documentation

◆ begin_tup_output_tupdesc()

TupOutputState* begin_tup_output_tupdesc ( DestReceiver dest,
TupleDesc  tupdesc,
const TupleTableSlotOps tts_ops 
)

Definition at line 2266 of file execTuples.c.

References CMD_SELECT, generate_unaccent_rules::dest, TupOutputState::dest, MakeSingleTupleTableSlot(), palloc(), _DestReceiver::rStartup, and TupOutputState::slot.

Referenced by CreateReplicationSlot(), ExecuteCallStmt(), ExplainQuery(), IdentifySystem(), ShowAllGUCConfig(), ShowGUCConfigOption(), and StartReplication().

2269 {
2270  TupOutputState *tstate;
2271 
2272  tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
2273 
2274  tstate->slot = MakeSingleTupleTableSlot(tupdesc, tts_ops);
2275  tstate->dest = dest;
2276 
2277  tstate->dest->rStartup(tstate->dest, (int) CMD_SELECT, tupdesc);
2278 
2279  return tstate;
2280 }
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1238
TupleTableSlot * slot
Definition: executor.h:489
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:122
void * palloc(Size size)
Definition: mcxt.c:1062
DestReceiver * dest
Definition: executor.h:490

◆ BuildTupleHashTable()

TupleHashTable BuildTupleHashTable ( PlanState parent,
TupleDesc  inputDesc,
int  numCols,
AttrNumber keyColIdx,
const Oid eqfuncoids,
FmgrInfo hashfunctions,
Oid collations,
long  nbuckets,
Size  additionalsize,
MemoryContext  tablecxt,
MemoryContext  tempcxt,
bool  use_variable_hash_iv 
)

Definition at line 255 of file execGrouping.c.

References BuildTupleHashTableExt().

265 {
266  return BuildTupleHashTableExt(parent,
267  inputDesc,
268  numCols, keyColIdx,
269  eqfuncoids,
270  hashfunctions,
271  collations,
272  nbuckets, additionalsize,
273  tablecxt,
274  tablecxt,
275  tempcxt,
276  use_variable_hash_iv);
277 }
TupleHashTable BuildTupleHashTableExt(PlanState *parent, TupleDesc inputDesc, int numCols, AttrNumber *keyColIdx, const Oid *eqfuncoids, FmgrInfo *hashfunctions, Oid *collations, long nbuckets, Size additionalsize, MemoryContext metacxt, MemoryContext tablecxt, MemoryContext tempcxt, bool use_variable_hash_iv)
Definition: execGrouping.c:154

◆ BuildTupleHashTableExt()

TupleHashTable BuildTupleHashTableExt ( PlanState parent,
TupleDesc  inputDesc,
int  numCols,
AttrNumber keyColIdx,
const Oid eqfuncoids,
FmgrInfo hashfunctions,
Oid collations,
long  nbuckets,
Size  additionalsize,
MemoryContext  metacxt,
MemoryContext  tablecxt,
MemoryContext  tempcxt,
bool  use_variable_hash_iv 
)

Definition at line 154 of file execGrouping.c.

References Assert, CreateStandaloneExprContext(), CreateTupleDescCopy(), TupleHashTableData::cur_eq_func, TupleHashTableData::entrysize, ExecBuildGroupingEqual(), TupleHashTableData::exprcontext, get_hash_memory_limit(), TupleHashTableData::hash_iv, TupleHashTableData::hashtab, TupleHashTableData::in_hash_funcs, TupleHashTableData::inputslot, TupleHashTableData::keyColIdx, MakeSingleTupleTableSlot(), MemoryContextSwitchTo(), murmurhash32(), TupleHashTableData::numCols, palloc(), ParallelWorkerNumber, TupleHashTableData::tab_collations, TupleHashTableData::tab_eq_func, TupleHashTableData::tab_hash_funcs, TupleHashTableData::tablecxt, TupleHashTableData::tableslot, TupleHashTableData::tempcxt, and TTSOpsMinimalTuple.

Referenced by build_hash_table(), buildSubPlanHash(), and BuildTupleHashTable().

165 {
166  TupleHashTable hashtable;
167  Size entrysize = sizeof(TupleHashEntryData) + additionalsize;
168  Size hash_mem_limit;
169  MemoryContext oldcontext;
170  bool allow_jit;
171 
172  Assert(nbuckets > 0);
173 
174  /* Limit initial table size request to not more than hash_mem */
175  hash_mem_limit = get_hash_memory_limit() / entrysize;
176  if (nbuckets > hash_mem_limit)
177  nbuckets = hash_mem_limit;
178 
179  oldcontext = MemoryContextSwitchTo(metacxt);
180 
181  hashtable = (TupleHashTable) palloc(sizeof(TupleHashTableData));
182 
183  hashtable->numCols = numCols;
184  hashtable->keyColIdx = keyColIdx;
185  hashtable->tab_hash_funcs = hashfunctions;
186  hashtable->tab_collations = collations;
187  hashtable->tablecxt = tablecxt;
188  hashtable->tempcxt = tempcxt;
189  hashtable->entrysize = entrysize;
190  hashtable->tableslot = NULL; /* will be made on first lookup */
191  hashtable->inputslot = NULL;
192  hashtable->in_hash_funcs = NULL;
193  hashtable->cur_eq_func = NULL;
194 
195  /*
196  * If parallelism is in use, even if the leader backend is performing the
197  * scan itself, we don't want to create the hashtable exactly the same way
198  * in all workers. As hashtables are iterated over in keyspace-order,
199  * doing so in all processes in the same way is likely to lead to
200  * "unbalanced" hashtables when the table size initially is
201  * underestimated.
202  */
203  if (use_variable_hash_iv)
205  else
206  hashtable->hash_iv = 0;
207 
208  hashtable->hashtab = tuplehash_create(metacxt, nbuckets, hashtable);
209 
210  /*
211  * We copy the input tuple descriptor just for safety --- we assume all
212  * input tuples will have equivalent descriptors.
213  */
216 
217  /*
218  * If the old reset interface is used (i.e. BuildTupleHashTable, rather
219  * than BuildTupleHashTableExt), allowing JIT would lead to the generated
220  * functions to a) live longer than the query b) be re-generated each time
221  * the table is being reset. Therefore prevent JIT from being used in that
222  * case, by not providing a parent node (which prevents accessing the
223  * JitContext in the EState).
224  */
225  allow_jit = metacxt != tablecxt;
226 
227  /* build comparator for all columns */
228  /* XXX: should we support non-minimal tuples for the inputslot? */
229  hashtable->tab_eq_func = ExecBuildGroupingEqual(inputDesc, inputDesc,
231  numCols,
232  keyColIdx, eqfuncoids, collations,
233  allow_jit ? parent : NULL);
234 
235  /*
236  * While not pretty, it's ok to not shut down this context, but instead
237  * rely on the containing memory context being reset, as
238  * ExecBuildGroupingEqual() only builds a very simple expression calling
239  * functions (i.e. nothing that'd employ RegisterExprContextCallback()).
240  */
242 
243  MemoryContextSwitchTo(oldcontext);
244 
245  return hashtable;
246 }
ExprContext * exprcontext
Definition: execnodes.h:756
ExprContext * CreateStandaloneExprContext(void)
Definition: execUtils.c:352
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:111
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1238
ExprState * ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, int numCols, const AttrNumber *keyColIdx, const Oid *eqfunctions, const Oid *collations, PlanState *parent)
Definition: execExpr.c:3708
TupleTableSlot * inputslot
Definition: execnodes.h:752
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
AttrNumber * keyColIdx
Definition: execnodes.h:743
ExprState * tab_eq_func
Definition: execnodes.h:745
ExprState * cur_eq_func
Definition: execnodes.h:754
static uint32 murmurhash32(uint32 data)
Definition: hashfn.h:92
FmgrInfo * tab_hash_funcs
Definition: execnodes.h:744
FmgrInfo * in_hash_funcs
Definition: execnodes.h:753
struct TupleHashEntryData TupleHashEntryData
MemoryContext tablecxt
Definition: execnodes.h:747
struct TupleHashTableData * TupleHashTable
Definition: execnodes.h:721
int ParallelWorkerNumber
Definition: parallel.c:112
tuplehash_hash * hashtab
Definition: execnodes.h:741
#define Assert(condition)
Definition: c.h:804
TupleTableSlot * tableslot
Definition: execnodes.h:750
size_t Size
Definition: c.h:540
size_t get_hash_memory_limit(void)
Definition: nodeHash.c:3401
void * palloc(Size size)
Definition: mcxt.c:1062
MemoryContext tempcxt
Definition: execnodes.h:748
const TupleTableSlotOps TTSOpsMinimalTuple
Definition: execTuples.c:85

◆ check_exclusion_constraint()

void check_exclusion_constraint ( Relation  heap,
Relation  index,
IndexInfo indexInfo,
ItemPointer  tupleid,
Datum values,
bool isnull,
EState estate,
bool  newIndex 
)

Definition at line 887 of file execIndexing.c.

References CEOUC_WAIT, and check_exclusion_or_unique_constraint().

Referenced by exec_rt_fetch(), IndexCheckExclusion(), and unique_key_recheck().

892 {
893  (void) check_exclusion_or_unique_constraint(heap, index, indexInfo, tupleid,
894  values, isnull,
895  estate, newIndex,
896  CEOUC_WAIT, false, NULL);
897 }
static bool check_exclusion_or_unique_constraint(Relation heap, Relation index, IndexInfo *indexInfo, ItemPointer tupleid, Datum *values, bool *isnull, EState *estate, bool newIndex, CEOUC_WAIT_MODE waitMode, bool errorOK, ItemPointer conflictTid)
Definition: execIndexing.c:667
static Datum values[MAXATTR]
Definition: bootstrap.c:156

◆ CheckCmdReplicaIdentity()

void CheckCmdReplicaIdentity ( Relation  rel,
CmdType  cmd 
)

Definition at line 568 of file execReplication.c.

References CMD_DELETE, CMD_UPDATE, ereport, errcode(), errhint(), errmsg(), ERROR, GetRelationPublicationActions(), OidIsValid, PublicationActions::pubdelete, PublicationActions::pubupdate, RelationData::rd_rel, RelationGetRelationName, and RelationGetReplicaIndex().

Referenced by CheckValidResultRel(), exec_rt_fetch(), ExecSimpleRelationDelete(), ExecSimpleRelationInsert(), and ExecSimpleRelationUpdate().

569 {
570  PublicationActions *pubactions;
571 
572  /* We only need to do checks for UPDATE and DELETE. */
573  if (cmd != CMD_UPDATE && cmd != CMD_DELETE)
574  return;
575 
576  /* If relation has replica identity we are always good. */
577  if (rel->rd_rel->relreplident == REPLICA_IDENTITY_FULL ||
579  return;
580 
581  /*
582  * This is either UPDATE OR DELETE and there is no replica identity.
583  *
584  * Check if the table publishes UPDATES or DELETES.
585  */
586  pubactions = GetRelationPublicationActions(rel);
587  if (cmd == CMD_UPDATE && pubactions->pubupdate)
588  ereport(ERROR,
589  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
590  errmsg("cannot update table \"%s\" because it does not have a replica identity and publishes updates",
592  errhint("To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.")));
593  else if (cmd == CMD_DELETE && pubactions->pubdelete)
594  ereport(ERROR,
595  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
596  errmsg("cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes",
598  errhint("To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE.")));
599 }
int errhint(const char *fmt,...)
Definition: elog.c:1156
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:4782
int errcode(int sqlerrcode)
Definition: elog.c:698
Form_pg_class rd_rel
Definition: rel.h:109
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
#define RelationGetRelationName(relation)
Definition: rel.h:511
#define ereport(elevel,...)
Definition: elog.h:157
struct PublicationActions * GetRelationPublicationActions(Relation relation)
Definition: relcache.c:5445
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ CheckSubscriptionRelkind()

void CheckSubscriptionRelkind ( char  relkind,
const char *  nspname,
const char *  relname 
)

Definition at line 608 of file execReplication.c.

References ereport, errcode(), errdetail_relkind_not_supported(), errmsg(), and ERROR.

Referenced by AlterSubscription_refresh(), CreateSubscription(), exec_rt_fetch(), and logicalrep_rel_open().

610 {
611  if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
612  ereport(ERROR,
613  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
614  errmsg("cannot use relation \"%s.%s\" as logical replication target",
615  nspname, relname),
617 }
int errdetail_relkind_not_supported(char relkind)
Definition: pg_class.c:24
int errcode(int sqlerrcode)
Definition: elog.c:698
NameData relname
Definition: pg_class.h:38
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ CheckValidResultRel()

void CheckValidResultRel ( ResultRelInfo resultRelInfo,
CmdType  operation 
)

Definition at line 992 of file execMain.c.

References CheckCmdReplicaIdentity(), CMD_DELETE, CMD_INSERT, CMD_UPDATE, elog, ereport, errcode(), errhint(), errmsg(), ERROR, FdwRoutine::ExecForeignDelete, FdwRoutine::ExecForeignInsert, FdwRoutine::ExecForeignUpdate, FdwRoutine::IsForeignRelUpdatable, MatViewIncrementalMaintenanceIsEnabled(), RelationData::rd_rel, RelationGetRelationName, ResultRelInfo::ri_FdwRoutine, ResultRelInfo::ri_RelationDesc, TriggerDesc::trig_delete_instead_row, TriggerDesc::trig_insert_instead_row, TriggerDesc::trig_update_instead_row, and RelationData::trigdesc.

Referenced by CopyFrom(), ExecFindPartition(), ExecGetJunkAttribute(), ExecInitModifyTable(), and ExecInitPartitionInfo().

993 {
994  Relation resultRel = resultRelInfo->ri_RelationDesc;
995  TriggerDesc *trigDesc = resultRel->trigdesc;
996  FdwRoutine *fdwroutine;
997 
998  switch (resultRel->rd_rel->relkind)
999  {
1000  case RELKIND_RELATION:
1001  case RELKIND_PARTITIONED_TABLE:
1002  CheckCmdReplicaIdentity(resultRel, operation);
1003  break;
1004  case RELKIND_SEQUENCE:
1005  ereport(ERROR,
1006  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1007  errmsg("cannot change sequence \"%s\"",
1008  RelationGetRelationName(resultRel))));
1009  break;
1010  case RELKIND_TOASTVALUE:
1011  ereport(ERROR,
1012  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1013  errmsg("cannot change TOAST relation \"%s\"",
1014  RelationGetRelationName(resultRel))));
1015  break;
1016  case RELKIND_VIEW:
1017 
1018  /*
1019  * Okay only if there's a suitable INSTEAD OF trigger. Messages
1020  * here should match rewriteHandler.c's rewriteTargetView and
1021  * RewriteQuery, except that we omit errdetail because we haven't
1022  * got the information handy (and given that we really shouldn't
1023  * get here anyway, it's not worth great exertion to get).
1024  */
1025  switch (operation)
1026  {
1027  case CMD_INSERT:
1028  if (!trigDesc || !trigDesc->trig_insert_instead_row)
1029  ereport(ERROR,
1030  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1031  errmsg("cannot insert into view \"%s\"",
1032  RelationGetRelationName(resultRel)),
1033  errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule.")));
1034  break;
1035  case CMD_UPDATE:
1036  if (!trigDesc || !trigDesc->trig_update_instead_row)
1037  ereport(ERROR,
1038  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1039  errmsg("cannot update view \"%s\"",
1040  RelationGetRelationName(resultRel)),
1041  errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.")));
1042  break;
1043  case CMD_DELETE:
1044  if (!trigDesc || !trigDesc->trig_delete_instead_row)
1045  ereport(ERROR,
1046  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1047  errmsg("cannot delete from view \"%s\"",
1048  RelationGetRelationName(resultRel)),
1049  errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule.")));
1050  break;
1051  default:
1052  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1053  break;
1054  }
1055  break;
1056  case RELKIND_MATVIEW:
1058  ereport(ERROR,
1059  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1060  errmsg("cannot change materialized view \"%s\"",
1061  RelationGetRelationName(resultRel))));
1062  break;
1063  case RELKIND_FOREIGN_TABLE:
1064  /* Okay only if the FDW supports it */
1065  fdwroutine = resultRelInfo->ri_FdwRoutine;
1066  switch (operation)
1067  {
1068  case CMD_INSERT:
1069  if (fdwroutine->ExecForeignInsert == NULL)
1070  ereport(ERROR,
1071  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1072  errmsg("cannot insert into foreign table \"%s\"",
1073  RelationGetRelationName(resultRel))));
1074  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1075  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_INSERT)) == 0)
1076  ereport(ERROR,
1077  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1078  errmsg("foreign table \"%s\" does not allow inserts",
1079  RelationGetRelationName(resultRel))));
1080  break;
1081  case CMD_UPDATE:
1082  if (fdwroutine->ExecForeignUpdate == NULL)
1083  ereport(ERROR,
1084  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1085  errmsg("cannot update foreign table \"%s\"",
1086  RelationGetRelationName(resultRel))));
1087  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1088  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_UPDATE)) == 0)
1089  ereport(ERROR,
1090  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1091  errmsg("foreign table \"%s\" does not allow updates",
1092  RelationGetRelationName(resultRel))));
1093  break;
1094  case CMD_DELETE:
1095  if (fdwroutine->ExecForeignDelete == NULL)
1096  ereport(ERROR,
1097  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1098  errmsg("cannot delete from foreign table \"%s\"",
1099  RelationGetRelationName(resultRel))));
1100  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1101  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_DELETE)) == 0)
1102  ereport(ERROR,
1103  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1104  errmsg("foreign table \"%s\" does not allow deletes",
1105  RelationGetRelationName(resultRel))));
1106  break;
1107  default:
1108  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1109  break;
1110  }
1111  break;
1112  default:
1113  ereport(ERROR,
1114  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1115  errmsg("cannot change relation \"%s\"",
1116  RelationGetRelationName(resultRel))));
1117  break;
1118  }
1119 }
ExecForeignDelete_function ExecForeignDelete
Definition: fdwapi.h:236
Relation ri_RelationDesc
Definition: execnodes.h:412
int errhint(const char *fmt,...)
Definition: elog.c:1156
bool MatViewIncrementalMaintenanceIsEnabled(void)
Definition: matview.c:928
ExecForeignInsert_function ExecForeignInsert
Definition: fdwapi.h:232
int errcode(int sqlerrcode)
Definition: elog.c:698
Form_pg_class rd_rel
Definition: rel.h:109
bool trig_insert_instead_row
Definition: reltrigger.h:58
#define ERROR
Definition: elog.h:46
TriggerDesc * trigdesc
Definition: rel.h:115
#define RelationGetRelationName(relation)
Definition: rel.h:511
struct FdwRoutine * ri_FdwRoutine
Definition: execnodes.h:456
void CheckCmdReplicaIdentity(Relation rel, CmdType cmd)
bool trig_update_instead_row
Definition: reltrigger.h:63
bool trig_delete_instead_row
Definition: reltrigger.h:68
#define ereport(elevel,...)
Definition: elog.h:157
ExecForeignUpdate_function ExecForeignUpdate
Definition: fdwapi.h:235
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
IsForeignRelUpdatable_function IsForeignRelUpdatable
Definition: fdwapi.h:240

◆ CreateExecutorState()

EState* CreateExecutorState ( void  )

Definition at line 90 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, CurrentMemoryContext, EState::es_auxmodifytables, EState::es_crosscheck_snapshot, EState::es_direction, EState::es_exprcontexts, EState::es_finished, EState::es_instrument, EState::es_jit, EState::es_jit_flags, EState::es_junkFilter, EState::es_opened_result_relations, EState::es_output_cid, EState::es_param_exec_vals, EState::es_param_list_info, EState::es_per_tuple_exprcontext, EState::es_plannedstmt, EState::es_processed, EState::es_query_cxt, EState::es_queryEnv, EState::es_range_table, EState::es_range_table_size, EState::es_relations, EState::es_result_relations, EState::es_rowmarks, EState::es_snapshot, EState::es_sourceText, EState::es_subplanstates, EState::es_top_eflags, EState::es_trig_target_relations, EState::es_tuple_routing_result_relations, EState::es_tupleTable, EState::es_use_parallel_mode, ForwardScanDirection, InvalidSnapshot, makeNode, MemoryContextSwitchTo(), and NIL.

Referenced by afterTriggerInvokeEvents(), ATRewriteTable(), check_default_partition_contents(), compute_expr_stats(), compute_index_stats(), CopyFrom(), create_edata_for_relation(), EvalPlanQualStart(), evaluate_expr(), ExecuteCallStmt(), ExecuteQuery(), ExecuteTruncateGuts(), ExplainExecuteQuery(), get_qual_for_range(), heapam_index_build_range_scan(), heapam_index_validate_scan(), IndexCheckExclusion(), make_build_data(), operator_predicate_proof(), plpgsql_create_econtext(), plpgsql_inline_handler(), standard_ExecutorStart(), StoreAttrDefault(), tuplesort_begin_cluster(), unique_key_recheck(), and validateDomainConstraint().

91 {
92  EState *estate;
93  MemoryContext qcontext;
94  MemoryContext oldcontext;
95 
96  /*
97  * Create the per-query context for this Executor run.
98  */
100  "ExecutorState",
102 
103  /*
104  * Make the EState node within the per-query context. This way, we don't
105  * need a separate pfree() operation for it at shutdown.
106  */
107  oldcontext = MemoryContextSwitchTo(qcontext);
108 
109  estate = makeNode(EState);
110 
111  /*
112  * Initialize all fields of the Executor State structure
113  */
115  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
116  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
117  estate->es_range_table = NIL;
118  estate->es_range_table_size = 0;
119  estate->es_relations = NULL;
120  estate->es_rowmarks = NULL;
121  estate->es_plannedstmt = NULL;
122 
123  estate->es_junkFilter = NULL;
124 
125  estate->es_output_cid = (CommandId) 0;
126 
127  estate->es_result_relations = NULL;
130  estate->es_trig_target_relations = NIL;
131 
132  estate->es_param_list_info = NULL;
133  estate->es_param_exec_vals = NULL;
134 
135  estate->es_queryEnv = NULL;
136 
137  estate->es_query_cxt = qcontext;
138 
139  estate->es_tupleTable = NIL;
140 
141  estate->es_processed = 0;
142 
143  estate->es_top_eflags = 0;
144  estate->es_instrument = 0;
145  estate->es_finished = false;
146 
147  estate->es_exprcontexts = NIL;
148 
149  estate->es_subplanstates = NIL;
150 
151  estate->es_auxmodifytables = NIL;
152 
153  estate->es_per_tuple_exprcontext = NULL;
154 
155  estate->es_sourceText = NULL;
156 
157  estate->es_use_parallel_mode = false;
158 
159  estate->es_jit_flags = 0;
160  estate->es_jit = NULL;
161 
162  /*
163  * Return the executor state structure
164  */
165  MemoryContextSwitchTo(oldcontext);
166 
167  return estate;
168 }
#define NIL
Definition: pg_list.h:65
uint32 CommandId
Definition: c.h:601
JunkFilter * es_junkFilter
Definition: execnodes.h:570
#define AllocSetContextCreate
Definition: memutils.h:173
CommandId es_output_cid
Definition: execnodes.h:573
struct JitContext * es_jit
Definition: execnodes.h:647
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:567
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:560
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:622
Snapshot es_snapshot
Definition: execnodes.h:559
List * es_range_table
Definition: execnodes.h:561
ScanDirection es_direction
Definition: execnodes.h:558
bool es_use_parallel_mode
Definition: execnodes.h:632
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:565
const char * es_sourceText
Definition: execnodes.h:568
ParamExecData * es_param_exec_vals
Definition: execnodes.h:596
MemoryContext es_query_cxt
Definition: execnodes.h:601
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195
int es_jit_flags
Definition: execnodes.h:646
List * es_opened_result_relations
Definition: execnodes.h:579
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
int es_instrument
Definition: execnodes.h:608
ResultRelInfo ** es_result_relations
Definition: execnodes.h:576
QueryEnvironment * es_queryEnv
Definition: execnodes.h:598
#define InvalidSnapshot
Definition: snapshot.h:123
List * es_trig_target_relations
Definition: execnodes.h:592
List * es_tupleTable
Definition: execnodes.h:603
List * es_auxmodifytables
Definition: execnodes.h:615
List * es_tuple_routing_result_relations
Definition: execnodes.h:589
bool es_finished
Definition: execnodes.h:609
#define makeNode(_type_)
Definition: nodes.h:584
Relation * es_relations
Definition: execnodes.h:563
uint64 es_processed
Definition: execnodes.h:605
Index es_range_table_size
Definition: execnodes.h:562
List * es_subplanstates
Definition: execnodes.h:613
int es_top_eflags
Definition: execnodes.h:607
ParamListInfo es_param_list_info
Definition: execnodes.h:595
List * es_exprcontexts
Definition: execnodes.h:611

◆ CreateExprContext()

ExprContext* CreateExprContext ( EState estate)

Definition at line 301 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, and CreateExprContextInternal().

Referenced by ExecAssignExprContext(), ExecInitMergeJoin(), ExecInitSubPlan(), ExecuteCallStmt(), MakePerTupleExprContext(), and plpgsql_create_econtext().

302 {
304 }
static ExprContext * CreateExprContextInternal(EState *estate, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: execUtils.c:231
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195

◆ CreateStandaloneExprContext()

ExprContext* CreateStandaloneExprContext ( void  )

Definition at line 352 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ExprContext::caseValue_datum, ExprContext::caseValue_isNull, CurrentMemoryContext, ExprContext::domainValue_datum, ExprContext::domainValue_isNull, ExprContext::ecxt_aggnulls, ExprContext::ecxt_aggvalues, ExprContext::ecxt_callbacks, ExprContext::ecxt_estate, ExprContext::ecxt_innertuple, ExprContext::ecxt_outertuple, ExprContext::ecxt_param_exec_vals, ExprContext::ecxt_param_list_info, ExprContext::ecxt_per_query_memory, ExprContext::ecxt_per_tuple_memory, ExprContext::ecxt_scantuple, and makeNode.

Referenced by BuildTupleHashTableExt(), domain_check_input(), and hypothetical_dense_rank_final().

353 {
354  ExprContext *econtext;
355 
356  /* Create the ExprContext node within the caller's memory context */
357  econtext = makeNode(ExprContext);
358 
359  /* Initialize fields of ExprContext */
360  econtext->ecxt_scantuple = NULL;
361  econtext->ecxt_innertuple = NULL;
362  econtext->ecxt_outertuple = NULL;
363 
365 
366  /*
367  * Create working memory for expression evaluation in this context.
368  */
369  econtext->ecxt_per_tuple_memory =
371  "ExprContext",
373 
374  econtext->ecxt_param_exec_vals = NULL;
375  econtext->ecxt_param_list_info = NULL;
376 
377  econtext->ecxt_aggvalues = NULL;
378  econtext->ecxt_aggnulls = NULL;
379 
380  econtext->caseValue_datum = (Datum) 0;
381  econtext->caseValue_isNull = true;
382 
383  econtext->domainValue_datum = (Datum) 0;
384  econtext->domainValue_isNull = true;
385 
386  econtext->ecxt_estate = NULL;
387 
388  econtext->ecxt_callbacks = NULL;
389 
390  return econtext;
391 }
#define AllocSetContextCreate
Definition: memutils.h:173
Datum * ecxt_aggvalues
Definition: execnodes.h:246
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:235
Datum domainValue_datum
Definition: execnodes.h:258
Datum caseValue_datum
Definition: execnodes.h:252
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:266
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:229
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:238
struct EState * ecxt_estate
Definition: execnodes.h:263
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
bool domainValue_isNull
Definition: execnodes.h:260
bool * ecxt_aggnulls
Definition: execnodes.h:248
uintptr_t Datum
Definition: postgres.h:411
#define makeNode(_type_)
Definition: nodes.h:584
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:231
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:227
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:234
bool caseValue_isNull
Definition: execnodes.h:254
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:239

◆ CreateWorkExprContext()

ExprContext* CreateWorkExprContext ( EState estate)

Definition at line 316 of file execUtils.c.

References ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, CreateExprContextInternal(), and work_mem.

Referenced by ExecInitAgg().

317 {
318  Size minContextSize = ALLOCSET_DEFAULT_MINSIZE;
319  Size initBlockSize = ALLOCSET_DEFAULT_INITSIZE;
320  Size maxBlockSize = ALLOCSET_DEFAULT_MAXSIZE;
321 
322  /* choose the maxBlockSize to be no larger than 1/16 of work_mem */
323  while (16 * maxBlockSize > work_mem * 1024L)
324  maxBlockSize >>= 1;
325 
326  if (maxBlockSize < ALLOCSET_DEFAULT_INITSIZE)
327  maxBlockSize = ALLOCSET_DEFAULT_INITSIZE;
328 
329  return CreateExprContextInternal(estate, minContextSize,
330  initBlockSize, maxBlockSize);
331 }
static ExprContext * CreateExprContextInternal(EState *estate, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: execUtils.c:231
#define ALLOCSET_DEFAULT_MINSIZE
Definition: memutils.h:192
int work_mem
Definition: globals.c:124
size_t Size
Definition: c.h:540
#define ALLOCSET_DEFAULT_INITSIZE
Definition: memutils.h:193
#define ALLOCSET_DEFAULT_MAXSIZE
Definition: memutils.h:194

◆ do_text_output_multiline()

void do_text_output_multiline ( TupOutputState tstate,
const char *  txt 
)

Definition at line 2314 of file execTuples.c.

References cstring_to_text_with_len(), DatumGetPointer, do_tup_output(), pfree(), PointerGetDatum, and values.

Referenced by ExplainQuery().

2315 {
2316  Datum values[1];
2317  bool isnull[1] = {false};
2318 
2319  while (*txt)
2320  {
2321  const char *eol;
2322  int len;
2323 
2324  eol = strchr(txt, '\n');
2325  if (eol)
2326  {
2327  len = eol - txt;
2328  eol++;
2329  }
2330  else
2331  {
2332  len = strlen(txt);
2333  eol = txt + len;
2334  }
2335 
2336  values[0] = PointerGetDatum(cstring_to_text_with_len(txt, len));
2337  do_tup_output(tstate, values, isnull);
2338  pfree(DatumGetPointer(values[0]));
2339  txt = eol;
2340  }
2341 }
#define PointerGetDatum(X)
Definition: postgres.h:600
void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
Definition: execTuples.c:2286
void pfree(void *pointer)
Definition: mcxt.c:1169
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:201
uintptr_t Datum
Definition: postgres.h:411
#define DatumGetPointer(X)
Definition: postgres.h:593
static Datum values[MAXATTR]
Definition: bootstrap.c:156

◆ do_tup_output()

void do_tup_output ( TupOutputState tstate,
Datum values,
bool isnull 
)

Definition at line 2286 of file execTuples.c.

References TupOutputState::dest, ExecClearTuple(), ExecStoreVirtualTuple(), TupleDescData::natts, _DestReceiver::receiveSlot, TupOutputState::slot, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.

Referenced by CreateReplicationSlot(), do_text_output_multiline(), IdentifySystem(), ShowAllGUCConfig(), and StartReplication().

2287 {
2288  TupleTableSlot *slot = tstate->slot;
2289  int natts = slot->tts_tupleDescriptor->natts;
2290 
2291  /* make sure the slot is clear */
2292  ExecClearTuple(slot);
2293 
2294  /* insert data */
2295  memcpy(slot->tts_values, values, natts * sizeof(Datum));
2296  memcpy(slot->tts_isnull, isnull, natts * sizeof(bool));
2297 
2298  /* mark slot as containing a virtual tuple */
2299  ExecStoreVirtualTuple(slot);
2300 
2301  /* send the tuple to the receiver */
2302  (void) tstate->dest->receiveSlot(slot, tstate->dest);
2303 
2304  /* clean up */
2305  ExecClearTuple(slot);
2306 }
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:119
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
Datum * tts_values
Definition: tuptable.h:126
TupleTableSlot * slot
Definition: executor.h:489
bool * tts_isnull
Definition: tuptable.h:128
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:124
uintptr_t Datum
Definition: postgres.h:411
static Datum values[MAXATTR]
Definition: bootstrap.c:156
DestReceiver * dest
Definition: executor.h:490
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1552

◆ end_tup_output()

void end_tup_output ( TupOutputState tstate)

Definition at line 2344 of file execTuples.c.

References TupOutputState::dest, ExecDropSingleTupleTableSlot(), pfree(), _DestReceiver::rShutdown, and TupOutputState::slot.

Referenced by CreateReplicationSlot(), ExecuteCallStmt(), ExplainQuery(), IdentifySystem(), ShowAllGUCConfig(), ShowGUCConfigOption(), and StartReplication().

2345 {
2346  tstate->dest->rShutdown(tstate->dest);
2347  /* note that destroying the dest is not ours to do */
2349  pfree(tstate);
2350 }
TupleTableSlot * slot
Definition: executor.h:489
void pfree(void *pointer)
Definition: mcxt.c:1169
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1254
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:125
DestReceiver * dest
Definition: executor.h:490

◆ EvalPlanQual()

TupleTableSlot* EvalPlanQual ( EPQState epqstate,
Relation  relation,
Index  rti,
TupleTableSlot testslot 
)

Definition at line 2359 of file execMain.c.

References Assert, EvalPlanQualBegin(), EvalPlanQualNext(), EvalPlanQualSlot(), ExecClearTuple(), ExecCopySlot(), ExecMaterializeSlot(), and TupIsNull.

Referenced by ExecDelete(), ExecGetJunkAttribute(), ExecUpdate(), and GetTupleForTrigger().

2361 {
2362  TupleTableSlot *slot;
2363  TupleTableSlot *testslot;
2364 
2365  Assert(rti > 0);
2366 
2367  /*
2368  * Need to run a recheck subquery. Initialize or reinitialize EPQ state.
2369  */
2370  EvalPlanQualBegin(epqstate);
2371 
2372  /*
2373  * Callers will often use the EvalPlanQualSlot to store the tuple to avoid
2374  * an unnecessary copy.
2375  */
2376  testslot = EvalPlanQualSlot(epqstate, relation, rti);
2377  if (testslot != inputslot)
2378  ExecCopySlot(testslot, inputslot);
2379 
2380  /*
2381  * Run the EPQ query. We assume it will return at most one tuple.
2382  */
2383  slot = EvalPlanQualNext(epqstate);
2384 
2385  /*
2386  * If we got a tuple, force the slot to materialize the tuple so that it
2387  * is not dependent on any local state in the EPQ query (in particular,
2388  * it's highly likely that the slot contains references to any pass-by-ref
2389  * datums that may be present in copyTuple). As with the next step, this
2390  * is to guard against early re-use of the EPQ query.
2391  */
2392  if (!TupIsNull(slot))
2393  ExecMaterializeSlot(slot);
2394 
2395  /*
2396  * Clear out the test tuple. This is needed in case the EPQ query is
2397  * re-used to test a tuple for a different relation. (Not clear that can
2398  * really happen, but let's be safe.)
2399  */
2400  ExecClearTuple(testslot);
2401 
2402  return slot;
2403 }
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition: tuptable.h:475
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
TupleTableSlot * EvalPlanQualNext(EPQState *epqstate)
Definition: execMain.c:2606
TupleTableSlot * EvalPlanQualSlot(EPQState *epqstate, Relation relation, Index rti)
Definition: execMain.c:2469
#define TupIsNull(slot)
Definition: tuptable.h:292
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition: tuptable.h:443
#define Assert(condition)
Definition: c.h:804
void EvalPlanQualBegin(EPQState *epqstate)
Definition: execMain.c:2622

◆ EvalPlanQualBegin()

void EvalPlanQualBegin ( EPQState epqstate)

Definition at line 2622 of file execMain.c.

References bms_add_member(), PlanState::chgParam, EPQState::epqParam, EState::es_param_exec_vals, EState::es_plannedstmt, EState::es_range_table_size, EvalPlanQualStart(), ExecSetParamPlanMulti(), Plan::extParam, GetPerTupleExprContext, i, ParamExecData::isnull, list_length(), MemSet, NIL, PlannedStmt::paramExecTypes, EPQState::parentestate, PlanState::plan, EPQState::plan, EPQState::recheckestate, EPQState::recheckplanstate, EPQState::relsubs_done, and ParamExecData::value.

Referenced by EvalPlanQual(), ExecDelete(), and ExecLockRows().

2623 {
2624  EState *parentestate = epqstate->parentestate;
2625  EState *recheckestate = epqstate->recheckestate;
2626 
2627  if (recheckestate == NULL)
2628  {
2629  /* First time through, so create a child EState */
2630  EvalPlanQualStart(epqstate, epqstate->plan);
2631  }
2632  else
2633  {
2634  /*
2635  * We already have a suitable child EPQ tree, so just reset it.
2636  */
2637  Index rtsize = parentestate->es_range_table_size;
2638  PlanState *rcplanstate = epqstate->recheckplanstate;
2639 
2640  MemSet(epqstate->relsubs_done, 0, rtsize * sizeof(bool));
2641 
2642  /* Recopy current values of parent parameters */
2643  if (parentestate->es_plannedstmt->paramExecTypes != NIL)
2644  {
2645  int i;
2646 
2647  /*
2648  * Force evaluation of any InitPlan outputs that could be needed
2649  * by the subplan, just in case they got reset since
2650  * EvalPlanQualStart (see comments therein).
2651  */
2652  ExecSetParamPlanMulti(rcplanstate->plan->extParam,
2653  GetPerTupleExprContext(parentestate));
2654 
2655  i = list_length(parentestate->es_plannedstmt->paramExecTypes);
2656 
2657  while (--i >= 0)
2658  {
2659  /* copy value if any, but not execPlan link */
2660  recheckestate->es_param_exec_vals[i].value =
2661  parentestate->es_param_exec_vals[i].value;
2662  recheckestate->es_param_exec_vals[i].isnull =
2663  parentestate->es_param_exec_vals[i].isnull;
2664  }
2665  }
2666 
2667  /*
2668  * Mark child plan tree as needing rescan at all scan nodes. The
2669  * first ExecProcNode will take care of actually doing the rescan.
2670  */
2671  rcplanstate->chgParam = bms_add_member(rcplanstate->chgParam,
2672  epqstate->epqParam);
2673  }
2674 }
List * paramExecTypes
Definition: plannodes.h:84
#define NIL
Definition: pg_list.h:65
void ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext)
Definition: nodeSubplan.c:1253
PlannedStmt * es_plannedstmt
Definition: execnodes.h:567
#define MemSet(start, val, len)
Definition: c.h:1008
EState * parentestate
Definition: execnodes.h:1104
#define GetPerTupleExprContext(estate)
Definition: executor.h:533
ParamExecData * es_param_exec_vals
Definition: execnodes.h:596
EState * recheckestate
Definition: execnodes.h:1134
bool isnull
Definition: params.h:150
static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
Definition: execMain.c:2683
bool * relsubs_done
Definition: execnodes.h:1147
Bitmapset * chgParam
Definition: execnodes.h:999
Plan * plan
Definition: execnodes.h:1120
unsigned int Index
Definition: c.h:549
Plan * plan
Definition: execnodes.h:967
static int list_length(const List *l)
Definition: pg_list.h:149
Bitmapset * extParam
Definition: plannodes.h:159
Index es_range_table_size
Definition: execnodes.h:562
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
int i
Datum value
Definition: params.h:149
int epqParam
Definition: execnodes.h:1105
PlanState * recheckplanstate
Definition: execnodes.h:1149

◆ EvalPlanQualEnd()

void EvalPlanQualEnd ( EPQState epqstate)

Definition at line 2834 of file execMain.c.

References EState::es_query_cxt, EState::es_range_table_size, EState::es_subplanstates, EState::es_tupleTable, ExecCloseResultRelations(), ExecEndNode(), ExecResetTupleTable(), FreeExecutorState(), lfirst, MemoryContextSwitchTo(), NIL, EPQState::origslot, EPQState::parentestate, EPQState::recheckestate, EPQState::recheckplanstate, EPQState::relsubs_done, EPQState::relsubs_rowmark, EPQState::relsubs_slot, and EPQState::tuple_table.

Referenced by apply_handle_delete_internal(), apply_handle_tuple_routing(), apply_handle_update_internal(), EvalPlanQualSetPlan(), ExecEndLockRows(), ExecEndModifyTable(), and ExecLockRows().

2835 {
2836  EState *estate = epqstate->recheckestate;
2837  Index rtsize;
2838  MemoryContext oldcontext;
2839  ListCell *l;
2840 
2841  rtsize = epqstate->parentestate->es_range_table_size;
2842 
2843  /*
2844  * We may have a tuple table, even if EPQ wasn't started, because we allow
2845  * use of EvalPlanQualSlot() without calling EvalPlanQualBegin().
2846  */
2847  if (epqstate->tuple_table != NIL)
2848  {
2849  memset(epqstate->relsubs_slot, 0,
2850  rtsize * sizeof(TupleTableSlot *));
2851  ExecResetTupleTable(epqstate->tuple_table, true);
2852  epqstate->tuple_table = NIL;
2853  }
2854 
2855  /* EPQ wasn't started, nothing further to do */
2856  if (estate == NULL)
2857  return;
2858 
2859  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
2860 
2861  ExecEndNode(epqstate->recheckplanstate);
2862 
2863  foreach(l, estate->es_subplanstates)
2864  {
2865  PlanState *subplanstate = (PlanState *) lfirst(l);
2866 
2867  ExecEndNode(subplanstate);
2868  }
2869 
2870  /* throw away the per-estate tuple table, some node may have used it */
2871  ExecResetTupleTable(estate->es_tupleTable, false);
2872 
2873  /* Close any result and trigger target relations attached to this EState */
2874  ExecCloseResultRelations(estate);
2875 
2876  MemoryContextSwitchTo(oldcontext);
2877 
2878  FreeExecutorState(estate);
2879 
2880  /* Mark EPQState idle */
2881  epqstate->origslot = NULL;
2882  epqstate->recheckestate = NULL;
2883  epqstate->recheckplanstate = NULL;
2884  epqstate->relsubs_rowmark = NULL;
2885  epqstate->relsubs_done = NULL;
2886 }
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1113
#define NIL
Definition: pg_list.h:65
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:556
void ExecCloseResultRelations(EState *estate)
Definition: execMain.c:1439
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
EState * parentestate
Definition: execnodes.h:1104
void FreeExecutorState(EState *estate)
Definition: execUtils.c:186
MemoryContext es_query_cxt
Definition: execnodes.h:601
EState * recheckestate
Definition: execnodes.h:1134
List * tuple_table
Definition: execnodes.h:1112
bool * relsubs_done
Definition: execnodes.h:1147
TupleTableSlot * origslot
Definition: execnodes.h:1129
List * es_tupleTable
Definition: execnodes.h:603
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:1191
unsigned int Index
Definition: c.h:549
#define lfirst(lc)
Definition: pg_list.h:169
Index es_range_table_size
Definition: execnodes.h:562
List * es_subplanstates
Definition: execnodes.h:613
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1141
PlanState * recheckplanstate
Definition: execnodes.h:1149

◆ EvalPlanQualFetchRowMark()

bool EvalPlanQualFetchRowMark ( EPQState epqstate,
Index  rti,
TupleTableSlot slot 
)

Definition at line 2497 of file execMain.c.

References Assert, ExecAuxRowMark::ctidAttNo, DatumGetObjectId, DatumGetPointer, elog, ereport, errcode(), errmsg(), ERROR, ExecGetJunkAttribute(), ExecStoreHeapTupleDatum(), GetFdwRoutineForRelation(), ExecRowMark::markType, OidIsValid, EPQState::origslot, ExecRowMark::prti, RelationData::rd_rel, EPQState::recheckestate, FdwRoutine::RefetchForeignRow, ExecRowMark::relation, RelationGetRelationName, ExecRowMark::relid, EPQState::relsubs_rowmark, ROW_MARK_COPY, ROW_MARK_REFERENCE, ExecAuxRowMark::rowmark, RowMarkRequiresRowShareLock, ExecRowMark::rti, SnapshotAny, table_tuple_fetch_row_version(), ExecAuxRowMark::toidAttNo, TupIsNull, and ExecAuxRowMark::wholeAttNo.

Referenced by ExecScanFetch().

2498 {
2499  ExecAuxRowMark *earm = epqstate->relsubs_rowmark[rti - 1];
2500  ExecRowMark *erm = earm->rowmark;
2501  Datum datum;
2502  bool isNull;
2503 
2504  Assert(earm != NULL);
2505  Assert(epqstate->origslot != NULL);
2506 
2508  elog(ERROR, "EvalPlanQual doesn't support locking rowmarks");
2509 
2510  /* if child rel, must check whether it produced this row */
2511  if (erm->rti != erm->prti)
2512  {
2513  Oid tableoid;
2514 
2515  datum = ExecGetJunkAttribute(epqstate->origslot,
2516  earm->toidAttNo,
2517  &isNull);
2518  /* non-locked rels could be on the inside of outer joins */
2519  if (isNull)
2520  return false;
2521 
2522  tableoid = DatumGetObjectId(datum);
2523 
2524  Assert(OidIsValid(erm->relid));
2525  if (tableoid != erm->relid)
2526  {
2527  /* this child is inactive right now */
2528  return false;
2529  }
2530  }
2531 
2532  if (erm->markType == ROW_MARK_REFERENCE)
2533  {
2534  Assert(erm->relation != NULL);
2535 
2536  /* fetch the tuple's ctid */
2537  datum = ExecGetJunkAttribute(epqstate->origslot,
2538  earm->ctidAttNo,
2539  &isNull);
2540  /* non-locked rels could be on the inside of outer joins */
2541  if (isNull)
2542  return false;
2543 
2544  /* fetch requests on foreign tables must be passed to their FDW */
2545  if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2546  {
2547  FdwRoutine *fdwroutine;
2548  bool updated = false;
2549 
2550  fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
2551  /* this should have been checked already, but let's be safe */
2552  if (fdwroutine->RefetchForeignRow == NULL)
2553  ereport(ERROR,
2554  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2555  errmsg("cannot lock rows in foreign table \"%s\"",
2557 
2558  fdwroutine->RefetchForeignRow(epqstate->recheckestate,
2559  erm,
2560  datum,
2561  slot,
2562  &updated);
2563  if (TupIsNull(slot))
2564  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2565 
2566  /*
2567  * Ideally we'd insist on updated == false here, but that assumes
2568  * that FDWs can track that exactly, which they might not be able
2569  * to. So just ignore the flag.
2570  */
2571  return true;
2572  }
2573  else
2574  {
2575  /* ordinary table, fetch the tuple */
2577  (ItemPointer) DatumGetPointer(datum),
2578  SnapshotAny, slot))
2579  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2580  return true;
2581  }
2582  }
2583  else
2584  {
2585  Assert(erm->markType == ROW_MARK_COPY);
2586 
2587  /* fetch the whole-row Var for the relation */
2588  datum = ExecGetJunkAttribute(epqstate->origslot,
2589  earm->wholeAttNo,
2590  &isNull);
2591  /* non-locked rels could be on the inside of outer joins */
2592  if (isNull)
2593  return false;
2594 
2595  ExecStoreHeapTupleDatum(datum, slot);
2596  return true;
2597  }
2598 }
Relation relation
Definition: execnodes.h:673
#define DatumGetObjectId(X)
Definition: postgres.h:544
int errcode(int sqlerrcode)
Definition: elog.c:698
Form_pg_class rd_rel
Definition: rel.h:109
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:1077
ExecRowMark * rowmark
Definition: execnodes.h:697
#define ERROR
Definition: elog.h:46
EState * recheckestate
Definition: execnodes.h:1134
Index rti
Definition: execnodes.h:675
AttrNumber wholeAttNo
Definition: execnodes.h:700
Index prti
Definition: execnodes.h:676
#define RelationGetRelationName(relation)
Definition: rel.h:511
#define TupIsNull(slot)
Definition: tuptable.h:292
TupleTableSlot * origslot
Definition: execnodes.h:1129
void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot)
Definition: execTuples.c:1606
static bool table_tuple_fetch_row_version(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
Definition: tableam.h:1257
static Datum ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, bool *isNull)
Definition: executor.h:178
uintptr_t Datum
Definition: postgres.h:411
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
RowMarkType markType
Definition: execnodes.h:678
AttrNumber toidAttNo
Definition: execnodes.h:699
#define SnapshotAny
Definition: snapmgr.h:67
#define DatumGetPointer(X)
Definition: postgres.h:593
int errmsg(const char *fmt,...)
Definition: elog.c:909
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Definition: foreign.c:427
#define elog(elevel,...)
Definition: elog.h:232
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1141
AttrNumber ctidAttNo
Definition: execnodes.h:698
RefetchForeignRow_function RefetchForeignRow
Definition: fdwapi.h:248

◆ EvalPlanQualInit()

void EvalPlanQualInit ( EPQState epqstate,
EState parentestate,
Plan subplan,
List auxrowmarks,
int  epqParam 
)

Definition at line 2413 of file execMain.c.

References EPQState::arowMarks, EPQState::epqParam, EState::es_range_table_size, NIL, EPQState::origslot, palloc0(), EPQState::parentestate, EPQState::plan, EPQState::recheckestate, EPQState::recheckplanstate, EPQState::relsubs_done, EPQState::relsubs_rowmark, EPQState::relsubs_slot, ExprEvalStep::subplan, and EPQState::tuple_table.

Referenced by apply_handle_delete_internal(), apply_handle_tuple_routing(), apply_handle_update_internal(), ExecGetJunkAttribute(), ExecInitLockRows(), and ExecInitModifyTable().

2415 {
2416  Index rtsize = parentestate->es_range_table_size;
2417 
2418  /* initialize data not changing over EPQState's lifetime */
2419  epqstate->parentestate = parentestate;
2420  epqstate->epqParam = epqParam;
2421 
2422  /*
2423  * Allocate space to reference a slot for each potential rti - do so now
2424  * rather than in EvalPlanQualBegin(), as done for other dynamically
2425  * allocated resources, so EvalPlanQualSlot() can be used to hold tuples
2426  * that *may* need EPQ later, without forcing the overhead of
2427  * EvalPlanQualBegin().
2428  */
2429  epqstate->tuple_table = NIL;
2430  epqstate->relsubs_slot = (TupleTableSlot **)
2431  palloc0(rtsize * sizeof(TupleTableSlot *));
2432 
2433  /* ... and remember data that EvalPlanQualBegin will need */
2434  epqstate->plan = subplan;
2435  epqstate->arowMarks = auxrowmarks;
2436 
2437  /* ... and mark the EPQ state inactive */
2438  epqstate->origslot = NULL;
2439  epqstate->recheckestate = NULL;
2440  epqstate->recheckplanstate = NULL;
2441  epqstate->relsubs_rowmark = NULL;
2442  epqstate->relsubs_done = NULL;
2443 }
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1113
#define NIL
Definition: pg_list.h:65
EState * parentestate
Definition: execnodes.h:1104
EState * recheckestate
Definition: execnodes.h:1134
List * arowMarks
Definition: execnodes.h:1121
List * tuple_table
Definition: execnodes.h:1112
bool * relsubs_done
Definition: execnodes.h:1147
TupleTableSlot * origslot
Definition: execnodes.h:1129
Plan * plan
Definition: execnodes.h:1120
void * palloc0(Size size)
Definition: mcxt.c:1093
unsigned int Index
Definition: c.h:549
Index es_range_table_size
Definition: execnodes.h:562
int epqParam
Definition: execnodes.h:1105
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1141
PlanState * recheckplanstate
Definition: execnodes.h:1149

◆ EvalPlanQualNext()

TupleTableSlot* EvalPlanQualNext ( EPQState epqstate)

Definition at line 2606 of file execMain.c.

References EState::es_query_cxt, ExecProcNode(), MemoryContextSwitchTo(), EPQState::recheckestate, and EPQState::recheckplanstate.

Referenced by EvalPlanQual(), and ExecLockRows().

2607 {
2608  MemoryContext oldcontext;
2609  TupleTableSlot *slot;
2610 
2611  oldcontext = MemoryContextSwitchTo(epqstate->recheckestate->es_query_cxt);
2612  slot = ExecProcNode(epqstate->recheckplanstate);
2613  MemoryContextSwitchTo(oldcontext);
2614 
2615  return slot;
2616 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:601
EState * recheckestate
Definition: execnodes.h:1134
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition: executor.h:252
PlanState * recheckplanstate
Definition: execnodes.h:1149

◆ EvalPlanQualSetPlan()

void EvalPlanQualSetPlan ( EPQState epqstate,
Plan subplan,
List auxrowmarks 
)

Definition at line 2452 of file execMain.c.

References EPQState::arowMarks, EvalPlanQualEnd(), EPQState::plan, and ExprEvalStep::subplan.

Referenced by ExecGetJunkAttribute(), and ExecInitModifyTable().

2453 {
2454  /* If we have a live EPQ query, shut it down */
2455  EvalPlanQualEnd(epqstate);
2456  /* And set/change the plan pointer */
2457  epqstate->plan = subplan;
2458  /* The rowmarks depend on the plan, too */
2459  epqstate->arowMarks = auxrowmarks;
2460 }
void EvalPlanQualEnd(EPQState *epqstate)
Definition: execMain.c:2834
List * arowMarks
Definition: execnodes.h:1121
Plan * plan
Definition: execnodes.h:1120

◆ EvalPlanQualSlot()

TupleTableSlot* EvalPlanQualSlot ( EPQState epqstate,
Relation  relation,
Index  rti 
)

Definition at line 2469 of file execMain.c.

References Assert, EState::es_query_cxt, MemoryContextSwitchTo(), EPQState::parentestate, EPQState::relsubs_slot, table_slot_create(), and EPQState::tuple_table.

Referenced by EvalPlanQual(), ExecDelete(), ExecGetJunkAttribute(), ExecLockRows(), and ExecUpdate().

2471 {
2472  TupleTableSlot **slot;
2473 
2474  Assert(relation);
2475  Assert(rti > 0 && rti <= epqstate->parentestate->es_range_table_size);
2476  slot = &epqstate->relsubs_slot[rti - 1];
2477 
2478  if (*slot == NULL)
2479  {
2480  MemoryContext oldcontext;
2481 
2482  oldcontext = MemoryContextSwitchTo(epqstate->parentestate->es_query_cxt);
2483  *slot = table_slot_create(relation, &epqstate->tuple_table);
2484  MemoryContextSwitchTo(oldcontext);
2485  }
2486 
2487  return *slot;
2488 }
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:91
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1113
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
EState * parentestate
Definition: execnodes.h:1104
MemoryContext es_query_cxt
Definition: execnodes.h:601
List * tuple_table
Definition: execnodes.h:1112
#define Assert(condition)
Definition: c.h:804

◆ exec_rt_fetch()

static RangeTblEntry* exec_rt_fetch ( Index  rti,
EState estate 
)
inlinestatic

Definition at line 571 of file executor.h.

References arg, attname, check_exclusion_constraint(), CheckCmdReplicaIdentity(), CheckSubscriptionRelkind(), EState::es_range_table, ExecCheckIndexConstraints(), ExecCleanTargetListLength(), ExecCloseIndices(), ExecGetAllUpdatedCols(), ExecGetChildToRootMap(), ExecGetExtraUpdatedCols(), ExecGetInsertedCols(), ExecGetRangeTableRelation(), ExecGetReturningSlot(), ExecGetTriggerNewSlot(), ExecGetTriggerOldSlot(), ExecGetUpdatedCols(), ExecGetUpdateNewTuple(), ExecInitResultRelation(), ExecInsertIndexTuples(), ExecLookupResultRelByOid(), ExecOpenIndices(), ExecSimpleRelationDelete(), ExecSimpleRelationInsert(), ExecSimpleRelationUpdate(), ExecTargetListLength(), executor_errposition(), GetAttributeByName(), GetAttributeByNum(), list_nth(), RegisterExprContextCallback(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), relname, UnregisterExprContextCallback(), and values.

Referenced by conversion_error_callback(), ExecEvalWholeRowVar(), ExecGetExtraUpdatedCols(), ExecGetInsertedCols(), ExecGetRangeTableRelation(), ExecGetUpdatedCols(), ExecInitBitmapIndexScan(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), InitPlan(), postgresBeginDirectModify(), postgresBeginForeignInsert(), postgresBeginForeignModify(), and postgresBeginForeignScan().

572 {
573  return (RangeTblEntry *) list_nth(estate->es_range_table, rti - 1);
574 }
List * es_range_table
Definition: execnodes.h:561
static void * list_nth(const List *list, int n)
Definition: pg_list.h:278

◆ ExecAssignExprContext()

◆ ExecAssignProjectionInfo()

void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

Definition at line 535 of file execUtils.c.

References ExecBuildProjectionInfo(), PlanState::plan, PlanState::ps_ExprContext, PlanState::ps_ProjInfo, PlanState::ps_ResultTupleSlot, and Plan::targetlist.

Referenced by ExecConditionalAssignProjectionInfo(), ExecInitAgg(), ExecInitGroup(), ExecInitHashJoin(), ExecInitMergeJoin(), ExecInitNestLoop(), ExecInitResult(), and ExecInitWindowAgg().

537 {
538  planstate->ps_ProjInfo =
540  planstate->ps_ExprContext,
541  planstate->ps_ResultTupleSlot,
542  planstate,
543  inputDesc);
544 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1007
ExprContext * ps_ExprContext
Definition: execnodes.h:1006
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1005
Plan * plan
Definition: execnodes.h:967
List * targetlist
Definition: plannodes.h:141
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:353

◆ ExecAssignScanProjectionInfo()

void ExecAssignScanProjectionInfo ( ScanState node)

◆ ExecAssignScanProjectionInfoWithVarno()

void ExecAssignScanProjectionInfoWithVarno ( ScanState node,
int  varno 
)

Definition at line 285 of file execScan.c.

References ExecConditionalAssignProjectionInfo(), ScanState::ps, ScanState::ss_ScanTupleSlot, and TupleTableSlot::tts_tupleDescriptor.

Referenced by ExecInitCustomScan(), ExecInitForeignScan(), and ExecInitIndexOnlyScan().

286 {
288 
289  ExecConditionalAssignProjectionInfo(&node->ps, tupdesc, varno);
290 }
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1381
PlanState ps
Definition: execnodes.h:1378
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:124
void ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, int varno)
Definition: execUtils.c:555

◆ ExecAssignScanType()

void ExecAssignScanType ( ScanState scanstate,
TupleDesc  tupDesc 
)

Definition at line 670 of file execUtils.c.

References ExecSetSlotDescriptor(), and ScanState::ss_ScanTupleSlot.

Referenced by ExecWorkTableScan().

671 {
672  TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
673 
674  ExecSetSlotDescriptor(slot, tupDesc);
675 }
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1381
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:1289

◆ ExecBuildAggTrans()

ExprState* ExecBuildAggTrans ( AggState aggstate,
struct AggStatePerPhaseData phase,
bool  doSort,
bool  doHash,
bool  nullcheck 
)

Referenced by ExecProcNode().

◆ ExecBuildAuxRowMark()

ExecAuxRowMark* ExecBuildAuxRowMark ( ExecRowMark erm,
List targetlist 
)

Definition at line 2289 of file execMain.c.

References AttributeNumberIsValid, ExecAuxRowMark::ctidAttNo, elog, ERROR, ExecFindJunkAttributeInTlist(), ExecRowMark::markType, palloc0(), ExecRowMark::prti, ROW_MARK_COPY, ExecAuxRowMark::rowmark, ExecRowMark::rowmarkId, ExecRowMark::rti, snprintf, ExecAuxRowMark::toidAttNo, and ExecAuxRowMark::wholeAttNo.

Referenced by ExecGetJunkAttribute(), ExecInitLockRows(), and ExecInitModifyTable().

2290 {
2291  ExecAuxRowMark *aerm = (ExecAuxRowMark *) palloc0(sizeof(ExecAuxRowMark));
2292  char resname[32];
2293 
2294  aerm->rowmark = erm;
2295 
2296  /* Look up the resjunk columns associated with this rowmark */
2297  if (erm->markType != ROW_MARK_COPY)
2298  {
2299  /* need ctid for all methods other than COPY */
2300  snprintf(resname, sizeof(resname), "ctid%u", erm->rowmarkId);
2301  aerm->ctidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2302  resname);
2303  if (!AttributeNumberIsValid(aerm->ctidAttNo))
2304  elog(ERROR, "could not find junk %s column", resname);
2305  }
2306  else
2307  {
2308  /* need wholerow if COPY */
2309  snprintf(resname, sizeof(resname), "wholerow%u", erm->rowmarkId);
2310  aerm->wholeAttNo = ExecFindJunkAttributeInTlist(targetlist,
2311  resname);
2312  if (!AttributeNumberIsValid(aerm->wholeAttNo))
2313  elog(ERROR, "could not find junk %s column", resname);
2314  }
2315 
2316  /* if child rel, need tableoid */
2317  if (erm->rti != erm->prti)
2318  {
2319  snprintf(resname, sizeof(resname), "tableoid%u", erm->rowmarkId);
2320  aerm->toidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2321  resname);
2322  if (!AttributeNumberIsValid(aerm->toidAttNo))
2323  elog(ERROR, "could not find junk %s column", resname);
2324  }
2325 
2326  return aerm;
2327 }
AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
Definition: execJunk.c:222
ExecRowMark * rowmark
Definition: execnodes.h:697
#define ERROR
Definition: elog.h:46
Index rti
Definition: execnodes.h:675
AttrNumber wholeAttNo
Definition: execnodes.h:700
Index prti
Definition: execnodes.h:676
Index rowmarkId
Definition: execnodes.h:677
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
void * palloc0(Size size)
Definition: mcxt.c:1093
RowMarkType markType
Definition: execnodes.h:678
AttrNumber toidAttNo
Definition: execnodes.h:699
#define elog(elevel,...)
Definition: elog.h:232
#define snprintf
Definition: port.h:217
AttrNumber ctidAttNo
Definition: execnodes.h:698

◆ ExecBuildGroupingEqual()

ExprState* ExecBuildGroupingEqual ( TupleDesc  ldesc,
TupleDesc  rdesc,
const TupleTableSlotOps lops,
const TupleTableSlotOps rops,
int  numCols,
const AttrNumber keyColIdx,
const Oid eqfunctions,
const Oid collations,
PlanState parent 
)

Definition at line 3708 of file execExpr.c.

References ACL_EXECUTE, aclcheck_error(), ACLCHECK_OK, FunctionCallInfoBaseData::args, Assert, ExprEvalStep::d, EEO_FLAG_IS_QUAL, EEOP_DONE, EEOP_INNER_FETCHSOME, EEOP_INNER_VAR, EEOP_NOT_DISTINCT, EEOP_OUTER_FETCHSOME, EEOP_OUTER_VAR, EEOP_QUAL, ExecComputeSlotInfo(), ExecReadyExpr(), ExprState::expr, ExprEvalPushStep(), ExprEvalStep::fetch, ExprState::flags, fmgr_info(), fmgr_info_set_expr, FmgrInfo::fn_addr, ExprEvalStep::func, get_func_name(), GetUserId(), InitFunctionCallInfoData, InvokeFunctionExecuteHook, NullableDatum::isnull, lappend_int(), lfirst_int, makeNode, NIL, OBJECT_FUNCTION, ExprEvalStep::opcode, palloc0(), ExprState::parent, pg_proc_aclcheck(), ExprEvalStep::qualexpr, ExprState::resnull, ExprEvalStep::resnull, ExprState::resvalue, ExprEvalStep::resvalue, SizeForFunctionCallInfo, ExprState::steps, ExprState::steps_len, TupleDescAttr, NullableDatum::value, and ExprEvalStep::var.

Referenced by BuildTupleHashTableExt(), ExecInitSubPlan(), ExecProcNode(), and execTuplesMatchPrepare().

3715 {
3717  ExprEvalStep scratch = {0};
3718  int maxatt = -1;
3719  List *adjust_jumps = NIL;
3720  ListCell *lc;
3721 
3722  /*
3723  * When no columns are actually compared, the result's always true. See
3724  * special case in ExecQual().
3725  */
3726  if (numCols == 0)
3727  return NULL;
3728 
3729  state->expr = NULL;
3730  state->flags = EEO_FLAG_IS_QUAL;
3731  state->parent = parent;
3732 
3733  scratch.resvalue = &state->resvalue;
3734  scratch.resnull = &state->resnull;
3735 
3736  /* compute max needed attribute */
3737  for (int natt = 0; natt < numCols; natt++)
3738  {
3739  int attno = keyColIdx[natt];
3740 
3741  if (attno > maxatt)
3742  maxatt = attno;
3743  }
3744  Assert(maxatt >= 0);
3745 
3746  /* push deform steps */
3747  scratch.opcode = EEOP_INNER_FETCHSOME;
3748  scratch.d.fetch.last_var = maxatt;
3749  scratch.d.fetch.fixed = false;
3750  scratch.d.fetch.known_desc = ldesc;
3751  scratch.d.fetch.kind = lops;
3752  if (ExecComputeSlotInfo(state, &scratch))
3753  ExprEvalPushStep(state, &scratch);
3754 
3755  scratch.opcode = EEOP_OUTER_FETCHSOME;
3756  scratch.d.fetch.last_var = maxatt;
3757  scratch.d.fetch.fixed = false;
3758  scratch.d.fetch.known_desc = rdesc;
3759  scratch.d.fetch.kind = rops;
3760  if (ExecComputeSlotInfo(state, &scratch))
3761  ExprEvalPushStep(state, &scratch);
3762 
3763  /*
3764  * Start comparing at the last field (least significant sort key). That's
3765  * the most likely to be different if we are dealing with sorted input.
3766  */
3767  for (int natt = numCols; --natt >= 0;)
3768  {
3769  int attno = keyColIdx[natt];
3770  Form_pg_attribute latt = TupleDescAttr(ldesc, attno - 1);
3771  Form_pg_attribute ratt = TupleDescAttr(rdesc, attno - 1);
3772  Oid foid = eqfunctions[natt];
3773  Oid collid = collations[natt];
3774  FmgrInfo *finfo;
3775  FunctionCallInfo fcinfo;
3776  AclResult aclresult;
3777 
3778  /* Check permission to call function */
3779  aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
3780  if (aclresult != ACLCHECK_OK)
3781  aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid));
3782 
3784 
3785  /* Set up the primary fmgr lookup information */
3786  finfo = palloc0(sizeof(FmgrInfo));
3787  fcinfo = palloc0(SizeForFunctionCallInfo(2));
3788  fmgr_info(foid, finfo);
3789  fmgr_info_set_expr(NULL, finfo);
3790  InitFunctionCallInfoData(*fcinfo, finfo, 2,
3791  collid, NULL, NULL);
3792 
3793  /* left arg */
3794  scratch.opcode = EEOP_INNER_VAR;
3795  scratch.d.var.attnum = attno - 1;
3796  scratch.d.var.vartype = latt->atttypid;
3797  scratch.resvalue = &fcinfo->args[0].value;
3798  scratch.resnull = &fcinfo->args[0].isnull;
3799  ExprEvalPushStep(state, &scratch);
3800 
3801  /* right arg */
3802  scratch.opcode = EEOP_OUTER_VAR;
3803  scratch.d.var.attnum = attno - 1;
3804  scratch.d.var.vartype = ratt->atttypid;
3805  scratch.resvalue = &fcinfo->args[1].value;
3806  scratch.resnull = &fcinfo->args[1].isnull;
3807  ExprEvalPushStep(state, &scratch);
3808 
3809  /* evaluate distinctness */
3810  scratch.opcode = EEOP_NOT_DISTINCT;
3811  scratch.d.func.finfo = finfo;
3812  scratch.d.func.fcinfo_data = fcinfo;
3813  scratch.d.func.fn_addr = finfo->fn_addr;
3814  scratch.d.func.nargs = 2;
3815  scratch.resvalue = &state->resvalue;
3816  scratch.resnull = &state->resnull;
3817  ExprEvalPushStep(state, &scratch);
3818 
3819  /* then emit EEOP_QUAL to detect if result is false (or null) */
3820  scratch.opcode = EEOP_QUAL;
3821  scratch.d.qualexpr.jumpdone = -1;
3822  scratch.resvalue = &state->resvalue;
3823  scratch.resnull = &state->resnull;
3824  ExprEvalPushStep(state, &scratch);
3825  adjust_jumps = lappend_int(adjust_jumps,
3826  state->steps_len - 1);
3827  }
3828 
3829  /* adjust jump targets */
3830  foreach(lc, adjust_jumps)
3831  {
3832  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
3833 
3834  Assert(as->opcode == EEOP_QUAL);
3835  Assert(as->d.qualexpr.jumpdone == -1);
3836  as->d.qualexpr.jumpdone = state->steps_len;
3837  }
3838 
3839  scratch.resvalue = NULL;
3840  scratch.resnull = NULL;
3841  scratch.opcode = EEOP_DONE;
3842  ExprEvalPushStep(state, &scratch);
3843 
3844  ExecReadyExpr(state);
3845 
3846  return state;
3847 }
#define NIL
Definition: pg_list.h:65
Definition: fmgr.h:56
struct PlanState * parent
Definition: execnodes.h:109
Datum * resvalue
Definition: execExpr.h:273
struct ExprEvalStep::@49::@50 fetch
Oid GetUserId(void)
Definition: miscinit.c:495
PGFunction fn_addr
Definition: fmgr.h:58
struct ExprEvalStep * steps
Definition: execnodes.h:86
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
struct ExprEvalStep::@49::@58 qualexpr
#define SizeForFunctionCallInfo(nargs)
Definition: fmgr.h:102
bool * resnull
Definition: execExpr.h:274
unsigned int Oid
Definition: postgres_ext.h:31
struct ExprEvalStep::@49::@51 var
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3308
bool resnull
Definition: execnodes.h:73
union ExprEvalStep::@49 d
Expr * expr
Definition: execnodes.h:95
#define lfirst_int(lc)
Definition: pg_list.h:170
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1579
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition: fmgr.h:95
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:126
#define EEO_FLAG_IS_QUAL
Definition: execnodes.h:60
#define fmgr_info_set_expr(expr, finfo)
Definition: fmgr.h:135
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
Datum value
Definition: postgres.h:422
List * lappend_int(List *list, int datum)
Definition: list.c:354
#define InvokeFunctionExecuteHook(objectId)
Definition: objectaccess.h:191
void * palloc0(Size size)
Definition: mcxt.c:1093
AclResult
Definition: acl.h:177
static bool ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op)
Definition: execExpr.c:2692
void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2445
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:883
struct ExprEvalStep::@49::@56 func
#define makeNode(_type_)
Definition: nodes.h:584
#define Assert(condition)
Definition: c.h:804
Definition: regguts.h:317
intptr_t opcode
Definition: execExpr.h:270
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:150
int steps_len
Definition: execnodes.h:105
#define ACL_EXECUTE
Definition: parsenodes.h:89
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4718
uint8 flags
Definition: execnodes.h:66
Definition: pg_list.h:50
Datum resvalue
Definition: execnodes.h:75

◆ ExecBuildParamSetEqual()

ExprState* ExecBuildParamSetEqual ( TupleDesc  desc,
const TupleTableSlotOps lops,
const TupleTableSlotOps rops,
const Oid eqfunctions,
const Oid collations,
const List param_exprs,
PlanState parent 
)

Definition at line 3865 of file execExpr.c.

References ACL_EXECUTE, aclcheck_error(), ACLCHECK_OK, FunctionCallInfoBaseData::args, Assert, ExprEvalStep::d, EEO_FLAG_IS_QUAL, EEOP_DONE, EEOP_INNER_FETCHSOME, EEOP_INNER_VAR, EEOP_NOT_DISTINCT, EEOP_OUTER_FETCHSOME, EEOP_OUTER_VAR, EEOP_QUAL, ExecComputeSlotInfo(), ExecReadyExpr(), ExprState::expr, ExprEvalPushStep(), ExprEvalStep::fetch, ExprState::flags, fmgr_info(), fmgr_info_set_expr, FmgrInfo::fn_addr, ExprEvalStep::func, get_func_name(), GetUserId(), InitFunctionCallInfoData, InvokeFunctionExecuteHook, NullableDatum::isnull, lappend_int(), lfirst_int, list_length(), makeNode, NIL, OBJECT_FUNCTION, ExprEvalStep::opcode, palloc0(), ExprState::parent, pg_proc_aclcheck(), ExprEvalStep::qualexpr, ExprState::resnull, ExprEvalStep::resnull, ExprState::resvalue, ExprEvalStep::resvalue, SizeForFunctionCallInfo, ExprState::steps, ExprState::steps_len, TupleDescAttr, NullableDatum::value, and ExprEvalStep::var.

Referenced by ExecInitMemoize(), and ExecProcNode().

3872 {
3874  ExprEvalStep scratch = {0};
3875  int maxatt = list_length(param_exprs);
3876  List *adjust_jumps = NIL;
3877  ListCell *lc;
3878 
3879  state->expr = NULL;
3880  state->flags = EEO_FLAG_IS_QUAL;
3881  state->parent = parent;
3882 
3883  scratch.resvalue = &state->resvalue;
3884  scratch.resnull = &state->resnull;
3885 
3886  /* push deform steps */
3887  scratch.opcode = EEOP_INNER_FETCHSOME;
3888  scratch.d.fetch.last_var = maxatt;
3889  scratch.d.fetch.fixed = false;
3890  scratch.d.fetch.known_desc = desc;
3891  scratch.d.fetch.kind = lops;
3892  if (ExecComputeSlotInfo(state, &scratch))
3893  ExprEvalPushStep(state, &scratch);
3894 
3895  scratch.opcode = EEOP_OUTER_FETCHSOME;
3896  scratch.d.fetch.last_var = maxatt;
3897  scratch.d.fetch.fixed = false;
3898  scratch.d.fetch.known_desc = desc;
3899  scratch.d.fetch.kind = rops;
3900  if (ExecComputeSlotInfo(state, &scratch))
3901  ExprEvalPushStep(state, &scratch);
3902 
3903  for (int attno = 0; attno < maxatt; attno++)
3904  {
3905  Form_pg_attribute att = TupleDescAttr(desc, attno);
3906  Oid foid = eqfunctions[attno];
3907  Oid collid = collations[attno];
3908  FmgrInfo *finfo;
3909  FunctionCallInfo fcinfo;
3910  AclResult aclresult;
3911 
3912  /* Check permission to call function */
3913  aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
3914  if (aclresult != ACLCHECK_OK)
3915  aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid));
3916 
3918 
3919  /* Set up the primary fmgr lookup information */
3920  finfo = palloc0(sizeof(FmgrInfo));
3921  fcinfo = palloc0(SizeForFunctionCallInfo(2));
3922  fmgr_info(foid, finfo);
3923  fmgr_info_set_expr(NULL, finfo);
3924  InitFunctionCallInfoData(*fcinfo, finfo, 2,
3925  collid, NULL, NULL);
3926 
3927  /* left arg */
3928  scratch.opcode = EEOP_INNER_VAR;
3929  scratch.d.var.attnum = attno;
3930  scratch.d.var.vartype = att->atttypid;
3931  scratch.resvalue = &fcinfo->args[0].value;
3932  scratch.resnull = &fcinfo->args[0].isnull;
3933  ExprEvalPushStep(state, &scratch);
3934 
3935  /* right arg */
3936  scratch.opcode = EEOP_OUTER_VAR;
3937  scratch.d.var.attnum = attno;
3938  scratch.d.var.vartype = att->atttypid;
3939  scratch.resvalue = &fcinfo->args[1].value;
3940  scratch.resnull = &fcinfo->args[1].isnull;
3941  ExprEvalPushStep(state, &scratch);
3942 
3943  /* evaluate distinctness */
3944  scratch.opcode = EEOP_NOT_DISTINCT;
3945  scratch.d.func.finfo = finfo;
3946  scratch.d.func.fcinfo_data = fcinfo;
3947  scratch.d.func.fn_addr = finfo->fn_addr;
3948  scratch.d.func.nargs = 2;
3949  scratch.resvalue = &state->resvalue;
3950  scratch.resnull = &state->resnull;
3951  ExprEvalPushStep(state, &scratch);
3952 
3953  /* then emit EEOP_QUAL to detect if result is false (or null) */
3954  scratch.opcode = EEOP_QUAL;
3955  scratch.d.qualexpr.jumpdone = -1;
3956  scratch.resvalue = &state->resvalue;
3957  scratch.resnull = &state->resnull;
3958  ExprEvalPushStep(state, &scratch);
3959  adjust_jumps = lappend_int(adjust_jumps,
3960  state->steps_len - 1);
3961  }
3962 
3963  /* adjust jump targets */
3964  foreach(lc, adjust_jumps)
3965  {
3966  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
3967 
3968  Assert(as->opcode == EEOP_QUAL);
3969  Assert(as->d.qualexpr.jumpdone == -1);
3970  as->d.qualexpr.jumpdone = state->steps_len;
3971  }
3972 
3973  scratch.resvalue = NULL;
3974  scratch.resnull = NULL;
3975  scratch.opcode = EEOP_DONE;
3976  ExprEvalPushStep(state, &scratch);
3977 
3978  ExecReadyExpr(state);
3979 
3980  return state;
3981 }
#define NIL
Definition: pg_list.h:65
Definition: fmgr.h:56
struct PlanState * parent
Definition: execnodes.h:109
Datum * resvalue
Definition: execExpr.h:273
struct ExprEvalStep::@49::@50 fetch
Oid GetUserId(void)
Definition: miscinit.c:495
PGFunction fn_addr
Definition: fmgr.h:58
struct ExprEvalStep * steps
Definition: execnodes.h:86
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
struct ExprEvalStep::@49::@58 qualexpr
#define SizeForFunctionCallInfo(nargs)
Definition: fmgr.h:102
bool * resnull
Definition: execExpr.h:274
unsigned int Oid
Definition: postgres_ext.h:31
struct ExprEvalStep::@49::@51 var
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3308
bool resnull
Definition: execnodes.h:73
union ExprEvalStep::@49 d
Expr * expr
Definition: execnodes.h:95
#define lfirst_int(lc)
Definition: pg_list.h:170
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1579
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition: fmgr.h:95
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:126
#define EEO_FLAG_IS_QUAL
Definition: execnodes.h:60
#define fmgr_info_set_expr(expr, finfo)
Definition: fmgr.h:135
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
Datum value
Definition: postgres.h:422
List * lappend_int(List *list, int datum)
Definition: list.c:354
#define InvokeFunctionExecuteHook(objectId)
Definition: objectaccess.h:191
void * palloc0(Size size)
Definition: mcxt.c:1093
AclResult
Definition: acl.h:177
static bool ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op)
Definition: execExpr.c:2692
void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2445
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:883
struct ExprEvalStep::@49::@56 func
#define makeNode(_type_)
Definition: nodes.h:584
#define Assert(condition)
Definition: c.h:804
Definition: regguts.h:317
intptr_t opcode
Definition: execExpr.h:270
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:150
static int list_length(const List *l)
Definition: pg_list.h:149
int steps_len
Definition: execnodes.h:105
#define ACL_EXECUTE
Definition: parsenodes.h:89
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4718
uint8 flags
Definition: execnodes.h:66
Definition: pg_list.h:50
Datum resvalue
Definition: execnodes.h:75

◆ ExecBuildProjectionInfo()

ProjectionInfo* ExecBuildProjectionInfo ( List targetList,
ExprContext econtext,
TupleTableSlot slot,
PlanState parent,
TupleDesc  inputDesc 
)

Definition at line 353 of file execExpr.c.

References ExprEvalStep::assign_tmp, ExprEvalStep::assign_var, attnum, ExprEvalStep::d, EEOP_ASSIGN_INNER_VAR, EEOP_ASSIGN_OUTER_VAR, EEOP_ASSIGN_SCAN_VAR, EEOP_ASSIGN_TMP, EEOP_ASSIGN_TMP_MAKE_RO, EEOP_DONE, ExecInitExprRec(), ExecInitExprSlots(), ExecReadyExpr(), ExprState::expr, TargetEntry::expr, ExprEvalPushStep(), exprType(), ExprState::ext_params, get_typlen(), INNER_VAR, IsA, lfirst_node, makeNode, ExprEvalStep::opcode, OUTER_VAR, ExprState::parent, ProjectionInfo::pi_exprContext, ProjectionInfo::pi_state, TargetEntry::resno, ExprState::resnull, ExprState::resultslot, ExprState::resvalue, T_ExprState, TupleDescAttr, ExprState::type, Var::varattno, Var::varno, and Var::vartype.

Referenced by ExecAssignProjectionInfo(), ExecInitInsertProjection(), ExecInitModifyTable(), ExecInitPartitionInfo(), ExecInitSubPlan(), and ExecProcNode().

358 {
360  ExprState *state;
361  ExprEvalStep scratch = {0};
362  ListCell *lc;
363 
364  projInfo->pi_exprContext = econtext;
365  /* We embed ExprState into ProjectionInfo instead of doing extra palloc */
366  projInfo->pi_state.type = T_ExprState;
367  state = &projInfo->pi_state;
368  state->expr = (Expr *) targetList;
369  state->parent = parent;
370  state->ext_params = NULL;
371 
372  state->resultslot = slot;
373 
374  /* Insert EEOP_*_FETCHSOME steps as needed */
375  ExecInitExprSlots(state, (Node *) targetList);
376 
377  /* Now compile each tlist column */
378  foreach(lc, targetList)
379  {
380  TargetEntry *tle = lfirst_node(TargetEntry, lc);
381  Var *variable = NULL;
382  AttrNumber attnum = 0;
383  bool isSafeVar = false;
384 
385  /*
386  * If tlist expression is a safe non-system Var, use the fast-path
387  * ASSIGN_*_VAR opcodes. "Safe" means that we don't need to apply
388  * CheckVarSlotCompatibility() during plan startup. If a source slot
389  * was provided, we make the equivalent tests here; if a slot was not
390  * provided, we assume that no check is needed because we're dealing
391  * with a non-relation-scan-level expression.
392  */
393  if (tle->expr != NULL &&
394  IsA(tle->expr, Var) &&
395  ((Var *) tle->expr)->varattno > 0)
396  {
397  /* Non-system Var, but how safe is it? */
398  variable = (Var *) tle->expr;
399  attnum = variable->varattno;
400 
401  if (inputDesc == NULL)
402  isSafeVar = true; /* can't check, just assume OK */
403  else if (attnum <= inputDesc->natts)
404  {
405  Form_pg_attribute attr = TupleDescAttr(inputDesc, attnum - 1);
406 
407  /*
408  * If user attribute is dropped or has a type mismatch, don't
409  * use ASSIGN_*_VAR. Instead let the normal expression
410  * machinery handle it (which'll possibly error out).
411  */
412  if (!attr->attisdropped && variable->vartype == attr->atttypid)
413  {
414  isSafeVar = true;
415  }
416  }
417  }
418 
419  if (isSafeVar)
420  {
421  /* Fast-path: just generate an EEOP_ASSIGN_*_VAR step */
422  switch (variable->varno)
423  {
424  case INNER_VAR:
425  /* get the tuple from the inner node */
426  scratch.opcode = EEOP_ASSIGN_INNER_VAR;
427  break;
428 
429  case OUTER_VAR:
430  /* get the tuple from the outer node */
431  scratch.opcode = EEOP_ASSIGN_OUTER_VAR;
432  break;
433 
434  /* INDEX_VAR is handled by default case */
435 
436  default:
437  /* get the tuple from the relation being scanned */
438  scratch.opcode = EEOP_ASSIGN_SCAN_VAR;
439  break;
440  }
441 
442  scratch.d.assign_var.attnum = attnum - 1;
443  scratch.d.assign_var.resultnum = tle->resno - 1;
444  ExprEvalPushStep(state, &scratch);
445  }
446  else
447  {
448  /*
449  * Otherwise, compile the column expression normally.
450  *
451  * We can't tell the expression to evaluate directly into the
452  * result slot, as the result slot (and the exprstate for that
453  * matter) can change between executions. We instead evaluate
454  * into the ExprState's resvalue/resnull and then move.
455  */
456  ExecInitExprRec(tle->expr, state,
457  &state->resvalue, &state->resnull);
458 
459  /*
460  * Column might be referenced multiple times in upper nodes, so
461  * force value to R/O - but only if it could be an expanded datum.
462  */
463  if (get_typlen(exprType((Node *) tle->expr)) == -1)
465  else
466  scratch.opcode = EEOP_ASSIGN_TMP;
467  scratch.d.assign_tmp.resultnum = tle->resno - 1;
468  ExprEvalPushStep(state, &scratch);
469  }
470  }
471 
472  scratch.opcode = EEOP_DONE;
473  ExprEvalPushStep(state, &scratch);
474 
475  ExecReadyExpr(state);
476 
477  return projInfo;
478 }
int varno
Definition: primnodes.h:189
#define IsA(nodeptr, _type_)
Definition: nodes.h:587
struct PlanState * parent
Definition: execnodes.h:109
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
ParamListInfo ext_params
Definition: execnodes.h:110
Definition: nodes.h:536
AttrNumber varattno
Definition: primnodes.h:191
TupleTableSlot * resultslot
Definition: execnodes.h:81
Definition: primnodes.h:186
bool resnull
Definition: execnodes.h:73
union ExprEvalStep::@49 d
Expr * expr
Definition: execnodes.h:95
Oid vartype
Definition: primnodes.h:193
static void ExecInitExprSlots(ExprState *state, Node *node)
Definition: execExpr.c:2576
#define lfirst_node(type, lc)
Definition: pg_list.h:172
AttrNumber resno
Definition: primnodes.h:1456
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
NodeTag type
Definition: execnodes.h:64
static void ExecInitExprRec(Expr *node, ExprState *state, Datum *resv, bool *resnull)
Definition: execExpr.c:900
struct ExprEvalStep::@49::@53 assign_var
void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2445
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:883
int16 attnum
Definition: pg_attribute.h:83
#define INNER_VAR
Definition: primnodes.h:175
#define makeNode(_type_)
Definition: nodes.h:584
Definition: regguts.h:317
intptr_t opcode
Definition: execExpr.h:270
Expr * expr
Definition: primnodes.h:1455
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
int16 get_typlen(Oid typid)
Definition: lsyscache.c:2144
ExprState pi_state
Definition: execnodes.h:334
struct ExprEvalStep::@49::@54 assign_tmp
ExprContext * pi_exprContext
Definition: execnodes.h:336
Datum resvalue
Definition: execnodes.h:75
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:176

◆ ExecBuildUpdateProjection()

ProjectionInfo* ExecBuildUpdateProjection ( List targetList,
bool  evalTargetList,
List targetColnos,
TupleDesc  relDesc,
ExprContext econtext,
TupleTableSlot slot,
PlanState parent 
)

Definition at line 513 of file execExpr.c.

References Assert, ExprEvalStep::assign_tmp, ExprEvalStep::assign_var, attnum, bms_add_member(), bms_is_member(), ExprEvalStep::constval, ExprEvalStep::d, EEOP_ASSIGN_OUTER_VAR, EEOP_ASSIGN_SCAN_VAR, EEOP_ASSIGN_TMP, EEOP_CONST, EEOP_DONE, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, ExecInitExprRec(), ExecPushExprSlots(), ExecReadyExpr(), ExprState::expr, TargetEntry::expr, ExprEvalPushStep(), exprType(), ExprState::ext_params, for_each_cell, forboth, format_type_be(), get_last_attnums_walker(), LastAttnumInfo::last_outer, LastAttnumInfo::last_scan, lfirst_int, lfirst_node, list_length(), makeNode, TupleDescData::natts, ExprEvalStep::opcode, ExprState::parent, ProjectionInfo::pi_exprContext, ProjectionInfo::pi_state, TargetEntry::resjunk, ExprState::resnull, ExprEvalStep::resnull, ExprState::resultslot, ExprState::resvalue, ExprEvalStep::resvalue, T_ExprState, TupleDescAttr, and ExprState::type.

Referenced by ExecInitModifyTable(), ExecInitPartitionInfo(), ExecInitUpdateProjection(), and ExecProcNode().

520 {
522  ExprState *state;
523  int nAssignableCols;
524  bool sawJunk;
525  Bitmapset *assignedCols;
526  LastAttnumInfo deform = {0, 0, 0};
527  ExprEvalStep scratch = {0};
528  int outerattnum;
529  ListCell *lc,
530  *lc2;
531 
532  projInfo->pi_exprContext = econtext;
533  /* We embed ExprState into ProjectionInfo instead of doing extra palloc */
534  projInfo->pi_state.type = T_ExprState;
535  state = &projInfo->pi_state;
536  if (evalTargetList)
537  state->expr = (Expr *) targetList;
538  else
539  state->expr = NULL; /* not used */
540  state->parent = parent;
541  state->ext_params = NULL;
542 
543  state->resultslot = slot;
544 
545  /*
546  * Examine the targetList to see how many non-junk columns there are, and
547  * to verify that the non-junk columns come before the junk ones.
548  */
549  nAssignableCols = 0;
550  sawJunk = false;
551  foreach(lc, targetList)
552  {
553  TargetEntry *tle = lfirst_node(TargetEntry, lc);
554 
555  if (tle->resjunk)
556  sawJunk = true;
557  else
558  {
559  if (sawJunk)
560  elog(ERROR, "subplan target list is out of order");
561  nAssignableCols++;
562  }
563  }
564 
565  /* We should have one targetColnos entry per non-junk column */
566  if (nAssignableCols != list_length(targetColnos))
567  elog(ERROR, "targetColnos does not match subplan target list");
568 
569  /*
570  * Build a bitmapset of the columns in targetColnos. (We could just use
571  * list_member_int() tests, but that risks O(N^2) behavior with many
572  * columns.)
573  */
574  assignedCols = NULL;
575  foreach(lc, targetColnos)
576  {
577  AttrNumber targetattnum = lfirst_int(lc);
578 
579  assignedCols = bms_add_member(assignedCols, targetattnum);
580  }
581 
582  /*
583  * We need to insert EEOP_*_FETCHSOME steps to ensure the input tuples are
584  * sufficiently deconstructed. The scan tuple must be deconstructed at
585  * least as far as the last old column we need.
586  */
587  for (int attnum = relDesc->natts; attnum > 0; attnum--)
588  {
589  Form_pg_attribute attr = TupleDescAttr(relDesc, attnum - 1);
590 
591  if (attr->attisdropped)
592  continue;
593  if (bms_is_member(attnum, assignedCols))
594  continue;
595  deform.last_scan = attnum;
596  break;
597  }
598 
599  /*
600  * If we're actually evaluating the tlist, incorporate its input
601  * requirements too; otherwise, we'll just need to fetch the appropriate
602  * number of columns of the "outer" tuple.
603  */
604  if (evalTargetList)
605  get_last_attnums_walker((Node *) targetList, &deform);
606  else
607  deform.last_outer = nAssignableCols;
608 
609  ExecPushExprSlots(state, &deform);
610 
611  /*
612  * Now generate code to evaluate the tlist's assignable expressions or
613  * fetch them from the outer tuple, incidentally validating that they'll
614  * be of the right data type. The checks above ensure that the forboth()
615  * will iterate over exactly the non-junk columns.
616  */
617  outerattnum = 0;
618  forboth(lc, targetList, lc2, targetColnos)
619  {
620  TargetEntry *tle = lfirst_node(TargetEntry, lc);
621  AttrNumber targetattnum = lfirst_int(lc2);
622  Form_pg_attribute attr;
623 
624  Assert(!tle->resjunk);
625 
626  /*
627  * Apply sanity checks comparable to ExecCheckPlanOutput().
628  */
629  if (targetattnum <= 0 || targetattnum > relDesc->natts)
630  ereport(ERROR,
631  (errcode(ERRCODE_DATATYPE_MISMATCH),
632  errmsg("table row type and query-specified row type do not match"),
633  errdetail("Query has too many columns.")));
634  attr = TupleDescAttr(relDesc, targetattnum - 1);
635 
636  if (attr->attisdropped)
637  ereport(ERROR,
638  (errcode(ERRCODE_DATATYPE_MISMATCH),
639  errmsg("table row type and query-specified row type do not match"),
640  errdetail("Query provides a value for a dropped column at ordinal position %d.",
641  targetattnum)));
642  if (exprType((Node *) tle->expr) != attr->atttypid)
643  ereport(ERROR,
644  (errcode(ERRCODE_DATATYPE_MISMATCH),
645  errmsg("table row type and query-specified row type do not match"),
646  errdetail("Table has type %s at ordinal position %d, but query expects %s.",
647  format_type_be(attr->atttypid),
648  targetattnum,
649  format_type_be(exprType((Node *) tle->expr)))));
650 
651  /* OK, generate code to perform the assignment. */
652  if (evalTargetList)
653  {
654  /*
655  * We must evaluate the TLE's expression and assign it. We do not
656  * bother jumping through hoops for "safe" Vars like
657  * ExecBuildProjectionInfo does; this is a relatively less-used
658  * path and it doesn't seem worth expending code for that.
659  */
660  ExecInitExprRec(tle->expr, state,
661  &state->resvalue, &state->resnull);
662  /* Needn't worry about read-only-ness here, either. */
663  scratch.opcode = EEOP_ASSIGN_TMP;
664  scratch.d.assign_tmp.resultnum = targetattnum - 1;
665  ExprEvalPushStep(state, &scratch);
666  }
667  else
668  {
669  /* Just assign from the outer tuple. */
670  scratch.opcode = EEOP_ASSIGN_OUTER_VAR;
671  scratch.d.assign_var.attnum = outerattnum;
672  scratch.d.assign_var.resultnum = targetattnum - 1;
673  ExprEvalPushStep(state, &scratch);
674  }
675  outerattnum++;
676  }
677 
678  /*
679  * If we're evaluating the tlist, must evaluate any resjunk columns too.
680  * (This matters for things like MULTIEXPR_SUBLINK SubPlans.)
681  */
682  if (evalTargetList)
683  {
684  for_each_cell(lc, targetList, lc)
685  {
686  TargetEntry *tle = lfirst_node(TargetEntry, lc);
687 
688  Assert(tle->resjunk);
689  ExecInitExprRec(tle->expr, state,
690  &state->resvalue, &state->resnull);
691  }
692  }
693 
694  /*
695  * Now generate code to copy over any old columns that were not assigned
696  * to, and to ensure that dropped columns are set to NULL.
697  */
698  for (int attnum = 1; attnum <= relDesc->natts; attnum++)
699  {
700  Form_pg_attribute attr = TupleDescAttr(relDesc, attnum - 1);
701 
702  if (attr->attisdropped)
703  {
704  /* Put a null into the ExprState's resvalue/resnull ... */
705  scratch.opcode = EEOP_CONST;
706  scratch.resvalue = &state->resvalue;
707  scratch.resnull = &state->resnull;
708  scratch.d.constval.value = (Datum) 0;
709  scratch.d.constval.isnull = true;
710  ExprEvalPushStep(state, &scratch);
711  /* ... then assign it to the result slot */
712  scratch.opcode = EEOP_ASSIGN_TMP;
713  scratch.d.assign_tmp.resultnum = attnum - 1;
714  ExprEvalPushStep(state, &scratch);
715  }
716  else if (!bms_is_member(attnum, assignedCols))
717  {
718  /* Certainly the right type, so needn't check */
719  scratch.opcode = EEOP_ASSIGN_SCAN_VAR;
720  scratch.d.assign_var.attnum = attnum - 1;
721  scratch.d.assign_var.resultnum = attnum - 1;
722  ExprEvalPushStep(state, &scratch);
723  }
724  }
725 
726  scratch.opcode = EEOP_DONE;
727  ExprEvalPushStep(state, &scratch);
728 
729  ExecReadyExpr(state);
730 
731  return projInfo;
732 }
struct PlanState * parent
Definition: execnodes.h:109
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:446
Datum * resvalue
Definition: execExpr.h:273
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define for_each_cell(cell, lst, initcell)
Definition: pg_list.h:417
bool * resnull
Definition: execExpr.h:274
ParamListInfo ext_params
Definition: execnodes.h:110
Definition: nodes.h:536
int errcode(int sqlerrcode)
Definition: elog.c:698
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
TupleTableSlot * resultslot
Definition: execnodes.h:81
bool resjunk
Definition: primnodes.h:1462
#define ERROR
Definition: elog.h:46
bool resnull
Definition: execnodes.h:73
union ExprEvalStep::@49 d
Expr * expr
Definition: execnodes.h:95
#define lfirst_int(lc)
Definition: pg_list.h:170
#define lfirst_node(type, lc)
Definition: pg_list.h:172
struct ExprEvalStep::@49::@55 constval
AttrNumber last_scan
Definition: execExpr.c:58
int errdetail(const char *fmt,...)
Definition: elog.c:1042
AttrNumber last_outer
Definition: execExpr.c:57
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
NodeTag type
Definition: execnodes.h:64
static void ExecPushExprSlots(ExprState *state, LastAttnumInfo *info)
Definition: execExpr.c:2594
static void ExecInitExprRec(Expr *node, ExprState *state, Datum *resv, bool *resnull)
Definition: execExpr.c:900
struct ExprEvalStep::@49::@53 assign_var
uintptr_t Datum
Definition: postgres.h:411
void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2445
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:883
int16 attnum
Definition: pg_attribute.h:83
#define ereport(elevel,...)
Definition: elog.h:157
#define makeNode(_type_)
Definition: nodes.h:584
#define Assert(condition)
Definition: c.h:804
Definition: regguts.h:317
intptr_t opcode
Definition: execExpr.h:270
Expr * expr
Definition: primnodes.h:1455
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
static int list_length(const List *l)
Definition: pg_list.h:149
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
static bool get_last_attnums_walker(Node *node, LastAttnumInfo *info)
Definition: execExpr.c:2638
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
ExprState pi_state
Definition: execnodes.h:334
struct ExprEvalStep::@49::@54 assign_tmp
ExprContext * pi_exprContext
Definition: execnodes.h:336
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:427
Datum resvalue
Definition: execnodes.h:75
int16 AttrNumber
Definition: attnum.h:21

◆ ExecCheck()

bool ExecCheck ( ExprState state,
ExprContext context 
)

Definition at line 853 of file execExpr.c.

References Assert, DatumGetBool, EEO_FLAG_IS_QUAL, ExecEvalExprSwitchContext(), and ExprState::flags.

Referenced by ATRewriteTable(), check_default_partition_contents(), domain_check_input(), ExecPartitionCheck(), ExecQualAndReset(), and ExecRelCheck().

854 {
855  Datum ret;
856  bool isnull;
857 
858  /* short-circuit (here and in ExecInitCheck) for empty restriction list */
859  if (state == NULL)
860  return true;
861 
862  /* verify that expression was not compiled using ExecInitQual */
863  Assert(!(state->flags & EEO_FLAG_IS_QUAL));
864 
865  ret = ExecEvalExprSwitchContext(state, econtext, &isnull);
866 
867  if (isnull)
868  return true;
869 
870  return DatumGetBool(ret);
871 }
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:331
#define EEO_FLAG_IS_QUAL
Definition: execnodes.h:60
#define DatumGetBool(X)
Definition: postgres.h:437
uintptr_t Datum
Definition: postgres.h:411
#define Assert(condition)
Definition: c.h:804
uint8 flags
Definition: execnodes.h:66

◆ ExecCheckIndexConstraints()

bool ExecCheckIndexConstraints ( ResultRelInfo resultRelInfo,
TupleTableSlot slot,
EState estate,
ItemPointer  conflictTid,
List arbiterIndexes 
)

Definition at line 505 of file execIndexing.c.

References CEOUC_WAIT, check_exclusion_or_unique_constraint(), ExprContext::ecxt_scantuple, elog, ereport, errcode(), errmsg(), ERROR, errtableconstraint(), ExecPrepareQual(), ExecQual(), FormIndexDatum(), GetPerTupleExprContext, i, IndexInfo::ii_ExclusionOps, IndexInfo::ii_Predicate, IndexInfo::ii_PredicateState, IndexInfo::ii_ReadyForInserts, IndexInfo::ii_Unique, INDEX_MAX_KEYS, ExprEvalStep::isnull, ItemPointerSetInvalid, list_member_oid(), NIL, RelationData::rd_index, RelationGetRelationName, ResultRelInfo::ri_IndexRelationDescs, ResultRelInfo::ri_IndexRelationInfo, ResultRelInfo::ri_NumIndices, ResultRelInfo::ri_RelationDesc, and values.

Referenced by exec_rt_fetch(), and ExecInsert().

508 {
509  int i;
510  int numIndices;
511  RelationPtr relationDescs;
512  Relation heapRelation;
513  IndexInfo **indexInfoArray;
514  ExprContext *econtext;
516  bool isnull[INDEX_MAX_KEYS];
517  ItemPointerData invalidItemPtr;
518  bool checkedIndex = false;
519 
520  ItemPointerSetInvalid(conflictTid);
521  ItemPointerSetInvalid(&invalidItemPtr);
522 
523  /*
524  * Get information from the result relation info structure.
525  */
526  numIndices = resultRelInfo->ri_NumIndices;
527  relationDescs = resultRelInfo->ri_IndexRelationDescs;
528  indexInfoArray = resultRelInfo->ri_IndexRelationInfo;
529  heapRelation = resultRelInfo->ri_RelationDesc;
530 
531  /*
532  * We will use the EState's per-tuple context for evaluating predicates
533  * and index expressions (creating it if it's not already there).
534  */
535  econtext = GetPerTupleExprContext(estate);
536 
537  /* Arrange for econtext's scan tuple to be the tuple under test */
538  econtext->ecxt_scantuple = slot;
539 
540  /*
541  * For each index, form index tuple and check if it satisfies the
542  * constraint.
543  */
544  for (i = 0; i < numIndices; i++)
545  {
546  Relation indexRelation = relationDescs[i];
547  IndexInfo *indexInfo;
548  bool satisfiesConstraint;
549 
550  if (indexRelation == NULL)
551  continue;
552 
553  indexInfo = indexInfoArray[i];
554 
555  if (!indexInfo->ii_Unique && !indexInfo->ii_ExclusionOps)
556  continue;
557 
558  /* If the index is marked as read-only, ignore it */
559  if (!indexInfo->ii_ReadyForInserts)
560  continue;
561 
562  /* When specific arbiter indexes requested, only examine them */
563  if (arbiterIndexes != NIL &&
564  !list_member_oid(arbiterIndexes,
565  indexRelation->rd_index->indexrelid))
566  continue;
567 
568  if (!indexRelation->rd_index->indimmediate)
569  ereport(ERROR,
570  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
571  errmsg("ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters"),
572  errtableconstraint(heapRelation,
573  RelationGetRelationName(indexRelation))));
574 
575  checkedIndex = true;
576 
577  /* Check for partial index */
578  if (indexInfo->ii_Predicate != NIL)
579  {
580  ExprState *predicate;
581 
582  /*
583  * If predicate state not set up yet, create it (in the estate's
584  * per-query context)
585  */
586  predicate = indexInfo->ii_PredicateState;
587  if (predicate == NULL)
588  {
589  predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
590  indexInfo->ii_PredicateState = predicate;
591  }
592 
593  /* Skip this index-update if the predicate isn't satisfied */
594  if (!ExecQual(predicate, econtext))
595  continue;
596  }
597 
598  /*
599  * FormIndexDatum fills in its values and isnull parameters with the
600  * appropriate values for the column(s) of the index.
601  */
602  FormIndexDatum(indexInfo,
603  slot,
604  estate,
605  values,
606  isnull);
607 
608  satisfiesConstraint =
609  check_exclusion_or_unique_constraint(heapRelation, indexRelation,
610  indexInfo, &invalidItemPtr,
611  values, isnull, estate, false,
612  CEOUC_WAIT, true,
613  conflictTid);
614  if (!satisfiesConstraint)
615  return false;
616  }
617 
618  if (arbiterIndexes != NIL && !checkedIndex)
619  elog(ERROR, "unexpected failure to find arbiter index");
620 
621  return true;
622 }
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
Definition: index.c:2662
int ri_NumIndices
Definition: execnodes.h:415
#define NIL
Definition: pg_list.h:65
Relation ri_RelationDesc
Definition: execnodes.h:412
List * ii_Predicate
Definition: execnodes.h:164
ExprState * ii_PredicateState
Definition: execnodes.h:165
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:396
static bool check_exclusion_or_unique_constraint(Relation heap, Relation index, IndexInfo *indexInfo, ItemPointer tupleid, Datum *values, bool *isnull, EState *estate, bool newIndex, CEOUC_WAIT_MODE waitMode, bool errorOK, ItemPointer conflictTid)
Definition: execIndexing.c:667
#define GetPerTupleExprContext(estate)
Definition: executor.h:533
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5690
Form_pg_index rd_index
Definition: rel.h:187
#define ERROR
Definition: elog.h:46
#define RelationGetRelationName(relation)
Definition: rel.h:511
ExprState * ExecPrepareQual(List *qual, EState *estate)
Definition: execExpr.c:774
bool ii_ReadyForInserts
Definition: execnodes.h:174
uintptr_t Datum
Definition: postgres.h:411
#define ereport(elevel,...)
Definition: elog.h:157
bool ii_Unique
Definition: execnodes.h:173
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:689
#define INDEX_MAX_KEYS
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:227
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
Oid * ii_ExclusionOps
Definition: execnodes.h:166
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
IndexInfo ** ri_IndexRelationInfo
Definition: execnodes.h:421
int i
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:418

◆ ExecCheckRTPerms()

bool ExecCheckRTPerms ( List rangeTable,
bool  ereport_on_violation 
)

Definition at line 568 of file execMain.c.

References aclcheck_error(), ACLCHECK_NO_PRIV, Assert, ExecCheckRTEPerms(), ExecutorCheckPerms_hook, get_rel_name(), get_rel_relkind(), get_relkind_objtype(), lfirst, RangeTblEntry::relid, RTE_RELATION, and RangeTblEntry::rtekind.

Referenced by DoCopy(), ExecGetJunkAttribute(), InitPlan(), and RI_Initial_Check().

569 {
570  ListCell *l;
571  bool result = true;
572 
573  foreach(l, rangeTable)
574  {
575  RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
576 
577  result = ExecCheckRTEPerms(rte);
578  if (!result)
579  {
580  Assert(rte->rtekind == RTE_RELATION);
581  if (ereport_on_violation)
583  get_rel_name(rte->relid));
584  return false;
585  }
586  }
587 
589  result = (*ExecutorCheckPerms_hook) (rangeTable,
590  ereport_on_violation);
591  return result;
592 }
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1974
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3308
static bool ExecCheckRTEPerms(RangeTblEntry *rte)
Definition: execMain.c:599
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
Definition: execMain.c:77
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
RTEKind rtekind
Definition: parsenodes.h:1007
ObjectType get_relkind_objtype(char relkind)
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1899

◆ ExecCleanTargetListLength()

int ExecCleanTargetListLength ( List targetlist)

Definition at line 1147 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), exec_rt_fetch(), and ExecTypeFromTLInternal().

1148 {
1149  int len = 0;
1150  ListCell *tl;
1151 
1152  foreach(tl, targetlist)
1153  {
1154  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1155 
1156  if (!curTle->resjunk)
1157  len++;
1158  }
1159  return len;
1160 }
bool resjunk
Definition: primnodes.h:1462
#define lfirst_node(type, lc)
Definition: pg_list.h:172

◆ ExecCleanTypeFromTL()

TupleDesc ExecCleanTypeFromTL ( List targetList)

Definition at line 1950 of file execTuples.c.

References ExecTypeFromTLInternal().

Referenced by ExecInitJunkFilter(), PlanCacheComputeResultDesc(), and PortalStart().

1951 {
1952  return ExecTypeFromTLInternal(targetList, true);
1953 }
static TupleDesc ExecTypeFromTLInternal(List *targetList, bool skipjunk)
Definition: execTuples.c:1956

◆ ExecCloseIndices()

void ExecCloseIndices ( ResultRelInfo resultRelInfo)

Definition at line 231 of file execIndexing.c.

References i, index_close(), ResultRelInfo::ri_IndexRelationDescs, ResultRelInfo::ri_NumIndices, and RowExclusiveLock.

Referenced by apply_handle_delete_internal(), apply_handle_insert_internal(), apply_handle_tuple_routing(), apply_handle_update_internal(), CatalogCloseIndexes(), exec_rt_fetch(), ExecCleanupTupleRouting(), and ExecCloseResultRelations().

232 {
233  int i;
234  int numIndices;
235  RelationPtr indexDescs;
236 
237  numIndices = resultRelInfo->ri_NumIndices;
238  indexDescs = resultRelInfo->ri_IndexRelationDescs;
239 
240  for (i = 0; i < numIndices; i++)
241  {
242  if (indexDescs[i] == NULL)
243  continue; /* shouldn't happen? */
244 
245  /* Drop lock acquired by ExecOpenIndices */
246  index_close(indexDescs[i], RowExclusiveLock);
247  }
248 
249  /*
250  * XXX should free indexInfo array here too? Currently we assume that
251  * such stuff will be cleaned up automatically in FreeExecutorState.
252  */
253 }
int ri_NumIndices
Definition: execnodes.h:415
#define RowExclusiveLock
Definition: lockdefs.h:38
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:158
int i
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:418

◆ ExecCloseRangeTableRelations()

void ExecCloseRangeTableRelations ( EState estate)

Definition at line 1482 of file execMain.c.

References EState::es_range_table_size, EState::es_relations, i, NoLock, and table_close().

Referenced by CopyFrom(), and ExecEndPlan().

1483 {
1484  int i;
1485 
1486  for (i = 0; i < estate->es_range_table_size; i++)
1487  {
1488  if (estate->es_relations[i])
1489  table_close(estate->es_relations[i], NoLock);
1490  }
1491 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
#define NoLock
Definition: lockdefs.h:34
Relation * es_relations
Definition: execnodes.h:563
Index es_range_table_size
Definition: execnodes.h:562
int i

◆ ExecCloseResultRelations()

void ExecCloseResultRelations ( EState estate)

Definition at line 1439 of file execMain.c.

References Assert, EState::es_opened_result_relations, EState::es_trig_target_relations, ExecCloseIndices(), lfirst, NoLock, ResultRelInfo::ri_NumIndices, ResultRelInfo::ri_RangeTableIndex, ResultRelInfo::ri_RelationDesc, and table_close().

Referenced by afterTriggerInvokeEvents(), CopyFrom(), EvalPlanQualEnd(), and ExecEndPlan().

1440 {
1441  ListCell *l;
1442 
1443  /*
1444  * close indexes of result relation(s) if any. (Rels themselves are
1445  * closed in ExecCloseRangeTableRelations())
1446  */
1447  foreach(l, estate->es_opened_result_relations)
1448  {
1449  ResultRelInfo *resultRelInfo = lfirst(l);
1450 
1451  ExecCloseIndices(resultRelInfo);
1452  }
1453 
1454  /* Close any relations that have been opened by ExecGetTriggerResultRel(). */
1455  foreach(l, estate->es_trig_target_relations)
1456  {
1457  ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
1458 
1459  /*
1460  * Assert this is a "dummy" ResultRelInfo, see above. Otherwise we
1461  * might be issuing a duplicate close against a Relation opened by
1462  * ExecGetRangeTableRelation.
1463  */
1464  Assert(resultRelInfo->ri_RangeTableIndex == 0);
1465 
1466  /*
1467  * Since ExecGetTriggerResultRel doesn't call ExecOpenIndices for
1468  * these rels, we needn't call ExecCloseIndices either.
1469  */
1470  Assert(resultRelInfo->ri_NumIndices == 0);
1471 
1472  table_close(resultRelInfo->ri_RelationDesc, NoLock);
1473  }
1474 }
int ri_NumIndices
Definition: execnodes.h:415
Relation ri_RelationDesc
Definition: execnodes.h:412
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
Index ri_RangeTableIndex
Definition: execnodes.h:409
#define NoLock
Definition: lockdefs.h:34
List * es_opened_result_relations
Definition: execnodes.h:579
List * es_trig_target_relations
Definition: execnodes.h:592
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
Definition: execIndexing.c:231

◆ ExecConditionalAssignProjectionInfo()

void ExecConditionalAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc,
int  varno 
)

Definition at line 555 of file execUtils.c.

References ExecAssignProjectionInfo(), ExecInitResultSlot(), PlanState::plan, PlanState::ps_ProjInfo, PlanState::ps_ResultTupleSlot, PlanState::resultops, PlanState::resultopsfixed, PlanState::resultopsset, PlanState::scanops, PlanState::scanopsfixed, PlanState::scanopsset, Plan::targetlist, tlist_matches_tupdesc(), and TTSOpsVirtual.

Referenced by ExecAssignScanProjectionInfo(), ExecAssignScanProjectionInfoWithVarno(), ExecInitGather(), and ExecInitGatherMerge().

557 {
558  if (tlist_matches_tupdesc(planstate,
559  planstate->plan->targetlist,
560  varno,
561  inputDesc))
562  {
563  planstate->ps_ProjInfo = NULL;
564  planstate->resultopsset = planstate->scanopsset;
565  planstate->resultopsfixed = planstate->scanopsfixed;
566  planstate->resultops = planstate->scanops;
567  }
568  else
569  {
570  if (!planstate->ps_ResultTupleSlot)
571  {
572  ExecInitResultSlot(planstate, &TTSOpsVirtual);
573  planstate->resultops = &TTSOpsVirtual;
574  planstate->resultopsfixed = true;
575  planstate->resultopsset = true;
576  }
577  ExecAssignProjectionInfo(planstate, inputDesc);
578  }
579 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1007
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
const TupleTableSlotOps * resultops
Definition: execnodes.h:1044
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1005
const TupleTableSlotOps * scanops
Definition: execnodes.h:1041
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:535
bool resultopsset
Definition: execnodes.h:1052
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc)
Definition: execUtils.c:582
Plan * plan
Definition: execnodes.h:967
bool scanopsfixed
Definition: execnodes.h:1045
void ExecInitResultSlot(PlanState *planstate, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1779
bool scanopsset
Definition: execnodes.h:1049
List * targetlist
Definition: plannodes.h:141
bool resultopsfixed
Definition: execnodes.h:1048

◆ ExecConstraints()

void ExecConstraints ( ResultRelInfo resultRelInfo,
TupleTableSlot slot,
EState estate 
)

Definition at line 1821 of file execMain.c.

References Assert, bms_union(), build_attrmap_by_name_if_req(), TupleDescData::constr, ereport, errcode(), errdetail(), errmsg(), ERROR, errtablecol(), errtableconstraint(), ExecBuildSlotValueDescription(), ExecGetInsertedCols(), ExecGetUpdatedCols(), ExecRelCheck(), execute_attr_map_slot(), TupleConstr::has_not_null, MakeTupleTableSlot(), ExprEvalStep::map, NameStr, TupleDescData::natts, RelationData::rd_rel, RelationGetDescr, RelationGetRelationName, RelationGetRelid, ResultRelInfo::ri_RelationDesc, ResultRelInfo::ri_RootResultRelInfo, slot_attisnull(), TTSOpsVirtual, ExprEvalStep::tupdesc, and TupleDescAttr.

Referenced by CopyFrom(), ExecGetJunkAttribute(), ExecInsert(), ExecSimpleRelationInsert(), ExecSimpleRelationUpdate(), and ExecUpdate().

1823 {
1824  Relation rel = resultRelInfo->ri_RelationDesc;
1825  TupleDesc tupdesc = RelationGetDescr(rel);
1826  TupleConstr *constr = tupdesc->constr;
1827  Bitmapset *modifiedCols;
1828 
1829  Assert(constr); /* we should not be called otherwise */
1830 
1831  if (constr->has_not_null)
1832  {
1833  int natts = tupdesc->natts;
1834  int attrChk;
1835 
1836  for (attrChk = 1; attrChk <= natts; attrChk++)
1837  {
1838  Form_pg_attribute att = TupleDescAttr(tupdesc, attrChk - 1);
1839 
1840  if (att->attnotnull && slot_attisnull(slot, attrChk))
1841  {
1842  char *val_desc;
1843  Relation orig_rel = rel;
1844  TupleDesc orig_tupdesc = RelationGetDescr(rel);
1845 
1846  /*
1847  * If the tuple has been routed, it's been converted to the
1848  * partition's rowtype, which might differ from the root
1849  * table's. We must convert it back to the root table's
1850  * rowtype so that val_desc shown error message matches the
1851  * input tuple.
1852  */
1853  if (resultRelInfo->ri_RootResultRelInfo)
1854  {
1855  ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
1856  AttrMap *map;
1857 
1858  tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
1859  /* a reverse map */
1860  map = build_attrmap_by_name_if_req(orig_tupdesc,
1861  tupdesc);
1862 
1863  /*
1864  * Partition-specific slot's tupdesc can't be changed, so
1865  * allocate a new one.
1866  */
1867  if (map != NULL)
1868  slot = execute_attr_map_slot(map, slot,
1869  MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
1870  modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate),
1871  ExecGetUpdatedCols(rootrel, estate));
1872  rel = rootrel->ri_RelationDesc;
1873  }
1874  else
1875  modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
1876  ExecGetUpdatedCols(resultRelInfo, estate));
1878  slot,
1879  tupdesc,
1880  modifiedCols,
1881  64);
1882 
1883  ereport(ERROR,
1884  (errcode(ERRCODE_NOT_NULL_VIOLATION),
1885  errmsg("null value in column \"%s\" of relation \"%s\" violates not-null constraint",
1886  NameStr(att->attname),
1887  RelationGetRelationName(orig_rel)),
1888  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1889  errtablecol(orig_rel, attrChk)));
1890  }
1891  }
1892  }
1893 
1894  if (rel->rd_rel->relchecks > 0)
1895  {
1896  const char *failed;
1897 
1898  if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
1899  {
1900  char *val_desc;
1901  Relation orig_rel = rel;
1902 
1903  /* See the comment above. */
1904  if (resultRelInfo->ri_RootResultRelInfo)
1905  {
1906  ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
1907  TupleDesc old_tupdesc = RelationGetDescr(rel);
1908  AttrMap *map;
1909 
1910  tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
1911  /* a reverse map */
1912  map = build_attrmap_by_name_if_req(old_tupdesc,
1913  tupdesc);
1914 
1915  /*
1916  * Partition-specific slot's tupdesc can't be changed, so
1917  * allocate a new one.
1918  */
1919  if (map != NULL)
1920  slot = execute_attr_map_slot(map, slot,
1921  MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
1922  modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate),
1923  ExecGetUpdatedCols(rootrel, estate));
1924  rel = rootrel->ri_RelationDesc;
1925  }
1926  else
1927  modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate),
1928  ExecGetUpdatedCols(resultRelInfo, estate));
1930  slot,
1931  tupdesc,
1932  modifiedCols,
1933  64);
1934  ereport(ERROR,
1935  (errcode(ERRCODE_CHECK_VIOLATION),
1936  errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
1937  RelationGetRelationName(orig_rel), failed),
1938  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1939  errtableconstraint(orig_rel, failed)));
1940  }
1941  }
1942 }
Relation ri_RelationDesc
Definition: execnodes.h:412
#define RelationGetDescr(relation)
Definition: rel.h:503
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
Bitmapset * ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1295
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
int errcode(int sqlerrcode)
Definition: elog.c:698
Form_pg_class rd_rel
Definition: rel.h:109
Definition: attmap.h:34
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5690
AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc)
Definition: attmap.c:259
#define ERROR
Definition: elog.h:46
static char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
Definition: execMain.c:2103
struct ResultRelInfo * ri_RootResultRelInfo
Definition: execnodes.h:513
TupleConstr * constr
Definition: tupdesc.h:85
int errdetail(const char *fmt,...)
Definition: elog.c:1042
#define RelationGetRelationName(relation)
Definition: rel.h:511
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
TupleTableSlot * MakeTupleTableSlot(TupleDesc tupleDesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1112
static const char * ExecRelCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1622
#define ereport(elevel,...)
Definition: elog.h:157
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition: tupconvert.c:177
#define Assert(condition)
Definition: c.h:804
int errtablecol(Relation rel, int attnum)
Definition: relcache.c:5653
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:225
Bitmapset * ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
Definition: execUtils.c:1256
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define NameStr(name)
Definition: c.h:681
bool has_not_null
Definition: tupdesc.h:44
static bool slot_attisnull(TupleTableSlot *slot, int attnum)
Definition: tuptable.h:367
#define RelationGetRelid(relation)
Definition: rel.h:477

◆ ExecCreateScanSlotFromOuterPlan()

void ExecCreateScanSlotFromOuterPlan ( EState estate,
ScanState scanstate,
const TupleTableSlotOps tts_ops 
)

Definition at line 682 of file execUtils.c.

References ExecGetResultType(), ExecInitScanTupleSlot(), outerPlan, and outerPlanState.

Referenced by ExecInitAgg(), ExecInitGroup(), ExecInitIncrementalSort(), ExecInitMaterial(), ExecInitMemoize(), ExecInitSort(), and ExecInitWindowAgg().

685 {
687  TupleDesc tupDesc;
688 
689  outerPlan = outerPlanState(scanstate);
690  tupDesc = ExecGetResultType(outerPlan);
691 
692  ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops);
693 }
#define outerPlanState(node)
Definition: execnodes.h:1063
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1811
#define outerPlan(node)
Definition: plannodes.h:171
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:490

◆ execCurrentOf()

bool execCurrentOf ( CurrentOfExpr cexpr,
ExprContext econtext,
Oid  table_oid,
ItemPointer  current_tid 
)

Definition at line 44 of file execCurrent.c.

References Assert, PortalData::atEnd, PortalData::atStart, ExecRowMark::curCtid, CurrentOfExpr::cursor_name, CurrentOfExpr::cursor_param, DatumGetObjectId, DatumGetPointer, elog, ereport, errcode(), errmsg(), ERROR, EState::es_range_table_size, EState::es_rowmarks, QueryDesc::estate, fetch_cursor_param_value(), get_rel_name(), GetPortalByName(), i, IsA, ItemPointerIsValid, ExecRowMark::markType, QueryDesc::planstate, PORTAL_ONE_SELECT, PortalIsValid, PortalData::queryDesc, ExecRowMark::relid, RowMarkRequiresRowShareLock, search_plan_tree(), SelfItemPointerAttributeNumber, slot_getsysattr(), ScanState::ss_ScanTupleSlot, PortalData::strategy, TableOidAttributeNumber, TupIsNull, and IndexScanDescData::xs_heaptid.

Referenced by TidListEval().

48 {
49  char *cursor_name;
50  char *table_name;
51  Portal portal;
52  QueryDesc *queryDesc;
53 
54  /* Get the cursor name --- may have to look up a parameter reference */
55  if (cexpr->cursor_name)
56  cursor_name = cexpr->cursor_name;
57  else
58  cursor_name = fetch_cursor_param_value(econtext, cexpr->cursor_param);
59 
60  /* Fetch table name for possible use in error messages */
61  table_name = get_rel_name(table_oid);
62  if (table_name == NULL)
63  elog(ERROR, "cache lookup failed for relation %u", table_oid);
64 
65  /* Find the cursor's portal */
66  portal = GetPortalByName(cursor_name);
67  if (!PortalIsValid(portal))
68  ereport(ERROR,
69  (errcode(ERRCODE_UNDEFINED_CURSOR),
70  errmsg("cursor \"%s\" does not exist", cursor_name)));
71 
72  /*
73  * We have to watch out for non-SELECT queries as well as held cursors,
74  * both of which may have null queryDesc.
75  */
76  if (portal->strategy != PORTAL_ONE_SELECT)
77  ereport(ERROR,
78  (errcode(ERRCODE_INVALID_CURSOR_STATE),
79  errmsg("cursor \"%s\" is not a SELECT query",
80  cursor_name)));
81  queryDesc = portal->queryDesc;
82  if (queryDesc == NULL || queryDesc->estate == NULL)
83  ereport(ERROR,
84  (errcode(ERRCODE_INVALID_CURSOR_STATE),
85  errmsg("cursor \"%s\" is held from a previous transaction",
86  cursor_name)));
87 
88  /*
89  * We have two different strategies depending on whether the cursor uses
90  * FOR UPDATE/SHARE or not. The reason for supporting both is that the
91  * FOR UPDATE code is able to identify a target table in many cases where
92  * the other code can't, while the non-FOR-UPDATE case allows use of WHERE
93  * CURRENT OF with an insensitive cursor.
94  */
95  if (queryDesc->estate->es_rowmarks)
96  {
97  ExecRowMark *erm;
98  Index i;
99 
100  /*
101  * Here, the query must have exactly one FOR UPDATE/SHARE reference to
102  * the target table, and we dig the ctid info out of that.
103  */
104  erm = NULL;
105  for (i = 0; i < queryDesc->estate->es_range_table_size; i++)
106  {
107  ExecRowMark *thiserm = queryDesc->estate->es_rowmarks[i];
108 
109  if (thiserm == NULL ||
111  continue; /* ignore non-FOR UPDATE/SHARE items */
112 
113  if (thiserm->relid == table_oid)
114  {
115  if (erm)
116  ereport(ERROR,
117  (errcode(ERRCODE_INVALID_CURSOR_STATE),
118  errmsg("cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"",
119  cursor_name, table_name)));
120  erm = thiserm;
121  }
122  }
123 
124  if (erm == NULL)
125  ereport(ERROR,
126  (errcode(ERRCODE_INVALID_CURSOR_STATE),
127  errmsg("cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"",
128  cursor_name, table_name)));
129 
130  /*
131  * The cursor must have a current result row: per the SQL spec, it's
132  * an error if not.
133  */
134  if (portal->atStart || portal->atEnd)
135  ereport(ERROR,
136  (errcode(ERRCODE_INVALID_CURSOR_STATE),
137  errmsg("cursor \"%s\" is not positioned on a row",
138  cursor_name)));
139 
140  /* Return the currently scanned TID, if there is one */
141  if (ItemPointerIsValid(&(erm->curCtid)))
142  {
143  *current_tid = erm->curCtid;
144  return true;
145  }
146 
147  /*
148  * This table didn't produce the cursor's current row; some other
149  * inheritance child of the same parent must have. Signal caller to
150  * do nothing on this table.
151  */
152  return false;
153  }
154  else
155  {
156  /*
157  * Without FOR UPDATE, we dig through the cursor's plan to find the
158  * scan node. Fail if it's not there or buried underneath
159  * aggregation.
160  */
161  ScanState *scanstate;
162  bool pending_rescan = false;
163 
164  scanstate = search_plan_tree(queryDesc->planstate, table_oid,
165  &pending_rescan);
166  if (!scanstate)
167  ereport(ERROR,
168  (errcode(ERRCODE_INVALID_CURSOR_STATE),
169  errmsg("cursor \"%s\" is not a simply updatable scan of table \"%s\"",
170  cursor_name, table_name)));
171 
172  /*
173  * The cursor must have a current result row: per the SQL spec, it's
174  * an error if not. We test this at the top level, rather than at the
175  * scan node level, because in inheritance cases any one table scan
176  * could easily not be on a row. We want to return false, not raise
177  * error, if the passed-in table OID is for one of the inactive scans.
178  */
179  if (portal->atStart || portal->atEnd)
180  ereport(ERROR,
181  (errcode(ERRCODE_INVALID_CURSOR_STATE),
182  errmsg("cursor \"%s\" is not positioned on a row",
183  cursor_name)));
184 
185  /*
186  * Now OK to return false if we found an inactive scan. It is
187  * inactive either if it's not positioned on a row, or there's a
188  * rescan pending for it.
189  */
190  if (TupIsNull(scanstate->ss_ScanTupleSlot) || pending_rescan)
191  return false;
192 
193  /*
194  * Extract TID of the scan's current row. The mechanism for this is
195  * in principle scan-type-dependent, but for most scan types, we can
196  * just dig the TID out of the physical scan tuple.
197  */
198  if (IsA(scanstate, IndexOnlyScanState))
199  {
200  /*
201  * For IndexOnlyScan, the tuple stored in ss_ScanTupleSlot may be
202  * a virtual tuple that does not have the ctid column, so we have
203  * to get the TID from xs_ctup.t_self.
204  */
205  IndexScanDesc scan = ((IndexOnlyScanState *) scanstate)->ioss_ScanDesc;
206 
207  *current_tid = scan->xs_heaptid;
208  }
209  else
210  {
211  /*
212  * Default case: try to fetch TID from the scan node's current
213  * tuple. As an extra cross-check, verify tableoid in the current
214  * tuple. If the scan hasn't provided a physical tuple, we have
215  * to fail.
216  */
217  Datum ldatum;
218  bool lisnull;
219  ItemPointer tuple_tid;
220 
221 #ifdef USE_ASSERT_CHECKING
222  ldatum = slot_getsysattr(scanstate->ss_ScanTupleSlot,
224  &lisnull);
225  if (lisnull)
226  ereport(ERROR,
227  (errcode(ERRCODE_INVALID_CURSOR_STATE),
228  errmsg("cursor \"%s\" is not a simply updatable scan of table \"%s\"",
229  cursor_name, table_name)));
230  Assert(DatumGetObjectId(ldatum) == table_oid);
231 #endif
232 
233  ldatum = slot_getsysattr(scanstate->ss_ScanTupleSlot,
235  &lisnull);
236  if (lisnull)
237  ereport(ERROR,
238  (errcode(ERRCODE_INVALID_CURSOR_STATE),
239  errmsg("cursor \"%s\" is not a simply updatable scan of table \"%s\"",
240  cursor_name, table_name)));
241  tuple_tid = (ItemPointer) DatumGetPointer(ldatum);
242 
243  *current_tid = *tuple_tid;
244  }
245 
246  Assert(ItemPointerIsValid(current_tid));
247 
248  return true;
249  }
250 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:82
#define IsA(nodeptr, _type_)
Definition: nodes.h:587
static ScanState * search_plan_tree(PlanState *node, Oid table_oid, bool *pending_rescan)
Definition: execCurrent.c:314
bool atEnd
Definition: portal.h:200
EState * estate
Definition: execdesc.h:48
Portal GetPortalByName(const char *name)
Definition: portalmem.c:130
#define DatumGetObjectId(X)
Definition: postgres.h:544
int errcode(int sqlerrcode)
Definition: elog.c:698
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1381
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:1077
ItemPointerData * ItemPointer
Definition: itemptr.h:49
ItemPointerData curCtid
Definition: execnodes.h:682
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:565
#define ERROR
Definition: elog.h:46
PlanState * planstate
Definition: execdesc.h:49
ItemPointerData xs_heaptid
Definition: relscan.h:147
#define TupIsNull(slot)
Definition: tuptable.h:292
#define TableOidAttributeNumber
Definition: sysattr.h:26
char * cursor_name
Definition: primnodes.h:1364
PortalStrategy strategy
Definition: portal.h:146
QueryDesc * queryDesc
Definition: portal.h:157
#define PortalIsValid(p)
Definition: portal.h:212
uintptr_t Datum
Definition: postgres.h:411
unsigned int Index
Definition: c.h:549
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
RowMarkType markType
Definition: execnodes.h:678
Index es_range_table_size
Definition: execnodes.h:562
#define DatumGetPointer(X)
Definition: postgres.h:593
bool atStart
Definition: portal.h:199
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
int i
static char * fetch_cursor_param_value(ExprContext *econtext, int paramId)
Definition: execCurrent.c:258
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
static Datum slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: tuptable.h:402
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1899

◆ ExecEndNode()

void ExecEndNode ( PlanState node)

Definition at line 556 of file execProcnode.c.

References bms_free(), check_stack_depth(), PlanState::chgParam, elog, ERROR, ExecEndAgg(), ExecEndAppend(), ExecEndBitmapAnd(), ExecEndBitmapHeapScan(), ExecEndBitmapIndexScan(), ExecEndBitmapOr(), ExecEndCteScan(), ExecEndCustomScan(), ExecEndForeignScan(), ExecEndFunctionScan(), ExecEndGather(), ExecEndGatherMerge(), ExecEndGroup(), ExecEndHash(), ExecEndHashJoin(), ExecEndIncrementalSort(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), ExecEndLimit(), ExecEndLockRows(), ExecEndMaterial(), ExecEndMemoize(), ExecEndMergeAppend(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNamedTuplestoreScan(), ExecEndNestLoop(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSampleScan(), ExecEndSeqScan(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndTableFuncScan(), ExecEndTidRangeScan(), ExecEndTidScan(), ExecEndUnique(), ExecEndValuesScan(), ExecEndWindowAgg(), ExecEndWorkTableScan(), nodeTag, T_AggState, T_AppendState, T_BitmapAndState, T_BitmapHeapScanState, T_BitmapIndexScanState, T_BitmapOrState, T_CteScanState, T_CustomScanState, T_ForeignScanState, T_FunctionScanState, T_GatherMergeState, T_GatherState, T_GroupState, T_HashJoinState, T_HashState, T_IncrementalSortState, T_IndexOnlyScanState, T_IndexScanState, T_LimitState, T_LockRowsState, T_MaterialState, T_MemoizeState, T_MergeAppendState, T_MergeJoinState, T_ModifyTableState, T_NamedTuplestoreScanState, T_NestLoopState, T_ProjectSetState, T_RecursiveUnionState, T_ResultState, T_SampleScanState, T_SeqScanState, T_SetOpState, T_SortState, T_SubqueryScanState, T_TableFuncScanState, T_TidRangeScanState, T_TidScanState, T_UniqueState, T_ValuesScanState, T_WindowAggState, and T_WorkTableScanState.

Referenced by EvalPlanQualEnd(), ExecEndAgg(), ExecEndAppend(), ExecEndBitmapAnd(), ExecEndBitmapHeapScan(), ExecEndBitmapOr(), ExecEndForeignScan(), ExecEndGather(), ExecEndGatherMerge(), ExecEndGroup(), ExecEndHash(), ExecEndHashJoin(), ExecEndIncrementalSort(), ExecEndLimit(), ExecEndLockRows(), ExecEndMaterial(), ExecEndMemoize(), ExecEndMergeAppend(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNestLoop(), ExecEndPlan(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndUnique(), and ExecEndWindowAgg().

557 {
558  /*
559  * do nothing when we get to the end of a leaf on tree.
560  */
561  if (node == NULL)
562  return;
563 
564  /*
565  * Make sure there's enough stack available. Need to check here, in
566  * addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not
567  * guaranteed that ExecProcNode() is reached for all nodes.
568  */
570 
571  if (node->chgParam != NULL)
572  {
573  bms_free(node->chgParam);
574  node->chgParam = NULL;
575  }
576 
577  switch (nodeTag(node))
578  {
579  /*
580  * control nodes
581  */
582  case T_ResultState:
583  ExecEndResult((ResultState *) node);
584  break;
585 
586  case T_ProjectSetState:
588  break;
589 
590  case T_ModifyTableState:
592  break;
593 
594  case T_AppendState:
595  ExecEndAppend((AppendState *) node);
596  break;
597 
598  case T_MergeAppendState:
600  break;
601 
604  break;
605 
606  case T_BitmapAndState:
608  break;
609 
610  case T_BitmapOrState:
611  ExecEndBitmapOr((BitmapOrState *) node);
612  break;
613 
614  /*
615  * scan nodes
616  */
617  case T_SeqScanState:
618  ExecEndSeqScan((SeqScanState *) node);
619  break;
620 
621  case T_SampleScanState:
623  break;
624 
625  case T_GatherState:
626  ExecEndGather((GatherState *) node);
627  break;
628 
629  case T_GatherMergeState:
631  break;
632 
633  case T_IndexScanState:
635  break;
636 
639  break;
640 
643  break;
644 
647  break;
648 
649  case T_TidScanState:
650  ExecEndTidScan((TidScanState *) node);
651  break;
652 
653  case T_TidRangeScanState:
655  break;
656 
657  case T_SubqueryScanState:
659  break;
660 
661  case T_FunctionScanState:
663  break;
664 
667  break;
668 
669  case T_ValuesScanState:
671  break;
672 
673  case T_CteScanState:
674  ExecEndCteScan((CteScanState *) node);
675  break;
676 
679  break;
680 
683  break;
684 
685  case T_ForeignScanState:
687  break;
688 
689  case T_CustomScanState:
691  break;
692 
693  /*
694  * join nodes
695  */
696  case T_NestLoopState:
697  ExecEndNestLoop((NestLoopState *) node);
698  break;
699 
700  case T_MergeJoinState:
702  break;
703 
704  case T_HashJoinState:
705  ExecEndHashJoin((HashJoinState *) node);
706  break;
707 
708  /*
709  * materialization nodes
710  */
711  case T_MaterialState:
712  ExecEndMaterial((MaterialState *) node);
713  break;
714 
715  case T_SortState:
716  ExecEndSort((SortState *) node);
717  break;
718 
721  break;
722 
723  case T_MemoizeState:
724  ExecEndMemoize((MemoizeState *) node);
725  break;
726 
727  case T_GroupState:
728  ExecEndGroup((GroupState *) node);
729  break;
730 
731  case T_AggState:
732  ExecEndAgg((AggState *) node);
733  break;
734 
735  case T_WindowAggState:
737  break;
738 
739  case T_UniqueState:
740  ExecEndUnique((UniqueState *) node);
741  break;
742 
743  case T_HashState:
744  ExecEndHash((HashState *) node);
745  break;
746 
747  case T_SetOpState:
748  ExecEndSetOp((SetOpState *) node);
749  break;
750 
751  case T_LockRowsState:
752  ExecEndLockRows((LockRowsState *) node);
753  break;
754 
755  case T_LimitState:
756  ExecEndLimit((LimitState *) node);
757  break;
758 
759  default:
760  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
761  break;
762  }
763 }
void ExecEndGroup(GroupState *node)
Definition: nodeGroup.c:227
void ExecEndSetOp(SetOpState *node)
Definition: nodeSetOp.c:583
void ExecEndFunctionScan(FunctionScanState *node)
void ExecEndNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:362
void ExecEndIndexScan(IndexScanState *node)
void ExecEndLimit(LimitState *node)
Definition: nodeLimit.c:535
void ExecEndUnique(UniqueState *node)
Definition: nodeUnique.c:169
void ExecEndGatherMerge(GatherMergeState *node)
void ExecEndIncrementalSort(IncrementalSortState *node)
void ExecEndWorkTableScan(WorkTableScanState *node)
void ExecEndLockRows(LockRowsState *node)
Definition: nodeLockRows.c:386
void ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecEndBitmapAnd(BitmapAndState *node)
void ExecEndRecursiveUnion(RecursiveUnionState *node)
void ExecEndSubqueryScan(SubqueryScanState *node)
void ExecEndHashJoin(HashJoinState *node)
Definition: nodeHashjoin.c:765
void ExecEndMemoize(MemoizeState *node)
Definition: nodeMemoize.c:939
void ExecEndTableFuncScan(TableFuncScanState *node)
void ExecEndResult(ResultState *node)
Definition: nodeResult.c:241
#define ERROR
Definition: elog.h:46
void ExecEndAppend(AppendState *node)
Definition: nodeAppend.c:395
void ExecEndForeignScan(ForeignScanState *node)
void ExecEndSort(SortState *node)
Definition: nodeSort.c:291
void ExecEndBitmapIndexScan(BitmapIndexScanState *node)
void check_stack_depth(void)
Definition: postgres.c:3469
void ExecEndValuesScan(ValuesScanState *node)
void ExecEndMergeJoin(MergeJoinState *node)
void ExecEndSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:184
void ExecEndIndexOnlyScan(IndexOnlyScanState *node)
void ExecEndTidScan(TidScanState *node)
Definition: nodeTidscan.c:468
Bitmapset * chgParam
Definition: execnodes.h:999
void ExecEndCteScan(CteScanState *node)
Definition: nodeCtescan.c:288
void ExecEndCustomScan(CustomScanState *node)
Definition: nodeCustom.c:119
void ExecEndBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:196
void ExecEndSampleScan(SampleScanState *node)
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208
void ExecEndWindowAgg(WindowAggState *node)
void ExecEndMergeAppend(MergeAppendState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:541
#define elog(elevel,...)
Definition: elog.h:232
void ExecEndHash(HashState *node)
Definition: nodeHash.c:407