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)
 
TupleHashEntry FindTupleHashEntry (TupleHashTable hashtable, TupleTableSlot *slot, ExprState *eqcomp, FmgrInfo *hashfunctions)
 
void ResetTupleHashTable (TupleHashTable hashtable)
 
JunkFilterExecInitJunkFilter (List *targetList, TupleTableSlot *slot)
 
JunkFilterExecInitJunkFilterConversion (List *targetList, TupleDesc cleanTupType, TupleTableSlot *slot)
 
AttrNumber ExecFindJunkAttribute (JunkFilter *junkfilter, const char *attrName)
 
AttrNumber ExecFindJunkAttributeInTlist (List *targetlist, const char *attrName)
 
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 ExecCleanUpTriggerState (EState *estate)
 
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)
 
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)
 
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)
 
static RangeTblEntryexec_rt_fetch (Index rti, EState *estate)
 
Relation ExecGetRangeTableRelation (EState *estate, 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 (TupleTableSlot *slot, EState *estate, bool noDupErr, bool *specConflict, List *arbiterIndexes)
 
bool ExecCheckIndexConstraints (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 (EState *estate, TupleTableSlot *slot)
 
void ExecSimpleRelationUpdate (EState *estate, EPQState *epqstate, TupleTableSlot *searchslot, TupleTableSlot *slot)
 
void ExecSimpleRelationDelete (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:171
#define DatumGetPointer(X)
Definition: postgres.h:549

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

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

Typedef Documentation

◆ ExecScanAccessMtd

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

Definition at line 425 of file executor.h.

◆ ExecScanRecheckMtd

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

Definition at line 426 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:458
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:121
void * palloc(Size size)
Definition: mcxt.c:949
DestReceiver * dest
Definition: executor.h:459

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

References BuildTupleHashTableExt().

262 {
263  return BuildTupleHashTableExt(parent,
264  inputDesc,
265  numCols, keyColIdx,
266  eqfuncoids,
267  hashfunctions,
268  collations,
269  nbuckets, additionalsize,
270  tablecxt,
271  tablecxt,
272  tempcxt,
273  use_variable_hash_iv);
274 }
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, 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, TTSOpsMinimalTuple, and work_mem.

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

165 {
166  TupleHashTable hashtable;
167  Size entrysize = sizeof(TupleHashEntryData) + additionalsize;
168  MemoryContext oldcontext;
169  bool allow_jit;
170 
171  Assert(nbuckets > 0);
172 
173  /* Limit initial table size request to not more than work_mem */
174  nbuckets = Min(nbuckets, (long) ((work_mem * 1024L) / entrysize));
175 
176  oldcontext = MemoryContextSwitchTo(metacxt);
177 
178  hashtable = (TupleHashTable) palloc(sizeof(TupleHashTableData));
179 
180  hashtable->numCols = numCols;
181  hashtable->keyColIdx = keyColIdx;
182  hashtable->tab_hash_funcs = hashfunctions;
183  hashtable->tab_collations = collations;
184  hashtable->tablecxt = tablecxt;
185  hashtable->tempcxt = tempcxt;
186  hashtable->entrysize = entrysize;
187  hashtable->tableslot = NULL; /* will be made on first lookup */
188  hashtable->inputslot = NULL;
189  hashtable->in_hash_funcs = NULL;
190  hashtable->cur_eq_func = NULL;
191 
192  /*
193  * If parallelism is in use, even if the master backend is performing the
194  * scan itself, we don't want to create the hashtable exactly the same way
195  * in all workers. As hashtables are iterated over in keyspace-order,
196  * doing so in all processes in the same way is likely to lead to
197  * "unbalanced" hashtables when the table size initially is
198  * underestimated.
199  */
200  if (use_variable_hash_iv)
202  else
203  hashtable->hash_iv = 0;
204 
205  hashtable->hashtab = tuplehash_create(metacxt, nbuckets, hashtable);
206 
207  /*
208  * We copy the input tuple descriptor just for safety --- we assume all
209  * input tuples will have equivalent descriptors.
210  */
213 
214  /*
215  * If the old reset interface is used (i.e. BuildTupleHashTable, rather
216  * than BuildTupleHashTableExt), allowing JIT would lead to the generated
217  * functions to a) live longer than the query b) be re-generated each time
218  * the table is being reset. Therefore prevent JIT from being used in that
219  * case, by not providing a parent node (which prevents accessing the
220  * JitContext in the EState).
221  */
222  allow_jit = metacxt != tablecxt;
223 
224  /* build comparator for all columns */
225  /* XXX: should we support non-minimal tuples for the inputslot? */
226  hashtable->tab_eq_func = ExecBuildGroupingEqual(inputDesc, inputDesc,
228  numCols,
229  keyColIdx, eqfuncoids, collations,
230  allow_jit ? parent : NULL);
231 
232  /*
233  * While not pretty, it's ok to not shut down this context, but instead
234  * rely on the containing memory context being reset, as
235  * ExecBuildGroupingEqual() only builds a very simple expression calling
236  * functions (i.e. nothing that'd employ RegisterExprContextCallback()).
237  */
239 
240  MemoryContextSwitchTo(oldcontext);
241 
242  return hashtable;
243 }
ExprContext * exprcontext
Definition: execnodes.h:708
ExprContext * CreateStandaloneExprContext(void)
Definition: execUtils.c:316
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:3331
TupleTableSlot * inputslot
Definition: execnodes.h:704
#define Min(x, y)
Definition: c.h:905
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
AttrNumber * keyColIdx
Definition: execnodes.h:695
ExprState * tab_eq_func
Definition: execnodes.h:697
ExprState * cur_eq_func
Definition: execnodes.h:706
FmgrInfo * tab_hash_funcs
Definition: execnodes.h:696
FmgrInfo * in_hash_funcs
Definition: execnodes.h:705
struct TupleHashEntryData TupleHashEntryData
MemoryContext tablecxt
Definition: execnodes.h:699
struct TupleHashTableData * TupleHashTable
Definition: execnodes.h:673
int ParallelWorkerNumber
Definition: parallel.c:109
int work_mem
Definition: globals.c:121
tuplehash_hash * hashtab
Definition: execnodes.h:693
#define Assert(condition)
Definition: c.h:733
TupleTableSlot * tableslot
Definition: execnodes.h:702
size_t Size
Definition: c.h:467
void * palloc(Size size)
Definition: mcxt.c:949
static uint32 murmurhash32(uint32 data)
Definition: hashutils.h:60
MemoryContext tempcxt
Definition: execnodes.h:700
const TupleTableSlotOps TTSOpsMinimalTuple
Definition: execTuples.c:85

◆ check_exclusion_constraint()

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

Definition at line 866 of file execIndexing.c.

References CEOUC_WAIT, and check_exclusion_or_unique_constraint().

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

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

◆ CheckCmdReplicaIdentity()

void CheckCmdReplicaIdentity ( Relation  rel,
CmdType  cmd 
)

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

551 {
552  PublicationActions *pubactions;
553 
554  /* We only need to do checks for UPDATE and DELETE. */
555  if (cmd != CMD_UPDATE && cmd != CMD_DELETE)
556  return;
557 
558  /* If relation has replica identity we are always good. */
559  if (rel->rd_rel->relreplident == REPLICA_IDENTITY_FULL ||
561  return;
562 
563  /*
564  * This is either UPDATE OR DELETE and there is no replica identity.
565  *
566  * Check if the table publishes UPDATES or DELETES.
567  */
568  pubactions = GetRelationPublicationActions(rel);
569  if (cmd == CMD_UPDATE && pubactions->pubupdate)
570  ereport(ERROR,
571  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
572  errmsg("cannot update table \"%s\" because it does not have a replica identity and publishes updates",
574  errhint("To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.")));
575  else if (cmd == CMD_DELETE && pubactions->pubdelete)
576  ereport(ERROR,
577  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
578  errmsg("cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes",
580  errhint("To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE.")));
581 }
int errhint(const char *fmt,...)
Definition: elog.c:1071
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:4556
int errcode(int sqlerrcode)
Definition: elog.c:608
Form_pg_class rd_rel
Definition: rel.h:83
#define OidIsValid(objectId)
Definition: c.h:639
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:457
#define ereport(elevel, rest)
Definition: elog.h:141
struct PublicationActions * GetRelationPublicationActions(Relation relation)
Definition: relcache.c:5088
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ CheckSubscriptionRelkind()

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

Definition at line 590 of file execReplication.c.

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

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

592 {
593  /*
594  * We currently only support writing to regular tables. However, give a
595  * more specific error for partitioned and foreign tables.
596  */
597  if (relkind == RELKIND_PARTITIONED_TABLE)
598  ereport(ERROR,
599  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
600  errmsg("cannot use relation \"%s.%s\" as logical replication target",
601  nspname, relname),
602  errdetail("\"%s.%s\" is a partitioned table.",
603  nspname, relname)));
604  else if (relkind == RELKIND_FOREIGN_TABLE)
605  ereport(ERROR,
606  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
607  errmsg("cannot use relation \"%s.%s\" as logical replication target",
608  nspname, relname),
609  errdetail("\"%s.%s\" is a foreign table.",
610  nspname, relname)));
611 
612  if (relkind != RELKIND_RELATION)
613  ereport(ERROR,
614  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
615  errmsg("cannot use relation \"%s.%s\" as logical replication target",
616  nspname, relname),
617  errdetail("\"%s.%s\" is not a table.",
618  nspname, relname)));
619 }
int errcode(int sqlerrcode)
Definition: elog.c:608
NameData relname
Definition: pg_class.h:35
char relkind
Definition: pg_class.h:81
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:957
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ CheckValidResultRel()

void CheckValidResultRel ( ResultRelInfo resultRelInfo,
CmdType  operation 
)

Definition at line 1076 of file execMain.c.

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

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

1077 {
1078  Relation resultRel = resultRelInfo->ri_RelationDesc;
1079  TriggerDesc *trigDesc = resultRel->trigdesc;
1080  FdwRoutine *fdwroutine;
1081 
1082  switch (resultRel->rd_rel->relkind)
1083  {
1084  case RELKIND_RELATION:
1085  case RELKIND_PARTITIONED_TABLE:
1086  CheckCmdReplicaIdentity(resultRel, operation);
1087  break;
1088  case RELKIND_SEQUENCE:
1089  ereport(ERROR,
1090  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1091  errmsg("cannot change sequence \"%s\"",
1092  RelationGetRelationName(resultRel))));
1093  break;
1094  case RELKIND_TOASTVALUE:
1095  ereport(ERROR,
1096  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1097  errmsg("cannot change TOAST relation \"%s\"",
1098  RelationGetRelationName(resultRel))));
1099  break;
1100  case RELKIND_VIEW:
1101 
1102  /*
1103  * Okay only if there's a suitable INSTEAD OF trigger. Messages
1104  * here should match rewriteHandler.c's rewriteTargetView, except
1105  * that we omit errdetail because we haven't got the information
1106  * handy (and given that we really shouldn't get here anyway, it's
1107  * not worth great exertion to get).
1108  */
1109  switch (operation)
1110  {
1111  case CMD_INSERT:
1112  if (!trigDesc || !trigDesc->trig_insert_instead_row)
1113  ereport(ERROR,
1114  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1115  errmsg("cannot insert into view \"%s\"",
1116  RelationGetRelationName(resultRel)),
1117  errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule.")));
1118  break;
1119  case CMD_UPDATE:
1120  if (!trigDesc || !trigDesc->trig_update_instead_row)
1121  ereport(ERROR,
1122  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1123  errmsg("cannot update view \"%s\"",
1124  RelationGetRelationName(resultRel)),
1125  errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.")));
1126  break;
1127  case CMD_DELETE:
1128  if (!trigDesc || !trigDesc->trig_delete_instead_row)
1129  ereport(ERROR,
1130  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1131  errmsg("cannot delete from view \"%s\"",
1132  RelationGetRelationName(resultRel)),
1133  errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule.")));
1134  break;
1135  default:
1136  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1137  break;
1138  }
1139  break;
1140  case RELKIND_MATVIEW:
1142  ereport(ERROR,
1143  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1144  errmsg("cannot change materialized view \"%s\"",
1145  RelationGetRelationName(resultRel))));
1146  break;
1147  case RELKIND_FOREIGN_TABLE:
1148  /* Okay only if the FDW supports it */
1149  fdwroutine = resultRelInfo->ri_FdwRoutine;
1150  switch (operation)
1151  {
1152  case CMD_INSERT:
1153  if (fdwroutine->ExecForeignInsert == NULL)
1154  ereport(ERROR,
1155  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1156  errmsg("cannot insert into foreign table \"%s\"",
1157  RelationGetRelationName(resultRel))));
1158  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1159  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_INSERT)) == 0)
1160  ereport(ERROR,
1161  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1162  errmsg("foreign table \"%s\" does not allow inserts",
1163  RelationGetRelationName(resultRel))));
1164  break;
1165  case CMD_UPDATE:
1166  if (fdwroutine->ExecForeignUpdate == NULL)
1167  ereport(ERROR,
1168  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1169  errmsg("cannot update foreign table \"%s\"",
1170  RelationGetRelationName(resultRel))));
1171  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1172  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_UPDATE)) == 0)
1173  ereport(ERROR,
1174  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1175  errmsg("foreign table \"%s\" does not allow updates",
1176  RelationGetRelationName(resultRel))));
1177  break;
1178  case CMD_DELETE:
1179  if (fdwroutine->ExecForeignDelete == NULL)
1180  ereport(ERROR,
1181  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1182  errmsg("cannot delete from foreign table \"%s\"",
1183  RelationGetRelationName(resultRel))));
1184  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1185  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_DELETE)) == 0)
1186  ereport(ERROR,
1187  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1188  errmsg("foreign table \"%s\" does not allow deletes",
1189  RelationGetRelationName(resultRel))));
1190  break;
1191  default:
1192  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1193  break;
1194  }
1195  break;
1196  default:
1197  ereport(ERROR,
1198  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1199  errmsg("cannot change relation \"%s\"",
1200  RelationGetRelationName(resultRel))));
1201  break;
1202  }
1203 }
ExecForeignDelete_function ExecForeignDelete
Definition: fdwapi.h:213
Relation ri_RelationDesc
Definition: execnodes.h:411
int errhint(const char *fmt,...)
Definition: elog.c:1071
bool MatViewIncrementalMaintenanceIsEnabled(void)
Definition: matview.c:912
ExecForeignInsert_function ExecForeignInsert
Definition: fdwapi.h:211
int errcode(int sqlerrcode)
Definition: elog.c:608
Form_pg_class rd_rel
Definition: rel.h:83
bool trig_insert_instead_row
Definition: reltrigger.h:57
#define ERROR
Definition: elog.h:43
TriggerDesc * trigdesc
Definition: rel.h:89
#define RelationGetRelationName(relation)
Definition: rel.h:457
struct FdwRoutine * ri_FdwRoutine
Definition: execnodes.h:440
void CheckCmdReplicaIdentity(Relation rel, CmdType cmd)
#define ereport(elevel, rest)
Definition: elog.h:141
bool trig_update_instead_row
Definition: reltrigger.h:62
bool trig_delete_instead_row
Definition: reltrigger.h:67
ExecForeignUpdate_function ExecForeignUpdate
Definition: fdwapi.h:212
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define elog(elevel,...)
Definition: elog.h:228
IsForeignRelUpdatable_function IsForeignRelUpdatable
Definition: fdwapi.h:217

