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 (Relation resultRel, CmdType operation)
 
void InitResultRelInfo (ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, Relation partition_root, int instrument_options)
 
ResultRelInfoExecGetTriggerResultRel (EState *estate, Oid relid)
 
bool ExecContextForcesOids (PlanState *planstate, bool *hasoids)
 
void ExecConstraints (ResultRelInfo *resultRelInfo, TupleTableSlot *slot, TupleTableSlot *orig_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, 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)
 
TupleTableSlotExecProcNode (PlanState *node)
 
NodeMultiExecProcNode (PlanState *node)
 
void ExecEndNode (PlanState *node)
 
bool ExecShutdownNode (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)
 
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)
 

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:950
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:1250

Definition at line 429 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:450

Definition at line 465 of file executor.h.

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

Typedef Documentation

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

Definition at line 389 of file executor.h.

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

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

1233 {
1234  TupOutputState *tstate;
1235 
1236  tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
1237 
1238  tstate->slot = MakeSingleTupleTableSlot(tupdesc);
1239  tstate->dest = dest;
1240 
1241  (*tstate->dest->rStartup) (tstate->dest, (int) CMD_SELECT, tupdesc);
1242 
1243  return tstate;
1244 }
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:121
TupleTableSlot * slot
Definition: executor.h:414
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:199
void * palloc(Size size)
Definition: mcxt.c:849
DestReceiver * dest
Definition: executor.h:415
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, NULL, 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:579
#define Min(x, y)
Definition: c.h:806
AttrNumber * keyColIdx
Definition: execnodes.h:571
FmgrInfo * tab_hash_funcs
Definition: execnodes.h:572
FmgrInfo * in_hash_funcs
Definition: execnodes.h:580
struct TupleHashEntryData TupleHashEntryData
MemoryContext tablecxt
Definition: execnodes.h:574
struct TupleHashTableData * TupleHashTable
Definition: execnodes.h:549
int ParallelWorkerNumber
Definition: parallel.c:96
Datum hash_uint32(uint32 k)
Definition: hashfunc.c:512
int work_mem
Definition: globals.c:112
tuplehash_hash * hashtab
Definition: execnodes.h:569
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
TupleTableSlot * tableslot
Definition: execnodes.h:577
size_t Size
Definition: c.h:356
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:707
FmgrInfo * cur_eq_funcs
Definition: execnodes.h:581
MemoryContext tempcxt
Definition: execnodes.h:575
FmgrInfo * tab_eq_funcs
Definition: execnodes.h:573
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, check_exclusion_or_unique_constraint(), and NULL.

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
#define NULL
Definition: c.h:229
static Datum values[MAXATTR]
Definition: bootstrap.c:162
void CheckCmdReplicaIdentity ( Relation  rel,
CmdType  cmd 
)

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

523 {
524  PublicationActions *pubactions;
525 
526  /* We only need to do checks for UPDATE and DELETE. */
527  if (cmd != CMD_UPDATE && cmd != CMD_DELETE)
528  return;
529 
530  /* If relation has replica identity we are always good. */
531  if (rel->rd_rel->relreplident == REPLICA_IDENTITY_FULL ||
533  return;
534 
535  /*
536  * This is either UPDATE OR DELETE and there is no replica identity.
537  *
538  * Check if the table publishes UPDATES or DELETES.
539  */
540  pubactions = GetRelationPublicationActions(rel);
541  if (cmd == CMD_UPDATE && pubactions->pubupdate)
542  ereport(ERROR,
543  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
544  errmsg("cannot update table \"%s\" because it does not have replica identity and publishes updates",
546  errhint("To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.")));
547  else if (cmd == CMD_DELETE && pubactions->pubdelete)
548  ereport(ERROR,
549  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
550  errmsg("cannot delete from table \"%s\" because it does not have replica identity and publishes deletes",
552  errhint("To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE.")));
553 }
int errhint(const char *fmt,...)
Definition: elog.c:987
Oid RelationGetReplicaIndex(Relation relation)
Definition: relcache.c:4665
int errcode(int sqlerrcode)
Definition: elog.c:575
Form_pg_class rd_rel
Definition: rel.h:114
#define OidIsValid(objectId)
Definition: c.h:538
#define REPLICA_IDENTITY_FULL
Definition: pg_class.h:179
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:437
#define ereport(elevel, rest)
Definition: elog.h:122
struct PublicationActions * GetRelationPublicationActions(Relation relation)
Definition: relcache.c:5161
int errmsg(const char *fmt,...)
Definition: elog.c:797
void CheckValidResultRel ( Relation  resultRel,
CmdType  operation 
)

Definition at line 1055 of file execMain.c.

References CheckCmdReplicaIdentity(), CMD_DELETE, CMD_INSERT, CMD_UPDATE, elog, ereport, errcode(), errhint(), errmsg(), ERROR, FdwRoutine::ExecForeignDelete, FdwRoutine::ExecForeignInsert, FdwRoutine::ExecForeignUpdate, GetFdwRoutineForRelation(), FdwRoutine::IsForeignRelUpdatable, MatViewIncrementalMaintenanceIsEnabled(), NULL, RelationData::rd_rel, RelationGetRelationName, RELKIND_FOREIGN_TABLE, RELKIND_MATVIEW, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_TOASTVALUE, RELKIND_VIEW, TriggerDesc::trig_delete_instead_row, TriggerDesc::trig_insert_instead_row, TriggerDesc::trig_update_instead_row, and RelationData::trigdesc.

Referenced by ExecInitModifyTable(), and ExecSetupPartitionTupleRouting().

1056 {
1057  TriggerDesc *trigDesc = resultRel->trigdesc;
1058  FdwRoutine *fdwroutine;
1059 
1060  switch (resultRel->rd_rel->relkind)
1061  {
1062  case RELKIND_RELATION:
1064  CheckCmdReplicaIdentity(resultRel, operation);
1065  break;
1066  case RELKIND_SEQUENCE:
1067  ereport(ERROR,
1068  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1069  errmsg("cannot change sequence \"%s\"",
1070  RelationGetRelationName(resultRel))));
1071  break;
1072  case RELKIND_TOASTVALUE:
1073  ereport(ERROR,
1074  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1075  errmsg("cannot change TOAST relation \"%s\"",
1076  RelationGetRelationName(resultRel))));
1077  break;
1078  case RELKIND_VIEW:
1079 
1080  /*
1081  * Okay only if there's a suitable INSTEAD OF trigger. Messages
1082  * here should match rewriteHandler.c's rewriteTargetView, except
1083  * that we omit errdetail because we haven't got the information
1084  * handy (and given that we really shouldn't get here anyway, it's
1085  * not worth great exertion to get).
1086  */
1087  switch (operation)
1088  {
1089  case CMD_INSERT:
1090  if (!trigDesc || !trigDesc->trig_insert_instead_row)
1091  ereport(ERROR,
1092  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1093  errmsg("cannot insert into view \"%s\"",
1094  RelationGetRelationName(resultRel)),
1095  errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule.")));
1096  break;
1097  case CMD_UPDATE:
1098  if (!trigDesc || !trigDesc->trig_update_instead_row)
1099  ereport(ERROR,
1100  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1101  errmsg("cannot update view \"%s\"",
1102  RelationGetRelationName(resultRel)),
1103  errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.")));
1104  break;
1105  case CMD_DELETE:
1106  if (!trigDesc || !trigDesc->trig_delete_instead_row)
1107  ereport(ERROR,
1108  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1109  errmsg("cannot delete from view \"%s\"",
1110  RelationGetRelationName(resultRel)),
1111  errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule.")));
1112  break;
1113  default:
1114  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1115  break;
1116  }
1117  break;
1118  case RELKIND_MATVIEW:
1120  ereport(ERROR,
1121  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1122  errmsg("cannot change materialized view \"%s\"",
1123  RelationGetRelationName(resultRel))));
1124  break;
1125  case RELKIND_FOREIGN_TABLE:
1126  /* Okay only if the FDW supports it */
1127  fdwroutine = GetFdwRoutineForRelation(resultRel, false);
1128  switch (operation)
1129  {
1130  case CMD_INSERT:
1131  if (fdwroutine->ExecForeignInsert == NULL)
1132  ereport(ERROR,
1133  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1134  errmsg("cannot insert into foreign table \"%s\"",
1135  RelationGetRelationName(resultRel))));
1136  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1137  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_INSERT)) == 0)
1138  ereport(ERROR,
1139  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1140  errmsg("foreign table \"%s\" does not allow inserts",
1141  RelationGetRelationName(resultRel))));
1142  break;
1143  case CMD_UPDATE:
1144  if (fdwroutine->ExecForeignUpdate == NULL)
1145  ereport(ERROR,
1146  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1147  errmsg("cannot update foreign table \"%s\"",
1148  RelationGetRelationName(resultRel))));
1149  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1150  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_UPDATE)) == 0)
1151  ereport(ERROR,
1152  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1153  errmsg("foreign table \"%s\" does not allow updates",
1154  RelationGetRelationName(resultRel))));
1155  break;
1156  case CMD_DELETE:
1157  if (fdwroutine->ExecForeignDelete == NULL)
1158  ereport(ERROR,
1159  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1160  errmsg("cannot delete from foreign table \"%s\"",
1161  RelationGetRelationName(resultRel))));
1162  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1163  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_DELETE)) == 0)
1164  ereport(ERROR,
1165  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1166  errmsg("foreign table \"%s\" does not allow deletes",
1167  RelationGetRelationName(resultRel))));
1168  break;
1169  default:
1170  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1171  break;
1172  }
1173  break;
1174  default:
1175  ereport(ERROR,
1176  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1177  errmsg("cannot change relation \"%s\"",
1178  RelationGetRelationName(resultRel))));
1179  break;
1180  }
1181 }
ExecForeignDelete_function ExecForeignDelete
Definition: fdwapi.h:199
int errhint(const char *fmt,...)
Definition: elog.c:987
bool MatViewIncrementalMaintenanceIsEnabled(void)
Definition: matview.c:860
ExecForeignInsert_function ExecForeignInsert
Definition: fdwapi.h:197
#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:437
#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:198
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Definition: foreign.c:395
#define RELKIND_VIEW
Definition: pg_class.h:164
IsForeignRelUpdatable_function IsForeignRelUpdatable
Definition: fdwapi.h:201
#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 77 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_num_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_range_table, EState::es_result_relation_info, EState::es_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(), NIL, and NULL.

Referenced by afterTriggerInvokeEvents(), ATRewriteTable(), 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().

