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)
 
JunkFilterExecInitJunkFilterInsertion (List *targetList, TupleDesc cleanTupType, TupleTableSlot *slot)
 
JunkFilterExecInitJunkFilterConversion (List *targetList, TupleDesc cleanTupType, TupleTableSlot *slot)
 
AttrNumber ExecFindJunkAttribute (JunkFilter *junkfilter, const char *attrName)
 
AttrNumber ExecFindJunkAttributeInTlist (List *targetlist, const char *attrName)
 
Datum ExecGetJunkAttribute (TupleTableSlot *slot, AttrNumber attno, bool *isNull)
 
TupleTableSlotExecFilterJunk (JunkFilter *junkfilter, TupleTableSlot *slot)
 
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, Relation partition_root, 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)
 
ProjectionInfoExecBuildProjectionInfo (List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
 
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, Index 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, Index 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)
 
void ExecOpenIndices (ResultRelInfo *resultRelInfo, bool speculative)
 
void ExecCloseIndices (ResultRelInfo *resultRelInfo)
 
ListExecInsertIndexTuples (ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, 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)
 

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:556
text * cstring_to_text(const char *s)
Definition: varlena.c:188
#define DatumGetPointer(X)
Definition: postgres.h:549

Definition at line 481 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 518 of file executor.h.

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

Typedef Documentation

◆ ExecScanAccessMtd

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

Definition at line 432 of file executor.h.

◆ ExecScanRecheckMtd

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

Definition at line 433 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 2236 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().

2239 {
2240  TupOutputState *tstate;
2241 
2242  tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
2243 
2244  tstate->slot = MakeSingleTupleTableSlot(tupdesc, tts_ops);
2245  tstate->dest = dest;
2246 
2247  tstate->dest->rStartup(tstate->dest, (int) CMD_SELECT, tupdesc);
2248 
2249  return tstate;
2250 }
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1208
TupleTableSlot * slot
Definition: executor.h:465
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:122
void * palloc(Size size)
Definition: mcxt.c:950
DestReceiver * dest
Definition: executor.h:466

◆ 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 253 of file execGrouping.c.

References BuildTupleHashTableExt().

263 {
264  return BuildTupleHashTableExt(parent,
265  inputDesc,
266  numCols, keyColIdx,
267  eqfuncoids,
268  hashfunctions,
269  collations,
270  nbuckets, additionalsize,
271  tablecxt,
272  tablecxt,
273  tempcxt,
274  use_variable_hash_iv);
275 }
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_mem(), TupleHashTableData::hash_iv, TupleHashTableData::hashtab, TupleHashTableData::in_hash_funcs, TupleHashTableData::inputslot, TupleHashTableData::keyColIdx, MakeSingleTupleTableSlot(), MemoryContextSwitchTo(), Min, 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  int hash_mem = get_hash_mem();
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  nbuckets = Min(nbuckets, (long) ((hash_mem * 1024L) / entrysize));
176 
177  oldcontext = MemoryContextSwitchTo(metacxt);
178 
179  hashtable = (TupleHashTable) palloc(sizeof(TupleHashTableData));
180 
181  hashtable->numCols = numCols;
182  hashtable->keyColIdx = keyColIdx;
183  hashtable->tab_hash_funcs = hashfunctions;
184  hashtable->tab_collations = collations;
185  hashtable->tablecxt = tablecxt;
186  hashtable->tempcxt = tempcxt;
187  hashtable->entrysize = entrysize;
188  hashtable->tableslot = NULL; /* will be made on first lookup */
189  hashtable->inputslot = NULL;
190  hashtable->in_hash_funcs = NULL;
191  hashtable->cur_eq_func = NULL;
192 
193  /*
194  * If parallelism is in use, even if the leader backend is performing the
195  * scan itself, we don't want to create the hashtable exactly the same way
196  * in all workers. As hashtables are iterated over in keyspace-order,
197  * doing so in all processes in the same way is likely to lead to
198  * "unbalanced" hashtables when the table size initially is
199  * underestimated.
200  */
201  if (use_variable_hash_iv)
203  else
204  hashtable->hash_iv = 0;
205 
206  hashtable->hashtab = tuplehash_create(metacxt, nbuckets, hashtable);
207 
208  /*
209  * We copy the input tuple descriptor just for safety --- we assume all
210  * input tuples will have equivalent descriptors.
211  */
214 
215  /*
216  * If the old reset interface is used (i.e. BuildTupleHashTable, rather
217  * than BuildTupleHashTableExt), allowing JIT would lead to the generated
218  * functions to a) live longer than the query b) be re-generated each time
219  * the table is being reset. Therefore prevent JIT from being used in that
220  * case, by not providing a parent node (which prevents accessing the
221  * JitContext in the EState).
222  */
223  allow_jit = metacxt != tablecxt;
224 
225  /* build comparator for all columns */
226  /* XXX: should we support non-minimal tuples for the inputslot? */
227  hashtable->tab_eq_func = ExecBuildGroupingEqual(inputDesc, inputDesc,
229  numCols,
230  keyColIdx, eqfuncoids, collations,
231  allow_jit ? parent : NULL);
232 
233  /*
234  * While not pretty, it's ok to not shut down this context, but instead
235  * rely on the containing memory context being reset, as
236  * ExecBuildGroupingEqual() only builds a very simple expression calling
237  * functions (i.e. nothing that'd employ RegisterExprContextCallback()).
238  */
240 
241  MemoryContextSwitchTo(oldcontext);
242 
243  return hashtable;
244 }
ExprContext * exprcontext
Definition: execnodes.h:717
ExprContext * CreateStandaloneExprContext(void)
Definition: execUtils.c:351
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:110
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1208
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:3333
TupleTableSlot * inputslot
Definition: execnodes.h:713
#define Min(x, y)
Definition: c.h:928
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
AttrNumber * keyColIdx
Definition: execnodes.h:704
ExprState * tab_eq_func
Definition: execnodes.h:706
ExprState * cur_eq_func
Definition: execnodes.h:715
static uint32 murmurhash32(uint32 data)
Definition: hashfn.h:92
FmgrInfo * tab_hash_funcs
Definition: execnodes.h:705
FmgrInfo * in_hash_funcs
Definition: execnodes.h:714
struct TupleHashEntryData TupleHashEntryData
MemoryContext tablecxt
Definition: execnodes.h:708
struct TupleHashTableData * TupleHashTable
Definition: execnodes.h:682
int ParallelWorkerNumber
Definition: parallel.c:112
tuplehash_hash * hashtab
Definition: execnodes.h:702
#define Assert(condition)
Definition: c.h:746
TupleTableSlot * tableslot
Definition: execnodes.h:711
size_t Size
Definition: c.h:474
void * palloc(Size size)
Definition: mcxt.c:950
MemoryContext tempcxt
Definition: execnodes.h:709
const TupleTableSlotOps TTSOpsMinimalTuple
Definition: execTuples.c:85
int get_hash_mem(void)
Definition: nodeHash.c:3389

◆ 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 863 of file execIndexing.c.

References CEOUC_WAIT, and check_exclusion_or_unique_constraint().

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

868 {
869  (void) check_exclusion_or_unique_constraint(heap, index, indexInfo, tupleid,
870  values, isnull,
871  estate, newIndex,
872  CEOUC_WAIT, false, NULL);
873 }
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:643
static Datum values[MAXATTR]
Definition: bootstrap.c:165

◆ 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:1068
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:4723
int errcode(int sqlerrcode)
Definition: elog.c:610
Form_pg_class rd_rel
Definition: rel.h:109
#define OidIsValid(objectId)
Definition: c.h:652
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:490
#define ereport(elevel,...)
Definition: elog.h:144
struct PublicationActions * GetRelationPublicationActions(Relation relation)
Definition: relcache.c:5306
int errmsg(const char *fmt,...)
Definition: elog.c:821

◆ CheckSubscriptionRelkind()

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

Definition at line 608 of file execReplication.c.

References ereport, errcode(), ERRCODE_WRONG_OBJECT_TYPE, errdetail(), errmsg(), and ERROR.

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

610 {
611  /*
612  * Give a more specific error for foreign tables.
613  */
614  if (relkind == RELKIND_FOREIGN_TABLE)
615  ereport(ERROR,
617  errmsg("cannot use relation \"%s.%s\" as logical replication target",
618  nspname, relname),
619  errdetail("\"%s.%s\" is a foreign table.",
620  nspname, relname)));
621 
622  if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
623  ereport(ERROR,
625  errmsg("cannot use relation \"%s.%s\" as logical replication target",
626  nspname, relname),
627  errdetail("\"%s.%s\" is not a table.",
628  nspname, relname)));
629 }
int errcode(int sqlerrcode)
Definition: elog.c:610
NameData relname
Definition: pg_class.h:38
#define ERRCODE_WRONG_OBJECT_TYPE
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:954
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:821

◆ CheckValidResultRel()

void CheckValidResultRel ( ResultRelInfo resultRelInfo,
CmdType  operation 
)

Definition at line 995 of file execMain.c.

References CheckCmdReplicaIdentity(), CMD_DELETE, CMD_INSERT, CMD_UPDATE, elog, ereport, errcode(), ERRCODE_WRONG_OBJECT_TYPE, 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(), ExecInitModifyTable(), and ExecInitPartitionInfo().

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

◆ CreateExecutorState()

EState* CreateExecutorState ( void  )

Definition at line 89 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_index_stats(), CopyFrom(), create_estate_for_relation(), EvalPlanQualStart(), evaluate_expr(), ExecuteCallStmt(), ExecuteQuery(), ExecuteTruncateGuts(), ExplainExecuteQuery(), get_qual_for_range(), heapam_index_build_range_scan(), heapam_index_validate_scan(), IndexCheckExclusion(), operator_predicate_proof(), plpgsql_create_econtext(), plpgsql_inline_handler(), standard_ExecutorStart(), StoreAttrDefault(), tuplesort_begin_cluster(), unique_key_recheck(), and validateDomainConstraint().

