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 ExecEvalExpr(expr, econtext, isNull)   ((*(expr)->evalfunc) (expr, econtext, isNull))
 
#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)
 
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)
 
void standard_ExecutorRun (QueryDesc *queryDesc, ScanDirection direction, uint64 count)
 
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)
 
Datum GetAttributeByNum (HeapTupleHeader tuple, AttrNumber attrno, bool *isNull)
 
Datum GetAttributeByName (HeapTupleHeader tuple, const char *attname, bool *isNull)
 
TuplestorestateExecMakeTableFunctionResult (ExprState *funcexpr, ExprContext *econtext, MemoryContext argContext, TupleDesc expectedDesc, bool randomAccess)
 
Datum ExecMakeFunctionResultSet (FuncExprState *fcache, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone)
 
Datum ExecEvalExprSwitchContext (ExprState *expression, ExprContext *econtext, bool *isNull)
 
ExprStateExecInitExpr (Expr *node, PlanState *parent)
 
ExprStateExecPrepareExpr (Expr *node, EState *estate)
 
bool ExecQual (List *qual, ExprContext *econtext, bool resultForNull)
 
int ExecTargetListLength (List *targetlist)
 
int ExecCleanTargetListLength (List *targetlist)
 
TupleTableSlotExecProject (ProjectionInfo *projInfo)
 
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)
 
ProjectionInfoExecBuildProjectionInfo (List *targetList, ExprContext *econtext, TupleTableSlot *slot, TupleDesc inputDesc)
 
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 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:564
char bool
Definition: c.h:199
void pfree(void *pointer)
Definition: mcxt.c:992
uintptr_t Datum
Definition: postgres.h:374
text * cstring_to_text(const char *s)
Definition: varlena.c:151
#define DatumGetPointer(X)
Definition: postgres.h:557
void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
Definition: execTuples.c:1250

Definition at line 311 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:332

Definition at line 347 of file executor.h.

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

Typedef Documentation

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

Definition at line 271 of file executor.h.

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

Definition at line 272 of file executor.h.

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

Definition at line 96 of file executor.h.

typedef void(* ExecutorEnd_hook_type)(QueryDesc *queryDesc)

Definition at line 92 of file executor.h.

typedef void(* ExecutorFinish_hook_type)(QueryDesc *queryDesc)

Definition at line 88 of file executor.h.

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

Definition at line 82 of file executor.h.

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

Definition at line 78 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:296
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:199
void * palloc(Size size)
Definition: mcxt.c:891
DestReceiver * dest
Definition: executor.h:297
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:541
#define Min(x, y)
Definition: c.h:802
AttrNumber * keyColIdx
Definition: execnodes.h:533
FmgrInfo * tab_hash_funcs
Definition: execnodes.h:534
FmgrInfo * in_hash_funcs
Definition: execnodes.h:542
struct TupleHashEntryData TupleHashEntryData
MemoryContext tablecxt
Definition: execnodes.h:536
struct TupleHashTableData * TupleHashTable
Definition: execnodes.h:511
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:531
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
TupleTableSlot * tableslot
Definition: execnodes.h:539
size_t Size
Definition: c.h:353
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
FmgrInfo * cur_eq_funcs
Definition: execnodes.h:543
MemoryContext tempcxt
Definition: execnodes.h:537
FmgrInfo * tab_eq_funcs
Definition: execnodes.h:535
void check_exclusion_constraint ( Relation  heap,
Relation  index,
IndexInfo indexInfo,
ItemPointer  tupleid,
Datum values,
bool isnull,
EState estate,
bool  newIndex 
)

Definition at line 867 of file execIndexing.c.

References CEOUC_WAIT, check_exclusion_or_unique_constraint(), and NULL.

Referenced by IndexCheckExclusion(), and unique_key_recheck().

872 {
873  (void) check_exclusion_or_unique_constraint(heap, index, indexInfo, tupleid,
874  values, isnull,
875  estate, newIndex,
876  CEOUC_WAIT, false, NULL);
877 }
static bool check_exclusion_or_unique_constraint(Relation heap, Relation index, IndexInfo *indexInfo, ItemPointer tupleid, Datum *values, bool *isnull, EState *estate, bool newIndex, CEOUC_WAIT_MODE waitMode, bool errorOK, ItemPointer conflictTid)
Definition: execIndexing.c:643
#define NULL
Definition: c.h:226
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:4588
int errcode(int sqlerrcode)
Definition: elog.c:575
Form_pg_class rd_rel
Definition: rel.h:113
#define OidIsValid(objectId)
Definition: c.h:534
#define REPLICA_IDENTITY_FULL
Definition: pg_class.h:179
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define ereport(elevel, rest)
Definition: elog.h:122
struct PublicationActions * GetRelationPublicationActions(Relation relation)
Definition: relcache.c:5084
int errmsg(const char *fmt,...)
Definition: elog.c:797
void CheckValidResultRel ( Relation  resultRel,
CmdType  operation 
)

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

1022 {
1023  TriggerDesc *trigDesc = resultRel->trigdesc;
1024  FdwRoutine *fdwroutine;
1025 
1026  switch (resultRel->rd_rel->relkind)
1027  {
1028  case RELKIND_RELATION:
1030  CheckCmdReplicaIdentity(resultRel, operation);
1031  break;
1032  case RELKIND_SEQUENCE:
1033  ereport(ERROR,
1034  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1035  errmsg("cannot change sequence \"%s\"",
1036  RelationGetRelationName(resultRel))));
1037  break;
1038  case RELKIND_TOASTVALUE:
1039  ereport(ERROR,
1040  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1041  errmsg("cannot change TOAST relation \"%s\"",
1042  RelationGetRelationName(resultRel))));
1043  break;
1044  case RELKIND_VIEW:
1045 
1046  /*
1047  * Okay only if there's a suitable INSTEAD OF trigger. Messages
1048  * here should match rewriteHandler.c's rewriteTargetView, except
1049  * that we omit errdetail because we haven't got the information
1050  * handy (and given that we really shouldn't get here anyway, it's
1051  * not worth great exertion to get).
1052  */
1053  switch (operation)
1054  {
1055  case CMD_INSERT:
1056  if (!trigDesc || !trigDesc->trig_insert_instead_row)
1057  ereport(ERROR,
1058  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1059  errmsg("cannot insert into view \"%s\"",
1060  RelationGetRelationName(resultRel)),
1061  errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule.")));
1062  break;
1063  case CMD_UPDATE:
1064  if (!trigDesc || !trigDesc->trig_update_instead_row)
1065  ereport(ERROR,
1066  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1067  errmsg("cannot update view \"%s\"",
1068  RelationGetRelationName(resultRel)),
1069  errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.")));
1070  break;
1071  case CMD_DELETE:
1072  if (!trigDesc || !trigDesc->trig_delete_instead_row)
1073  ereport(ERROR,
1074  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1075  errmsg("cannot delete from view \"%s\"",
1076  RelationGetRelationName(resultRel)),
1077  errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule.")));
1078  break;
1079  default:
1080  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1081  break;
1082  }
1083  break;
1084  case RELKIND_MATVIEW:
1086  ereport(ERROR,
1087  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1088  errmsg("cannot change materialized view \"%s\"",
1089  RelationGetRelationName(resultRel))));
1090  break;
1091  case RELKIND_FOREIGN_TABLE:
1092  /* Okay only if the FDW supports it */
1093  fdwroutine = GetFdwRoutineForRelation(resultRel, false);
1094  switch (operation)
1095  {
1096  case CMD_INSERT:
1097  if (fdwroutine->ExecForeignInsert == NULL)
1098  ereport(ERROR,
1099  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1100  errmsg("cannot insert into foreign table \"%s\"",
1101  RelationGetRelationName(resultRel))));
1102  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1103  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_INSERT)) == 0)
1104  ereport(ERROR,
1105  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1106  errmsg("foreign table \"%s\" does not allow inserts",
1107  RelationGetRelationName(resultRel))));
1108  break;
1109  case CMD_UPDATE:
1110  if (fdwroutine->ExecForeignUpdate == NULL)
1111  ereport(ERROR,
1112  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1113  errmsg("cannot update foreign table \"%s\"",
1114  RelationGetRelationName(resultRel))));
1115  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1116  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_UPDATE)) == 0)
1117  ereport(ERROR,
1118  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1119  errmsg("foreign table \"%s\" does not allow updates",
1120  RelationGetRelationName(resultRel))));
1121  break;
1122  case CMD_DELETE:
1123  if (fdwroutine->ExecForeignDelete == NULL)
1124  ereport(ERROR,
1125  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1126  errmsg("cannot delete from foreign table \"%s\"",
1127  RelationGetRelationName(resultRel))));
1128  if (fdwroutine->IsForeignRelUpdatable != NULL &&
1129  (fdwroutine->IsForeignRelUpdatable(resultRel) & (1 << CMD_DELETE)) == 0)
1130  ereport(ERROR,
1131  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1132  errmsg("foreign table \"%s\" does not allow deletes",
1133  RelationGetRelationName(resultRel))));
1134  break;
1135  default:
1136  elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1137  break;
1138  }
1139  break;
1140  default:
1141  ereport(ERROR,
1142  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1143  errmsg("cannot change relation \"%s\"",
1144  RelationGetRelationName(resultRel))));
1145  break;
1146  }
1147 }
ExecForeignDelete_function ExecForeignDelete
Definition: fdwapi.h:198
int errhint(const char *fmt,...)
Definition: elog.c:987
bool MatViewIncrementalMaintenanceIsEnabled(void)
Definition: matview.c:836
ExecForeignInsert_function ExecForeignInsert
Definition: fdwapi.h:196
#define RELKIND_MATVIEW
Definition: pg_class.h:167
int errcode(int sqlerrcode)
Definition: elog.c:575
Form_pg_class rd_rel
Definition: rel.h:113
bool trig_insert_instead_row
Definition: reltrigger.h:57
#define ERROR
Definition: elog.h:43
TriggerDesc * trigdesc
Definition: rel.h:119
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:166
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:197
#define NULL
Definition: c.h:226
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:200
#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 72 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().