◆ CreateExecutorState()

EState* CreateExecutorState ( void  )

Definition at line 88 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_num_result_relations, EState::es_num_root_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_relation_info, EState::es_result_relations, EState::es_root_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(), validateCheckConstraint(), and validateDomainConstraint().

89 {
90  EState *estate;
91  MemoryContext qcontext;
92  MemoryContext oldcontext;
93 
94  /*
95  * Create the per-query context for this Executor run.
96  */
98  "ExecutorState",
100 
101  /*
102  * Make the EState node within the per-query context. This way, we don't
103  * need a separate pfree() operation for it at shutdown.
104  */
105  oldcontext = MemoryContextSwitchTo(qcontext);
106 
107  estate = makeNode(EState);
108 
109  /*
110  * Initialize all fields of the Executor State structure
111  */
113  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
114  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
115  estate->es_range_table = NIL;
116  estate->es_range_table_size = 0;
117  estate->es_relations = NULL;
118  estate->es_rowmarks = NULL;
119  estate->es_plannedstmt = NULL;
120 
121  estate->es_junkFilter = NULL;
122 
123  estate->es_output_cid = (CommandId) 0;
124 
125  estate->es_result_relations = NULL;
126  estate->es_num_result_relations = 0;
127  estate->es_result_relation_info = NULL;
128 
129  estate->es_root_result_relations = NULL;
130  estate->es_num_root_result_relations = 0;
131 
133 
134  estate->es_trig_target_relations = NIL;
135 
136  estate->es_param_list_info = NULL;
137  estate->es_param_exec_vals = NULL;
138 
139  estate->es_queryEnv = NULL;
140 
141  estate->es_query_cxt = qcontext;
142 
143  estate->es_tupleTable = NIL;
144 
145  estate->es_processed = 0;
146 
147  estate->es_top_eflags = 0;
148  estate->es_instrument = 0;
149  estate->es_finished = false;
150 
151  estate->es_exprcontexts = NIL;
152 
153  estate->es_subplanstates = NIL;
154 
155  estate->es_auxmodifytables = NIL;
156 
157  estate->es_per_tuple_exprcontext = NULL;
158 
159  estate->es_sourceText = NULL;
160 
161  estate->es_use_parallel_mode = false;
162 
163  estate->es_jit_flags = 0;
164  estate->es_jit = NULL;
165 
166  /*
167  * Return the executor state structure
168  */
169  MemoryContextSwitchTo(oldcontext);
170 
171  return estate;
172 }
#define NIL
Definition: pg_list.h:65
uint32 CommandId
Definition: c.h:522
JunkFilter * es_junkFilter
Definition: execnodes.h:514
#define AllocSetContextCreate
Definition: memutils.h:170
CommandId es_output_cid
Definition: execnodes.h:517
struct JitContext * es_jit
Definition: execnodes.h:596
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:511
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:504
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:571
Snapshot es_snapshot
Definition: execnodes.h:503
List * es_range_table
Definition: execnodes.h:505
ScanDirection es_direction
Definition: execnodes.h:502
bool es_use_parallel_mode
Definition: execnodes.h:581
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:509
const char * es_sourceText
Definition: execnodes.h:512
ParamExecData * es_param_exec_vals
Definition: execnodes.h:545
MemoryContext es_query_cxt
Definition: execnodes.h:550
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
int es_jit_flags
Definition: execnodes.h:595
ResultRelInfo * es_result_relations
Definition: execnodes.h:520
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
int es_instrument
Definition: execnodes.h:557
QueryEnvironment * es_queryEnv
Definition: execnodes.h:547
int es_num_root_result_relations
Definition: execnodes.h:531
#define InvalidSnapshot
Definition: snapshot.h:123
List * es_trig_target_relations
Definition: execnodes.h:541
List * es_tupleTable
Definition: execnodes.h:552
List * es_auxmodifytables
Definition: execnodes.h:564
int es_num_result_relations
Definition: execnodes.h:521
List * es_tuple_routing_result_relations
Definition: execnodes.h:538
bool es_finished
Definition: execnodes.h:558
#define makeNode(_type_)
Definition: nodes.h:573
Relation * es_relations
Definition: execnodes.h:507
uint64 es_processed
Definition: execnodes.h:554
Index es_range_table_size
Definition: execnodes.h:506
List * es_subplanstates
Definition: execnodes.h:562
int es_top_eflags
Definition: execnodes.h:556
ResultRelInfo * es_root_result_relations
Definition: execnodes.h:530
ParamListInfo es_param_list_info
Definition: execnodes.h:544
List * es_exprcontexts
Definition: execnodes.h:560
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:522