90 {
91  EState *estate;
92  MemoryContext qcontext;
93  MemoryContext oldcontext;
94 
95  /*
96  * Create the per-query context for this Executor run.
97  */
99  "ExecutorState",
101 
102  /*
103  * Make the EState node within the per-query context. This way, we don't
104  * need a separate pfree() operation for it at shutdown.
105  */
106  oldcontext = MemoryContextSwitchTo(qcontext);
107 
108  estate = makeNode(EState);
109 
110  /*
111  * Initialize all fields of the Executor State structure
112  */
114  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
115  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
116  estate->es_range_table = NIL;
117  estate->es_range_table_size = 0;
118  estate->es_relations = NULL;
119  estate->es_rowmarks = NULL;
120  estate->es_plannedstmt = NULL;
121 
122  estate->es_junkFilter = NULL;
123 
124  estate->es_output_cid = (CommandId) 0;
125 
126  estate->es_result_relations = NULL;
129  estate->es_trig_target_relations = NIL;
130 
131  estate->es_param_list_info = NULL;
132  estate->es_param_exec_vals = NULL;
133 
134  estate->es_queryEnv = NULL;
135 
136  estate->es_query_cxt = qcontext;
137 
138  estate->es_tupleTable = NIL;
139 
140  estate->es_processed = 0;
141 
142  estate->es_top_eflags = 0;
143  estate->es_instrument = 0;
144  estate->es_finished = false;
145 
146  estate->es_exprcontexts = NIL;
147 
148  estate->es_subplanstates = NIL;
149 
150  estate->es_auxmodifytables = NIL;
151 
152  estate->es_per_tuple_exprcontext = NULL;
153 
154  estate->es_sourceText = NULL;
155 
156  estate->es_use_parallel_mode = false;
157 
158  estate->es_jit_flags = 0;
159  estate->es_jit = NULL;
160 
161  /*
162  * Return the executor state structure
163  */
164  MemoryContextSwitchTo(oldcontext);
165 
166  return estate;
167 }
#define NIL
Definition: pg_list.h:65
uint32 CommandId
Definition: c.h:535
JunkFilter * es_junkFilter
Definition: execnodes.h:528
#define AllocSetContextCreate
Definition: memutils.h:170
CommandId es_output_cid
Definition: execnodes.h:531
struct JitContext * es_jit
Definition: execnodes.h:605
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:525
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:518
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:580
Snapshot es_snapshot
Definition: execnodes.h:517
List * es_range_table
Definition: execnodes.h:519
ScanDirection es_direction
Definition: execnodes.h:516
bool es_use_parallel_mode
Definition: execnodes.h:590
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:523
const char * es_sourceText
Definition: execnodes.h:526
ParamExecData * es_param_exec_vals
Definition: execnodes.h:554
MemoryContext es_query_cxt
Definition: execnodes.h:559
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
int es_jit_flags
Definition: execnodes.h:604
List * es_opened_result_relations
Definition: execnodes.h:537
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
int es_instrument
Definition: execnodes.h:566
ResultRelInfo ** es_result_relations
Definition: execnodes.h:534
QueryEnvironment * es_queryEnv
Definition: execnodes.h:556
#define InvalidSnapshot
Definition: snapshot.h:123
List * es_trig_target_relations
Definition: execnodes.h:550
List * es_tupleTable
Definition: execnodes.h:561
List * es_auxmodifytables
Definition: execnodes.h:573
List * es_tuple_routing_result_relations
Definition: execnodes.h:547
bool es_finished
Definition: execnodes.h:567
#define makeNode(_type_)
Definition: nodes.h:576
Relation * es_relations
Definition: execnodes.h:521
uint64 es_processed
Definition: execnodes.h:563
Index es_range_table_size
Definition: execnodes.h:520
List * es_subplanstates
Definition: execnodes.h:571
int es_top_eflags
Definition: execnodes.h:565
ParamListInfo es_param_list_info
Definition: execnodes.h:553
List * es_exprcontexts
Definition: execnodes.h:569

◆ CreateExprContext()

ExprContext* CreateExprContext ( EState estate)

Definition at line 300 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, and CreateExprContextInternal().

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

301 {
303 }
static ExprContext * CreateExprContextInternal(EState *estate, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: execUtils.c:230
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192

◆ CreateStandaloneExprContext()

ExprContext* CreateStandaloneExprContext ( void  )

Definition at line 351 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().

352 {
353  ExprContext *econtext;
354 
355  /* Create the ExprContext node within the caller's memory context */
356  econtext = makeNode(ExprContext);
357 
358  /* Initialize fields of ExprContext */
359  econtext->ecxt_scantuple = NULL;
360  econtext->ecxt_innertuple = NULL;
361  econtext->ecxt_outertuple = NULL;
362 
364 
365  /*
366  * Create working memory for expression evaluation in this context.
367  */
368  econtext->ecxt_per_tuple_memory =
370  "ExprContext",
372 
373  econtext->ecxt_param_exec_vals = NULL;
374  econtext->ecxt_param_list_info = NULL;
375 
376  econtext->ecxt_aggvalues = NULL;
377  econtext->ecxt_aggnulls = NULL;
378 
379  econtext->caseValue_datum = (Datum) 0;
380  econtext->caseValue_isNull = true;
381 
382  econtext->domainValue_datum = (Datum) 0;
383  econtext->domainValue_isNull = true;
384 
385  econtext->ecxt_estate = NULL;
386 
387  econtext->ecxt_callbacks = NULL;
388 
389  return econtext;
390 }
#define AllocSetContextCreate
Definition: memutils.h:170
Datum * ecxt_aggvalues
Definition: execnodes.h:244
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:233
Datum domainValue_datum
Definition: execnodes.h:256
Datum caseValue_datum
Definition: execnodes.h:250
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:264
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:227
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:236
struct EState * ecxt_estate
Definition: execnodes.h:261
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
bool domainValue_isNull
Definition: execnodes.h:258
bool * ecxt_aggnulls
Definition: execnodes.h:246
uintptr_t Datum
Definition: postgres.h:367
#define makeNode(_type_)
Definition: nodes.h:576
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:229
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:225
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:232
bool caseValue_isNull
Definition: execnodes.h:252
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:237

◆ CreateWorkExprContext()

ExprContext* CreateWorkExprContext ( EState estate)

Definition at line 315 of file execUtils.c.

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

Referenced by ExecInitAgg().

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

◆ do_text_output_multiline()

void do_text_output_multiline ( TupOutputState tstate,
const char *  txt 
)

Definition at line 2284 of file execTuples.c.

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

Referenced by ExplainQuery().

2285 {
2286  Datum values[1];
2287  bool isnull[1] = {false};
2288 
2289  while (*txt)
2290  {
2291  const char *eol;
2292  int len;
2293 
2294  eol = strchr(txt, '\n');
2295  if (eol)
2296  {
2297  len = eol - txt;
2298  eol++;
2299  }
2300  else
2301  {
2302  len = strlen(txt);
2303  eol = txt + len;
2304  }
2305 
2306  values[0] = PointerGetDatum(cstring_to_text_with_len(txt, len));
2307  do_tup_output(tstate, values, isnull);
2308  pfree(DatumGetPointer(values[0]));
2309  txt = eol;
2310  }
2311 }
#define PointerGetDatum(X)
Definition: postgres.h:556
void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
Definition: execTuples.c:2256
void pfree(void *pointer)
Definition: mcxt.c:1057
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:200
uintptr_t Datum
Definition: postgres.h:367
#define DatumGetPointer(X)
Definition: postgres.h:549
static Datum values[MAXATTR]
Definition: bootstrap.c:165

◆ do_tup_output()

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

Definition at line 2256 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().

2257 {
2258  TupleTableSlot *slot = tstate->slot;
2259  int natts = slot->tts_tupleDescriptor->natts;
2260 
2261  /* make sure the slot is clear */
2262  ExecClearTuple(slot);
2263 
2264  /* insert data */
2265  memcpy(slot->tts_values, values, natts * sizeof(Datum));
2266  memcpy(slot->tts_isnull, isnull, natts * sizeof(bool));
2267 
2268  /* mark slot as containing a virtual tuple */
2269  ExecStoreVirtualTuple(slot);
2270 
2271  /* send the tuple to the receiver */
2272  (void) tstate->dest->receiveSlot(slot, tstate->dest);
2273 
2274  /* clean up */
2275  ExecClearTuple(slot);
2276 }
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:465
bool * tts_isnull
Definition: tuptable.h:128
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:124
uintptr_t Datum
Definition: postgres.h:367
static Datum values[MAXATTR]
Definition: bootstrap.c:165
DestReceiver * dest
Definition: executor.h:466
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1522

◆ end_tup_output()

void end_tup_output ( TupOutputState tstate)

Definition at line 2314 of file execTuples.c.

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

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

2315 {
2316  tstate->dest->rShutdown(tstate->dest);
2317  /* note that destroying the dest is not ours to do */
2319  pfree(tstate);
2320 }
TupleTableSlot * slot
Definition: executor.h:465
void pfree(void *pointer)
Definition: mcxt.c:1057
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1224
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:125
DestReceiver * dest
Definition: executor.h:466

◆ EvalPlanQual()

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

Definition at line 2336 of file execMain.c.

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

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

2338 {
2339  TupleTableSlot *slot;
2340  TupleTableSlot *testslot;
2341 
2342  Assert(rti > 0);
2343 
2344  /*
2345  * Need to run a recheck subquery. Initialize or reinitialize EPQ state.
2346  */
2347  EvalPlanQualBegin(epqstate);
2348 
2349  /*
2350  * Callers will often use the EvalPlanQualSlot to store the tuple to avoid
2351  * an unnecessary copy.
2352  */
2353  testslot = EvalPlanQualSlot(epqstate, relation, rti);
2354  if (testslot != inputslot)
2355  ExecCopySlot(testslot, inputslot);
2356 
2357  /*
2358  * Run the EPQ query. We assume it will return at most one tuple.
2359  */
2360  slot = EvalPlanQualNext(epqstate);
2361 
2362  /*
2363  * If we got a tuple, force the slot to materialize the tuple so that it
2364  * is not dependent on any local state in the EPQ query (in particular,
2365  * it's highly likely that the slot contains references to any pass-by-ref
2366  * datums that may be present in copyTuple). As with the next step, this
2367  * is to guard against early re-use of the EPQ query.
2368  */
2369  if (!TupIsNull(slot))
2370  ExecMaterializeSlot(slot);
2371 
2372  /*
2373  * Clear out the test tuple. This is needed in case the EPQ query is
2374  * re-used to test a tuple for a different relation. (Not clear that can
2375  * really happen, but let's be safe.)
2376  */
2377  ExecClearTuple(testslot);
2378 
2379  return slot;
2380 }
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:2582
TupleTableSlot * EvalPlanQualSlot(EPQState *epqstate, Relation relation, Index rti)
Definition: execMain.c:2445
#define TupIsNull(slot)
Definition: tuptable.h:292
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition: tuptable.h:443
#define Assert(condition)
Definition: c.h:746
void EvalPlanQualBegin(EPQState *epqstate)
Definition: execMain.c:2598

◆ EvalPlanQualBegin()

void EvalPlanQualBegin ( EPQState epqstate)

Definition at line 2598 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().

2599 {
2600  EState *parentestate = epqstate->parentestate;
2601  EState *recheckestate = epqstate->recheckestate;
2602 
2603  if (recheckestate == NULL)
2604  {
2605  /* First time through, so create a child EState */
2606  EvalPlanQualStart(epqstate, epqstate->plan);
2607  }
2608  else
2609  {
2610  /*
2611  * We already have a suitable child EPQ tree, so just reset it.
2612  */
2613  Index rtsize = parentestate->es_range_table_size;
2614  PlanState *rcplanstate = epqstate->recheckplanstate;
2615 
2616  MemSet(epqstate->relsubs_done, 0, rtsize * sizeof(bool));
2617 
2618  /* Recopy current values of parent parameters */
2619  if (parentestate->es_plannedstmt->paramExecTypes != NIL)
2620  {
2621  int i;
2622 
2623  /*
2624  * Force evaluation of any InitPlan outputs that could be needed
2625  * by the subplan, just in case they got reset since
2626  * EvalPlanQualStart (see comments therein).
2627  */
2628  ExecSetParamPlanMulti(rcplanstate->plan->extParam,
2629  GetPerTupleExprContext(parentestate));
2630 
2631  i = list_length(parentestate->es_plannedstmt->paramExecTypes);
2632 
2633  while (--i >= 0)
2634  {
2635  /* copy value if any, but not execPlan link */
2636  recheckestate->es_param_exec_vals[i].value =
2637  parentestate->es_param_exec_vals[i].value;
2638  recheckestate->es_param_exec_vals[i].isnull =
2639  parentestate->es_param_exec_vals[i].isnull;
2640  }
2641  }
2642 
2643  /*
2644  * Mark child plan tree as needing rescan at all scan nodes. The
2645  * first ExecProcNode will take care of actually doing the rescan.
2646  */
2647  rcplanstate->chgParam = bms_add_member(rcplanstate->chgParam,
2648  epqstate->epqParam);
2649  }
2650 }
List * paramExecTypes
Definition: plannodes.h:84
#define NIL
Definition: pg_list.h:65
void ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext)
Definition: nodeSubplan.c:1245
PlannedStmt * es_plannedstmt
Definition: execnodes.h:525
#define MemSet(start, val, len)
Definition: c.h:950
EState * parentestate
Definition: execnodes.h:1075
#define GetPerTupleExprContext(estate)
Definition: executor.h:509
ParamExecData * es_param_exec_vals
Definition: execnodes.h:554
EState * recheckestate
Definition: execnodes.h:1105
bool isnull
Definition: params.h:150
static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
Definition: execMain.c:2659
bool * relsubs_done
Definition: execnodes.h:1118
Bitmapset * chgParam
Definition: execnodes.h:971
Plan * plan
Definition: execnodes.h:1091
unsigned int Index
Definition: c.h:483
Plan * plan
Definition: execnodes.h:939
static int list_length(const List *l)
Definition: pg_list.h:149
Bitmapset * extParam
Definition: plannodes.h:154
Index es_range_table_size
Definition: execnodes.h:520
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:1076
PlanState * recheckplanstate
Definition: execnodes.h:1120