73 {
74  EState *estate;
75  MemoryContext qcontext;
76  MemoryContext oldcontext;
77 
78  /*
79  * Create the per-query context for this Executor run.
80  */
82  "ExecutorState",
84 
85  /*
86  * Make the EState node within the per-query context. This way, we don't
87  * need a separate pfree() operation for it at shutdown.
88  */
89  oldcontext = MemoryContextSwitchTo(qcontext);
90 
91  estate = makeNode(EState);
92 
93  /*
94  * Initialize all fields of the Executor State structure
95  */
97  estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
98  estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
99  estate->es_range_table = NIL;
100  estate->es_plannedstmt = NULL;
101 
102  estate->es_junkFilter = NULL;
103 
104  estate->es_output_cid = (CommandId) 0;
105 
106  estate->es_result_relations = NULL;
107  estate->es_num_result_relations = 0;
108  estate->es_result_relation_info = NULL;
109 
110  estate->es_trig_target_relations = NIL;
111  estate->es_trig_tuple_slot = NULL;
112  estate->es_trig_oldtup_slot = NULL;
113  estate->es_trig_newtup_slot = NULL;
114 
115  estate->es_param_list_info = NULL;
116  estate->es_param_exec_vals = NULL;
117 
118  estate->es_query_cxt = qcontext;
119 
120  estate->es_tupleTable = NIL;
121 
122  estate->es_rowMarks = NIL;
123 
124  estate->es_processed = 0;
125  estate->es_lastoid = InvalidOid;
126 
127  estate->es_top_eflags = 0;
128  estate->es_instrument = 0;
129  estate->es_finished = false;
130 
131  estate->es_exprcontexts = NIL;
132 
133  estate->es_subplanstates = NIL;
134 
135  estate->es_auxmodifytables = NIL;
136 
137  estate->es_per_tuple_exprcontext = NULL;
138 
139  estate->es_epqTuple = NULL;
140  estate->es_epqTupleSet = NULL;
141  estate->es_epqScanDone = NULL;
142  estate->es_sourceText = NULL;
143 
144  /*
145  * Return the executor state structure
146  */
147  MemoryContextSwitchTo(oldcontext);
148 
149  return estate;
150 }
#define NIL
Definition: pg_list.h:69
uint32 CommandId
Definition: c.h:408
HeapTuple * es_epqTuple
Definition: execnodes.h:432
JunkFilter * es_junkFilter
Definition: execnodes.h:376
CommandId es_output_cid
Definition: execnodes.h:379
TupleTableSlot * es_trig_newtup_slot
Definition: execnodes.h:390
Oid es_lastoid
Definition: execnodes.h:404
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlannedStmt * es_plannedstmt
Definition: execnodes.h:373
Snapshot es_crosscheck_snapshot
Definition: execnodes.h:371
ExprContext * es_per_tuple_exprcontext
Definition: execnodes.h:421
Snapshot es_snapshot
Definition: execnodes.h:370
List * es_range_table
Definition: execnodes.h:372
ScanDirection es_direction
Definition: execnodes.h:369
const char * es_sourceText
Definition: execnodes.h:374
ParamExecData * es_param_exec_vals
Definition: execnodes.h:394
MemoryContext es_query_cxt
Definition: execnodes.h:397
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:145
ResultRelInfo * es_result_relations
Definition: execnodes.h:382
TupleTableSlot * es_trig_oldtup_slot
Definition: execnodes.h:389
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
int es_instrument
Definition: execnodes.h:407
TupleTableSlot * es_trig_tuple_slot
Definition: execnodes.h:388
#define InvalidSnapshot
Definition: snapshot.h:25
List * es_trig_target_relations
Definition: execnodes.h:387
List * es_tupleTable
Definition: execnodes.h:399
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:440
List * es_auxmodifytables
Definition: execnodes.h:414
int es_num_result_relations
Definition: execnodes.h:383
#define InvalidOid
Definition: postgres_ext.h:36
bool es_finished
Definition: execnodes.h:408
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
uint64 es_processed
Definition: execnodes.h:403
bool * es_epqTupleSet
Definition: execnodes.h:433
List * es_subplanstates
Definition: execnodes.h:412
List * es_rowMarks
Definition: execnodes.h:401
int es_top_eflags
Definition: execnodes.h:406
bool * es_epqScanDone
Definition: execnodes.h:434
ParamListInfo es_param_list_info
Definition: execnodes.h:393
List * es_exprcontexts
Definition: execnodes.h:410
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:384
ExprContext* CreateExprContext ( EState estate)

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

209 {
210  ExprContext *econtext;
211  MemoryContext oldcontext;
212 
213  /* Create the ExprContext node within the per-query memory context */
214  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
215 
216  econtext = makeNode(ExprContext);
217 
218  /* Initialize fields of ExprContext */
219  econtext->ecxt_scantuple = NULL;
220  econtext->ecxt_innertuple = NULL;
221  econtext->ecxt_outertuple = NULL;
222 
223  econtext->ecxt_per_query_memory = estate->es_query_cxt;
224 
225  /*
226  * Create working memory for expression evaluation in this context.
227  */
228  econtext->ecxt_per_tuple_memory =
230  "ExprContext",
232 
233  econtext->ecxt_param_exec_vals = estate->es_param_exec_vals;
234  econtext->ecxt_param_list_info = estate->es_param_list_info;
235 
236  econtext->ecxt_aggvalues = NULL;
237  econtext->ecxt_aggnulls = NULL;
238 
239  econtext->caseValue_datum = (Datum) 0;
240  econtext->caseValue_isNull = true;
241 
242  econtext->domainValue_datum = (Datum) 0;
243  econtext->domainValue_isNull = true;
244 
245  econtext->ecxt_estate = estate;
246 
247  econtext->ecxt_callbacks = NULL;
248 
249  /*
250  * Link the ExprContext into the EState to ensure it is shut down when the
251  * EState is freed. Because we use lcons(), shutdowns will occur in
252  * reverse order of creation, which may not be essential but can't hurt.
253  */
254  estate->es_exprcontexts = lcons(econtext, estate->es_exprcontexts);
255 
256  MemoryContextSwitchTo(oldcontext);
257 
258  return econtext;
259 }
Datum * ecxt_aggvalues
Definition: execnodes.h:144
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:134
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum domainValue_datum
Definition: execnodes.h:152
ParamExecData * es_param_exec_vals
Definition: execnodes.h:394
MemoryContext es_query_cxt
Definition: execnodes.h:397
Datum caseValue_datum
Definition: execnodes.h:148
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:159
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:145
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:129
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:137
struct EState * ecxt_estate
Definition: execnodes.h:156
bool domainValue_isNull
Definition: execnodes.h:153
bool * ecxt_aggnulls
Definition: execnodes.h:145
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:440
uintptr_t Datum
Definition: postgres.h:374
List * lcons(void *datum, List *list)
Definition: list.c:259
#define makeNode(_type_)
Definition: nodes.h:556
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:130
#define NULL
Definition: c.h:226
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
bool caseValue_isNull
Definition: execnodes.h:149
ParamListInfo es_param_list_info
Definition: execnodes.h:393
List * es_exprcontexts
Definition: execnodes.h:410
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:138
ExprContext* CreateStandaloneExprContext ( void  )

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

281 {
282  ExprContext *econtext;
283 
284  /* Create the ExprContext node within the caller's memory context */
285  econtext = makeNode(ExprContext);
286 
287  /* Initialize fields of ExprContext */
288  econtext->ecxt_scantuple = NULL;
289  econtext->ecxt_innertuple = NULL;
290  econtext->ecxt_outertuple = NULL;
291 
293 
294  /*
295  * Create working memory for expression evaluation in this context.
296  */
297  econtext->ecxt_per_tuple_memory =
299  "ExprContext",
301 
302  econtext->ecxt_param_exec_vals = NULL;
303  econtext->ecxt_param_list_info = NULL;
304 
305  econtext->ecxt_aggvalues = NULL;
306  econtext->ecxt_aggnulls = NULL;
307 
308  econtext->caseValue_datum = (Datum) 0;
309  econtext->caseValue_isNull = true;
310 
311  econtext->domainValue_datum = (Datum) 0;
312  econtext->domainValue_isNull = true;
313 
314  econtext->ecxt_estate = NULL;
315 
316  econtext->ecxt_callbacks = NULL;
317 
318  return econtext;
319 }
Datum * ecxt_aggvalues
Definition: execnodes.h:144
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:134
Datum domainValue_datum
Definition: execnodes.h:152
Datum caseValue_datum
Definition: execnodes.h:148
ExprContext_CB * ecxt_callbacks
Definition: execnodes.h:159
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:145
TupleTableSlot * ecxt_innertuple
Definition: execnodes.h:129
ParamExecData * ecxt_param_exec_vals
Definition: execnodes.h:137
struct EState * ecxt_estate
Definition: execnodes.h:156
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
bool domainValue_isNull
Definition: execnodes.h:153
bool * ecxt_aggnulls
Definition: execnodes.h:145
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:440
uintptr_t Datum
Definition: postgres.h:374
#define makeNode(_type_)
Definition: nodes.h:556
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:130
#define NULL
Definition: c.h:226
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:128
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:133
bool caseValue_isNull
Definition: execnodes.h:149
ParamListInfo ecxt_param_list_info
Definition: execnodes.h:138
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:564
void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
Definition: execTuples.c:1250
void pfree(void *pointer)
Definition: mcxt.c:992
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:163
uintptr_t Datum
Definition: postgres.h:374
#define DatumGetPointer(X)
Definition: postgres.h:557
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:296
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:374
static Datum values[MAXATTR]
Definition: bootstrap.c:162
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:118
DestReceiver * dest
Definition: executor.h:297
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:296
void pfree(void *pointer)
Definition: mcxt.c:992
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:216
DestReceiver * dest
Definition: executor.h:297
TupleTableSlot* EvalPlanQual ( EState estate,
EPQState epqstate,
Relation  relation,
Index  rti,
int  lockmode,
ItemPointer  tid,
TransactionId  priorXmax 
)

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

2306 {
2307  TupleTableSlot *slot;
2308  HeapTuple copyTuple;
2309 
2310  Assert(rti > 0);
2311 
2312  /*
2313  * Get and lock the updated version of the row; if fail, return NULL.
2314  */
2315  copyTuple = EvalPlanQualFetch(estate, relation, lockmode, LockWaitBlock,
2316  tid, priorXmax);
2317 
2318  if (copyTuple == NULL)
2319  return NULL;
2320 
2321  /*
2322  * For UPDATE/DELETE we have to return tid of actual row we're executing
2323  * PQ for.
2324  */
2325  *tid = copyTuple->t_self;
2326 
2327  /*
2328  * Need to run a recheck subquery. Initialize or reinitialize EPQ state.
2329  */
2330  EvalPlanQualBegin(epqstate, estate);
2331 
2332  /*
2333  * Free old test tuple, if any, and store new tuple where relation's scan
2334  * node will see it
2335  */
2336  EvalPlanQualSetTuple(epqstate, rti, copyTuple);
2337 
2338  /*
2339  * Fetch any non-locked source rows
2340  */
2341  EvalPlanQualFetchRowMarks(epqstate);
2342 
2343  /*
2344  * Run the EPQ query. We assume it will return at most one tuple.
2345  */
2346  slot = EvalPlanQualNext(epqstate);
2347 
2348  /*
2349  * If we got a tuple, force the slot to materialize the tuple so that it
2350  * is not dependent on any local state in the EPQ query (in particular,
2351  * it's highly likely that the slot contains references to any pass-by-ref
2352  * datums that may be present in copyTuple). As with the next step, this
2353  * is to guard against early re-use of the EPQ query.
2354  */
2355  if (!TupIsNull(slot))
2356  (void) ExecMaterializeSlot(slot);
2357 
2358  /*
2359  * Clear out the test tuple. This is needed in case the EPQ query is
2360  * re-used to test a tuple for a different relation. (Not clear that can
2361  * really happen, but let's be safe.)
2362  */
2363  EvalPlanQualSetTuple(epqstate, rti, NULL);
2364 
2365  return slot;
2366 }
void EvalPlanQualSetTuple(EPQState *epqstate, Index rti, HeapTuple tuple)
Definition: execMain.c:2654
HeapTuple EvalPlanQualFetch(EState *estate, Relation relation, int lockmode, LockWaitPolicy wait_policy, ItemPointer tid, TransactionId priorXmax)
Definition: execMain.c:2390
void EvalPlanQualFetchRowMarks(EPQState *epqstate)
Definition: execMain.c:2689
void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate)
Definition: execMain.c:2840
TupleTableSlot * EvalPlanQualNext(EPQState *epqstate)
Definition: execMain.c:2824
ItemPointerData t_self
Definition: htup.h:65
#define TupIsNull(slot)
Definition: tuptable.h:138
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
HeapTuple ExecMaterializeSlot(TupleTableSlot *slot)
Definition: execTuples.c:725
void EvalPlanQualBegin ( EPQState epqstate,
EState parentestate 
)

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

