PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
executor.h File Reference
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_OIDS   0x0020 /* force OIDs in returned tuples */
 
#define EXEC_FLAG_WITHOUT_OIDS   0x0040 /* force no OIDs in returned tuples */
 
#define EXEC_FLAG_WITH_NO_DATA   0x0080 /* 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)
 
bool execTuplesMatch (TupleTableSlot *slot1, TupleTableSlot *slot2, int numCols, AttrNumber *matchColIdx, FmgrInfo *eqfunctions, MemoryContext evalContext)
 
bool execTuplesUnequal (TupleTableSlot *slot1, TupleTableSlot *slot2, int numCols, AttrNumber *matchColIdx, FmgrInfo *eqfunctions, MemoryContext evalContext)
 
FmgrInfoexecTuplesMatchPrepare (int numCols, Oid *eqOperators)
 
void execTuplesHashPrepare (int numCols, Oid *eqOperators, FmgrInfo **eqFunctions, FmgrInfo **hashFunctions)
 
TupleHashTable BuildTupleHashTable (int numCols, AttrNumber *keyColIdx, FmgrInfo *eqfunctions, FmgrInfo *hashfunctions, long nbuckets, Size additionalsize, MemoryContext tablecxt, MemoryContext tempcxt, bool use_variable_hash_iv)
 
TupleHashEntry LookupTupleHashEntry (TupleHashTable hashtable, TupleTableSlot *slot, bool *isnew)
 
TupleHashEntry FindTupleHashEntry (TupleHashTable hashtable, TupleTableSlot *slot, FmgrInfo *eqfunctions, FmgrInfo *hashfunctions)
 
JunkFilterExecInitJunkFilter (List *targetList, bool hasoid, 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)
 
bool ExecContextForcesOids (PlanState *planstate, bool *hasoids)
 
void ExecConstraints (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, int lockmode, ItemPointer tid, TransactionId priorXmax)
 
HeapTuple EvalPlanQualFetch (EState *estate, Relation relation, int lockmode, LockWaitPolicy wait_policy, ItemPointer tid, TransactionId priorXmax)
 
void EvalPlanQualInit (EPQState *epqstate, EState *estate, Plan *subplan, List *auxrowmarks, int epqParam)
 
void EvalPlanQualSetPlan (EPQState *epqstate, Plan *subplan, List *auxrowmarks)
 
void EvalPlanQualSetTuple (EPQState *epqstate, Index rti, HeapTuple tuple)
 
HeapTuple EvalPlanQualGetTuple (EPQState *epqstate, Index rti)
 
void ExecSetupPartitionTupleRouting (Relation rel, Index resultRTindex, EState *estate, PartitionDispatch **pd, ResultRelInfo **partitions, TupleConversionMap ***tup_conv_maps, TupleTableSlot **partition_tuple_slot, int *num_parted, int *num_partitions)
 
int ExecFindPartition (ResultRelInfo *resultRelInfo, PartitionDispatch *pd, TupleTableSlot *slot, EState *estate)
 
void EvalPlanQualFetchRowMarks (EPQState *epqstate)
 
TupleTableSlotEvalPlanQualNext (EPQState *epqstate)
 
void EvalPlanQualBegin (EPQState *epqstate, EState *parentestate)
 
void EvalPlanQualEnd (EPQState *epqstate)
 
PlanStateExecInitNode (Plan *node, EState *estate, int eflags)
 
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)
 
ExprStateExecInitQual (List *qual, PlanState *parent)
 
ExprStateExecInitCheck (List *qual, PlanState *parent)
 
ListExecInitExprList (List *nodes, 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)
 
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, 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 ExecInitResultTupleSlot (EState *estate, PlanState *planstate)
 
void ExecInitScanTupleSlot (EState *estate, ScanState *scanstate)
 
TupleTableSlotExecInitExtraTupleSlot (EState *estate)
 
TupleTableSlotExecInitNullTupleSlot (EState *estate, TupleDesc tupType)
 
TupleDesc ExecTypeFromTL (List *targetList, bool hasoid)
 
TupleDesc ExecCleanTypeFromTL (List *targetList, bool hasoid)
 
TupleDesc ExecTypeFromExprList (List *exprList)
 
void ExecTypeSetColNames (TupleDesc typeInfo, List *namesList)
 
void UpdateChangedParamSet (PlanState *node, Bitmapset *newchg)
 
TupOutputStatebegin_tup_output_tupdesc (DestReceiver *dest, TupleDesc tupdesc)
 
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)
 
void ExecAssignResultType (PlanState *planstate, TupleDesc tupDesc)
 
void ExecAssignResultTypeFromTL (PlanState *planstate)
 
TupleDesc ExecGetResultType (PlanState *planstate)
 
void ExecAssignProjectionInfo (PlanState *planstate, TupleDesc inputDesc)
 
void ExecFreeExprContext (PlanState *planstate)
 
void ExecAssignScanType (ScanState *scanstate, TupleDesc tupDesc)
 
void ExecAssignScanTypeFromOuterPlan (ScanState *scanstate)
 
bool ExecRelationIsTargetRelation (EState *estate, Index scanrelid)
 
Relation ExecOpenScanRelation (EState *estate, Index scanrelid, int eflags)
 
void ExecCloseScanRelation (Relation scanrel)
 
int executor_errposition (EState *estate, int location)
 
void RegisterExprContextCallback (ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
 
void UnregisterExprContextCallback (ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
 
void ExecLockNonLeafAppendTables (List *partitioned_rels, EState *estate)
 
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)
 
void ExecOpenIndices (ResultRelInfo *resultRelInfo, bool speculative)
 
void ExecCloseIndices (ResultRelInfo *resultRelInfo)
 
ListExecInsertIndexTuples (TupleTableSlot *slot, ItemPointer tupleid, 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

#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:562
char bool
Definition: c.h:202
void pfree(void *pointer)
Definition: mcxt.c:949
uintptr_t Datum
Definition: postgres.h:372
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define DatumGetPointer(X)
Definition: postgres.h:555
void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
Definition: execTuples.c:1253

Definition at line 449 of file executor.h.

Referenced by ExplainQuery(), and ShowGUCConfigOption().

#define EvalPlanQualSetSlot (   epqstate,
  slot 
)    ((epqstate)->origslot = (slot))
#define EXEC_FLAG_SKIP_TRIGGERS   0x0010 /* skip AfterTrigger calls */
#define EXEC_FLAG_WITH_NO_DATA   0x0080 /* rel scannability doesn't matter */

Definition at line 65 of file executor.h.

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

#define EXEC_FLAG_WITH_OIDS   0x0020 /* force OIDs in returned tuples */

Definition at line 63 of file executor.h.

Referenced by ExecContextForcesOids(), and GetIntoRelEFlags().

#define EXEC_FLAG_WITHOUT_OIDS   0x0040 /* force no OIDs in returned tuples */

Definition at line 64 of file executor.h.

Referenced by ExecContextForcesOids(), GetIntoRelEFlags(), and refresh_matview_datafill().

#define ResetPerTupleExprContext (   estate)
Value:
do { \
if ((estate)->es_per_tuple_exprcontext) \
ResetExprContext((estate)->es_per_tuple_exprcontext); \
} while (0)
#define ResetExprContext(econtext)
Definition: executor.h:470

Definition at line 485 of file executor.h.

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

Typedef Documentation

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

Definition at line 409 of file executor.h.

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

Definition at line 410 of file executor.h.

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

Definition at line 88 of file executor.h.

typedef void(* ExecutorEnd_hook_type)(QueryDesc *queryDesc)

Definition at line 84 of file executor.h.

typedef void(* ExecutorFinish_hook_type)(QueryDesc *queryDesc)

Definition at line 80 of file executor.h.

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

Definition at line 73 of file executor.h.

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

Definition at line 69 of file executor.h.

Function Documentation

TupOutputState* begin_tup_output_tupdesc ( DestReceiver dest,
TupleDesc  tupdesc 
)

Definition at line 1235 of file execTuples.c.

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

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

1236 {
1237  TupOutputState *tstate;
1238 
1239  tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
1240 
1241  tstate->slot = MakeSingleTupleTableSlot(tupdesc);
1242  tstate->dest = dest;
1243 
1244  tstate->dest->rStartup(tstate->dest, (int) CMD_SELECT, tupdesc);
1245 
1246  return tstate;
1247 }
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:121
TupleTableSlot * slot
Definition: executor.h:434
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:199
void * palloc(Size size)
Definition: mcxt.c:848
DestReceiver * dest
Definition: executor.h:435
TupleHashTable BuildTupleHashTable ( int  numCols,
AttrNumber keyColIdx,
FmgrInfo eqfunctions,
FmgrInfo hashfunctions,
long  nbuckets,
Size  additionalsize,
MemoryContext  tablecxt,
MemoryContext  tempcxt,
bool  use_variable_hash_iv 
)

Definition at line 290 of file execGrouping.c.

References Assert, TupleHashTableData::cur_eq_funcs, TupleHashTableData::entrysize, TupleHashTableData::hash_iv, hash_uint32(), TupleHashTableData::hashtab, TupleHashTableData::in_hash_funcs, TupleHashTableData::inputslot, TupleHashTableData::keyColIdx, MemoryContextAlloc(), Min, TupleHashTableData::numCols, ParallelWorkerNumber, TupleHashTableData::tab_eq_funcs, TupleHashTableData::tab_hash_funcs, TupleHashTableData::tablecxt, TupleHashTableData::tableslot, TupleHashTableData::tempcxt, and work_mem.

Referenced by build_hash_table(), and buildSubPlanHash().

296 {
297  TupleHashTable hashtable;
298  Size entrysize = sizeof(TupleHashEntryData) + additionalsize;
299 
300  Assert(nbuckets > 0);
301 
302  /* Limit initial table size request to not more than work_mem */
303  nbuckets = Min(nbuckets, (long) ((work_mem * 1024L) / entrysize));
304 
305  hashtable = (TupleHashTable)
306  MemoryContextAlloc(tablecxt, sizeof(TupleHashTableData));
307 
308  hashtable->numCols = numCols;
309  hashtable->keyColIdx = keyColIdx;
310  hashtable->tab_hash_funcs = hashfunctions;
311  hashtable->tab_eq_funcs = eqfunctions;
312  hashtable->tablecxt = tablecxt;
313  hashtable->tempcxt = tempcxt;
314  hashtable->entrysize = entrysize;
315  hashtable->tableslot = NULL; /* will be made on first lookup */
316  hashtable->inputslot = NULL;
317  hashtable->in_hash_funcs = NULL;
318  hashtable->cur_eq_funcs = NULL;
319 
320  /*
321  * If parallelism is in use, even if the master backend is performing the
322  * scan itself, we don't want to create the hashtable exactly the same way
323  * in all workers. As hashtables are iterated over in keyspace-order,
324  * doing so in all processes in the same way is likely to lead to
325  * "unbalanced" hashtables when the table size initially is
326  * underestimated.
327  */
328  if (use_variable_hash_iv)
330  else
331  hashtable->hash_iv = 0;
332 
333  hashtable->hashtab = tuplehash_create(tablecxt, nbuckets, hashtable);
334 
335  return hashtable;
336 }
TupleTableSlot * inputslot
Definition: execnodes.h:615
#define Min(x, y)
Definition: c.h:795
AttrNumber * keyColIdx
Definition: execnodes.h:607
FmgrInfo * tab_hash_funcs
Definition: execnodes.h:608
FmgrInfo * in_hash_funcs
Definition: execnodes.h:616
struct TupleHashEntryData TupleHashEntryData
MemoryContext tablecxt
Definition: execnodes.h:610
struct TupleHashTableData * TupleHashTable
Definition: execnodes.h:585
int ParallelWorkerNumber
Definition: parallel.c:98
Datum hash_uint32(uint32 k)
Definition: hashfunc.c:853
int work_mem
Definition: globals.c:113
tuplehash_hash * hashtab
Definition: execnodes.h:605
#define Assert(condition)
Definition: c.h:664
TupleTableSlot * tableslot
Definition: execnodes.h:613
size_t Size
Definition: c.h:350
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:706
FmgrInfo * cur_eq_funcs
Definition: execnodes.h:617
MemoryContext tempcxt
Definition: execnodes.h:611
FmgrInfo * tab_eq_funcs
Definition: execnodes.h:609
void check_exclusion_constraint ( Relation  heap,
Relation  index,
IndexInfo indexInfo,
ItemPointer  tupleid,
Datum values,
bool isnull,
EState estate,
bool  newIndex 
)

Definition at line 863 of file execIndexing.c.

References CEOUC_WAIT, and check_exclusion_or_unique_constraint().

Referenced by IndexCheckExclusion(), and unique_key_recheck().

868 {
869  (void) check_exclusion_or_unique_constraint(heap, index, indexInfo, tupleid,
870  values, isnull,
871  estate, newIndex,
872  CEOUC_WAIT, false, NULL);
873 }
static bool check_exclusion_or_unique_constraint(Relation heap, Relation index, IndexInfo *indexInfo, ItemPointer tupleid, Datum *values, bool *isnull, EState *estate, bool newIndex, CEOUC_WAIT_MODE waitMode, bool errorOK, ItemPointer conflictTid)
Definition: execIndexing.c:639
static Datum values[MAXATTR]
Definition: bootstrap.c:164
void CheckCmdReplicaIdentity ( Relation  rel,
CmdType  cmd 
)

Definition at line 540 of file execReplication.c.

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

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

541 {
542  PublicationActions *pubactions;
543 
544  /* We only need to do checks for UPDATE and DELETE. */
545  if (cmd != CMD_UPDATE && cmd != CMD_DELETE)
546  return;
547 
548  /* If relation has replica identity we are always good. */
549  if (rel->rd_rel->relreplident == REPLICA_IDENTITY_FULL ||
551  return;
552 
553  /*
554  * This is either UPDATE OR DELETE and there is no replica identity.
555  *
556  * Check if the table publishes UPDATES or DELETES.
557  */
558  pubactions = GetRelationPublicationActions(rel);
559  if (cmd == CMD_UPDATE && pubactions->pubupdate)
560  ereport(ERROR,
561  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
562  errmsg("cannot update table \"%s\" because it does not have a replica identity and publishes updates",
564  errhint("To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.")));
565  else if (cmd == CMD_DELETE && pubactions->pubdelete)
566  ereport(ERROR,
567  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
568  errmsg("cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes",
570  errhint("To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE.")));
571 }
int errhint(const char *fmt,...)
Definition: elog.c:987
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:4688
int errcode(int sqlerrcode)
Definition: elog.c:575
Form_pg_class rd_rel
Definition: rel.h:114
#define OidIsValid(objectId)
Definition: c.h:532
#define REPLICA_IDENTITY_FULL
Definition: pg_class.h:179
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:436
#define ereport(elevel, rest)
Definition: elog.h:122
struct PublicationActions * GetRelationPublicationActions(Relation relation)
Definition: relcache.c:5184
int errmsg(const char *fmt,...)
Definition: elog.c:797
void CheckSubscriptionRelkind ( char  relkind,
const char *  nspname,
const char *  relname 
)

Definition at line 580 of file execReplication.c.

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

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

582 {
583  /*
584  * We currently only support writing to regular tables.
585  */
586  if (relkind != RELKIND_RELATION)
587  ereport(ERROR,
588  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
589  errmsg("logical replication target relation \"%s.%s\" is not a table",
590  nspname, relname)));
591 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_RELATION
Definition: pg_class.h:160
void CheckValidResultRel ( ResultRelInfo resultRelInfo,
CmdType  operation 
)

Definition at line 1100 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, RELKIND_FOREIGN_TABLE, RELKIND_MATVIEW, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_TOASTVALUE, RELKIND_VIEW, ResultRelInfo::ri_FdwRoutine, ResultRelInfo::ri_PartitionRoot, ResultRelInfo::ri_RelationDesc, TriggerDesc::trig_delete_instead_row, TriggerDesc::trig_insert_instead_row, TriggerDesc::trig_update_instead_row, and RelationData::trigdesc.

Referenced by ExecInitModifyTable(), and ExecSetupPartitionTupleRouting().

1101 {
1102  Relation resultRel = resultRelInfo->ri_RelationDesc;
1103  TriggerDesc *trigDesc = resultRel->trigdesc;
1104  FdwRoutine *fdwroutine;
1105 
1106  switch (resultRel->rd_rel->relkind)
1107  {
1108  case RELKIND_RELATION:
1110  CheckCmdReplicaIdentity(resultRel, operation);
1111  break;
1112  case RELKIND_SEQUENCE:
1113  ereport(ERROR,
1114  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1115  errmsg("cannot change sequence \"%s\"",
1116  RelationGetRelationName(resultRel))));
1117  break;
1118  case RELKIND_TOASTVALUE:
1119  ereport(ERROR,
1120  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1121  errmsg("cannot change TOAST relation \"%s\"",
1122  RelationGetRelationName(resultRel))));
1123  break;
1124  case RELKIND_VIEW:
1125 
1126  /*
1127  * Okay only if there's a suitable INSTEAD OF trigger. Messages
1128  * here should match rewriteHandler.c's rewriteTargetView, except
1129  * that we omit errdetail because we haven't got the information
1130  * handy (and given that we really shouldn't get here anyway, it's
1131  * not worth great exertion to get).
1132  */
1133  switch (operation)
1134  {
1135  case CMD_INSERT:
1136  if (!trigDesc || !trigDesc->trig_insert_instead_row)
1137  ereport(ERROR,
1138  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1139  errmsg("cannot insert into view \"%s\"",
1140  RelationGetRelationName(resultRel)),
1141  errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule.")));
1142  break;
1143  case CMD_UPDATE:
1144  if (!trigDesc || !trigDesc->trig_update_instead_row)
1145  ereport(ERROR,
1146  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1147  errmsg("cannot update view \"%s\"",
1148  RelationGetRelationName(resultRel)),
1149  errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.")));
1150  break;
1151  case CMD_DELETE:
1152  if (!trigDesc || !trigDesc->trig_delete_instead_row)
1153  ereport(ERROR,
1154  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1155  errmsg("cannot delete from view \"%s\"",
1156  RelationGetRelationName(resultRel)),
1157  errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule.")));
1158  break;
1159  default:
1160  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1161  break;
1162  }
1163  break;
1164  case RELKIND_MATVIEW:
1166  ereport(ERROR,
1167  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1168  errmsg("cannot change materialized view \"%s\"",
1169  RelationGetRelationName(resultRel))));
1170  break;
1171  case RELKIND_FOREIGN_TABLE:
1172  /* Okay only if the FDW supports it */
1173  fdwroutine = resultRelInfo->ri_FdwRoutine;
1174  switch (operation)
1175  {
1176  case CMD_INSERT:
1177 
1178  /*
1179  * If foreign partition to do tuple-routing for, skip the
1180  * check; it's disallowed elsewhere.
1181  */
1182  if (resultRelInfo->ri_PartitionRoot)
1183  break;
1184  if (fdwroutine->ExecForeignInsert == NULL)
1185  ereport(ERROR,
1186  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1187  errmsg("cannot insert into foreign table \"%s\"",
1188  RelationGetRelationName(resultRel))));
1189  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1190  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_INSERT)) == 0)
1191  ereport(ERROR,
1192  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1193  errmsg("foreign table \"%s\" does not allow inserts",
1194  RelationGetRelationName(resultRel))));
1195  break;
1196  case CMD_UPDATE:
1197  if (fdwroutine->ExecForeignUpdate == NULL)
1198  ereport(ERROR,
1199  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1200  errmsg("cannot update foreign table \"%s\"",
1201  RelationGetRelationName(resultRel))));
1202  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1203  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_UPDATE)) == 0)
1204  ereport(ERROR,
1205  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1206  errmsg("foreign table \"%s\" does not allow updates",
1207  RelationGetRelationName(resultRel))));
1208  break;
1209  case CMD_DELETE:
1210  if (fdwroutine->ExecForeignDelete == NULL)
1211  ereport(ERROR,
1212  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1213  errmsg("cannot delete from foreign table \"%s\"",
1214  RelationGetRelationName(resultRel))));
1215  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1216  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_DELETE)) == 0)
1217  ereport(ERROR,
1218  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1219  errmsg("foreign table \"%s\" does not allow deletes",
1220  RelationGetRelationName(resultRel))));
1221  break;
1222  default:
1223  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1224  break;
1225  }
1226  break;
1227  default:
1228  ereport(ERROR,
1229  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1230  errmsg("cannot change relation \"%s\"",
1231  RelationGetRelationName(resultRel))));
1232  break;
1233  }
1234 }
ExecForeignDelete_function ExecForeignDelete
Definition: fdwapi.h:202
Relation ri_RelationDesc
Definition: execnodes.h:354
int errhint(const char *fmt,...)
Definition: elog.c:987
bool MatViewIncrementalMaintenanceIsEnabled(void)
Definition: matview.c:861
ExecForeignInsert_function ExecForeignInsert
Definition: fdwapi.h:200
Relation ri_PartitionRoot
Definition: execnodes.h:414
#define RELKIND_MATVIEW
Definition: pg_class.h:165
int errcode(int sqlerrcode)
Definition: elog.c:575
Form_pg_class rd_rel
Definition: rel.h:114
bool trig_insert_instead_row
Definition: reltrigger.h:57
#define ERROR
Definition: elog.h:43
TriggerDesc * trigdesc
Definition: rel.h:120
#define RelationGetRelationName(relation)
Definition: rel.h:436
struct FdwRoutine * ri_FdwRoutine
Definition: execnodes.h:378
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:167
void CheckCmdReplicaIdentity(Relation rel, CmdType cmd)
#define ereport(elevel, rest)
Definition: elog.h:122
bool trig_update_instead_row
Definition: reltrigger.h:62
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
bool trig_delete_instead_row
Definition: reltrigger.h:67
#define RELKIND_TOASTVALUE
Definition: pg_class.h:163
ExecForeignUpdate_function ExecForeignUpdate
Definition: fdwapi.h:201
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_VIEW
Definition: pg_class.h:164
IsForeignRelUpdatable_function IsForeignRelUpdatable
Definition: fdwapi.h:204
#define elog
Definition: elog.h:219
#define RELKIND_RELATION
Definition: pg_class.h:160
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
EState* CreateExecutorState ( void  )