◆ CreateExprContext()

ExprContext* CreateExprContext ( EState estate)

Definition at line 244 of file execUtils.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ExprContext::caseValue_datum, ExprContext::caseValue_isNull, 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, EState::es_exprcontexts, EState::es_param_exec_vals, EState::es_param_list_info, EState::es_query_cxt, lcons(), makeNode, and MemoryContextSwitchTo().

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

245 {
246  ExprContext *econtext;
247  MemoryContext oldcontext;
248 
249  /* Create the ExprContext node within the per-query memory context */
250  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
251 
252  econtext = makeNode(ExprContext);
253 
254  /* Initialize fields of ExprContext */
255  econtext->ecxt_scantuple = NULL;
256  econtext->ecxt_innertuple = NULL;
257  econtext->ecxt_outertuple = NULL;
258 
259  econtext->ecxt_per_query_memory = estate->es_query_cxt;
260 
261  /*
262  * Create working memory for expression evaluation in this context.
263  */
264  econtext->ecxt_per_tuple_memory =
266  "ExprContext",
268 
269  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
270  econtext->ecxt_param_list_info = estate->es_param_list_info;
271 
272  econtext->ecxt_aggvalues = NULL;
273  econtext->ecxt_aggnulls = NULL;
274 
275  econtext->caseValue_datum = (Datum) 0;
276  econtext->caseValue_isNull = true;
277 
278  econtext->domainValue_datum = (Datum) 0;
279  econtext->domainValue_isNull = true;
280 
281  econtext->ecxt_estate = estate;
282 
283  econtext->ecxt_callbacks = NULL;
284 
285  /*
286  * Link the ExprContext into the EState to ensure it is shut down when the
287  * EState is freed. Because we use lcons(), shutdowns will occur in
288  * reverse order of creation, which may not be essential but can't hurt.
289  */
290  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
291 
292  MemoryContextSwitchTo(oldcontext);
293 
294  return econtext;
295 }
#define AllocSetContextCreate
Definition: memutils.h:170
Datum * ecxt_aggvalues
Definition: execnodes.h:243
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:232
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum domainValue_datum
Definition: execnodes.h:255
ParamExecData * es_param_exec_vals
Definition: execnodes.h:545
MemoryContext es_query_cxt
Definition: execnodes.h:550
Datum caseValue_datum
Definition: execnodes.h:249
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:263
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:226
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:235
struct EState * ecxt_estate
Definition: execnodes.h:260
bool domainValue_isNull
Definition: execnodes.h:257
bool * ecxt_aggnulls
Definition: execnodes.h:245
uintptr_t Datum
Definition: postgres.h:367
List * lcons(void *datum, List *list)
Definition: list.c:454
#define makeNode(_type_)
Definition: nodes.h:573
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:228
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:224
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:231
bool caseValue_isNull
Definition: execnodes.h:251
ParamListInfo es_param_list_info
Definition: execnodes.h:544
List * es_exprcontexts
Definition: execnodes.h:560
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:236

◆ CreateStandaloneExprContext()

ExprContext* CreateStandaloneExprContext ( void  )

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

317 {
318  ExprContext *econtext;
319 
320  /* Create the ExprContext node within the caller's memory context */
321  econtext = makeNode(ExprContext);
322 
323  /* Initialize fields of ExprContext */
324  econtext->ecxt_scantuple = NULL;
325  econtext->ecxt_innertuple = NULL;
326  econtext->ecxt_outertuple = NULL;
327 
329 
330  /*
331  * Create working memory for expression evaluation in this context.
332  */
333  econtext->ecxt_per_tuple_memory =
335  "ExprContext",
337 
338  econtext->ecxt_param_exec_vals = NULL;
339  econtext->ecxt_param_list_info = NULL;
340 
341  econtext->ecxt_aggvalues = NULL;
342  econtext->ecxt_aggnulls = NULL;
343 
344  econtext->caseValue_datum = (Datum) 0;
345  econtext->caseValue_isNull = true;
346 
347  econtext->domainValue_datum = (Datum) 0;
348  econtext->domainValue_isNull = true;
349 
350  econtext->ecxt_estate = NULL;
351 
352  econtext->ecxt_callbacks = NULL;
353 
354  return econtext;
355 }
#define AllocSetContextCreate
Definition: memutils.h:170
Datum * ecxt_aggvalues
Definition: execnodes.h:243
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:232
Datum domainValue_datum
Definition: execnodes.h:255
Datum caseValue_datum
Definition: execnodes.h:249
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:263
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:226
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:235
struct EState * ecxt_estate
Definition: execnodes.h:260
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
bool domainValue_isNull
Definition: execnodes.h:257
bool * ecxt_aggnulls
Definition: execnodes.h:245
uintptr_t Datum
Definition: postgres.h:367
#define makeNode(_type_)
Definition: nodes.h:573
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:228
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:224
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:231
bool caseValue_isNull
Definition: execnodes.h:251
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:236

◆ 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:1056
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
uintptr_t Datum
Definition: postgres.h:367
#define DatumGetPointer(X)
Definition: postgres.h:549
static Datum values[MAXATTR]
Definition: bootstrap.c:167

◆ 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:118
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
Datum * tts_values
Definition: tuptable.h:126
TupleTableSlot * slot
Definition: executor.h:458
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:167
DestReceiver * dest
Definition: executor.h:459
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:458
void pfree(void *pointer)
Definition: mcxt.c:1056
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1224
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:124
DestReceiver * dest
Definition: executor.h:459

◆ EvalPlanQual()

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

Definition at line 2439 of file execMain.c.

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

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

2441 {
2442  TupleTableSlot *slot;
2443  TupleTableSlot *testslot;
2444 
2445  Assert(rti > 0);
2446 
2447  /*
2448  * Need to run a recheck subquery. Initialize or reinitialize EPQ state.
2449  */
2450  EvalPlanQualBegin(epqstate);
2451 
2452  /*
2453  * Callers will often use the EvalPlanQualSlot to store the tuple to avoid
2454  * an unnecessary copy.
2455  */
2456  testslot = EvalPlanQualSlot(epqstate, relation, rti);
2457  if (testslot != inputslot)
2458  ExecCopySlot(testslot, inputslot);
2459 
2460  /*
2461  * Run the EPQ query. We assume it will return at most one tuple.
2462  */
2463  slot = EvalPlanQualNext(epqstate);
2464 
2465  /*
2466  * If we got a tuple, force the slot to materialize the tuple so that it
2467  * is not dependent on any local state in the EPQ query (in particular,
2468  * it's highly likely that the slot contains references to any pass-by-ref
2469  * datums that may be present in copyTuple). As with the next step, this
2470  * is to guard against early re-use of the EPQ query.
2471  */
2472  if (!TupIsNull(slot))
2473  ExecMaterializeSlot(slot);
2474 
2475  /*
2476  * Clear out the test tuple. This is needed in case the EPQ query is
2477  * re-used to test a tuple for a different relation. (Not clear that can
2478  * really happen, but let's be safe.)
2479  */
2480  ExecClearTuple(testslot);
2481 
2482  return slot;
2483 }
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:2685
TupleTableSlot * EvalPlanQualSlot(EPQState *epqstate, Relation relation, Index rti)
Definition: execMain.c:2548
#define TupIsNull(slot)
Definition: tuptable.h:292
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition: tuptable.h:443
#define Assert(condition)
Definition: c.h:733
void EvalPlanQualBegin(EPQState *epqstate)
Definition: execMain.c:2701

◆ EvalPlanQualBegin()

void EvalPlanQualBegin ( EPQState epqstate)

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