2841 {
2842  EState *estate = epqstate->estate;
2843 
2844  if (estate == NULL)
2845  {
2846  /* First time through, so create a child EState */
2847  EvalPlanQualStart(epqstate, parentestate, epqstate->plan);
2848  }
2849  else
2850  {
2851  /*
2852  * We already have a suitable child EPQ tree, so just reset it.
2853  */
2854  int rtsize = list_length(parentestate->es_range_table);
2855  PlanState *planstate = epqstate->planstate;
2856 
2857  MemSet(estate->es_epqScanDone, 0, rtsize * sizeof(bool));
2858 
2859  /* Recopy current values of parent parameters */
2860  if (parentestate->es_plannedstmt->nParamExec > 0)
2861  {
2862  int i = parentestate->es_plannedstmt->nParamExec;
2863 
2864  while (--i >= 0)
2865  {
2866  /* copy value if any, but not execPlan link */
2867  estate->es_param_exec_vals[i].value =
2868  parentestate->es_param_exec_vals[i].value;
2869  estate->es_param_exec_vals[i].isnull =
2870  parentestate->es_param_exec_vals[i].isnull;
2871  }
2872  }
2873 
2874  /*
2875  * Mark child plan tree as needing rescan at all scan nodes. The
2876  * first ExecProcNode will take care of actually doing the rescan.
2877  */
2878  planstate->chgParam = bms_add_member(planstate->chgParam,
2879  epqstate->epqParam);
2880  }
2881 }
PlannedStmt * es_plannedstmt
Definition: execnodes.h:373
#define MemSet(start, val, len)
Definition: c.h:853
List * es_range_table
Definition: execnodes.h:372
PlanState * planstate
Definition: execnodes.h:1112
int nParamExec
Definition: plannodes.h:78
ParamExecData * es_param_exec_vals
Definition: execnodes.h:394
bool isnull
Definition: params.h:101
static void EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
Definition: execMain.c:2890
Bitmapset * chgParam
Definition: execnodes.h:1072
Plan * plan
Definition: execnodes.h:1114
#define NULL
Definition: c.h:226
static int list_length(const List *l)
Definition: pg_list.h:89
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:668
int i
bool * es_epqScanDone
Definition: execnodes.h:434
Datum value
Definition: params.h:100
int epqParam
Definition: execnodes.h:1116
EState * estate
Definition: execnodes.h:1111
void EvalPlanQualEnd ( EPQState epqstate)

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

3031 {
3032  EState *estate = epqstate->estate;
3033  MemoryContext oldcontext;
3034  ListCell *l;
3035 
3036  if (estate == NULL)
3037  return; /* idle, so nothing to do */
3038 
3039  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
3040 
3041  ExecEndNode(epqstate->planstate);
3042 
3043  foreach(l, estate->es_subplanstates)
3044  {
3045  PlanState *subplanstate = (PlanState *) lfirst(l);
3046 
3047  ExecEndNode(subplanstate);
3048  }
3049 
3050  /* throw away the per-estate tuple table */
3051  ExecResetTupleTable(estate->es_tupleTable, false);
3052 
3053  /* close any trigger target relations attached to this EState */
3054  foreach(l, estate->es_trig_target_relations)
3055  {
3056  ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l);
3057 
3058  /* Close indices and then the relation itself */
3059  ExecCloseIndices(resultRelInfo);
3060  heap_close(resultRelInfo->ri_RelationDesc, NoLock);
3061  }
3062 
3063  MemoryContextSwitchTo(oldcontext);
3064 
3065  FreeExecutorState(estate);
3066 
3067  /* Mark EPQState idle */
3068  epqstate->estate = NULL;
3069  epqstate->planstate = NULL;
3070  epqstate->origslot = NULL;
3071 }
Relation ri_RelationDesc
Definition: execnodes.h:335
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:624
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define heap_close(r, l)
Definition: heapam.h:97
PlanState * planstate
Definition: execnodes.h:1112
void FreeExecutorState(EState *estate)
Definition: execUtils.c:168
MemoryContext es_query_cxt
Definition: execnodes.h:397
#define NoLock
Definition: lockdefs.h:34
TupleTableSlot * origslot
Definition: execnodes.h:1113
List * es_trig_target_relations
Definition: execnodes.h:387
List * es_tupleTable
Definition: execnodes.h:399
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:156
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
List * es_subplanstates
Definition: execnodes.h:412
EState * estate
Definition: execnodes.h:1111
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 2390 of file execMain.c.

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

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

References EPQState::arowMarks, Assert, 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().

2690 {
2691  ListCell *l;
2692 
2693  Assert(epqstate->origslot != NULL);
2694 
2695  foreach(l, epqstate->arowMarks)
2696  {
2697  ExecAuxRowMark *aerm = (ExecAuxRowMark *) lfirst(l);
2698  ExecRowMark *erm = aerm->rowmark;
2699  Datum datum;
2700  bool isNull;
2701  HeapTupleData tuple;
2702 
2704  elog(ERROR, "EvalPlanQual doesn't support locking rowmarks");
2705 
2706  /* clear any leftover test tuple for this rel */
2707  EvalPlanQualSetTuple(epqstate, erm->rti, NULL);
2708 
2709  /* if child rel, must check whether it produced this row */
2710  if (erm->rti != erm->prti)
2711  {
2712  Oid tableoid;
2713 
2714  datum = ExecGetJunkAttribute(epqstate->origslot,
2715  aerm->toidAttNo,
2716  &isNull);
2717  /* non-locked rels could be on the inside of outer joins */
2718  if (isNull)
2719  continue;
2720  tableoid = DatumGetObjectId(datum);
2721 
2722  Assert(OidIsValid(erm->relid));
2723  if (tableoid != erm->relid)
2724  {
2725  /* this child is inactive right now */
2726  continue;
2727  }
2728  }
2729 
2730  if (erm->markType == ROW_MARK_REFERENCE)
2731  {
2732  HeapTuple copyTuple;
2733 
2734  Assert(erm->relation != NULL);
2735 
2736  /* fetch the tuple's ctid */
2737  datum = ExecGetJunkAttribute(epqstate->origslot,
2738  aerm->ctidAttNo,
2739  &isNull);
2740  /* non-locked rels could be on the inside of outer joins */
2741  if (isNull)
2742  continue;
2743 
2744  /* fetch requests on foreign tables must be passed to their FDW */
2745  if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2746  {
2747  FdwRoutine *fdwroutine;
2748  bool updated = false;
2749 
2750  fdwroutine = GetFdwRoutineForRelation(erm->relation, false);
2751  /* this should have been checked already, but let's be safe */
2752  if (fdwroutine->RefetchForeignRow == NULL)
2753  ereport(ERROR,
2754  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2755  errmsg("cannot lock rows in foreign table \"%s\"",
2757  copyTuple = fdwroutine->RefetchForeignRow(epqstate->estate,
2758  erm,
2759  datum,
2760  &updated);
2761  if (copyTuple == NULL)
2762  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2763 
2764  /*
2765  * Ideally we'd insist on updated == false here, but that
2766  * assumes that FDWs can track that exactly, which they might
2767  * not be able to. So just ignore the flag.
2768  */
2769  }
2770  else
2771  {
2772  /* ordinary table, fetch the tuple */
2773  Buffer buffer;
2774 
2775  tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
2776  if (!heap_fetch(erm->relation, SnapshotAny, &tuple, &buffer,
2777  false, NULL))
2778  elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2779 
2780  /* successful, copy tuple */
2781  copyTuple = heap_copytuple(&tuple);
2782  ReleaseBuffer(buffer);
2783  }
2784 
2785  /* store tuple */
2786  EvalPlanQualSetTuple(epqstate, erm->rti, copyTuple);
2787  }
2788  else
2789  {
2790  HeapTupleHeader td;
2791 
2792  Assert(erm->markType == ROW_MARK_COPY);
2793 
2794  /* fetch the whole-row Var for the relation */
2795  datum = ExecGetJunkAttribute(epqstate->origslot,
2796  aerm->wholeAttNo,
2797  &isNull);
2798  /* non-locked rels could be on the inside of outer joins */
2799  if (isNull)
2800  continue;
2801  td = DatumGetHeapTupleHeader(datum);
2802 
2803  /* build a temporary HeapTuple control structure */
2805  tuple.t_data = td;
2806  /* relation might be a foreign table, if so provide tableoid */
2807  tuple.t_tableOid = erm->relid;
2808  /* also copy t_ctid in case there's valid data there */
2809  tuple.t_self = td->t_ctid;
2810 
2811  /* copy and store tuple */
2812  EvalPlanQualSetTuple(epqstate, erm->rti,
2813  heap_copytuple(&tuple));
2814  }
2815  }
2816 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
void EvalPlanQualSetTuple(EPQState *epqstate, Index rti, HeapTuple tuple)
Definition: execMain.c:2654
Relation relation
Definition: execnodes.h:460
bool heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tuple, Buffer *userbuf, bool keep_buf, Relation stats_relation)
Definition: heapam.c:1849
#define DatumGetObjectId(X)
Definition: postgres.h:508
int errcode(int sqlerrcode)
Definition: elog.c:575
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3292
Form_pg_class rd_rel
Definition: rel.h:113
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:254
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:897
ItemPointerData * ItemPointer
Definition: itemptr.h:48
ExecRowMark * rowmark
Definition: execnodes.h:487
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:1115
uint32 t_len
Definition: htup.h:64
Index rti
Definition: execnodes.h:462
AttrNumber wholeAttNo
Definition: execnodes.h:490
Index prti
Definition: execnodes.h:463
#define RelationGetRelationName(relation)
Definition: rel.h:433
Oid t_tableOid
Definition: htup.h:66
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:166
TupleTableSlot * origslot
Definition: execnodes.h:1113
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:374
#define SnapshotAny
Definition: tqual.h:28
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define lfirst(lc)
Definition: pg_list.h:106
RowMarkType markType
Definition: execnodes.h:465
AttrNumber toidAttNo
Definition: execnodes.h:489
#define DatumGetPointer(X)
Definition: postgres.h:557
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:1111
int Buffer
Definition: buf.h:23
AttrNumber ctidAttNo
Definition: execnodes.h:488
RefetchForeignRow_function RefetchForeignRow
Definition: fdwapi.h:208
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
HeapTuple EvalPlanQualGetTuple ( EPQState epqstate,
Index  rti 
)

Definition at line 2674 of file execMain.c.

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

2675 {
2676  EState *estate = epqstate->estate;
2677 
2678  Assert(rti > 0);
2679 
2680  return estate->es_epqTuple[rti - 1];
2681 }
HeapTuple * es_epqTuple
Definition: execnodes.h:432
#define Assert(condition)
Definition: c.h:671
EState * estate
Definition: execnodes.h:1111
void EvalPlanQualInit ( EPQState epqstate,
EState estate,
Plan subplan,
List auxrowmarks,
int  epqParam 
)

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

2621 {
2622  /* Mark the EPQ state inactive */
2623  epqstate->estate = NULL;
2624  epqstate->planstate = NULL;
2625  epqstate->origslot = NULL;
2626  /* ... and remember data that EvalPlanQualBegin will need */
2627  epqstate->plan = subplan;
2628  epqstate->arowMarks = auxrowmarks;
2629  epqstate->epqParam = epqParam;
2630 }
PlanState * planstate
Definition: execnodes.h:1112
List * arowMarks
Definition: execnodes.h:1115
TupleTableSlot * origslot
Definition: execnodes.h:1113
Plan * plan
Definition: execnodes.h:1114
#define NULL
Definition: c.h:226
int epqParam
Definition: execnodes.h:1116
EState * estate
Definition: execnodes.h:1111
TupleTableSlot* EvalPlanQualNext ( EPQState epqstate)

Definition at line 2824 of file execMain.c.

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

Referenced by EvalPlanQual(), and ExecLockRows().

2825 {
2826  MemoryContext oldcontext;
2827  TupleTableSlot *slot;
2828 
2829  oldcontext = MemoryContextSwitchTo(epqstate->estate->es_query_cxt);
2830  slot = ExecProcNode(epqstate->planstate);
2831  MemoryContextSwitchTo(oldcontext);
2832 
2833  return slot;
2834 }
TupleTableSlot * ExecProcNode(PlanState *node)
Definition: execProcnode.c:380
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PlanState * planstate
Definition: execnodes.h:1112
MemoryContext es_query_cxt
Definition: execnodes.h:397
EState * estate
Definition: execnodes.h:1111
void EvalPlanQualSetPlan ( EPQState epqstate,
Plan subplan,
List auxrowmarks 
)

Definition at line 2638 of file execMain.c.

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

Referenced by ExecInitModifyTable(), and ExecModifyTable().

2639 {
2640  /* If we have a live EPQ query, shut it down */
2641  EvalPlanQualEnd(epqstate);
2642  /* And set/change the plan pointer */
2643  epqstate->plan = subplan;
2644  /* The rowmarks depend on the plan, too */
2645  epqstate->arowMarks = auxrowmarks;
2646 }
void EvalPlanQualEnd(EPQState *epqstate)
Definition: execMain.c:3030
List * arowMarks
Definition: execnodes.h:1115
Plan * plan
Definition: execnodes.h:1114
void EvalPlanQualSetTuple ( EPQState epqstate,
Index  rti,
HeapTuple  tuple 
)

Definition at line 2654 of file execMain.c.

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

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

2655 {
2656  EState *estate = epqstate->estate;
2657 
2658  Assert(rti > 0);
2659 
2660  /*
2661  * free old test tuple, if any, and store new tuple where relation's scan
2662  * node will see it
2663  */
2664  if (estate->es_epqTuple[rti - 1] != NULL)
2665  heap_freetuple(estate->es_epqTuple[rti - 1]);
2666  estate->es_epqTuple[rti - 1] = tuple;
2667  estate->es_epqTupleSet[rti - 1] = true;
2668 }
HeapTuple * es_epqTuple
Definition: execnodes.h:432
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
bool * es_epqTupleSet
Definition: execnodes.h:433
EState * estate
Definition: execnodes.h:1111
void ExecAssignProjectionInfo ( PlanState planstate,
TupleDesc  inputDesc 
)

Definition at line 657 of file execUtils.c.

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

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

659 {
660  planstate->ps_ProjInfo =
662  planstate->ps_ExprContext,
663  planstate->ps_ResultTupleSlot,
664  inputDesc);
665 }
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1079
ExprContext * ps_ExprContext
Definition: execnodes.h:1078
List * targetlist
Definition: execnodes.h:1061
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1077
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, TupleDesc inputDesc)
Definition: execUtils.c:482
void ExecAssignResultType ( PlanState planstate,
TupleDesc  tupDesc 
)