Definition at line 80 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_epqTuple, EState::es_epqTupleSet, EState::es_exprcontexts, EState::es_finished, EState::es_instrument, EState::es_junkFilter, EState::es_lastoid, EState::es_leaf_result_relations, 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_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_newtup_slot, EState::es_trig_oldtup_slot, EState::es_trig_target_relations, EState::es_trig_tuple_slot, EState::es_tupleTable, ForwardScanDirection, InvalidOid, InvalidSnapshot, makeNode, MemoryContextSwitchTo(), and NIL.

Referenced by afterTriggerInvokeEvents(), ATRewriteTable(), check_default_allows_bound(), compute_index_stats(), CopyFrom(), create_estate_for_relation(), EvalPlanQualStart(), evaluate_expr(), ExecuteQuery(), ExecuteTruncate(), ExplainExecuteQuery(), get_actual_variable_range(), get_qual_for_range(), IndexBuildHeapRangeScan(), IndexCheckExclusion(), operator_predicate_proof(), plpgsql_create_econtext(), plpgsql_inline_handler(), standard_ExecutorStart(), tuplesort_begin_cluster(), unique_key_recheck(), validate_index_heapscan(), validateCheckConstraint(), and validateDomainConstraint().

81 {
82  EState *estate;
83  MemoryContext qcontext;
84  MemoryContext oldcontext;
85 
86  /*
87  * Create the per-query context for this Executor run.
88  */
90  "ExecutorState",
92 
93  /*
94  * Make the EState node within the per-query context. This way, we don't
95  * need a separate pfree() operation for it at shutdown.
96  */
97  oldcontext = MemoryContextSwitchTo(qcontext);
98 
99  estate = makeNode(EState);
100 
101  /*
102  * Initialize all fields of the Executor State structure
103  */
105  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
106  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
107  estate->es_range_table = NIL;
108  estate->es_plannedstmt = NULL;
109 
110  estate->es_junkFilter = NULL;
111 
112  estate->es_output_cid = (CommandId) 0;
113 
114  estate->es_result_relations = NULL;
115  estate->es_num_result_relations = 0;
116  estate->es_result_relation_info = NULL;
117 
118  estate->es_root_result_relations = NULL;
119  estate->es_num_root_result_relations = 0;
120 
121  estate->es_leaf_result_relations = NIL;
122 
123  estate->es_trig_target_relations = NIL;
124  estate->es_trig_tuple_slot = NULL;
125  estate->es_trig_oldtup_slot = NULL;
126  estate->es_trig_newtup_slot = NULL;
127 
128  estate->es_param_list_info = NULL;
129  estate->es_param_exec_vals = NULL;
130 
131  estate->es_queryEnv = NULL;
132 
133  estate->es_query_cxt = qcontext;
134 
135  estate->es_tupleTable = NIL;
136 
137  estate->es_rowMarks = NIL;
138 
139  estate->es_processed = 0;
140  estate->es_lastoid = InvalidOid;
141 
142  estate->es_top_eflags = 0;
143  estate->es_instrument = 0;
144  estate->es_finished = false;
145 
146  estate->es_exprcontexts = NIL;
147 
148  estate->es_subplanstates = NIL;
149 
150  estate->es_auxmodifytables = NIL;
151 
152  estate->es_per_tuple_exprcontext = NULL;
153 
154  estate->es_epqTuple = NULL;
155  estate->es_epqTupleSet = NULL;
156  estate->es_epqScanDone = NULL;
157  estate->es_sourceText = NULL;
158 
159  /*
160  * Return the executor state structure
161  */
162  MemoryContextSwitchTo(oldcontext);
163 
164  return estate;
165 }
#define NIL
Definition: pg_list.h:69
uint32 CommandId
Definition: c.h:405
HeapTuple * es_epqTuple
Definition: execnodes.h:506
JunkFilter * es_junkFilter
Definition: execnodes.h:435
CommandId es_output_cid
Definition: execnodes.h:438
TupleTableSlot * es_trig_newtup_slot
Definition: execnodes.h:462
Oid es_lastoid
Definition: execnodes.h:478
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:432
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:430
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:495
Snapshot es_snapshot
Definition: execnodes.h:429
List * es_range_table
Definition: execnodes.h:431
ScanDirection es_direction
Definition: execnodes.h:428
const char * es_sourceText
Definition: execnodes.h:433
ParamExecData * es_param_exec_vals
Definition: execnodes.h:466
MemoryContext es_query_cxt
Definition: execnodes.h:471
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
ResultRelInfo * es_result_relations
Definition: execnodes.h:441
TupleTableSlot * es_trig_oldtup_slot
Definition: execnodes.h:461
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
int es_instrument
Definition: execnodes.h:481
TupleTableSlot * es_trig_tuple_slot
Definition: execnodes.h:460
List * es_leaf_result_relations
Definition: execnodes.h:456
QueryEnvironment * es_queryEnv
Definition: execnodes.h:468
int es_num_root_result_relations
Definition: execnodes.h:453
#define InvalidSnapshot
Definition: snapshot.h:25
List * es_trig_target_relations
Definition: execnodes.h:459
List * es_tupleTable
Definition: execnodes.h:473
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
List * es_auxmodifytables
Definition: execnodes.h:488
int es_num_result_relations
Definition: execnodes.h:442
#define InvalidOid
Definition: postgres_ext.h:36
bool es_finished
Definition: execnodes.h:482
#define makeNode(_type_)
Definition: nodes.h:557
uint64 es_processed
Definition: execnodes.h:477
bool * es_epqTupleSet
Definition: execnodes.h:507
List * es_subplanstates
Definition: execnodes.h:486
List * es_rowMarks
Definition: execnodes.h:475
int es_top_eflags
Definition: execnodes.h:480
ResultRelInfo * es_root_result_relations
Definition: execnodes.h:452
bool * es_epqScanDone
Definition: execnodes.h:508
ParamListInfo es_param_list_info
Definition: execnodes.h:465
List * es_exprcontexts
Definition: execnodes.h:484
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:443
ExprContext* CreateExprContext ( EState estate)

Definition at line 223 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(), MakePerTupleExprContext(), and plpgsql_create_econtext().

224 {
225  ExprContext *econtext;
226  MemoryContext oldcontext;
227 
228  /* Create the ExprContext node within the per-query memory context */
229  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
230 
231  econtext = makeNode(ExprContext);
232 
233  /* Initialize fields of ExprContext */
234  econtext->ecxt_scantuple = NULL;
235  econtext->ecxt_innertuple = NULL;
236  econtext->ecxt_outertuple = NULL;
237 
238  econtext->ecxt_per_query_memory = estate->es_query_cxt;
239 
240  /*
241  * Create working memory for expression evaluation in this context.
242  */
243  econtext->ecxt_per_tuple_memory =
245  "ExprContext",
247 
248  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
249  econtext->ecxt_param_list_info = estate->es_param_list_info;
250 
251  econtext->ecxt_aggvalues = NULL;
252  econtext->ecxt_aggnulls = NULL;
253 
254  econtext->caseValue_datum = (Datum) 0;
255  econtext->caseValue_isNull = true;
256 
257  econtext->domainValue_datum = (Datum) 0;
258  econtext->domainValue_isNull = true;
259 
260  econtext->ecxt_estate = estate;
261 
262  econtext->ecxt_callbacks = NULL;
263 
264  /*
265  * Link the ExprContext into the EState to ensure it is shut down when the
266  * EState is freed. Because we use lcons(), shutdowns will occur in
267  * reverse order of creation, which may not be essential but can't hurt.
268  */
269  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
270 
271  MemoryContextSwitchTo(oldcontext);
272 
273  return econtext;
274 }
Datum * ecxt_aggvalues
Definition: execnodes.h:213
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:203
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum domainValue_datum
Definition: execnodes.h:221
ParamExecData * es_param_exec_vals
Definition: execnodes.h:466
MemoryContext es_query_cxt
Definition: execnodes.h:471
Datum caseValue_datum
Definition: execnodes.h:217
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:228
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:198
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:206
struct EState * ecxt_estate
Definition: execnodes.h:225
bool domainValue_isNull
Definition: execnodes.h:222
bool * ecxt_aggnulls
Definition: execnodes.h:214
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
uintptr_t Datum
Definition: postgres.h:372
List * lcons(void *datum, List *list)
Definition: list.c:259
#define makeNode(_type_)
Definition: nodes.h:557
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:199
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:197
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:202
bool caseValue_isNull
Definition: execnodes.h:218
ParamListInfo es_param_list_info
Definition: execnodes.h:465
List * es_exprcontexts
Definition: execnodes.h:484
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:207
ExprContext* CreateStandaloneExprContext ( void  )

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

296 {
297  ExprContext *econtext;
298 
299  /* Create the ExprContext node within the caller's memory context */
300  econtext = makeNode(ExprContext);
301 
302  /* Initialize fields of ExprContext */
303  econtext->ecxt_scantuple = NULL;
304  econtext->ecxt_innertuple = NULL;
305  econtext->ecxt_outertuple = NULL;
306 
308 
309  /*
310  * Create working memory for expression evaluation in this context.
311  */
312  econtext->ecxt_per_tuple_memory =
314  "ExprContext",
316 
317  econtext->ecxt_param_exec_vals = NULL;
318  econtext->ecxt_param_list_info = NULL;
319 
320  econtext->ecxt_aggvalues = NULL;
321  econtext->ecxt_aggnulls = NULL;
322 
323  econtext->caseValue_datum = (Datum) 0;
324  econtext->caseValue_isNull = true;
325 
326  econtext->domainValue_datum = (Datum) 0;
327  econtext->domainValue_isNull = true;
328 
329  econtext->ecxt_estate = NULL;
330 
331  econtext->ecxt_callbacks = NULL;
332 
333  return econtext;
334 }
Datum * ecxt_aggvalues
Definition: execnodes.h:213
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:203
Datum domainValue_datum
Definition: execnodes.h:221
Datum caseValue_datum
Definition: execnodes.h:217
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:228
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:198
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:206
struct EState * ecxt_estate
Definition: execnodes.h:225
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
bool domainValue_isNull
Definition: execnodes.h:222
bool * ecxt_aggnulls
Definition: execnodes.h:214
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
uintptr_t Datum
Definition: postgres.h:372
#define makeNode(_type_)
Definition: nodes.h:557
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:199
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:197
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:202
bool caseValue_isNull
Definition: execnodes.h:218
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:207
void do_text_output_multiline ( TupOutputState tstate,
const char *  txt 
)