◆ EvalPlanQualEnd()

void EvalPlanQualEnd ( EPQState epqstate)

Definition at line 2810 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(), and ExecEndModifyTable().

2811 {
2812  EState *estate = epqstate->recheckestate;
2813  Index rtsize;
2814  MemoryContext oldcontext;
2815  ListCell *l;
2816 
2817  rtsize = epqstate->parentestate->es_range_table_size;
2818 
2819  /*
2820  * We may have a tuple table, even if EPQ wasn't started, because we allow
2821  * use of EvalPlanQualSlot() without calling EvalPlanQualBegin().
2822  */
2823  if (epqstate->tuple_table != NIL)
2824  {
2825  memset(epqstate->relsubs_slot, 0,
2826  rtsize * sizeof(TupleTableSlot *));
2827  ExecResetTupleTable(epqstate->tuple_table, true);
2828  epqstate->tuple_table = NIL;
2829  }
2830 
2831  /* EPQ wasn't started, nothing further to do */
2832  if (estate == NULL)
2833  return;
2834 
2835  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
2836 
2837  ExecEndNode(epqstate->recheckplanstate);
2838 
2839  foreach(l, estate->es_subplanstates)
2840  {
2841  PlanState *subplanstate = (PlanState *) lfirst(l);
2842 
2843  ExecEndNode(subplanstate);
2844  }
2845 
2846  /* throw away the per-estate tuple table, some node may have used it */
2847  ExecResetTupleTable(estate->es_tupleTable, false);
2848 
2849  /* Close any result and trigger target relations attached to this EState */
2850  ExecCloseResultRelations(estate);
2851 
2852  MemoryContextSwitchTo(oldcontext);
2853 
2854  FreeExecutorState(estate);
2855 
2856  /* Mark EPQState idle */
2857  epqstate->origslot = NULL;
2858  epqstate->recheckestate = NULL;
2859  epqstate->recheckplanstate = NULL;
2860  epqstate->relsubs_rowmark = NULL;
2861  epqstate->relsubs_done = NULL;
2862 }
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1084
#define NIL
Definition: pg_list.h:65
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:543
void ExecCloseResultRelations(EState *estate)
Definition: execMain.c:1430
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
EState * parentestate
Definition: execnodes.h:1075
void FreeExecutorState(EState *estate)
Definition: execUtils.c:185
MemoryContext es_query_cxt
Definition: execnodes.h:559
EState * recheckestate
Definition: execnodes.h:1105
List * tuple_table
Definition: execnodes.h:1083
bool * relsubs_done
Definition: execnodes.h:1118
TupleTableSlot * origslot
Definition: execnodes.h:1100
List * es_tupleTable
Definition: execnodes.h:561
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:1161
unsigned int Index
Definition: c.h:483
#define lfirst(lc)
Definition: pg_list.h:169
Index es_range_table_size
Definition: execnodes.h:520
List * es_subplanstates
Definition: execnodes.h:571
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1112
PlanState * recheckplanstate
Definition: execnodes.h:1120

◆ EvalPlanQualFetchRowMark()

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

Definition at line 2473 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().

2474 {
2475  ExecAuxRowMark *earm = epqstate->relsubs_rowmark[rti - 1];
2476  ExecRowMark *erm = earm->rowmark;
2477  Datum datum;
2478  bool isNull;
2479 
2480  Assert(earm != NULL);
2481  Assert(epqstate->origslot != NULL);
2482 
2484  elog(ERROR, "EvalPlanQual doesn't support locking rowmarks");
2485 
2486  /* if child rel, must check whether it produced this row */
2487  if (erm->rti != erm->prti)
2488  {
2489  Oid tableoid;
2490 
2491  datum = ExecGetJunkAttribute(epqstate->origslot,
2492  earm->toidAttNo,
2493  &isNull);
2494  /* non-locked rels could be on the inside of outer joins */
2495  if (isNull)
2496  return false;
2497 
2498  tableoid = DatumGetObjectId(datum);
2499 
2500  Assert(OidIsValid(erm->relid));
2501  if (tableoid != erm->relid)
2502  {
2503  /* this child is inactive right now */
2504  return false;
2505  }
2506  }
2507 
2508  if (erm->markType == ROW_MARK_REFERENCE)
2509  {
2510  Assert(erm->relation != NULL);
2511 
2512  /* fetch the tuple's ctid */
2513  datum = ExecGetJunkAttribute(epqstate->origslot,
2514  earm->ctidAttNo,
2515  &isNull);
2516  /* non-locked rels could be on the inside of outer joins */
2517  if (isNull)
2518  return false;
2519 
2520  /* fetch requests on foreign tables must be passed to their FDW */
2521  if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2522  {
2523  FdwRoutine *fdwroutine;
2524  bool updated = false;
2525 
2526  fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
2527  /* this should have been checked already, but let's be safe */
2528  if (fdwroutine->RefetchForeignRow == NULL)
2529  ereport(ERROR,
2530  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2531  errmsg("cannot lock rows in foreign table \"%s\"",
2533 
2534  fdwroutine->RefetchForeignRow(epqstate->recheckestate,
2535  erm,
2536  datum,
2537  slot,
2538  &updated);
2539  if (TupIsNull(slot))
2540  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2541 
2542  /*
2543  * Ideally we'd insist on updated == false here, but that assumes
2544  * that FDWs can track that exactly, which they might not be able
2545  * to. So just ignore the flag.
2546  */
2547  return true;
2548  }
2549  else
2550  {
2551  /* ordinary table, fetch the tuple */
2553  (ItemPointer) DatumGetPointer(datum),
2554  SnapshotAny, slot))
2555  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2556  return true;
2557  }
2558  }
2559  else
2560  {
2561  Assert(erm->markType == ROW_MARK_COPY);
2562 
2563  /* fetch the whole-row Var for the relation */
2564  datum = ExecGetJunkAttribute(epqstate->origslot,
2565  earm->wholeAttNo,
2566  &isNull);
2567  /* non-locked rels could be on the inside of outer joins */
2568  if (isNull)
2569  return false;
2570 
2571  ExecStoreHeapTupleDatum(datum, slot);
2572  return true;
2573  }
2574 }
Relation relation
Definition: execnodes.h:631
#define DatumGetObjectId(X)
Definition: postgres.h:500
int errcode(int sqlerrcode)
Definition: elog.c:610
Form_pg_class rd_rel
Definition: rel.h:109
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:652
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:1033
ExecRowMark * rowmark
Definition: execnodes.h:658
#define ERROR
Definition: elog.h:43
EState * recheckestate
Definition: execnodes.h:1105
Index rti
Definition: execnodes.h:633
AttrNumber wholeAttNo
Definition: execnodes.h:661
Index prti
Definition: execnodes.h:634
#define RelationGetRelationName(relation)
Definition: rel.h:490
#define TupIsNull(slot)
Definition: tuptable.h:292
TupleTableSlot * origslot
Definition: execnodes.h:1100
void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot)
Definition: execTuples.c:1576
static bool table_tuple_fetch_row_version(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
Definition: tableam.h:1071
uintptr_t Datum
Definition: postgres.h:367
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:746
RowMarkType markType
Definition: execnodes.h:636
AttrNumber toidAttNo
Definition: execnodes.h:660
#define SnapshotAny
Definition: snapmgr.h:68
#define DatumGetPointer(X)
Definition: postgres.h:549
int errmsg(const char *fmt,...)
Definition: elog.c:821
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Definition: foreign.c:427
Datum ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, bool *isNull)
Definition: execJunk.c:273
#define elog(elevel,...)
Definition: elog.h:214
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1112
AttrNumber ctidAttNo
Definition: execnodes.h:659
RefetchForeignRow_function RefetchForeignRow
Definition: fdwapi.h:225

◆ EvalPlanQualInit()

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

Definition at line 2390 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, and EPQState::tuple_table.

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

2392 {
2393  Index rtsize = parentestate->es_range_table_size;
2394 
2395  /* initialize data not changing over EPQState's lifetime */
2396  epqstate->parentestate = parentestate;
2397  epqstate->epqParam = epqParam;
2398 
2399  /*
2400  * Allocate space to reference a slot for each potential rti - do so now
2401  * rather than in EvalPlanQualBegin(), as done for other dynamically
2402  * allocated resources, so EvalPlanQualSlot() can be used to hold tuples
2403  * that *may* need EPQ later, without forcing the overhead of
2404  * EvalPlanQualBegin().
2405  */
2406  epqstate->tuple_table = NIL;
2407  epqstate->relsubs_slot = (TupleTableSlot **)
2408  palloc0(rtsize * sizeof(TupleTableSlot *));
2409 
2410  /* ... and remember data that EvalPlanQualBegin will need */
2411  epqstate->plan = subplan;
2412  epqstate->arowMarks = auxrowmarks;
2413 
2414  /* ... and mark the EPQ state inactive */
2415  epqstate->origslot = NULL;
2416  epqstate->recheckestate = NULL;
2417  epqstate->recheckplanstate = NULL;
2418  epqstate->relsubs_rowmark = NULL;
2419  epqstate->relsubs_done = NULL;
2420 }
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1084
#define NIL
Definition: pg_list.h:65
EState * parentestate
Definition: execnodes.h:1075
EState * recheckestate
Definition: execnodes.h:1105
List * arowMarks
Definition: execnodes.h:1092
List * tuple_table
Definition: execnodes.h:1083
bool * relsubs_done
Definition: execnodes.h:1118
TupleTableSlot * origslot
Definition: execnodes.h:1100
Plan * plan
Definition: execnodes.h:1091
void * palloc0(Size size)
Definition: mcxt.c:981
unsigned int Index
Definition: c.h:483
Index es_range_table_size
Definition: execnodes.h:520
int epqParam
Definition: execnodes.h:1076
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1112
PlanState * recheckplanstate
Definition: execnodes.h:1120

◆ EvalPlanQualNext()

TupleTableSlot* EvalPlanQualNext ( EPQState epqstate)

Definition at line 2582 of file execMain.c.

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

Referenced by EvalPlanQual(), and ExecLockRows().

