X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=src%2Finclude%2Fnodes%2Fexecnodes.h;h=12cfcc4fdfa31304127ddf85cca17f5bd49e46fb;hb=7839d35991f1c79a291e67635d5f4c5750c16e9b;hp=30b3fce41653b105c0dd01692e84c50cb095d051;hpb=c68489863c91a23821c4fcbfd9cfb5bce3220e8f;p=postgresql diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 30b3fce416..12cfcc4fdf 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -4,21 +4,25 @@ * definitions for executor state nodes * * - * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.158 2006/08/04 21:33:36 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.215 2010/01/01 23:03:10 tgl Exp $ * *------------------------------------------------------------------------- */ #ifndef EXECNODES_H #define EXECNODES_H -#include "access/relscan.h" +#include "access/genam.h" +#include "access/heapam.h" +#include "access/skey.h" #include "nodes/params.h" #include "nodes/plannodes.h" #include "nodes/tidbitmap.h" #include "utils/hsearch.h" +#include "utils/rel.h" +#include "utils/snapshot.h" #include "utils/tuplestore.h" @@ -36,7 +40,16 @@ * ExpressionsState exec state for expressions, or NIL if none * Predicate partial-index predicate, or NIL if none * PredicateState exec state for predicate, or NIL if none + * ExclusionOps Per-column exclusion operators, or NULL if none + * ExclusionProcs Underlying function OIDs for ExclusionOps + * ExclusionStrats Opclass strategy numbers for ExclusionOps * Unique is it a unique index? + * ReadyForInserts is it valid for inserts? + * Concurrent are we doing a concurrent index build? + * BrokenHotChain did we detect any broken HOT chains? + * + * ii_Concurrent and ii_BrokenHotChain are used only during index build; + * they're conventionally set to false otherwise. * ---------------- */ typedef struct IndexInfo @@ -48,7 +61,13 @@ typedef struct IndexInfo List *ii_ExpressionsState; /* list of ExprState */ List *ii_Predicate; /* list of Expr */ List *ii_PredicateState; /* list of ExprState */ + Oid *ii_ExclusionOps; /* array with one entry per column */ + Oid *ii_ExclusionProcs; /* array with one entry per column */ + uint16 *ii_ExclusionStrats; /* array with one entry per column */ bool ii_Unique; + bool ii_ReadyForInserts; + bool ii_Concurrent; + bool ii_BrokenHotChain; } IndexInfo; /* ---------------- @@ -106,9 +125,12 @@ typedef struct ExprContext ParamExecData *ecxt_param_exec_vals; /* for PARAM_EXEC params */ ParamListInfo ecxt_param_list_info; /* for other param types */ - /* Values to substitute for Aggref nodes in expression */ - Datum *ecxt_aggvalues; /* precomputed values for Aggref nodes */ - bool *ecxt_aggnulls; /* null flags for Aggref nodes */ + /* + * Values to substitute for Aggref nodes in the expressions of an Agg + * node, or for WindowFunc nodes within a WindowAgg node. + */ + Datum *ecxt_aggvalues; /* precomputed values for aggs/windowfuncs */ + bool *ecxt_aggnulls; /* null flags for aggs/windowfuncs */ /* Value to substitute for CaseTestExpr nodes in expression */ Datum caseValue_datum; @@ -138,12 +160,15 @@ typedef enum /* * Return modes for functions returning sets. Note values must be chosen * as separate bits so that a bitmask can be formed to indicate supported - * modes. + * modes. SFRM_Materialize_Random and SFRM_Materialize_Preferred are + * auxiliary flags about SFRM_Materialize mode, rather than separate modes. */ typedef enum { SFRM_ValuePerCall = 0x01, /* one value returned per call */ - SFRM_Materialize = 0x02 /* result set instantiated in Tuplestore */ + SFRM_Materialize = 0x02, /* result set instantiated in Tuplestore */ + SFRM_Materialize_Random = 0x04, /* Tuplestore needs randomAccess */ + SFRM_Materialize_Preferred = 0x08 /* caller prefers Tuplestore */ } SetFunctionReturnMode; /* @@ -182,16 +207,25 @@ typedef struct ReturnSetInfo * * The planner very often produces tlists that consist entirely of * simple Var references (lower levels of a plan tree almost always - * look like that). So we have an optimization to handle that case - * with minimum overhead. + * look like that). And top-level tlists are often mostly Vars too. + * We therefore optimize execution of simple-Var tlist entries. + * The pi_targetlist list actually contains only the tlist entries that + * aren't simple Vars, while those that are Vars are processed using the + * varSlotOffsets/varNumbers/varOutputCols arrays. + * + * The lastXXXVar fields are used to optimize fetching of fields from + * input tuples: they let us do a slot_getsomeattrs() call to ensure + * that all needed attributes are extracted in one pass. * - * targetlist target list for projection + * targetlist target list for projection (non-Var expressions only) * exprContext expression context in which to evaluate targetlist * slot slot to place projection result in - * itemIsDone workspace for ExecProject - * isVarList TRUE if simple-Var-list optimization applies + * itemIsDone workspace array for ExecProject + * directMap true if varOutputCols[] is an identity map + * numSimpleVars number of simple Vars found in original tlist * varSlotOffsets array indicating which slot each simple Var is from - * varNumbers array indicating attr numbers of simple Vars + * varNumbers array containing input attr numbers of simple Vars + * varOutputCols array containing output attr numbers of simple Vars * lastInnerVar highest attnum from inner tuple slot (0 if none) * lastOuterVar highest attnum from outer tuple slot (0 if none) * lastScanVar highest attnum from scan tuple slot (0 if none) @@ -204,9 +238,11 @@ typedef struct ProjectionInfo ExprContext *pi_exprContext; TupleTableSlot *pi_slot; ExprDoneCond *pi_itemIsDone; - bool pi_isVarList; + bool pi_directMap; + int pi_numSimpleVars; int *pi_varSlotOffsets; int *pi_varNumbers; + int *pi_varOutputCols; int pi_lastInnerVar; int pi_lastOuterVar; int pi_lastScanVar; @@ -224,7 +260,8 @@ typedef struct ProjectionInfo * the tuple to be updated. This is needed to do the update, but we * don't want the ctid to be part of the stored new tuple! So, we * apply a "junk filter" to remove the junk attributes and form the - * real output tuple. + * real output tuple. The junkfilter code also provides routines to + * extract the values of the junk attribute(s) from the input tuple. * * targetList: the original target list (including junk attributes). * cleanTupType: the tuple descriptor for the "clean" tuple (with @@ -233,6 +270,9 @@ typedef struct ProjectionInfo * attribute numbers of the "original" tuple and the * attribute numbers of the "clean" tuple. * resultSlot: tuple slot used to hold cleaned tuple. + * junkAttNo: not used by junkfilter code. Can be used by caller + * to remember the attno of a specific junk attribute + * (execMain.c stores the "ctid" attno here). * ---------------- */ typedef struct JunkFilter @@ -242,6 +282,7 @@ typedef struct JunkFilter TupleDesc jf_cleanTupType; AttrNumber *jf_cleanMap; TupleTableSlot *jf_resultSlot; + AttrNumber jf_junkAttNo; } JunkFilter; /* ---------------- @@ -259,9 +300,11 @@ typedef struct JunkFilter * IndexRelationInfo array of key/attr info for indices * TrigDesc triggers to be fired, if any * TrigFunctions cached lookup info for trigger functions + * TrigWhenExprs array of trigger WHEN expr states * TrigInstrument optional runtime measurements for triggers * ConstraintExprs array of constraint-checking expr states * junkFilter for removing junk attributes from tuples + * projectReturning for computing a RETURNING list * ---------------- */ typedef struct ResultRelInfo @@ -274,9 +317,11 @@ typedef struct ResultRelInfo IndexInfo **ri_IndexRelationInfo; TriggerDesc *ri_TrigDesc; FmgrInfo *ri_TrigFunctions; + List **ri_TrigWhenExprs; struct Instrumentation *ri_TrigInstrument; List **ri_ConstraintExprs; JunkFilter *ri_junkFilter; + ProjectionInfo *ri_projectReturning; } ResultRelInfo; /* ---------------- @@ -293,18 +338,23 @@ typedef struct EState ScanDirection es_direction; /* current scan direction */ Snapshot es_snapshot; /* time qual to use */ Snapshot es_crosscheck_snapshot; /* crosscheck time qual for RI */ - List *es_range_table; /* List of RangeTableEntrys */ + List *es_range_table; /* List of RangeTblEntry */ + PlannedStmt *es_plannedstmt; /* link to top of plan tree */ + + JunkFilter *es_junkFilter; /* top-level junk filter, if any */ + + /* If query can insert/delete tuples, the command ID to mark them with */ + CommandId es_output_cid; /* Info about target table for insert/update/delete queries: */ ResultRelInfo *es_result_relations; /* array of ResultRelInfos */ int es_num_result_relations; /* length of array */ ResultRelInfo *es_result_relation_info; /* currently active array elt */ - JunkFilter *es_junkFilter; /* currently active junk filter */ - TupleTableSlot *es_trig_tuple_slot; /* for trigger output tuples */ - - Relation es_into_relation_descriptor; /* for SELECT INTO */ - bool es_into_relation_use_wal; + /* Stuff used for firing triggers: */ + List *es_trig_target_relations; /* trigger-only ResultRelInfos */ + TupleTableSlot *es_trig_tuple_slot; /* for trigger output tuples */ + TupleTableSlot *es_trig_oldtup_slot; /* for trigger old tuples */ /* Parameter info: */ ParamListInfo es_param_list_info; /* values of external params */ @@ -313,18 +363,21 @@ typedef struct EState /* Other working state: */ MemoryContext es_query_cxt; /* per-query context in which EState lives */ - TupleTable es_tupleTable; /* Array of TupleTableSlots */ + List *es_tupleTable; /* List of TupleTableSlots */ + + List *es_rowMarks; /* List of ExecRowMarks */ uint32 es_processed; /* # of tuples processed */ Oid es_lastoid; /* last oid processed (by INSERT) */ - List *es_rowMarks; /* not good place, but there is no other */ - bool es_instrument; /* true requests runtime instrumentation */ + int es_instrument; /* OR of InstrumentOption flags */ bool es_select_into; /* true if doing SELECT INTO */ bool es_into_oids; /* true to generate OIDs in SELECT INTO */ List *es_exprcontexts; /* List of ExprContexts within EState */ + List *es_subplanstates; /* List of PlanState for SubPlans */ + /* * this ExprContext is for per-output-tuple operations, such as constraint * checks and index-value computations. It will be reset for each output @@ -332,23 +385,46 @@ typedef struct EState */ ExprContext *es_per_tuple_exprcontext; - /* Below is to re-evaluate plan qual in READ COMMITTED mode */ - Plan *es_topPlan; /* link to top of plan tree */ - struct evalPlanQual *es_evalPlanQual; /* chain of PlanQual states */ - bool *es_evTupleNull; /* local array of EPQ status */ - HeapTuple *es_evTuple; /* shared array of EPQ substitute tuples */ - bool es_useEvalPlan; /* evaluating EPQ tuples? */ + /* + * These fields are for re-evaluating plan quals when an updated tuple is + * substituted in READ COMMITTED mode. es_epqTuple[] contains tuples + * that scan plan nodes should return instead of whatever they'd normally + * return, or NULL if nothing to return; es_epqTupleSet[] is true if a + * particular array entry is valid; and es_epqScanDone[] is state to + * remember if the tuple has been returned already. Arrays are of size + * list_length(es_range_table) and are indexed by scan node scanrelid - 1. + */ + HeapTuple *es_epqTuple; /* array of EPQ substitute tuples */ + bool *es_epqTupleSet; /* true if EPQ tuple is provided */ + bool *es_epqScanDone; /* true if EPQ tuple has been fetched */ } EState; -/* es_rowMarks is a list of these structs: */ +/* + * ExecRowMark - + * runtime representation of FOR UPDATE/SHARE clauses + * + * When doing UPDATE, DELETE, or SELECT FOR UPDATE/SHARE, we should have an + * ExecRowMark for each non-target relation in the query (except inheritance + * parent RTEs, which can be ignored at runtime). See PlanRowMark for details + * about most of the fields. + * + * es_rowMarks is a list of these structs. Each LockRows node has its own + * list, which is the subset of locks that it is supposed to enforce; note + * that the per-node lists point to the same structs that are in the global + * list. + */ typedef struct ExecRowMark { - Relation relation; /* opened and RowShareLock'd relation */ + Relation relation; /* opened and suitably locked relation */ Index rti; /* its range table index */ - bool forUpdate; /* true = FOR UPDATE, false = FOR SHARE */ + Index prti; /* parent range table index, if child */ + RowMarkType markType; /* see enum in nodes/plannodes.h */ bool noWait; /* NOWAIT option */ - char resname[32]; /* name for its ctid junk attribute */ + AttrNumber ctidAttNo; /* resno of ctid junk attribute, if any */ + AttrNumber toidAttNo; /* resno of tableoid junk attribute, if any */ + AttrNumber wholeAttNo; /* resno of whole-row junk attribute, if any */ + ItemPointerData curCtid; /* ctid of currently locked tuple, if any */ } ExecRowMark; @@ -356,6 +432,16 @@ typedef struct ExecRowMark * Tuple Hash Tables * * All-in-memory tuple hash tables are used for a number of purposes. + * + * Note: tab_hash_funcs are for the key datatype(s) stored in the table, + * and tab_eq_funcs are non-cross-type equality operators for those types. + * Normally these are the only functions used, but FindTupleHashEntry() + * supports searching a hashtable using cross-data-type hashing. For that, + * the caller must supply hash functions for the LHS datatype as well as + * the cross-type equality operators to use. in_hash_funcs and cur_eq_funcs + * are set to point to the caller's function arrays while doing such a search. + * During LookupTupleHashEntry(), they point to tab_hash_funcs and + * tab_eq_funcs respectively. * ---------------------------------------------------------------- */ typedef struct TupleHashEntryData *TupleHashEntry; @@ -373,19 +459,34 @@ typedef struct TupleHashTableData HTAB *hashtab; /* underlying dynahash table */ int numCols; /* number of columns in lookup key */ AttrNumber *keyColIdx; /* attr numbers of key columns */ - FmgrInfo *eqfunctions; /* lookup data for comparison functions */ - FmgrInfo *hashfunctions; /* lookup data for hash functions */ + FmgrInfo *tab_hash_funcs; /* hash functions for table datatype(s) */ + FmgrInfo *tab_eq_funcs; /* equality functions for table datatype(s) */ MemoryContext tablecxt; /* memory context containing table */ MemoryContext tempcxt; /* context for function evaluations */ Size entrysize; /* actual size to make each hash entry */ TupleTableSlot *tableslot; /* slot for referencing table entries */ + /* The following fields are set transiently for each table search: */ TupleTableSlot *inputslot; /* current input tuple's slot */ + FmgrInfo *in_hash_funcs; /* hash functions for input datatype(s) */ + FmgrInfo *cur_eq_funcs; /* equality functions for input vs. table */ } TupleHashTableData; typedef HASH_SEQ_STATUS TupleHashIterator; -#define ResetTupleHashIterator(htable, iter) \ +/* + * Use InitTupleHashIterator/TermTupleHashIterator for a read/write scan. + * Use ResetTupleHashIterator if the table can be frozen (in this case no + * explicit scan termination is needed). + */ +#define InitTupleHashIterator(htable, iter) \ hash_seq_init(iter, (htable)->hashtab) +#define TermTupleHashIterator(iter) \ + hash_seq_term(iter) +#define ResetTupleHashIterator(htable, iter) \ + do { \ + hash_freeze((htable)->hashtab); \ + hash_seq_init(iter, (htable)->hashtab); \ + } while (0) #define ScanTupleHashTable(iter) \ ((TupleHashEntry) hash_seq_search(iter)) @@ -453,6 +554,17 @@ typedef struct AggrefExprState int aggno; /* ID number for agg within its plan node */ } AggrefExprState; +/* ---------------- + * WindowFuncExprState node + * ---------------- + */ +typedef struct WindowFuncExprState +{ + ExprState xprstate; + List *args; /* states of argument expressions */ + int wfuncno; /* ID number for wfunc within its plan node */ +} WindowFuncExprState; + /* ---------------- * ArrayRefExprState node * @@ -489,13 +601,30 @@ typedef struct FuncExprState /* * Function manager's lookup info for the target function. If func.fn_oid - * is InvalidOid, we haven't initialized it yet. + * is InvalidOid, we haven't initialized it yet (nor any of the following + * fields). */ FmgrInfo func; /* - * We also need to store argument values across calls when evaluating a - * function-returning-set. + * For a set-returning function (SRF) that returns a tuplestore, we keep + * the tuplestore here and dole out the result rows one at a time. The + * slot holds the row currently being returned. + */ + Tuplestorestate *funcResultStore; + TupleTableSlot *funcResultSlot; + + /* + * In some cases we need to compute a tuple descriptor for the function's + * output. If so, it's stored here. + */ + TupleDesc funcResultDesc; + bool funcReturnsTuple; /* valid when funcResultDesc isn't + * NULL */ + + /* + * We need to store argument values across calls when evaluating a SRF + * that uses value-per-call mode. * * setArgsValid is true when we are evaluating a set-valued function and * we are in the middle of a call series; we want to pass the same @@ -507,14 +636,15 @@ typedef struct FuncExprState /* * Flag to remember whether we found a set-valued argument to the * function. This causes the function result to be a set as well. Valid - * only when setArgsValid is true. + * only when setArgsValid is true or funcResultStore isn't NULL. */ bool setHasSetArg; /* some argument returns a set */ /* * Flag to remember whether we have registered a shutdown callback for - * this FuncExprState. We do so only if setArgsValid has been true at - * least once (since all the callback is for is to clear setArgsValid). + * this FuncExprState. We do so only if funcResultStore or setArgsValid + * has been set at least once (since all the callback is for is to release + * the tuplestore or clear setArgsValid). */ bool shutdown_reg; /* a shutdown callback is registered */ @@ -558,11 +688,9 @@ typedef struct BoolExprState typedef struct SubPlanState { ExprState xprstate; - EState *sub_estate; /* subselect plan has its own EState */ struct PlanState *planstate; /* subselect plan's state tree */ ExprState *testexpr; /* state of combining expression */ List *args; /* states of argument expression(s) */ - bool needShutdown; /* TRUE = need to shutdown subplan */ HeapTuple curTuple; /* copy of most recent tuple from subplan */ /* these are used when hashing the subselect's output: */ ProjectionInfo *projLeft; /* for projecting lefthand exprs */ @@ -574,10 +702,23 @@ typedef struct SubPlanState MemoryContext tablecxt; /* memory context containing tables */ ExprContext *innerecontext; /* working context for comparisons */ AttrNumber *keyColIdx; /* control data for hash tables */ - FmgrInfo *eqfunctions; /* comparison functions for hash tables */ - FmgrInfo *hashfunctions; /* lookup data for hash functions */ + FmgrInfo *tab_hash_funcs; /* hash functions for table datatype(s) */ + FmgrInfo *tab_eq_funcs; /* equality functions for table datatype(s) */ + FmgrInfo *lhs_hash_funcs; /* hash functions for lefthand datatype(s) */ + FmgrInfo *cur_eq_funcs; /* equality functions for LHS vs. table */ } SubPlanState; +/* ---------------- + * AlternativeSubPlanState node + * ---------------- + */ +typedef struct AlternativeSubPlanState +{ + ExprState xprstate; + List *subplans; /* states of alternative subplans */ + int active; /* list index of the one we're using */ +} AlternativeSubPlanState; + /* ---------------- * FieldSelectState node * ---------------- @@ -601,6 +742,33 @@ typedef struct FieldStoreState TupleDesc argdesc; /* tupdesc for most recent input */ } FieldStoreState; +/* ---------------- + * CoerceViaIOState node + * ---------------- + */ +typedef struct CoerceViaIOState +{ + ExprState xprstate; + ExprState *arg; /* input expression */ + FmgrInfo outfunc; /* lookup info for source output function */ + FmgrInfo infunc; /* lookup info for result input function */ + Oid intypioparam; /* argument needed for input function */ +} CoerceViaIOState; + +/* ---------------- + * ArrayCoerceExprState node + * ---------------- + */ +typedef struct ArrayCoerceExprState +{ + ExprState xprstate; + ExprState *arg; /* input array value */ + Oid resultelemtype; /* element type of result array */ + FmgrInfo elemfunc; /* lookup info for element coercion function */ + /* use struct pointer to avoid including array.h here */ + struct ArrayMapState *amstate; /* workspace for array_map */ +} ArrayCoerceExprState; + /* ---------------- * ConvertRowtypeExprState node * ---------------- @@ -611,11 +779,9 @@ typedef struct ConvertRowtypeExprState ExprState *arg; /* input tuple value */ TupleDesc indesc; /* tupdesc for source rowtype */ TupleDesc outdesc; /* tupdesc for result rowtype */ - AttrNumber *attrMap; /* indexes of input fields, or 0 for null */ - Datum *invalues; /* workspace for deconstructing source */ - bool *inisnull; - Datum *outvalues; /* workspace for constructing result */ - bool *outisnull; + /* use "struct" so we needn't include tupconvert.h here */ + struct TupleConversionMap *map; + bool initialized; } ConvertRowtypeExprState; /* ---------------- @@ -701,6 +867,29 @@ typedef struct MinMaxExprState FmgrInfo cfunc; /* lookup info for comparison func */ } MinMaxExprState; +/* ---------------- + * XmlExprState node + * ---------------- + */ +typedef struct XmlExprState +{ + ExprState xprstate; + List *named_args; /* ExprStates for named arguments */ + List *args; /* ExprStates for other arguments */ +} XmlExprState; + +/* ---------------- + * NullTestState node + * ---------------- + */ +typedef struct NullTestState +{ + ExprState xprstate; + ExprState *arg; /* input expression */ + /* used only if input is of composite type: */ + TupleDesc argdesc; /* tupdesc for most recent input */ +} NullTestState; + /* ---------------- * CoerceToDomainState node * ---------------- @@ -756,7 +945,7 @@ typedef struct PlanState Plan *plan; /* associated Plan node */ - EState *state; /* at execution time, state's of individual + EState *state; /* at execution time, states of individual * nodes point to one EState for the whole * top-level plan */ @@ -784,7 +973,6 @@ typedef struct PlanState /* * Other run-time state needed by most if not all node types. */ - TupleTableSlot *ps_OuterTupleSlot; /* slot for current "outer" tuple */ TupleTableSlot *ps_ResultTupleSlot; /* slot for my result tuples */ ExprContext *ps_ExprContext; /* node's expression-evaluation context */ ProjectionInfo *ps_ProjInfo; /* info for doing tuple projection */ @@ -802,6 +990,21 @@ typedef struct PlanState #define innerPlanState(node) (((PlanState *)(node))->righttree) #define outerPlanState(node) (((PlanState *)(node))->lefttree) +/* + * EPQState is state for executing an EvalPlanQual recheck on a candidate + * tuple in ModifyTable or LockRows. The estate and planstate fields are + * NULL if inactive. + */ +typedef struct EPQState +{ + EState *estate; /* subsidiary EState */ + PlanState *planstate; /* plan state tree ready to be executed */ + TupleTableSlot *origslot; /* original output tuple to be rechecked */ + Plan *plan; /* plan tree to be executed */ + List *rowMarks; /* ExecRowMarks (non-locking only) */ + int epqParam; /* ID of Param to force scan node re-eval */ +} EPQState; + /* ---------------- * ResultState information @@ -815,13 +1018,26 @@ typedef struct ResultState bool rs_checkqual; /* do we need to check the qual? */ } ResultState; +/* ---------------- + * ModifyTableState information + * ---------------- + */ +typedef struct ModifyTableState +{ + PlanState ps; /* its first field is NodeTag */ + CmdType operation; + PlanState **mt_plans; /* subplans (one per target rel) */ + int mt_nplans; /* number of plans in the array */ + int mt_whichplan; /* which one is being executed (0..n-1) */ + EPQState mt_epqstate; /* for evaluating EvalPlanQual rechecks */ + bool fireBSTriggers; /* do we need to fire stmt triggers? */ +} ModifyTableState; + /* ---------------- * AppendState information * - * nplans how many plans are in the list + * nplans how many plans are in the array * whichplan which plan is being executed (0 .. n-1) - * firstplan first plan to execute (usually 0) - * lastplan last plan to execute (usually n-1) * ---------------- */ typedef struct AppendState @@ -830,10 +1046,34 @@ typedef struct AppendState PlanState **appendplans; /* array of PlanStates for my inputs */ int as_nplans; int as_whichplan; - int as_firstplan; - int as_lastplan; } AppendState; +/* ---------------- + * RecursiveUnionState information + * + * RecursiveUnionState is used for performing a recursive union. + * + * recursing T when we're done scanning the non-recursive term + * intermediate_empty T if intermediate_table is currently empty + * working_table working table (to be scanned by recursive term) + * intermediate_table current recursive output (next generation of WT) + * ---------------- + */ +typedef struct RecursiveUnionState +{ + PlanState ps; /* its first field is NodeTag */ + bool recursing; + bool intermediate_empty; + Tuplestorestate *working_table; + Tuplestorestate *intermediate_table; + /* Remaining fields are unused in UNION ALL case */ + FmgrInfo *eqfunctions; /* per-grouping-field equality fns */ + FmgrInfo *hashfunctions; /* per-grouping-field hash fns */ + MemoryContext tempContext; /* short-term context for comparisons */ + TupleHashTable hashtable; /* hash table for tuples already seen */ + MemoryContext tableContext; /* memory context containing hash table */ +} RecursiveUnionState; + /* ---------------- * BitmapAndState information * ---------------- @@ -898,6 +1138,7 @@ typedef struct { ScanKey scan_key; /* scankey to put value into */ ExprState *key_expr; /* expr to evaluate to get value */ + bool key_toastable; /* is expr's result a toastable datatype? */ } IndexRuntimeKeyInfo; typedef struct @@ -975,7 +1216,11 @@ typedef struct BitmapIndexScanState * * bitmapqualorig execution state for bitmapqualorig expressions * tbm bitmap obtained from child index scan(s) + * tbmiterator iterator for scanning current pages * tbmres current-page data + * prefetch_iterator iterator for prefetching ahead of current page + * prefetch_pages # pages prefetch iterator is ahead of current + * prefetch_target target prefetch distance * ---------------- */ typedef struct BitmapHeapScanState @@ -983,12 +1228,17 @@ typedef struct BitmapHeapScanState ScanState ss; /* its first field is NodeTag */ List *bitmapqualorig; TIDBitmap *tbm; + TBMIterator *tbmiterator; TBMIterateResult *tbmres; + TBMIterator *prefetch_iterator; + int prefetch_pages; + int prefetch_target; } BitmapHeapScanState; /* ---------------- * TidScanState information * + * isCurrentOf scan has a CurrentOfExpr qual * NumTids number of tids in this scan * TidPtr index of currently fetched tid * TidList evaluated item pointers (array of size NumTids) @@ -998,6 +1248,7 @@ typedef struct TidScanState { ScanState ss; /* its first field is NodeTag */ List *tss_tidquals; /* list of ExprState nodes */ + bool tss_isCurrentOf; int tss_NumTids; int tss_TidPtr; int tss_MarkTidPtr; @@ -1009,17 +1260,13 @@ typedef struct TidScanState * SubqueryScanState information * * SubqueryScanState is used for scanning a sub-query in the range table. - * The sub-query will have its own EState, which we save here. * ScanTupleSlot references the current output tuple of the sub-query. - * - * SubEState exec state for sub-query * ---------------- */ typedef struct SubqueryScanState { ScanState ss; /* its first field is NodeTag */ PlanState *subplan; - EState *sss_SubEState; } SubqueryScanState; /* ---------------- @@ -1028,6 +1275,7 @@ typedef struct SubqueryScanState * Function nodes are used to scan the results of a * function appearing in FROM (typically a function returning set). * + * eflags node's capability flags * tupdesc expected return tuple description * tuplestorestate private state of tuplestore.c * funcexpr state for function expression being evaluated @@ -1036,6 +1284,7 @@ typedef struct SubqueryScanState typedef struct FunctionScanState { ScanState ss; /* its first field is NodeTag */ + int eflags; TupleDesc tupdesc; Tuplestorestate *tuplestorestate; ExprState *funcexpr; @@ -1069,6 +1318,43 @@ typedef struct ValuesScanState int marked_idx; } ValuesScanState; +/* ---------------- + * CteScanState information + * + * CteScan nodes are used to scan a CommonTableExpr query. + * + * Multiple CteScan nodes can read out from the same CTE query. We use + * a tuplestore to hold rows that have been read from the CTE query but + * not yet consumed by all readers. + * ---------------- + */ +typedef struct CteScanState +{ + ScanState ss; /* its first field is NodeTag */ + int eflags; /* capability flags to pass to tuplestore */ + int readptr; /* index of my tuplestore read pointer */ + PlanState *cteplanstate; /* PlanState for the CTE query itself */ + /* Link to the "leader" CteScanState (possibly this same node) */ + struct CteScanState *leader; + /* The remaining fields are only valid in the "leader" CteScanState */ + Tuplestorestate *cte_table; /* rows already read from the CTE query */ + bool eof_cte; /* reached end of CTE query? */ +} CteScanState; + +/* ---------------- + * WorkTableScanState information + * + * WorkTableScan nodes are used to scan the work table created by + * a RecursiveUnion node. We locate the RecursiveUnion node + * during executor startup. + * ---------------- + */ +typedef struct WorkTableScanState +{ + ScanState ss; /* its first field is NodeTag */ + RecursiveUnionState *rustate; +} WorkTableScanState; + /* ---------------------------------------------------------------- * Join State Information * ---------------------------------------------------------------- @@ -1109,6 +1395,7 @@ typedef struct NestLoopState * NumClauses number of mergejoinable join clauses * Clauses info for each mergejoinable clause * JoinState current "state" of join. see execdefs.h + * ExtraMarks true to issue extra Mark operations on inner scan * FillOuter true if should emit unjoined outer tuples anyway * FillInner true if should emit unjoined inner tuples anyway * MatchedOuter true if found a join match for current outer tuple @@ -1131,6 +1418,7 @@ typedef struct MergeJoinState int mj_NumClauses; MergeJoinClause mj_Clauses; /* array of length mj_NumClauses */ int mj_JoinState; + bool mj_ExtraMarks; bool mj_FillOuter; bool mj_FillInner; bool mj_MatchedOuter; @@ -1150,11 +1438,12 @@ typedef struct MergeJoinState * hj_HashTable hash table for the hashjoin * (NULL if table not built yet) * hj_CurHashValue hash value for current outer tuple - * hj_CurBucketNo bucket# for current outer tuple + * hj_CurBucketNo regular bucket# for current outer tuple + * hj_CurSkewBucketNo skew bucket# for current outer tuple * hj_CurTuple last inner tuple matched to current outer * tuple, or NULL if starting search - * (CurHashValue, CurBucketNo and CurTuple are - * undefined if OuterTupleSlot is empty!) + * (hj_CurXXX variables are undefined if + * OuterTupleSlot is empty!) * hj_OuterHashKeys the outer hash keys in the hashjoin condition * hj_InnerHashKeys the inner hash keys in the hashjoin condition * hj_HashOperators the join operators in the hashjoin condition @@ -1179,6 +1468,7 @@ typedef struct HashJoinState HashJoinTable hj_HashTable; uint32 hj_CurHashValue; int hj_CurBucketNo; + int hj_CurSkewBucketNo; HashJoinTuple hj_CurTuple; List *hj_OuterHashKeys; /* list of ExprState nodes */ List *hj_InnerHashKeys; /* list of ExprState nodes */ @@ -1210,9 +1500,9 @@ typedef struct HashJoinState typedef struct MaterialState { ScanState ss; /* its first field is NodeTag */ - bool randomAccess; /* need random access to subplan output? */ + int eflags; /* capability flags to pass to tuplestore */ bool eof_underlying; /* reached end of underlying plan? */ - void *tuplestorestate; /* private state of tuplestore.c */ + Tuplestorestate *tuplestorestate; } MaterialState; /* ---------------- @@ -1223,7 +1513,11 @@ typedef struct SortState { ScanState ss; /* its first field is NodeTag */ bool randomAccess; /* need random access to sort output? */ + bool bounded; /* is the result set bounded? */ + int64 bound; /* if bounded, how many tuples are needed */ bool sort_Done; /* sort completed yet? */ + bool bounded_Done; /* value of bounded we did the sort with */ + int64 bound_Done; /* value of bound we did the sort with */ void *tuplesortstate; /* private state of tuplesort.c */ } SortState; @@ -1276,6 +1570,56 @@ typedef struct AggState TupleHashIterator hashiter; /* for iterating through hash table */ } AggState; +/* ---------------- + * WindowAggState information + * ---------------- + */ +/* these structs are private in nodeWindowAgg.c: */ +typedef struct WindowStatePerFuncData *WindowStatePerFunc; +typedef struct WindowStatePerAggData *WindowStatePerAgg; + +typedef struct WindowAggState +{ + ScanState ss; /* its first field is NodeTag */ + + /* these fields are filled in by ExecInitExpr: */ + List *funcs; /* all WindowFunc nodes in targetlist */ + int numfuncs; /* total number of window functions */ + int numaggs; /* number that are plain aggregates */ + + WindowStatePerFunc perfunc; /* per-window-function information */ + WindowStatePerAgg peragg; /* per-plain-aggregate information */ + FmgrInfo *partEqfunctions; /* equality funcs for partition columns */ + FmgrInfo *ordEqfunctions; /* equality funcs for ordering columns */ + Tuplestorestate *buffer; /* stores rows of current partition */ + int current_ptr; /* read pointer # for current */ + int agg_ptr; /* read pointer # for aggregates */ + int64 spooled_rows; /* total # of rows in buffer */ + int64 currentpos; /* position of current row in partition */ + int64 frametailpos; /* current frame tail position */ + int64 aggregatedupto; /* rows before this one are aggregated */ + + MemoryContext wincontext; /* context for partition-lifespan data */ + ExprContext *tmpcontext; /* short-term evaluation context */ + + bool all_done; /* true if the scan is finished */ + bool partition_spooled; /* true if all tuples in current + * partition have been spooled into + * tuplestore */ + bool more_partitions;/* true if there's more partitions after this + * one */ + bool frametail_valid;/* true if frametailpos is known up to date + * for current row */ + + TupleTableSlot *first_part_slot; /* first tuple of current or next + * partition */ + + /* temporary slots for tuples fetched back from tuplestore */ + TupleTableSlot *agg_row_slot; + TupleTableSlot *temp_slot_1; + TupleTableSlot *temp_slot_2; +} WindowAggState; + /* ---------------- * UniqueState information * @@ -1309,23 +1653,46 @@ typedef struct HashState /* ---------------- * SetOpState information * - * SetOp nodes are used "on top of" sort nodes to discard - * duplicate tuples returned from the sort phase. These are - * more complex than a simple Unique since we have to count - * how many duplicates to return. + * Even in "sorted" mode, SetOp nodes are more complex than a simple + * Unique, since we have to count how many duplicates to return. But + * we also support hashing, so this is really more like a cut-down + * form of Agg. * ---------------- */ +/* this struct is private in nodeSetOp.c: */ +typedef struct SetOpStatePerGroupData *SetOpStatePerGroup; + typedef struct SetOpState { PlanState ps; /* its first field is NodeTag */ - FmgrInfo *eqfunctions; /* per-field lookup data for equality fns */ - bool subplan_done; /* has subplan returned EOF? */ - long numLeft; /* number of left-input dups of cur group */ - long numRight; /* number of right-input dups of cur group */ + FmgrInfo *eqfunctions; /* per-grouping-field equality fns */ + FmgrInfo *hashfunctions; /* per-grouping-field hash fns */ + bool setop_done; /* indicates completion of output scan */ long numOutput; /* number of dups left to output */ MemoryContext tempContext; /* short-term context for comparisons */ + /* these fields are used in SETOP_SORTED mode: */ + SetOpStatePerGroup pergroup; /* per-group working state */ + HeapTuple grp_firstTuple; /* copy of first tuple of current group */ + /* these fields are used in SETOP_HASHED mode: */ + TupleHashTable hashtable; /* hash table with one entry per group */ + MemoryContext tableContext; /* memory context containing hash table */ + bool table_filled; /* hash table filled yet? */ + TupleHashIterator hashiter; /* for iterating through hash table */ } SetOpState; +/* ---------------- + * LockRowsState information + * + * LockRows nodes are used to enforce FOR UPDATE/FOR SHARE locking. + * ---------------- + */ +typedef struct LockRowsState +{ + PlanState ps; /* its first field is NodeTag */ + List *lr_rowMarks; /* List of ExecRowMarks */ + EPQState lr_epqstate; /* for evaluating EvalPlanQual rechecks */ +} LockRowsState; + /* ---------------- * LimitState information * @@ -1341,6 +1708,7 @@ typedef struct SetOpState typedef enum { LIMIT_INITIAL, /* initial state for LIMIT node */ + LIMIT_RESCAN, /* rescan after recomputing parameters */ LIMIT_EMPTY, /* there are no returnable rows */ LIMIT_INWINDOW, /* have returned a row in the window */ LIMIT_SUBPLANEOF, /* at EOF of subplan (within window) */