Definition at line 1281 of file execTuples.c.

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

Referenced by ExplainQuery().

1282 {
1283  Datum values[1];
1284  bool isnull[1] = {false};
1285 
1286  while (*txt)
1287  {
1288  const char *eol;
1289  int len;
1290 
1291  eol = strchr(txt, '\n');
1292  if (eol)
1293  {
1294  len = eol - txt;
1295  eol++;
1296  }
1297  else
1298  {
1299  len = strlen(txt);
1300  eol = txt + len;
1301  }
1302 
1303  values[0] = PointerGetDatum(cstring_to_text_with_len(txt, len));
1304  do_tup_output(tstate, values, isnull);
1305  pfree(DatumGetPointer(values[0]));
1306  txt = eol;
1307  }
1308 }
#define PointerGetDatum(X)
Definition: postgres.h:562
void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
Definition: execTuples.c:1253
void pfree(void *pointer)
Definition: mcxt.c:949
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:161
uintptr_t Datum
Definition: postgres.h:372
#define DatumGetPointer(X)
Definition: postgres.h:555
static Datum values[MAXATTR]
Definition: bootstrap.c:164
void do_tup_output ( TupOutputState tstate,
Datum values,
bool isnull 
)

Definition at line 1253 of file execTuples.c.

References TupOutputState::dest, ExecClearTuple(), ExecStoreVirtualTuple(), tupleDesc::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().

1254 {
1255  TupleTableSlot *slot = tstate->slot;
1256  int natts = slot->tts_tupleDescriptor->natts;
1257 
1258  /* make sure the slot is clear */
1259  ExecClearTuple(slot);
1260 
1261  /* insert data */
1262  memcpy(slot->tts_values, values, natts * sizeof(Datum));
1263  memcpy(slot->tts_isnull, isnull, natts * sizeof(bool));
1264 
1265  /* mark slot as containing a virtual tuple */
1266  ExecStoreVirtualTuple(slot);
1267 
1268  /* send the tuple to the receiver */
1269  (void) tstate->dest->receiveSlot(slot, tstate->dest);
1270 
1271  /* clean up */
1272  ExecClearTuple(slot);
1273 }
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
Datum * tts_values
Definition: tuptable.h:125
TupleTableSlot * slot
Definition: executor.h:434
int natts
Definition: tupdesc.h:73
bool * tts_isnull
Definition: tuptable.h:126
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
uintptr_t Datum
Definition: postgres.h:372
static Datum values[MAXATTR]
Definition: bootstrap.c:164
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:118
DestReceiver * dest
Definition: executor.h:435
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:488
void end_tup_output ( TupOutputState tstate)

Definition at line 1311 of file execTuples.c.

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

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

1312 {
1313  tstate->dest->rShutdown(tstate->dest);
1314  /* note that destroying the dest is not ours to do */
1316  pfree(tstate);
1317 }
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:124
TupleTableSlot * slot
Definition: executor.h:434
void pfree(void *pointer)
Definition: mcxt.c:949
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:216
DestReceiver * dest
Definition: executor.h:435
TupleTableSlot* EvalPlanQual ( EState estate,
EPQState epqstate,
Relation  relation,
Index  rti,
int  lockmode,
ItemPointer  tid,
TransactionId  priorXmax 
)

Definition at line 2479 of file execMain.c.

References Assert, EvalPlanQualBegin(), EvalPlanQualFetch(), EvalPlanQualFetchRowMarks(), EvalPlanQualNext(), EvalPlanQualSetTuple(), ExecMaterializeSlot(), LockWaitBlock, HeapTupleData::t_self, and TupIsNull.

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

2482 {
2483  TupleTableSlot *slot;
2484  HeapTuple copyTuple;
2485 
2486  Assert(rti > 0);
2487 
2488  /*
2489  * Get and lock the updated version of the row; if fail, return NULL.
2490  */
2491  copyTuple = EvalPlanQualFetch(estate, relation, lockmode, LockWaitBlock,
2492  tid, priorXmax);
2493 
2494  if (copyTuple == NULL)
2495  return NULL;
2496 
2497  /*
2498  * For UPDATE/DELETE we have to return tid of actual row we're executing
2499  * PQ for.
2500  */
2501  *tid = copyTuple->t_self;
2502 
2503  /*
2504  * Need to run a recheck subquery. Initialize or reinitialize EPQ state.
2505  */
2506  EvalPlanQualBegin(epqstate, estate);
2507 
2508  /*
2509  * Free old test tuple, if any, and store new tuple where relation's scan
2510  * node will see it
2511  */
2512  EvalPlanQualSetTuple(epqstate, rti, copyTuple);
2513 
2514  /*
2515  * Fetch any non-locked source rows
2516  */
2517  EvalPlanQualFetchRowMarks(epqstate);
2518 
2519  /*
2520  * Run the EPQ query. We assume it will return at most one tuple.
2521  */
2522  slot = EvalPlanQualNext(epqstate);
2523 
2524  /*
2525  * If we got a tuple, force the slot to materialize the tuple so that it
2526  * is not dependent on any local state in the EPQ query (in particular,
2527  * it's highly likely that the slot contains references to any pass-by-ref
2528  * datums that may be present in copyTuple). As with the next step, this
2529  * is to guard against early re-use of the EPQ query.
2530  */
2531  if (!TupIsNull(slot))
2532  (void) ExecMaterializeSlot(slot);
2533 
2534  /*
2535  * Clear out the test tuple. This is needed in case the EPQ query is
2536  * re-used to test a tuple for a different relation. (Not clear that can
2537  * really happen, but let's be safe.)
2538  */
2539  EvalPlanQualSetTuple(epqstate, rti, NULL);
2540 
2541  return slot;
2542 }
void EvalPlanQualSetTuple(EPQState *epqstate, Index rti, HeapTuple tuple)
Definition: execMain.c:2830
HeapTuple EvalPlanQualFetch(EState *estate, Relation relation, int lockmode, LockWaitPolicy wait_policy, ItemPointer tid, TransactionId priorXmax)
Definition: execMain.c:2566
void EvalPlanQualFetchRowMarks(EPQState *epqstate)
Definition: execMain.c:2865
void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate)
Definition: execMain.c:3016
TupleTableSlot * EvalPlanQualNext(EPQState *epqstate)
Definition: execMain.c:3000
ItemPointerData t_self
Definition: htup.h:65
#define TupIsNull(slot)
Definition: tuptable.h:138
#define Assert(condition)
Definition: c.h:664
HeapTuple ExecMaterializeSlot(TupleTableSlot *slot)
Definition: execTuples.c:725
void EvalPlanQualBegin ( EPQState epqstate,
EState parentestate 
)

Definition at line 3016 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, EPQState::estate, EvalPlanQualStart(), i, ParamExecData::isnull, list_length(), MemSet, PlannedStmt::nParamExec, EPQState::plan, EPQState::planstate, and ParamExecData::value.

Referenced by EvalPlanQual(), and ExecLockRows().

3017 {
3018  EState *estate = epqstate->estate;
3019 
3020  if (estate == NULL)
3021  {
3022  /* First time through, so create a child EState */
3023  EvalPlanQualStart(epqstate, parentestate, epqstate->plan);
3024  }
3025  else
3026  {
3027  /*
3028  * We already have a suitable child EPQ tree, so just reset it.
3029  */
3030  int rtsize = list_length(parentestate->es_range_table);
3031  PlanState *planstate = epqstate->planstate;
3032 
3033  MemSet(estate->es_epqScanDone, 0, rtsize * sizeof(bool));
3034 
3035  /* Recopy current values of parent parameters */
3036  if (parentestate->es_plannedstmt->nParamExec > 0)
3037  {
3038  int i = parentestate->es_plannedstmt->nParamExec;
3039 
3040  while (--i >= 0)
3041  {
3042  /* copy value if any, but not execPlan link */
3043  estate->es_param_exec_vals[i].value =
3044  parentestate->es_param_exec_vals[i].value;
3045  estate->es_param_exec_vals[i].isnull =
3046  parentestate->es_param_exec_vals[i].isnull;
3047  }
3048  }
3049 
3050  /*
3051  * Mark child plan tree as needing rescan at all scan nodes. The
3052  * first ExecProcNode will take care of actually doing the rescan.
3053  */
3054  planstate->chgParam = bms_add_member(planstate->chgParam,
3055  epqstate->epqParam);
3056  }
3057 }
PlannedStmt * es_plannedstmt
Definition: execnodes.h:432
#define MemSet(start, val, len)
Definition: c.h:846
List * es_range_table
Definition: execnodes.h:431
PlanState * planstate
Definition: execnodes.h:915
int nParamExec
Definition: plannodes.h:92
ParamExecData * es_param_exec_vals
Definition: execnodes.h:466
bool isnull
Definition: params.h:101
static void EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
Definition: execMain.c:3066
Bitmapset * chgParam
Definition: execnodes.h:875
Plan * plan
Definition: execnodes.h:917
static int list_length(const List *l)
Definition: pg_list.h:89
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
int i
bool * es_epqScanDone
Definition: execnodes.h:508
Datum value
Definition: params.h:100
int epqParam
Definition: execnodes.h:919
EState * estate
Definition: execnodes.h:914
void EvalPlanQualEnd ( EPQState epqstate)

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

3207 {
3208  EState *estate = epqstate->estate;
3209  MemoryContext oldcontext;
3210  ListCell *l;
3211 
3212  if (estate == NULL)
3213  return; /* idle, so nothing to do */
3214 
3215  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
3216 
3217  ExecEndNode(epqstate->planstate);
3218 
3219  foreach(l, estate->es_subplanstates)
3220  {
3221  PlanState *subplanstate = (PlanState *) lfirst(l);
3222 
3223  ExecEndNode(subplanstate);
3224  }
3225 
3226  /* throw away the per-estate tuple table */
3227  ExecResetTupleTable(estate->es_tupleTable, false);
3228 
3229  /* close any trigger target relations attached to this EState */
3230  ExecCleanUpTriggerState(estate);
3231 
3232  MemoryContextSwitchTo(oldcontext);
3233 
3234  FreeExecutorState(estate);
3235 
3236  /* Mark EPQState idle */
3237  epqstate->estate = NULL;
3238  epqstate->planstate = NULL;
3239  epqstate->origslot = NULL;
3240 }
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:523
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlanState * planstate
Definition: execnodes.h:915
void FreeExecutorState(EState *estate)
Definition: execUtils.c:183
MemoryContext es_query_cxt
Definition: execnodes.h:471
TupleTableSlot * origslot
Definition: execnodes.h:916
List * es_tupleTable
Definition: execnodes.h:473
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:156
#define lfirst(lc)
Definition: pg_list.h:106
List * es_subplanstates
Definition: execnodes.h:486
void ExecCleanUpTriggerState(EState *estate)
Definition: execMain.c:1468
EState * estate
Definition: execnodes.h:914
HeapTuple EvalPlanQualFetch ( EState estate,
Relation  relation,
int  lockmode,
LockWaitPolicy  wait_policy,
ItemPointer  tid,
TransactionId  priorXmax 
)

Definition at line 2566 of file execMain.c.

References Assert, buffer, ConditionalXactLockTableWait(), HeapUpdateFailureData::ctid, elog, ereport, errcode(), errmsg(), ERROR, EState::es_output_cid, heap_copytuple(), heap_fetch(), heap_lock_tuple(), HeapTupleHeaderGetCmin(), HeapTupleHeaderGetUpdateXid, HeapTupleHeaderGetXmin, HeapTupleHeaderIsSpeculative, HeapTupleInvisible, HeapTupleMayBeUpdated, HeapTupleSelfUpdated, HeapTupleUpdated, HeapTupleWouldBlock, InitDirtySnapshot, IsolationUsesXactSnapshot, ItemPointerEquals(), LockWaitBlock, LockWaitError, LockWaitSkip, RelationGetRelationName, ReleaseBuffer(), HeapTupleHeaderData::t_ctid, HeapTupleData::t_data, HeapTupleData::t_self, test(), TransactionIdEquals, TransactionIdIsCurrentTransactionId(), TransactionIdIsValid, XactLockTableWait(), XLTW_FetchUpdated, SnapshotData::xmax, HeapUpdateFailureData::xmax, and SnapshotData::xmin.

Referenced by EvalPlanQual(), and ExecLockRows().