Definition at line 418 of file execUtils.c.

References ExecSetSlotDescriptor(), and PlanState::ps_ResultTupleSlot.

Referenced by ExecAssignResultTypeFromTL(), and ExecInitModifyTable().

419 {
420  TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
421 
422  ExecSetSlotDescriptor(slot, tupDesc);
423 }
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:1077
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
void ExecAssignResultTypeFromTL ( PlanState planstate)

Definition at line 430 of file execUtils.c.

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

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

431 {
432  bool hasoid;
433  TupleDesc tupDesc;
434 
435  if (ExecContextForcesOids(planstate, &hasoid))
436  {
437  /* context forces OID choice; hasoid is now set correctly */
438  }
439  else
440  {
441  /* given free choice, don't leave space for OIDs in result tuples */
442  hasoid = false;
443  }
444 
445  /*
446  * ExecTypeFromTL needs the parse-time representation of the tlist, not a
447  * list of ExprStates. This is good because some plan nodes don't bother
448  * to set up planstate->targetlist ...
449  */
450  tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
451  ExecAssignResultType(planstate, tupDesc);
452 }
void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc)
Definition: execUtils.c:418
TupleDesc ExecTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:888
Plan * plan
Definition: execnodes.h:1047
List * targetlist
Definition: plannodes.h:129
bool ExecContextForcesOids(PlanState *planstate, bool *hasoids)
Definition: execMain.c:1406
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:305
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:1079
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1291
PlanState ps
Definition: execnodes.h:1288
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:657
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:1047
#define NULL
Definition: c.h:226
List * targetlist
Definition: plannodes.h:129
void ExecAssignScanType ( ScanState scanstate,
TupleDesc  tupDesc 
)
void ExecAssignScanTypeFromOuterPlan ( ScanState scanstate)

Definition at line 721 of file execUtils.c.

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

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

722 {
724  TupleDesc tupDesc;
725 
726  outerPlan = outerPlanState(scanstate);
727  tupDesc = ExecGetResultType(outerPlan);
728 
729  ExecAssignScanType(scanstate, tupDesc);
730 }
#define outerPlanState(node)
Definition: execnodes.h:1090
#define outerPlan(node)
Definition: plannodes.h:159
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:459
void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc)
Definition: execUtils.c:709
ExecAuxRowMark* ExecBuildAuxRowMark ( ExecRowMark erm,
List targetlist 
)

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

2233 {
2234  ExecAuxRowMark *aerm = (ExecAuxRowMark *) palloc0(sizeof(ExecAuxRowMark));
2235  char resname[32];
2236 
2237  aerm->rowmark = erm;
2238 
2239  /* Look up the resjunk columns associated with this rowmark */
2240  if (erm->markType != ROW_MARK_COPY)
2241  {
2242  /* need ctid for all methods other than COPY */
2243  snprintf(resname, sizeof(resname), "ctid%u", erm->rowmarkId);
2244  aerm->ctidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2245  resname);
2246  if (!AttributeNumberIsValid(aerm->ctidAttNo))
2247  elog(ERROR, "could not find junk %s column", resname);
2248  }
2249  else
2250  {
2251  /* need wholerow if COPY */
2252  snprintf(resname, sizeof(resname), "wholerow%u", erm->rowmarkId);
2253  aerm->wholeAttNo = ExecFindJunkAttributeInTlist(targetlist,
2254  resname);
2255  if (!AttributeNumberIsValid(aerm->wholeAttNo))
2256  elog(ERROR, "could not find junk %s column", resname);
2257  }
2258 
2259  /* if child rel, need tableoid */
2260  if (erm->rti != erm->prti)
2261  {
2262  snprintf(resname, sizeof(resname), "tableoid%u", erm->rowmarkId);
2263  aerm->toidAttNo = ExecFindJunkAttributeInTlist(targetlist,
2264  resname);
2265  if (!AttributeNumberIsValid(aerm->toidAttNo))
2266  elog(ERROR, "could not find junk %s column", resname);
2267  }
2268 
2269  return aerm;
2270 }
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:487
#define ERROR
Definition: elog.h:43
Index rti
Definition: execnodes.h:462
AttrNumber wholeAttNo
Definition: execnodes.h:490
Index prti
Definition: execnodes.h:463
Index rowmarkId
Definition: execnodes.h:464
#define AttributeNumberIsValid(attributeNumber)
Definition: attnum.h:34
void * palloc0(Size size)
Definition: mcxt.c:920
RowMarkType markType
Definition: execnodes.h:465
AttrNumber toidAttNo
Definition: execnodes.h:489
#define elog
Definition: elog.h:219
AttrNumber ctidAttNo
Definition: execnodes.h:488
ProjectionInfo* ExecBuildProjectionInfo ( List targetList,
ExprContext econtext,
TupleTableSlot slot,
TupleDesc  inputDesc 
)

Definition at line 482 of file execUtils.c.

References GenericExprState::arg, tupleDesc::attrs, ExecTargetListLength(), ExprState::expr, get_last_attnums(), INNER_VAR, IsA, lappend(), lfirst, makeNode, tupleDesc::natts, NIL, NULL, offsetof, OUTER_VAR, palloc(), ProjectionInfo::pi_directMap, ProjectionInfo::pi_exprContext, ProjectionInfo::pi_lastInnerVar, ProjectionInfo::pi_lastOuterVar, ProjectionInfo::pi_lastScanVar, ProjectionInfo::pi_numSimpleVars, ProjectionInfo::pi_slot, ProjectionInfo::pi_targetlist, ProjectionInfo::pi_varNumbers, ProjectionInfo::pi_varOutputCols, ProjectionInfo::pi_varSlotOffsets, TargetEntry::resno, Var::varattno, Var::varno, Var::vartype, and GenericExprState::xprstate.

Referenced by ExecAssignProjectionInfo(), ExecInitAgg(), ExecInitModifyTable(), and ExecInitSubPlan().