78 {
79  EState *estate;
80  MemoryContext qcontext;
81  MemoryContext oldcontext;
82 
83  /*
84  * Create the per-query context for this Executor run.
85  */
87  "ExecutorState",
89 
90  /*
91  * Make the EState node within the per-query context. This way, we don't
92  * need a separate pfree() operation for it at shutdown.
93  */
94  oldcontext = MemoryContextSwitchTo(qcontext);
95 
96  estate = makeNode(EState);
97 
98  /*
99  * Initialize all fields of the Executor State structure
100  */
102  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
103  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
104  estate->es_range_table = NIL;
105  estate->es_plannedstmt = NULL;
106 
107  estate->es_junkFilter = NULL;
108 
109  estate->es_output_cid = (CommandId) 0;
110 
111  estate->es_result_relations = NULL;
112  estate->es_num_result_relations = 0;
113  estate->es_result_relation_info = NULL;
114 
115  estate->es_trig_target_relations = NIL;
116  estate->es_trig_tuple_slot = NULL;
117  estate->es_trig_oldtup_slot = NULL;
118  estate->es_trig_newtup_slot = NULL;
119 
120  estate->es_param_list_info = NULL;
121  estate->es_param_exec_vals = NULL;
122 
123  estate->es_query_cxt = qcontext;
124 
125  estate->es_tupleTable = NIL;
126 
127  estate->es_rowMarks = NIL;
128 
129  estate->es_processed = 0;
130  estate->es_lastoid = InvalidOid;
131 
132  estate->es_top_eflags = 0;
133  estate->es_instrument = 0;
134  estate->es_finished = false;
135 
136  estate->es_exprcontexts = NIL;
137 
138  estate->es_subplanstates = NIL;
139 
140  estate->es_auxmodifytables = NIL;
141 
142  estate->es_per_tuple_exprcontext = NULL;
143 
144  estate->es_epqTuple = NULL;
145  estate->es_epqTupleSet = NULL;
146  estate->es_epqScanDone = NULL;
147  estate->es_sourceText = NULL;
148 
149  /*
150  * Return the executor state structure
151  */
152  MemoryContextSwitchTo(oldcontext);
153 
154  return estate;
155 }
#define NIL
Definition: pg_list.h:69
uint32 CommandId
Definition: c.h:411
HeapTuple * es_epqTuple
Definition: execnodes.h:470
JunkFilter * es_junkFilter
Definition: execnodes.h:414
CommandId es_output_cid
Definition: execnodes.h:417
TupleTableSlot * es_trig_newtup_slot
Definition: execnodes.h:428
Oid es_lastoid
Definition: execnodes.h:442
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:411
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:409
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:459
Snapshot es_snapshot
Definition: execnodes.h:408
List * es_range_table
Definition: execnodes.h:410
ScanDirection es_direction
Definition: execnodes.h:407
const char * es_sourceText
Definition: execnodes.h:412
ParamExecData * es_param_exec_vals
Definition: execnodes.h:432
MemoryContext es_query_cxt
Definition: execnodes.h:435
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
ResultRelInfo * es_result_relations
Definition: execnodes.h:420
TupleTableSlot * es_trig_oldtup_slot
Definition: execnodes.h:427
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
int es_instrument
Definition: execnodes.h:445
TupleTableSlot * es_trig_tuple_slot
Definition: execnodes.h:426
#define InvalidSnapshot
Definition: snapshot.h:25
List * es_trig_target_relations
Definition: execnodes.h:425
List * es_tupleTable
Definition: execnodes.h:437
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
List * es_auxmodifytables
Definition: execnodes.h:452
int es_num_result_relations
Definition: execnodes.h:421
#define InvalidOid
Definition: postgres_ext.h:36
bool es_finished
Definition: execnodes.h:446
#define makeNode(_type_)
Definition: nodes.h:554
#define NULL
Definition: c.h:229
uint64 es_processed
Definition: execnodes.h:441
bool * es_epqTupleSet
Definition: execnodes.h:471
List * es_subplanstates
Definition: execnodes.h:450
List * es_rowMarks
Definition: execnodes.h:439
int es_top_eflags
Definition: execnodes.h:444
bool * es_epqScanDone
Definition: execnodes.h:472
ParamListInfo es_param_list_info
Definition: execnodes.h:431
List * es_exprcontexts
Definition: execnodes.h:448
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:422
ExprContext* CreateExprContext ( EState estate)

Definition at line 213 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, MemoryContextSwitchTo(), and NULL.

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

214 {
215  ExprContext *econtext;
216  MemoryContext oldcontext;
217 
218  /* Create the ExprContext node within the per-query memory context */
219  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
220 
221  econtext = makeNode(ExprContext);
222 
223  /* Initialize fields of ExprContext */
224  econtext->ecxt_scantuple = NULL;
225  econtext->ecxt_innertuple = NULL;
226  econtext->ecxt_outertuple = NULL;
227 
228  econtext->ecxt_per_query_memory = estate->es_query_cxt;
229 
230  /*
231  * Create working memory for expression evaluation in this context.
232  */
233  econtext->ecxt_per_tuple_memory =
235  "ExprContext",
237 
238  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
239  econtext->ecxt_param_list_info = estate->es_param_list_info;
240 
241  econtext->ecxt_aggvalues = NULL;
242  econtext->ecxt_aggnulls = NULL;
243 
244  econtext->caseValue_datum = (Datum) 0;
245  econtext->caseValue_isNull = true;
246 
247  econtext->domainValue_datum = (Datum) 0;
248  econtext->domainValue_isNull = true;
249 
250  econtext->ecxt_estate = estate;
251 
252  econtext->ecxt_callbacks = NULL;
253 
254  /*
255  * Link the ExprContext into the EState to ensure it is shut down when the
256  * EState is freed. Because we use lcons(), shutdowns will occur in
257  * reverse order of creation, which may not be essential but can't hurt.
258  */
259  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
260 
261  MemoryContextSwitchTo(oldcontext);
262 
263  return econtext;
264 }
Datum * ecxt_aggvalues
Definition: execnodes.h:212
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:202
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum domainValue_datum
Definition: execnodes.h:220
ParamExecData * es_param_exec_vals
Definition: execnodes.h:432
MemoryContext es_query_cxt
Definition: execnodes.h:435
Datum caseValue_datum
Definition: execnodes.h:216
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:227
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:197
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:205
struct EState * ecxt_estate
Definition: execnodes.h:224
bool domainValue_isNull
Definition: execnodes.h:221
bool * ecxt_aggnulls
Definition: execnodes.h:213
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:554
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:198
#define NULL
Definition: c.h:229
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:196
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:201
bool caseValue_isNull
Definition: execnodes.h:217
ParamListInfo es_param_list_info
Definition: execnodes.h:431
List * es_exprcontexts
Definition: execnodes.h:448
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:206
ExprContext* CreateStandaloneExprContext ( void  )

Definition at line 285 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, makeNode, and NULL.

Referenced by domain_check_input().

286 {
287  ExprContext *econtext;
288 
289  /* Create the ExprContext node within the caller's memory context */
290  econtext = makeNode(ExprContext);
291 
292  /* Initialize fields of ExprContext */
293  econtext->ecxt_scantuple = NULL;
294  econtext->ecxt_innertuple = NULL;
295  econtext->ecxt_outertuple = NULL;
296 
298 
299  /*
300  * Create working memory for expression evaluation in this context.
301  */
302  econtext->ecxt_per_tuple_memory =
304  "ExprContext",
306 
307  econtext->ecxt_param_exec_vals = NULL;
308  econtext->ecxt_param_list_info = NULL;
309 
310  econtext->ecxt_aggvalues = NULL;
311  econtext->ecxt_aggnulls = NULL;
312 
313  econtext->caseValue_datum = (Datum) 0;
314  econtext->caseValue_isNull = true;
315 
316  econtext->domainValue_datum = (Datum) 0;
317  econtext->domainValue_isNull = true;
318 
319  econtext->ecxt_estate = NULL;
320 
321  econtext->ecxt_callbacks = NULL;
322 
323  return econtext;
324 }
Datum * ecxt_aggvalues
Definition: execnodes.h:212
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:202
Datum domainValue_datum
Definition: execnodes.h:220
Datum caseValue_datum
Definition: execnodes.h:216
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:227
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:197
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:205
struct EState * ecxt_estate
Definition: execnodes.h:224
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
bool domainValue_isNull
Definition: execnodes.h:221
bool * ecxt_aggnulls
Definition: execnodes.h:213
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:554
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:198
#define NULL
Definition: c.h:229
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:196
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:201
bool caseValue_isNull
Definition: execnodes.h:217
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:206
void do_text_output_multiline ( TupOutputState tstate,
const char *  txt 
)

Definition at line 1278 of file execTuples.c.

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

Referenced by ExplainQuery().

1279 {
1280  Datum values[1];
1281  bool isnull[1] = {false};
1282 
1283  while (*txt)
1284  {
1285  const char *eol;
1286  int len;
1287 
1288  eol = strchr(txt, '\n');
1289  if (eol)
1290  {
1291  len = eol - txt;
1292  eol++;
1293  }
1294  else
1295  {
1296  len = strlen(txt);
1297  eol = txt + len;
1298  }
1299 
1300  values[0] = PointerGetDatum(cstring_to_text_with_len(txt, len));
1301  do_tup_output(tstate, values, isnull);
1302  pfree(DatumGetPointer(values[0]));
1303  txt = eol;
1304  }
1305 }
#define PointerGetDatum(X)
Definition: postgres.h:562
void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
Definition: execTuples.c:1250
void pfree(void *pointer)
Definition: mcxt.c:950
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:162
void do_tup_output ( TupOutputState tstate,
Datum values,
bool isnull 
)

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

1251 {
1252  TupleTableSlot *slot = tstate->slot;
1253  int natts = slot->tts_tupleDescriptor->natts;
1254 
1255  /* make sure the slot is clear */
1256  ExecClearTuple(slot);
1257 
1258  /* insert data */
1259  memcpy(slot->tts_values, values, natts * sizeof(Datum));
1260  memcpy(slot->tts_isnull, isnull, natts * sizeof(bool));
1261 
1262  /* mark slot as containing a virtual tuple */
1263  ExecStoreVirtualTuple(slot);
1264 
1265  /* send the tuple to the receiver */
1266  (void) (*tstate->dest->receiveSlot) (slot, tstate->dest);
1267 
1268  /* clean up */
1269  ExecClearTuple(slot);
1270 }
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
Datum * tts_values
Definition: tuptable.h:125
TupleTableSlot * slot
Definition: executor.h:414
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:162
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:118
DestReceiver * dest
Definition: executor.h:415
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:488
void end_tup_output ( TupOutputState tstate)

Definition at line 1308 of file execTuples.c.

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

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

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

Definition at line 2339 of file execMain.c.

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

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