2569 {
2570  HeapTuple copyTuple = NULL;
2571  HeapTupleData tuple;
2572  SnapshotData SnapshotDirty;
2573 
2574  /*
2575  * fetch target tuple
2576  *
2577  * Loop here to deal with updated or busy tuples
2578  */
2579  InitDirtySnapshot(SnapshotDirty);
2580  tuple.t_self = *tid;
2581  for (;;)
2582  {
2583  Buffer buffer;
2584 
2585  if (heap_fetch(relation, &SnapshotDirty, &tuple, &buffer, true, NULL))
2586  {
2587  HTSU_Result test;
2588  HeapUpdateFailureData hufd;
2589 
2590  /*
2591  * If xmin isn't what we're expecting, the slot must have been
2592  * recycled and reused for an unrelated tuple. This implies that
2593  * the latest version of the row was deleted, so we need do
2594  * nothing. (Should be safe to examine xmin without getting
2595  * buffer's content lock. We assume reading a TransactionId to be
2596  * atomic, and Xmin never changes in an existing tuple, except to
2597  * invalid or frozen, and neither of those can match priorXmax.)
2598  */
2600  priorXmax))
2601  {
2602  ReleaseBuffer(buffer);
2603  return NULL;
2604  }
2605 
2606  /* otherwise xmin should not be dirty... */
2607  if (TransactionIdIsValid(SnapshotDirty.xmin))
2608  elog(ERROR, "t_xmin is uncommitted in tuple to be updated");
2609 
2610  /*
2611  * If tuple is being updated by other transaction then we have to
2612  * wait for its commit/abort, or die trying.
2613  */
2614  if (TransactionIdIsValid(SnapshotDirty.xmax))
2615  {
2616  ReleaseBuffer(buffer);
2617  switch (wait_policy)
2618  {
2619  case LockWaitBlock:
2620  XactLockTableWait(SnapshotDirty.xmax,
2621  relation, &tuple.t_self,
2623  break;
2624  case LockWaitSkip:
2625  if (!ConditionalXactLockTableWait(SnapshotDirty.xmax))
2626  return NULL; /* skip instead of waiting */
2627  break;
2628  case LockWaitError:
2629  if (!ConditionalXactLockTableWait(SnapshotDirty.xmax))
2630  ereport(ERROR,
2631  (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
2632  errmsg("could not obtain lock on row in relation \"%s\"",
2633  RelationGetRelationName(relation))));
2634  break;
2635  }
2636  continue; /* loop back to repeat heap_fetch */
2637  }
2638 
2639  /*
2640  * If tuple was inserted by our own transaction, we have to check
2641  * cmin against es_output_cid: cmin >= current CID means our
2642  * command cannot see the tuple, so we should ignore it. Otherwise
2643  * heap_lock_tuple() will throw an error, and so would any later
2644  * attempt to update or delete the tuple. (We need not check cmax
2645  * because HeapTupleSatisfiesDirty will consider a tuple deleted
2646  * by our transaction dead, regardless of cmax.) We just checked
2647  * that priorXmax == xmin, so we can test that variable instead of
2648  * doing HeapTupleHeaderGetXmin again.
2649  */
2650  if (TransactionIdIsCurrentTransactionId(priorXmax) &&
2651  HeapTupleHeaderGetCmin(tuple.t_data) >= estate->es_output_cid)
2652  {
2653  ReleaseBuffer(buffer);
2654  return NULL;
2655  }
2656 
2657  /*
2658  * This is a live tuple, so now try to lock it.
2659  */
2660  test = heap_lock_tuple(relation, &tuple,
2661  estate->es_output_cid,
2662  lockmode, wait_policy,
2663  false, &buffer, &hufd);
2664  /* We now have two pins on the buffer, get rid of one */
2665  ReleaseBuffer(buffer);
2666 
2667  switch (test)
2668  {
2669  case HeapTupleSelfUpdated:
2670 
2671  /*
2672  * The target tuple was already updated or deleted by the
2673  * current command, or by a later command in the current
2674  * transaction. We *must* ignore the tuple in the former
2675  * case, so as to avoid the "Halloween problem" of
2676  * repeated update attempts. In the latter case it might
2677  * be sensible to fetch the updated tuple instead, but
2678  * doing so would require changing heap_update and
2679  * heap_delete to not complain about updating "invisible"
2680  * tuples, which seems pretty scary (heap_lock_tuple will
2681  * not complain, but few callers expect
2682  * HeapTupleInvisible, and we're not one of them). So for
2683  * now, treat the tuple as deleted and do not process.
2684  */
2685  ReleaseBuffer(buffer);
2686  return NULL;
2687 
2688  case HeapTupleMayBeUpdated:
2689  /* successfully locked */
2690  break;
2691 
2692  case HeapTupleUpdated:
2693  ReleaseBuffer(buffer);
2695  ereport(ERROR,
2696  (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
2697  errmsg("could not serialize access due to concurrent update")));
2698 
2699  /* Should not encounter speculative tuple on recheck */
2701  if (!ItemPointerEquals(&hufd.ctid, &tuple.t_self))
2702  {
2703  /* it was updated, so look at the updated version */
2704  tuple.t_self = hufd.ctid;
2705  /* updated row should have xmin matching this xmax */
2706  priorXmax = hufd.xmax;
2707  continue;
2708  }
2709  /* tuple was deleted, so give up */
2710  return NULL;
2711 
2712  case HeapTupleWouldBlock:
2713  ReleaseBuffer(buffer);
2714  return NULL;
2715 
2716  case HeapTupleInvisible:
2717  elog(ERROR, "attempted to lock invisible tuple");
2718 
2719  default:
2720  ReleaseBuffer(buffer);
2721  elog(ERROR, "unrecognized heap_lock_tuple status: %u",
2722  test);
2723  return NULL; /* keep compiler quiet */
2724  }
2725 
2726  /*
2727  * We got tuple - now copy it for use by recheck query.
2728  */
2729  copyTuple = heap_copytuple(&tuple);
2730  ReleaseBuffer(buffer);
2731  break;
2732  }
2733 
2734  /*
2735  * If the referenced slot was actually empty, the latest version of
2736  * the row must have been deleted, so we need do nothing.
2737  */
2738  if (tuple.t_data == NULL)
2739  {
2740  ReleaseBuffer(buffer);
2741  return NULL;
2742  }
2743 
2744  /*
2745  * As above, if xmin isn't what we're expecting, do nothing.
2746  */
2748  priorXmax))
2749  {
2750  ReleaseBuffer(buffer);
2751  return NULL;
2752  }
2753 
2754  /*
2755  * If we get here, the tuple was found but failed SnapshotDirty.
2756  * Assuming the xmin is either a committed xact or our own xact (as it
2757  * certainly should be if we're trying to modify the tuple), this must
2758  * mean that the row was updated or deleted by either a committed xact
2759  * or our own xact. If it was deleted, we can ignore it; if it was
2760  * updated then chain up to the next version and repeat the whole
2761  * process.
2762  *
2763  * As above, it should be safe to examine xmax and t_ctid without the
2764  * buffer content lock, because they can't be changing.
2765  */
2766  if (ItemPointerEquals(&tuple.t_self, &tuple.t_data->t_ctid))
2767  {
2768  /* deleted, so forget about it */
2769  ReleaseBuffer(buffer);
2770  return NULL;
2771  }
2772 
2773  /* updated, so look at the updated row */
2774  tuple.t_self = tuple.t_data->t_ctid;
2775  /* updated row should have xmin matching this xmax */
2776  priorXmax = HeapTupleHeaderGetUpdateXid(tuple.t_data);
2777  ReleaseBuffer(buffer);
2778  /* loop back to fetch next in chain */
2779  }
2780 
2781  /*
2782  * Return the copied tuple
2783  */
2784  return copyTuple;
2785 }
#define HeapTupleHeaderGetUpdateXid(tup)
Definition: htup_details.h:359
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:611
CommandId es_output_cid
Definition: execnodes.h:438
static void test(void)
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:775
HTSU_Result heap_lock_tuple(Relation relation, HeapTuple tuple, CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, bool follow_updates, Buffer *buffer, HeapUpdateFailureData *hufd)
Definition: heapam.c:4558
CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup)
Definition: combocid.c:105
bool heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tuple, Buffer *userbuf, bool keep_buf, Relation stats_relation)
Definition: heapam.c:1876
#define IsolationUsesXactSnapshot()
Definition: xact.h:43
#define HeapTupleHeaderIsSpeculative(tup)
Definition: htup_details.h:423
int errcode(int sqlerrcode)
Definition: elog.c:575
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
bool ConditionalXactLockTableWait(TransactionId xid)
Definition: lmgr.c:607
HeapTupleHeader t_data
Definition: htup.h:67
#define ERROR
Definition: elog.h:43
#define InitDirtySnapshot(snapshotdata)
Definition: tqual.h:102
ItemPointerData t_ctid
Definition: htup_details.h:150
ItemPointerData t_self
Definition: htup.h:65
HTSU_Result
Definition: snapshot.h:121
#define RelationGetRelationName(relation)
Definition: rel.h:436
TransactionId xmax
Definition: snapshot.h:69
TransactionId xmin
Definition: snapshot.h:68
#define ereport(elevel, rest)
Definition: elog.h:122
TransactionId xmax
Definition: heapam.h:71
void XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, XLTW_Oper oper)
Definition: lmgr.c:554
#define Assert(condition)
Definition: c.h:664
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:307
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:29
int errmsg(const char *fmt,...)
Definition: elog.c:797
ItemPointerData ctid
Definition: heapam.h:70
#define elog
Definition: elog.h:219
#define TransactionIdIsValid(xid)
Definition: transam.h:41
int Buffer
Definition: buf.h:23
void EvalPlanQualFetchRowMarks ( EPQState epqstate)

Definition at line 2865 of file execMain.c.

References EPQState::arowMarks, Assert, buffer, ExecAuxRowMark::ctidAttNo, DatumGetHeapTupleHeader, DatumGetObjectId, DatumGetPointer, elog, ereport, errcode(), errmsg(), ERROR, EPQState::estate, EvalPlanQualSetTuple(), ExecGetJunkAttribute(), GetFdwRoutineForRelation(), heap_copytuple(), heap_fetch(), HeapTupleHeaderGetDatumLength, lfirst, ExecRowMark::markType, OidIsValid, EPQState::origslot, ExecRowMark::prti, RelationData::rd_rel, FdwRoutine::RefetchForeignRow, ExecRowMark::relation, RelationGetRelationName, ReleaseBuffer(), ExecRowMark::relid, RELKIND_FOREIGN_TABLE, ROW_MARK_COPY, ROW_MARK_REFERENCE, ExecAuxRowMark::rowmark, RowMarkRequiresRowShareLock, ExecRowMark::rti, SnapshotAny, HeapTupleHeaderData::t_ctid, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, ExecAuxRowMark::toidAttNo, and ExecAuxRowMark::wholeAttNo.

Referenced by EvalPlanQual(), and ExecLockRows().

