PostgreSQL Source Code  git master
executor.h File Reference
#include "executor/execdesc.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 (EState *estate, EPQState *epqstate, Relation relation, Index rti, TupleTableSlot *testslot)
 
void EvalPlanQualInit (EPQState *epqstate, EState *estate, Plan *subplan, List *auxrowmarks, int epqParam)
 
void EvalPlanQualSetPlan (EPQState *epqstate, Plan *subplan, List *auxrowmarks)
 
TupleTableSlotEvalPlanQualSlot (EPQState *epqstate, Relation relation, Index rti)
 
void EvalPlanQualFetchRowMarks (EPQState *epqstate)
 
TupleTableSlotEvalPlanQualNext (EPQState *epqstate)
 
void EvalPlanQualBegin (EPQState *epqstate, EState *parentestate)
 
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 473 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 60 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 509 of file executor.h.

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

Typedef Documentation

◆ ExecScanAccessMtd

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

Definition at line 424 of file executor.h.

◆ ExecScanRecheckMtd

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

Definition at line 425 of file executor.h.

◆ ExecutorCheckPerms_hook_type

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

Definition at line 83 of file executor.h.

◆ ExecutorEnd_hook_type

typedef void(* ExecutorEnd_hook_type) (QueryDesc *queryDesc)

Definition at line 79 of file executor.h.

◆ ExecutorFinish_hook_type

typedef void(* ExecutorFinish_hook_type) (QueryDesc *queryDesc)

Definition at line 75 of file executor.h.

◆ ExecutorRun_hook_type

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

Definition at line 68 of file executor.h.

◆ ExecutorStart_hook_type

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

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

2234 {
2235  TupOutputState *tstate;
2236 
2237  tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
2238 
2239  tstate->slot = MakeSingleTupleTableSlot(tupdesc, tts_ops);
2240  tstate->dest = dest;
2241 
2242  tstate->dest->rStartup(tstate->dest, (int) CMD_SELECT, tupdesc);
2243 
2244  return tstate;
2245 }
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1202
TupleTableSlot * slot
Definition: executor.h:457
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:121
void * palloc(Size size)
Definition: mcxt.c:924
DestReceiver * dest
Definition: executor.h:458

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

References BuildTupleHashTableExt().

251 {
252  return BuildTupleHashTableExt(parent,
253  inputDesc,
254  numCols, keyColIdx,
255  eqfuncoids,
256  hashfunctions,
257  collations,
258  nbuckets, additionalsize,
259  tablecxt,
260  tablecxt,
261  tempcxt,
262  use_variable_hash_iv);
263 }
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 
170  Assert(nbuckets > 0);
171 
172  /* Limit initial table size request to not more than work_mem */
173  nbuckets = Min(nbuckets, (long) ((work_mem * 1024L) / entrysize));
174 
175  oldcontext = MemoryContextSwitchTo(metacxt);
176 
177  hashtable = (TupleHashTable) palloc(sizeof(TupleHashTableData));
178 
179  hashtable->numCols = numCols;
180  hashtable->keyColIdx = keyColIdx;
181  hashtable->tab_hash_funcs = hashfunctions;
182  hashtable->tab_collations = collations;
183  hashtable->tablecxt = tablecxt;
184  hashtable->tempcxt = tempcxt;
185  hashtable->entrysize = entrysize;
186  hashtable->tableslot = NULL; /* will be made on first lookup */
187  hashtable->inputslot = NULL;
188  hashtable->in_hash_funcs = NULL;
189  hashtable->cur_eq_func = NULL;
190 
191  /*
192  * If parallelism is in use, even if the master backend is performing the
193  * scan itself, we don't want to create the hashtable exactly the same way
194  * in all workers. As hashtables are iterated over in keyspace-order,
195  * doing so in all processes in the same way is likely to lead to
196  * "unbalanced" hashtables when the table size initially is
197  * underestimated.
198  */
199  if (use_variable_hash_iv)
201  else
202  hashtable->hash_iv = 0;
203 
204  hashtable->hashtab = tuplehash_create(metacxt, nbuckets, hashtable);
205 
206  /*
207  * We copy the input tuple descriptor just for safety --- we assume all
208  * input tuples will have equivalent descriptors.
209  */
212 
213  /* build comparator for all columns */
214  /* XXX: should we support non-minimal tuples for the inputslot? */
215  hashtable->tab_eq_func = ExecBuildGroupingEqual(inputDesc, inputDesc,
217  numCols,
218  keyColIdx, eqfuncoids, collations,
219  NULL);
220 
221  /*
222  * While not pretty, it's ok to not shut down this context, but instead
223  * rely on the containing memory context being reset, as
224  * ExecBuildGroupingEqual() only builds a very simple expression calling
225  * functions (i.e. nothing that'd employ RegisterExprContextCallback()).
226  */
228 
229  MemoryContextSwitchTo(oldcontext);
230 
231  return hashtable;
232 }
ExprContext * exprcontext
Definition: execnodes.h:713
ExprContext * CreateStandaloneExprContext(void)
Definition: execUtils.c:319
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:110
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1202
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:3315
TupleTableSlot * inputslot
Definition: execnodes.h:709
#define Min(x, y)
Definition: c.h:890
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
AttrNumber * keyColIdx
Definition: execnodes.h:700
ExprState * tab_eq_func
Definition: execnodes.h:702
ExprState * cur_eq_func
Definition: execnodes.h:711
FmgrInfo * tab_hash_funcs
Definition: execnodes.h:701
FmgrInfo * in_hash_funcs
Definition: execnodes.h:710
struct TupleHashEntryData TupleHashEntryData
MemoryContext tablecxt
Definition: execnodes.h:704
struct TupleHashTableData * TupleHashTable
Definition: execnodes.h:678
int ParallelWorkerNumber
Definition: parallel.c:110
int work_mem
Definition: globals.c:121
tuplehash_hash * hashtab
Definition: execnodes.h:698
#define Assert(condition)
Definition: c.h:732
TupleTableSlot * tableslot
Definition: execnodes.h:707
size_t Size
Definition: c.h:466
void * palloc(Size size)
Definition: mcxt.c:924
static uint32 murmurhash32(uint32 data)
Definition: hashutils.h:60
MemoryContext tempcxt
Definition: execnodes.h:705
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:974
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:4578
int errcode(int sqlerrcode)
Definition: elog.c:570
Form_pg_class rd_rel
Definition: rel.h:84
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:448
#define ereport(elevel, rest)
Definition: elog.h:141
struct PublicationActions * GetRelationPublicationActions(Relation relation)
Definition: relcache.c:5110
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ 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:570
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:860
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ CheckValidResultRel()

void CheckValidResultRel ( ResultRelInfo resultRelInfo,
CmdType  operation 
)

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