2342 {
2343  TupleTableSlot *slot;
2344  HeapTuple copyTuple;
2345 
2346  Assert(rti > 0);
2347 
2348  /*
2349  * Get and lock the updated version of the row; if fail, return NULL.
2350  */
2351  copyTuple = EvalPlanQualFetch(estate, relation, lockmode, LockWaitBlock,
2352  tid, priorXmax);
2353 
2354  if (copyTuple == NULL)
2355  return NULL;
2356 
2357  /*
2358  * For UPDATE/DELETE we have to return tid of actual row we're executing
2359  * PQ for.
2360  */
2361  *tid = copyTuple->t_self;
2362 
2363  /*
2364  * Need to run a recheck subquery. Initialize or reinitialize EPQ state.
2365  */
2366  EvalPlanQualBegin(epqstate, estate);
2367 
2368  /*
2369  * Free old test tuple, if any, and store new tuple where relation's scan
2370  * node will see it
2371  */
2372  EvalPlanQualSetTuple(epqstate, rti, copyTuple);
2373 
2374  /*
2375  * Fetch any non-locked source rows
2376  */
2377  EvalPlanQualFetchRowMarks(epqstate);
2378 
2379  /*
2380  * Run the EPQ query. We assume it will return at most one tuple.
2381  */
2382  slot = EvalPlanQualNext(epqstate);
2383 
2384  /*
2385  * If we got a tuple, force the slot to materialize the tuple so that it
2386  * is not dependent on any local state in the EPQ query (in particular,
2387  * it's highly likely that the slot contains references to any pass-by-ref
2388  * datums that may be present in copyTuple). As with the next step, this
2389  * is to guard against early re-use of the EPQ query.
2390  */
2391  if (!TupIsNull(slot))
2392  (void) ExecMaterializeSlot(slot);
2393 
2394  /*
2395  * Clear out the test tuple. This is needed in case the EPQ query is
2396  * re-used to test a tuple for a different relation. (Not clear that can
2397  * really happen, but let's be safe.)
2398  */
2399  EvalPlanQualSetTuple(epqstate, rti, NULL);
2400 
2401  return slot;
2402 }
void EvalPlanQualSetTuple(EPQState *epqstate, Index rti, HeapTuple tuple)
Definition: execMain.c:2690
HeapTuple EvalPlanQualFetch(EState *estate, Relation relation, int lockmode, LockWaitPolicy wait_policy, ItemPointer tid, TransactionId priorXmax)
Definition: execMain.c:2426
void EvalPlanQualFetchRowMarks(EPQState *epqstate)
Definition: execMain.c:2725
void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate)
Definition: execMain.c:2876
TupleTableSlot * EvalPlanQualNext(EPQState *epqstate)
Definition: execMain.c:2860
ItemPointerData t_self
Definition: htup.h:65
#define TupIsNull(slot)
Definition: tuptable.h:138
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
HeapTuple ExecMaterializeSlot(TupleTableSlot *slot)
Definition: execTuples.c:725
void EvalPlanQualBegin ( EPQState epqstate,
EState parentestate 
)

Definition at line 2876 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, NULL, EPQState::plan, EPQState::planstate, and ParamExecData::value.

Referenced by EvalPlanQual(), and ExecLockRows().

2877 {
2878  EState *estate = epqstate->estate;
2879 
2880  if (estate == NULL)
2881  {
2882  /* First time through, so create a child EState */
2883  EvalPlanQualStart(epqstate, parentestate, epqstate->plan);
2884  }
2885  else
2886  {
2887  /*
2888  * We already have a suitable child EPQ tree, so just reset it.
2889  */
2890  int rtsize = list_length(parentestate->es_range_table);
2891  PlanState *planstate = epqstate->planstate;
2892 
2893  MemSet(estate->es_epqScanDone, 0, rtsize * sizeof(bool));
2894 
2895  /* Recopy current values of parent parameters */
2896  if (parentestate->es_plannedstmt->nParamExec > 0)
2897  {
2898  int i = parentestate->es_plannedstmt->nParamExec;
2899 
2900  while (--i >= 0)
2901  {
2902  /* copy value if any, but not execPlan link */
2903  estate->es_param_exec_vals[i].value =
2904  parentestate->es_param_exec_vals[i].value;
2905  estate->es_param_exec_vals[i].isnull =
2906  parentestate->es_param_exec_vals[i].isnull;
2907  }
2908  }
2909 
2910  /*
2911  * Mark child plan tree as needing rescan at all scan nodes. The
2912  * first ExecProcNode will take care of actually doing the rescan.
2913  */
2914  planstate->chgParam = bms_add_member(planstate->chgParam,
2915  epqstate->epqParam);
2916  }
2917 }
PlannedStmt * es_plannedstmt
Definition: execnodes.h:411
#define MemSet(start, val, len)
Definition: c.h:857
List * es_range_table
Definition: execnodes.h:410
PlanState * planstate
Definition: execnodes.h:864
int nParamExec
Definition: plannodes.h:81
ParamExecData * es_param_exec_vals
Definition: execnodes.h:432
bool isnull
Definition: params.h:101
static void EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
Definition: execMain.c:2926
Bitmapset * chgParam
Definition: execnodes.h:824
Plan * plan
Definition: execnodes.h:866
#define NULL
Definition: c.h:229
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:472
Datum value
Definition: params.h:100
int epqParam
Definition: execnodes.h:868
EState * estate
Definition: execnodes.h:863
void EvalPlanQualEnd ( EPQState epqstate)

Definition at line 3066 of file execMain.c.

References EState::es_query_cxt, EState::es_subplanstates, EState::es_trig_target_relations, EState::es_tupleTable, EPQState::estate, ExecCloseIndices(), ExecEndNode(), ExecResetTupleTable(), FreeExecutorState(), heap_close, lfirst, MemoryContextSwitchTo(), NoLock, NULL, EPQState::origslot, EPQState::planstate, and ResultRelInfo::ri_RelationDesc.

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

3067 {
3068  EState *estate = epqstate->estate;
3069  MemoryContext oldcontext;
3070  ListCell *l;
3071 
3072  if (estate == NULL)
3073  return; /* idle, so nothing to do */
3074 
3075  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
3076 
3077  ExecEndNode(epqstate->planstate);
3078 
3079  foreach(l, estate->es_subplanstates)
3080  {
3081  PlanState *subplanstate = (PlanState *) lfirst(l);
3082 
3083  ExecEndNode(subplanstate);
3084  }
3085 
3086  /* throw away the per-estate tuple table */
3087  ExecResetTupleTable(estate->es_tupleTable, false);
3088 
3089  /* close any trigger target relations attached to this EState */
3090  foreach(l, estate->es_trig_target_relations)
3091  {
3092  ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
3093 
3094  /* Close indices and then the relation itself */
3095  ExecCloseIndices(resultRelInfo);
3096  heap_close(resultRelInfo->ri_RelationDesc, NoLock);
3097  }
3098 
3099  MemoryContextSwitchTo(oldcontext);
3100 
3101  FreeExecutorState(estate);
3102 
3103  /* Mark EPQState idle */
3104  epqstate->estate = NULL;
3105  epqstate->planstate = NULL;
3106  epqstate->origslot = NULL;
3107 }
Relation ri_RelationDesc
Definition: execnodes.h:373
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:644
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define heap_close(r, l)
Definition: heapam.h:97
PlanState * planstate
Definition: execnodes.h:864
void FreeExecutorState(EState *estate)
Definition: execUtils.c:173
MemoryContext es_query_cxt
Definition: execnodes.h:435
#define NoLock
Definition: lockdefs.h:34
TupleTableSlot * origslot
Definition: execnodes.h:865
List * es_trig_target_relations
Definition: execnodes.h:425
List * es_tupleTable
Definition: execnodes.h:437
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:156
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
List * es_subplanstates
Definition: execnodes.h:450
EState * estate
Definition: execnodes.h:863
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
Definition: execIndexing.c:224
HeapTuple EvalPlanQualFetch ( EState estate,
Relation  relation,
int  lockmode,
LockWaitPolicy  wait_policy,
ItemPointer  tid,
TransactionId  priorXmax 
)

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