2866 {
2867  ListCell *l;
2868 
2869  Assert(epqstate->origslot != NULL);
2870 
2871  foreach(l, epqstate->arowMarks)
2872  {
2873  ExecAuxRowMark *aerm = (ExecAuxRowMark *) lfirst(l);
2874  ExecRowMark *erm = aerm->rowmark;
2875  Datum datum;
2876  bool isNull;
2877  HeapTupleData tuple;
2878 
2880  elog(ERROR, "EvalPlanQual doesn't support locking rowmarks");
2881 
2882  /* clear any leftover test tuple for this rel */
2883  EvalPlanQualSetTuple(epqstate, erm->rti, NULL);
2884 
2885  /* if child rel, must check whether it produced this row */
2886  if (erm->rti != erm->prti)
2887  {
2888  Oid tableoid;
2889 
2890  datum = ExecGetJunkAttribute(epqstate->origslot,
2891  aerm->toidAttNo,
2892  &isNull);
2893  /* non-locked rels could be on the inside of outer joins */
2894  if (isNull)
2895  continue;
2896  tableoid = DatumGetObjectId(datum);
2897 
2898  Assert(OidIsValid(erm->relid));
2899  if (tableoid != erm->relid)
2900  {
2901  /* this child is inactive right now */
2902  continue;
2903  }
2904  }
2905 
2906  if (erm->markType == ROW_MARK_REFERENCE)
2907  {
2908  HeapTuple copyTuple;
2909 
2910  Assert(erm->relation != NULL);
2911 
2912  /* fetch the tuple's ctid */
2913  datum = ExecGetJunkAttribute(epqstate->origslot,
2914  aerm->ctidAttNo,
2915  &isNull);
2916  /* non-locked rels could be on the inside of outer joins */
2917  if (isNull)
2918  continue;
2919 
2920  /* fetch requests on foreign tables must be passed to their FDW */
2921  if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2922  {
2923  FdwRoutine *fdwroutine;
2924  bool updated = false;
2925 
2926  fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
2927  /* this should have been checked already, but let's be safe */
2928  if (fdwroutine->RefetchForeignRow == NULL)
2929  ereport(ERROR,
2930  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2931  errmsg("cannot lock rows in foreign table \"%s\"",
2933  copyTuple = fdwroutine->RefetchForeignRow(epqstate->estate,
2934  erm,
2935  datum,
2936  &updated);
2937  if (copyTuple == NULL)
2938  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2939 
2940  /*
2941  * Ideally we'd insist on updated == false here, but that
2942  * assumes that FDWs can track that exactly, which they might
2943  * not be able to. So just ignore the flag.
2944  */
2945  }
2946  else
2947  {
2948  /* ordinary table, fetch the tuple */
2949  Buffer buffer;
2950 
2951  tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
2952  if (!heap_fetch(erm->relation, SnapshotAny, &tuple, &buffer,
2953  false, NULL))
2954  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2955 
2956  /* successful, copy tuple */
2957  copyTuple = heap_copytuple(&tuple);
2958  ReleaseBuffer(buffer);
2959  }
2960 
2961  /* store tuple */
2962  EvalPlanQualSetTuple(epqstate, erm->rti, copyTuple);
2963  }
2964  else
2965  {
2966  HeapTupleHeader td;
2967 
2968  Assert(erm->markType == ROW_MARK_COPY);
2969 
2970  /* fetch the whole-row Var for the relation */
2971  datum = ExecGetJunkAttribute(epqstate->origslot,
2972  aerm->wholeAttNo,
2973  &isNull);
2974  /* non-locked rels could be on the inside of outer joins */
2975  if (isNull)
2976  continue;
2977  td = DatumGetHeapTupleHeader(datum);
2978 
2979  /* build a temporary HeapTuple control structure */
2981  tuple.t_data = td;
2982  /* relation might be a foreign table, if so provide tableoid */
2983  tuple.t_tableOid = erm->relid;
2984  /* also copy t_ctid in case there's valid data there */
2985  tuple.t_self = td->t_ctid;
2986 
2987  /* copy and store tuple */
2988  EvalPlanQualSetTuple(epqstate, erm->rti,
2989  heap_copytuple(&tuple));
2990  }
2991  }
2992 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:611
void EvalPlanQualSetTuple(EPQState *epqstate, Index rti, HeapTuple tuple)
Definition: execMain.c:2830
Relation relation
Definition: execnodes.h:534
bool heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tuple, Buffer *userbuf, bool keep_buf, Relation stats_relation)
Definition: heapam.c:1876
#define DatumGetObjectId(X)
Definition: postgres.h:506
int errcode(int sqlerrcode)
Definition: elog.c:575
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:259
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:969
ItemPointerData * ItemPointer
Definition: itemptr.h:49
ExecRowMark * rowmark
Definition: execnodes.h:561
HeapTupleHeader t_data
Definition: htup.h:67
#define ERROR
Definition: elog.h:43
ItemPointerData t_ctid
Definition: htup_details.h:150
ItemPointerData t_self
Definition: htup.h:65
List * arowMarks
Definition: execnodes.h:918
uint32 t_len
Definition: htup.h:64
Index rti
Definition: execnodes.h:536
AttrNumber wholeAttNo
Definition: execnodes.h:564
Index prti
Definition: execnodes.h:537
#define RelationGetRelationName(relation)
Definition: rel.h:436
Oid t_tableOid
Definition: htup.h:66
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:167
TupleTableSlot * origslot
Definition: execnodes.h:916
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:372
#define SnapshotAny
Definition: tqual.h:28
#define Assert(condition)
Definition: c.h:664
#define lfirst(lc)
Definition: pg_list.h:106
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
RowMarkType markType
Definition: execnodes.h:539
AttrNumber toidAttNo
Definition: execnodes.h:563
#define DatumGetPointer(X)
Definition: postgres.h:555
int errmsg(const char *fmt,...)
Definition: elog.c:797
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Definition: foreign.c:395
Datum ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, bool *isNull)
Definition: execJunk.c:248
#define elog
Definition: elog.h:219
EState * estate
Definition: execnodes.h:914
int Buffer
Definition: buf.h:23
AttrNumber ctidAttNo
Definition: execnodes.h:562
RefetchForeignRow_function RefetchForeignRow
Definition: fdwapi.h:212
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
HeapTuple EvalPlanQualGetTuple ( EPQState epqstate,
Index  rti 
)

Definition at line 2850 of file execMain.c.

References Assert, EState::es_epqTuple, and EPQState::estate.

2851 {
2852  EState *estate = epqstate->estate;
2853 
2854  Assert(rti > 0);
2855 
2856  return estate->es_epqTuple[rti - 1];
2857 }
HeapTuple * es_epqTuple
Definition: execnodes.h:506
#define Assert(condition)
Definition: c.h:664
EState * estate
Definition: execnodes.h:914
void EvalPlanQualInit ( EPQState epqstate,
EState estate,
Plan subplan,
List auxrowmarks,
int  epqParam 
)

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

2797 {
2798  /* Mark the EPQ state inactive */
2799  epqstate->estate = NULL;
2800  epqstate->planstate = NULL;
2801  epqstate->origslot = NULL;
2802  /* ... and remember data that EvalPlanQualBegin will need */
2803  epqstate->plan = subplan;
2804  epqstate->arowMarks = auxrowmarks;
2805  epqstate->epqParam = epqParam;
2806 }
PlanState * planstate
Definition: execnodes.h:915
List * arowMarks
Definition: execnodes.h:918
TupleTableSlot * origslot
Definition: execnodes.h:916
Plan * plan
Definition: execnodes.h:917
int epqParam
Definition: execnodes.h:919
EState * estate
Definition: execnodes.h:914
TupleTableSlot* EvalPlanQualNext ( EPQState epqstate)

Definition at line 3000 of file execMain.c.

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

Referenced by EvalPlanQual(), and ExecLockRows().

3001 {
3002  MemoryContext oldcontext;
3003  TupleTableSlot *slot;
3004 
3005  oldcontext = MemoryContextSwitchTo(epqstate->estate->es_query_cxt);
3006  slot = ExecProcNode(epqstate->planstate);
3007  MemoryContextSwitchTo(oldcontext);
3008 
3009  return slot;
3010 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlanState * planstate
Definition: execnodes.h:915
MemoryContext es_query_cxt
Definition: execnodes.h:471
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition: executor.h:246
EState * estate
Definition: execnodes.h:914
void EvalPlanQualSetPlan ( EPQState epqstate,
Plan subplan,
List auxrowmarks 
)

Definition at line 2814 of file execMain.c.

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

Referenced by ExecInitModifyTable(), and ExecModifyTable().

2815 {
2816  /* If we have a live EPQ query, shut it down */
2817  EvalPlanQualEnd(epqstate);
2818  /* And set/change the plan pointer */
2819  epqstate->plan = subplan;
2820  /* The rowmarks depend on the plan, too */
2821  epqstate->arowMarks = auxrowmarks;
2822 }
void EvalPlanQualEnd(EPQState *epqstate)
Definition: execMain.c:3206
List * arowMarks
Definition: execnodes.h:918
Plan * plan
Definition: execnodes.h:917
void EvalPlanQualSetTuple ( EPQState epqstate,
Index  rti,
HeapTuple  tuple 
)

Definition at line 2830 of file execMain.c.

References Assert, EState::es_epqTuple, EState::es_epqTupleSet, EPQState::estate, and heap_freetuple().

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

2831 {
2832  EState *estate = epqstate->estate;
2833 
2834  Assert(rti > 0);
2835 
2836  /*
2837  * free old test tuple, if any, and store new tuple where relation's scan
2838  * node will see it
2839  */
2840  if (estate->es_epqTuple[rti - 1] != NULL)
2841  heap_freetuple(estate->es_epqTuple[rti - 1]);
2842  estate->es_epqTuple[rti - 1] = tuple;
2843  estate->es_epqTupleSet[rti - 1] = true;
2844 }
HeapTuple * es_epqTuple
Definition: execnodes.h:506
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
#define Assert(condition)
Definition: c.h:664
bool * es_epqTupleSet
Definition: execnodes.h:507
EState * estate
Definition: execnodes.h:914
void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

Definition at line 492 of file execUtils.c.

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

Referenced by ExecAssignScanProjectionInfoWithVarno(), ExecInitAgg(), ExecInitGather(), ExecInitGatherMerge(), ExecInitGroup(), ExecInitHashJoin(), ExecInitMergeJoin(), ExecInitNestLoop(), ExecInitResult(), and ExecInitWindowAgg().

494 {
495  planstate->ps_ProjInfo =
497  planstate->ps_ExprContext,
498  planstate->ps_ResultTupleSlot,
499  planstate,
500  inputDesc);
501 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:882
ExprContext * ps_ExprContext
Definition: execnodes.h:881
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:880
Plan * plan
Definition: execnodes.h:847
List * targetlist
Definition: plannodes.h:144
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:301
void ExecAssignResultType ( PlanState planstate,
TupleDesc  tupDesc 
)

Definition at line 433 of file execUtils.c.

References ExecSetSlotDescriptor(), and PlanState::ps_ResultTupleSlot.

Referenced by ExecAssignResultTypeFromTL(), and ExecInitModifyTable().

434 {
435  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
436 
437  ExecSetSlotDescriptor(slot, tupDesc);
438 }
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:880
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
void ExecAssignResultTypeFromTL ( PlanState planstate)

Definition at line 445 of file execUtils.c.

References ExecAssignResultType(), ExecContextForcesOids(), ExecTypeFromTL(), PlanState::plan, and Plan::targetlist.

Referenced by ExecInitAgg(), ExecInitAppend(), ExecInitBitmapHeapScan(), ExecInitCteScan(), ExecInitCustomScan(), ExecInitForeignScan(), ExecInitFunctionScan(), ExecInitGather(), ExecInitGatherMerge(), ExecInitGroup(), ExecInitHash(), ExecInitHashJoin(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecInitLimit(), ExecInitLockRows(), ExecInitMaterial(), ExecInitMergeAppend(), ExecInitMergeJoin(), ExecInitNamedTuplestoreScan(), ExecInitNestLoop(), ExecInitProjectSet(), ExecInitRecursiveUnion(), ExecInitResult(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitSetOp(), ExecInitSort(), ExecInitSubqueryScan(), ExecInitTableFuncScan(), ExecInitTidScan(), ExecInitUnique(), ExecInitValuesScan(), ExecInitWindowAgg(), and ExecInitWorkTableScan().

446 {
447  bool hasoid;
448  TupleDesc tupDesc;
449 
450  if (ExecContextForcesOids(planstate, &hasoid))
451  {
452  /* context forces OID choice; hasoid is now set correctly */
453  }
454  else
455  {
456  /* given free choice, don't leave space for OIDs in result tuples */
457  hasoid = false;
458  }
459 
460  /*
461  * ExecTypeFromTL needs the parse-time representation of the tlist, not a
462  * list of ExprStates. This is good because some plan nodes don't bother
463  * to set up planstate->targetlist ...
464  */
465  tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
466  ExecAssignResultType(planstate, tupDesc);
467 }
void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc)
Definition: execUtils.c:433
TupleDesc ExecTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:888
Plan * plan
Definition: execnodes.h:847
List * targetlist
Definition: plannodes.h:144
bool ExecContextForcesOids(PlanState *planstate, bool *hasoids)
Definition: execMain.c:1515
void ExecAssignScanProjectionInfo ( ScanState node)
void ExecAssignScanProjectionInfoWithVarno ( ScanState node,
Index  varno 
)

Definition at line 249 of file execScan.c.

References ExecAssignProjectionInfo(), Scan::plan, PlanState::plan, ScanState::ps, PlanState::ps_ProjInfo, ScanState::ss_ScanTupleSlot, Plan::targetlist, tlist_matches_tupdesc(), and TupleTableSlot::tts_tupleDescriptor.

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

250 {
251  Scan *scan = (Scan *) node->ps.plan;
252 
253  if (tlist_matches_tupdesc(&node->ps,
254  scan->plan.targetlist,
255  varno,
257  node->ps.ps_ProjInfo = NULL;
258  else
261 }
Plan plan
Definition: plannodes.h:328
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:882
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1103
PlanState ps
Definition: execnodes.h:1100
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:492
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
Definition: execScan.c:264
Plan * plan
Definition: execnodes.h:847
List * targetlist
Definition: plannodes.h:144
void ExecAssignScanTypeFromOuterPlan ( ScanState scanstate)

Definition at line 557 of file execUtils.c.

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

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

558 {
560  TupleDesc tupDesc;
561 
562  outerPlan = outerPlanState(scanstate);
563  tupDesc = ExecGetResultType(outerPlan);
564 
565  ExecAssignScanType(scanstate, tupDesc);
566 }
#define outerPlanState(node)
Definition: execnodes.h:893
#define outerPlan(node)
Definition: plannodes.h:174
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:474
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:545
ExecAuxRowMark* ExecBuildAuxRowMark ( ExecRowMark erm,
List targetlist 
)

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

2409 {
2410  ExecAuxRowMark *aerm = (ExecAuxRowMark *) palloc0(sizeof(ExecAuxRowMark));
2411  char resname[32];
2412 
2413  aerm->rowmark = erm;
2414 
2415  /* Look up the resjunk columns associated with this rowmark */
2416  if (erm->markType != ROW_MARK_COPY)
2417  {
2418  /* need ctid for all methods other than COPY */
2419  snprintf(resname, sizeof(resname), "ctid%u", erm->rowmarkId);
2420  aerm->ctidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2421  resname);
2422  if (!AttributeNumberIsValid(aerm->ctidAttNo))
2423  elog(ERROR, "could not find junk %s column", resname);
2424  }
2425  else
2426  {
2427  /* need wholerow if COPY */
2428  snprintf(resname, sizeof(resname), "wholerow%u", erm->rowmarkId);
2429  aerm->wholeAttNo = ExecFindJunkAttributeInTlist(targetlist,
2430  resname);
2431  if (!AttributeNumberIsValid(aerm->wholeAttNo))
2432  elog(ERROR, "could not find junk %s column", resname);
2433  }
2434 
2435  /* if child rel, need tableoid */
2436  if (erm->rti != erm->prti)
2437  {
2438  snprintf(resname, sizeof(resname), "tableoid%u", erm->rowmarkId);
2439  aerm->toidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2440  resname);
2441  if (!AttributeNumberIsValid(aerm->toidAttNo))
2442  elog(ERROR, "could not find junk %s column", resname);
2443  }
2444 
2445  return aerm;
2446 }
AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
Definition: execJunk.c:221
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
ExecRowMark * rowmark
Definition: execnodes.h:561
#define ERROR
Definition: elog.h:43
Index rti
Definition: execnodes.h:536
AttrNumber wholeAttNo
Definition: execnodes.h:564
Index prti
Definition: execnodes.h:537
Index rowmarkId
Definition: execnodes.h:538
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
void * palloc0(Size size)
Definition: mcxt.c:877
RowMarkType markType
Definition: execnodes.h:539
AttrNumber toidAttNo
Definition: execnodes.h:563
#define elog
Definition: elog.h:219
AttrNumber ctidAttNo
Definition: execnodes.h:562
ProjectionInfo* ExecBuildProjectionInfo ( List targetList,
ExprContext econtext,
TupleTableSlot slot,
PlanState parent,
TupleDesc  inputDesc 
)

Definition at line 301 of file execExpr.c.

References ExprEvalStep::assign_tmp, ExprEvalStep::assign_var, 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(), get_typlen(), INNER_VAR, IsA, lfirst_node, makeNode, ExprEvalStep::opcode, OUTER_VAR, 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(), ExecInitAgg(), ExecInitModifyTable(), and ExecInitSubPlan().

306 {
308  ExprState *state;
309  ExprEvalStep scratch;
310  ListCell *lc;
311 
312  projInfo->pi_exprContext = econtext;
313  /* We embed ExprState into ProjectionInfo instead of doing extra palloc */
314  projInfo->pi_state.tag.type = T_ExprState;
315  state = &projInfo->pi_state;
316  state->expr = (Expr *) targetList;
317  state->resultslot = slot;
318 
319  /* Insert EEOP_*_FETCHSOME steps as needed */
320  ExecInitExprSlots(state, (Node *) targetList);
321 
322  /* Now compile each tlist column */
323  foreach(lc, targetList)
324  {
325  TargetEntry *tle = lfirst_node(TargetEntry, lc);
326  Var *variable = NULL;
327  AttrNumber attnum = 0;
328  bool isSafeVar = false;
329 
330  /*
331  * If tlist expression is a safe non-system Var, use the fast-path
332  * ASSIGN_*_VAR opcodes. "Safe" means that we don't need to apply
333  * CheckVarSlotCompatibility() during plan startup. If a source slot
334  * was provided, we make the equivalent tests here; if a slot was not
335  * provided, we assume that no check is needed because we're dealing
336  * with a non-relation-scan-level expression.
337  */
338  if (tle->expr != NULL &&
339  IsA(tle->expr, Var) &&
340  ((Var *) tle->expr)->varattno > 0)
341  {
342  /* Non-system Var, but how safe is it? */
343  variable = (Var *) tle->expr;
344  attnum = variable->varattno;
345 
346  if (inputDesc == NULL)
347  isSafeVar = true; /* can't check, just assume OK */
348  else if (attnum <= inputDesc->natts)
349  {
350  Form_pg_attribute attr = TupleDescAttr(inputDesc, attnum - 1);
351 
352  /*
353  * If user attribute is dropped or has a type mismatch, don't
354  * use ASSIGN_*_VAR. Instead let the normal expression
355  * machinery handle it (which'll possibly error out).
356  */
357  if (!attr->attisdropped && variable->vartype == attr->atttypid)
358  {
359  isSafeVar = true;
360  }
361  }
362  }
363 
364  if (isSafeVar)
365  {
366  /* Fast-path: just generate an EEOP_ASSIGN_*_VAR step */
367  switch (variable->varno)
368  {
369  case INNER_VAR:
370  /* get the tuple from the inner node */
371  scratch.opcode = EEOP_ASSIGN_INNER_VAR;
372  break;
373 
374  case OUTER_VAR:
375  /* get the tuple from the outer node */
376  scratch.opcode = EEOP_ASSIGN_OUTER_VAR;
377  break;
378 
379  /* INDEX_VAR is handled by default case */
380 
381  default:
382  /* get the tuple from the relation being scanned */
383  scratch.opcode = EEOP_ASSIGN_SCAN_VAR;
384  break;
385  }
386 
387  scratch.d.assign_var.attnum = attnum - 1;
388  scratch.d.assign_var.resultnum = tle->resno - 1;
389  ExprEvalPushStep(state, &scratch);
390  }
391  else
392  {
393  /*
394  * Otherwise, compile the column expression normally.
395  *
396  * We can't tell the expression to evaluate directly into the
397  * result slot, as the result slot (and the exprstate for that
398  * matter) can change between executions. We instead evaluate
399  * into the ExprState's resvalue/resnull and then move.
400  */
401  ExecInitExprRec(tle->expr, parent, state,
402  &state->resvalue, &state->resnull);
403 
404  /*
405  * Column might be referenced multiple times in upper nodes, so
406  * force value to R/O - but only if it could be an expanded datum.
407  */
408  if (get_typlen(exprType((Node *) tle->expr)) == -1)
410  else
411  scratch.opcode = EEOP_ASSIGN_TMP;
412  scratch.d.assign_tmp.resultnum = tle->resno - 1;
413  ExprEvalPushStep(state, &scratch);
414  }
415  }
416 
417  scratch.opcode = EEOP_DONE;
418  ExprEvalPushStep(state, &scratch);
419 
420  ExecReadyExpr(state);
421 
422  return projInfo;
423 }
Node tag
Definition: execnodes.h:55
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:84
Definition: nodes.h:509
AttrNumber varattno
Definition: primnodes.h:168
TupleTableSlot * resultslot
Definition: execnodes.h:69
union ExprEvalStep::@52 d
Definition: primnodes.h:163
bool resnull
Definition: execnodes.h:63
Expr * expr
Definition: execnodes.h:83
Oid vartype
Definition: primnodes.h:170
static void ExecInitExprSlots(ExprState *state, Node *node)
Definition: execExpr.c:2171
#define lfirst_node(type, lc)
Definition: pg_list.h:109
NodeTag type
Definition: nodes.h:511
AttrNumber resno
Definition: primnodes.h:1369
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
Index varno
Definition: primnodes.h:166
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:574
struct ExprEvalStep::@52::@56 assign_var
#define INNER_VAR
Definition: primnodes.h:153
#define makeNode(_type_)
Definition: nodes.h:557
Definition: regguts.h:298
intptr_t opcode
Definition: execExpr.h:227
Expr * expr
Definition: primnodes.h:1368
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
static void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2042
int16 get_typlen(Oid typid)
Definition: lsyscache.c:1947
ExprState pi_state
Definition: execnodes.h:296
static void ExecInitExprRec(Expr *node, PlanState *parent, ExprState *state, Datum *resv, bool *resnull)
Definition: execExpr.c:589
ExprContext * pi_exprContext
Definition: execnodes.h:298
Datum resvalue
Definition: execnodes.h:64
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:154
struct ExprEvalStep::@52::@57 assign_tmp
bool ExecCheck ( ExprState state,
ExprContext context 
)

Definition at line 544 of file execExpr.c.

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

Referenced by ATRewriteTable(), check_default_allows_bound(), domain_check_input(), ExecPartitionCheck(), ExecRelCheck(), and validateCheckConstraint().

545 {
546  Datum ret;
547  bool isnull;
548 
549  /* short-circuit (here and in ExecInitCheck) for empty restriction list */
550  if (state == NULL)
551  return true;
552 
553  /* verify that expression was not compiled using ExecInitQual */
554  Assert(!(state->flags & EEO_FLAG_IS_QUAL));
555 
556  ret = ExecEvalExprSwitchContext(state, econtext, &isnull);
557 
558  if (isnull)
559  return true;
560 
561  return DatumGetBool(ret);
562 }
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:301
#define EEO_FLAG_IS_QUAL
Definition: execnodes.h:51
#define DatumGetBool(X)
Definition: postgres.h:399
uintptr_t Datum
Definition: postgres.h:372
#define Assert(condition)
Definition: c.h:664
uint8 flags
Definition: execnodes.h:57
bool ExecCheckIndexConstraints ( TupleTableSlot slot,
EState estate,
ItemPointer  conflictTid,
List arbiterIndexes 
)

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

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

Definition at line 570 of file execMain.c.

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

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

571 {
572  ListCell *l;
573  bool result = true;
574 
575  foreach(l, rangeTable)
576  {
577  RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
578 
579  result = ExecCheckRTEPerms(rte);
580  if (!result)
581  {
582  Assert(rte->rtekind == RTE_RELATION);
583  if (ereport_on_violation)
585  get_rel_name(rte->relid));
586  return false;
587  }
588  }
589 
591  result = (*ExecutorCheckPerms_hook) (rangeTable,
592  ereport_on_violation);
593  return result;
594 }
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
static bool ExecCheckRTEPerms(RangeTblEntry *rte)
Definition: execMain.c:601
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
Definition: execMain.c:76
#define Assert(condition)
Definition: c.h:664
#define lfirst(lc)
Definition: pg_list.h:106
RTEKind rtekind
Definition: parsenodes.h:945
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1726
int ExecCleanTargetListLength ( List targetlist)

Definition at line 1014 of file execUtils.c.

References lfirst_node, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), and ExecTypeFromTLInternal().

1015 {
1016  int len = 0;
1017  ListCell *tl;
1018 
1019  foreach(tl, targetlist)
1020  {
1021  TargetEntry *curTle = lfirst_node(TargetEntry, tl);
1022 
1023  if (!curTle->resjunk)
1024  len++;
1025  }
1026  return len;
1027 }
bool resjunk
Definition: primnodes.h:1375
#define lfirst_node(type, lc)
Definition: pg_list.h:109
TupleDesc ExecCleanTypeFromTL ( List targetList,
bool  hasoid 
)

Definition at line 900 of file execTuples.c.

References ExecTypeFromTLInternal().

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

901 {
902  return ExecTypeFromTLInternal(targetList, hasoid, true);
903 }
static TupleDesc ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
Definition: execTuples.c:906
void ExecCleanUpTriggerState ( EState estate)

Definition at line 1468 of file execMain.c.

References EState::es_trig_target_relations, ExecCloseIndices(), heap_close, lfirst, NoLock, and ResultRelInfo::ri_RelationDesc.

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

1469 {
1470  ListCell *l;
1471 
1472  foreach(l, estate->es_trig_target_relations)
1473  {
1474  ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
1475 
1476  /* Close indices and then the relation itself */
1477  ExecCloseIndices(resultRelInfo);
1478  heap_close(resultRelInfo->ri_RelationDesc, NoLock);
1479  }
1480 }
Relation ri_RelationDesc
Definition: execnodes.h:354
#define heap_close(r, l)
Definition: heapam.h:97
#define NoLock
Definition: lockdefs.h:34
List * es_trig_target_relations
Definition: execnodes.h:459
#define lfirst(lc)
Definition: pg_list.h:106
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
Definition: execIndexing.c:224
void ExecCloseIndices ( ResultRelInfo resultRelInfo)

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

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

Definition at line 666 of file execUtils.c.

References heap_close, and NoLock.

Referenced by ExecEndBitmapHeapScan(), ExecEndCustomScan(), ExecEndForeignScan(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), ExecEndSampleScan(), ExecEndSeqScan(), and ExecEndTidScan().

667 {
668  heap_close(scanrel, NoLock);
669 }
#define heap_close(r, l)
Definition: heapam.h:97
#define NoLock
Definition: lockdefs.h:34
void ExecConstraints ( ResultRelInfo resultRelInfo,
TupleTableSlot slot,
EState estate 
)

Definition at line 1942 of file execMain.c.

References Assert, bms_union(), tupleDesc::constr, convert_tuples_by_name(), do_convert_tuple(), ereport, errcode(), errdetail(), errmsg(), ERROR, errtablecol(), errtableconstraint(), ExecBuildSlotValueDescription(), ExecFetchSlotTuple(), ExecPartitionCheck(), ExecRelCheck(), ExecSetSlotDescriptor(), ExecStoreTuple(), GetInsertedColumns, gettext_noop, GetUpdatedColumns, tupleConstr::has_not_null, InvalidBuffer, NameStr, tupleDesc::natts, tupleConstr::num_check, RelationGetDescr, RelationGetRelationName, RelationGetRelid, ResultRelInfo::ri_PartitionCheck, ResultRelInfo::ri_PartitionRoot, ResultRelInfo::ri_RelationDesc, slot_attisnull(), and TupleDescAttr.

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

1944 {
1945  Relation rel = resultRelInfo->ri_RelationDesc;
1946  TupleDesc tupdesc = RelationGetDescr(rel);
1947  TupleConstr *constr = tupdesc->constr;
1948  Bitmapset *modifiedCols;
1949  Bitmapset *insertedCols;
1950  Bitmapset *updatedCols;
1951 
1952  Assert(constr || resultRelInfo->ri_PartitionCheck);
1953 
1954  if (constr && constr->has_not_null)
1955  {
1956  int natts = tupdesc->natts;
1957  int attrChk;
1958 
1959  for (attrChk = 1; attrChk <= natts; attrChk++)
1960  {
1961  Form_pg_attribute att = TupleDescAttr(tupdesc, attrChk - 1);
1962 
1963  if (att->attnotnull && slot_attisnull(slot, attrChk))
1964  {
1965  char *val_desc;
1966  Relation orig_rel = rel;
1967  TupleDesc orig_tupdesc = RelationGetDescr(rel);
1968 
1969  /*
1970  * If the tuple has been routed, it's been converted to the
1971  * partition's rowtype, which might differ from the root
1972  * table's. We must convert it back to the root table's
1973  * rowtype so that val_desc shown error message matches the
1974  * input tuple.
1975  */
1976  if (resultRelInfo->ri_PartitionRoot)
1977  {
1978  HeapTuple tuple = ExecFetchSlotTuple(slot);
1979  TupleConversionMap *map;
1980 
1981  rel = resultRelInfo->ri_PartitionRoot;
1982  tupdesc = RelationGetDescr(rel);
1983  /* a reverse map */
1984  map = convert_tuples_by_name(orig_tupdesc, tupdesc,
1985  gettext_noop("could not convert row type"));
1986  if (map != NULL)
1987  {
1988  tuple = do_convert_tuple(tuple, map);
1989  ExecSetSlotDescriptor(slot, tupdesc);
1990  ExecStoreTuple(tuple, slot, InvalidBuffer, false);
1991  }
1992  }
1993 
1994  insertedCols = GetInsertedColumns(resultRelInfo, estate);
1995  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
1996  modifiedCols = bms_union(insertedCols, updatedCols);
1998  slot,
1999  tupdesc,
2000  modifiedCols,
2001  64);
2002 
2003  ereport(ERROR,
2004  (errcode(ERRCODE_NOT_NULL_VIOLATION),
2005  errmsg("null value in column \"%s\" violates not-null constraint",
2006  NameStr(att->attname)),
2007  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
2008  errtablecol(orig_rel, attrChk)));
2009  }
2010  }
2011  }
2012 
2013  if (constr && constr->num_check > 0)
2014  {
2015  const char *failed;
2016 
2017  if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
2018  {
2019  char *val_desc;
2020  Relation orig_rel = rel;
2021 
2022  /* See the comment above. */
2023  if (resultRelInfo->ri_PartitionRoot)
2024  {
2025  HeapTuple tuple = ExecFetchSlotTuple(slot);
2026  TupleDesc old_tupdesc = RelationGetDescr(rel);
2027  TupleConversionMap *map;
2028 
2029  rel = resultRelInfo->ri_PartitionRoot;
2030  tupdesc = RelationGetDescr(rel);
2031  /* a reverse map */
2032  map = convert_tuples_by_name(old_tupdesc, tupdesc,
2033  gettext_noop("could not convert row type"));
2034  if (map != NULL)
2035  {
2036  tuple = do_convert_tuple(tuple, map);
2037  ExecSetSlotDescriptor(slot, tupdesc);
2038  ExecStoreTuple(tuple, slot, InvalidBuffer, false);
2039  }
2040  }
2041 
2042  insertedCols = GetInsertedColumns(resultRelInfo, estate);
2043  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
2044  modifiedCols = bms_union(insertedCols, updatedCols);
2046  slot,
2047  tupdesc,
2048  modifiedCols,
2049  64);
2050  ereport(ERROR,
2051  (errcode(ERRCODE_CHECK_VIOLATION),
2052  errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
2053  RelationGetRelationName(orig_rel), failed),
2054  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
2055  errtableconstraint(orig_rel, failed)));
2056  }
2057  }
2058 
2059  if (resultRelInfo->ri_PartitionCheck)
2060  ExecPartitionCheck(resultRelInfo, slot, estate);
2061 }
#define GetUpdatedColumns(relinfo, estate)
Definition: execMain.c:118
TupleTableSlot * ExecStoreTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
Definition: execTuples.c:320
Relation ri_RelationDesc
Definition: execnodes.h:354
#define RelationGetDescr(relation)
Definition: rel.h:428
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:84
Relation ri_PartitionRoot
Definition: execnodes.h:414
#define InvalidBuffer
Definition: buf.h:25
#define gettext_noop(x)
Definition: c.h:139
int errcode(int sqlerrcode)
Definition: elog.c:575
int natts
Definition: tupdesc.h:73
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5309
#define ERROR
Definition: elog.h:43
static char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
Definition: execMain.c:2221
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define RelationGetRelationName(relation)
Definition: rel.h:436
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define ereport(elevel, rest)
Definition: elog.h:122
bool has_not_null
Definition: tupdesc.h:43
TupleConversionMap * convert_tuples_by_name(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:210
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
List * ri_PartitionCheck
Definition: execnodes.h:408
static const char * ExecRelCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1793
bool slot_attisnull(TupleTableSlot *slot, int attnum)
Definition: heaptuple.c:1329
#define Assert(condition)
Definition: c.h:664
int errtablecol(Relation rel, int attnum)
Definition: relcache.c:5272
TupleConstr * constr
Definition: tupdesc.h:78
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:218
HeapTuple do_convert_tuple(HeapTuple tuple, TupleConversionMap *map)
Definition: tupconvert.c:354
HeapTuple ExecFetchSlotTuple(TupleTableSlot *slot)
Definition: execTuples.c:618
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:493
uint16 num_check
Definition: tupdesc.h:42
#define RelationGetRelid(relation)
Definition: rel.h:416
#define GetInsertedColumns(relinfo, estate)
Definition: execMain.c:116
static void ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1855
bool ExecContextForcesOids ( PlanState planstate,
bool hasoids 
)

Definition at line 1515 of file execMain.c.

References EState::es_result_relation_info, EState::es_top_eflags, EXEC_FLAG_WITH_OIDS, EXEC_FLAG_WITHOUT_OIDS, RelationData::rd_rel, ResultRelInfo::ri_RelationDesc, and PlanState::state.

Referenced by ExecAssignResultTypeFromTL(), ExecInitGather(), ExecInitGatherMerge(), and tlist_matches_tupdesc().

1516 {
1517  ResultRelInfo *ri = planstate->state->es_result_relation_info;
1518 
1519  if (ri != NULL)
1520  {
1521  Relation rel = ri->ri_RelationDesc;
1522 
1523  if (rel != NULL)
1524  {
1525  *hasoids = rel->rd_rel->relhasoids;
1526  return true;
1527  }
1528  }
1529 
1530  if (planstate->state->es_top_eflags & EXEC_FLAG_WITH_OIDS)
1531  {
1532  *hasoids = true;
1533  return true;
1534  }
1535  if (planstate->state->es_top_eflags & EXEC_FLAG_WITHOUT_OIDS)
1536  {
1537  *hasoids = false;
1538  return true;
1539  }
1540 
1541  return false;
1542 }
Relation ri_RelationDesc
Definition: execnodes.h:354
EState * state
Definition: execnodes.h:849
Form_pg_class rd_rel
Definition: rel.h:114
#define EXEC_FLAG_WITHOUT_OIDS
Definition: executor.h:64
#define EXEC_FLAG_WITH_OIDS
Definition: executor.h:63
int es_top_eflags
Definition: execnodes.h:480
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:443
bool execCurrentOf ( CurrentOfExpr cexpr,
ExprContext econtext,
Oid  table_oid,
ItemPointer  current_tid 
)

Definition at line 41 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_rowMarks, QueryDesc::estate, fetch_cursor_param_value(), get_rel_name(), GetPortalByName(), ItemPointerIsValid, lfirst, ExecRowMark::markType, PG_USED_FOR_ASSERTS_ONLY, QueryDesc::planstate, PORTAL_ONE_SELECT, PortalGetQueryDesc, PortalIsValid, ExecRowMark::relid, RowMarkRequiresRowShareLock, search_plan_tree(), SelfItemPointerAttributeNumber, slot_getattr(), ScanState::ss_ScanTupleSlot, PortalData::strategy, TableOidAttributeNumber, and TupIsNull.

Referenced by TidListEval().

45 {
46  char *cursor_name;
47  char *table_name;
48  Portal portal;
49  QueryDesc *queryDesc;
50 
51  /* Get the cursor name --- may have to look up a parameter reference */
52  if (cexpr->cursor_name)
53  cursor_name = cexpr->cursor_name;
54  else
55  cursor_name = fetch_cursor_param_value(econtext, cexpr->cursor_param);
56 
57  /* Fetch table name for possible use in error messages */
58  table_name = get_rel_name(table_oid);
59  if (table_name == NULL)
60  elog(ERROR, "cache lookup failed for relation %u", table_oid);
61 
62  /* Find the cursor's portal */
63  portal = GetPortalByName(cursor_name);
64  if (!PortalIsValid(portal))
65  ereport(ERROR,
66  (errcode(ERRCODE_UNDEFINED_CURSOR),
67  errmsg("cursor \"%s\" does not exist", cursor_name)));
68 
69  /*
70  * We have to watch out for non-SELECT queries as well as held cursors,
71  * both of which may have null queryDesc.
72  */
73  if (portal->strategy != PORTAL_ONE_SELECT)
74  ereport(ERROR,
75  (errcode(ERRCODE_INVALID_CURSOR_STATE),
76  errmsg("cursor \"%s\" is not a SELECT query",
77  cursor_name)));
78  queryDesc = PortalGetQueryDesc(portal);
79  if (queryDesc == NULL || queryDesc->estate == NULL)
80  ereport(ERROR,
81  (errcode(ERRCODE_INVALID_CURSOR_STATE),
82  errmsg("cursor \"%s\" is held from a previous transaction",
83  cursor_name)));
84 
85  /*
86  * We have two different strategies depending on whether the cursor uses
87  * FOR UPDATE/SHARE or not. The reason for supporting both is that the
88  * FOR UPDATE code is able to identify a target table in many cases where
89  * the other code can't, while the non-FOR-UPDATE case allows use of WHERE
90  * CURRENT OF with an insensitive cursor.
91  */
92  if (queryDesc->estate->es_rowMarks)
93  {
94  ExecRowMark *erm;
95  ListCell *lc;
96 
97  /*
98  * Here, the query must have exactly one FOR UPDATE/SHARE reference to
99  * the target table, and we dig the ctid info out of that.
100  */
101  erm = NULL;
102  foreach(lc, queryDesc->estate->es_rowMarks)
103  {
104  ExecRowMark *thiserm = (ExecRowMark *) lfirst(lc);
105 
106  if (!RowMarkRequiresRowShareLock(thiserm->markType))
107  continue; /* ignore non-FOR UPDATE/SHARE items */
108 
109  if (thiserm->relid == table_oid)
110  {
111  if (erm)
112  ereport(ERROR,
113  (errcode(ERRCODE_INVALID_CURSOR_STATE),
114  errmsg("cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"",
115  cursor_name, table_name)));
116  erm = thiserm;
117  }
118  }
119 
120  if (erm == NULL)
121  ereport(ERROR,
122  (errcode(ERRCODE_INVALID_CURSOR_STATE),
123  errmsg("cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"",
124  cursor_name, table_name)));
125 
126  /*
127  * The cursor must have a current result row: per the SQL spec, it's
128  * an error if not.
129  */
130  if (portal->atStart || portal->atEnd)
131  ereport(ERROR,
132  (errcode(ERRCODE_INVALID_CURSOR_STATE),
133  errmsg("cursor \"%s\" is not positioned on a row",
134  cursor_name)));
135 
136  /* Return the currently scanned TID, if there is one */
137  if (ItemPointerIsValid(&(erm->curCtid)))
138  {
139  *current_tid = erm->curCtid;
140  return true;
141  }
142 
143  /*
144  * This table didn't produce the cursor's current row; some other
145  * inheritance child of the same parent must have. Signal caller to
146  * do nothing on this table.
147  */
148  return false;
149  }
150  else
151  {
152  ScanState *scanstate;
153  bool lisnull;
154  Oid tuple_tableoid PG_USED_FOR_ASSERTS_ONLY;
155  ItemPointer tuple_tid;
156 
157  /*
158  * Without FOR UPDATE, we dig through the cursor's plan to find the
159  * scan node. Fail if it's not there or buried underneath
160  * aggregation.
161  */
162  scanstate = search_plan_tree(queryDesc->planstate, table_oid);
163  if (!scanstate)
164  ereport(ERROR,
165  (errcode(ERRCODE_INVALID_CURSOR_STATE),
166  errmsg("cursor \"%s\" is not a simply updatable scan of table \"%s\"",
167  cursor_name, table_name)));
168 
169  /*
170  * The cursor must have a current result row: per the SQL spec, it's
171  * an error if not. We test this at the top level, rather than at the
172  * scan node level, because in inheritance cases any one table scan
173  * could easily not be on a row. We want to return false, not raise
174  * error, if the passed-in table OID is for one of the inactive scans.
175  */
176  if (portal->atStart || portal->atEnd)
177  ereport(ERROR,
178  (errcode(ERRCODE_INVALID_CURSOR_STATE),
179  errmsg("cursor \"%s\" is not positioned on a row",
180  cursor_name)));
181 
182  /* Now OK to return false if we found an inactive scan */
183  if (TupIsNull(scanstate->ss_ScanTupleSlot))
184  return false;
185 
186  /* Use slot_getattr to catch any possible mistakes */
187  tuple_tableoid =
190  &lisnull));
191  Assert(!lisnull);
192  tuple_tid = (ItemPointer)
195  &lisnull));
196  Assert(!lisnull);
197 
198  Assert(tuple_tableoid == table_oid);
199 
200  *current_tid = *tuple_tid;
201 
202  return true;
203  }
204 }
#define ItemPointerIsValid(pointer)
Definition: itemptr.h:60
bool atEnd
Definition: portal.h:187
EState * estate
Definition: execdesc.h:48
Portal GetPortalByName(const char *name)
Definition: portalmem.c:129
#define DatumGetObjectId(X)
Definition: postgres.h:506
int errcode(int sqlerrcode)
Definition: elog.c:575
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1103
unsigned int Oid
Definition: postgres_ext.h:31
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:969
ItemPointerData * ItemPointer
Definition: itemptr.h:49
ItemPointerData curCtid
Definition: execnodes.h:543
#define ERROR
Definition: elog.h:43
PlanState * planstate
Definition: execdesc.h:49
#define TupIsNull(slot)
Definition: tuptable.h:138
#define TableOidAttributeNumber
Definition: sysattr.h:27
char * cursor_name
Definition: primnodes.h:1278
PortalStrategy strategy
Definition: portal.h:143
#define ereport(elevel, rest)
Definition: elog.h:122
#define PortalIsValid(p)
Definition: portal.h:199
static ScanState * search_plan_tree(PlanState *node, Oid table_oid)
Definition: execCurrent.c:254
#define Assert(condition)
Definition: c.h:664
#define lfirst(lc)
Definition: pg_list.h:106
RowMarkType markType
Definition: execnodes.h:539
List * es_rowMarks
Definition: execnodes.h:475
#define DatumGetPointer(X)
Definition: postgres.h:555
#define PortalGetQueryDesc(portal)
Definition: portal.h:204
bool atStart
Definition: portal.h:186
int errmsg(const char *fmt,...)
Definition: elog.c:797
static char * fetch_cursor_param_value(ExprContext *econtext, int paramId)
Definition: execCurrent.c:212
Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: heaptuple.c:1142
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
#define elog
Definition: elog.h:219
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:979
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1726
void ExecEndNode ( PlanState node)

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