2702 {
2703  EState *parentestate = epqstate->parentestate;
2704  EState *recheckestate = epqstate->recheckestate;
2705 
2706  if (recheckestate == NULL)
2707  {
2708  /* First time through, so create a child EState */
2709  EvalPlanQualStart(epqstate, epqstate->plan);
2710  }
2711  else
2712  {
2713  /*
2714  * We already have a suitable child EPQ tree, so just reset it.
2715  */
2716  Index rtsize = parentestate->es_range_table_size;
2717  PlanState *rcplanstate = epqstate->recheckplanstate;
2718 
2719  MemSet(epqstate->relsubs_done, 0, rtsize * sizeof(bool));
2720 
2721  /* Recopy current values of parent parameters */
2722  if (parentestate->es_plannedstmt->paramExecTypes != NIL)
2723  {
2724  int i;
2725 
2726  /*
2727  * Force evaluation of any InitPlan outputs that could be needed
2728  * by the subplan, just in case they got reset since
2729  * EvalPlanQualStart (see comments therein).
2730  */
2731  ExecSetParamPlanMulti(rcplanstate->plan->extParam,
2732  GetPerTupleExprContext(parentestate));
2733 
2734  i = list_length(parentestate->es_plannedstmt->paramExecTypes);
2735 
2736  while (--i >= 0)
2737  {
2738  /* copy value if any, but not execPlan link */
2739  recheckestate->es_param_exec_vals[i].value =
2740  parentestate->es_param_exec_vals[i].value;
2741  recheckestate->es_param_exec_vals[i].isnull =
2742  parentestate->es_param_exec_vals[i].isnull;
2743  }
2744  }
2745 
2746  /*
2747  * Mark child plan tree as needing rescan at all scan nodes. The
2748  * first ExecProcNode will take care of actually doing the rescan.
2749  */
2750  rcplanstate->chgParam = bms_add_member(rcplanstate->chgParam,
2751  epqstate->epqParam);
2752  }
2753 }
List * paramExecTypes
Definition: plannodes.h:88
#define NIL
Definition: pg_list.h:65
void ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext)
Definition: nodeSubplan.c:1245
PlannedStmt * es_plannedstmt
Definition: execnodes.h:511
#define MemSet(start, val, len)
Definition: c.h:956
EState * parentestate
Definition: execnodes.h:1076
#define GetPerTupleExprContext(estate)
Definition: executor.h:501
ParamExecData * es_param_exec_vals
Definition: execnodes.h:545
EState * recheckestate
Definition: execnodes.h:1106
bool isnull
Definition: params.h:149
static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
Definition: execMain.c:2762
bool * relsubs_done
Definition: execnodes.h:1119
Bitmapset * chgParam
Definition: execnodes.h:972
Plan * plan
Definition: execnodes.h:1092
unsigned int Index
Definition: c.h:476
Plan * plan
Definition: execnodes.h:940
static int list_length(const List *l)
Definition: pg_list.h:169
Bitmapset * extParam
Definition: plannodes.h:158
Index es_range_table_size
Definition: execnodes.h:506
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
int i
Datum value
Definition: params.h:148
int epqParam
Definition: execnodes.h:1077
PlanState * recheckplanstate
Definition: execnodes.h:1121

◆ EvalPlanQualEnd()

void EvalPlanQualEnd ( EPQState epqstate)

Definition at line 2953 of file execMain.c.

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

Referenced by apply_handle_delete(), apply_handle_update(), EvalPlanQualSetPlan(), ExecEndLockRows(), and ExecEndModifyTable().

2954 {
2955  EState *estate = epqstate->recheckestate;
2956  Index rtsize;
2957  MemoryContext oldcontext;
2958  ListCell *l;
2959 
2960  rtsize = epqstate->parentestate->es_range_table_size;
2961 
2962  /*
2963  * We may have a tuple table, even if EPQ wasn't started, because we allow
2964  * use of EvalPlanQualSlot() without calling EvalPlanQualBegin().
2965  */
2966  if (epqstate->tuple_table != NIL)
2967  {
2968  memset(epqstate->relsubs_slot, 0,
2969  rtsize * sizeof(TupleTableSlot *));
2970  ExecResetTupleTable(epqstate->tuple_table, true);
2971  epqstate->tuple_table = NIL;
2972  }
2973 
2974  /* EPQ wasn't started, nothing further to do */
2975  if (estate == NULL)
2976  return;
2977 
2978  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
2979 
2980  ExecEndNode(epqstate->recheckplanstate);
2981 
2982  foreach(l, estate->es_subplanstates)
2983  {
2984  PlanState *subplanstate = (PlanState *) lfirst(l);
2985 
2986  ExecEndNode(subplanstate);
2987  }
2988 
2989  /* throw away the per-estate tuple table, some node may have used it */
2990  ExecResetTupleTable(estate->es_tupleTable, false);
2991 
2992  /* close any trigger target relations attached to this EState */
2993  ExecCleanUpTriggerState(estate);
2994 
2995  MemoryContextSwitchTo(oldcontext);
2996 
2997  FreeExecutorState(estate);
2998 
2999  /* Mark EPQState idle */
3000  epqstate->recheckestate = NULL;
3001  epqstate->recheckplanstate = NULL;
3002  epqstate->origslot = NULL;
3003 }
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1085
#define NIL
Definition: pg_list.h:65
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:537
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
EState * parentestate
Definition: execnodes.h:1076
void FreeExecutorState(EState *estate)
Definition: execUtils.c:190
MemoryContext es_query_cxt
Definition: execnodes.h:550
EState * recheckestate
Definition: execnodes.h:1106
List * tuple_table
Definition: execnodes.h:1084
TupleTableSlot * origslot
Definition: execnodes.h:1101
List * es_tupleTable
Definition: execnodes.h:552
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:1161
unsigned int Index
Definition: c.h:476
#define lfirst(lc)
Definition: pg_list.h:190
Index es_range_table_size
Definition: execnodes.h:506
List * es_subplanstates
Definition: execnodes.h:562
void ExecCleanUpTriggerState(EState *estate)
Definition: execMain.c:1454
PlanState * recheckplanstate
Definition: execnodes.h:1121

◆ EvalPlanQualFetchRowMark()

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

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

2577 {
2578  ExecAuxRowMark *earm = epqstate->relsubs_rowmark[rti - 1];
2579  ExecRowMark *erm = earm->rowmark;
2580  Datum datum;
2581  bool isNull;
2582 
2583  Assert(earm != NULL);
2584  Assert(epqstate->origslot != NULL);
2585 
2587  elog(ERROR, "EvalPlanQual doesn't support locking rowmarks");
2588 
2589  /* if child rel, must check whether it produced this row */
2590  if (erm->rti != erm->prti)
2591  {
2592  Oid tableoid;
2593 
2594  datum = ExecGetJunkAttribute(epqstate->origslot,
2595  earm->toidAttNo,
2596  &isNull);
2597  /* non-locked rels could be on the inside of outer joins */
2598  if (isNull)
2599  return false;
2600 
2601  tableoid = DatumGetObjectId(datum);
2602 
2603  Assert(OidIsValid(erm->relid));
2604  if (tableoid != erm->relid)
2605  {
2606  /* this child is inactive right now */
2607  return false;
2608  }
2609  }
2610 
2611  if (erm->markType == ROW_MARK_REFERENCE)
2612  {
2613  Assert(erm->relation != NULL);
2614 
2615  /* fetch the tuple's ctid */
2616  datum = ExecGetJunkAttribute(epqstate->origslot,
2617  earm->ctidAttNo,
2618  &isNull);
2619  /* non-locked rels could be on the inside of outer joins */
2620  if (isNull)
2621  return false;
2622 
2623  /* fetch requests on foreign tables must be passed to their FDW */
2624  if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2625  {
2626  FdwRoutine *fdwroutine;
2627  bool updated = false;
2628 
2629  fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
2630  /* this should have been checked already, but let's be safe */
2631  if (fdwroutine->RefetchForeignRow == NULL)
2632  ereport(ERROR,
2633  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2634  errmsg("cannot lock rows in foreign table \"%s\"",
2636 
2637  fdwroutine->RefetchForeignRow(epqstate->recheckestate,
2638  erm,
2639  datum,
2640  slot,
2641  &updated);
2642  if (TupIsNull(slot))
2643  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2644 
2645  /*
2646  * Ideally we'd insist on updated == false here, but that assumes
2647  * that FDWs can track that exactly, which they might not be able
2648  * to. So just ignore the flag.
2649  */
2650  return true;
2651  }
2652  else
2653  {
2654  /* ordinary table, fetch the tuple */
2656  (ItemPointer) DatumGetPointer(datum),
2657  SnapshotAny, slot))
2658  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2659  return true;
2660  }
2661  }
2662  else
2663  {
2664  Assert(erm->markType == ROW_MARK_COPY);
2665 
2666  /* fetch the whole-row Var for the relation */
2667  datum = ExecGetJunkAttribute(epqstate->origslot,
2668  earm->wholeAttNo,
2669  &isNull);
2670  /* non-locked rels could be on the inside of outer joins */
2671  if (isNull)
2672  return false;
2673 
2674  ExecStoreHeapTupleDatum(datum, slot);
2675  return true;
2676  }
2677 }
Relation relation
Definition: execnodes.h:622
#define DatumGetObjectId(X)
Definition: postgres.h:500
int errcode(int sqlerrcode)
Definition: elog.c:608
Form_pg_class rd_rel
Definition: rel.h:83
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:639
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:1013
ExecRowMark * rowmark
Definition: execnodes.h:649
#define ERROR
Definition: elog.h:43
EState * recheckestate
Definition: execnodes.h:1106
Index rti
Definition: execnodes.h:624
AttrNumber wholeAttNo
Definition: execnodes.h:652
Index prti
Definition: execnodes.h:625
#define RelationGetRelationName(relation)
Definition: rel.h:457
#define TupIsNull(slot)
Definition: tuptable.h:292
TupleTableSlot * origslot
Definition: execnodes.h:1101
#define ereport(elevel, rest)
Definition: elog.h:141
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:1021
uintptr_t Datum
Definition: postgres.h:367
#define Assert(condition)
Definition: c.h:733
RowMarkType markType
Definition: execnodes.h:627
AttrNumber toidAttNo
Definition: execnodes.h:651
#define SnapshotAny
Definition: snapmgr.h:69
#define DatumGetPointer(X)
Definition: postgres.h:549
int errmsg(const char *fmt,...)
Definition: elog.c:822
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Definition: foreign.c:427
Datum ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, bool *isNull)
Definition: execJunk.c:247
#define elog(elevel,...)
Definition: elog.h:228
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1113
AttrNumber ctidAttNo
Definition: execnodes.h:650
RefetchForeignRow_function RefetchForeignRow
Definition: fdwapi.h:225

◆ EvalPlanQualInit()

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

Definition at line 2493 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(), apply_handle_update(), ExecInitLockRows(), and ExecInitModifyTable().