486 {
488  int len = ExecTargetListLength(targetList);
489  int *workspace;
490  int *varSlotOffsets;
491  int *varNumbers;
492  int *varOutputCols;
493  List *exprlist;
494  int numSimpleVars;
495  bool directMap;
496  ListCell *tl;
497 
498  projInfo->pi_exprContext = econtext;
499  projInfo->pi_slot = slot;
500  /* since these are all int arrays, we need do just one palloc */
501  workspace = (int *) palloc(len * 3 * sizeof(int));
502  projInfo->pi_varSlotOffsets = varSlotOffsets = workspace;
503  projInfo->pi_varNumbers = varNumbers = workspace + len;
504  projInfo->pi_varOutputCols = varOutputCols = workspace + len * 2;
505  projInfo->pi_lastInnerVar = 0;
506  projInfo->pi_lastOuterVar = 0;
507  projInfo->pi_lastScanVar = 0;
508 
509  /*
510  * We separate the target list elements into simple Var references and
511  * expressions which require the full ExecTargetList machinery. To be a
512  * simple Var, a Var has to be a user attribute and not mismatch the
513  * inputDesc. (Note: if there is a type mismatch then ExecEvalScalarVar
514  * will probably throw an error at runtime, but we leave that to it.)
515  */
516  exprlist = NIL;
517  numSimpleVars = 0;
518  directMap = true;
519  foreach(tl, targetList)
520  {
521  GenericExprState *gstate = (GenericExprState *) lfirst(tl);
522  Var *variable = (Var *) gstate->arg->expr;
523  bool isSimpleVar = false;
524 
525  if (variable != NULL &&
526  IsA(variable, Var) &&
527  variable->varattno > 0)
528  {
529  if (!inputDesc)
530  isSimpleVar = true; /* can't check type, assume OK */
531  else if (variable->varattno <= inputDesc->natts)
532  {
533  Form_pg_attribute attr;
534 
535  attr = inputDesc->attrs[variable->varattno - 1];
536  if (!attr->attisdropped && variable->vartype == attr->atttypid)
537  isSimpleVar = true;
538  }
539  }
540 
541  if (isSimpleVar)
542  {
543  TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
544  AttrNumber attnum = variable->varattno;
545 
546  varNumbers[numSimpleVars] = attnum;
547  varOutputCols[numSimpleVars] = tle->resno;
548  if (tle->resno != numSimpleVars + 1)
549  directMap = false;
550 
551  switch (variable->varno)
552  {
553  case INNER_VAR:
554  varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
555  ecxt_innertuple);
556  if (projInfo->pi_lastInnerVar < attnum)
557  projInfo->pi_lastInnerVar = attnum;
558  break;
559 
560  case OUTER_VAR:
561  varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
562  ecxt_outertuple);
563  if (projInfo->pi_lastOuterVar < attnum)
564  projInfo->pi_lastOuterVar = attnum;
565  break;
566 
567  /* INDEX_VAR is handled by default case */
568 
569  default:
570  varSlotOffsets[numSimpleVars] = offsetof(ExprContext,
571  ecxt_scantuple);
572  if (projInfo->pi_lastScanVar < attnum)
573  projInfo->pi_lastScanVar = attnum;
574  break;
575  }
576  numSimpleVars++;
577  }
578  else
579  {
580  /* Not a simple variable, add it to generic targetlist */
581  exprlist = lappend(exprlist, gstate);
582  /* Examine expr to include contained Vars in lastXXXVar counts */
583  get_last_attnums((Node *) variable, projInfo);
584  }
585  }
586  projInfo->pi_targetlist = exprlist;
587  projInfo->pi_numSimpleVars = numSimpleVars;
588  projInfo->pi_directMap = directMap;
589 
590  return projInfo;
591 }
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
ExprState xprstate
Definition: execnodes.h:611
int ExecTargetListLength(List *targetlist)
Definition: execQual.c:5122
Form_pg_attribute * attrs
Definition: tupdesc.h:74
Definition: nodes.h:508
AttrNumber varattno
Definition: primnodes.h:146
int * pi_varSlotOffsets
Definition: execnodes.h:254
Definition: primnodes.h:141
int natts
Definition: tupdesc.h:73
int pi_lastScanVar
Definition: execnodes.h:259
List * pi_targetlist
Definition: execnodes.h:249
Expr * expr
Definition: execnodes.h:598
Oid vartype
Definition: primnodes.h:148
TupleTableSlot * pi_slot
Definition: execnodes.h:251
AttrNumber resno
Definition: primnodes.h:1331
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
int * pi_varNumbers
Definition: execnodes.h:255
List * lappend(List *list, void *datum)
Definition: list.c:128
Index varno
Definition: primnodes.h:144
ExprState * arg
Definition: execnodes.h:612
int * pi_varOutputCols
Definition: execnodes.h:256
static bool get_last_attnums(Node *node, ProjectionInfo *projInfo)
Definition: execUtils.c:600
#define INNER_VAR
Definition: primnodes.h:131
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
bool pi_directMap
Definition: execnodes.h:252
void * palloc(Size size)
Definition: mcxt.c:891
int pi_lastInnerVar
Definition: execnodes.h:257
int pi_lastOuterVar
Definition: execnodes.h:258
ExprContext * pi_exprContext
Definition: execnodes.h:250
Definition: pg_list.h:45
int16 AttrNumber
Definition: attnum.h:21
#define OUTER_VAR
Definition: primnodes.h:132
int pi_numSimpleVars
Definition: execnodes.h:253
#define offsetof(type, field)
Definition: c.h:551
bool ExecCheckIndexConstraints ( TupleTableSlot slot,
EState estate,
ItemPointer  conflictTid,
List arbiterIndexes 
)

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

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

Definition at line 548 of file execMain.c.

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

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

549 {
550  ListCell *l;
551  bool result = true;
552 
553  foreach(l, rangeTable)
554  {
555  RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
556 
557  result = ExecCheckRTEPerms(rte);
558  if (!result)
559  {
560  Assert(rte->rtekind == RTE_RELATION);
561  if (ereport_on_violation)
563  get_rel_name(rte->relid));
564  return false;
565  }
566  }
567 
569  result = (*ExecutorCheckPerms_hook) (rangeTable,
570  ereport_on_violation);
571  return result;
572 }
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
static bool ExecCheckRTEPerms(RangeTblEntry *rte)
Definition: execMain.c:579
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
Definition: execMain.c:74
#define Assert(condition)
Definition: c.h:671
#define lfirst(lc)
Definition: pg_list.h:106
RTEKind rtekind
Definition: parsenodes.h:882
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1694
int ExecCleanTargetListLength ( List targetlist)

Definition at line 5132 of file execQual.c.

References castNode, lfirst, and TargetEntry::resjunk.

Referenced by check_sql_fn_retval(), and ExecTypeFromTLInternal().

5133 {
5134  int len = 0;
5135  ListCell *tl;
5136 
5137  foreach(tl, targetlist)
5138  {
5139  TargetEntry *curTle = castNode(TargetEntry, lfirst(tl));
5140 
5141  if (!curTle->resjunk)
5142  len++;
5143  }
5144  return len;
5145 }
#define castNode(_type_, nodeptr)
Definition: nodes.h:577
bool resjunk
Definition: primnodes.h:1337
#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:336
#define RowExclusiveLock
Definition: lockdefs.h:38
#define NULL
Definition: c.h:226
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
int i
RelationPtr ri_IndexRelationDescs
Definition: execnodes.h:337
void ExecCloseScanRelation ( Relation  scanrel)

Definition at line 830 of file execUtils.c.

References heap_close, and NoLock.

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

831 {
832  heap_close(scanrel, NoLock);
833 }
#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 1789 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().

1792 {
1793  Relation rel = resultRelInfo->ri_RelationDesc;
1794  TupleDesc tupdesc = RelationGetDescr(rel);
1795  TupleConstr *constr = tupdesc->constr;
1796  Bitmapset *modifiedCols;
1797  Bitmapset *insertedCols;
1798  Bitmapset *updatedCols;
1799 
1800  Assert(constr || resultRelInfo->ri_PartitionCheck);
1801 
1802  if (constr && constr->has_not_null)
1803  {
1804  int natts = tupdesc->natts;
1805  int attrChk;
1806 
1807  for (attrChk = 1; attrChk <= natts; attrChk++)
1808  {
1809  if (tupdesc->attrs[attrChk - 1]->attnotnull &&
1810  slot_attisnull(slot, attrChk))
1811  {
1812  char *val_desc;
1813  Relation orig_rel = rel;
1814  TupleDesc orig_tupdesc = tupdesc;
1815 
1816  /*
1817  * choose the correct relation to build val_desc from the
1818  * tuple contained in orig_slot
1819  */
1820  if (resultRelInfo->ri_PartitionRoot)
1821  {
1822  rel = resultRelInfo->ri_PartitionRoot;
1823  tupdesc = RelationGetDescr(rel);
1824  }
1825 
1826  insertedCols = GetInsertedColumns(resultRelInfo, estate);
1827  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
1828  modifiedCols = bms_union(insertedCols, updatedCols);
1830  orig_slot,
1831  tupdesc,
1832  modifiedCols,
1833  64);
1834 
1835  ereport(ERROR,
1836  (errcode(ERRCODE_NOT_NULL_VIOLATION),
1837  errmsg("null value in column \"%s\" violates not-null constraint",
1838  NameStr(orig_tupdesc->attrs[attrChk - 1]->attname)),
1839  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1840  errtablecol(orig_rel, attrChk)));
1841  }
1842  }
1843  }
1844 
1845  if (constr && constr->num_check > 0)
1846  {
1847  const char *failed;
1848 
1849  if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
1850  {
1851  char *val_desc;
1852  Relation orig_rel = rel;
1853 
1854  /* See the comment above. */
1855  if (resultRelInfo->ri_PartitionRoot)
1856  {
1857  rel = resultRelInfo->ri_PartitionRoot;
1858  tupdesc = RelationGetDescr(rel);
1859  }
1860 
1861  insertedCols = GetInsertedColumns(resultRelInfo, estate);
1862  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
1863  modifiedCols = bms_union(insertedCols, updatedCols);
1865  orig_slot,
1866  tupdesc,
1867  modifiedCols,
1868  64);
1869  ereport(ERROR,
1870  (errcode(ERRCODE_CHECK_VIOLATION),
1871  errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
1872  RelationGetRelationName(orig_rel), failed),
1873  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1874  errtableconstraint(orig_rel, failed)));
1875  }
1876  }
1877 
1878  if (resultRelInfo->ri_PartitionCheck &&
1879  !ExecPartitionCheck(resultRelInfo, slot, estate))
1880  {
1881  char *val_desc;
1882  Relation orig_rel = rel;
1883 
1884  /* See the comment above. */
1885  if (resultRelInfo->ri_PartitionRoot)
1886  {
1887  rel = resultRelInfo->ri_PartitionRoot;
1888  tupdesc = RelationGetDescr(rel);
1889  }
1890 
1891  insertedCols = GetInsertedColumns(resultRelInfo, estate);
1892  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
1893  modifiedCols = bms_union(insertedCols, updatedCols);
1895  orig_slot,
1896  tupdesc,
1897  modifiedCols,
1898  64);
1899  ereport(ERROR,
1900  (errcode(ERRCODE_CHECK_VIOLATION),
1901  errmsg("new row for relation \"%s\" violates partition constraint",
1902  RelationGetRelationName(orig_rel)),
1903  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
1904  }
1905 }
#define GetUpdatedColumns(relinfo, estate)
Definition: execMain.c:109
Relation ri_RelationDesc
Definition: execnodes.h:335
#define RelationGetDescr(relation)
Definition: rel.h:425
Relation ri_PartitionRoot
Definition: execnodes.h:355
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:5209
static bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1743
#define ERROR
Definition: elog.h:43
static char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
Definition: execMain.c:2046
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define ereport(elevel, rest)
Definition: elog.h:122
bool has_not_null
Definition: tupdesc.h:43
List * ri_PartitionCheck
Definition: execnodes.h:353
static const char * ExecRelCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
Definition: execMain.c:1679
bool slot_attisnull(TupleTableSlot *slot, int attnum)
Definition: heaptuple.c:1330
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
int errtablecol(Relation rel, int attnum)
Definition: relcache.c:5172
TupleConstr * constr
Definition: tupdesc.h:76
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:217
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:495
uint16 num_check
Definition: tupdesc.h:42
#define RelationGetRelid(relation)
Definition: rel.h:413
#define GetInsertedColumns(relinfo, estate)
Definition: execMain.c:107
bool ExecContextForcesOids ( PlanState planstate,
bool hasoids 
)

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