1079 {
1080  Relation resultRel = resultRelInfo->ri_RelationDesc;
1081  TriggerDesc *trigDesc = resultRel->trigdesc;
1082  FdwRoutine *fdwroutine;
1083 
1084  switch (resultRel->rd_rel->relkind)
1085  {
1086  case RELKIND_RELATION:
1087  case RELKIND_PARTITIONED_TABLE:
1088  CheckCmdReplicaIdentity(resultRel, operation);
1089  break;
1090  case RELKIND_SEQUENCE:
1091  ereport(ERROR,
1092  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1093  errmsg("cannot change sequence \"%s\"",
1094  RelationGetRelationName(resultRel))));
1095  break;
1096  case RELKIND_TOASTVALUE:
1097  ereport(ERROR,
1098  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1099  errmsg("cannot change TOAST relation \"%s\"",
1100  RelationGetRelationName(resultRel))));
1101  break;
1102  case RELKIND_VIEW:
1103 
1104  /*
1105  * Okay only if there's a suitable INSTEAD OF trigger. Messages
1106  * here should match rewriteHandler.c's rewriteTargetView, except
1107  * that we omit errdetail because we haven't got the information
1108  * handy (and given that we really shouldn't get here anyway, it's
1109  * not worth great exertion to get).
1110  */
1111  switch (operation)
1112  {
1113  case CMD_INSERT:
1114  if (!trigDesc || !trigDesc->trig_insert_instead_row)
1115  ereport(ERROR,
1116  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1117  errmsg("cannot insert into view \"%s\"",
1118  RelationGetRelationName(resultRel)),
1119  errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule.")));
1120  break;
1121  case CMD_UPDATE:
1122  if (!trigDesc || !trigDesc->trig_update_instead_row)
1123  ereport(ERROR,
1124  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1125  errmsg("cannot update view \"%s\"",
1126  RelationGetRelationName(resultRel)),
1127  errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.")));
1128  break;
1129  case CMD_DELETE:
1130  if (!trigDesc || !trigDesc->trig_delete_instead_row)
1131  ereport(ERROR,
1132  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1133  errmsg("cannot delete from view \"%s\"",
1134  RelationGetRelationName(resultRel)),
1135  errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule.")));
1136  break;
1137  default:
1138  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1139  break;
1140  }
1141  break;
1142  case RELKIND_MATVIEW:
1144  ereport(ERROR,
1145  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1146  errmsg("cannot change materialized view \"%s\"",
1147  RelationGetRelationName(resultRel))));
1148  break;
1149  case RELKIND_FOREIGN_TABLE:
1150  /* Okay only if the FDW supports it */
1151  fdwroutine = resultRelInfo->ri_FdwRoutine;
1152  switch (operation)
1153  {
1154  case CMD_INSERT:
1155  if (fdwroutine->ExecForeignInsert == NULL)
1156  ereport(ERROR,
1157  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1158  errmsg("cannot insert into foreign table \"%s\"",
1159  RelationGetRelationName(resultRel))));
1160  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1161  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_INSERT)) == 0)
1162  ereport(ERROR,
1163  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1164  errmsg("foreign table \"%s\" does not allow inserts",
1165  RelationGetRelationName(resultRel))));
1166  break;
1167  case CMD_UPDATE:
1168  if (fdwroutine->ExecForeignUpdate == NULL)
1169  ereport(ERROR,
1170  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1171  errmsg("cannot update foreign table \"%s\"",
1172  RelationGetRelationName(resultRel))));
1173  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1174  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_UPDATE)) == 0)
1175  ereport(ERROR,
1176  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1177  errmsg("foreign table \"%s\" does not allow updates",
1178  RelationGetRelationName(resultRel))));
1179  break;
1180  case CMD_DELETE:
1181  if (fdwroutine->ExecForeignDelete == NULL)
1182  ereport(ERROR,
1183  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1184  errmsg("cannot delete from foreign table \"%s\"",
1185  RelationGetRelationName(resultRel))));
1186  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1187  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_DELETE)) == 0)
1188  ereport(ERROR,
1189  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1190  errmsg("foreign table \"%s\" does not allow deletes",
1191  RelationGetRelationName(resultRel))));
1192  break;
1193  default:
1194  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1195  break;
1196  }
1197  break;
1198  default:
1199  ereport(ERROR,
1200  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1201  errmsg("cannot change relation \"%s\"",
1202  RelationGetRelationName(resultRel))));
1203  break;
1204  }
1205 }
ExecForeignDelete_function ExecForeignDelete
Definition: fdwapi.h:213
Relation ri_RelationDesc
Definition: execnodes.h:410
int errhint(const char *fmt,...)
Definition: elog.c:974
bool MatViewIncrementalMaintenanceIsEnabled(void)
Definition: matview.c:912
ExecForeignInsert_function ExecForeignInsert
Definition: fdwapi.h:211
int errcode(int sqlerrcode)
Definition: elog.c:570
Form_pg_class rd_rel
Definition: rel.h:84
bool trig_insert_instead_row
Definition: reltrigger.h:57
#define ERROR
Definition: elog.h:43
TriggerDesc * trigdesc
Definition: rel.h:90
#define RelationGetRelationName(relation)
Definition: rel.h:448
struct FdwRoutine * ri_FdwRoutine
Definition: execnodes.h:439
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:784
#define elog(elevel,...)
Definition: elog.h:226
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_epqScanDone, EState::es_epqTupleSlot, 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_array, 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_array = NULL;
117  estate->es_range_table_size = 0;
118  estate->es_relations = NULL;
119  estate->es_rowmarks = NULL;
120  estate->es_plannedstmt = NULL;
121 
122  estate->es_junkFilter = NULL;
123 
124  estate->es_output_cid = (CommandId) 0;
125 
126  estate->es_result_relations = NULL;
127  estate->es_num_result_relations = 0;
128  estate->es_result_relation_info = NULL;
129 
130  estate->es_root_result_relations = NULL;
131  estate->es_num_root_result_relations = 0;
132 
134 
135  estate->es_trig_target_relations = NIL;
136 
137  estate->es_param_list_info = NULL;
138  estate->es_param_exec_vals = NULL;
139 
140  estate->es_queryEnv = NULL;
141 
142  estate->es_query_cxt = qcontext;
143 
144  estate->es_tupleTable = NIL;
145 
146  estate->es_processed = 0;
147 
148  estate->es_top_eflags = 0;
149  estate->es_instrument = 0;
150  estate->es_finished = false;
151 
152  estate->es_exprcontexts = NIL;
153 
154  estate->es_subplanstates = NIL;
155 
156  estate->es_auxmodifytables = NIL;
157 
158  estate->es_per_tuple_exprcontext = NULL;
159 
160  estate->es_epqTupleSlot = NULL;
161  estate->es_epqScanDone = NULL;
162  estate->es_sourceText = NULL;
163 
164  estate->es_use_parallel_mode = false;
165 
166  estate->es_jit_flags = 0;
167  estate->es_jit = NULL;
168 
169  /*
170  * Return the executor state structure
171  */
172  MemoryContextSwitchTo(oldcontext);
173 
174  return estate;
175 }
#define NIL
Definition: pg_list.h:65
uint32 CommandId
Definition: c.h:521
JunkFilter * es_junkFilter
Definition: execnodes.h:514
#define AllocSetContextCreate
Definition: memutils.h:169
CommandId es_output_cid
Definition: execnodes.h:517
struct JitContext * es_jit
Definition: execnodes.h:601
struct RangeTblEntry ** es_range_table_array
Definition: execnodes.h:505
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:511
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:503
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:571
Snapshot es_snapshot
Definition: execnodes.h:502
List * es_range_table
Definition: execnodes.h:504
ScanDirection es_direction
Definition: execnodes.h:501
bool es_use_parallel_mode
Definition: execnodes.h:586
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:191
int es_jit_flags
Definition: execnodes.h:600
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:572
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
TupleTableSlot ** es_epqTupleSlot
Definition: execnodes.h:583
ResultRelInfo * es_root_result_relations
Definition: execnodes.h:530
bool * es_epqScanDone
Definition: execnodes.h:584
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 247 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().

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

◆ CreateStandaloneExprContext()

ExprContext* CreateStandaloneExprContext ( void  )

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