2495 {
2496  Index rtsize = parentestate->es_range_table_size;
2497 
2498  /* initialize data not changing over EPQState's lifetime */
2499  epqstate->parentestate = parentestate;
2500  epqstate->epqParam = epqParam;
2501 
2502  /*
2503  * Allocate space to reference a slot for each potential rti - do so now
2504  * rather than in EvalPlanQualBegin(), as done for other dynamically
2505  * allocated resources, so EvalPlanQualSlot() can be used to hold tuples
2506  * that *may* need EPQ later, without forcing the overhead of
2507  * EvalPlanQualBegin().
2508  */
2509  epqstate->tuple_table = NIL;
2510  epqstate->relsubs_slot = (TupleTableSlot **)
2511  palloc0(rtsize * sizeof(TupleTableSlot *));
2512 
2513  /* ... and remember data that EvalPlanQualBegin will need */
2514  epqstate->plan = subplan;
2515  epqstate->arowMarks = auxrowmarks;
2516 
2517  /* ... and mark the EPQ state inactive */
2518  epqstate->origslot = NULL;
2519  epqstate->recheckestate = NULL;
2520  epqstate->recheckplanstate = NULL;
2521  epqstate->relsubs_rowmark = NULL;
2522  epqstate->relsubs_done = NULL;
2523 }
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1085
#define NIL
Definition: pg_list.h:65
EState * parentestate
Definition: execnodes.h:1076
EState * recheckestate
Definition: execnodes.h:1106
List * arowMarks
Definition: execnodes.h:1093
List * tuple_table
Definition: execnodes.h:1084
bool * relsubs_done
Definition: execnodes.h:1119
TupleTableSlot * origslot
Definition: execnodes.h:1101
Plan * plan
Definition: execnodes.h:1092
void * palloc0(Size size)
Definition: mcxt.c:980
unsigned int Index
Definition: c.h:476
Index es_range_table_size
Definition: execnodes.h:506
int epqParam
Definition: execnodes.h:1077
ExecAuxRowMark ** relsubs_rowmark
Definition: execnodes.h:1113
PlanState * recheckplanstate
Definition: execnodes.h:1121

◆ EvalPlanQualNext()

TupleTableSlot* EvalPlanQualNext ( EPQState epqstate)

Definition at line 2685 of file execMain.c.

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

Referenced by EvalPlanQual(), and ExecLockRows().

2686 {
2687  MemoryContext oldcontext;
2688  TupleTableSlot *slot;
2689 
2690  oldcontext = MemoryContextSwitchTo(epqstate->recheckestate->es_query_cxt);
2691  slot = ExecProcNode(epqstate->recheckplanstate);
2692  MemoryContextSwitchTo(oldcontext);
2693 
2694  return slot;
2695 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:550
EState * recheckestate
Definition: execnodes.h:1106
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition: executor.h:235
PlanState * recheckplanstate
Definition: execnodes.h:1121

◆ EvalPlanQualSetPlan()

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

Definition at line 2531 of file execMain.c.

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

Referenced by ExecInitModifyTable(), and ExecModifyTable().

2532 {
2533  /* If we have a live EPQ query, shut it down */
2534  EvalPlanQualEnd(epqstate);
2535  /* And set/change the plan pointer */
2536  epqstate->plan = subplan;
2537  /* The rowmarks depend on the plan, too */
2538  epqstate->arowMarks = auxrowmarks;
2539 }
void EvalPlanQualEnd(EPQState *epqstate)
Definition: execMain.c:2953
List * arowMarks
Definition: execnodes.h:1093
Plan * plan
Definition: execnodes.h:1092

◆ EvalPlanQualSlot()

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

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

2550 {
2551  TupleTableSlot **slot;
2552 
2553  Assert(relation);
2554  Assert(rti > 0 && rti <= epqstate->parentestate->es_range_table_size);
2555  slot = &epqstate->relsubs_slot[rti - 1];
2556 
2557  if (*slot == NULL)
2558  {
2559  MemoryContext oldcontext;
2560 
2561  oldcontext = MemoryContextSwitchTo(epqstate->parentestate->es_query_cxt);
2562  *slot = table_slot_create(relation, &epqstate->tuple_table);
2563  MemoryContextSwitchTo(oldcontext);
2564  }
2565 
2566  return *slot;
2567 }
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:77
TupleTableSlot ** relsubs_slot
Definition: execnodes.h:1085
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
EState * parentestate
Definition: execnodes.h:1076
MemoryContext es_query_cxt
Definition: execnodes.h:550
List * tuple_table
Definition: execnodes.h:1084
#define Assert(condition)
Definition: c.h:733

◆ exec_rt_fetch()

◆ ExecAssignExprContext()

◆ ExecAssignProjectionInfo()

void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

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

501 {
502  planstate->ps_ProjInfo =
504  planstate->ps_ExprContext,
505  planstate->ps_ResultTupleSlot,
506  planstate,
507  inputDesc);
508 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:980
ExprContext * ps_ExprContext
Definition: execnodes.h:979
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:978
Plan * plan
Definition: execnodes.h:940
List * targetlist
Definition: plannodes.h:140
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:351

◆ 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:1334
void ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, Index varno)
Definition: execUtils.c:519
PlanState ps
Definition: execnodes.h:1331
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:124

◆ ExecAssignScanType()

void ExecAssignScanType ( ScanState scanstate,
TupleDesc  tupDesc 
)

Definition at line 634 of file execUtils.c.

References ExecSetSlotDescriptor(), and ScanState::ss_ScanTupleSlot.

Referenced by ExecWorkTableScan().

635 {
636  TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
637 
638  ExecSetSlotDescriptor(slot, tupDesc);
639 }
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1334
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:1259

◆ ExecBuildAggTrans()

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

Referenced by ExecProcNode().

◆ ExecBuildAuxRowMark()

ExecAuxRowMark* ExecBuildAuxRowMark ( ExecRowMark erm,
List targetlist 
)

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

2370 {
2371  ExecAuxRowMark *aerm = (ExecAuxRowMark *) palloc0(sizeof(ExecAuxRowMark));
2372  char resname[32];
2373 
2374  aerm->rowmark = erm;
2375 
2376  /* Look up the resjunk columns associated with this rowmark */
2377  if (erm->markType != ROW_MARK_COPY)
2378  {
2379  /* need ctid for all methods other than COPY */
2380  snprintf(resname, sizeof(resname), "ctid%u", erm->rowmarkId);
2381  aerm->ctidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2382  resname);
2383  if (!AttributeNumberIsValid(aerm->ctidAttNo))
2384  elog(ERROR, "could not find junk %s column", resname);
2385  }
2386  else
2387  {
2388  /* need wholerow if COPY */
2389  snprintf(resname, sizeof(resname), "wholerow%u", erm->rowmarkId);
2390  aerm->wholeAttNo = ExecFindJunkAttributeInTlist(targetlist,
2391  resname);
2392  if (!AttributeNumberIsValid(aerm->wholeAttNo))
2393  elog(ERROR, "could not find junk %s column", resname);
2394  }
2395 
2396  /* if child rel, need tableoid */
2397  if (erm->rti != erm->prti)
2398  {
2399  snprintf(resname, sizeof(resname), "tableoid%u", erm->rowmarkId);
2400  aerm->toidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2401  resname);
2402  if (!AttributeNumberIsValid(aerm->toidAttNo))
2403  elog(ERROR, "could not find junk %s column", resname);
2404  }
2405 
2406  return aerm;
2407 }
AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
Definition: execJunk.c:220
ExecRowMark * rowmark
Definition: execnodes.h:649
#define ERROR
Definition: elog.h:43
Index rti
Definition: execnodes.h:624
AttrNumber wholeAttNo
Definition: execnodes.h:652
Index prti
Definition: execnodes.h:625
Index rowmarkId
Definition: execnodes.h:626
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
void * palloc0(Size size)
Definition: mcxt.c:980
RowMarkType markType
Definition: execnodes.h:627
AttrNumber toidAttNo
Definition: execnodes.h:651
#define elog(elevel,...)
Definition: elog.h:228
#define snprintf
Definition: port.h:192
AttrNumber ctidAttNo
Definition: execnodes.h:650

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

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

◆ ExecBuildProjectionInfo()

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

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

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

◆ ExecCheck()

bool ExecCheck ( ExprState state,
ExprContext context 
)

Definition at line 597 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(), ExecRelCheck(), and validateCheckConstraint().

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

◆ ExecCheckIndexConstraints()

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

Definition at line 482 of file execIndexing.c.

References CEOUC_WAIT, check_exclusion_or_unique_constraint(), ExprContext::ecxt_scantuple, elog, ereport, errcode(), errmsg(), ERROR, errtableconstraint(), EState::es_result_relation_info, 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().

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

◆ 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:1805
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3352
static bool ExecCheckRTEPerms(RangeTblEntry *rte)
Definition: execMain.c:602
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
Definition: execMain.c:76
#define Assert(condition)
Definition: c.h:733
#define lfirst(lc)
Definition: pg_list.h:190
RTEKind rtekind
Definition: parsenodes.h:974
ObjectType get_relkind_objtype(char relkind)
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730

◆ ExecCleanTargetListLength()

int ExecCleanTargetListLength ( List targetlist)

Definition at line 1085 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

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

1086 {
1087  int len = 0;
1088  ListCell *tl;
1089 
1090  foreach(tl, targetlist)
1091  {
1092  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1093 
1094  if (!curTle->resjunk)
1095  len++;
1096  }
1097  return len;
1098 }
bool resjunk
Definition: primnodes.h:1400
#define lfirst_node(type, lc)
Definition: pg_list.h:193

◆ 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

◆ ExecCleanUpTriggerState()

void ExecCleanUpTriggerState ( EState estate)

Definition at line 1454 of file execMain.c.

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

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