1407 {
1408  ResultRelInfo *ri = planstate->state->es_result_relation_info;
1409 
1410  if (ri != NULL)
1411  {
1412  Relation rel = ri->ri_RelationDesc;
1413 
1414  if (rel != NULL)
1415  {
1416  *hasoids = rel->rd_rel->relhasoids;
1417  return true;
1418  }
1419  }
1420 
1421  if (planstate->state->es_top_eflags & EXEC_FLAG_WITH_OIDS)
1422  {
1423  *hasoids = true;
1424  return true;
1425  }
1426  if (planstate->state->es_top_eflags & EXEC_FLAG_WITHOUT_OIDS)
1427  {
1428  *hasoids = false;
1429  return true;
1430  }
1431 
1432  return false;
1433 }
Relation ri_RelationDesc
Definition: execnodes.h:335
EState * state
Definition: execnodes.h:1049
Form_pg_class rd_rel
Definition: rel.h:113
#define EXEC_FLAG_WITHOUT_OIDS
Definition: executor.h:64
#define NULL
Definition: c.h:226
#define EXEC_FLAG_WITH_OIDS
Definition: executor.h:63
int es_top_eflags
Definition: execnodes.h:406
ResultRelInfo * es_result_relation_info
Definition: execnodes.h:384
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 TidListCreate().

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:185
EState * estate
Definition: execdesc.h:47
Portal GetPortalByName(const char *name)
Definition: portalmem.c:129
#define DatumGetObjectId(X)
Definition: postgres.h:508
int errcode(int sqlerrcode)
Definition: elog.c:575
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1291
unsigned int Oid
Definition: postgres_ext.h:31
#define RowMarkRequiresRowShareLock(marktype)
Definition: plannodes.h:897
ItemPointerData * ItemPointer
Definition: itemptr.h:48
ItemPointerData curCtid
Definition: execnodes.h:469
#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:1254
PortalStrategy strategy
Definition: portal.h:142
#define ereport(elevel, rest)
Definition: elog.h:122
#define PortalIsValid(p)
Definition: portal.h:197
static ScanState * search_plan_tree(PlanState *node, Oid table_oid)
Definition: execCurrent.c:254
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define lfirst(lc)
Definition: pg_list.h:106
RowMarkType markType
Definition: execnodes.h:465
List * es_rowMarks
Definition: execnodes.h:401
#define DatumGetPointer(X)
Definition: postgres.h:557
#define PortalGetQueryDesc(portal)
Definition: portal.h:202
bool atStart
Definition: portal.h:184
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:986
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1694
void ExecEndNode ( PlanState node)

Definition at line 624 of file execProcnode.c.