2583 {
2584  MemoryContext oldcontext;
2585  TupleTableSlot *slot;
2586 
2587  oldcontext = MemoryContextSwitchTo(epqstate->recheckestate->es_query_cxt);
2588  slot = ExecProcNode(epqstate->recheckplanstate);
2589  MemoryContextSwitchTo(oldcontext);
2590 
2591  return slot;
2592 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:559
EState * recheckestate
Definition: execnodes.h:1105
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition: executor.h:242
PlanState * recheckplanstate
Definition: execnodes.h:1120

◆ EvalPlanQualSetPlan()

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

Definition at line 2428 of file execMain.c.

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

Referenced by ExecInitModifyTable(), and ExecModifyTable().

2429 {
2430  /* If we have a live EPQ query, shut it down */
2431  EvalPlanQualEnd(epqstate);
2432  /* And set/change the plan pointer */
2433  epqstate->plan = subplan;
2434  /* The rowmarks depend on the plan, too */
2435  epqstate->arowMarks = auxrowmarks;
2436 }
void EvalPlanQualEnd(EPQState *epqstate)
Definition: execMain.c:2810
List * arowMarks
Definition: execnodes.h:1092
Plan * plan
Definition: execnodes.h:1091

◆ EvalPlanQualSlot()

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

Definition at line 2445 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(), ExecLockRows(), and ExecUpdate().

2447 {
2448  TupleTableSlot **slot;
2449 
2450  Assert(relation);
2451  Assert(rti > 0 && rti <= epqstate->parentestate->es_range_table_size);
2452  slot = &epqstate->relsubs_slot[rti - 1];
2453 
2454  if (*slot == NULL)
2455  {
2456  MemoryContext oldcontext;
2457 
2458  oldcontext = MemoryContextSwitchTo(epqstate->parentestate->es_query_cxt);
2459  *slot = table_slot_create(relation, &epqstate->tuple_table);
2460  MemoryContextSwitchTo(oldcontext);
2461  }
2462 
2463  return *slot;
2464 }
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:91
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1084
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
EState * parentestate
Definition: execnodes.h:1075
MemoryContext es_query_cxt
Definition: execnodes.h:559
List * tuple_table
Definition: execnodes.h:1083
#define Assert(condition)
Definition: c.h:746

◆ exec_rt_fetch()

◆ ExecAssignExprContext()

◆ ExecAssignProjectionInfo()

void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

Definition at line 534 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().

536 {
537  planstate->ps_ProjInfo =
539  planstate->ps_ExprContext,
540  planstate->ps_ResultTupleSlot,
541  planstate,
542  inputDesc);
543 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:979
ExprContext * ps_ExprContext
Definition: execnodes.h:978
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:977
Plan * plan
Definition: execnodes.h:939
List * targetlist
Definition: plannodes.h:136
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,
Index  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:1331
void ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, Index varno)
Definition: execUtils.c:554
PlanState ps
Definition: execnodes.h:1328
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:124

◆ ExecAssignScanType()

void ExecAssignScanType ( ScanState scanstate,
TupleDesc  tupDesc 
)

Definition at line 669 of file execUtils.c.

References ExecSetSlotDescriptor(), and ScanState::ss_ScanTupleSlot.

Referenced by ExecWorkTableScan().

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

◆ 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 2266 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 ExecInitLockRows(), and ExecInitModifyTable().

2267 {
2268  ExecAuxRowMark *aerm = (ExecAuxRowMark *) palloc0(sizeof(ExecAuxRowMark));
2269  char resname[32];
2270 
2271  aerm->rowmark = erm;
2272 
2273  /* Look up the resjunk columns associated with this rowmark */
2274  if (erm->markType != ROW_MARK_COPY)
2275  {
2276  /* need ctid for all methods other than COPY */
2277  snprintf(resname, sizeof(resname), "ctid%u", erm->rowmarkId);
2278  aerm->ctidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2279  resname);
2280  if (!AttributeNumberIsValid(aerm->ctidAttNo))
2281  elog(ERROR, "could not find junk %s column", resname);
2282  }
2283  else
2284  {
2285  /* need wholerow if COPY */
2286  snprintf(resname, sizeof(resname), "wholerow%u", erm->rowmarkId);
2287  aerm->wholeAttNo = ExecFindJunkAttributeInTlist(targetlist,
2288  resname);
2289  if (!AttributeNumberIsValid(aerm->wholeAttNo))
2290  elog(ERROR, "could not find junk %s column", resname);
2291  }
2292 
2293  /* if child rel, need tableoid */
2294  if (erm->rti != erm->prti)
2295  {
2296  snprintf(resname, sizeof(resname), "tableoid%u", erm->rowmarkId);
2297  aerm->toidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2298  resname);
2299  if (!AttributeNumberIsValid(aerm->toidAttNo))
2300  elog(ERROR, "could not find junk %s column", resname);
2301  }
2302 
2303  return aerm;
2304 }
AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
Definition: execJunk.c:246
ExecRowMark * rowmark
Definition: execnodes.h:658
#define ERROR
Definition: elog.h:43
Index rti
Definition: execnodes.h:633
AttrNumber wholeAttNo
Definition: execnodes.h:661
Index prti
Definition: execnodes.h:634
Index rowmarkId
Definition: execnodes.h:635
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
void * palloc0(Size size)
Definition: mcxt.c:981
RowMarkType markType
Definition: execnodes.h:636
AttrNumber toidAttNo
Definition: execnodes.h:660
#define elog(elevel,...)
Definition: elog.h:214
#define snprintf
Definition: port.h:215
AttrNumber ctidAttNo
Definition: execnodes.h:659

◆ 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 3333 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().

3340 {
3342  ExprEvalStep scratch = {0};
3343  int maxatt = -1;
3344  List *adjust_jumps = NIL;
3345  ListCell *lc;
3346 
3347  /*
3348  * When no columns are actually compared, the result's always true. See
3349  * special case in ExecQual().
3350  */
3351  if (numCols == 0)
3352  return NULL;
3353 
3354  state->expr = NULL;
3355  state->flags = EEO_FLAG_IS_QUAL;
3356  state->parent = parent;
3357 
3358  scratch.resvalue = &state->resvalue;
3359  scratch.resnull = &state->resnull;
3360 
3361  /* compute max needed attribute */
3362  for (int natt = 0; natt < numCols; natt++)
3363  {
3364  int attno = keyColIdx[natt];
3365 
3366  if (attno > maxatt)
3367  maxatt = attno;
3368  }
3369  Assert(maxatt >= 0);
3370 
3371  /* push deform steps */
3372  scratch.opcode = EEOP_INNER_FETCHSOME;
3373  scratch.d.fetch.last_var = maxatt;
3374  scratch.d.fetch.fixed = false;
3375  scratch.d.fetch.known_desc = ldesc;
3376  scratch.d.fetch.kind = lops;
3377  if (ExecComputeSlotInfo(state, &scratch))
3378  ExprEvalPushStep(state, &scratch);
3379 
3380  scratch.opcode = EEOP_OUTER_FETCHSOME;
3381  scratch.d.fetch.last_var = maxatt;
3382  scratch.d.fetch.fixed = false;
3383  scratch.d.fetch.known_desc = rdesc;
3384  scratch.d.fetch.kind = rops;
3385  if (ExecComputeSlotInfo(state, &scratch))
3386  ExprEvalPushStep(state, &scratch);
3387 
3388  /*
3389  * Start comparing at the last field (least significant sort key). That's
3390  * the most likely to be different if we are dealing with sorted input.
3391  */
3392  for (int natt = numCols; --natt >= 0;)
3393  {
3394  int attno = keyColIdx[natt];
3395  Form_pg_attribute latt = TupleDescAttr(ldesc, attno - 1);
3396  Form_pg_attribute ratt = TupleDescAttr(rdesc, attno - 1);
3397  Oid foid = eqfunctions[natt];
3398  Oid collid = collations[natt];
3399  FmgrInfo *finfo;
3400  FunctionCallInfo fcinfo;
3401  AclResult aclresult;
3402 
3403  /* Check permission to call function */
3404  aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
3405  if (aclresult != ACLCHECK_OK)
3406  aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid));
3407 
3409 
3410  /* Set up the primary fmgr lookup information */
3411  finfo = palloc0(sizeof(FmgrInfo));
3412  fcinfo = palloc0(SizeForFunctionCallInfo(2));
3413  fmgr_info(foid, finfo);
3414  fmgr_info_set_expr(NULL, finfo);
3415  InitFunctionCallInfoData(*fcinfo, finfo, 2,
3416  collid, NULL, NULL);
3417 
3418  /* left arg */
3419  scratch.opcode = EEOP_INNER_VAR;
3420  scratch.d.var.attnum = attno - 1;
3421  scratch.d.var.vartype = latt->atttypid;
3422  scratch.resvalue = &fcinfo->args[0].value;
3423  scratch.resnull = &fcinfo->args[0].isnull;
3424  ExprEvalPushStep(state, &scratch);
3425 
3426  /* right arg */
3427  scratch.opcode = EEOP_OUTER_VAR;
3428  scratch.d.var.attnum = attno - 1;
3429  scratch.d.var.vartype = ratt->atttypid;
3430  scratch.resvalue = &fcinfo->args[1].value;
3431  scratch.resnull = &fcinfo->args[1].isnull;
3432  ExprEvalPushStep(state, &scratch);
3433 
3434  /* evaluate distinctness */
3435  scratch.opcode = EEOP_NOT_DISTINCT;
3436  scratch.d.func.finfo = finfo;
3437  scratch.d.func.fcinfo_data = fcinfo;
3438  scratch.d.func.fn_addr = finfo->fn_addr;
3439  scratch.d.func.nargs = 2;
3440  scratch.resvalue = &state->resvalue;
3441  scratch.resnull = &state->resnull;
3442  ExprEvalPushStep(state, &scratch);
3443 
3444  /* then emit EEOP_QUAL to detect if result is false (or null) */
3445  scratch.opcode = EEOP_QUAL;
3446  scratch.d.qualexpr.jumpdone = -1;
3447  scratch.resvalue = &state->resvalue;
3448  scratch.resnull = &state->resnull;
3449  ExprEvalPushStep(state, &scratch);
3450  adjust_jumps = lappend_int(adjust_jumps,
3451  state->steps_len - 1);
3452  }
3453 
3454  /* adjust jump targets */
3455  foreach(lc, adjust_jumps)
3456  {
3457  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
3458 
3459  Assert(as->opcode == EEOP_QUAL);
3460  Assert(as->d.qualexpr.jumpdone == -1);
3461  as->d.qualexpr.jumpdone = state->steps_len;
3462  }
3463 
3464  scratch.resvalue = NULL;
3465  scratch.resnull = NULL;
3466  scratch.opcode = EEOP_DONE;
3467  ExprEvalPushStep(state, &scratch);
3468 
3469  ExecReadyExpr(state);
3470 
3471  return state;
3472 }
#define NIL
Definition: pg_list.h:65
Definition: fmgr.h:56
struct PlanState * parent
Definition: execnodes.h:107
Datum * resvalue
Definition: execExpr.h:252
Oid GetUserId(void)
Definition: miscinit.c:476
PGFunction fn_addr
Definition: fmgr.h:58
struct ExprEvalStep * steps
Definition: execnodes.h:84
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define SizeForFunctionCallInfo(nargs)
Definition: fmgr.h:102
struct ExprEvalStep::@51::@52 fetch
bool * resnull
Definition: execExpr.h:253
unsigned int Oid
Definition: postgres_ext.h:31
struct ExprEvalStep::@51::@58 func
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
bool resnull
Definition: execnodes.h:71
Expr * expr
Definition: execnodes.h:93
#define lfirst_int(lc)
Definition: pg_list.h:170
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1520
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:58
#define fmgr_info_set_expr(expr, finfo)
Definition: fmgr.h:135
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
Datum value
Definition: postgres.h:378
List * lappend_int(List *list, int datum)
Definition: list.c:339
#define InvokeFunctionExecuteHook(objectId)
Definition: objectaccess.h:191
union ExprEvalStep::@51 d
void * palloc0(Size size)
Definition: mcxt.c:981
AclResult
Definition: acl.h:177
static bool ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op)
Definition: execExpr.c:2355
void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2108
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:629
struct ExprEvalStep::@51::@53 var
#define makeNode(_type_)
Definition: nodes.h:576
#define Assert(condition)
Definition: c.h:746
Definition: regguts.h:298
intptr_t opcode
Definition: execExpr.h:249
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:150
int steps_len
Definition: execnodes.h:103
#define ACL_EXECUTE
Definition: parsenodes.h:81
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4587
uint8 flags
Definition: execnodes.h:64
Definition: pg_list.h:50
Datum resvalue
Definition: execnodes.h:73
struct ExprEvalStep::@51::@60 qualexpr