1455 {
1456  ListCell *l;
1457 
1458  foreach(l, estate->es_trig_target_relations)
1459  {
1460  ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
1461 
1462  /*
1463  * Assert this is a "dummy" ResultRelInfo, see above. Otherwise we
1464  * might be issuing a duplicate close against a Relation opened by
1465  * ExecGetRangeTableRelation.
1466  */
1467  Assert(resultRelInfo->ri_RangeTableIndex == 0);
1468 
1469  /*
1470  * Since ExecGetTriggerResultRel doesn't call ExecOpenIndices for
1471  * these rels, we needn't call ExecCloseIndices either.
1472  */
1473  Assert(resultRelInfo->ri_NumIndices == 0);
1474 
1475  table_close(resultRelInfo->ri_RelationDesc, NoLock);
1476  }
1477 }
int ri_NumIndices
Definition: execnodes.h:414
Relation ri_RelationDesc
Definition: execnodes.h:411
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
Index ri_RangeTableIndex
Definition: execnodes.h:408
#define NoLock
Definition: lockdefs.h:34
List * es_trig_target_relations
Definition: execnodes.h:541
#define Assert(condition)
Definition: c.h:733
#define lfirst(lc)
Definition: pg_list.h:190

◆ 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(), apply_handle_insert(), apply_handle_update(), CatalogCloseIndexes(), CopyFrom(), exec_rt_fetch(), ExecCleanupTupleRouting(), and ExecEndPlan().

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:414
#define RowExclusiveLock
Definition: lockdefs.h:38
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:152
int i
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:417

◆ ExecConditionalAssignProjectionInfo()

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

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

521 {
522  if (tlist_matches_tupdesc(planstate,
523  planstate->plan->targetlist,
524  varno,
525  inputDesc))
526  {
527  planstate->ps_ProjInfo = NULL;
528  planstate->resultopsset = planstate->scanopsset;
529  planstate->resultopsfixed = planstate->scanopsfixed;
530  planstate->resultops = planstate->scanops;
531  }
532  else
533  {
534  if (!planstate->ps_ResultTupleSlot)
535  {
536  ExecInitResultSlot(planstate, &TTSOpsVirtual);
537  planstate->resultops = &TTSOpsVirtual;
538  planstate->resultopsfixed = true;
539  planstate->resultopsset = true;
540  }
541  ExecAssignProjectionInfo(planstate, inputDesc);
542  }
543 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:980
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
const TupleTableSlotOps * resultops
Definition: execnodes.h:1015
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:978
const TupleTableSlotOps * scanops
Definition: execnodes.h:1012
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:499
bool resultopsset
Definition: execnodes.h:1023
Plan * plan
Definition: execnodes.h:940
bool scanopsfixed
Definition: execnodes.h:1016
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:546
bool scanopsset
Definition: execnodes.h:1020
List * targetlist
Definition: plannodes.h:140
bool resultopsfixed
Definition: execnodes.h:1019

◆ ExecConstraints()

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

Definition at line 1905 of file execMain.c.

References Assert, bms_union(), TupleDescData::constr, convert_tuples_by_name_map_if_req(), 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_PartitionCheck, ResultRelInfo::ri_PartitionRoot, ResultRelInfo::ri_RelationDesc, slot_attisnull(), TTSOpsVirtual, and TupleDescAttr.

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

1907 {
1908  Relation rel = resultRelInfo->ri_RelationDesc;
1909  TupleDesc tupdesc = RelationGetDescr(rel);
1910  TupleConstr *constr = tupdesc->constr;
1911  Bitmapset *modifiedCols;
1912  Bitmapset *insertedCols;
1913  Bitmapset *updatedCols;
1914 
1915  Assert(constr || resultRelInfo->ri_PartitionCheck);
1916 
1917  if (constr && constr->has_not_null)
1918  {
1919  int natts = tupdesc->natts;
1920  int attrChk;
1921 
1922  for (attrChk = 1; attrChk <= natts; attrChk++)
1923  {
1924  Form_pg_attribute att = TupleDescAttr(tupdesc, attrChk - 1);
1925 
1926  if (att->attnotnull && slot_attisnull(slot, attrChk))
1927  {
1928  char *val_desc;
1929  Relation orig_rel = rel;
1930  TupleDesc orig_tupdesc = RelationGetDescr(rel);
1931 
1932  /*
1933  * If the tuple has been routed, it's been converted to the
1934  * partition's rowtype, which might differ from the root
1935  * table's. We must convert it back to the root table's
1936  * rowtype so that val_desc shown error message matches the
1937  * input tuple.
1938  */
1939  if (resultRelInfo->ri_PartitionRoot)
1940  {
1941  AttrNumber *map;
1942 
1943  rel = resultRelInfo->ri_PartitionRoot;
1944  tupdesc = RelationGetDescr(rel);
1945  /* a reverse map */
1946  map = convert_tuples_by_name_map_if_req(orig_tupdesc,
1947  tupdesc);
1948 
1949  /*
1950  * Partition-specific slot's tupdesc can't be changed, so
1951  * allocate a new one.
1952  */
1953  if (map != NULL)
1954  slot = execute_attr_map_slot(map, slot,
1955  MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
1956  }
1957 
1958  insertedCols = GetInsertedColumns(resultRelInfo, estate);
1959  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
1960  modifiedCols = bms_union(insertedCols, updatedCols);
1962  slot,
1963  tupdesc,
1964  modifiedCols,
1965  64);
1966 
1967  ereport(ERROR,
1968  (errcode(ERRCODE_NOT_NULL_VIOLATION),
1969  errmsg("null value in column \"%s\" violates not-null constraint",
1970  NameStr(att->attname)),
1971  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1972  errtablecol(orig_rel, attrChk)));
1973  }
1974  }
1975  }
1976 
1977  if (constr && constr->num_check > 0)
1978  {
1979  const char *failed;
1980 
1981  if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
1982  {
1983  char *val_desc;
1984  Relation orig_rel = rel;
1985 
1986  /* See the comment above. */
1987  if (resultRelInfo->ri_PartitionRoot)
1988  {
1989  TupleDesc old_tupdesc = RelationGetDescr(rel);
1990  AttrNumber *map;
1991 
1992  rel = resultRelInfo->ri_PartitionRoot;
1993  tupdesc = RelationGetDescr(rel);
1994  /* a reverse map */
1995  map = convert_tuples_by_name_map_if_req(old_tupdesc,
1996  tupdesc);
1997 
1998  /*
1999  * Partition-specific slot's tupdesc can't be changed, so
2000  * allocate a new one.
2001  */
2002  if (map != NULL)
2003  slot = execute_attr_map_slot(map, slot,
2004  MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
2005  }
2006 
2007  insertedCols = GetInsertedColumns(resultRelInfo, estate);
2008  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
2009  modifiedCols = bms_union(insertedCols, updatedCols);
2011  slot,
2012  tupdesc,
2013  modifiedCols,
2014  64);
2015  ereport(ERROR,
2016  (errcode(ERRCODE_CHECK_VIOLATION),
2017  errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
2018  RelationGetRelationName(orig_rel), failed),
2019  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
2020  errtableconstraint(orig_rel, failed)));
2021  }
2022  }
2023 }
#define GetUpdatedColumns(relinfo, estate)
Definition: execMain.c:111
Relation ri_RelationDesc
Definition: execnodes.h:411
#define RelationGetDescr(relation)
Definition: rel.h:449
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
Relation ri_PartitionRoot
Definition: execnodes.h:482
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
int errcode(int sqlerrcode)
Definition: elog.c:608
TupleTableSlot * execute_attr_map_slot(AttrNumber *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition: tupconvert.c:425
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5221
#define ERROR
Definition: elog.h:43
static char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
Definition: execMain.c:2183
TupleConstr * constr
Definition: tupdesc.h:85
int errdetail(const char *fmt,...)
Definition: elog.c:957
#define RelationGetRelationName(relation)
Definition: rel.h:457
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
#define ereport(elevel, rest)
Definition: elog.h:141
AttrNumber * convert_tuples_by_name_map_if_req(TupleDesc indesc, TupleDesc outdesc)
Definition: tupconvert.c:327
List * ri_PartitionCheck
Definition: execnodes.h:476
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:1726
#define Assert(condition)
Definition: c.h:733
int errtablecol(Relation rel, int attnum)
Definition: relcache.c:5184
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:225
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define NameStr(name)
Definition: c.h:610
bool has_not_null
Definition: tupdesc.h:44
static bool slot_attisnull(TupleTableSlot *slot, int attnum)
Definition: tuptable.h:367
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:423
#define GetInsertedColumns(relinfo, estate)
Definition: execMain.c:109

◆ ExecCreateScanSlotFromOuterPlan()

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

Definition at line 646 of file execUtils.c.

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

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

649 {
651  TupleDesc tupDesc;
652 
653  outerPlan = outerPlanState(scanstate);
654  tupDesc = ExecGetResultType(outerPlan);
655 
656  ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops);
657 }
#define outerPlanState(node)
Definition: execnodes.h:1034
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1781
#define outerPlan(node)
Definition: plannodes.h:170
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:454

◆ 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:576
static ScanState * search_plan_tree(PlanState *node, Oid table_oid, bool *pending_rescan)
Definition: execCurrent.c:310
bool atEnd
Definition: portal.h:189
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:608
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1334
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:1013
ItemPointerData * ItemPointer
Definition: itemptr.h:49
ItemPointerData curCtid
Definition: execnodes.h:631
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:509
#define ERROR
Definition: elog.h:43
PlanState * planstate
Definition: execdesc.h:49
ItemPointerData xs_heaptid
Definition: relscan.h:132
#define TupIsNull(slot)
Definition: tuptable.h:292
#define TableOidAttributeNumber
Definition: sysattr.h:26
char * cursor_name
Definition: primnodes.h:1303
PortalStrategy strategy
Definition: portal.h:143
#define ereport(elevel, rest)
Definition: elog.h:141
QueryDesc * queryDesc
Definition: portal.h:154
#define PortalIsValid(p)
Definition: portal.h:201
uintptr_t Datum
Definition: postgres.h:367
unsigned int Index
Definition: c.h:476
#define Assert(condition)
Definition: c.h:733
RowMarkType markType
Definition: execnodes.h:627
Index es_range_table_size
Definition: execnodes.h:506
#define DatumGetPointer(X)
Definition: postgres.h:549
bool atStart
Definition: portal.h:188
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define elog(elevel,...)
Definition: elog.h:228
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:1730