References bms_free(), PlanState::chgParam, elog, ERROR, ExecEndAgg(), ExecEndAppend(), ExecEndBitmapAnd(), ExecEndBitmapHeapScan(), ExecEndBitmapIndexScan(), ExecEndBitmapOr(), ExecEndCteScan(), ExecEndCustomScan(), ExecEndForeignScan(), ExecEndFunctionScan(), ExecEndGather(), ExecEndGroup(), ExecEndHash(), ExecEndHashJoin(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), ExecEndLimit(), ExecEndLockRows(), ExecEndMaterial(), ExecEndMergeAppend(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNestLoop(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSampleScan(), ExecEndSeqScan(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), 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_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_TidScanState, T_UniqueState, T_ValuesScanState, T_WindowAggState, and T_WorkTableScanState.

Referenced by EvalPlanQualEnd(), ExecEndAgg(), ExecEndAppend(), ExecEndBitmapAnd(), ExecEndBitmapHeapScan(), ExecEndBitmapOr(), ExecEndForeignScan(), ExecEndGather(), ExecEndGroup(), ExecEndHash(), ExecEndHashJoin(), ExecEndLimit(), ExecEndLockRows(), ExecEndMaterial(), ExecEndMergeAppend(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNestLoop(), ExecEndPlan(), ExecEndProjectSet(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndUnique(), and ExecEndWindowAgg().

625 {
626  /*
627  * do nothing when we get to the end of a leaf on tree.
628  */
629  if (node == NULL)
630  return;
631 
632  if (node->chgParam != NULL)
633  {
634  bms_free(node->chgParam);
635  node->chgParam = NULL;
636  }
637 
638  switch (nodeTag(node))
639  {
640  /*
641  * control nodes
642  */
643  case T_ResultState:
644  ExecEndResult((ResultState *) node);
645  break;
646 
647  case T_ProjectSetState:
649  break;
650 
651  case T_ModifyTableState:
653  break;
654 
655  case T_AppendState:
656  ExecEndAppend((AppendState *) node);
657  break;
658 
659  case T_MergeAppendState:
661  break;
662 
665  break;
666 
667  case T_BitmapAndState:
669  break;
670 
671  case T_BitmapOrState:
672  ExecEndBitmapOr((BitmapOrState *) node);
673  break;
674 
675  /*
676  * scan nodes
677  */
678  case T_SeqScanState:
679  ExecEndSeqScan((SeqScanState *) node);
680  break;
681 
682  case T_SampleScanState:
684  break;
685 
686  case T_GatherState:
687  ExecEndGather((GatherState *) node);
688  break;
689 
690  case T_IndexScanState:
692  break;
693 
696  break;
697 
700  break;
701 
704  break;
705 
706  case T_TidScanState:
707  ExecEndTidScan((TidScanState *) node);
708  break;
709 
710  case T_SubqueryScanState:
712  break;
713 
714  case T_FunctionScanState:
716  break;
717 
718  case T_ValuesScanState:
720  break;
721 
722  case T_CteScanState:
723  ExecEndCteScan((CteScanState *) node);
724  break;
725 
728  break;
729 
730  case T_ForeignScanState:
732  break;
733 
734  case T_CustomScanState:
736  break;
737 
738  /*
739  * join nodes
740  */
741  case T_NestLoopState:
742  ExecEndNestLoop((NestLoopState *) node);
743  break;
744 
745  case T_MergeJoinState:
747  break;
748 
749  case T_HashJoinState:
750  ExecEndHashJoin((HashJoinState *) node);
751  break;
752 
753  /*
754  * materialization nodes
755  */
756  case T_MaterialState:
757  ExecEndMaterial((MaterialState *) node);
758  break;
759 
760  case T_SortState:
761  ExecEndSort((SortState *) node);
762  break;
763 
764  case T_GroupState:
765  ExecEndGroup((GroupState *) node);
766  break;
767 
768  case T_AggState:
769  ExecEndAgg((AggState *) node);
770  break;
771 
772  case T_WindowAggState:
774  break;
775 
776  case T_UniqueState:
777  ExecEndUnique((UniqueState *) node);
778  break;
779 
780  case T_HashState:
781  ExecEndHash((HashState *) node);
782  break;
783 
784  case T_SetOpState:
785  ExecEndSetOp((SetOpState *) node);
786  break;
787 
788  case T_LockRowsState:
789  ExecEndLockRows((LockRowsState *) node);
790  break;
791 
792  case T_LimitState:
793  ExecEndLimit((LimitState *) node);
794  break;
795 
796  default:
797  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
798  break;
799  }
800 }
void ExecEndGroup(GroupState *node)
Definition: nodeGroup.c:230
void ExecEndSetOp(SetOpState *node)
Definition: nodeSetOp.c:575
void ExecEndFunctionScan(FunctionScanState *node)
void ExecEndNestLoop(NestLoopState *node)
Definition: nodeNestloop.c:358
void ExecEndIndexScan(IndexScanState *node)
void ExecEndLimit(LimitState *node)
Definition: nodeLimit.c:426
void ExecEndUnique(UniqueState *node)
Definition: nodeUnique.c:173
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:549
void ExecEndResult(ResultState *node)
Definition: nodeResult.c:247
#define ERROR
Definition: elog.h:43
void ExecEndAppend(AppendState *node)
Definition: nodeAppend.c:246
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:225
void ExecEndIndexOnlyScan(IndexOnlyScanState *node)
void ExecEndTidScan(TidScanState *node)
Definition: nodeTidscan.c:420
Bitmapset * chgParam
Definition: execnodes.h:1072
void ExecEndCteScan(CteScanState *node)
Definition: nodeCtescan.c:281
void ExecEndCustomScan(CustomScanState *node)
Definition: nodeCustom.c:116
void ExecEndBitmapOr(BitmapOrState *node)
Definition: nodeBitmapOr.c:180
void ExecEndSampleScan(SampleScanState *node)
void bms_free(Bitmapset *a)
Definition: bitmapset.c:200
void ExecEndWindowAgg(WindowAggState *node)
#define NULL
Definition: c.h:226
void ExecEndMergeAppend(MergeAppendState *node)
#define nodeTag(nodeptr)
Definition: nodes.h:513
void ExecEndHash(HashState *node)
Definition: nodeHash.c:222
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:3487
void ExecEndModifyTable(ModifyTableState *node)
void ExecEndGather(GatherState *node)
Definition: nodeGather.c:230
Datum ExecEvalExprSwitchContext ( ExprState expression,
ExprContext econtext,
bool isNull 
)

Definition at line 4219 of file execQual.c.

References ExprContext::ecxt_per_tuple_memory, ExecEvalExpr, and MemoryContextSwitchTo().

Referenced by advance_aggregates(), domain_check_input(), evaluate_expr(), EvaluateParams(), ExecScanSubPlan(), ExecSetParamPlan(), ExecWindowAgg(), FormIndexDatum(), FormPartitionKeyDatum(), get_qual_for_range(), operator_predicate_proof(), recompute_limits(), tablesample_init(), TidListCreate(), and validateDomainConstraint().

4222 {
4223  Datum retDatum;
4224  MemoryContext oldContext;
4225 
4226  oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
4227  retDatum = ExecEvalExpr(expression, econtext, isNull);
4228  MemoryContextSwitchTo(oldContext);
4229  return retDatum;
4230 }
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:134
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define ExecEvalExpr(expr, econtext, isNull)
Definition: executor.h:73
uintptr_t Datum
Definition: postgres.h:374
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(), ExecEvalWholeRowFast(), ExecEvalWholeRowSlow(), 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:295
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
TupleTableSlot * jf_resultSlot
Definition: execnodes.h:296
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:294
void slot_getallattrs(TupleTableSlot *slot)
Definition: heaptuple.c:1239
uintptr_t Datum
Definition: postgres.h:374
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:293
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:1332
bool resjunk
Definition: primnodes.h:1337
AttrNumber resno
Definition: primnodes.h:1331
#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 3188 of file execMain.c.

References Assert, bms_union(), ereport, errcode(), errdetail(), errmsg(), ERROR, ExecBuildSlotValueDescription(), get_partition_for_tuple(), get_rel_name(), GetInsertedColumns, GetUpdatedColumns, OidIsValid, RelationGetDescr, RelationGetRelid, and ResultRelInfo::ri_RelationDesc.

Referenced by CopyFrom(), and ExecInsert().

3190 {
3191  int result;
3192  Oid failed_at;
3193 
3194  result = get_partition_for_tuple(pd, slot, estate, &failed_at);
3195  if (result < 0)
3196  {
3197  Relation rel = resultRelInfo->ri_RelationDesc;
3198  char *val_desc;
3199  Bitmapset *insertedCols,
3200  *updatedCols,
3201  *modifiedCols;
3202  TupleDesc tupDesc = RelationGetDescr(rel);
3203 
3204  insertedCols = GetInsertedColumns(resultRelInfo, estate);
3205  updatedCols = GetUpdatedColumns(resultRelInfo, estate);
3206  modifiedCols = bms_union(insertedCols, updatedCols);
3208  slot,
3209  tupDesc,
3210  modifiedCols,
3211  64);
3212  Assert(OidIsValid(failed_at));
3213  ereport(ERROR,
3214  (errcode(ERRCODE_CHECK_VIOLATION),
3215  errmsg("no partition of relation \"%s\" found for row",
3216  get_rel_name(failed_at)),
3217  val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
3218  }
3219 
3220  return result;
3221 }
#define GetUpdatedColumns(relinfo, estate)
Definition: execMain.c:109
Relation ri_RelationDesc
Definition: execnodes.h:335
#define RelationGetDescr(relation)
Definition: rel.h:425
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
#define ERROR
Definition: elog.h:43
int get_partition_for_tuple(PartitionDispatch *pd, TupleTableSlot *slot, EState *estate, Oid *failed_at)
Definition: partition.c:1672
static char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
Definition: execMain.c:2046
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
#define Assert(condition)
Definition: c.h:671
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:217
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1694
#define RelationGetRelid(relation)
Definition: rel.h:413
#define GetInsertedColumns(relinfo, estate)
Definition: execMain.c:107
ExecRowMark* ExecFindRowMark ( EState estate,
Index  rti,
bool  missing_ok 
)

Definition at line 2208 of file execMain.c.

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

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

2209 {
2210  ListCell *lc;
2211 
2212  foreach(lc, estate->es_rowMarks)
2213  {
2214  ExecRowMark *erm = (ExecRowMark *) lfirst(lc);
2215 
2216  if (erm->rti == rti)
2217  return erm;
2218  }
2219  if (!missing_ok)
2220  elog(ERROR, "failed to find ExecRowMark for rangetable index %u", rti);
2221  return NULL;
2222 }
#define ERROR
Definition: elog.h:43
Index rti
Definition: execnodes.h:462
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
List * es_rowMarks
Definition: execnodes.h:401
#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:671
Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
Definition: heaptuple.c:1143
ResultRelInfo* ExecGetTriggerResultRel ( EState estate,
Oid  relid 
)

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

1317 {
1318  ResultRelInfo *rInfo;
1319  int nr;
1320  ListCell *l;
1321  Relation rel;
1322  MemoryContext oldcontext;
1323 
1324  /* First, search through the query result relations */
1325  rInfo = estate->es_result_relations;
1326  nr = estate->es_num_result_relations;
1327  while (nr > 0)
1328  {
1329  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1330  return rInfo;
1331  rInfo++;
1332  nr--;
1333  }
1334  /* Nope, but maybe we already made an extra ResultRelInfo for it */
1335  foreach(l, estate->es_trig_target_relations)
1336  {
1337  rInfo = (ResultRelInfo *) lfirst(l);
1338  if (RelationGetRelid(rInfo->ri_RelationDesc) == relid)
1339  return rInfo;
1340  }
1341  /* Nope, so we need a new one */
1342 
1343  /*
1344  * Open the target relation's relcache entry. We assume that an
1345  * appropriate lock is still held by the backend from whenever the trigger
1346  * event got queued, so we need take no new lock here. Also, we need not
1347  * recheck the relkind, so no need for CheckValidResultRel.
1348  */
1349  rel = heap_open(relid, NoLock);
1350 
1351  /*
1352  * Make the new entry in the right context.
1353  */
1354  oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
1355  rInfo = makeNode(ResultRelInfo);
1356  InitResultRelInfo(rInfo,
1357  rel,
1358  0, /* dummy rangetable index */
1359  NULL,
1360  estate->es_instrument);
1361  estate->es_trig_target_relations =
1362  lappend(estate->es_trig_target_relations, rInfo);
1363  MemoryContextSwitchTo(oldcontext);
1364 
1365  /*
1366  * Currently, we don't need any index information in ResultRelInfos used
1367  * only for triggers, so no need to call ExecOpenIndices.
1368  */
1369 
1370  return rInfo;
1371 }
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, Relation partition_root, int instrument_options)
Definition: execMain.c:1221
Relation ri_RelationDesc
Definition: execnodes.h:335
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext es_query_cxt
Definition: execnodes.h:397
#define NoLock
Definition: lockdefs.h:34
ResultRelInfo * es_result_relations
Definition: execnodes.h:382
int es_instrument
Definition: execnodes.h:407
List * lappend(List *list, void *datum)
Definition: list.c:128
List * es_trig_target_relations
Definition: execnodes.h:387
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
int es_num_result_relations
Definition: execnodes.h:383
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
#define RelationGetRelid(relation)
Definition: rel.h:413
ExprState* ExecInitExpr ( Expr node,
PlanState parent 
)

Definition at line 4266 of file execQual.c.

References WindowFunc::aggfilter, WindowFuncExprState::aggfilter, AggState::aggs, GroupingFuncExprState::aggstate, ArrayCoerceExprState::amstate, AND_EXPR, arg, GenericExprState::arg, FieldSelect::arg, FieldStore::arg, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, FieldSelectState::arg, ConvertRowtypeExpr::arg, FieldStoreState::arg, CoerceViaIOState::arg, ArrayCoerceExprState::arg, ConvertRowtypeExprState::arg, CaseExpr::arg, CaseExprState::arg, NullTestState::arg, CoerceToDomainState::arg, NullTest::arg, BooleanTest::arg, CoerceToDomain::arg, FieldSelectState::argdesc, FieldStoreState::argdesc, NullTestState::argdesc, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, WindowFuncExprState::args, FuncExprState::args, BoolExprState::args, CaseExpr::args, CaseExprState::args, RowExprState::args, CoalesceExprState::args, RowExpr::args, MinMaxExprState::args, XmlExprState::args, CoalesceExpr::args, MinMaxExpr::args, XmlExpr::args, CaseExprState::argtyplen, Assert, tupleDesc::attrs, BlessTupleDesc(), BoolExpr::boolop, BTORDER_PROC, castNode, MinMaxExprState::cfunc, check_stack_depth(), GroupingFuncExprState::clauses, TypeCacheEntry::cmp_proc, RowCompareExprState::collations, RowExpr::colnames, GroupingFunc::cols, CoerceToDomainState::constraint_ref, convert(), CurrentMemoryContext, CaseExpr::defresult, CaseExprState::defresult, ArrayExprState::elemalign, ArrayExprState::elembyval, ScalarArrayOpExprState::element_type, ArrayExpr::element_typeid, ArrayExprState::elements, ArrayExpr::elements, ArrayCoerceExprState::elemfunc, ArrayExprState::elemlength, elog, ereport, errcode(), errmsg(), ERROR, ExprState::evalfunc, ExecEvalAggref(), ExecEvalAnd(), ExecEvalArray(), ExecEvalArrayCoerceExpr(), ExecEvalArrayRef(), ExecEvalBooleanTest(), ExecEvalCase(), ExecEvalCaseTestExpr(), ExecEvalCoalesce(), ExecEvalCoerceToDomain(), ExecEvalCoerceToDomainValue(), ExecEvalCoerceViaIO(), ExecEvalConst(), ExecEvalConvertRowtype(), ExecEvalCurrentOfExpr(), ExecEvalDistinct(), ExecEvalFieldSelect(), ExecEvalFieldStore(), ExecEvalFunc(), ExecEvalGroupingFuncExpr(), ExecEvalMinMax(), ExecEvalNot(), ExecEvalNullIf(), ExecEvalNullTest(), ExecEvalOper(), ExecEvalOr(), ExecEvalParamExec(), ExecEvalParamExtern(), ExecEvalRelabelType(), ExecEvalRow(), ExecEvalRowCompare(), ExecEvalScalarArrayOp(), ExecEvalScalarVar(), ExecEvalSQLValueFunction(), ExecEvalWholeRowVar(), ExecEvalWindowFunc(), ExecEvalXml(), ExecInitAlternativeSubPlan(), ExecInitExpr(), ExecInitSubPlan(), ExecTypeFromExprList(), ExecTypeSetColNames(), ExprState::expr, CaseWhen::expr, CaseWhenState::expr, TargetEntry::expr, exprType(), fmgr_info(), FmgrInfo::fn_oid, format_type_be(), forthree, FuncExprState::func, FuncExpr::funcretset, FuncExprState::funcReturnsSet, RowCompareExprState::funcs, WindowAggState::funcs, ScalarArrayOpExprState::fxprstate, get_element_type(), get_op_opfamily_properties(), get_opfamily_proc(), get_typlen(), get_typlenbyvalalign(), getBaseType(), getTypeInputInfo(), getTypeOutputInfo(), Agg::groupingSets, i, CoerceViaIOState::infunc, InitDomainConstraintRef(), RowCompareExpr::inputcollids, INT4OID, CoerceViaIOState::intypioparam, InvalidAttrNumber, InvalidOid, IsA, lappend(), RowCompareExprState::largs, RowCompareExpr::largs, lcons(), lfirst, lfirst_oid, list_length(), lookup_rowtype_tupdesc_copy(), lookup_type_cache(), makeNode, makeNullConst(), MinMaxExpr::minmaxtype, XmlExprState::named_args, XmlExpr::named_args, tupleDesc::natts, FieldStore::newvals, FieldStoreState::newvals, NIL, nodeTag, NOT_EXPR, NULL, AggState::numaggs, WindowAggState::numaggs, WindowAggState::numfuncs, OidIsValid, RowCompareExpr::opfamilies, RowCompareExpr::opnos, OpExpr::opretset, OR_EXPR, CoerceViaIOState::outfunc, palloc(), palloc0(), PARAM_EXEC, PARAM_EXTERN, WholeRowVarExprState::parent, PlanState::plan, RowCompareExprState::rargs, RowCompareExpr::rargs, RECORDOID, ArrayRef::refarraytype, ArrayRef::refassgnexpr, ArrayRefExprState::refassgnexpr, ArrayRefExprState::refattrlength, ArrayRefExprState::refelemalign, ArrayRefExprState::refelembyval, ArrayRefExprState::refelemlength, ArrayRef::refelemtype, ArrayRef::refexpr, ArrayRefExprState::refexpr, ArrayRef::reflowerindexpr, ArrayRefExprState::reflowerindexpr, ArrayRef::refupperindexpr, ArrayRefExprState::refupperindexpr, CaseWhen::result, CaseWhenState::result, ArrayCoerceExprState::resultelemtype, CoerceViaIO::resulttype, ArrayCoerceExpr::resulttype, CoerceToDomain::resulttype, RowExpr::row_typeid, PlanState::subPlan, T_Aggref, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncExpr, T_GroupingFunc, T_List, T_MinMaxExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SQLValueFunction, T_SubPlan, T_TargetEntry, T_Var, T_WindowFunc, T_XmlExpr, RowExprState::tupdesc, TYPECACHE_CMP_PROC, WindowFunc::winagg, WholeRowVarExprState::wrv_junkFilter, WholeRowVarExprState::wrv_tupdesc, GenericExprState::xprstate, AggrefExprState::xprstate, WindowFuncExprState::xprstate, ArrayRefExprState::xprstate, FuncExprState::xprstate, BoolExprState::xprstate, FieldSelectState::xprstate, FieldStoreState::xprstate, CoerceViaIOState::xprstate, ArrayCoerceExprState::xprstate, ConvertRowtypeExprState::xprstate, CaseExprState::xprstate, CaseWhenState::xprstate, ArrayExprState::xprstate, RowExprState::xprstate, RowCompareExprState::xprstate, CoalesceExprState::xprstate, MinMaxExprState::xprstate, XmlExprState::xprstate, NullTestState::xprstate, and CoerceToDomainState::xprstate.

Referenced by ATRewriteTable(), BeginCopyFrom(), build_pertrans_for_aggref(), evaluate_expr(), exec_eval_simple_expr(), ExecIndexBuildScanKeys(), ExecInitAgg(), ExecInitAlternativeSubPlan(), ExecInitBitmapHeapScan(), ExecInitCteScan(), ExecInitCustomScan(), ExecInitExpr(), ExecInitForeignScan(), ExecInitFunctionScan(), ExecInitGather(), ExecInitGroup(), ExecInitHash(), ExecInitHashJoin(), ExecInitIndexOnlyScan(), ExecInitIndexScan(), ExecInitLimit(), ExecInitMergeJoin(), ExecInitModifyTable(), ExecInitNestLoop(), ExecInitProjectSet(), ExecInitResult(), ExecInitSampleScan(), ExecInitSeqScan(), ExecInitSubPlan(), ExecInitSubqueryScan(), ExecInitTidScan(), ExecInitValuesScan(), ExecInitWindowAgg(), ExecInitWorkTableScan(), ExecPrepareExpr(), get_cast_hashentry(), get_qual_for_range(), MJExamineQuals(), operator_predicate_proof(), prep_domain_constraints(), prepare_query_params(), slot_fill_defaults(), and ValuesNext().

4267 {
4268  ExprState *state;
4269 
4270  if (node == NULL)
4271  return NULL;
4272 
4273  /* Guard against stack overflow due to overly complex expressions */
4275 
4276  switch (nodeTag(node))
4277  {
4278  case T_Var:
4279  /* varattno == InvalidAttrNumber means it's a whole-row Var */
4280  if (((Var *) node)->varattno == InvalidAttrNumber)
4281  {
4283 
4284  wstate->parent = parent;
4285  wstate->wrv_tupdesc = NULL;
4286  wstate->wrv_junkFilter = NULL;
4287  state = (ExprState *) wstate;
4289  }
4290  else
4291  {
4292  state = makeNode(ExprState);
4293  state->evalfunc = ExecEvalScalarVar;
4294  }
4295  break;
4296  case T_Const:
4297  state = makeNode(ExprState);
4298  state->evalfunc = ExecEvalConst;
4299  break;
4300  case T_Param:
4301  state = makeNode(ExprState);
4302  switch (((Param *) node)->paramkind)
4303  {
4304  case PARAM_EXEC:
4305  state->evalfunc = ExecEvalParamExec;
4306  break;
4307  case PARAM_EXTERN:
4308  state->evalfunc = ExecEvalParamExtern;
4309  break;
4310  default:
4311  elog(ERROR, "unrecognized paramkind: %d",
4312  (int) ((Param *) node)->paramkind);
4313  break;
4314  }
4315  break;
4316  case T_CoerceToDomainValue:
4317  state = makeNode(ExprState);
4319  break;
4320  case T_CaseTestExpr:
4321  state = makeNode(ExprState);
4322  state->evalfunc = ExecEvalCaseTestExpr;
4323  break;
4324  case T_Aggref:
4325  {
4327 
4329  if (parent && IsA(parent, AggState))
4330  {
4331  AggState *aggstate = (AggState *) parent;
4332 
4333  aggstate->aggs = lcons(astate, aggstate->aggs);
4334  aggstate->numaggs++;
4335  }
4336  else
4337  {
4338  /* planner messed up */
4339  elog(ERROR, "Aggref found in non-Agg plan node");
4340  }
4341  state = (ExprState *) astate;
4342  }
4343  break;
4344  case T_GroupingFunc:
4345  {
4346  GroupingFunc *grp_node = (GroupingFunc *) node;
4348  Agg *agg = NULL;
4349 
4350  if (!parent || !IsA(parent, AggState) ||!IsA(parent->plan, Agg))
4351  elog(ERROR, "parent of GROUPING is not Agg node");
4352 
4353  grp_state->aggstate = (AggState *) parent;
4354 
4355  agg = (Agg *) (parent->plan);
4356 
4357  if (agg->groupingSets)
4358  grp_state->clauses = grp_node->cols;
4359  else
4360  grp_state->clauses = NIL;
4361 
4362  state = (ExprState *) grp_state;
4364  }
4365  break;
4366  case T_WindowFunc:
4367  {
4368  WindowFunc *wfunc = (WindowFunc *) node;
4370 
4372  if (parent && IsA(parent, WindowAggState))
4373  {
4374  WindowAggState *winstate = (WindowAggState *) parent;
4375  int nfuncs;
4376 
4377  winstate->funcs = lcons(wfstate, winstate->funcs);
4378  nfuncs = ++winstate->numfuncs;
4379  if (wfunc->winagg)
4380  winstate->numaggs++;
4381 
4382  wfstate->args = (List *) ExecInitExpr((Expr *) wfunc->args,
4383  parent);
4384  wfstate->aggfilter = ExecInitExpr(wfunc->aggfilter,
4385  parent);
4386 
4387  /*
4388  * Complain if the windowfunc's arguments contain any
4389  * windowfuncs; nested window functions are semantically
4390  * nonsensical. (This should have been caught earlier,
4391  * but we defend against it here anyway.)
4392  */
4393  if (nfuncs != winstate->numfuncs)
4394  ereport(ERROR,
4395  (errcode(ERRCODE_WINDOWING_ERROR),
4396  errmsg("window function calls cannot be nested")));
4397  }
4398  else
4399  {
4400  /* planner messed up */
4401  elog(ERROR, "WindowFunc found in non-WindowAgg plan node");
4402  }
4403  state = (ExprState *) wfstate;
4404  }
4405  break;
4406  case T_ArrayRef:
4407  {
4408  ArrayRef *aref = (ArrayRef *) node;
4410 
4412  astate->refupperindexpr = (List *)
4413  ExecInitExpr((Expr *) aref->refupperindexpr, parent);
4414  astate->reflowerindexpr = (List *)
4415  ExecInitExpr((Expr *) aref->reflowerindexpr, parent);
4416  astate->refexpr = ExecInitExpr(aref->refexpr, parent);
4417  astate->refassgnexpr = ExecInitExpr(aref->refassgnexpr,
4418  parent);
4419  /* do one-time catalog lookups for type info */
4420  astate->refattrlength = get_typlen(aref->refarraytype);
4422  &astate->refelemlength,
4423  &astate->refelembyval,
4424  &astate->refelemalign);
4425  state = (ExprState *) astate;
4426  }
4427  break;
4428  case T_FuncExpr:
4429  {
4430  FuncExpr *funcexpr = (FuncExpr *) node;
4432 
4434  fstate->args = (List *)
4435  ExecInitExpr((Expr *) funcexpr->args, parent);
4436  fstate->func.fn_oid = InvalidOid; /* not initialized */
4437  fstate->funcReturnsSet = funcexpr->funcretset;
4438  state = (ExprState *) fstate;
4439  }
4440  break;
4441  case T_OpExpr:
4442  {
4443  OpExpr *opexpr = (OpExpr *) node;
4445 
4447  fstate->args = (List *)
4448  ExecInitExpr((Expr *) opexpr->args, parent);
4449  fstate->func.fn_oid = InvalidOid; /* not initialized */
4450  fstate->funcReturnsSet = opexpr->opretset;
4451  state = (ExprState *) fstate;
4452  }
4453  break;
4454  case T_DistinctExpr:
4455  {
4456  DistinctExpr *distinctexpr = (DistinctExpr *) node;
4458 
4460  fstate->args = (List *)
4461  ExecInitExpr((Expr *) distinctexpr->args, parent);
4462  fstate->func.fn_oid = InvalidOid; /* not initialized */
4463  fstate->funcReturnsSet = false; /* not supported */
4464  state = (ExprState *) fstate;
4465  }
4466  break;
4467  case T_NullIfExpr:
4468  {
4469  NullIfExpr *nullifexpr = (NullIfExpr *) node;
4471 
4473  fstate->args = (List *)
4474  ExecInitExpr((Expr *) nullifexpr->args, parent);
4475  fstate->func.fn_oid = InvalidOid; /* not initialized */
4476  fstate->funcReturnsSet = false; /* not supported */
4477  state = (ExprState *) fstate;
4478  }
4479  break;
4480  case T_ScalarArrayOpExpr:
4481  {
4482  ScalarArrayOpExpr *opexpr = (ScalarArrayOpExpr *) node;
4484 
4486  sstate->fxprstate.args = (List *)
4487  ExecInitExpr((Expr *) opexpr->args, parent);
4488  sstate->fxprstate.func.fn_oid = InvalidOid; /* not initialized */
4489  sstate->fxprstate.funcReturnsSet = false; /* not supported */
4490  sstate->element_type = InvalidOid; /* ditto */
4491  state = (ExprState *) sstate;
4492  }
4493  break;
4494  case T_BoolExpr:
4495  {
4496  BoolExpr *boolexpr = (BoolExpr *) node;
4498 
4499  switch (boolexpr->boolop)
4500  {
4501  case AND_EXPR:
4503  break;
4504  case OR_EXPR:
4506  break;
4507  case NOT_EXPR:
4509  break;
4510  default:
4511  elog(ERROR, "unrecognized boolop: %d",
4512  (int) boolexpr->boolop);
4513  break;
4514  }
4515  bstate->args = (List *)
4516  ExecInitExpr((Expr *) boolexpr->args, parent);
4517  state = (ExprState *) bstate;
4518  }
4519  break;
4520  case T_SubPlan:
4521  {
4522  SubPlan *subplan = (SubPlan *) node;
4523  SubPlanState *sstate;
4524 
4525  if (!parent)
4526  elog(ERROR, "SubPlan found with no parent plan");
4527 
4528  sstate = ExecInitSubPlan(subplan, parent);
4529 
4530  /* Add SubPlanState nodes to parent->subPlan */
4531  parent->subPlan = lappend(parent->subPlan, sstate);
4532 
4533  state = (ExprState *) sstate;
4534  }
4535  break;
4536  case T_AlternativeSubPlan:
4537  {
4538  AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
4539  AlternativeSubPlanState *asstate;
4540 
4541  if (!parent)
4542  elog(ERROR, "AlternativeSubPlan found with no parent plan");
4543 
4544  asstate = ExecInitAlternativeSubPlan(asplan, parent);
4545 
4546  state = (ExprState *) asstate;
4547  }
4548  break;
4549  case T_FieldSelect:
4550  {
4551  FieldSelect *fselect = (FieldSelect *) node;
4553 
4555  fstate->arg = ExecInitExpr(fselect->arg, parent);
4556  fstate->argdesc = NULL;
4557  state = (ExprState *) fstate;
4558  }
4559  break;
4560  case T_FieldStore:
4561  {
4562  FieldStore *fstore = (FieldStore *) node;
4564 
4566  fstate->arg = ExecInitExpr(fstore->arg, parent);
4567  fstate->newvals = (List *) ExecInitExpr((Expr *) fstore->newvals, parent);
4568  fstate->argdesc = NULL;
4569  state = (ExprState *) fstate;
4570  }
4571  break;
4572  case T_RelabelType:
4573  {
4574  RelabelType *relabel = (RelabelType *) node;
4576 
4578  gstate->arg = ExecInitExpr(relabel->arg, parent);
4579  state = (ExprState *) gstate;
4580  }
4581  break;
4582  case T_CoerceViaIO:
4583  {
4584  CoerceViaIO *iocoerce = (CoerceViaIO *) node;
4586  Oid iofunc;
4587  bool typisvarlena;
4588 
4590  iostate->arg =