◆ 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, ExprState::tag, TupleDescAttr, Var::varattno, Var::varno, and Var::vartype.

Referenced by ExecAssignProjectionInfo(), 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.tag = 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 }
NodeTag tag
Definition: execnodes.h:62
#define IsA(nodeptr, _type_)
Definition: nodes.h:579
struct PlanState * parent
Definition: execnodes.h:107
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
ParamListInfo ext_params
Definition: execnodes.h:108
Definition: nodes.h:528
AttrNumber varattno
Definition: primnodes.h:186
struct ExprEvalStep::@51::@55 assign_var
TupleTableSlot * resultslot
Definition: execnodes.h:79
Definition: primnodes.h:181
bool resnull
Definition: execnodes.h:71
Expr * expr
Definition: execnodes.h:93
Oid vartype
Definition: primnodes.h:188
static void ExecInitExprSlots(ExprState *state, Node *node)
Definition: execExpr.c:2239
#define lfirst_node(type, lc)
Definition: pg_list.h:172
AttrNumber resno
Definition: primnodes.h:1411
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
union ExprEvalStep::@51 d
Index varno
Definition: primnodes.h:184
static void ExecInitExprRec(Expr *node, ExprState *state, Datum *resv, bool *resnull)
Definition: execExpr.c:646
void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2108
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:629
int16 attnum
Definition: pg_attribute.h:79
#define INNER_VAR
Definition: primnodes.h:171
#define makeNode(_type_)
Definition: nodes.h:576
struct ExprEvalStep::@51::@56 assign_tmp
Definition: regguts.h:298
intptr_t opcode
Definition: execExpr.h:249
Expr * expr
Definition: primnodes.h:1410
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
int16 get_typlen(Oid typid)
Definition: lsyscache.c:2085
ExprState pi_state
Definition: execnodes.h:332
ExprContext * pi_exprContext
Definition: execnodes.h:334
Datum resvalue
Definition: execnodes.h:73
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:172

◆ ExecCheck()

bool ExecCheck ( ExprState state,
ExprContext context 
)

Definition at line 599 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().

600 {
601  Datum ret;
602  bool isnull;
603 
604  /* short-circuit (here and in ExecInitCheck) for empty restriction list */
605  if (state == NULL)
606  return true;
607 
608  /* verify that expression was not compiled using ExecInitQual */
609  Assert(!(state->flags & EEO_FLAG_IS_QUAL));
610 
611  ret = ExecEvalExprSwitchContext(state, econtext, &isnull);
612 
613  if (isnull)
614  return true;
615 
616  return DatumGetBool(ret);
617 }
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:307
#define EEO_FLAG_IS_QUAL
Definition: execnodes.h:58
#define DatumGetBool(X)
Definition: postgres.h:393
uintptr_t Datum
Definition: postgres.h:367
#define Assert(condition)
Definition: c.h:746
uint8 flags
Definition: execnodes.h:64

◆ ExecCheckIndexConstraints()

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

Definition at line 481 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, 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().

484 {
485  int i;
486  int numIndices;
487  RelationPtr relationDescs;
488  Relation heapRelation;
489  IndexInfo **indexInfoArray;
490  ExprContext *econtext;
492  bool isnull[INDEX_MAX_KEYS];
493  ItemPointerData invalidItemPtr;
494  bool checkedIndex = false;
495 
496  ItemPointerSetInvalid(conflictTid);
497  ItemPointerSetInvalid(&invalidItemPtr);
498 
499  /*
500  * Get information from the result relation info structure.
501  */
502  numIndices = resultRelInfo->ri_NumIndices;
503  relationDescs = resultRelInfo->ri_IndexRelationDescs;
504  indexInfoArray = resultRelInfo->ri_IndexRelationInfo;
505  heapRelation = resultRelInfo->ri_RelationDesc;
506 
507  /*
508  * We will use the EState's per-tuple context for evaluating predicates
509  * and index expressions (creating it if it's not already there).
510  */
511  econtext = GetPerTupleExprContext(estate);
512 
513  /* Arrange for econtext's scan tuple to be the tuple under test */
514  econtext->ecxt_scantuple = slot;
515 
516  /*
517  * For each index, form index tuple and check if it satisfies the
518  * constraint.
519  */
520  for (i = 0; i < numIndices; i++)
521  {
522  Relation indexRelation = relationDescs[i];
523  IndexInfo *indexInfo;
524  bool satisfiesConstraint;
525 
526  if (indexRelation == NULL)
527  continue;
528 
529  indexInfo = indexInfoArray[i];
530 
531  if (!indexInfo->ii_Unique && !indexInfo->ii_ExclusionOps)
532  continue;
533 
534  /* If the index is marked as read-only, ignore it */
535  if (!indexInfo->ii_ReadyForInserts)
536  continue;
537 
538  /* When specific arbiter indexes requested, only examine them */
539  if (arbiterIndexes != NIL &&
540  !list_member_oid(arbiterIndexes,
541  indexRelation->rd_index->indexrelid))
542  continue;
543 
544  if (!indexRelation->rd_index->indimmediate)
545  ereport(ERROR,
546  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
547  errmsg("ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters"),
548  errtableconstraint(heapRelation,
549  RelationGetRelationName(indexRelation))));
550 
551  checkedIndex = true;
552 
553  /* Check for partial index */
554  if (indexInfo->ii_Predicate != NIL)
555  {
556  ExprState *predicate;
557 
558  /*
559  * If predicate state not set up yet, create it (in the estate's
560  * per-query context)
561  */
562  predicate = indexInfo->ii_PredicateState;
563  if (predicate == NULL)
564  {
565  predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
566  indexInfo->ii_PredicateState = predicate;
567  }
568 
569  /* Skip this index-update if the predicate isn't satisfied */
570  if (!ExecQual(predicate, econtext))
571  continue;
572  }
573 
574  /*
575  * FormIndexDatum fills in its values and isnull parameters with the
576  * appropriate values for the column(s) of the index.
577  */
578  FormIndexDatum(indexInfo,
579  slot,
580  estate,
581  values,
582  isnull);
583 
584  satisfiesConstraint =
585  check_exclusion_or_unique_constraint(heapRelation, indexRelation,
586  indexInfo, &invalidItemPtr,
587  values, isnull, estate, false,
588  CEOUC_WAIT, true,
589  conflictTid);
590  if (!satisfiesConstraint)
591  return false;
592  }
593 
594  if (arbiterIndexes != NIL && !checkedIndex)
595  elog(ERROR, "unexpected failure to find arbiter index");
596 
597  return true;
598 }
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
Definition: index.c:2585
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:162
ExprState * ii_PredicateState
Definition: execnodes.h:163
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:372
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:643
#define GetPerTupleExprContext(estate)
Definition: executor.h:509
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5551
Form_pg_index rd_index
Definition: rel.h:174
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:490
ExprState * ExecPrepareQual(List *qual, EState *estate)
Definition: execExpr.c:520
bool ii_ReadyForInserts
Definition: execnodes.h:172
uintptr_t Datum
Definition: postgres.h:367
#define ereport(elevel,...)
Definition: elog.h:144
bool ii_Unique
Definition: execnodes.h:171
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674
#define INDEX_MAX_KEYS
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:225
static Datum values[MAXATTR]
Definition: bootstrap.c:165
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
Oid * ii_ExclusionOps
Definition: execnodes.h:164
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define elog(elevel,...)
Definition: elog.h:214
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 571 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(), InitPlan(), intorel_startup(), and RI_Initial_Check().

572 {
573  ListCell *l;
574  bool result = true;
575 
576  foreach(l, rangeTable)
577  {
578  RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
579 
580  result = ExecCheckRTEPerms(rte);
581  if (!result)
582  {
583  Assert(rte->rtekind == RTE_RELATION);
584  if (ereport_on_violation)
586  get_rel_name(rte->relid));
587  return false;
588  }
589  }
590 
592  result = (*ExecutorCheckPerms_hook) (rangeTable,
593  ereport_on_violation);
594  return result;
595 }
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1915
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
static bool ExecCheckRTEPerms(RangeTblEntry *rte)
Definition: execMain.c:602
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
Definition: execMain.c:76
#define Assert(condition)
Definition: c.h:746
#define lfirst(lc)
Definition: pg_list.h:169
RTEKind rtekind
Definition: parsenodes.h:981
ObjectType get_relkind_objtype(char relkind)
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1840

◆ ExecCleanTargetListLength()

int ExecCleanTargetListLength ( List targetlist)

Definition at line 1146 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

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

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

◆ ExecCleanTypeFromTL()

TupleDesc ExecCleanTypeFromTL ( List targetList)

Definition at line 1920 of file execTuples.c.

References ExecTypeFromTLInternal().

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

1921 {
1922  return ExecTypeFromTLInternal(targetList, true);
1923 }
static TupleDesc ExecTypeFromTLInternal(List *targetList, bool skipjunk)
Definition: execTuples.c:1926

◆ ExecCloseIndices()

void ExecCloseIndices ( ResultRelInfo resultRelInfo)

Definition at line 226 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().

227 {
228  int i;
229  int numIndices;
230  RelationPtr indexDescs;
231 
232  numIndices = resultRelInfo->ri_NumIndices;
233  indexDescs = resultRelInfo->ri_IndexRelationDescs;
234 
235  for (i = 0; i < numIndices; i++)
236  {
237  if (indexDescs[i] == NULL)
238  continue; /* shouldn't happen? */
239 
240  /* Drop lock acquired by ExecOpenIndices */
241  index_close(indexDescs[i], RowExclusiveLock);
242  }
243 
244  /*
245  * XXX should free indexInfo array here too? Currently we assume that
246  * such stuff will be cleaned up automatically in FreeExecutorState.
247  */
248 }
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 1473 of file execMain.c.

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

Referenced by CopyFrom(), and ExecEndPlan().