524 {
525  /*
526  * do nothing when we get to the end of a leaf on tree.
527  */
528  if (node == NULL)
529  return;
530 
531  /*
532  * Make sure there's enough stack available. Need to check here, in
533  * addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not
534  * guaranteed that ExecProcNode() is reached for all nodes.
535  */
537 
538  if (node->chgParam != NULL)
539  {
540  bms_free(node->chgParam);
541  node->chgParam = NULL;
542  }
543 
544  switch (nodeTag(node))
545  {
546  /*
547  * control nodes
548  */
549  case T_ResultState:
550  ExecEndResult((ResultState *) node);
551  break;
552 
553  case T_ProjectSetState:
555  break;
556 
557  case T_ModifyTableState:
559  break;
560 
561  case T_AppendState:
562  ExecEndAppend((AppendState *) node);
563  break;
564 
565  case T_MergeAppendState:
567  break;
568 
571  break;
572 
573  case T_BitmapAndState:
575  break;
576 
577  case T_BitmapOrState:
578  ExecEndBitmapOr((BitmapOrState *) node);
579  break;
580 
581  /*
582  * scan nodes
583  */
584  case T_SeqScanState:
585  ExecEndSeqScan((SeqScanState *) node);
586  break;
587 
588  case T_SampleScanState:
590  break;
591 
592  case T_GatherState:
593  ExecEndGather((GatherState *) node);
594  break;
595 
596  case T_GatherMergeState:
598  break;
599 
600  case T_IndexScanState:
602  break;
603 
606  break;
607 
610  break;
611 
614  break;
615 
616  case T_TidScanState:
617  ExecEndTidScan((TidScanState *) node);
618  break;
619 
620  case T_SubqueryScanState:
622  break;
623 
624  case T_FunctionScanState:
626  break;
627 
630  break;
631 
632  case T_ValuesScanState:
634  break;
635 
636  case T_CteScanState:
637  ExecEndCteScan((CteScanState *) node);
638  break;
639 
642  break;
643 
646  break;
647 
648  case T_ForeignScanState:
650  break;
651 
652  case T_CustomScanState:
654  break;
655 
656  /*
657  * join nodes
658  */
659  case T_NestLoopState:
660  ExecEndNestLoop((NestLoopState *) node);
661  break;
662 
663  case T_MergeJoinState:
665  break;
666 
667  case T_HashJoinState:
668  ExecEndHashJoin((HashJoinState *) node);
669  break;
670 
671  /*
672  * materialization nodes
673  */
674  case T_MaterialState:
675  ExecEndMaterial((MaterialState *) node);
676  break;
677 
678  case T_SortState:
679  ExecEndSort((SortState *) node);
680  break;
681 
682  case T_GroupState:
683  ExecEndGroup((GroupState *) node);
684  break;
685 
686  case T_AggState:
687  ExecEndAgg((AggState *) node);
688  break;
689 
690  case T_WindowAggState:
692  break;
693 
694  case T_UniqueState:
695  ExecEndUnique((UniqueState *) node);
696  break;
697 
698  case T_HashState:
699  ExecEndHash((HashState *) node);
700  break;
701 
702  case T_SetOpState:
703  ExecEndSetOp((SetOpState *) node);
704  break;
705 
706  case T_LockRowsState:
707  ExecEndLockRows((LockRowsState *) node);
708  break;
709 
710  case T_LimitState:
711  ExecEndLimit((LimitState *) node);
712  break;
713 
714  default:
715  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
716  break;
717  }
718 }
void ExecEndGroup(GroupState *node)
Definition: nodeGroup.c:231
void ExecEndSetOp(SetOpState *node)
Definition: nodeSetOp.c:582
void ExecEndFunctionScan(FunctionScanState *node)
void ExecEndNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:366
void ExecEndIndexScan(IndexScanState *node)
void ExecEndLimit(LimitState *node)
Definition: nodeLimit.c:393
void ExecEndUnique(UniqueState *node)
Definition: nodeUnique.c:178
void ExecEndGatherMerge(GatherMergeState *node)
void ExecEndWorkTableScan(WorkTableScanState *node)
void ExecEndLockRows(LockRowsState *node)
Definition: nodeLockRows.c:451
void ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node)
void ExecEndBitmapAnd(BitmapAndState *node)
void ExecEndRecursiveUnion(RecursiveUnionState *node)
void ExecEndSubqueryScan(SubqueryScanState *node)
void ExecEndHashJoin(HashJoinState *node)
Definition: nodeHashjoin.c:551
void ExecEndTableFuncScan(TableFuncScanState *node)
void ExecEndResult(ResultState *node)
Definition: nodeResult.c:246
#define ERROR
Definition: elog.h:43
void ExecEndAppend(AppendState *node)
Definition: nodeAppend.c:259
void ExecEndForeignScan(ForeignScanState *node)
void ExecEndSort(SortState *node)
Definition: nodeSort.c:238
void ExecEndBitmapIndexScan(BitmapIndexScanState *node)
void check_stack_depth(void)
Definition: postgres.c:3144
void ExecEndValuesScan(ValuesScanState *node)
void ExecEndMergeJoin(MergeJoinState *node)
void ExecEndSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:225
void ExecEndIndexOnlyScan(IndexOnlyScanState *node)
void ExecEndTidScan(TidScanState *node)
Definition: nodeTidscan.c:482
Bitmapset * chgParam
Definition: execnodes.h:875
void ExecEndCteScan(CteScanState *node)
Definition: nodeCtescan.c:280
void ExecEndCustomScan(CustomScanState *node)
Definition: nodeCustom.c:122
void ExecEndBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:196
void ExecEndSampleScan(SampleScanState *node)
void bms_free(Bitmapset *a)
Definition: bitmapset.c:201
void ExecEndWindowAgg(WindowAggState *node)
void ExecEndMergeAppend(MergeAppendState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:514
void ExecEndHash(HashState *node)
Definition: nodeHash.c:219
void ExecEndProjectSet(ProjectSetState *node)
void ExecEndMaterial(MaterialState *node)
Definition: nodeMaterial.c:244
#define elog
Definition: elog.h:219
void ExecEndBitmapHeapScan(BitmapHeapScanState *node)
void ExecEndAgg(AggState *node)
Definition: nodeAgg.c:3850
void ExecEndModifyTable(ModifyTableState *node)
void ExecEndGather(GatherState *node)
Definition: nodeGather.c:234
static Datum ExecEvalExprSwitchContext ( ExprState state,
ExprContext econtext,
bool isNull 
)
inlinestatic

Definition at line 301 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(), ExecWindowAgg(), FormIndexDatum(), FormPartitionKeyDatum(), get_qual_for_range(), operator_predicate_proof(), recompute_limits(), tablesample_init(), TidListEval(), and validateDomainConstraint().

304 {
305  Datum retDatum;
306  MemoryContext oldContext;
307 
308  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
309  retDatum = state->evalfunc(state, econtext, isNull);
310  MemoryContextSwitchTo(oldContext);
311  return retDatum;
312 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:203
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ExprStateEvalFunc evalfunc
Definition: execnodes.h:80
uintptr_t Datum
Definition: postgres.h:372
TupleTableSlot* ExecFilterJunk ( JunkFilter junkfilter,
TupleTableSlot slot 
)

Definition at line 262 of file execJunk.c.

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

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

263 {
264  TupleTableSlot *resultSlot;
265  AttrNumber *cleanMap;
266  TupleDesc cleanTupType;
267  int cleanLength;
268  int i;
269  Datum *values;
270  bool *isnull;
271  Datum *old_values;
272  bool *old_isnull;
273 
274  /*
275  * Extract all the values of the old tuple.
276  */
277  slot_getallattrs(slot);
278  old_values = slot->tts_values;
279  old_isnull = slot->tts_isnull;
280 
281  /*
282  * get info from the junk filter
283  */
284  cleanTupType = junkfilter->jf_cleanTupType;
285  cleanLength = cleanTupType->natts;
286  cleanMap = junkfilter->jf_cleanMap;
287  resultSlot = junkfilter->jf_resultSlot;
288 
289  /*
290  * Prepare to build a virtual result tuple.
291  */
292  ExecClearTuple(resultSlot);
293  values = resultSlot->tts_values;
294  isnull = resultSlot->tts_isnull;
295 
296  /*
297  * Transpose data into proper fields of the new tuple.
298  */
299  for (i = 0; i < cleanLength; i++)
300  {
301  int j = cleanMap[i];
302 
303  if (j == 0)
304  {
305  values[i] = (Datum) 0;
306  isnull[i] = true;
307  }
308  else
309  {
310  values[i] = old_values[j - 1];
311  isnull[i] = old_isnull[j - 1];
312  }
313  }
314 
315  /*
316  * And return the virtual tuple.
317  */
318  return ExecStoreVirtualTuple(resultSlot);
319 }
AttrNumber * jf_cleanMap
Definition: execnodes.h:334
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
TupleTableSlot * jf_resultSlot
Definition: execnodes.h:335
Datum * tts_values
Definition: tuptable.h:125
int natts
Definition: tupdesc.h:73
bool * tts_isnull
Definition: tuptable.h:126
TupleDesc jf_cleanTupType
Definition: execnodes.h:333
void slot_getallattrs(TupleTableSlot *slot)
Definition: heaptuple.c:1238
uintptr_t Datum
Definition: postgres.h:372
static Datum values[MAXATTR]
Definition: bootstrap.c:164
int i
int16 AttrNumber
Definition: attnum.h:21
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:488
AttrNumber ExecFindJunkAttribute ( JunkFilter junkfilter,
const char *  attrName 
)

Definition at line 209 of file execJunk.c.

References ExecFindJunkAttributeInTlist(), and JunkFilter::jf_targetList.

Referenced by ExecInitModifyTable().

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

Definition at line 221 of file execJunk.c.

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

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

222 {
223  ListCell *t;
224 
225  foreach(t, targetlist)
226  {
227  TargetEntry *tle = lfirst(t);
228 
229  if (tle->resjunk && tle->resname &&
230  (strcmp(tle->resname, attrName) == 0))
231  {
232  /* We found it ! */
233  return tle->resno;
234  }
235  }
236 
237  return InvalidAttrNumber;
238 }
char * resname
Definition: primnodes.h:1370
bool resjunk
Definition: primnodes.h:1375
AttrNumber resno
Definition: primnodes.h:1369
#define lfirst(lc)
Definition: pg_list.h:106
#define InvalidAttrNumber
Definition: attnum.h:23
int ExecFindPartition ( ResultRelInfo resultRelInfo,
PartitionDispatch pd,
TupleTableSlot slot,
EState estate 
)

Definition at line 3365 of file execMain.c.

References Assert, ExprContext::ecxt_scantuple, ereport, errcode(), errdetail(), errmsg(), ERROR, ExecBuildSlotPartitionKeyDescription(), ExecPartitionCheck(), FormPartitionKeyDatum(), get_partition_for_tuple(), GetPerTupleExprContext, OidIsValid, PARTITION_MAX_KEYS, RelationGetRelationName, RelationGetRelid, PartitionDispatchData::reldesc, and ResultRelInfo::ri_PartitionCheck.

Referenced by CopyFrom(), and ExecInsert().

3367 {
3368  int result;
3369  PartitionDispatchData *failed_at;
3370  TupleTableSlot *failed_slot;
3371 
3372  /*
3373  * First check the root table's partition constraint, if any. No point in
3374  * routing the tuple if it doesn't belong in the root table itself.
3375  */
3376  if (resultRelInfo->ri_PartitionCheck)
3377  ExecPartitionCheck(resultRelInfo, slot, estate);
3378 
3379  result = get_partition_for_tuple(pd, slot, estate,
3380  &failed_at, &failed_slot);
3381  if (result < 0)
3382  {
3383  Relation failed_rel;
3384  Datum key_values[PARTITION_MAX_KEYS];
3385  bool key_isnull[PARTITION_MAX_KEYS];
3386  char *val_desc;
3387  ExprContext *ecxt = GetPerTupleExprContext(estate);
3388 
3389  failed_rel = failed_at->reldesc;
3390  ecxt->ecxt_scantuple = failed_slot;
3391  FormPartitionKeyDatum(failed_at, failed_slot, estate,
3392  key_values, key_isnull);
3393  val_desc = ExecBuildSlotPartitionKeyDescription(failed_rel,
3394  key_values,
3395  key_isnull,
3396  64);
3397  Assert(OidIsValid(RelationGetRelid(failed_rel)));
3398  ereport(ERROR,
3399  (errcode(ERRCODE_CHECK_VIOLATION),
3400  errmsg("no partition of relation \"%s\" found for row",
3401  RelationGetRelationName(failed_rel)),
3402  val_desc ? errdetail("Partition key of the failing row contains %s.", val_desc) : 0));
3403  }
3404 
3405  return result;
3406 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PARTITION_MAX_KEYS
int get_partition_for_tuple(PartitionDispatch *pd, TupleTableSlot *slot, EState *estate, PartitionDispatchData **failed_at, TupleTableSlot **failed_slot)
Definition: partition.c:2273
#define OidIsValid(objectId)
Definition: c.h:532
#define GetPerTupleExprContext(estate)
Definition: executor.h:476
#define ERROR
Definition: elog.h:43
static char * ExecBuildSlotPartitionKeyDescription(Relation rel, Datum *values, bool *isnull, int maxfieldlen)
Definition: execMain.c:3416
void FormPartitionKeyDatum(PartitionDispatch pd, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
Definition: partition.c:2214
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define RelationGetRelationName(relation)
Definition: rel.h:436
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:372
List * ri_PartitionCheck
Definition: execnodes.h:408
#define Assert(condition)
Definition: c.h:664
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:197
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RelationGetRelid(relation)
Definition: rel.h:416
static void ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1855
ExecRowMark* ExecFindRowMark ( EState estate,
Index  rti,
bool  missing_ok 
)

Definition at line 2384 of file execMain.c.

References elog, ERROR, EState::es_rowMarks, lfirst, and ExecRowMark::rti.

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

2385 {
2386  ListCell *lc;
2387 
2388  foreach(lc, estate->es_rowMarks)
2389  {
2390  ExecRowMark *erm = (ExecRowMark *) lfirst(lc);
2391 
2392  if (erm->rti == rti)
2393  return erm;
2394  }
2395  if (!missing_ok)
2396  elog(ERROR, "failed to find ExecRowMark for rangetable index %u", rti);
2397  return NULL;
2398 }
#define ERROR
Definition: elog.h:43
Index rti
Definition: execnodes.h:536
#define lfirst(lc)
Definition: pg_list.h:106
List * es_rowMarks
Definition: execnodes.h:475
#define elog
Definition: elog.h:219
Datum ExecGetJunkAttribute ( TupleTableSlot slot,
AttrNumber  attno,
bool isNull 
)

Definition at line 248 of file execJunk.c.

References Assert, and slot_getattr().

Referenced by EvalPlanQualFetchRowMarks(), ExecLockRows(), ExecModifyTable(), postgresExecForeignDelete(), and postgresExecForeignUpdate().

250 {
251  Assert(attno > 0);
252 
253  return slot_getattr(slot, attno, isNull);
254 }
#define Assert(condition)
Definition: c.h:664
Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: heaptuple.c:1142
ResultRelInfo* ExecGetTriggerResultRel ( EState estate,
Oid  relid 
)

Definition at line 1390 of file execMain.c.

References EState::es_instrument, EState::es_leaf_result_relations, 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, heap_open(), InitResultRelInfo(), lappend(), lfirst, makeNode, MemoryContextSwitchTo(), NoLock, RelationGetRelid, and ResultRelInfo::ri_RelationDesc.

Referenced by afterTriggerInvokeEvents().

1391 {
1392  ResultRelInfo *rInfo;
1393  int nr;
1394  ListCell *l;
1395  Relation rel;
1396  MemoryContext oldcontext;
1397 
1398  /* First, search through the query result relations */
1399  rInfo = estate->es_result_relations;
1400  nr = estate->es_num_result_relations;
1401  while (nr > 0)
1402  {
1403  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1404  return rInfo;
1405  rInfo++;
1406  nr--;
1407  }
1408  /* Second, search through the root result relations, if any */
1409  rInfo = estate->es_root_result_relations;
1410  nr = estate->es_num_root_result_relations;
1411  while (nr > 0)
1412  {
1413  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1414  return rInfo;
1415  rInfo++;
1416  nr--;
1417  }
1418  /* Third, search through the leaf result relations, if any */
1419  foreach(l, estate->es_leaf_result_relations)
1420  {
1421  rInfo = (ResultRelInfo *) lfirst(l);
1422  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1423  return rInfo;
1424  }
1425  /* Nope, but maybe we already made an extra ResultRelInfo for it */
1426  foreach(l, estate->es_trig_target_relations)
1427  {
1428  rInfo = (ResultRelInfo *) lfirst(l);
1429  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1430  return rInfo;
1431  }
1432  /* Nope, so we need a new one */
1433 
1434  /*
1435  * Open the target relation's relcache entry. We assume that an
1436  * appropriate lock is still held by the backend from whenever the trigger
1437  * event got queued, so we need take no new lock here. Also, we need not
1438  * recheck the relkind, so no need for CheckValidResultRel.
1439  */
1440  rel = heap_open(relid, NoLock);
1441 
1442  /*
1443  * Make the new entry in the right context.
1444  */
1445  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1446  rInfo = makeNode(ResultRelInfo);
1447  InitResultRelInfo(rInfo,
1448  rel,
1449  0, /* dummy rangetable index */
1450  NULL,
1451  estate->es_instrument);
1452  estate->es_trig_target_relations =
1453  lappend(estate->es_trig_target_relations, rInfo);
1454  MemoryContextSwitchTo(oldcontext);
1455 
1456  /*
1457  * Currently, we don't need any index information in ResultRelInfos used
1458  * only for triggers, so no need to call ExecOpenIndices.
1459  */
1460 
1461  return rInfo;
1462 }
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, Relation partition_root, int instrument_options)
Definition: execMain.c:1308
Relation ri_RelationDesc
Definition: execnodes.h:354
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:471
#define NoLock
Definition: lockdefs.h:34
ResultRelInfo * es_result_relations
Definition: execnodes.h:441
int es_instrument
Definition: execnodes.h:481
List * es_leaf_result_relations
Definition: execnodes.h:456
List * lappend(List *list, void *datum)
Definition: list.c:128
int es_num_root_result_relations
Definition: execnodes.h:453
List * es_trig_target_relations
Definition: execnodes.h:459
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
int es_num_result_relations
Definition: execnodes.h:442
#define makeNode(_type_)
Definition: nodes.h:557
#define lfirst(lc)
Definition: pg_list.h:106
ResultRelInfo * es_root_result_relations
Definition: execnodes.h:452
#define RelationGetRelid(relation)
Definition: rel.h:416
ExprState* ExecInitCheck ( List qual,
PlanState parent 
)

Definition at line 246 of file execExpr.c.

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

Referenced by ExecPrepareCheck().

247 {
248  /* short-circuit (here and in ExecCheck) for empty restriction list */
249  if (qual == NIL)
250  return NULL;
251 
252  Assert(IsA(qual, List));
253 
254  /*
255  * Just convert the implicit-AND list to an explicit AND (if there's more
256  * than one entry), and compile normally. Unlike ExecQual, we can't
257  * short-circuit on NULL results, so the regular AND behavior is needed.
258  */
259  return ExecInitExpr(make_ands_explicit(qual), parent);
260 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Expr * make_ands_explicit(List *andclauses)
Definition: clauses.c:367
#define Assert(condition)
Definition: c.h:664
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execExpr.c:113
Definition: pg_list.h:45
ExprState* ExecInitExpr ( Expr node,
PlanState parent 
)

Definition at line 113 of file execExpr.c.

References EEOP_DONE, ExecInitExprRec(), ExecInitExprSlots(), ExecReadyExpr(), ExprState::expr, ExprEvalPushStep(), makeNode, ExprEvalStep::opcode, ExprState::resnull, and ExprState::resvalue.

Referenced by ATRewriteTable(), BeginCopyFrom(), build_pertrans_for_aggref(), evaluate_expr(), exec_eval_simple_expr(), ExecIndexBuildScanKeys(), ExecInitCheck(), ExecInitExprList(), ExecInitExprRec(), ExecInitHashJoin(), ExecInitLimit(), ExecInitProjectSet(), ExecInitSampleScan(), ExecInitSubPlan(), ExecInitTableFuncScan(), ExecInitTableFunctionResult(), ExecInitWindowAgg(), ExecPrepareExpr(), get_cast_hashentry(), get_qual_for_range(), MJExamineQuals(), operator_predicate_proof(), prep_domain_constraints(), slot_fill_defaults(), and TidExprListCreate().

114 {
115  ExprState *state;
116  ExprEvalStep scratch;
117 
118  /* Special case: NULL expression produces a NULL ExprState pointer */
119  if (node == NULL)
120  return NULL;
121 
122  /* Initialize ExprState with empty step list */
123  state = makeNode(ExprState);
124  state->expr = node;
125 
126  /* Insert EEOP_*_FETCHSOME steps as needed */
127  ExecInitExprSlots(state, (Node *) node);
128 
129  /* Compile the expression proper */
130  ExecInitExprRec(node, parent, state, &state->resvalue, &state->resnull);
131 
132  /* Finally, append a DONE step */
133  scratch.opcode = EEOP_DONE;
134  ExprEvalPushStep(state, &scratch);
135 
136  ExecReadyExpr(state);
137 
138  return state;
139 }
Definition: nodes.h:509
bool resnull
Definition: execnodes.h:63
Expr * expr
Definition: execnodes.h:83
static void ExecInitExprSlots(ExprState *state, Node *node)
Definition: execExpr.c:2171
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:574
#define makeNode(_type_)
Definition: nodes.h:557
Definition: regguts.h:298
intptr_t opcode
Definition: execExpr.h:227
static void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2042
static void ExecInitExprRec(Expr *node, PlanState *parent, ExprState *state, Datum *resv, bool *resnull)
Definition: execExpr.c:589
Datum resvalue
Definition: execnodes.h:64
List* ExecInitExprList ( List nodes,
PlanState parent 
)

Definition at line 266 of file execExpr.c.

References ExecInitExpr(), lappend(), lfirst, and NIL.

Referenced by build_pertrans_for_aggref(), ExecInitExprRec(), ExecInitFunctionResultSet(), ExecInitIndexScan(), ExecInitSampleScan(), ExecInitSubPlan(), ExecInitTableFuncScan(), ExecInitTableFunctionResult(), prepare_query_params(), and ValuesNext().

267 {
268  List *result = NIL;
269  ListCell *lc;
270 
271  foreach(lc, nodes)
272  {
273  Expr *e = lfirst(lc);
274 
275  result = lappend(result, ExecInitExpr(e, parent));
276  }
277 
278  return result;
279 }
#define NIL
Definition: pg_list.h:69
List * lappend(List *list, void *datum)
Definition: list.c:128
#define lfirst(lc)
Definition: pg_list.h:106
e
Definition: preproc-init.c:82
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition: execExpr.c:113
Definition: pg_list.h:45
SetExprState* ExecInitFunctionResultSet ( Expr expr,
ExprContext econtext,
PlanState parent 
)

Definition at line 424 of file execSRF.c.

References FuncExpr::args, OpExpr::args, SetExprState::args, Assert, ExprContext::ecxt_per_query_memory, elog, ERROR, ExecInitExprList(), SetExprState::expr, FmgrInfo::fn_oid, FmgrInfo::fn_retset, SetExprState::func, FuncExpr::funcid, SetExprState::funcReturnsSet, init_sexpr(), FuncExpr::inputcollid, OpExpr::inputcollid, InvalidOid, IsA, makeNode, nodeTag, and OpExpr::opfuncid.

Referenced by ExecInitProjectSet().

426 {
428 
429  state->funcReturnsSet = true;
430  state->expr = expr;
431  state->func.fn_oid = InvalidOid;
432 
433  /*
434  * Initialize metadata. The expression node could be either a FuncExpr or
435  * an OpExpr.
436  */
437  if (IsA(expr, FuncExpr))
438  {
439  FuncExpr *func = (FuncExpr *) expr;
440 
441  state->args = ExecInitExprList(func->args, parent);
442  init_sexpr(func->funcid, func->inputcollid, expr, state, parent,
443  econtext->ecxt_per_query_memory, true, true);
444  }
445  else if (IsA(expr, OpExpr))
446  {
447  OpExpr *op = (OpExpr *) expr;
448 
449  state->args = ExecInitExprList(op->args, parent);
450  init_sexpr(op->opfuncid, op->inputcollid, expr, state, parent,
451  econtext->ecxt_per_query_memory, true, true);
452  }
453  else
454  elog(ERROR, "unrecognized node type: %d",
455  (int) nodeTag(expr));
456 
457  /* shouldn't get here unless the selected function returns set */
458  Assert(state->func.fn_retset);
459 
460  return state;
461 }
FmgrInfo func
Definition: execnodes.h:702
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
List * args
Definition: primnodes.h:457
List * args
Definition: execnodes.h:688
static void init_sexpr(Oid foid, Oid input_collation, Expr *node, SetExprState *sexpr, PlanState *parent, MemoryContext sexprCxt, bool allowSRF, bool needDescForSRF)
Definition: execSRF.c:649
bool fn_retset
Definition: fmgr.h:62
Oid funcid
Definition: primnodes.h:449
#define ERROR
Definition: elog.h:43
bool funcReturnsSet
Definition: execnodes.h:723
List * ExecInitExprList(List *nodes, PlanState *parent)
Definition: execExpr.c:266
Oid opfuncid
Definition: primnodes.h:497
Expr * expr
Definition: execnodes.h:687
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:59
#define makeNode(_type_)
Definition: nodes.h:557
Oid inputcollid
Definition: primnodes.h:456
#define Assert(condition)
Definition: c.h:664
Definition: regguts.h:298
Oid inputcollid
Definition: primnodes.h:501
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:202
#define nodeTag(nodeptr)
Definition: nodes.h:514
#define elog
Definition: elog.h:219
List * args
Definition: primnodes.h:502
JunkFilter* ExecInitJunkFilter ( List targetList,
bool  hasoid,
TupleTableSlot slot 
)

Definition at line 61 of file execJunk.c.

References ExecCleanTypeFromTL(), ExecSetSlotDescriptor(), JunkFilter::jf_cleanMap, JunkFilter::jf_cleanTupType, JunkFilter::jf_resultSlot, JunkFilter::jf_targetList, lfirst, makeNode, MakeSingleTupleTableSlot(), tupleDesc::natts, palloc(), TargetEntry::resjunk, and TargetEntry::resno.

Referenced by check_sql_fn_retval(), ExecInitModifyTable(), ExecInitWholeRowVar(), and InitPlan().

62 {
63  JunkFilter *junkfilter;
64  TupleDesc cleanTupType;
65  int cleanLength;
66  AttrNumber *cleanMap;
67  ListCell *t;
68  AttrNumber cleanResno;
69 
70  /*
71  * Compute the tuple descriptor for the cleaned tuple.
72  */
73  cleanTupType = ExecCleanTypeFromTL(targetList, hasoid);
74 
75  /*
76  * Use the given slot, or make a new slot if we weren't given one.
77  */
78  if (slot)
79  ExecSetSlotDescriptor(slot, cleanTupType);
80  else
81  slot = MakeSingleTupleTableSlot(cleanTupType);
82 
83  /*
84  * Now calculate the mapping between the original tuple's attributes and
85  * the "clean" tuple's attributes.
86  *
87  * The "map" is an array of "cleanLength" attribute numbers, i.e. one
88  * entry for every attribute of the "clean" tuple. The value of this entry
89  * is the attribute number of the corresponding attribute of the
90  * "original" tuple. (Zero indicates a NULL output attribute, but we do
91  * not use that feature in this routine.)
92  */
93  cleanLength = cleanTupType->natts;
94  if (cleanLength > 0)
95  {
96  cleanMap = (AttrNumber *) palloc(cleanLength * sizeof(AttrNumber));
97  cleanResno = 1;
98  foreach(t, targetList)
99  {
100  TargetEntry *tle = lfirst(t);
101 
102  if (!tle->resjunk)
103  {
104  cleanMap[cleanResno - 1] = tle->resno;