2429 {
2430  HeapTuple copyTuple = NULL;
2431  HeapTupleData tuple;
2432  SnapshotData SnapshotDirty;
2433 
2434  /*
2435  * fetch target tuple
2436  *
2437  * Loop here to deal with updated or busy tuples
2438  */
2439  InitDirtySnapshot(SnapshotDirty);
2440  tuple.t_self = *tid;
2441  for (;;)
2442  {
2443  Buffer buffer;
2444 
2445  if (heap_fetch(relation, &SnapshotDirty, &tuple, &buffer, true, NULL))
2446  {
2447  HTSU_Result test;
2448  HeapUpdateFailureData hufd;
2449 
2450  /*
2451  * If xmin isn't what we're expecting, the slot must have been
2452  * recycled and reused for an unrelated tuple. This implies that
2453  * the latest version of the row was deleted, so we need do
2454  * nothing. (Should be safe to examine xmin without getting
2455  * buffer's content lock. We assume reading a TransactionId to be
2456  * atomic, and Xmin never changes in an existing tuple, except to
2457  * invalid or frozen, and neither of those can match priorXmax.)
2458  */
2460  priorXmax))
2461  {
2462  ReleaseBuffer(buffer);
2463  return NULL;
2464  }
2465 
2466  /* otherwise xmin should not be dirty... */
2467  if (TransactionIdIsValid(SnapshotDirty.xmin))
2468  elog(ERROR, "t_xmin is uncommitted in tuple to be updated");
2469 
2470  /*
2471  * If tuple is being updated by other transaction then we have to
2472  * wait for its commit/abort, or die trying.
2473  */
2474  if (TransactionIdIsValid(SnapshotDirty.xmax))
2475  {
2476  ReleaseBuffer(buffer);
2477  switch (wait_policy)
2478  {
2479  case LockWaitBlock:
2480  XactLockTableWait(SnapshotDirty.xmax,
2481  relation, &tuple.t_self,
2483  break;
2484  case LockWaitSkip:
2485  if (!ConditionalXactLockTableWait(SnapshotDirty.xmax))
2486  return NULL; /* skip instead of waiting */
2487  break;
2488  case LockWaitError:
2489  if (!ConditionalXactLockTableWait(SnapshotDirty.xmax))
2490  ereport(ERROR,
2491  (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
2492  errmsg("could not obtain lock on row in relation \"%s\"",
2493  RelationGetRelationName(relation))));
2494  break;
2495  }
2496  continue; /* loop back to repeat heap_fetch */
2497  }
2498 
2499  /*
2500  * If tuple was inserted by our own transaction, we have to check
2501  * cmin against es_output_cid: cmin >= current CID means our
2502  * command cannot see the tuple, so we should ignore it. Otherwise
2503  * heap_lock_tuple() will throw an error, and so would any later
2504  * attempt to update or delete the tuple. (We need not check cmax
2505  * because HeapTupleSatisfiesDirty will consider a tuple deleted
2506  * by our transaction dead, regardless of cmax.) We just checked
2507  * that priorXmax == xmin, so we can test that variable instead of
2508  * doing HeapTupleHeaderGetXmin again.
2509  */
2510  if (TransactionIdIsCurrentTransactionId(priorXmax) &&
2511  HeapTupleHeaderGetCmin(tuple.t_data) >= estate->es_output_cid)
2512  {
2513  ReleaseBuffer(buffer);
2514  return NULL;
2515  }
2516 
2517  /*
2518  * This is a live tuple, so now try to lock it.
2519  */
2520  test = heap_lock_tuple(relation, &tuple,
2521  estate->es_output_cid,
2522  lockmode, wait_policy,
2523  false, &buffer, &hufd);
2524  /* We now have two pins on the buffer, get rid of one */
2525  ReleaseBuffer(buffer);
2526 
2527  switch (test)
2528  {
2529  case HeapTupleSelfUpdated:
2530 
2531  /*
2532  * The target tuple was already updated or deleted by the
2533  * current command, or by a later command in the current
2534  * transaction. We *must* ignore the tuple in the former
2535  * case, so as to avoid the "Halloween problem" of
2536  * repeated update attempts. In the latter case it might
2537  * be sensible to fetch the updated tuple instead, but
2538  * doing so would require changing heap_update and
2539  * heap_delete to not complain about updating "invisible"
2540  * tuples, which seems pretty scary (heap_lock_tuple will
2541  * not complain, but few callers expect
2542  * HeapTupleInvisible, and we're not one of them). So for
2543  * now, treat the tuple as deleted and do not process.
2544  */
2545  ReleaseBuffer(buffer);
2546  return NULL;
2547 
2548  case HeapTupleMayBeUpdated:
2549  /* successfully locked */
2550  break;
2551 
2552  case HeapTupleUpdated:
2553  ReleaseBuffer(buffer);
2555  ereport(ERROR,
2556  (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
2557  errmsg("could not serialize access due to concurrent update")));
2558 
2559  /* Should not encounter speculative tuple on recheck */
2561  if (!ItemPointerEquals(&hufd.ctid, &tuple.t_self))
2562  {
2563  /* it was updated, so look at the updated version */
2564  tuple.t_self = hufd.ctid;
2565  /* updated row should have xmin matching this xmax */
2566  priorXmax = hufd.xmax;
2567  continue;
2568  }
2569  /* tuple was deleted, so give up */
2570  return NULL;
2571 
2572  case HeapTupleWouldBlock:
2573  ReleaseBuffer(buffer);
2574  return NULL;
2575 
2576  case HeapTupleInvisible:
2577  elog(ERROR, "attempted to lock invisible tuple");
2578 
2579  default:
2580  ReleaseBuffer(buffer);
2581  elog(ERROR, "unrecognized heap_lock_tuple status: %u",
2582  test);
2583  return NULL; /* keep compiler quiet */
2584  }
2585 
2586  /*
2587  * We got tuple - now copy it for use by recheck query.
2588  */
2589  copyTuple = heap_copytuple(&tuple);
2590  ReleaseBuffer(buffer);
2591  break;
2592  }
2593 
2594  /*
2595  * If the referenced slot was actually empty, the latest version of
2596  * the row must have been deleted, so we need do nothing.
2597  */
2598  if (tuple.t_data == NULL)
2599  {
2600  ReleaseBuffer(buffer);
2601  return NULL;
2602  }
2603 
2604  /*
2605  * As above, if xmin isn't what we're expecting, do nothing.
2606  */
2608  priorXmax))
2609  {
2610  ReleaseBuffer(buffer);
2611  return NULL;
2612  }
2613 
2614  /*
2615  * If we get here, the tuple was found but failed SnapshotDirty.
2616  * Assuming the xmin is either a committed xact or our own xact (as it
2617  * certainly should be if we're trying to modify the tuple), this must
2618  * mean that the row was updated or deleted by either a committed xact
2619  * or our own xact. If it was deleted, we can ignore it; if it was
2620  * updated then chain up to the next version and repeat the whole
2621  * process.
2622  *
2623  * As above, it should be safe to examine xmax and t_ctid without the
2624  * buffer content lock, because they can't be changing.
2625  */
2626  if (ItemPointerEquals(&tuple.t_self, &tuple.t_data->t_ctid))
2627  {
2628  /* deleted, so forget about it */
2629  ReleaseBuffer(buffer);
2630  return NULL;
2631  }
2632 
2633  /* updated, so look at the updated row */
2634  tuple.t_self = tuple.t_data->t_ctid;
2635  /* updated row should have xmin matching this xmax */
2636  priorXmax = HeapTupleHeaderGetUpdateXid(tuple.t_data);
2637  ReleaseBuffer(buffer);
2638  /* loop back to fetch next in chain */
2639  }
2640 
2641  /*
2642  * Return the copied tuple
2643  */
2644  return copyTuple;
2645 }
#define HeapTupleHeaderGetUpdateXid(tup)
Definition: htup_details.h:359
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
CommandId es_output_cid
Definition: execnodes.h:417
static void test(void)
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:773
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:4539
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:1862
#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:100
ItemPointerData t_ctid
Definition: htup_details.h:150
ItemPointerData t_self
Definition: htup.h:65
HTSU_Result
Definition: snapshot.h:119
#define RelationGetRelationName(relation)
Definition: rel.h:437
TransactionId xmax
Definition: snapshot.h:67
TransactionId xmin
Definition: snapshot.h:66
#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 NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:207
#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 2725 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, NULL, 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().