320 {
321  ExprContext *econtext;
322 
323  /* Create the ExprContext node within the caller's memory context */
324  econtext = makeNode(ExprContext);
325 
326  /* Initialize fields of ExprContext */
327  econtext->ecxt_scantuple = NULL;
328  econtext->ecxt_innertuple = NULL;
329  econtext->ecxt_outertuple = NULL;
330 
332 
333  /*
334  * Create working memory for expression evaluation in this context.
335  */
336  econtext->ecxt_per_tuple_memory =
338  "ExprContext",
340 
341  econtext->ecxt_param_exec_vals = NULL;
342  econtext->ecxt_param_list_info = NULL;
343 
344  econtext->ecxt_aggvalues = NULL;
345  econtext->ecxt_aggnulls = NULL;
346 
347  econtext->caseValue_datum = (Datum) 0;
348  econtext->caseValue_isNull = true;
349 
350  econtext->domainValue_datum = (Datum) 0;
351  econtext->domainValue_isNull = true;
352 
353  econtext->ecxt_estate = NULL;
354 
355  econtext->ecxt_callbacks = NULL;
356 
357  return econtext;
358 }
#define AllocSetContextCreate
Definition: memutils.h:169
Datum * ecxt_aggvalues
Definition: execnodes.h:242
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:231
Datum domainValue_datum
Definition: execnodes.h:254
Datum caseValue_datum
Definition: execnodes.h:248
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:262
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:191
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:225
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:234
struct EState * ecxt_estate
Definition: execnodes.h:259
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
bool domainValue_isNull
Definition: execnodes.h:256
bool * ecxt_aggnulls
Definition: execnodes.h:244
uintptr_t Datum
Definition: postgres.h:367
#define makeNode(_type_)
Definition: nodes.h:572
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:227
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:223
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:230
bool caseValue_isNull
Definition: execnodes.h:250
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:235

◆ do_text_output_multiline()

void do_text_output_multiline ( TupOutputState tstate,
const char *  txt 
)

Definition at line 2279 of file execTuples.c.

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

Referenced by ExplainQuery().

2280 {
2281  Datum values[1];
2282  bool isnull[1] = {false};
2283 
2284  while (*txt)
2285  {
2286  const char *eol;
2287  int len;
2288 
2289  eol = strchr(txt, '\n');
2290  if (eol)
2291  {
2292  len = eol - txt;
2293  eol++;
2294  }
2295  else
2296  {
2297  len = strlen(txt);
2298  eol = txt + len;
2299  }
2300 
2301  values[0] = PointerGetDatum(cstring_to_text_with_len(txt, len));
2302  do_tup_output(tstate, values, isnull);
2303  pfree(DatumGetPointer(values[0]));
2304  txt = eol;
2305  }
2306 }
#define PointerGetDatum(X)
Definition: postgres.h:556
void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
Definition: execTuples.c:2251
void pfree(void *pointer)
Definition: mcxt.c:1031
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 2251 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().

2252 {
2253  TupleTableSlot *slot = tstate->slot;
2254  int natts = slot->tts_tupleDescriptor->natts;
2255 
2256  /* make sure the slot is clear */
2257  ExecClearTuple(slot);
2258 
2259  /* insert data */
2260  memcpy(slot->tts_values, values, natts * sizeof(Datum));
2261  memcpy(slot->tts_isnull, isnull, natts * sizeof(bool));
2262 
2263  /* mark slot as containing a virtual tuple */
2264  ExecStoreVirtualTuple(slot);
2265 
2266  /* send the tuple to the receiver */
2267  (void) tstate->dest->receiveSlot(slot, tstate->dest);
2268 
2269  /* clean up */
2270  ExecClearTuple(slot);
2271 }
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:118
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:426
Datum * tts_values
Definition: tuptable.h:126
TupleTableSlot * slot
Definition: executor.h:457
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:458
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1516

◆ end_tup_output()

void end_tup_output ( TupOutputState tstate)

Definition at line 2309 of file execTuples.c.

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

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

2310 {
2311  tstate->dest->rShutdown(tstate->dest);
2312  /* note that destroying the dest is not ours to do */
2314  pfree(tstate);
2315 }
TupleTableSlot * slot
Definition: executor.h:457
void pfree(void *pointer)
Definition: mcxt.c:1031
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1218
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:124
DestReceiver * dest
Definition: executor.h:458

◆ EvalPlanQual()

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

Definition at line 2446 of file execMain.c.

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

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

2448 {
2449  TupleTableSlot *slot;
2450  TupleTableSlot *testslot;
2451 
2452  Assert(rti > 0);
2453 
2454  /*
2455  * Need to run a recheck subquery. Initialize or reinitialize EPQ state.
2456  */
2457  EvalPlanQualBegin(epqstate, estate);
2458 
2459  /*
2460  * Callers will often use the EvalPlanQualSlot to store the tuple to avoid
2461  * an unnecessary copy.
2462  */
2463  testslot = EvalPlanQualSlot(epqstate, relation, rti);
2464  if (testslot != inputslot)
2465  ExecCopySlot(testslot, inputslot);
2466 
2467  /*
2468  * Fetch any non-locked source rows
2469  */
2470  EvalPlanQualFetchRowMarks(epqstate);
2471 
2472  /*
2473  * Run the EPQ query. We assume it will return at most one tuple.
2474  */
2475  slot = EvalPlanQualNext(epqstate);
2476 
2477  /*
2478  * If we got a tuple, force the slot to materialize the tuple so that it
2479  * is not dependent on any local state in the EPQ query (in particular,
2480  * it's highly likely that the slot contains references to any pass-by-ref
2481  * datums that may be present in copyTuple). As with the next step, this
2482  * is to guard against early re-use of the EPQ query.
2483  */
2484  if (!TupIsNull(slot))
2485  ExecMaterializeSlot(slot);
2486 
2487  /*
2488  * Clear out the test tuple. This is needed in case the EPQ query is
2489  * re-used to test a tuple for a different relation. (Not clear that can
2490  * really happen, but let's be safe.)
2491  */
2492  ExecClearTuple(testslot);
2493 
2494  return slot;
2495 }
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition: tuptable.h:476
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:426
void EvalPlanQualFetchRowMarks(EPQState *epqstate)
Definition: execMain.c:2572
void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate)
Definition: execMain.c:2702
TupleTableSlot * EvalPlanQualNext(EPQState *epqstate)
Definition: execMain.c:2686
TupleTableSlot * EvalPlanQualSlot(EPQState *epqstate, Relation relation, Index rti)
Definition: execMain.c:2538
#define TupIsNull(slot)
Definition: tuptable.h:293
static void ExecMaterializeSlot(TupleTableSlot *slot)
Definition: tuptable.h:444
#define Assert(condition)
Definition: c.h:732

◆ EvalPlanQualBegin()

void EvalPlanQualBegin ( EPQState epqstate,
EState parentestate 
)

Definition at line 2702 of file execMain.c.

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

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