◆ ExecEndNode()

void ExecEndNode ( PlanState node)

Definition at line 537 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(), 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_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(), ExecEndLimit(), ExecEndLockRows(), ExecEndMaterial(), ExecEndMergeAppend(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNestLoop(), ExecEndPlan(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndUnique(), and ExecEndWindowAgg().

538 {
539  /*
540  * do nothing when we get to the end of a leaf on tree.
541  */
542  if (node == NULL)
543  return;
544 
545  /*
546  * Make sure there's enough stack available. Need to check here, in
547  * addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not
548  * guaranteed that ExecProcNode() is reached for all nodes.
549  */
551 
552  if (node->chgParam != NULL)
553  {
554  bms_free(node->chgParam);
555  node->chgParam = NULL;
556  }
557 
558  switch (nodeTag(node))
559  {
560  /*
561  * control nodes
562  */
563  case T_ResultState:
564  ExecEndResult((ResultState *) node);
565  break;
566 
567  case T_ProjectSetState:
569  break;
570 
571  case T_ModifyTableState:
573  break;
574 
575  case T_AppendState:
576  ExecEndAppend((AppendState *) node);
577  break;
578 
579  case T_MergeAppendState:
581  break;
582 
585  break;
586 
587  case T_BitmapAndState:
589  break;
590 
591  case T_BitmapOrState:
592  ExecEndBitmapOr((BitmapOrState *) node);
593  break;
594 
595  /*
596  * scan nodes
597  */
598  case T_SeqScanState:
599  ExecEndSeqScan((SeqScanState *) node);
600  break;
601 
602  case T_SampleScanState:
604  break;
605 
606  case T_GatherState:
607  ExecEndGather((GatherState *) node);
608  break;
609 
610  case T_GatherMergeState:
612  break;
613 
614  case T_IndexScanState:
616  break;
617 
620  break;
621 
624  break;
625 
628  break;
629 
630  case T_TidScanState:
631  ExecEndTidScan((TidScanState *) node);
632  break;
633 
634  case T_SubqueryScanState:
636  break;
637 
638  case T_FunctionScanState:
640  break;
641 
644  break;
645 
646  case T_ValuesScanState:
648  break;
649 
650  case T_CteScanState:
651  ExecEndCteScan((CteScanState *) node);
652  break;
653 
656  break;
657 
660  break;
661 
662  case T_ForeignScanState:
664  break;
665 
666  case T_CustomScanState:
668  break;
669 
670  /*
671  * join nodes
672  */
673  case T_NestLoopState:
674  ExecEndNestLoop((NestLoopState *) node);
675  break;
676 
677  case T_MergeJoinState:
679  break;
680 
681  case T_HashJoinState:
682  ExecEndHashJoin((HashJoinState *) node);
683  break;
684 
685  /*
686  * materialization nodes
687  */
688  case T_MaterialState:
689  ExecEndMaterial((MaterialState *) node);
690  break;
691 
692  case T_SortState:
693  ExecEndSort((SortState *) node);
694  break;
695 
696  case T_GroupState:
697  ExecEndGroup((GroupState *) node);
698  break;
699 
700  case T_AggState:
701  ExecEndAgg((AggState *) node);
702  break;
703 
704  case T_WindowAggState:
706  break;
707 
708  case T_UniqueState:
709  ExecEndUnique((UniqueState *) node);
710  break;
711 
712  case T_HashState:
713  ExecEndHash((HashState *) node);
714  break;
715 
716  case T_SetOpState:
717  ExecEndSetOp((SetOpState *) node);
718  break;
719 
720  case T_LockRowsState:
721  ExecEndLockRows((LockRowsState *) node);
722  break;
723 
724  case T_LimitState:
725  ExecEndLimit((LimitState *) node);
726  break;
727 
728  default:
729  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
730  break;
731  }
732 }
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:404
void ExecEndUnique(UniqueState *node)
Definition: nodeUnique.c:169
void ExecEndGatherMerge(GatherMergeState *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:746
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:314
void ExecEndForeignScan(ForeignScanState *node)
void ExecEndSort(SortState *node)
Definition: nodeSort.c:234
void ExecEndBitmapIndexScan(BitmapIndexScanState *node)
void check_stack_depth(void)
Definition: postgres.c:3284
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:469
Bitmapset * chgParam
Definition: execnodes.h:972
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:530
#define elog(elevel,...)
Definition: elog.h:228
void ExecEndHash(HashState *node)
Definition: nodeHash.c:405
void ExecEndProjectSet(ProjectSetState *node)
void ExecEndMaterial(MaterialState *node)
Definition: nodeMaterial.c:240
void ExecEndBitmapHeapScan(BitmapHeapScanState *node)
void ExecEndAgg(AggState *node)
Definition: nodeAgg.c:3387
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 300 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().

303 {
304  Datum retDatum;
305  MemoryContext oldContext;
306 
307  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
308  retDatum = state->evalfunc(state, econtext, isNull);
309  MemoryContextSwitchTo(oldContext);
310  return retDatum;
311 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:232
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ExprStateEvalFunc evalfunc
Definition: execnodes.h:92
uintptr_t Datum
Definition: postgres.h:367

◆ ExecFilterJunk()

TupleTableSlot* ExecFilterJunk ( JunkFilter junkfilter,
TupleTableSlot slot 
)

Definition at line 261 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(), ExecEvalWholeRowVar(), ExecModifyTable(), ExecUpdate(), ExecutePlan(), and sqlfunction_receive().

262 {
263  TupleTableSlot *resultSlot;
264  AttrNumber *cleanMap;
265  TupleDesc cleanTupType;
266  int cleanLength;
267  int i;
268  Datum *values;
269  bool *isnull;
270  Datum *old_values;
271  bool *old_isnull;
272 
273  /*
274  * Extract all the values of the old tuple.
275  */
276  slot_getallattrs(slot);
277  old_values = slot->tts_values;
278  old_isnull = slot->tts_isnull;
279 
280  /*
281  * get info from the junk filter
282  */
283  cleanTupType = junkfilter->jf_cleanTupType;
284  cleanLength = cleanTupType->natts;
285  cleanMap = junkfilter->jf_cleanMap;
286  resultSlot = junkfilter->jf_resultSlot;
287 
288  /*
289  * Prepare to build a virtual result tuple.
290  */
291  ExecClearTuple(resultSlot);
292  values = resultSlot->tts_values;
293  isnull = resultSlot->tts_isnull;
294 
295  /*
296  * Transpose data into proper fields of the new tuple.
297  */
298  for (i = 0; i < cleanLength; i++)
299  {
300  int j = cleanMap[i];
301 
302  if (j == 0)
303  {
304  values[i] = (Datum) 0;
305  isnull[i] = true;
306  }
307  else
308  {
309  values[i] = old_values[j - 1];
310  isnull[i] = old_isnull[j - 1];
311  }
312  }
313 
314  /*
315  * And return the virtual tuple.
316  */
317  return ExecStoreVirtualTuple(resultSlot);
318 }
AttrNumber * jf_cleanMap
Definition: execnodes.h:369
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
TupleTableSlot * jf_resultSlot
Definition: execnodes.h:370
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:368
uintptr_t Datum
Definition: postgres.h:367
static Datum values[MAXATTR]
Definition: bootstrap.c:167
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 208 of file execJunk.c.

References ExecFindJunkAttributeInTlist(), and JunkFilter::jf_targetList.

Referenced by ExecInitModifyTable().

209 {
210  return ExecFindJunkAttributeInTlist(junkfilter->jf_targetList, attrName);
211 }
AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
Definition: execJunk.c:220
List * jf_targetList
Definition: execnodes.h:367

◆ ExecFindJunkAttributeInTlist()

AttrNumber ExecFindJunkAttributeInTlist ( List targetlist,
const char *  attrName 
)

Definition at line 220 of file execJunk.c.

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

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

221 {
222  ListCell *t;
223 
224  foreach(t, targetlist)
225  {
226  TargetEntry *tle = lfirst(t);
227 
228  if (tle->resjunk && tle->resname &&
229  (strcmp(tle->resname, attrName) == 0))
230  {
231  /* We found it ! */
232  return tle->resno;
233  }
234  }
235 
236  return InvalidAttrNumber;
237 }
char * resname
Definition: primnodes.h:1395
bool resjunk
Definition: primnodes.h:1400
AttrNumber resno
Definition: primnodes.h:1394
#define lfirst(lc)
Definition: pg_list.h:190
#define InvalidAttrNumber
Definition: attnum.h:23

◆ ExecFindRowMark()

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

Definition at line 2346 of file execMain.c.

References elog, ERROR, and EState::es_rowmarks.

Referenced by ExecInitLockRows(), and ExecInitModifyTable().

2347 {
2348  if (rti > 0 && rti <= estate->es_range_table_size &&
2349  estate->es_rowmarks != NULL)
2350  {
2351  ExecRowMark *erm = estate->es_rowmarks[rti - 1];
2352 
2353  if (erm)
2354  return erm;
2355  }
2356  if (!missing_ok)
2357  elog(ERROR, "failed to find ExecRowMark for rangetable index %u", rti);
2358  return NULL;
2359 }
struct ExecRowMark ** es_rowmarks
Definition: execnodes.h:509
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:228

◆ ExecFreeExprContext()

◆ ExecGetJunkAttribute()

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

Definition at line 247 of file execJunk.c.

References Assert, and slot_getattr().

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

249 {
250  Assert(attno > 0);
251 
252  return slot_getattr(slot, attno, isNull);
253 }
static Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: tuptable.h:381
#define Assert(condition)
Definition: c.h:733

◆ ExecGetRangeTableRelation()

Relation ExecGetRangeTableRelation ( EState estate,
Index  rti 
)

Definition at line 754 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(), ExecOpenScanRelation(), and InitPlan().

755 {
756  Relation rel;
757 
758  Assert(rti > 0 && rti <= estate->es_range_table_size);
759 
760  rel = estate->es_relations[rti - 1];
761  if (rel == NULL)
762  {
763  /* First time through, so open the relation */
764  RangeTblEntry *rte = exec_rt_fetch(rti, estate);
765 
766  Assert(rte->rtekind == RTE_RELATION);
767 
768  if (!IsParallelWorker())
769  {
770  /*
771  * In a normal query, we should already have the appropriate lock,
772  * but verify that through an Assert. Since there's already an
773  * Assert inside table_open that insists on holding some lock, it
774  * seems sufficient to check this only when rellockmode is higher
775  * than the minimum.
776  */
777  rel = table_open(rte->relid, NoLock);
779  CheckRelationLockedByMe(rel, rte->rellockmode, false));
780  }
781  else
782  {
783  /*
784  * If we are a parallel worker, we need to obtain our own local
785  * lock on the relation. This ensures sane behavior in case the
786  * parent process exits before we do.
787  */
788  rel = table_open(rte->relid, rte->rellockmode);
789  }
790 
791  estate->es_relations[rti - 1] = rel;
792  }
793 
794  return rel;
795 }
#define AccessShareLock
Definition: lockdefs.h:36
#define NoLock
Definition: lockdefs.h:34
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:537
#define IsParallelWorker()
Definition: parallel.h:60
#define Assert(condition)
Definition: c.h:733
Relation * es_relations
Definition: execnodes.h:507
bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger)
Definition: lmgr.c:302
RTEKind rtekind
Definition: parsenodes.h:974
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ ExecGetResultSlotOps()

const TupleTableSlotOps* ExecGetResultSlotOps ( PlanState planstate,
bool isfixed 
)

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

464 {
465  if (planstate->resultopsset && planstate->resultops)
466  {
467  if (isfixed)
468  *isfixed = planstate->resultopsfixed;
469  return planstate->resultops;
470  }
471 
472  if (isfixed)
473  {
474  if (planstate->resultopsset)
475  *isfixed = planstate->resultopsfixed;
476  else if (planstate->ps_ResultTupleSlot)
477  *isfixed = TTS_FIXED(planstate->ps_ResultTupleSlot);
478  else
479  *isfixed = false;
480  }
481 
482  if (!planstate->ps_ResultTupleSlot)
483  return &TTSOpsVirtual;
484 
485  return planstate->ps_ResultTupleSlot->tts_ops;
486 }
#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:1015
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:978
bool resultopsset
Definition: execnodes.h:1023
bool resultopsfixed
Definition: execnodes.h:1019

◆ ExecGetResultType()

◆ ExecGetReturningSlot()

TupleTableSlot* ExecGetReturningSlot ( EState estate,
ResultRelInfo relInfo 
)

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

1149 {
1150  if (relInfo->ri_ReturningSlot == NULL)
1151  {
1152  Relation rel = relInfo->ri_RelationDesc;
1153  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1154 
1155  relInfo->ri_ReturningSlot =
1156  ExecInitExtraTupleSlot(estate,
1157  RelationGetDescr(rel),
1158  table_slot_callbacks(rel));
1159 
1160  MemoryContextSwitchTo(oldcontext);
1161  }
1162 
1163  return relInfo->ri_ReturningSlot;
1164 }
Relation ri_RelationDesc
Definition: execnodes.h:411
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1801
#define RelationGetDescr(relation)
Definition: rel.h:449
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:44
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:550
TupleTableSlot * ri_ReturningSlot
Definition: execnodes.h:435

◆ ExecGetTriggerNewSlot()

TupleTableSlot* ExecGetTriggerNewSlot ( EState estate,
ResultRelInfo relInfo 
)

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

1127 {
1128  if (relInfo->ri_TrigNewSlot == NULL)
1129  {
1130  Relation rel = relInfo->ri_RelationDesc;
1131  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1132 
1133  relInfo->ri_TrigNewSlot =
1134  ExecInitExtraTupleSlot(estate,
1135  RelationGetDescr(rel),
1136  table_slot_callbacks(rel));
1137 
1138  MemoryContextSwitchTo(oldcontext);
1139  }
1140 
1141  return relInfo->ri_TrigNewSlot;
1142 }
Relation ri_RelationDesc
Definition: execnodes.h:411
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1801
#define RelationGetDescr(relation)
Definition: rel.h:449
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:44
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
TupleTableSlot * ri_TrigNewSlot
Definition: execnodes.h:437
MemoryContext es_query_cxt
Definition: execnodes.h:550

◆ ExecGetTriggerOldSlot()

TupleTableSlot* ExecGetTriggerOldSlot ( EState estate,
ResultRelInfo relInfo 
)

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

1105 {
1106  if (relInfo->ri_TrigOldSlot == NULL)
1107  {
1108  Relation rel = relInfo->ri_RelationDesc;
1109  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1110 
1111  relInfo->ri_TrigOldSlot =
1112  ExecInitExtraTupleSlot(estate,
1113  RelationGetDescr(rel),
1114  table_slot_callbacks(rel));
1115 
1116  MemoryContextSwitchTo(oldcontext);
1117  }
1118 
1119  return relInfo->ri_TrigOldSlot;
1120 }
Relation ri_RelationDesc
Definition: execnodes.h:411
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1801
#define RelationGetDescr(relation)
Definition: rel.h:449
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:44
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:550
TupleTableSlot * ri_TrigOldSlot
Definition: execnodes.h:436

◆ ExecGetTriggerResultRel()

ResultRelInfo* ExecGetTriggerResultRel ( EState estate,
Oid  relid 
)

Definition at line 1371 of file execMain.c.

References EState::es_instrument, EState::es_num_result_relations, EState::es_num_root_result_relations, EState::es_query_cxt, EState::es_result_relations, EState::es_root_result_relations, 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().

1372 {
1373  ResultRelInfo *rInfo;
1374  int nr;
1375  ListCell *l;
1376  Relation rel;
1377  MemoryContext oldcontext;
1378 
1379  /* First, search through the query result relations */
1380  rInfo = estate->es_result_relations;
1381  nr = estate->es_num_result_relations;
1382  while (nr > 0)
1383  {
1384  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1385  return rInfo;
1386  rInfo++;
1387  nr--;
1388  }
1389  /* Second, search through the root result relations, if any */
1390  rInfo = estate->es_root_result_relations;
1391  nr = estate->es_num_root_result_relations;
1392  while (nr > 0)
1393  {
1394  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1395  return rInfo;
1396  rInfo++;
1397  nr--;
1398  }
1399 
1400  /*
1401  * Third, search through the result relations that were created during
1402  * tuple routing, if any.
1403  */
1404  foreach(l, estate->es_tuple_routing_result_relations)
1405  {
1406  rInfo = (ResultRelInfo *) lfirst(l);
1407  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1408  return rInfo;
1409  }
1410 
1411  /* Nope, but maybe we already made an extra ResultRelInfo for it */
1412  foreach(l, estate->es_trig_target_relations)
1413  {
1414  rInfo = (ResultRelInfo *) lfirst(l);
1415  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1416  return rInfo;
1417  }
1418  /* Nope, so we need a new one */
1419 
1420  /*
1421  * Open the target relation's relcache entry. We assume that an
1422  * appropriate lock is still held by the backend from whenever the trigger
1423  * event got queued, so we need take no new lock here. Also, we need not
1424  * recheck the relkind, so no need for CheckValidResultRel.
1425  */
1426  rel = table_open(relid, NoLock);
1427 
1428  /*
1429  * Make the new entry in the right context.
1430  */
1431  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1432  rInfo = makeNode(ResultRelInfo);
1433  InitResultRelInfo(rInfo,
1434  rel,
1435  0, /* dummy rangetable index */
1436  NULL,
1437  estate->es_instrument);
1438  estate->es_trig_target_relations =
1439  lappend(estate->es_trig_target_relations, rInfo);
1440  MemoryContextSwitchTo(oldcontext);
1441 
1442  /*
1443  * Currently, we don't need any index information in ResultRelInfos used
1444  * only for triggers, so no need to call ExecOpenIndices.
1445  */
1446 
1447  return rInfo;
1448 }
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, Relation partition_root, int instrument_options)
Definition: execMain.c:1277
Relation ri_RelationDesc
Definition: execnodes.h:411
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:550
#define NoLock
Definition: lockdefs.h:34
ResultRelInfo * es_result_relations
Definition: execnodes.h:520
int es_instrument
Definition: execnodes.h:557
List * lappend(List *list, void *datum)
Definition: list.c:322
int es_num_root_result_relations
Definition: execnodes.h:531
List * es_trig_target_relations
Definition: execnodes.h:541
int es_num_result_relations
Definition: execnodes.h:521
List * es_tuple_routing_result_relations
Definition: execnodes.h:538
#define makeNode(_type_)
Definition: nodes.h:573
#define lfirst(lc)
Definition: pg_list.h:190
ResultRelInfo * es_root_result_relations
Definition: execnodes.h:530
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define RelationGetRelid(relation)
Definition: rel.h:423

◆ ExecInitCheck()

ExprState* ExecInitCheck ( List qual,
PlanState parent 
)

Definition at line 296 of file execExpr.c.

References Assert,