2726 {
2727  ListCell *l;
2728 
2729  Assert(epqstate->origslot != NULL);
2730 
2731  foreach(l, epqstate->arowMarks)
2732  {
2733  ExecAuxRowMark *aerm = (ExecAuxRowMark *) lfirst(l);
2734  ExecRowMark *erm = aerm->rowmark;
2735  Datum datum;
2736  bool isNull;
2737  HeapTupleData tuple;
2738 
2740  elog(ERROR, "EvalPlanQual doesn't support locking rowmarks");
2741 
2742  /* clear any leftover test tuple for this rel */
2743  EvalPlanQualSetTuple(epqstate, erm->rti, NULL);
2744 
2745  /* if child rel, must check whether it produced this row */
2746  if (erm->rti != erm->prti)
2747  {
2748  Oid tableoid;
2749 
2750  datum = ExecGetJunkAttribute(epqstate->origslot,
2751  aerm->toidAttNo,
2752  &isNull);
2753  /* non-locked rels could be on the inside of outer joins */
2754  if (isNull)
2755  continue;
2756  tableoid = DatumGetObjectId(datum);
2757 
2758  Assert(OidIsValid(erm->relid));
2759  if (tableoid != erm->relid)
2760  {
2761  /* this child is inactive right now */
2762  continue;
2763  }
2764  }
2765 
2766  if (erm->markType == ROW_MARK_REFERENCE)
2767  {
2768  HeapTuple copyTuple;
2769 
2770  Assert(erm->relation != NULL);
2771 
2772  /* fetch the tuple's ctid */
2773  datum = ExecGetJunkAttribute(epqstate->origslot,
2774  aerm->ctidAttNo,
2775  &isNull);
2776  /* non-locked rels could be on the inside of outer joins */
2777  if (isNull)
2778  continue;
2779 
2780  /* fetch requests on foreign tables must be passed to their FDW */
2781  if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2782  {
2783  FdwRoutine *fdwroutine;
2784  bool updated = false;
2785 
2786  fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
2787  /* this should have been checked already, but let's be safe */
2788  if (fdwroutine->RefetchForeignRow == NULL)
2789  ereport(ERROR,
2790  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2791  errmsg("cannot lock rows in foreign table \"%s\"",
2793  copyTuple = fdwroutine->RefetchForeignRow(epqstate->estate,
2794  erm,
2795  datum,
2796  &updated);
2797  if (copyTuple == NULL)
2798  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2799 
2800  /*
2801  * Ideally we'd insist on updated == false here, but that
2802  * assumes that FDWs can track that exactly, which they might
2803  * not be able to. So just ignore the flag.
2804  */
2805  }
2806  else
2807  {
2808  /* ordinary table, fetch the tuple */
2809  Buffer buffer;
2810 
2811  tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
2812  if (!heap_fetch(erm->relation, SnapshotAny, &tuple, &buffer,
2813  false, NULL))
2814  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2815 
2816  /* successful, copy tuple */
2817  copyTuple = heap_copytuple(&tuple);
2818  ReleaseBuffer(buffer);
2819  }
2820 
2821  /* store tuple */
2822  EvalPlanQualSetTuple(epqstate, erm->rti, copyTuple);
2823  }
2824  else
2825  {
2826  HeapTupleHeader td;
2827 
2828  Assert(erm->markType == ROW_MARK_COPY);
2829 
2830  /* fetch the whole-row Var for the relation */
2831  datum = ExecGetJunkAttribute(epqstate->origslot,
2832  aerm->wholeAttNo,
2833  &isNull);
2834  /* non-locked rels could be on the inside of outer joins */
2835  if (isNull)
2836  continue;
2837  td = DatumGetHeapTupleHeader(datum);
2838 
2839  /* build a temporary HeapTuple control structure */
2841  tuple.t_data = td;
2842  /* relation might be a foreign table, if so provide tableoid */
2843  tuple.t_tableOid = erm->relid;
2844  /* also copy t_ctid in case there's valid data there */
2845  tuple.t_self = td->t_ctid;
2846 
2847  /* copy and store tuple */
2848  EvalPlanQualSetTuple(epqstate, erm->rti,
2849  heap_copytuple(&tuple));
2850  }
2851  }
2852 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
void EvalPlanQualSetTuple(EPQState *epqstate, Index rti, HeapTuple tuple)
Definition: execMain.c:2690
Relation relation
Definition: execnodes.h:498
bool heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tuple, Buffer *userbuf, bool keep_buf, Relation stats_relation)
Definition: heapam.c:1862
#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:538
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:259
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:934
ItemPointerData * ItemPointer
Definition: itemptr.h:48
ExecRowMark * rowmark
Definition: execnodes.h:525
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:867
uint32 t_len
Definition: htup.h:64
Index rti
Definition: execnodes.h:500
AttrNumber wholeAttNo
Definition: execnodes.h:528
Index prti
Definition: execnodes.h:501
#define RelationGetRelationName(relation)
Definition: rel.h:437
Oid t_tableOid
Definition: htup.h:66
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:167
TupleTableSlot * origslot
Definition: execnodes.h:865
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:372
#define SnapshotAny
Definition: tqual.h:28
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:207
RowMarkType markType
Definition: execnodes.h:503
AttrNumber toidAttNo
Definition: execnodes.h:527
#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:863
int Buffer
Definition: buf.h:23
AttrNumber ctidAttNo
Definition: execnodes.h:526
RefetchForeignRow_function RefetchForeignRow
Definition: fdwapi.h:209
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
HeapTuple EvalPlanQualGetTuple ( EPQState epqstate,
Index  rti 
)

Definition at line 2710 of file execMain.c.

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

2711 {
2712  EState *estate = epqstate->estate;
2713 
2714  Assert(rti > 0);
2715 
2716  return estate->es_epqTuple[rti - 1];
2717 }
HeapTuple * es_epqTuple
Definition: execnodes.h:470
#define Assert(condition)
Definition: c.h:675
EState * estate
Definition: execnodes.h:863
void EvalPlanQualInit ( EPQState epqstate,
EState estate,
Plan subplan,
List auxrowmarks,
int  epqParam 
)

Definition at line 2655 of file execMain.c.

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

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

2657 {
2658  /* Mark the EPQ state inactive */
2659  epqstate->estate = NULL;
2660  epqstate->planstate = NULL;
2661  epqstate->origslot = NULL;
2662  /* ... and remember data that EvalPlanQualBegin will need */
2663  epqstate->plan = subplan;
2664  epqstate->arowMarks = auxrowmarks;
2665  epqstate->epqParam = epqParam;
2666 }
PlanState * planstate
Definition: execnodes.h:864
List * arowMarks
Definition: execnodes.h:867
TupleTableSlot * origslot
Definition: execnodes.h:865
Plan * plan
Definition: execnodes.h:866
#define NULL
Definition: c.h:229
int epqParam
Definition: execnodes.h:868
EState * estate
Definition: execnodes.h:863
TupleTableSlot* EvalPlanQualNext ( EPQState epqstate)

Definition at line 2860 of file execMain.c.

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

Referenced by EvalPlanQual(), and ExecLockRows().

2861 {
2862  MemoryContext oldcontext;
2863  TupleTableSlot *slot;
2864 
2865  oldcontext = MemoryContextSwitchTo(epqstate->estate->es_query_cxt);
2866  slot = ExecProcNode(epqstate->planstate);
2867  MemoryContextSwitchTo(oldcontext);
2868 
2869  return slot;
2870 }
TupleTableSlot * ExecProcNode(PlanState *node)
Definition: execProcnode.c:392
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlanState * planstate
Definition: execnodes.h:864
MemoryContext es_query_cxt
Definition: execnodes.h:435
EState * estate
Definition: execnodes.h:863
void EvalPlanQualSetPlan ( EPQState epqstate,
Plan subplan,
List auxrowmarks 
)

Definition at line 2674 of file execMain.c.

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

Referenced by ExecInitModifyTable(), and ExecModifyTable().

2675 {
2676  /* If we have a live EPQ query, shut it down */
2677  EvalPlanQualEnd(epqstate);
2678  /* And set/change the plan pointer */
2679  epqstate->plan = subplan;
2680  /* The rowmarks depend on the plan, too */
2681  epqstate->arowMarks = auxrowmarks;
2682 }
void EvalPlanQualEnd(EPQState *epqstate)
Definition: execMain.c:3066
List * arowMarks
Definition: execnodes.h:867
Plan * plan
Definition: execnodes.h:866
void EvalPlanQualSetTuple ( EPQState epqstate,
Index  rti,
HeapTuple  tuple 
)

Definition at line 2690 of file execMain.c.

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

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

2691 {
2692  EState *estate = epqstate->estate;
2693 
2694  Assert(rti > 0);
2695 
2696  /*
2697  * free old test tuple, if any, and store new tuple where relation's scan
2698  * node will see it
2699  */
2700  if (estate->es_epqTuple[rti - 1] != NULL)
2701  heap_freetuple(estate->es_epqTuple[rti - 1]);
2702  estate->es_epqTuple[rti - 1] = tuple;
2703  estate->es_epqTupleSet[rti - 1] = true;
2704 }
HeapTuple * es_epqTuple
Definition: execnodes.h:470
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool * es_epqTupleSet
Definition: execnodes.h:471
EState * estate
Definition: execnodes.h:863
void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

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

484 {
485  planstate->ps_ProjInfo =
487  planstate->ps_ExprContext,
488  planstate->ps_ResultTupleSlot,
489  planstate,
490  inputDesc);
491 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:831
ExprContext * ps_ExprContext
Definition: execnodes.h:830
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:829
Plan * plan
Definition: execnodes.h:800
List * targetlist
Definition: plannodes.h:132
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 423 of file execUtils.c.

References ExecSetSlotDescriptor(), and PlanState::ps_ResultTupleSlot.

Referenced by ExecAssignResultTypeFromTL(), and ExecInitModifyTable().

424 {
425  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
426 
427  ExecSetSlotDescriptor(slot, tupDesc);
428 }
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:829
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
void ExecAssignResultTypeFromTL ( PlanState planstate)

Definition at line 435 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(), ExecInitNestLoop(), ExecInitProjectSet(), ExecInitRecursiveUnion(), ExecInitResult(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitSetOp(), ExecInitSort(), ExecInitSubqueryScan(), ExecInitTableFuncScan(), ExecInitTidScan(), ExecInitUnique(), ExecInitValuesScan(), ExecInitWindowAgg(), and ExecInitWorkTableScan().

436 {
437  bool hasoid;
438  TupleDesc tupDesc;
439 
440  if (ExecContextForcesOids(planstate, &hasoid))
441  {
442  /* context forces OID choice; hasoid is now set correctly */
443  }
444  else
445  {
446  /* given free choice, don't leave space for OIDs in result tuples */
447  hasoid = false;
448  }
449 
450  /*
451  * ExecTypeFromTL needs the parse-time representation of the tlist, not a
452  * list of ExprStates. This is good because some plan nodes don't bother
453  * to set up planstate->targetlist ...
454  */
455  tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
456  ExecAssignResultType(planstate, tupDesc);
457 }
void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc)
Definition: execUtils.c:423
TupleDesc ExecTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:888
Plan * plan
Definition: execnodes.h:800
List * targetlist
Definition: plannodes.h:132
bool ExecContextForcesOids(PlanState *planstate, bool *hasoids)
Definition: execMain.c:1440
void ExecAssignScanProjectionInfo ( ScanState node)
void ExecAssignScanProjectionInfoWithVarno ( ScanState node,
Index  varno 
)

Definition at line 247 of file execScan.c.

References ExecAssignProjectionInfo(), NULL, 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().

248 {
249  Scan *scan = (Scan *) node->ps.plan;
250 
251  if (tlist_matches_tupdesc(&node->ps,
252  scan->plan.targetlist,
253  varno,
255  node->ps.ps_ProjInfo = NULL;
256  else
259 }
Plan plan
Definition: plannodes.h:315
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:831
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1047
PlanState ps
Definition: execnodes.h:1044
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:482
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
Definition: execScan.c:262
Plan * plan
Definition: execnodes.h:800
#define NULL
Definition: c.h:229
List * targetlist
Definition: plannodes.h:132
void ExecAssignScanType ( ScanState scanstate,
TupleDesc  tupDesc 
)
void ExecAssignScanTypeFromOuterPlan ( ScanState scanstate)

Definition at line 547 of file execUtils.c.

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

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

548 {
550  TupleDesc tupDesc;
551 
552  outerPlan = outerPlanState(scanstate);
553  tupDesc = ExecGetResultType(outerPlan);
554 
555  ExecAssignScanType(scanstate, tupDesc);
556 }
#define outerPlanState(node)
Definition: execnodes.h:842
#define outerPlan(node)
Definition: plannodes.h:162
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:464
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:535
ExecAuxRowMark* ExecBuildAuxRowMark ( ExecRowMark erm,
List targetlist 
)

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

2269 {
2270  ExecAuxRowMark *aerm = (ExecAuxRowMark *) palloc0(sizeof(ExecAuxRowMark));
2271  char resname[32];
2272 
2273  aerm->rowmark = erm;
2274 
2275  /* Look up the resjunk columns associated with this rowmark */
2276  if (erm->markType != ROW_MARK_COPY)
2277  {
2278  /* need ctid for all methods other than COPY */
2279  snprintf(resname, sizeof(resname), "ctid%u", erm->rowmarkId);
2280  aerm->ctidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2281  resname);
2282  if (!AttributeNumberIsValid(aerm->ctidAttNo))
2283  elog(ERROR, "could not find junk %s column", resname);
2284  }
2285  else
2286  {
2287  /* need wholerow if COPY */
2288  snprintf(resname, sizeof(resname), "wholerow%u", erm->rowmarkId);
2289  aerm->wholeAttNo = ExecFindJunkAttributeInTlist(targetlist,
2290  resname);
2291  if (!AttributeNumberIsValid(aerm->wholeAttNo))
2292  elog(ERROR, "could not find junk %s column", resname);
2293  }
2294 
2295  /* if child rel, need tableoid */
2296  if (erm->rti != erm->prti)
2297  {
2298  snprintf(resname, sizeof(resname), "tableoid%u", erm->rowmarkId);
2299  aerm->toidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2300  resname);
2301  if (!AttributeNumberIsValid(aerm->toidAttNo))
2302  elog(ERROR, "could not find junk %s column", resname);
2303  }
2304 
2305  return aerm;
2306 }
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:525
#define ERROR
Definition: elog.h:43
Index rti
Definition: execnodes.h:500
AttrNumber wholeAttNo
Definition: execnodes.h:528
Index prti
Definition: execnodes.h:501
Index rowmarkId
Definition: execnodes.h:502
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
void * palloc0(Size size)
Definition: mcxt.c:878
RowMarkType markType
Definition: execnodes.h:503
AttrNumber toidAttNo
Definition: execnodes.h:527
#define elog
Definition: elog.h:219
AttrNumber ctidAttNo
Definition: execnodes.h:526
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, tupleDesc::attrs, castNode, 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, makeNode, NULL, ExprEvalStep::opcode, OUTER_VAR, ProjectionInfo::pi_exprContext, ProjectionInfo::pi_state, TargetEntry::resno, ExprState::resnull, ExprState::resultslot, ExprState::resvalue, T_ExprState, ExprState::tag, 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 = castNode(TargetEntry, lfirst(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 = inputDesc->attrs[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:54
#define IsA(nodeptr, _type_)
Definition: nodes.h:557
#define castNode(_type_, nodeptr)
Definition: nodes.h:575
Form_pg_attribute * attrs
Definition: tupdesc.h:74
Definition: nodes.h:506
AttrNumber varattno
Definition: primnodes.h:168
TupleTableSlot * resultslot
Definition: execnodes.h:68
Definition: primnodes.h:163
struct ExprEvalStep::@46::@51 assign_tmp
bool resnull
Definition: execnodes.h:62
Expr * expr
Definition: execnodes.h:82
Oid vartype
Definition: primnodes.h:170
static void ExecInitExprSlots(ExprState *state, Node *node)
Definition: execExpr.c:2137
NodeTag type
Definition: nodes.h:508
union ExprEvalStep::@46 d
AttrNumber resno
Definition: primnodes.h:1353
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
Index varno
Definition: primnodes.h:166
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:568
#define INNER_VAR
Definition: primnodes.h:153
#define makeNode(_type_)
Definition: nodes.h:554
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
Definition: regguts.h:298
intptr_t opcode
Definition: execExpr.h:226
Expr * expr
Definition: primnodes.h:1352
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
static void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2010
struct ExprEvalStep::@46::@50 assign_var
int16 get_typlen(Oid typid)
Definition: lsyscache.c:1915
ExprState pi_state
Definition: execnodes.h:295
static void ExecInitExprRec(Expr *node, PlanState *parent, ExprState *state, Datum *resv, bool *resnull)
Definition: execExpr.c:583
ExprContext * pi_exprContext
Definition: execnodes.h:297
Datum resvalue
Definition: execnodes.h:63
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:154
bool ExecCheck ( ExprState state,
ExprContext context 
)

Definition at line 538 of file execExpr.c.

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

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

539 {
540  Datum ret;
541  bool isnull;
542 
543  /* short-circuit (here and in ExecInitCheck) for empty restriction list */
544  if (state == NULL)
545  return true;
546 
547  /* verify that expression was not compiled using ExecInitQual */
548  Assert(!(state->flags & EEO_FLAG_IS_QUAL));
549 
550  ret = ExecEvalExprSwitchContext(state, econtext, &isnull);
551 
552  if (isnull)
553  return true;
554 
555  return DatumGetBool(ret);
556 }
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:281
#define EEO_FLAG_IS_QUAL
Definition: execnodes.h:50
#define DatumGetBool(X)
Definition: postgres.h:399
uintptr_t Datum
Definition: postgres.h:372
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
uint8 flags
Definition: execnodes.h:56
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, NULL, 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:1764
int ri_NumIndices
Definition: execnodes.h:374
#define NIL
Definition: pg_list.h:69
Relation ri_RelationDesc
Definition: execnodes.h:373
List * ii_Predicate
Definition: execnodes.h:137
ExprState * ii_PredicateState
Definition: execnodes.h:138
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:346
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:456
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5286
Form_pg_index rd_index
Definition: rel.h:159
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:437
ExprState * ExecPrepareQual(List *qual, EState *estate)
Definition: execExpr.c:465
bool ii_ReadyForInserts
Definition: execnodes.h:146
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:372
bool ii_Unique
Definition: execnodes.h:145
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505
#define NULL
Definition: c.h:229
#define INDEX_MAX_KEYS
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:196
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:149
Oid * ii_ExclusionOps
Definition: execnodes.h:139
int errmsg(const char *fmt,...)
Definition: elog.c:797
IndexInfo ** ri_IndexRelationInfo
Definition: execnodes.h:376
int i
#define elog
Definition: elog.h:219
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:375
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:422
bool ExecCheckRTPerms ( List rangeTable,
bool  ereport_on_violation 
)

Definition at line 562 of file execMain.c.

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

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

563 {
564  ListCell *l;
565  bool result = true;
566 
567  foreach(l, rangeTable)
568  {
569  RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
570 
571  result = ExecCheckRTEPerms(rte);
572  if (!result)
573  {
574  Assert(rte->rtekind == RTE_RELATION);
575  if (ereport_on_violation)
577  get_rel_name(rte->relid));
578  return false;
579  }
580  }
581 
583  result = (*ExecutorCheckPerms_hook) (rangeTable,
584  ereport_on_violation);
585  return result;
586 }
return result
Definition: formatting.c:1618
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
static bool ExecCheckRTEPerms(RangeTblEntry *rte)
Definition: execMain.c:593
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
Definition: execMain.c:75
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
RTEKind rtekind
Definition: parsenodes.h:916
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1694
int ExecCleanTargetListLength ( List targetlist)

Definition at line 972 of file execUtils.c.

References castNode, lfirst, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), and ExecTypeFromTLInternal().

973 {
974  int len = 0;
975  ListCell *tl;
976 
977  foreach(tl, targetlist)
978  {
979  TargetEntry *curTle = castNode(TargetEntry, lfirst(tl));
980 
981  if (!curTle->resjunk)
982  len++;
983  }
984  return len;
985 }
#define castNode(_type_, nodeptr)
Definition: nodes.h:575
bool resjunk
Definition: primnodes.h:1359
#define lfirst(lc)
Definition: pg_list.h:106
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 ExecCloseIndices ( ResultRelInfo resultRelInfo)

Definition at line 224 of file execIndexing.c.

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

Referenced by afterTriggerInvokeEvents(), apply_handle_delete(), apply_handle_insert(), apply_handle_update(), CatalogCloseIndexes(), CopyFrom(), EvalPlanQualEnd(), 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:374
#define RowExclusiveLock
Definition: lockdefs.h:38
#define NULL
Definition: c.h:229
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
int i
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:375
void ExecCloseScanRelation ( Relation  scanrel)

Definition at line 656 of file execUtils.c.

References heap_close, and NoLock.

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

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

Definition at line 1827 of file execMain.c.

References Assert, tupleDesc::attrs, bms_union(), tupleDesc::constr, ereport, errcode(), errdetail(), errmsg(), ERROR, errtablecol(), errtableconstraint(), ExecBuildSlotValueDescription(), ExecPartitionCheck(), ExecRelCheck(), GetInsertedColumns, GetUpdatedColumns, tupleConstr::has_not_null, NameStr, tupleDesc::natts, NULL, tupleConstr::num_check, RelationGetDescr, RelationGetRelationName, RelationGetRelid, ResultRelInfo::ri_PartitionCheck, ResultRelInfo::ri_PartitionRoot, ResultRelInfo::ri_RelationDesc, and slot_attisnull().

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

1830 {
1831  Relation rel = resultRelInfo->ri_RelationDesc;
1832  TupleDesc tupdesc = RelationGetDescr(rel);
1833  TupleConstr *constr = tupdesc->constr;
1834  Bitmapset *modifiedCols;
1835  Bitmapset *insertedCols;
1836  Bitmapset *updatedCols;
1837 
1838  Assert(constr || resultRelInfo->ri_PartitionCheck);
1839 
1840  if (constr && constr->has_not_null)
1841  {
1842  int natts = tupdesc->natts;
1843  int attrChk;
1844 
1845  for (attrChk = 1; attrChk <= natts; attrChk++)
1846  {
1847  if (tupdesc->attrs[attrChk - 1]->attnotnull &&
1848  slot_attisnull(slot, attrChk))
1849  {
1850  char *val_desc;
1851  Relation orig_rel = rel;
1852  TupleDesc orig_tupdesc = tupdesc;
1853 
1854  /*
1855  * choose the correct relation to build val_desc from the
1856  * tuple contained in orig_slot
1857  */
1858  if (resultRelInfo->ri_PartitionRoot)
1859  {
1860  rel = resultRelInfo->ri_PartitionRoot;
1861  tupdesc = RelationGetDescr(rel);
1862  }
1863 
1864  insertedCols = GetInsertedColumns(resultRelInfo, estate);
1865  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
1866  modifiedCols = bms_union(insertedCols, updatedCols);
1868  orig_slot,
1869  tupdesc,
1870  modifiedCols,
1871  64);
1872 
1873  ereport(ERROR,
1874  (errcode(ERRCODE_NOT_NULL_VIOLATION),
1875  errmsg("null value in column \"%s\" violates not-null constraint",
1876  NameStr(orig_tupdesc->attrs[attrChk - 1]->attname)),
1877  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1878  errtablecol(orig_rel, attrChk)));
1879  }
1880  }
1881  }
1882 
1883  if (constr && constr->num_check > 0)
1884  {
1885  const char *failed;
1886 
1887  if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
1888  {
1889  char *val_desc;
1890  Relation orig_rel = rel;
1891 
1892  /* See the comment above. */
1893  if (resultRelInfo->ri_PartitionRoot)
1894  {
1895  rel = resultRelInfo->ri_PartitionRoot;
1896  tupdesc = RelationGetDescr(rel);
1897  }
1898 
1899  insertedCols = GetInsertedColumns(resultRelInfo, estate);
1900  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
1901  modifiedCols = bms_union(insertedCols, updatedCols);
1903  orig_slot,
1904  tupdesc,
1905  modifiedCols,
1906  64);
1907  ereport(ERROR,
1908  (errcode(ERRCODE_CHECK_VIOLATION),
1909  errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
1910  RelationGetRelationName(orig_rel), failed),
1911  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1912  errtableconstraint(orig_rel, failed)));
1913  }
1914  }
1915 
1916  if (resultRelInfo->ri_PartitionCheck &&
1917  !ExecPartitionCheck(resultRelInfo, slot, estate))
1918  {
1919  char *val_desc;
1920  Relation orig_rel = rel;
1921 
1922  /* See the comment above. */
1923  if (resultRelInfo->ri_PartitionRoot)
1924  {
1925  rel = resultRelInfo->ri_PartitionRoot;
1926  tupdesc = RelationGetDescr(rel);
1927  }
1928 
1929  insertedCols = GetInsertedColumns(resultRelInfo, estate);
1930  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
1931  modifiedCols = bms_union(insertedCols, updatedCols);
1933  orig_slot,
1934  tupdesc,
1935  modifiedCols,
1936  64);
1937  ereport(ERROR,
1938  (errcode(ERRCODE_CHECK_VIOLATION),
1939  errmsg("new row for relation \"%s\" violates partition constraint",
1940  RelationGetRelationName(orig_rel)),
1941  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
1942  }
1943 }
#define GetUpdatedColumns(relinfo, estate)
Definition: execMain.c:115
Relation ri_RelationDesc
Definition: execnodes.h:373
#define RelationGetDescr(relation)
Definition: rel.h:429
Relation ri_PartitionRoot
Definition: execnodes.h:393
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int errcode(int sqlerrcode)
Definition: elog.c:575
int natts
Definition: tupdesc.h:73
int errtableconstraint(Relation rel, const char *conname)
Definition: relcache.c:5286
static bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1782
#define ERROR
Definition: elog.h:43
static char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
Definition: execMain.c:2082
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define RelationGetRelationName(relation)
Definition: rel.h:437
#define ereport(elevel, rest)
Definition: elog.h:122
bool has_not_null
Definition: tupdesc.h:43
List * ri_PartitionCheck
Definition: execnodes.h:391
static const char * ExecRelCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1718
bool slot_attisnull(TupleTableSlot *slot, int attnum)
Definition: heaptuple.c:1330
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
int errtablecol(Relation rel, int attnum)
Definition: relcache.c:5249
TupleConstr * constr
Definition: tupdesc.h:76
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:218
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:499
uint16 num_check
Definition: tupdesc.h:42
#define RelationGetRelid(relation)
Definition: rel.h:417
#define GetInsertedColumns(relinfo, estate)
Definition: execMain.c:113
bool ExecContextForcesOids ( PlanState planstate,
bool hasoids 
)

Definition at line 1440 of file execMain.c.

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

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

1441 {
1442  ResultRelInfo *ri = planstate->state->es_result_relation_info;
1443 
1444  if (ri != NULL)
1445  {
1446  Relation rel = ri->ri_RelationDesc;
1447 
1448  if (rel != NULL)
1449  {
1450  *hasoids = rel->rd_rel->relhasoids;
1451  return true;
1452  }
1453  }
1454 
1455  if (planstate->state->es_top_eflags & EXEC_FLAG_WITH_OIDS)
1456  {
1457  *hasoids = true;
1458  return true;
1459  }
1460  if (planstate->state->es_top_eflags & EXEC_FLAG_WITHOUT_OIDS)
1461  {
1462  *hasoids = false;
1463  return true;
1464  }
1465 
1466  return false;
1467 }
Relation ri_RelationDesc
Definition: execnodes.h:373
EState * state
Definition: execnodes.h:802
Form_pg_class rd_rel
Definition: rel.h:114
#define EXEC_FLAG_WITHOUT_OIDS
Definition: executor.h:64
#define NULL
Definition: c.h:229
#define EXEC_FLAG_WITH_OIDS
Definition: executor.h:63
int es_top_eflags
Definition: execnodes.h:444
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:422
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, NULL, 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:59
bool atEnd
Definition: portal.h:186
EState * estate
Definition: execdesc.h:47
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:1047
unsigned int Oid
Definition: postgres_ext.h:31
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:934
ItemPointerData * ItemPointer
Definition: itemptr.h:48
ItemPointerData curCtid
Definition: execnodes.h:507
#define ERROR
Definition: elog.h:43
PlanState * planstate
Definition: execdesc.h:48
#define TupIsNull(slot)
Definition: tuptable.h:138
#define TableOidAttributeNumber
Definition: sysattr.h:27
char * cursor_name
Definition: primnodes.h:1276
PortalStrategy strategy
Definition: portal.h:142
#define ereport(elevel, rest)
Definition: elog.h:122
#define PortalIsValid(p)
Definition: portal.h:198
static ScanState * search_plan_tree(PlanState *node, Oid table_oid)
Definition: execCurrent.c:254
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
RowMarkType markType
Definition: execnodes.h:503
List * es_rowMarks
Definition: execnodes.h:439
#define DatumGetPointer(X)
Definition: postgres.h:555
#define PortalGetQueryDesc(portal)
Definition: portal.h:203
bool atStart
Definition: portal.h:185
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:1143
#define SelfItemPointerAttributeNumber
Definition: sysattr.h:21
#define elog
Definition: elog.h:219
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:990
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1694
void ExecEndNode ( PlanState node)

Definition at line 644 of file execProcnode.c.

References bms_free(), 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(), ExecEndNestLoop(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSampleScan(), ExecEndSeqScan(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndTableFuncScan(), ExecEndTidScan(), ExecEndUnique(), ExecEndValuesScan(), ExecEndWindowAgg(), ExecEndWorkTableScan(), nodeTag, NULL, 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_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().

645 {
646  /*
647  * do nothing when we get to the end of a leaf on tree.
648  */
649  if (node == NULL)
650  return;
651 
652  if (node->chgParam != NULL)
653  {
654  bms_free(node->chgParam);
655  node->chgParam = NULL;
656  }
657 
658  switch (nodeTag(node))
659  {
660  /*
661  * control nodes
662  */
663  case T_ResultState:
664  ExecEndResult((ResultState *) node);
665  break;
666 
667  case T_ProjectSetState:
669  break;
670 
671  case T_ModifyTableState:
673  break;
674 
675  case T_AppendState:
676  ExecEndAppend((AppendState *) node);
677  break;
678 
679  case T_MergeAppendState:
681  break;
682 
685  break;
686 
687  case T_BitmapAndState:
689  break;
690 
691  case T_BitmapOrState:
692  ExecEndBitmapOr((BitmapOrState *) node);
693  break;
694 
695  /*
696  * scan nodes
697  */
698  case T_SeqScanState:
699  ExecEndSeqScan((SeqScanState *) node);
700  break;
701 
702  case T_SampleScanState:
704  break;
705 
706  case T_GatherState:
707  ExecEndGather((GatherState *) node);
708  break;
709 
710  case T_GatherMergeState:
712  break;
713 
714  case T_IndexScanState:
716  break;
717 
720  break;
721 
724  break;
725 
728  break;
729 
730  case T_TidScanState:
731  ExecEndTidScan((TidScanState *) node);
732  break;
733 
734  case T_SubqueryScanState:
736  break;
737 
738  case T_FunctionScanState:
740  break;
741 
744  break;
745 
746  case T_ValuesScanState:
748  break;
749 
750  case T_CteScanState:
751  ExecEndCteScan((CteScanState *) node);
752  break;
753 
756  break;
757 
758  case T_ForeignScanState:
760  break;
761 
762  case T_CustomScanState:
764  break;
765 
766  /*
767  * join nodes
768  */
769  case T_NestLoopState:
770  ExecEndNestLoop((NestLoopState *) node);
771  break;
772 
773  case T_MergeJoinState:
775  break;
776 
777  case T_HashJoinState:
778  ExecEndHashJoin((HashJoinState *) node);
779  break;
780 
781  /*
782  * materialization nodes
783  */
784  case T_MaterialState:
785  ExecEndMaterial((MaterialState *) node);
786  break;
787 
788  case T_SortState:
789  ExecEndSort((SortState *) node);
790  break;
791 
792  case T_GroupState:
793  ExecEndGroup((GroupState *) node);
794  break;
795 
796  case T_AggState:
797  ExecEndAgg((AggState *) node);
798  break;
799 
800  case T_WindowAggState:
802  break;
803 
804  case T_UniqueState:
805  ExecEndUnique((UniqueState *) node);
806  break;
807 
808  case T_HashState:
809  ExecEndHash((HashState *) node);
810  break;
811 
812  case T_SetOpState:
813  ExecEndSetOp((SetOpState *) node);
814  break;
815 
816  case T_LockRowsState:
817  ExecEndLockRows((LockRowsState *) node);
818  break;
819 
820  case T_LimitState:
821  ExecEndLimit((LimitState *) node);
822  break;
823 
824  default:
825  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
826  break;
827  }
828 }
void ExecEndGroup(GroupState *node)
Definition: nodeGroup.c:226
void ExecEndSetOp(SetOpState *node)
Definition: nodeSetOp.c:575
void ExecEndFunctionScan(FunctionScanState *node)
void ExecEndNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:353
void ExecEndIndexScan(IndexScanState *node)
void ExecEndLimit(LimitState *node)
Definition: nodeLimit.c:426
void ExecEndUnique(UniqueState *node)
Definition: nodeUnique.c:173
void ExecEndGatherMerge(GatherMergeState *node)
void ExecEndWorkTableScan(WorkTableScanState *node)
void ExecEndLockRows(LockRowsState *node)
Definition: nodeLockRows.c:446
void ExecEndBitmapAnd(BitmapAndState *node)
void ExecEndRecursiveUnion(RecursiveUnionState *node)
void ExecEndSubqueryScan(SubqueryScanState *node)
void ExecEndHashJoin(HashJoinState *node)
Definition: nodeHashjoin.c:541
void ExecEndTableFuncScan(TableFuncScanState *node)
void ExecEndResult(ResultState *node)
Definition: nodeResult.c:241
#define ERROR
Definition: elog.h:43
void ExecEndAppend(AppendState *node)
Definition: nodeAppend.c:252
void ExecEndForeignScan(ForeignScanState *node)
void ExecEndSort(SortState *node)
Definition: nodeSort.c:223
void ExecEndBitmapIndexScan(BitmapIndexScanState *node)
void ExecEndValuesScan(ValuesScanState *node)
void ExecEndMergeJoin(MergeJoinState *node)
void ExecEndSeqScan(SeqScanState *node)
Definition: nodeSeqscan.c:221
void ExecEndIndexOnlyScan(IndexOnlyScanState *node)
void ExecEndTidScan(TidScanState *node)
Definition: nodeTidscan.c:477
Bitmapset * chgParam
Definition: execnodes.h:824
void ExecEndCteScan(CteScanState *node)
Definition: nodeCtescan.c:277
void ExecEndCustomScan(CustomScanState *node)
Definition: nodeCustom.c:112
void ExecEndBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:182
void ExecEndSampleScan(SampleScanState *node)
void bms_free(Bitmapset *a)
Definition: bitmapset.c:201
void ExecEndWindowAgg(WindowAggState *node)
#define NULL
Definition: c.h:229
void ExecEndMergeAppend(MergeAppendState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:511
void ExecEndHash(HashState *node)
Definition: nodeHash.c:218
void ExecEndProjectSet(ProjectSetState *node)
void ExecEndMaterial(MaterialState *node)
Definition: nodeMaterial.c:240
#define elog
Definition: elog.h:219
void ExecEndBitmapHeapScan(BitmapHeapScanState *node)
void ExecEndAgg(AggState *node)
Definition: nodeAgg.c:3834
void ExecEndModifyTable(ModifyTableState *node)
void ExecEndGather(GatherState *node)
Definition: nodeGather.c:226
static Datum ExecEvalExprSwitchContext ( ExprState state,
ExprContext econtext,
bool isNull 
)
inlinestatic

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

284 {
285  Datum retDatum;
286  MemoryContext oldContext;
287 
288  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
289  retDatum = (*state->evalfunc) (state, econtext, isNull);
290  MemoryContextSwitchTo(oldContext);
291  return retDatum;
292 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:202
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ExprStateEvalFunc evalfunc
Definition: execnodes.h:79
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:333
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
TupleTableSlot * jf_resultSlot
Definition: execnodes.h:334
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:332
void slot_getallattrs(TupleTableSlot *slot)
Definition: heaptuple.c:1239
uintptr_t Datum
Definition: postgres.h:372
static Datum values[MAXATTR]
Definition: bootstrap.c:162
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:331
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:1354
bool resjunk
Definition: primnodes.h:1359
AttrNumber resno
Definition: primnodes.h:1353
#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 3224 of file execMain.c.

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

Referenced by CopyFrom(), and ExecInsert().

3226 {
3227  int result;
3228  PartitionDispatchData *failed_at;
3229  TupleTableSlot *failed_slot;
3230 
3231  result = get_partition_for_tuple(pd, slot, estate,
3232  &failed_at, &failed_slot);
3233  if (result < 0)
3234  {
3235  Relation failed_rel;
3236  Datum key_values[PARTITION_MAX_KEYS];
3237  bool key_isnull[PARTITION_MAX_KEYS];
3238  char *val_desc;
3239  ExprContext *ecxt = GetPerTupleExprContext(estate);
3240 
3241  failed_rel = failed_at->reldesc;
3242  ecxt->ecxt_scantuple = failed_slot;
3243  FormPartitionKeyDatum(failed_at, failed_slot, estate,
3244  key_values, key_isnull);
3245  val_desc = ExecBuildSlotPartitionKeyDescription(failed_rel,
3246  key_values,
3247  key_isnull,
3248  64);
3249  Assert(OidIsValid(RelationGetRelid(failed_rel)));
3250  ereport(ERROR,
3251  (errcode(ERRCODE_CHECK_VIOLATION),
3252  errmsg("no partition of relation \"%s\" found for row",
3253  RelationGetRelationName(failed_rel)),
3254  val_desc ? errdetail("Partition key of the failing row contains %s.", val_desc) : 0));
3255  }
3256 
3257  return result;
3258 }
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:1668
return result
Definition: formatting.c:1618
#define OidIsValid(objectId)
Definition: c.h:538
#define GetPerTupleExprContext(estate)
Definition: executor.h:456
#define ERROR
Definition: elog.h:43
static char * ExecBuildSlotPartitionKeyDescription(Relation rel, Datum *values, bool *isnull, int maxfieldlen)
Definition: execMain.c:3268
void FormPartitionKeyDatum(PartitionDispatch pd, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
Definition: partition.c:1609
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define RelationGetRelationName(relation)
Definition: rel.h:437
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:372
#define Assert(condition)
Definition: c.h:675
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:196
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RelationGetRelid(relation)
Definition: rel.h:417
ExecRowMark* ExecFindRowMark ( EState estate,
Index  rti,
bool  missing_ok 
)

Definition at line 2244 of file execMain.c.

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

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

2245 {
2246  ListCell *lc;
2247 
2248  foreach(lc, estate->es_rowMarks)
2249  {
2250  ExecRowMark *erm = (ExecRowMark *) lfirst(lc);
2251 
2252  if (erm->rti == rti)
2253  return erm;
2254  }
2255  if (!missing_ok)
2256  elog(ERROR, "failed to find ExecRowMark for rangetable index %u", rti);
2257  return NULL;
2258 }
#define ERROR
Definition: elog.h:43
Index rti
Definition: execnodes.h:500
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
List * es_rowMarks
Definition: execnodes.h:439
#define elog
Definition: elog.h:219
void ExecFreeExprContext ( PlanState planstate)
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:675
Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: heaptuple.c:1143
ResultRelInfo* ExecGetTriggerResultRel ( EState estate,
Oid  relid 
)

Definition at line 1350 of file execMain.c.

References EState::es_instrument, EState::es_num_result_relations, EState::es_query_cxt, EState::es_result_relations, EState::es_trig_target_relations, heap_open(), InitResultRelInfo(), lappend(), lfirst, makeNode, MemoryContextSwitchTo(), NoLock, NULL, RelationGetRelid, and ResultRelInfo::ri_RelationDesc.

Referenced by afterTriggerInvokeEvents().

1351 {
1352  ResultRelInfo *rInfo;
1353  int nr;
1354  ListCell *l;
1355  Relation rel;
1356  MemoryContext oldcontext;
1357 
1358  /* First, search through the query result relations */
1359  rInfo = estate->es_result_relations;
1360  nr = estate->es_num_result_relations;
1361  while (nr > 0)
1362  {
1363  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1364  return rInfo;
1365  rInfo++;
1366  nr--;
1367  }
1368  /* Nope, but maybe we already made an extra ResultRelInfo for it */
1369  foreach(l, estate->es_trig_target_relations)
1370  {
1371  rInfo = (ResultRelInfo *) lfirst(l);
1372  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1373  return rInfo;
1374  }
1375  /* Nope, so we need a new one */
1376 
1377  /*
1378  * Open the target relation's relcache entry. We assume that an
1379  * appropriate lock is still held by the backend from whenever the trigger
1380  * event got queued, so we need take no new lock here. Also, we need not
1381  * recheck the relkind, so no need for CheckValidResultRel.
1382  */
1383  rel = heap_open(relid, NoLock);
1384 
1385  /*
1386  * Make the new entry in the right context.
1387  */
1388  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1389  rInfo = makeNode(ResultRelInfo);
1390  InitResultRelInfo(rInfo,
1391  rel,
1392  0, /* dummy rangetable index */
1393  NULL,
1394  estate->es_instrument);
1395  estate->es_trig_target_relations =
1396  lappend(estate->es_trig_target_relations, rInfo);
1397  MemoryContextSwitchTo(oldcontext);
1398 
1399  /*
1400  * Currently, we don't need any index information in ResultRelInfos used
1401  * only for triggers, so no need to call ExecOpenIndices.
1402  */
1403 
1404  return rInfo;
1405 }
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, Relation partition_root, int instrument_options)
Definition: execMain.c:1255
Relation ri_RelationDesc
Definition: execnodes.h:373
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:435
#define NoLock
Definition: lockdefs.h:34
ResultRelInfo * es_result_relations
Definition: execnodes.h:420
int es_instrument
Definition: execnodes.h:445
List * lappend(List *list, void *datum)
Definition: list.c:128
List * es_trig_target_relations
Definition: execnodes.h:425
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
int es_num_result_relations
Definition: execnodes.h:421
#define makeNode(_type_)
Definition: nodes.h:554
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
#define RelationGetRelid(relation)
Definition: rel.h:417
ExprState* ExecInitCheck ( List qual,
PlanState parent 
)

Definition at line 246 of file execExpr.c.

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

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:557
Expr * make_ands_explicit(List *andclauses)
Definition: clauses.c:366
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
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, NULL, 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:506
bool resnull
Definition: execnodes.h:62
Expr * expr
Definition: execnodes.h:82
static void ExecInitExprSlots(ExprState *state, Node *node)
Definition: execExpr.c:2137
static void ExecReadyExpr(ExprState *state)
Definition: execExpr.c:568
#define makeNode(_type_)
Definition: nodes.h:554
#define NULL
Definition: c.h:229
Definition: regguts.h:298
intptr_t opcode
Definition: execExpr.h:226
static void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s)
Definition: execExpr.c:2010
static void ExecInitExprRec(Expr *node, PlanState *parent, ExprState *state, Datum *resv, bool *resnull)
Definition: execExpr.c:583
Datum resvalue
Definition: execnodes.h:63
List* ExecInitExprList ( List nodes,
PlanState parent 
)

Definition at line 266 of file execExpr.c.

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

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
return result
Definition: formatting.c:1618
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 423 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().

425 {
427 
428  state->funcReturnsSet = true;
429  state->expr = expr;
430  state->func.fn_oid = InvalidOid;
431 
432  /*
433  * Initialize metadata. The expression node could be either a FuncExpr or
434  * an OpExpr.
435  */
436  if (IsA(expr, FuncExpr))
437  {
438  FuncExpr *func = (FuncExpr *) expr;
439 
440  state->args = ExecInitExprList(func->args, parent);
441  init_sexpr(func->funcid, func->inputcollid, state,
442  econtext->ecxt_per_query_memory, true, true);
443  }
444  else if (IsA(expr, OpExpr))
445  {
446  OpExpr *op = (OpExpr *) expr;
447 
448  state->args = ExecInitExprList(op->args, parent);
449  init_sexpr(op->opfuncid, op->inputcollid, state,
450  econtext->ecxt_per_query_memory, true, true);
451  }
452  else
453  elog(ERROR, "unrecognized node type: %d",
454  (int) nodeTag(expr));
455 
456  /* shouldn't get here unless the selected function returns set */
457  Assert(state->func.fn_retset);
458 
459  return state;
460 }
FmgrInfo func
Definition: execnodes.h:666
#define IsA(nodeptr, _type_)
Definition: nodes.h:557
List * args
Definition: primnodes.h:456
List * args
Definition: execnodes.h:652
bool fn_retset
Definition: fmgr.h:62
Oid funcid
Definition: primnodes.h:448
#define ERROR
Definition: elog.h:43
static void init_sexpr(Oid foid, Oid input_collation, SetExprState *sexpr, MemoryContext sexprCxt, bool allowSRF, bool needDescForSRF)
Definition: execSRF.c:648
bool funcReturnsSet
Definition: execnodes.h:688
List * ExecInitExprList(List *nodes, PlanState *parent)
Definition: execExpr.c:266
Oid opfuncid
Definition: primnodes.h:496
Expr * expr
Definition: execnodes.h:651
#define InvalidOid
Definition: postgres_ext.h:36
Oid fn_oid
Definition: fmgr.h:59
#define makeNode(_type_)
Definition: nodes.h:554
Oid inputcollid
Definition: primnodes.h:455
#define Assert(condition)
Definition: c.h:675
Definition: regguts.h:298
Oid inputcollid
Definition: primnodes.h:500
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:201
#define nodeTag(nodeptr)
Definition: nodes.h:511
#define elog
Definition: elog.h:219
List * args
Definition: primnodes.h:501
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, NULL, 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;
105  cleanResno++;
106  }
107  }
108  }
109  else
110  cleanMap = NULL;
111 
112  /*
113  * Finally create and initialize the JunkFilter struct.
114  */
115  junkfilter = makeNode(JunkFilter);
116 
117  junkfilter->jf_targetList = targetList;
118  junkfilter->jf_cleanTupType = cleanTupType;
119  junkfilter->jf_cleanMap = cleanMap;
120  junkfilter->jf_resultSlot = slot;
121 
122  return junkfilter;
123 }
AttrNumber * jf_cleanMap
Definition: execnodes.h:333
List * jf_targetList
Definition: execnodes.h:331
TupleTableSlot * jf_resultSlot
Definition: execnodes.h:334
int natts
Definition: tupdesc.h:73
bool resjunk
Definition: primnodes.h:1359
TupleDesc jf_cleanTupType
Definition: execnodes.h:332
AttrNumber resno
Definition: primnodes.h:1353
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:199
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
#define makeNode(_type_)
Definition: nodes.h:554
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
void * palloc(Size size)
Definition: mcxt.c:849
TupleDesc ExecCleanTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:900
int16 AttrNumber
Definition: attnum.h:21
JunkFilter* ExecInitJunkFilterConversion ( List targetList,
TupleDesc  cleanTupType,
TupleTableSlot slot 
)

Definition at line 136 of file execJunk.c.

References tupleDesc::attrs, ExecSetSlotDescriptor(), i, JunkFilter::jf_cleanMap, JunkFilter::jf_cleanTupType, JunkFilter::jf_resultSlot, JunkFilter::jf_targetList, lfirst, list_head(), lnext, makeNode, MakeSingleTupleTableSlot(), tupleDesc::natts, NULL, palloc0(), TargetEntry::resjunk, and TargetEntry::resno.

Referenced by check_sql_fn_retval().

139 {
140  JunkFilter *junkfilter;
141  int cleanLength;
142  AttrNumber *cleanMap;
143  ListCell *t;
144  int i;
145 
146  /*
147  * Use the given slot, or make a new slot if we weren't given one.
148  */
149  if (slot)
150  ExecSetSlotDescriptor(slot, cleanTupType);
151  else
152  sl