1474 {
1475  int i;
1476 
1477  for (i = 0; i < estate->es_range_table_size; i++)
1478  {
1479  if (estate->es_relations[i])
1480  table_close(estate->es_relations[i], NoLock);
1481  }
1482 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
#define NoLock
Definition: lockdefs.h:34
Relation * es_relations
Definition: execnodes.h:521
Index es_range_table_size
Definition: execnodes.h:520
int i

◆ ExecCloseResultRelations()

void ExecCloseResultRelations ( EState estate)

Definition at line 1430 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().

1431 {
1432  ListCell *l;
1433 
1434  /*
1435  * close indexes of result relation(s) if any. (Rels themselves are
1436  * closed in ExecCloseRangeTableRelations())
1437  */
1438  foreach(l, estate->es_opened_result_relations)
1439  {
1440  ResultRelInfo *resultRelInfo = lfirst(l);
1441 
1442  ExecCloseIndices(resultRelInfo);
1443  }
1444 
1445  /* Close any relations that have been opened by ExecGetTriggerResultRel(). */
1446  foreach(l, estate->es_trig_target_relations)
1447  {
1448  ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
1449 
1450  /*
1451  * Assert this is a "dummy" ResultRelInfo, see above. Otherwise we
1452  * might be issuing a duplicate close against a Relation opened by
1453  * ExecGetRangeTableRelation.
1454  */
1455  Assert(resultRelInfo->ri_RangeTableIndex == 0);
1456 
1457  /*
1458  * Since ExecGetTriggerResultRel doesn't call ExecOpenIndices for
1459  * these rels, we needn't call ExecCloseIndices either.
1460  */
1461  Assert(resultRelInfo->ri_NumIndices == 0);
1462 
1463  table_close(resultRelInfo->ri_RelationDesc, NoLock);
1464  }
1465 }
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:537
List * es_trig_target_relations
Definition: execnodes.h:550
#define Assert(condition)
Definition: c.h:746
#define lfirst(lc)
Definition: pg_list.h:169
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
Definition: execIndexing.c:226

◆ ExecConditionalAssignProjectionInfo()

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

Definition at line 554 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().

556 {
557  if (tlist_matches_tupdesc(planstate,
558  planstate->plan->targetlist,
559  varno,
560  inputDesc))
561  {
562  planstate->ps_ProjInfo = NULL;
563  planstate->resultopsset = planstate->scanopsset;
564  planstate->resultopsfixed = planstate->scanopsfixed;
565  planstate->resultops = planstate->scanops;
566  }
567  else
568  {
569  if (!planstate->ps_ResultTupleSlot)
570  {
571  ExecInitResultSlot(planstate, &TTSOpsVirtual);
572  planstate->resultops = &TTSOpsVirtual;
573  planstate->resultopsfixed = true;
574  planstate->resultopsset = true;
575  }
576  ExecAssignProjectionInfo(planstate, inputDesc);
577  }
578 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:979
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
const TupleTableSlotOps * resultops
Definition: execnodes.h:1014
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:977
const TupleTableSlotOps * scanops
Definition: execnodes.h:1011
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:534
bool resultopsset
Definition: execnodes.h:1022
Plan * plan
Definition: execnodes.h:939
bool scanopsfixed
Definition: execnodes.h:1015
void ExecInitResultSlot(PlanState *planstate, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1749
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
Definition: execUtils.c:581
bool scanopsset
Definition: execnodes.h:1019
List * targetlist
Definition: plannodes.h:136
bool resultopsfixed
Definition: execnodes.h:1018

◆ ExecConstraints()

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

Definition at line 1801 of file execMain.c.

References Assert, bms_union(), build_attrmap_by_name_if_req(), TupleDescData::constr, ereport, errcode(), errdetail(), errmsg(), ERROR, errtablecol(), errtableconstraint(), ExecBuildSlotValueDescription(), ExecRelCheck(), execute_attr_map_slot(), GetInsertedColumns, GetUpdatedColumns, TupleConstr::has_not_null, MakeTupleTableSlot(), NameStr, TupleDescData::natts, TupleConstr::num_check, RelationGetDescr, RelationGetRelationName, RelationGetRelid, ResultRelInfo::ri_PartitionRoot, ResultRelInfo::ri_RelationDesc, slot_attisnull(), TTSOpsVirtual, and TupleDescAttr.

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

1803 {
1804  Relation rel = resultRelInfo->ri_RelationDesc;
1805  TupleDesc tupdesc = RelationGetDescr(rel);
1806  TupleConstr *constr = tupdesc->constr;
1807  Bitmapset *modifiedCols;
1808  Bitmapset *insertedCols;
1809  Bitmapset *updatedCols;
1810 
1811  Assert(constr); /* we should not be called otherwise */
1812 
1813  if (constr->has_not_null)
1814  {
1815  int natts = tupdesc->natts;
1816  int attrChk;
1817 
1818  for (attrChk = 1; attrChk <= natts; attrChk++)
1819  {
1820  Form_pg_attribute att = TupleDescAttr(tupdesc, attrChk - 1);
1821 
1822  if (att->attnotnull && slot_attisnull(slot, attrChk))
1823  {
1824  char *val_desc;
1825  Relation orig_rel = rel;
1826  TupleDesc orig_tupdesc = RelationGetDescr(rel);
1827 
1828  /*
1829  * If the tuple has been routed, it's been converted to the
1830  * partition's rowtype, which might differ from the root
1831  * table's. We must convert it back to the root table's
1832  * rowtype so that val_desc shown error message matches the
1833  * input tuple.
1834  */
1835  if (resultRelInfo->ri_PartitionRoot)
1836  {
1837  AttrMap *map;
1838 
1839  rel = resultRelInfo->ri_PartitionRoot;
1840  tupdesc = RelationGetDescr(rel);
1841  /* a reverse map */
1842  map = build_attrmap_by_name_if_req(orig_tupdesc,
1843  tupdesc);
1844 
1845  /*
1846  * Partition-specific slot's tupdesc can't be changed, so
1847  * allocate a new one.
1848  */
1849  if (map != NULL)
1850  slot = execute_attr_map_slot(map, slot,
1851  MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
1852  }
1853 
1854  insertedCols = GetInsertedColumns(resultRelInfo, estate);
1855  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
1856  modifiedCols = bms_union(insertedCols, updatedCols);
1858  slot,
1859  tupdesc,
1860  modifiedCols,
1861  64);
1862 
1863  ereport(ERROR,
1864  (errcode(ERRCODE_NOT_NULL_VIOLATION),
1865  errmsg("null value in column \"%s\" of relation \"%s\" violates not-null constraint",
1866  NameStr(att->attname),
1867  RelationGetRelationName(orig_rel)),
1868  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1869  errtablecol(orig_rel, attrChk)));
1870  }
1871  }
1872  }
1873 
1874  if (constr->num_check > 0)
1875  {
1876  const char *failed;
1877 
1878  if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
1879  {
1880  char *val_desc;
1881  Relation orig_rel = rel;
1882 
1883  /* See the comment above. */
1884  if (resultRelInfo->ri_PartitionRoot)
1885  {
1886  TupleDesc old_tupdesc = RelationGetDescr(rel);
1887  AttrMap *map;
1888 
1889  rel = resultRelInfo->ri_PartitionRoot;
1890  tupdesc = RelationGetDescr(rel);
1891  /* a reverse map */
1892  map = build_attrmap_by_name_if_req(old_tupdesc,
1893  tupdesc);
1894 
1895  /*
1896  * Partition-specific slot's tupdesc can't be changed, so
1897  * allocate a new one.
1898  */
1899  if (map != NULL)
1900  slot = execute_attr_map_slot(map, slot,
1901  MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
1902  }
1903 
1904  insertedCols = GetInsertedColumns(resultRelInfo, estate);
1905  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
1906  modifiedCols = bms_union(insertedCols, updatedCols);
1908  slot,
1909  tupdesc,
1910  modifiedCols,
1911  64);
1912  ereport(ERROR,
1913  (errcode(ERRCODE_CHECK_VIOLATION),
1914  errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
1915  RelationGetRelationName(orig_rel), failed),
1916  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1917  errtableconstraint(orig_rel, failed)));
1918  }
1919  }
1920 }
#define GetUpdatedColumns(relinfo, estate)
Definition: execMain.c:111
Relation ri_RelationDesc
Definition: execnodes.h:412
#define RelationGetDescr(relation)
Definition: rel.h:482
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
Relation ri_PartitionRoot
Definition: execnodes.h:490
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
int errcode(int sqlerrcode)
Definition: elog.c:610
Definition: attmap.h:34
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5551
AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc)
Definition: attmap.c:259
#define ERROR
Definition: elog.h:43
static char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
Definition: execMain.c:2080
TupleConstr * constr
Definition: tupdesc.h:85
int errdetail(const char *fmt,...)
Definition: elog.c:954
#define RelationGetRelationName(relation)
Definition: rel.h:490
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
TupleTableSlot * MakeTupleTableSlot(TupleDesc tupleDesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1082
uint16 num_check
Definition: tupdesc.h:43
static const char * ExecRelCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1613
#define ereport(elevel,...)
Definition: elog.h:144
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition: tupconvert.c:177
#define Assert(condition)
Definition: c.h:746
int errtablecol(Relation rel, int attnum)
Definition: relcache.c:5514
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:225
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define NameStr(name)
Definition: c.h:623
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:456
#define GetInsertedColumns(relinfo, estate)
Definition: execMain.c:109

◆ ExecCreateScanSlotFromOuterPlan()

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

Definition at line 681 of file execUtils.c.

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

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

684 {
686  TupleDesc tupDesc;
687 
688  outerPlan = outerPlanState(scanstate);
689  tupDesc = ExecGetResultType(outerPlan);
690 
691  ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops);
692 }
#define outerPlanState(node)
Definition: execnodes.h:1033
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1781
#define outerPlan(node)
Definition: plannodes.h:166
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:489

◆ 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:579
static ScanState * search_plan_tree(PlanState *node, Oid table_oid, bool *pending_rescan)
Definition: execCurrent.c:310
bool atEnd
Definition: portal.h:191
EState * estate
Definition: execdesc.h:48
Portal GetPortalByName(const char *name)
Definition: portalmem.c:130
#define DatumGetObjectId(X)
Definition: postgres.h:500
int errcode(int sqlerrcode)
Definition: elog.c:610
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1331
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:1033
ItemPointerData * ItemPointer
Definition: itemptr.h:49
ItemPointerData curCtid
Definition: execnodes.h:640
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:523
#define ERROR
Definition: elog.h:43
PlanState * planstate
Definition: execdesc.h:49
ItemPointerData xs_heaptid
Definition: relscan.h:144
#define TupIsNull(slot)
Definition: tuptable.h:292
#define TableOidAttributeNumber
Definition: sysattr.h:26
char * cursor_name
Definition: primnodes.h:1320
PortalStrategy strategy
Definition: portal.h:145
QueryDesc * queryDesc
Definition: portal.h:156
#define PortalIsValid(p)
Definition: portal.h:203
uintptr_t Datum
Definition: postgres.h:367
unsigned int Index
Definition: c.h:483
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:746
RowMarkType markType
Definition: execnodes.h:636
Index es_range_table_size
Definition: execnodes.h:520
#define DatumGetPointer(X)
Definition: postgres.h:549
bool atStart
Definition: portal.h:190
int errmsg(const char *fmt,...)
Definition: elog.c:821
#define elog(elevel,...)
Definition: elog.h:214
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:1840

◆ ExecEndNode()

void ExecEndNode ( PlanState node)

Definition at line 543 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(), ExecEndMergeAppend(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNamedTuplestoreScan(), ExecEndNestLoop(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSampleScan(), ExecEndSeqScan(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndTableFuncScan(), 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_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_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(), ExecEndMergeAppend(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNestLoop(), ExecEndPlan(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndUnique(), and ExecEndWindowAgg().

544 {
545  /*
546  * do nothing when we get to the end of a leaf on tree.
547  */
548  if (node == NULL)
549  return;
550 
551  /*
552  * Make sure there's enough stack available. Need to check here, in
553  * addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not
554  * guaranteed that ExecProcNode() is reached for all nodes.
555  */
557 
558  if (node->chgParam != NULL)
559  {
560  bms_free(node->chgParam);
561  node->chgParam = NULL;
562  }
563 
564  switch (nodeTag(node))
565  {
566  /*
567  * control nodes
568  */
569  case T_ResultState:
570  ExecEndResult((ResultState *) node);
571  break;
572 
573  case T_ProjectSetState:
575  break;
576 
577  case T_ModifyTableState:
579  break;
580 
581  case T_AppendState:
582  ExecEndAppend((AppendState *) node);
583  break;
584 
585  case T_MergeAppendState:
587  break;
588 
591  break;
592 
593  case T_BitmapAndState:
595  break;
596 
597  case T_BitmapOrState:
598  ExecEndBitmapOr((BitmapOrState *) node);
599  break;
600 
601  /*
602  * scan nodes
603  */
604  case T_SeqScanState:
605  ExecEndSeqScan((SeqScanState *) node);
606  break;
607 
608  case T_SampleScanState:
610  break;
611 
612  case T_GatherState:
613  ExecEndGather((GatherState *) node);
614  break;
615 
616  case T_GatherMergeState:
618  break;
619 
620  case T_IndexScanState:
622  break;
623 
626  break;
627 
630  break;
631 
634  break;
635 
636  case T_TidScanState:
637  ExecEndTidScan((TidScanState *) node);
638  break;
639 
640  case T_SubqueryScanState:
642  break;
643 
644  case T_FunctionScanState:
646  break;
647 
650  break;
651 
652  case T_ValuesScanState:
654  break;
655 
656  case T_CteScanState:
657  ExecEndCteScan((CteScanState *) node);
658  break;
659 
662  break;
663 
666  break;
667 
668  case T_ForeignScanState:
670  break;
671 
672  case T_CustomScanState:
674  break;
675 
676  /*
677  * join nodes
678  */
679  case T_NestLoopState:
680  ExecEndNestLoop((NestLoopState *) node);
681  break;
682 
683  case T_MergeJoinState:
685  break;
686 
687  case T_HashJoinState:
688  ExecEndHashJoin((HashJoinState *) node);
689  break;
690 
691  /*
692  * materialization nodes
693  */
694  case T_MaterialState:
695  ExecEndMaterial((MaterialState *) node);
696  break;
697 
698  case T_SortState:
699  ExecEndSort((SortState *) node);
700  break;
701 
704  break;
705 
706  case T_GroupState:
707  ExecEndGroup((GroupState *) node);
708  break;
709 
710  case T_AggState:
711  ExecEndAgg((AggState *) node);
712  break;
713 
714  case T_WindowAggState:
716  break;
717 
718  case T_UniqueState:
719  ExecEndUnique((UniqueState *) node);
720  break;
721 
722  case T_HashState:
723  ExecEndHash((HashState *) node);
724  break;
725 
726  case T_SetOpState:
727  ExecEndSetOp((SetOpState *) node);
728  break;
729 
730  case T_LockRowsState:
731  ExecEndLockRows((LockRowsState *) node);
732  break;
733 
734  case T_LimitState:
735  ExecEndLimit((LimitState *) node);
736  break;
737 
738  default:
739  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
740  break;
741  }
742 }
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:382
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 ExecEndTableFuncScan(TableFuncScanState *node)
void ExecEndResult(ResultState *node)
Definition: nodeResult.c:241
#define ERROR
Definition: elog.h:43
void ExecEndAppend(AppendState *node)
Definition: nodeAppend.c:294
void ExecEndForeignScan(ForeignScanState *node)
void ExecEndSort(SortState *node)
Definition: nodeSort.c:235
void ExecEndBitmapIndexScan(BitmapIndexScanState *node)
void check_stack_depth(void)
Definition: postgres.c:3312
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:971
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:533
#define elog(elevel,...)
Definition: elog.h:214
void ExecEndHash(HashState *node)
Definition: nodeHash.c:407
void ExecEndProjectSet(ProjectSetState *node)
void ExecEndMaterial(MaterialState *node)
Definition: nodeMaterial.c:240
void ExecEndBitmapHeapScan(BitmapHeapScanState *node)
void ExecEndAgg(AggState *node)
Definition: nodeAgg.c:4561
void ExecEndModifyTable(ModifyTableState *node)
void ExecEndGather(GatherState *node)
Definition: nodeGather.c:249

◆ ExecEvalExpr()

◆ ExecEvalExprSwitchContext()

static Datum ExecEvalExprSwitchContext ( ExprState state,
ExprContext econtext,
bool isNull 
)
inlinestatic

Definition at line 307 of file executor.h.

References ExprContext::ecxt_per_tuple_memory, ExprState::evalfunc, and MemoryContextSwitchTo().

Referenced by advance_aggregates(), evaluate_expr(), EvaluateParams(), ExecCheck(), ExecProject(), ExecQual(), ExecScanSubPlan(), ExecSetParamPlan(), ExecuteCallStmt(), ExecWindowAgg(), FormIndexDatum(), FormPartitionKeyDatum(), get_qual_for_range(), operator_predicate_proof(), partkey_datum_from_expr(), recompute_limits(), tablesample_init(), TidListEval(), and validateDomainConstraint().

310 {
311  Datum retDatum;
312  MemoryContext oldContext;
313 
314  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
315  retDatum = state->evalfunc(state, econtext, isNull);
316  MemoryContextSwitchTo(oldContext);
317  return retDatum;
318 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:233
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ExprStateEvalFunc evalfunc
Definition: execnodes.h:90
uintptr_t Datum
Definition: postgres.h:367

◆ ExecFilterJunk()

TupleTableSlot* ExecFilterJunk ( JunkFilter junkfilter,
TupleTableSlot slot 
)

Definition at line 287 of file execJunk.c.

References ExecClearTuple(), ExecStoreVirtualTuple(), i, JunkFilter::jf_cleanMap, JunkFilter::jf_cleanTupType, JunkFilter::jf_resultSlot, TupleDescData::natts, slot_getallattrs(), TupleTableSlot::tts_isnull, TupleTableSlot::tts_values, and values.

Referenced by ExecBRUpdateTriggers(), ExecCrossPartitionUpdate(), ExecEvalWholeRowVar(), ExecModifyTable(), ExecUpdate(), ExecutePlan(), and sqlfunction_receive().

288 {
289  TupleTableSlot *resultSlot;
290  AttrNumber *cleanMap;
291  TupleDesc cleanTupType;
292  int cleanLength;
293  int i;
294  Datum *values;
295  bool *isnull;
296  Datum *old_values;
297  bool *old_isnull;
298 
299  /*
300  * Extract all the values of the old tuple.
301  */
302  slot_getallattrs(slot);
303  old_values = slot->tts_values;
304  old_isnull = slot->tts_isnull;
305 
306  /*
307  * get info from the junk filter
308  */
309  cleanTupType = junkfilter->jf_cleanTupType;
310  cleanLength = cleanTupType->natts;
311  cleanMap = junkfilter->jf_cleanMap;
312  resultSlot = junkfilter->jf_resultSlot;
313 
314  /*
315  * Prepare to build a virtual result tuple.
316  */
317  ExecClearTuple(resultSlot);
318  values = resultSlot->tts_values;
319  isnull = resultSlot->tts_isnull;
320 
321  /*
322  * Transpose data into proper fields of the new tuple.
323  */
324  for (i = 0; i < cleanLength; i++)
325  {
326  int j = cleanMap[i];
327 
328  if (j == 0)
329  {
330  values[i] = (Datum) 0;
331  isnull[i] = true;
332  }
333  else
334  {
335  values[i] = old_values[j - 1];
336  isnull[i] = old_isnull[j - 1];
337  }
338  }
339 
340  /*
341  * And return the virtual tuple.
342  */
343  return ExecStoreVirtualTuple(resultSlot);
344 }
AttrNumber * jf_cleanMap
Definition: execnodes.h:370
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
TupleTableSlot * jf_resultSlot
Definition: execnodes.h:371
Datum * tts_values
Definition: tuptable.h:126
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:354
bool * tts_isnull
Definition: tuptable.h:128
TupleDesc jf_cleanTupType
Definition: execnodes.h:369
uintptr_t Datum
Definition: postgres.h:367
static Datum values[MAXATTR]
Definition: bootstrap.c:165
int i
int16 AttrNumber
Definition: attnum.h:21
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1522

◆ ExecFindJunkAttribute()

AttrNumber ExecFindJunkAttribute ( JunkFilter junkfilter,
const char *  attrName 
)

Definition at line 234 of file execJunk.c.

References ExecFindJunkAttributeInTlist(), and JunkFilter::jf_targetList.

Referenced by ExecInitModifyTable().

235 {
236  return ExecFindJunkAttributeInTlist(junkfilter->jf_targetList, attrName);
237 }
AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
Definition: execJunk.c:246
List * jf_targetList
Definition: execnodes.h:368

◆ ExecFindJunkAttributeInTlist()

AttrNumber ExecFindJunkAttributeInTlist ( List targetlist,
const char *  attrName 
)

Definition at line 246 of file execJunk.c.

References InvalidAttrNumber, lfirst, TargetEntry::resjunk, TargetEntry::resname, and TargetEntry::resno.

Referenced by create_foreign_modify(), ExecBuildAuxRowMark(), and ExecFindJunkAttribute().

247 {
248  ListCell *t;
249 
250  foreach(t, targetlist)
251  {
252  TargetEntry *tle = lfirst(t);
253 
254  if (tle->resjunk && tle->resname &&
255  (strcmp(tle->resname, attrName) == 0))
256  {
257  /* We found it ! */
258  return tle->resno;
259  }
260  }
261 
262  return InvalidAttrNumber;
263 }
char * resname
Definition: primnodes.h:1412
bool resjunk
Definition: primnodes.h:1417
AttrNumber resno
Definition: primnodes.h:1411
#define lfirst(lc)
Definition: pg_list.h:169
#define InvalidAttrNumber
Definition: attnum.h:23

◆ ExecFindRowMark()

ExecRowMark* ExecFindRowMark ( EState estate,
Index  rti,
bool  missing_ok 
)

Definition at line 2243 of file execMain.c.

References elog, ERROR, and EState::es_rowmarks.

Referenced by ExecInitLockRows(), and ExecInitModifyTable().

2244 {
2245  if (rti > 0 && rti <= estate->es_range_table_size &&
2246  estate->es_rowmarks != NULL)
2247  {
2248  ExecRowMark *erm = estate->es_rowmarks[rti - 1];
2249 
2250  if (erm)
2251  return erm;
2252  }
2253  if (!missing_ok)
2254  elog(ERROR, "failed to find ExecRowMark for rangetable index %u", rti);
2255  return NULL;
2256 }
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:523
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:214

◆ ExecFreeExprContext()

◆ ExecGetJunkAttribute()

Datum ExecGetJunkAttribute ( TupleTableSlot slot,
AttrNumber  attno,
bool isNull 
)

Definition at line 273 of file execJunk.c.

References Assert, and slot_getattr().

Referenced by EvalPlanQualFetchRowMark(), ExecLockRows(), ExecModifyTable(), and execute_foreign_modify().

275 {
276  Assert(attno > 0);
277 
278  return slot_getattr(slot, attno, isNull);
279 }
static Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: tuptable.h:381
#define Assert(condition)
Definition: c.h:746

◆ ExecGetRangeTableRelation()

Relation ExecGetRangeTableRelation ( EState estate,
Index  rti 
)

Definition at line 781 of file execUtils.c.

References AccessShareLock, Assert, CheckRelationLockedByMe(), EState::es_relations, exec_rt_fetch(), IsParallelWorker, NoLock, RangeTblEntry::relid, RangeTblEntry::rellockmode, RTE_RELATION, RangeTblEntry::rtekind, and table_open().

Referenced by exec_rt_fetch(), ExecCreatePartitionPruneState(), ExecInitResultRelation(), ExecOpenScanRelation(), and InitPlan().

782 {
783  Relation rel;
784 
785  Assert(rti > 0 && rti <= estate->es_range_table_size);
786 
787  rel = estate->es_relations[rti - 1];
788  if (rel == NULL)
789  {
790  /* First time through, so open the relation */
791  RangeTblEntry *rte = exec_rt_fetch(rti, estate);
792 
793  Assert(rte->rtekind == RTE_RELATION);
794 
795  if (!IsParallelWorker())
796  {
797  /*
798  * In a normal query, we should already have the appropriate lock,
799  * but verify that through an Assert. Since there's already an
800  * Assert inside table_open that insists on holding some lock, it
801  * seems sufficient to check this only when rellockmode is higher
802  * than the minimum.
803  */
804  rel = table_open(rte->relid, NoLock);
806  CheckRelationLockedByMe(rel, rte->rellockmode, false));
807  }
808  else
809  {
810  /*
811  * If we are a parallel worker, we need to obtain our own local
812  * lock on the relation. This ensures sane behavior in case the
813  * parent process exits before we do.
814  */
815  rel = table_open(rte->relid, rte->rellockmode);
816  }
817 
818  estate->es_relations[rti - 1] = rel;
819  }
820 
821  return rel;
822 }
#define AccessShareLock
Definition: lockdefs.h:36
#define NoLock
Definition: lockdefs.h:34
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:547
#define IsParallelWorker()
Definition: parallel.h:61
#define Assert(condition)
Definition: c.h:746
Relation * es_relations
Definition: execnodes.h:521
bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger)
Definition: lmgr.c:302
RTEKind rtekind
Definition: parsenodes.h:981
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ ExecGetResultSlotOps()

const TupleTableSlotOps* ExecGetResultSlotOps ( PlanState planstate,
bool isfixed 
)

Definition at line 498 of file execUtils.c.

References PlanState::ps_ResultTupleSlot, PlanState::resultops, PlanState::resultopsfixed, PlanState::resultopsset, TTS_FIXED, TupleTableSlot::tts_ops, and TTSOpsVirtual.

Referenced by ExecComputeSlotInfo(), ExecInitAgg(), ExecInitGroup(), ExecInitHashJoin(), ExecInitLimit(), ExecInitLockRows(), ExecInitMergeJoin(), and ExecInitSubqueryScan().

499 {
500  if (planstate->resultopsset && planstate->resultops)
501  {
502  if (isfixed)
503  *isfixed = planstate->resultopsfixed;
504  return planstate->resultops;
505  }
506 
507  if (isfixed)
508  {
509  if (planstate->resultopsset)
510  *isfixed = planstate->resultopsfixed;
511  else if (planstate->ps_ResultTupleSlot)
512  *isfixed = TTS_FIXED(planstate->ps_ResultTupleSlot);
513  else
514  *isfixed = false;
515  }
516 
517  if (!planstate->ps_ResultTupleSlot)
518  return &TTSOpsVirtual;
519 
520  return planstate->ps_ResultTupleSlot->tts_ops;
521 }
#define TTS_FIXED(slot)
Definition: tuptable.h:109
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
const TupleTableSlotOps *const tts_ops
Definition: tuptable.h:122
const TupleTableSlotOps * resultops
Definition: execnodes.h:1014
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:977
bool resultopsset
Definition: execnodes.h:1022
bool resultopsfixed
Definition: execnodes.h:1018

◆ ExecGetResultType()

◆ ExecGetReturningSlot()

TupleTableSlot* ExecGetReturningSlot ( EState estate,
ResultRelInfo relInfo 
)

Definition at line 1209 of file execUtils.c.

References EState::es_query_cxt, ExecInitExtraTupleSlot(), MemoryContextSwitchTo(), RelationGetDescr, ResultRelInfo::ri_RelationDesc, ResultRelInfo::ri_ReturningSlot, and table_slot_callbacks().

Referenced by apply_returning_filter(), exec_rt_fetch(), ExecDelete(), and ExecInsert().

1210 {
1211  if (relInfo->ri_ReturningSlot == NULL)
1212  {
1213  Relation rel = relInfo->ri_RelationDesc;
1214  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1215 
1216  relInfo->ri_ReturningSlot =
1217  ExecInitExtraTupleSlot(estate,
1218  RelationGetDescr(rel),
1219  table_slot_callbacks(rel));
1220 
1221  MemoryContextSwitchTo(oldcontext);
1222  }
1223 
1224  return relInfo->ri_ReturningSlot;
1225 }
Relation ri_RelationDesc
Definition: execnodes.h:412
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1801
#define RelationGetDescr(relation)
Definition: rel.h:482
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:559
TupleTableSlot * ri_ReturningSlot
Definition: execnodes.h:436

◆ ExecGetTriggerNewSlot()

TupleTableSlot* ExecGetTriggerNewSlot ( EState estate,
ResultRelInfo relInfo 
)

Definition at line 1187 of file execUtils.c.

References EState::es_query_cxt, ExecInitExtraTupleSlot(), MemoryContextSwitchTo(), RelationGetDescr, ResultRelInfo::ri_RelationDesc, ResultRelInfo::ri_TrigNewSlot, and table_slot_callbacks().

Referenced by AfterTriggerExecute(), and exec_rt_fetch().

1188 {
1189  if (relInfo->ri_TrigNewSlot == NULL)
1190  {
1191  Relation rel = relInfo->ri_RelationDesc;
1192  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1193 
1194  relInfo->ri_TrigNewSlot =
1195  ExecInitExtraTupleSlot(estate,
1196  RelationGetDescr(rel),
1197  table_slot_callbacks(rel));
1198 
1199  MemoryContextSwitchTo(oldcontext);
1200  }
1201 
1202  return relInfo->ri_TrigNewSlot;
1203 }
Relation ri_RelationDesc
Definition: execnodes.h:412
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1801
#define RelationGetDescr(relation)
Definition: rel.h:482
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
TupleTableSlot * ri_TrigNewSlot
Definition: execnodes.h:438
MemoryContext es_query_cxt
Definition: execnodes.h:559

◆ ExecGetTriggerOldSlot()

TupleTableSlot* ExecGetTriggerOldSlot ( EState estate,
ResultRelInfo relInfo 
)

Definition at line 1165 of file execUtils.c.

References EState::es_query_cxt, ExecInitExtraTupleSlot(), MemoryContextSwitchTo(), RelationGetDescr, ResultRelInfo::ri_RelationDesc, ResultRelInfo::ri_TrigOldSlot, and table_slot_callbacks().

Referenced by AfterTriggerExecute(), exec_rt_fetch(), ExecARDeleteTriggers(), ExecARUpdateTriggers(), ExecBRDeleteTriggers(), ExecBRUpdateTriggers(), ExecIRDeleteTriggers(), and ExecIRUpdateTriggers().

1166 {
1167  if (relInfo->ri_TrigOldSlot == NULL)
1168  {
1169  Relation rel = relInfo->ri_RelationDesc;
1170  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1171 
1172  relInfo->ri_TrigOldSlot =
1173  ExecInitExtraTupleSlot(estate,
1174  RelationGetDescr(rel),
1175  table_slot_callbacks(rel));
1176 
1177  MemoryContextSwitchTo(oldcontext);
1178  }
1179 
1180  return relInfo->ri_TrigOldSlot;
1181 }
Relation ri_RelationDesc
Definition: execnodes.h:412
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1801
#define RelationGetDescr(relation)
Definition: rel.h:482
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:559
TupleTableSlot * ri_TrigOldSlot
Definition: execnodes.h:437

◆ ExecGetTriggerResultRel()

ResultRelInfo* ExecGetTriggerResultRel ( EState estate,
Oid  relid 
)

Definition at line 1273 of file execMain.c.

References EState::es_instrument, EState::es_opened_result_relations, EState::es_query_cxt, EState::es_trig_target_relations, EState::es_tuple_routing_result_relations, InitResultRelInfo(), lappend(), lfirst, makeNode, MemoryContextSwitchTo(), NoLock, RelationGetRelid, ResultRelInfo::ri_RelationDesc, and table_open().

Referenced by afterTriggerInvokeEvents().

1274 {
1275  ResultRelInfo *rInfo;
1276  ListCell *l;
1277  Relation rel;
1278  MemoryContext oldcontext;
1279 
1280  /* First, search through the query result relations */
1281  foreach(l, estate->es_opened_result_relations)
1282  {
1283  rInfo = lfirst(l);
1284  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1285  return rInfo;
1286  }
1287 
1288  /*
1289  * Third, search through the result relations that were created during
1290  * tuple routing, if any.
1291  */
1292  foreach(l, estate->es_tuple_routing_result_relations)
1293  {
1294  rInfo = (ResultRelInfo *) lfirst(l);
1295  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1296  return rInfo;
1297  }
1298 
1299  /* Nope, but maybe we already made an extra ResultRelInfo for it */
1300  foreach(l, estate->es_trig_target_relations)
1301  {
1302  rInfo = (ResultRelInfo *) lfirst(l);
1303  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1304  return rInfo;
1305  }
1306  /* Nope, so we need a new one */
1307 
1308  /*
1309  * Open the target relation's relcache entry. We assume that an
1310  * appropriate lock is still held by the backend from whenever the trigger
1311  * event got queued, so we need take no new lock here. Also, we need not
1312  * recheck the relkind, so no need for CheckValidResultRel.
1313  */
1314  rel = table_open(relid, NoLock);
1315 
1316  /*
1317  * Make the new entry in the right context.
1318  */
1319  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1320  rInfo = makeNode(ResultRelInfo);
1321  InitResultRelInfo(rInfo,
1322  rel,
1323  0, /* dummy rangetable index */
1324  NULL,
1325  estate->es_instrument);
1326  estate->es_trig_target_relations =
1327  lappend(estate->es_trig_target_relations, rInfo);
1328  MemoryContextSwitchTo(oldcontext);
1329 
1330  /*
1331  * Currently, we don't need any index information in ResultRelInfos used
1332  * only for triggers, so no need to call ExecOpenIndices.
1333  */
1334 
1335  return rInfo;
1336 }
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, Relation partition_root, int instrument_options)
Definition: execMain.c:1196
Relation ri_RelationDesc
Definition: execnodes.h:412
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:559
#define NoLock
Definition: lockdefs.h:34
List * es_opened_result_relations
Definition: execnodes.h:537
int es_instrument
Definition: execnodes.h:566
List * lappend(List *list, void *datum)
Definition: list.c:321
List * es_trig_target_relations
Definition: execnodes.h:550
List * es_tuple_routing_result_relations
Definition: execnodes.h:547
#define makeNode(_type_)
Definition: nodes.h:576
#define lfirst(lc)
Definition: pg_list.h:169
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define RelationGetRelid(relation)
Definition: rel.h:456

◆ ExecInitCheck()

ExprState* ExecInitCheck ( List qual,
PlanState parent 
)

Definition at line 298 of file execExpr.c.

References Assert, ExecInitExpr(), IsA, make_ands_explicit(), and NIL.

Referenced by ExecPrepareCheck(), and ExecProcNode().

299 {
300  /* short-circuit (here and in ExecCheck) for empty restriction list */
301  if (qual == NIL)
302  return NULL;
303 
304  Assert(IsA(qual, List));
305 
306  /*
307  * Just convert the implicit-AND list to an explicit AND (if there's more
308  * than one entry), and compile normally. Unlike ExecQual, we can't
309  * short-circuit on NULL results, so the regular AND behavior is needed.
310  */
311  return ExecInitExpr(make_ands_explicit(qual), parent);
312 }
#define NIL
Defi