2703 {
2704  EState *estate = epqstate->estate;
2705 
2706  if (estate == NULL)
2707  {
2708  /* First time through, so create a child EState */
2709  EvalPlanQualStart(epqstate, parentestate, 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 *planstate = epqstate->planstate;
2718 
2719  MemSet(estate->es_epqScanDone, 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(planstate->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  estate->es_param_exec_vals[i].value =
2740  parentestate->es_param_exec_vals[i].value;
2741  estate->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  planstate->chgParam = bms_add_member(planstate->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:1241
PlannedStmt * es_plannedstmt
Definition: execnodes.h:511
#define MemSet(start, val, len)
Definition: c.h:941
PlanState * planstate
Definition: execnodes.h:1066
#define GetPerTupleExprContext(estate)
Definition: executor.h:500
ParamExecData * es_param_exec_vals
Definition: execnodes.h:545
bool isnull
Definition: params.h:149
static void EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
Definition: execMain.c:2762
Bitmapset * chgParam
Definition: execnodes.h:977
Plan * plan
Definition: execnodes.h:1068
unsigned int Index
Definition: c.h:475
Plan * plan
Definition: execnodes.h:945
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
bool * es_epqScanDone
Definition: execnodes.h:584
Datum value
Definition: params.h:148
int epqParam
Definition: execnodes.h:1070
EState * estate
Definition: execnodes.h:1065

◆ EvalPlanQualEnd()

void EvalPlanQualEnd ( EPQState epqstate)

Definition at line 2940 of file execMain.c.

References EState::es_query_cxt, EState::es_subplanstates, EState::es_tupleTable, EPQState::estate, ExecCleanUpTriggerState(), ExecEndNode(), ExecResetTupleTable(), FreeExecutorState(), lfirst, MemoryContextSwitchTo(), EPQState::origslot, and EPQState::planstate.

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

2941 {
2942  EState *estate = epqstate->estate;
2943  MemoryContext oldcontext;
2944  ListCell *l;
2945 
2946  if (estate == NULL)
2947  return; /* idle, so nothing to do */
2948 
2949  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
2950 
2951  ExecEndNode(epqstate->planstate);
2952 
2953  foreach(l, estate->es_subplanstates)
2954  {
2955  PlanState *subplanstate = (PlanState *) lfirst(l);
2956 
2957  ExecEndNode(subplanstate);
2958  }
2959 
2960  /* throw away the per-estate tuple table */
2961  ExecResetTupleTable(estate->es_tupleTable, false);
2962 
2963  /* close any trigger target relations attached to this EState */
2964  ExecCleanUpTriggerState(estate);
2965 
2966  MemoryContextSwitchTo(oldcontext);
2967 
2968  FreeExecutorState(estate);
2969 
2970  /* Mark EPQState idle */
2971  epqstate->estate = NULL;
2972  epqstate->planstate = NULL;
2973  epqstate->origslot = NULL;
2974 }
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:538
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlanState * planstate
Definition: execnodes.h:1066
void FreeExecutorState(EState *estate)
Definition: execUtils.c:193
MemoryContext es_query_cxt
Definition: execnodes.h:550
TupleTableSlot * origslot
Definition: execnodes.h:1067
List * es_tupleTable
Definition: execnodes.h:552
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:1155
#define lfirst(lc)
Definition: pg_list.h:190
List * es_subplanstates
Definition: execnodes.h:562
void ExecCleanUpTriggerState(EState *estate)
Definition: execMain.c:1456
EState * estate
Definition: execnodes.h:1065

◆ EvalPlanQualFetchRowMarks()

void EvalPlanQualFetchRowMarks ( EPQState epqstate)

Definition at line 2572 of file execMain.c.

References EPQState::arowMarks, Assert, ExecAuxRowMark::ctidAttNo, DatumGetObjectId, DatumGetPointer, elog, ereport, errcode(), errmsg(), ERROR, EPQState::estate, EvalPlanQualSlot(), ExecClearTuple(), ExecGetJunkAttribute(), ExecStoreHeapTupleDatum(), GetFdwRoutineForRelation(), lfirst, ExecRowMark::markType, OidIsValid, EPQState::origslot, ExecRowMark::prti, RelationData::rd_rel, FdwRoutine::RefetchForeignRow, ExecRowMark::relation, RelationGetRelationName, ExecRowMark::relid, 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 EvalPlanQual(), and ExecLockRows().

2573 {
2574  ListCell *l;
2575 
2576  Assert(epqstate->origslot != NULL);
2577 
2578  foreach(l, epqstate->arowMarks)
2579  {
2580  ExecAuxRowMark *aerm = (ExecAuxRowMark *) lfirst(l);
2581  ExecRowMark *erm = aerm->rowmark;
2582  Datum datum;
2583  bool isNull;
2584  TupleTableSlot *slot;
2585 
2587  elog(ERROR, "EvalPlanQual doesn't support locking rowmarks");
2588 
2589  /* clear any leftover test tuple for this rel */
2590  slot = EvalPlanQualSlot(epqstate, erm->relation, erm->rti);
2591  ExecClearTuple(slot);
2592 
2593  /* if child rel, must check whether it produced this row */
2594  if (erm->rti != erm->prti)
2595  {
2596  Oid tableoid;
2597 
2598  datum = ExecGetJunkAttribute(epqstate->origslot,
2599  aerm->toidAttNo,
2600  &isNull);
2601  /* non-locked rels could be on the inside of outer joins */
2602  if (isNull)
2603  continue;
2604  tableoid = DatumGetObjectId(datum);
2605 
2606  Assert(OidIsValid(erm->relid));
2607  if (tableoid != erm->relid)
2608  {
2609  /* this child is inactive right now */
2610  continue;
2611  }
2612  }
2613 
2614  if (erm->markType == ROW_MARK_REFERENCE)
2615  {
2616  Assert(erm->relation != NULL);
2617 
2618  /* fetch the tuple's ctid */
2619  datum = ExecGetJunkAttribute(epqstate->origslot,
2620  aerm->ctidAttNo,
2621  &isNull);
2622  /* non-locked rels could be on the inside of outer joins */
2623  if (isNull)
2624  continue;
2625 
2626  /* fetch requests on foreign tables must be passed to their FDW */
2627  if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2628  {
2629  FdwRoutine *fdwroutine;
2630  bool updated = false;
2631 
2632  fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
2633  /* this should have been checked already, but let's be safe */
2634  if (fdwroutine->RefetchForeignRow == NULL)
2635  ereport(ERROR,
2636  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2637  errmsg("cannot lock rows in foreign table \"%s\"",
2639 
2640  fdwroutine->RefetchForeignRow(epqstate->estate,
2641  erm,
2642  datum,
2643  slot,
2644  &updated);
2645  if (TupIsNull(slot))
2646  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2647 
2648  /*
2649  * Ideally we'd insist on updated == false here, but that
2650  * assumes that FDWs can track that exactly, which they might
2651  * not be able to. So just ignore the flag.
2652  */
2653  }
2654  else
2655  {
2656  /* ordinary table, fetch the tuple */
2658  (ItemPointer) DatumGetPointer(datum),
2659  SnapshotAny, slot))
2660  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2661  }
2662  }
2663  else
2664  {
2665  Assert(erm->markType == ROW_MARK_COPY);
2666 
2667  /* fetch the whole-row Var for the relation */
2668  datum = ExecGetJunkAttribute(epqstate->origslot,
2669  aerm->wholeAttNo,
2670  &isNull);
2671  /* non-locked rels could be on the inside of outer joins */
2672  if (isNull)
2673  continue;
2674 
2675  ExecStoreHeapTupleDatum(datum, slot);
2676  }
2677  }
2678 }
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:426
Relation relation
Definition: execnodes.h:627
#define DatumGetObjectId(X)
Definition: postgres.h:500
int errcode(int sqlerrcode)
Definition: elog.c:570
Form_pg_class rd_rel
Definition: rel.h:84
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:999
ExecRowMark * rowmark
Definition: execnodes.h:654
#define ERROR
Definition: elog.h:43
TupleTableSlot * EvalPlanQualSlot(EPQState *epqstate, Relation relation, Index rti)
Definition: execMain.c:2538
List * arowMarks
Definition: execnodes.h:1069
Index rti
Definition: execnodes.h:629
AttrNumber wholeAttNo
Definition: execnodes.h:657
Index prti
Definition: execnodes.h:630
#define RelationGetRelationName(relation)
Definition: rel.h:448
#define TupIsNull(slot)
Definition: tuptable.h:293
TupleTableSlot * origslot
Definition: execnodes.h:1067
#define ereport(elevel, rest)
Definition: elog.h:141
void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot)
Definition: execTuples.c:1570
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:732
#define lfirst(lc)
Definition: pg_list.h:190
RowMarkType markType
Definition: execnodes.h:632
AttrNumber toidAttNo
Definition: execnodes.h:656
#define SnapshotAny
Definition: snapmgr.h:70
#define DatumGetPointer(X)
Definition: postgres.h:549
int errmsg(const char *fmt,...)
Definition: elog.c:784
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:226
EState * estate
Definition: execnodes.h:1065
AttrNumber ctidAttNo
Definition: execnodes.h:655
RefetchForeignRow_function RefetchForeignRow
Definition: fdwapi.h:225

◆ EvalPlanQualInit()

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

Definition at line 2505 of file execMain.c.

References EPQState::arowMarks, EPQState::epqParam, EPQState::estate, EPQState::origslot, EPQState::plan, and EPQState::planstate.

Referenced by apply_handle_delete(), apply_handle_update(), ExecInitLockRows(), and ExecInitModifyTable().

2507 {
2508  /* Mark the EPQ state inactive */
2509  epqstate->estate = NULL;
2510  epqstate->planstate = NULL;
2511  epqstate->origslot = NULL;
2512  /* ... and remember data that EvalPlanQualBegin will need */
2513  epqstate->plan = subplan;
2514  epqstate->arowMarks = auxrowmarks;
2515  epqstate->epqParam = epqParam;
2516 }
PlanState * planstate
Definition: execnodes.h:1066
List * arowMarks
Definition: execnodes.h:1069
TupleTableSlot * origslot
Definition: execnodes.h:1067
Plan * plan
Definition: execnodes.h:1068
int epqParam
Definition: execnodes.h:1070
EState * estate
Definition: execnodes.h:1065

◆ EvalPlanQualNext()

TupleTableSlot* EvalPlanQualNext ( EPQState epqstate)

Definition at line 2686 of file execMain.c.

References EState::es_query_cxt, EPQState::estate, ExecProcNode(), MemoryContextSwitchTo(), and EPQState::planstate.

Referenced by EvalPlanQual(), and ExecLockRows().

2687 {
2688  MemoryContext oldcontext;
2689  TupleTableSlot *slot;
2690 
2691  oldcontext = MemoryContextSwitchTo(epqstate->estate->es_query_cxt);
2692  slot = ExecProcNode(epqstate->planstate);
2693  MemoryContextSwitchTo(oldcontext);
2694 
2695  return slot;
2696 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlanState * planstate
Definition: execnodes.h:1066
MemoryContext es_query_cxt
Definition: execnodes.h:550
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition: executor.h:234
EState * estate
Definition: execnodes.h:1065

◆ EvalPlanQualSetPlan()

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

Definition at line 2524 of file execMain.c.

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

Referenced by ExecInitModifyTable(), and ExecModifyTable().

2525 {
2526  /* If we have a live EPQ query, shut it down */
2527  EvalPlanQualEnd(epqstate);
2528  /* And set/change the plan pointer */
2529  epqstate->plan = subplan;
2530  /* The rowmarks depend on the plan, too */
2531  epqstate->arowMarks = auxrowmarks;
2532 }
void EvalPlanQualEnd(EPQState *epqstate)
Definition: execMain.c:2940
List * arowMarks
Definition: execnodes.h:1069
Plan * plan
Definition: execnodes.h:1068

◆ EvalPlanQualSlot()

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

Definition at line 2538 of file execMain.c.

References Assert, EState::es_epqTupleSlot, EState::es_query_cxt, EState::es_tupleTable, EPQState::estate, ExecAllocTableSlot(), MemoryContextSwitchTo(), EPQState::origslot, table_slot_create(), TupleTableSlot::tts_tupleDescriptor, and TTSOpsVirtual.

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

2540 {
2541  TupleTableSlot **slot;
2542 
2543  Assert(rti > 0 && rti <= epqstate->estate->es_range_table_size);
2544  slot = &epqstate->estate->es_epqTupleSlot[rti - 1];
2545 
2546  if (*slot == NULL)
2547  {
2548  MemoryContext oldcontext;
2549 
2550  oldcontext = MemoryContextSwitchTo(epqstate->estate->es_query_cxt);
2551 
2552  if (relation)
2553  *slot = table_slot_create(relation,
2554  &epqstate->estate->es_tupleTable);
2555  else
2556  *slot = ExecAllocTableSlot(&epqstate->estate->es_tupleTable,
2557  epqstate->origslot->tts_tupleDescriptor,
2558  &TTSOpsVirtual);
2559 
2560  MemoryContextSwitchTo(oldcontext);
2561  }
2562 
2563  return *slot;
2564 }
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
Definition: tableam.c:77
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:550
TupleTableSlot * origslot
Definition: execnodes.h:1067
TupleTableSlot * ExecAllocTableSlot(List **tupleTable, TupleDesc desc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1135
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:124
List * es_tupleTable
Definition: execnodes.h:552
#define Assert(condition)
Definition: c.h:732
TupleTableSlot ** es_epqTupleSlot
Definition: execnodes.h:583
EState * estate
Definition: execnodes.h:1065

◆ exec_rt_fetch()

◆ ExecAssignExprContext()

◆ ExecAssignProjectionInfo()

void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

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

504 {
505  planstate->ps_ProjInfo =
507  planstate->ps_ExprContext,
508  planstate->ps_ResultTupleSlot,
509  planstate,
510  inputDesc);
511 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:985
ExprContext * ps_ExprContext
Definition: execnodes.h:984
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:983
Plan * plan
Definition: execnodes.h:945
List * targetlist
Definition: plannodes.h:140
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:350

◆ ExecAssignScanProjectionInfo()

void ExecAssignScanProjectionInfo ( ScanState node)

◆ ExecAssignScanProjectionInfoWithVarno()

void ExecAssignScanProjectionInfoWithVarno ( ScanState node,
Index  varno 
)

Definition at line 246 of file execScan.c.

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

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

247 {
249 
250  ExecConditionalAssignProjectionInfo(&node->ps, tupdesc, varno);
251 }
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1283
void ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, Index varno)
Definition: execUtils.c:522
PlanState ps
Definition: execnodes.h:1280
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:124

◆ ExecAssignScanType()

void ExecAssignScanType ( ScanState scanstate,
TupleDesc  tupDesc 
)

Definition at line 637 of file execUtils.c.

References ExecSetSlotDescriptor(), and ScanState::ss_ScanTupleSlot.

Referenced by ExecWorkTableScan().

638 {
639  TupleTableSlot *slot = scanstate->ss_ScanTupleSlot;
640 
641  ExecSetSlotDescriptor(slot, tupDesc);
642 }
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1283
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:1253

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

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

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

3322 {
3324  ExprEvalStep scratch = {0};
3325  int natt;
3326  int maxatt = -1;
3327  List *adjust_jumps = NIL;
3328  ListCell *lc;
3329 
3330  /*
3331  * When no columns are actually compared, the result's always true. See
3332  * special case in ExecQual().
3333  */
3334  if (numCols == 0)
3335  return NULL;
3336 
3337  state->expr = NULL;
3338  state->flags = EEO_FLAG_IS_QUAL;
3339  state->parent = parent;
3340 
3341  scratch.resvalue = &state->resvalue;
3342  scratch.resnull = &state->resnull;
3343 
3344  /* compute max needed attribute */
3345  for (natt = 0; natt < numCols; natt++)
3346  {
3347  int attno = keyColIdx[natt];
3348 
3349  if (attno > maxatt)
3350  maxatt = attno;
3351  }
3352  Assert(maxatt >= 0);
3353 
3354  /* push deform steps */
3355  scratch.opcode = EEOP_INNER_FETCHSOME;
3356  scratch.d.fetch.last_var = maxatt;
3357  scratch.d.fetch.fixed = false;
3358  scratch.d.fetch.known_desc = ldesc;
3359  scratch.d.fetch.kind = lops;
3360  ExecComputeSlotInfo(state, &scratch);
3361  ExprEvalPushStep(state, &scratch);
3362 
3363  scratch.opcode = EEOP_OUTER_FETCHSOME;
3364  scratch.d.fetch.last_var = maxatt;
3365  scratch.d.fetch.fixed = false;
3366  scratch.d.fetch.known_desc = rdesc;
3367  scratch.d.fetch.kind = rops;
3368  ExecComputeSlotInfo(state, &scratch);
3369  ExprEvalPushStep(state, &scratch);
3370 
3371  /*
3372  * Start comparing at the last field (least significant sort key). That's
3373  * the most likely to be different if we are dealing with sorted input.
3374  */
3375  for (natt = numCols; --natt >= 0;)
3376  {
3377  int attno = keyColIdx[natt];
3378  Form_pg_attribute latt = TupleDescAttr(ldesc, attno - 1);
3379  Form_pg_attribute ratt = TupleDescAttr(rdesc, attno - 1);
3380  Oid foid = eqfunctions[natt];
3381  Oid collid = collations[natt];
3382  FmgrInfo *finfo;
3383  FunctionCallInfo fcinfo;
3384  AclResult aclresult;
3385 
3386  /* Check permission to call function */
3387  aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
3388  if (aclresult != ACLCHECK_OK)
3389  aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid));
3390 
3392 
3393  /* Set up the primary fmgr lookup information */
3394  finfo = palloc0(sizeof(FmgrInfo));
3395  fcinfo = palloc0(SizeForFunctionCallInfo(2));
3396  fmgr_info(foid, finfo);
3397  fmgr_info_set_expr(NULL, finfo);
3398  InitFunctionCallInfoData(*fcinfo, finfo, 2,
3399  collid, NULL, NULL);
3400 
3401  /* left arg */
3402  scratch.opcode = EEOP_INNER_VAR;
3403  scratch.d.var.attnum = attno - 1;
3404  scratch.d.var.vartype = latt->atttypid;
3405  scratch.resvalue = &fcinfo->args[0].value;
3406  scratch.resnull = &fcinfo->args[0].isnull;
3407  ExprEvalPushStep(state, &scratch);
3408 
3409  /* right arg */
3410  scratch.opcode = EEOP_OUTER_VAR;
3411  scratch.d.var.attnum = attno - 1;
3412  scratch.d.var.vartype = ratt->atttypid;
3413  scratch.resvalue = &fcinfo->args[1].value;
3414  scratch.resnull = &fcinfo->args[1].isnull;
3415  ExprEvalPushStep(state, &scratch);
3416 
3417  /* evaluate distinctness */
3418  scratch.opcode = EEOP_NOT_DISTINCT;
3419  scratch.d.func.finfo = finfo;
3420  scratch.d.func.fcinfo_data = fcinfo;
3421  scratch.d.func.fn_addr = finfo->fn_addr;
3422  scratch.d.func.nargs = 2;
3423  scratch.resvalue = &state->resvalue;
3424  scratch.resnull = &state->resnull;
3425  ExprEvalPushStep(state, &scratch);
3426 
3427  /* then emit EEOP_QUAL to detect if result is false (or null) */
3428  scratch.opcode = EEOP_QUAL;
3429  scratch.d.qualexpr.jumpdone = -1;
3430  scratch.resvalue = &state->resvalue;
3431  scratch.resnull = &state->resnull;
3432  ExprEvalPushStep(state, &scratch);
3433  adjust_jumps = lappend_int(adjust_jumps,
3434  state->steps_len - 1);
3435  }
3436 
3437  /* adjust jump targets */
3438  foreach(lc, adjust_jumps)
3439  {
3440  ExprEvalStep *as = &state->steps[lfirst_int(lc)];
3441 
3442  Assert(as->opcode == EEOP_QUAL);
3443  Assert(as->d.qualexpr.jumpdone == -1);
3444  as->d.qualexpr.jumpdone = state->steps_len;
3445  }
3446 
3447  scratch.resvalue = NULL;
3448  scratch.resnull = NULL;
3449  scratch.opcode = EEOP_DONE;
3450  ExprEvalPushStep(state, &scratch);
3451 
3452  ExecReadyExpr(state);
3453 
3454  return state;
3455 }
#define NIL
Definition: pg_list.h:65
Definition: fmgr.h:56
struct PlanState * parent
Definition: execnodes.h:107
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:85
#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
static void ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op)
Definition: execExpr.c:2368
struct ExprEvalStep::@52::@61 qualexpr
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
struct ExprEvalStep::@52::@53 fetch
bool resnull
Definition: execnodes.h:72
Expr * expr
Definition: execnodes.h:94
#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:59
#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:339
#define InvokeFunctionExecuteHook(objectId)
Definition: objectaccess.h:179
void * palloc0(Size size)
Definition: mcxt.c:955
AclResult
Definition: acl.h:178
void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2123
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:626
struct ExprEvalStep::@52::@59 func
#define makeNode(_type_)
Definition: nodes.h:572
#define Assert(condition)
Definition: c.h:732
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:104
#define ACL_EXECUTE
Definition: parsenodes.h:81
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4655
uint8 flags
Definition: execnodes.h:65
Definition: pg_list.h:50
Datum resvalue
Definition: execnodes.h:74

◆ ExecBuildProjectionInfo()

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

Definition at line 350 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, Node::type, Var::varattno, Var::varno, and Var::vartype.

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

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

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

◆ 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:2422
int ri_NumIndices
Definition: execnodes.h:413
#define NIL
Definition: pg_list.h:65
Relation ri_RelationDesc
Definition: execnodes.h:410
List * ii_Predicate
Definition: execnodes.h:161
ExprState * ii_PredicateState
Definition: execnodes.h:162
int errcode(int sqlerrcode)
Definition: elog.c:570
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:364
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:500
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5243
Form_pg_index rd_index
Definition: rel.h:144
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:448
ExprState * ExecPrepareQual(List *qual, EState *estate)
Definition: execExpr.c:517
bool ii_ReadyForInserts
Definition: execnodes.h:170
#define ereport(elevel, rest)
Definition: elog.h:141
uintptr_t Datum
Definition: postgres.h:367
bool ii_Unique
Definition: execnodes.h:169
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:683
#define INDEX_MAX_KEYS
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:223
static Datum values[MAXATTR]
Definition: bootstrap.c:167
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
Oid * ii_ExclusionOps
Definition: execnodes.h:163
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
IndexInfo ** ri_IndexRelationInfo
Definition: execnodes.h:419
int i
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:416
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:522

◆ ExecCheckRTPerms()

bool ExecCheckRTPerms ( List rangeTable,
bool  ereport_on_violation 
)

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

573 {
574  ListCell *l;
575  bool result = true;
576 
577  foreach(l, rangeTable)
578  {
579  RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
580 
581  result = ExecCheckRTEPerms(rte);
582  if (!result)
583  {
584  Assert(rte->rtekind == RTE_RELATION);
585  if (ereport_on_violation)
587  get_rel_name(rte->relid));
588  return false;
589  }
590  }
591 
593  result = (*ExecutorCheckPerms_hook) (rangeTable,
594  ereport_on_violation);
595  return result;
596 }
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1805
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
static bool ExecCheckRTEPerms(RangeTblEntry *rte)
Definition: execMain.c:603
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
Definition: execMain.c:76
#define Assert(condition)
Definition: c.h:732
#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 1100 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

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

1101 {
1102  int len = 0;
1103  ListCell *tl;
1104 
1105  foreach(tl, targetlist)
1106  {
1107  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1108 
1109  if (!curTle->resjunk)
1110  len++;
1111  }
1112  return len;
1113 }
bool resjunk
Definition: primnodes.h:1400
#define lfirst_node(type, lc)
Definition: pg_list.h:193

◆ ExecCleanTypeFromTL()

TupleDesc ExecCleanTypeFromTL ( List targetList)

Definition at line 1915 of file execTuples.c.

References ExecTypeFromTLInternal().

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

1916 {
1917  return ExecTypeFromTLInternal(targetList, true);
1918 }
static TupleDesc ExecTypeFromTLInternal(List *targetList, bool skipjunk)
Definition: execTuples.c:1921

◆ ExecCleanUpTriggerState()

void ExecCleanUpTriggerState ( EState estate)

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

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

◆ ExecConditionalAssignProjectionInfo()

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

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

524 {
525  if (tlist_matches_tupdesc(planstate,
526  planstate->plan->targetlist,
527  varno,
528  inputDesc))
529  {
530  planstate->ps_ProjInfo = NULL;
531  planstate->resultopsset = planstate->scanopsset;
532  planstate->resultopsfixed = planstate->scanopsfixed;
533  planstate->resultops = planstate->scanops;
534  }
535  else
536  {
537  if (!planstate->ps_ResultTupleSlot)
538  {
539  ExecInitResultSlot(planstate, &TTSOpsVirtual);
540  planstate->resultops = &TTSOpsVirtual;
541  planstate->resultopsfixed = true;
542  planstate->resultopsset = true;
543  }
544  ExecAssignProjectionInfo(planstate, inputDesc);
545  }
546 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:985
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
const TupleTableSlotOps * resultops
Definition: execnodes.h:1020
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:983
const TupleTableSlotOps * scanops
Definition: execnodes.h:1017
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:502
bool resultopsset
Definition: execnodes.h:1028
Plan * plan
Definition: execnodes.h:945
bool scanopsfixed
Definition: execnodes.h:1021
void ExecInitResultSlot(PlanState *planstate, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1743
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
Definition: execUtils.c:549
bool scanopsset
Definition: execnodes.h:1025
List * targetlist
Definition: plannodes.h:140
bool resultopsfixed
Definition: execnodes.h:1024

◆ ExecConstraints()

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

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

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

◆ ExecCreateScanSlotFromOuterPlan()

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

Definition at line 649 of file execUtils.c.

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

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

652 {
654  TupleDesc tupDesc;
655 
656  outerPlan = outerPlanState(scanstate);
657  tupDesc = ExecGetResultType(outerPlan);
658 
659  ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops);
660 }
#define outerPlanState(node)
Definition: execnodes.h:1039
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1775
#define outerPlan(node)
Definition: plannodes.h:170
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:457

◆ 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:575
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:570
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1283
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:999
ItemPointerData * ItemPointer
Definition: itemptr.h:49
ItemPointerData curCtid
Definition: execnodes.h:636
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:293
#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:475
#define Assert(condition)
Definition: c.h:732
RowMarkType markType
Definition: execnodes.h:632
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:784
#define elog(elevel,...)
Definition: elog.h:226
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:403
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730

◆ ExecEndNode()

void ExecEndNode ( PlanState node)

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

539 {
540  /*
541  * do nothing when we get to the end of a leaf on tree.
542  */
543  if (node == NULL)
544  return;
545 
546  /*
547  * Make sure there's enough stack available. Need to check here, in
548  * addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not
549  * guaranteed that ExecProcNode() is reached for all nodes.
550  */
552 
553  if (node->chgParam != NULL)
554  {
555  bms_free(node->chgParam);
556  node->chgParam = NULL;
557  }
558 
559  switch (nodeTag(node))
560  {
561  /*
562  * control nodes
563  */
564  case T_ResultState:
565  ExecEndResult((ResultState *) node);
566  break;
567 
568  case T_ProjectSetState:
570  break;
571 
572  case T_ModifyTableState:
574  break;
575 
576  case T_AppendState:
577  ExecEndAppend((AppendState *) node);
578  break;
579 
580  case T_MergeAppendState:
582  break;
583 
586  break;
587 
588  case T_BitmapAndState:
590  break;
591 
592  case T_BitmapOrState:
593  ExecEndBitmapOr((BitmapOrState *) node);
594  break;
595 
596  /*
597  * scan nodes
598  */
599  case T_SeqScanState:
600  ExecEndSeqScan((SeqScanState *) node);
601  break;
602 
603  case T_SampleScanState:
605  break;
606 
607  case T_GatherState:
608  ExecEndGather((GatherState *) node);
609  break;
610 
611  case T_GatherMergeState:
613  break;
614 
615  case T_IndexScanState:
617  break;
618 
621  break;
622 
625  break;
626 
629  break;
630 
631  case T_TidScanState:
632  ExecEndTidScan((TidScanState *) node);
633  break;
634 
635  case T_SubqueryScanState:
637  break;
638 
639  case T_FunctionScanState:
641  break;
642 
645  break;
646 
647  case T_ValuesScanState:
649  break;
650 
651  case T_CteScanState:
652  ExecEndCteScan((CteScanState *) node);
653  break;
654 
657  break;
658 
661  break;
662 
663  case T_ForeignScanState:
665  break;
666 
667  case T_CustomScanState:
669  break;
670 
671  /*
672  * join nodes
673  */
674  case T_NestLoopState:
675  ExecEndNestLoop((NestLoopState *) node);
676  break;
677 
678  case T_MergeJoinState:
680  break;
681 
682  case T_HashJoinState:
683  ExecEndHashJoin((HashJoinState *) node);
684  break;
685 
686  /*
687  * materialization nodes
688  */
689  case T_MaterialState:
690  ExecEndMaterial((MaterialState *) node);
691  break;
692 
693  case T_SortState:
694  ExecEndSort((SortState *) node);
695  break;
696 
697  case T_GroupState:
698  ExecEndGroup((GroupState *) node);
699  break;
700 
701  case T_AggState:
702  ExecEndAgg((AggState *) node);
703  break;
704 
705  case T_WindowAggState:
707  break;
708 
709  case T_UniqueState:
710  ExecEndUnique((UniqueState *) node);
711  break;
712 
713  case T_HashState:
714  ExecEndHash((HashState *) node);
715  break;
716 
717  case T_SetOpState:
718  ExecEndSetOp((SetOpState *) node);
719  break;
720 
721  case T_LockRowsState:
722  ExecEndLockRows((LockRowsState *) node);
723  break;
724 
725  case T_LimitState:
726  ExecEndLimit((LimitState *) node);
727  break;
728 
729  default:
730  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
731  break;
732  }
733 }
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:386
void ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecEndBitmapAnd(BitmapAndState *node)
void ExecEndRecursiveUnion(RecursiveUnionState *node)
void ExecEndSubqueryScan(SubqueryScanState *node)
void ExecEndHashJoin(HashJoinState *node)
Definition: nodeHashjoin.c:778
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:319
void ExecEndForeignScan(ForeignScanState *node)
void ExecEndSort(SortState *node)
Definition: nodeSort.c:234
void ExecEndBitmapIndexScan(BitmapIndexScanState *node)
void check_stack_depth(void)
Definition: postgres.c:3275
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:476
Bitmapset * chgParam
Definition: execnodes.h:977
void ExecEndCteScan(CteScanState *node)
Definition: nodeCtescan.c:288
void ExecEndCustomScan(CustomScanState *node)
Definition: nodeCustom.c:120
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:529
#define elog(elevel,...)
Definition: elog.h:226
void ExecEndHash(HashState *node)
Definition: nodeHash.c:404
void ExecEndProjectSet(ProjectSetState *node)
void ExecEndMaterial(MaterialState *node)
Definition: nodeMaterial.c:240
void ExecEndBitmapHeapScan(BitmapHeapScanState *node)
void ExecEndAgg(AggState *node)
Definition: nodeAgg.c:3357
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 299 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().

302 {
303  Datum retDatum;
304  MemoryContext oldContext;
305 
306  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
307  retDatum = state->evalfunc(state, econtext, isNull);
308  MemoryContextSwitchTo(oldContext);
309  return retDatum;
310 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:231
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ExprStateEvalFunc evalfunc
Definition: execnodes.h:91
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:368
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:426
TupleTableSlot * jf_resultSlot
Definition: execnodes.h:369
Datum * tts_values
Definition: tuptable.h:126
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:355
bool * tts_isnull
Definition: tuptable.h:128
TupleDesc jf_cleanTupType
Definition: execnodes.h:367
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:1516

◆ 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:366

◆ 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 2352 of file execMain.c.

References elog, ERROR, and EState::es_rowmarks.

Referenced by ExecInitLockRows(), and ExecInitModifyTable().

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

◆ 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 EvalPlanQualFetchRowMarks(), 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:382
#define Assert(condition)
Definition: c.h:732

◆ ExecGetRangeTableRelation()

Relation ExecGetRangeTableRelation ( EState estate,
Index  rti 
)

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

770 {
771  Relation rel;
772 
773  Assert(rti > 0 && rti <= estate->es_range_table_size);
774 
775  rel = estate->es_relations[rti - 1];
776  if (rel == NULL)
777  {
778  /* First time through, so open the relation */
779  RangeTblEntry *rte = exec_rt_fetch(rti, estate);
780 
781  Assert(rte->rtekind == RTE_RELATION);
782 
783  if (!IsParallelWorker())
784  {
785  /*
786  * In a normal query, we should already have the appropriate lock,
787  * but verify that through an Assert. Since there's already an
788  * Assert inside table_open that insists on holding some lock, it
789  * seems sufficient to check this only when rellockmode is higher
790  * than the minimum.
791  */
792  rel = table_open(rte->relid, NoLock);
794  CheckRelationLockedByMe(rel, rte->rellockmode, false));
795  }
796  else
797  {
798  /*
799  * If we are a parallel worker, we need to obtain our own local
800  * lock on the relation. This ensures sane behavior in case the
801  * parent process exits before we do.
802  */
803  rel = table_open(rte->relid, rte->rellockmode);
804  }
805 
806  estate->es_relations[rti - 1] = rel;
807  }
808 
809  return rel;
810 }
#define AccessShareLock
Definition: lockdefs.h:36
#define NoLock
Definition: lockdefs.h:34
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
Definition: executor.h:536
#define IsParallelWorker()
Definition: parallel.h:60
#define Assert(condition)
Definition: c.h:732
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 466 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().

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

◆ ExecGetResultType()

◆ ExecGetReturningSlot()

TupleTableSlot* ExecGetReturningSlot ( EState estate,
ResultRelInfo relInfo 
)

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

1164 {
1165  if (relInfo->ri_ReturningSlot == NULL)
1166  {
1167  Relation rel = relInfo->ri_RelationDesc;
1168  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1169 
1170  relInfo->ri_ReturningSlot =
1171  ExecInitExtraTupleSlot(estate,
1172  RelationGetDescr(rel),
1173  table_slot_callbacks(rel));
1174 
1175  MemoryContextSwitchTo(oldcontext);
1176  }
1177 
1178  return relInfo->ri_ReturningSlot;
1179 }
Relation ri_RelationDesc
Definition: execnodes.h:410
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1795
#define RelationGetDescr(relation)
Definition: rel.h:440
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:434

◆ ExecGetTriggerNewSlot()

TupleTableSlot* ExecGetTriggerNewSlot ( EState estate,
ResultRelInfo relInfo 
)

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

1142 {
1143  if (relInfo->ri_TrigNewSlot == NULL)
1144  {
1145  Relation rel = relInfo->ri_RelationDesc;
1146  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1147 
1148  relInfo->ri_TrigNewSlot =
1149  ExecInitExtraTupleSlot(estate,
1150  RelationGetDescr(rel),
1151  table_slot_callbacks(rel));
1152 
1153  MemoryContextSwitchTo(oldcontext);
1154  }
1155 
1156  return relInfo->ri_TrigNewSlot;
1157 }
Relation ri_RelationDesc
Definition: execnodes.h:410
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1795
#define RelationGetDescr(relation)
Definition: rel.h:440
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:436
MemoryContext es_query_cxt
Definition: execnodes.h:550

◆ ExecGetTriggerOldSlot()

TupleTableSlot* ExecGetTriggerOldSlot ( EState estate,
ResultRelInfo relInfo 
)

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

1120 {
1121  if (relInfo->ri_TrigOldSlot == NULL)
1122  {
1123  Relation rel = relInfo->ri_RelationDesc;
1124  MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1125 
1126  relInfo->ri_TrigOldSlot =
1127  ExecInitExtraTupleSlot(estate,
1128  RelationGetDescr(rel),
1129  table_slot_callbacks(rel));
1130 
1131  MemoryContextSwitchTo(oldcontext);
1132  }
1133 
1134  return relInfo->ri_TrigOldSlot;
1135 }
Relation ri_RelationDesc
Definition: execnodes.h:410
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1795
#define RelationGetDescr(relation)
Definition: rel.h:440
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:435

◆ ExecGetTriggerResultRel()

ResultRelInfo* ExecGetTriggerResultRel ( EState estate,
Oid  relid 
)

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

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

◆ ExecInitCheck()

ExprState* ExecInitCheck ( List qual,
PlanState parent 
)

Definition at line 295 of file execExpr.c.

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

Referenced by ExecPrepareCheck(), and ExecProcNode().

296 {
297  /* short-circuit (here and in ExecCheck) for empty restriction list */
298  if (qual == NIL)
299  return NULL;
300 
301  Assert(IsA(qual, List));
302 
303  /*
304  * Just convert the implicit-AND list to an explicit AND (if there's more
305  * than one entry), and compile normally. Unlike ExecQual, we can't
306  * short-circuit on NULL results, so the regular AND behavior is needed.
307  */
308  return ExecInitExpr(make_ands_explicit(qual), parent);
309 }
#define NIL
Definition: pg_list.h:65
#define IsA(nodeptr, _type_)
Definition: nodes.h:575
Expr * make_ands_explicit(List *andclauses)
Definition: makefuncs.c:706
#define Assert(condition)
Definition: c.h:732