* definitions for executor state nodes
*
*
- * Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: execnodes.h,v 1.27 1999/03/23 16:51:00 momjian Exp $
+ * $Id: execnodes.h,v 1.67 2001/11/21 22:57:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef EXECNODES_H
#define EXECNODES_H
-#include <nodes/memnodes.h>
-#include <nodes/primnodes.h>
-#include <executor/hashjoin.h>
-#include <access/relscan.h>
-#include <access/sdir.h>
-#include <nodes/params.h>
-#include <executor/tuptable.h>
-#include <access/funcindex.h>
+#include "access/relscan.h"
+#include "access/sdir.h"
+#include "executor/hashjoin.h"
+#include "executor/tuptable.h"
+#include "fmgr.h"
+#include "nodes/params.h"
+#include "nodes/primnodes.h"
/* ----------------
* IndexInfo information
*
- * this class holds the information saying what attributes
- * are the key attributes for this index. -cim 10/15/89
- *
- * NumKeyAttributes number of key attributes for this index
- * KeyAttributeNumbers array of attribute numbers used as keys
- * Predicate partial-index predicate for this index
+ * this class holds the information needed to construct new index
+ * entries for a particular index. Used for both index_build and
+ * retail creation of index entries.
+ *
+ * NumIndexAttrs number of columns in this index
+ * (1 if a func. index, else same as NumKeyAttrs)
+ * NumKeyAttrs number of key attributes for this index
+ * (ie, number of attrs from underlying relation)
+ * KeyAttrNumbers underlying-rel attribute numbers used as keys
+ * Predicate partial-index predicate, or NIL if none
+ * FuncOid OID of function, or InvalidOid if not f. index
+ * FuncInfo fmgr lookup data for function, if FuncOid valid
+ * Unique is it a unique index?
* ----------------
*/
typedef struct IndexInfo
{
NodeTag type;
- int ii_NumKeyAttributes;
- AttrNumber *ii_KeyAttributeNumbers;
- FuncIndexInfoPtr ii_FuncIndexInfo;
- Node *ii_Predicate;
+ int ii_NumIndexAttrs;
+ int ii_NumKeyAttrs;
+ AttrNumber ii_KeyAttrNumbers[INDEX_MAX_KEYS];
+ List *ii_Predicate;
+ Oid ii_FuncOid;
+ FmgrInfo ii_FuncInfo;
+ bool ii_Unique;
} IndexInfo;
-/* ----------------
- * RelationInfo information
- *
- * whenever we update an existing relation, we have to
- * update indices on the relation. The RelationInfo class
- * is used to hold all the information on result relations,
- * including indices.. -cim 10/15/89
- *
- * RangeTableIndex result relation's range table index
- * RelationDesc relation descriptor for result relation
- * NumIndices number indices existing on result relation
- * IndexRelationDescs array of relation descriptors for indices
- * IndexRelationInfo array of key/attr info for indices
- * ----------------
- */
-typedef struct RelationInfo
-{
- NodeTag type;
- Index ri_RangeTableIndex;
- Relation ri_RelationDesc;
- int ri_NumIndices;
- RelationPtr ri_IndexRelationDescs;
- IndexInfo **ri_IndexRelationInfo;
-} RelationInfo;
-
/* ----------------
* ExprContext
*
* to an attribute in the current inner tuple then we need to know
* what the current inner tuple is and so we look at the expression
* context.
+ *
+ * There are two memory contexts associated with an ExprContext:
+ * * ecxt_per_query_memory is a relatively long-lived context (such as
+ * TransactionCommandContext); typically it's the same context the
+ * ExprContext node itself is allocated in. This context can be
+ * used for purposes such as storing operator/function fcache nodes.
+ * * ecxt_per_tuple_memory is a short-term context for expression results.
+ * As the name suggests, it will typically be reset once per tuple,
+ * before we begin to evaluate expressions for that tuple. Each
+ * ExprContext normally has its very own per-tuple memory context.
+ * CurrentMemoryContext should be set to ecxt_per_tuple_memory before
+ * calling ExecEvalExpr() --- see ExecEvalExprSwitchContext().
* ----------------
*/
typedef struct ExprContext
{
NodeTag type;
+ /* Tuples that Var nodes in expression may refer to */
TupleTableSlot *ecxt_scantuple;
TupleTableSlot *ecxt_innertuple;
TupleTableSlot *ecxt_outertuple;
- Relation ecxt_relation;
- Index ecxt_relid;
- ParamListInfo ecxt_param_list_info;
- ParamExecData *ecxt_param_exec_vals; /* this is for subselects */
- List *ecxt_range_table;
- Datum *ecxt_values; /* precomputed values for aggreg */
- char *ecxt_nulls; /* null flags for aggreg values */
+ /* Memory contexts for expression evaluation --- see notes above */
+ MemoryContext ecxt_per_query_memory;
+ MemoryContext ecxt_per_tuple_memory;
+ /* Values to substitute for Param nodes in expression */
+ 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 */
} ExprContext;
+/*
+ * Set-result status returned by ExecEvalExpr()
+ */
+typedef enum
+{
+ ExprSingleResult, /* expression does not return a set */
+ ExprMultipleResult, /* this result is an element of a set */
+ ExprEndResult /* there are no more elements in the set */
+} ExprDoneCond;
+
+/*
+ * When calling a function that might return a set (multiple rows),
+ * a node of this type is passed as fcinfo->resultinfo to allow
+ * return status to be passed back. A function returning set should
+ * raise an error if no such resultinfo is provided.
+ *
+ * XXX this mechanism is a quick hack and probably needs to be redesigned.
+ */
+typedef struct ReturnSetInfo
+{
+ NodeTag type;
+ ExprDoneCond isDone;
+} ReturnSetInfo;
+
+
/* ----------------
* ProjectionInfo node information
*
- * This is all the information needed to preform projections
+ * This is all the information needed to perform projections
* on a tuple. Nodes which need to do projections create one
- * of these. In theory, when a node wants to preform a projection
+ * of these. In theory, when a node wants to perform a projection
* it should just update this information as necessary and then
* call ExecProject(). -cim 6/3/91
*
/* ----------------
* JunkFilter
*
- * this class is used to store information regarding junk attributes.
+ * This class is used to store information regarding junk attributes.
* A junk attribute is an attribute in a tuple that is needed only for
* storing intermediate information in the executor, and does not belong
- * in the tuple proper. For example, when we do a delete or replace
- * query, the planner adds an entry to the targetlist so that the tuples
- * returned to ExecutePlan() contain an extra attribute: the t_ctid of
- * the tuple to be deleted/replaced. This is needed for amdelete() and
- * amreplace(). In doing a delete this does not make much of a
- * difference, but in doing a replace we have to make sure we disgard
- * all the junk in a tuple before calling amreplace(). Otherwise the
- * inserted tuple will not have the correct schema. This solves a
- * problem with hash-join and merge-sort replace plans. -cim 10/10/90
+ * in emitted tuples. For example, when we do an UPDATE query,
+ * the planner adds a "junk" entry to the targetlist so that the tuples
+ * returned to ExecutePlan() contain an extra attribute: the ctid of
+ * 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.
*
* targetList: the original target list (including junk attributes).
* length: the length of 'targetList'.
* (including the junk attributes).
* cleanTargetList: the "clean" target list (junk attributes removed).
* cleanLength: the length of 'cleanTargetList'
- * cleanTupTyp: the tuple descriptor of the "clean" tuple (with
+ * cleanTupType: the tuple descriptor of the "clean" tuple (with
* junk attributes removed).
- * cleanMap: A map with the correspondance between the non junk
- * attributes of the "original" tuple and the
- * attributes of the "clean" tuple.
+ * cleanMap: A map with the correspondence between the non-junk
+ * attribute numbers of the "original" tuple and the
+ * attribute numbers of the "clean" tuple.
+ * junkContext: memory context holding the JunkFilter node and all
+ * its subsidiary data structures.
+ * resultSlot: tuple slot that can be used to hold cleaned tuple.
+ *
+ * NOTE: the original targetList and tupType are passed to ExecInitJunkFilter,
+ * as is the resultSlot. These items do not belong to the JunkFilter. All
+ * the other subsidiary structures are created during ExecInitJunkFilter,
+ * and all of them can be freed by deleting the memory context junkContext.
+ * This would not be needed if we had a cleaner approach to managing
+ * query-lifetime data structures...
* ----------------
*/
typedef struct JunkFilter
int jf_cleanLength;
TupleDesc jf_cleanTupType;
AttrNumber *jf_cleanMap;
+ MemoryContext jf_junkContext;
+ TupleTableSlot *jf_resultSlot;
} JunkFilter;
+/* ----------------
+ * ResultRelInfo information
+ *
+ * Whenever we update an existing relation, we have to
+ * update indices on the relation, and perhaps also fire triggers.
+ * The ResultRelInfo class is used to hold all the information needed
+ * about a result relation, including indices.. -cim 10/15/89
+ *
+ * RangeTableIndex result relation's range table index
+ * RelationDesc relation descriptor for result relation
+ * NumIndices # of indices existing on result relation
+ * IndexRelationDescs array of relation descriptors for indices
+ * IndexRelationInfo array of key/attr info for indices
+ * TrigDesc triggers to be fired, if any
+ * TrigFunctions cached lookup info for trigger functions
+ * ConstraintExprs array of constraint-checking expressions
+ * junkFilter for removing junk attributes from tuples
+ * ----------------
+ */
+typedef struct ResultRelInfo
+{
+ NodeTag type;
+ Index ri_RangeTableIndex;
+ Relation ri_RelationDesc;
+ int ri_NumIndices;
+ RelationPtr ri_IndexRelationDescs;
+ IndexInfo **ri_IndexRelationInfo;
+ TriggerDesc *ri_TrigDesc;
+ FmgrInfo *ri_TrigFunctions;
+ List **ri_ConstraintExprs;
+ JunkFilter *ri_junkFilter;
+} ResultRelInfo;
+
/* ----------------
* EState information
*
*
* range_table array of scan relation information
*
- * result_relation_information for update queries
+ * result_relation information for insert/update/delete queries
*
* into_relation_descriptor relation being retrieved "into"
*
* param_list_info information needed to transform
* Param nodes into Const nodes
*
- * BaseId during InitPlan(), each node is
- * given a number. this is the next
- * number to be assigned.
- *
* tupleTable this is a pointer to an array
* of pointers to tuples used by
* the executor at any given moment.
- *
- * junkFilter contains information used to
- * extract junk attributes from a tuple.
- * (see JunkFilter above)
- *
- * refcount local buffer refcounts used in
- * an ExecMain cycle. this is introduced
- * to avoid ExecStart's unpinning each
- * other's buffers when called recursively
* ----------------
*/
typedef struct EState
{
- NodeTag type;
- ScanDirection es_direction;
- Snapshot es_snapshot;
- List *es_range_table;
- RelationInfo *es_result_relation_info;
- List **es_result_relation_constraints;
- Relation es_into_relation_descriptor;
- ParamListInfo es_param_list_info;
- ParamExecData *es_param_exec_vals; /* this is for subselects */
- int es_BaseId;
- TupleTable es_tupleTable;
- JunkFilter *es_junkFilter;
- int *es_refcount;
- uint32 es_processed; /* # of tuples processed */
- Oid es_lastoid; /* last oid processed (by INSERT) */
- List *es_rowMark; /* not good place, but there is no other */
+ NodeTag type;
+ ScanDirection es_direction;
+ Snapshot es_snapshot;
+ List *es_range_table;
+ 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 */
+ Relation es_into_relation_descriptor;
+ ParamListInfo es_param_list_info;
+ ParamExecData *es_param_exec_vals; /* this is for subselects */
+ TupleTable es_tupleTable;
+ uint32 es_processed; /* # of tuples processed */
+ Oid es_lastoid; /* last oid processed (by INSERT) */
+ List *es_rowMark; /* not good place, but there is no other */
+ MemoryContext es_query_cxt; /* per-query context in which EState lives */
+
+ /*
+ * this ExprContext is for per-output-tuple operations, such as
+ * constraint checks and index-value computations. It will be reset
+ * for each output tuple. Note that it will be created only if
+ * needed.
+ */
+ ExprContext *es_per_tuple_exprcontext;
/* Below is to re-evaluate plan qual in READ COMMITTED mode */
- struct Plan *es_origPlan;
- Pointer es_evalPlanQual;
- bool *es_evTupleNull;
- HeapTuple *es_evTuple;
- bool es_useEvalPlan;
+ struct Plan *es_origPlan;
+ Pointer es_evalPlanQual;
+ bool *es_evTupleNull;
+ HeapTuple *es_evTuple;
+ bool es_useEvalPlan;
} EState;
/* ----------------
*|
*| As a result, many classes have extra slots which they
*| don't use. These slots are denoted (unused) in the
- *| comment preceeding the class definition. If you
+ *| comment preceding the class definition. If you
*| comes up with a better idea of a way of doing things
*| along these lines, then feel free to make your idea
*| known to me.. -cim 10/15/89
* ----------------------------------------------------------------
*/
-/* BaseNode removed -- base_id moved into CommonState - jolly */
-
/* ----------------
* CommonState information
*
- *| this is a bogus class used to hold slots so other
- *| nodes can inherit them...
+ * Superclass for all executor node-state object types.
*
* OuterTupleSlot pointer to slot containing current "outer" tuple
* ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
+ * ExprContext node's expression-evaluation context
* ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
- *
+ * TupFromTlist state flag used by some node types (why kept here?)
* ----------------
*/
typedef struct CommonState
{
NodeTag type; /* its first field is NodeTag */
- int cs_base_id;
TupleTableSlot *cs_OuterTupleSlot;
TupleTableSlot *cs_ResultTupleSlot;
ExprContext *cs_ExprContext;
*
* done flag which tells us to quit when we
* have already returned a constant tuple.
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct ResultState
/* ----------------
* AppendState information
*
- * append nodes have this field "unionplans" which is this
- * list of plans to execute in sequence.. these variables
- * keep track of things..
- *
- * whichplan which plan is being executed
+ * whichplan which plan is being executed (0 .. n-1)
+ * firstplan first plan to execute (usually 0)
+ * lastplan last plan to execute (usually n-1)
* nplans how many plans are in the list
* initialized array of ExecInitNode() results
- * rtentries range table for the current plan
- * result_relation_info_list array of each subplan's result relation info
- * junkFilter_list array of each subplan's junk filter
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct AppendState
{
CommonState cstate; /* its first field is NodeTag */
int as_whichplan;
+ int as_firstplan;
+ int as_lastplan;
int as_nplans;
bool *as_initialized;
- List *as_rtentries;
- List *as_result_relation_info_list;
- List *as_junkFilter_list;
} AppendState;
/* ----------------------------------------------------------------
/* ----------------
* CommonScanState information
*
- * CommonScanState is a class like CommonState, but is used more
- * by the nodes like SeqScan and Sort which want to
- * keep track of an underlying relation.
+ * CommonScanState extends CommonState for node types that represent
+ * scans of an underlying relation. It can also be used for nodes
+ * that scan the output of an underlying plan node --- in that case,
+ * only ScanTupleSlot is actually useful, and it refers to the tuple
+ * retrieved from the subplan.
*
- * currentRelation relation being scanned
- * currentScanDesc current scan descriptor for scan
+ * currentRelation relation being scanned (NULL if none)
+ * currentScanDesc current scan descriptor for scan (NULL if none)
* ScanTupleSlot pointer to slot in tuple table holding scan tuple
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct CommonScanState
TupleTableSlot *css_ScanTupleSlot;
} CommonScanState;
+/*
+ * SeqScan uses a bare CommonScanState as its state item, since it needs
+ * no additional fields.
+ */
+
/* ----------------
* IndexScanState information
*
- *| index scans don't use CommonScanState because
- *| the underlying AM abstractions for heap scans and
- *| index scans are too different.. It would be nice
- *| if the current abstraction was more useful but ... -cim 10/15/89
+ * Note that an IndexScan node *also* has a CommonScanState state item.
+ * IndexScanState stores the info needed specifically for indexing.
+ * There's probably no good reason why this is a separate node type
+ * rather than an extension of CommonScanState.
*
- * IndexPtr current index in use
* NumIndices number of indices in this scan
+ * IndexPtr current index in use
* ScanKeys Skey structures to scan index rels
* NumScanKeys array of no of keys in each Skey struct
* RuntimeKeyInfo array of array of flags for Skeys evaled at runtime
+ * RuntimeContext expr context for evaling runtime Skeys
+ * RuntimeKeysReady true if runtime Skeys have been computed
* RelationDescs ptr to array of relation descriptors
* ScanDescs ptr to array of scan descriptors
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
* ----------------
*/
typedef struct IndexScanState
{
- CommonState cstate; /* its first field is NodeTag */
- int iss_NumIndices;
- int iss_IndexPtr;
- int iss_MarkIndexPtr;
- ScanKey *iss_ScanKeys;
- int *iss_NumScanKeys;
- Pointer iss_RuntimeKeyInfo;
- RelationPtr iss_RelationDescs;
- IndexScanDescPtr iss_ScanDescs;
- HeapTupleData iss_htup;
+ NodeTag type;
+ int iss_NumIndices;
+ int iss_IndexPtr;
+ int iss_MarkIndexPtr;
+ ScanKey *iss_ScanKeys;
+ int *iss_NumScanKeys;
+ int **iss_RuntimeKeyInfo;
+ ExprContext *iss_RuntimeContext;
+ bool iss_RuntimeKeysReady;
+ RelationPtr iss_RelationDescs;
+ IndexScanDescPtr iss_ScanDescs;
+ HeapTupleData iss_htup;
} IndexScanState;
+/* ----------------
+ * TidScanState information
+ *
+ * Note that a TidScan node *also* has a CommonScanState state item.
+ * There's probably no good reason why this is a separate node type
+ * rather than an extension of CommonScanState.
+ *
+ * NumTids number of tids in this scan
+ * TidPtr current tid in use
+ * TidList evaluated item pointers
+ * ----------------
+ */
+typedef struct TidScanState
+{
+ NodeTag type;
+ int tss_NumTids;
+ int tss_TidPtr;
+ int tss_MarkTidPtr;
+ ItemPointerData *tss_TidList;
+ HeapTupleData tss_htup;
+} 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
+{
+ CommonScanState csstate; /* its first field is NodeTag */
+ EState *sss_SubEState;
+} SubqueryScanState;
/* ----------------------------------------------------------------
* Join State Information
/* ----------------
* JoinState information
*
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * Superclass for state items of join nodes.
+ * Currently this is the same as CommonState.
* ----------------
*/
typedef CommonState JoinState;
/* ----------------
* NestLoopState information
*
- * PortalFlag Set to enable portals to work.
- *
- * JoinState information
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * NeedNewOuter true if need new outer tuple on next call
+ * MatchedOuter true if found a join match for current outer tuple
+ * NullInnerTupleSlot prepared null tuple for left outer joins
* ----------------
*/
typedef struct NestLoopState
{
JoinState jstate; /* its first field is NodeTag */
- bool nl_PortalFlag;
+ bool nl_NeedNewOuter;
+ bool nl_MatchedOuter;
+ TupleTableSlot *nl_NullInnerTupleSlot;
} NestLoopState;
/* ----------------
* OuterSkipQual outerKey1 < innerKey1 ...
* InnerSkipQual outerKey1 > innerKey1 ...
* JoinState current "state" of join. see executor.h
+ * MatchedOuter true if found a join match for current outer tuple
+ * MatchedInner true if found a join match for current inner tuple
+ * OuterTupleSlot pointer to slot in tuple table for cur outer tuple
+ * InnerTupleSlot pointer to slot in tuple table for cur inner tuple
* MarkedTupleSlot pointer to slot in tuple table for marked tuple
- *
- * JoinState information
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * NullOuterTupleSlot prepared null tuple for right outer joins
+ * NullInnerTupleSlot prepared null tuple for left outer joins
* ----------------
*/
typedef struct MergeJoinState
List *mj_OuterSkipQual;
List *mj_InnerSkipQual;
int mj_JoinState;
+ bool mj_MatchedOuter;
+ bool mj_MatchedInner;
+ TupleTableSlot *mj_OuterTupleSlot;
+ TupleTableSlot *mj_InnerTupleSlot;
TupleTableSlot *mj_MarkedTupleSlot;
+ TupleTableSlot *mj_NullOuterTupleSlot;
+ TupleTableSlot *mj_NullInnerTupleSlot;
} MergeJoinState;
/* ----------------
* HashJoinState information
*
- * hj_HashTable address of the hash table for the hashjoin
- * hj_HashTableShmId shared memory id of hash table
- * hj_CurBucket the current hash bucket that we are searching
- * for matches of the current outer tuple
- * hj_CurTuple the current matching inner tuple in the
- * current hash bucket
- * hj_CurOTuple the current matching inner tuple in the
- * current hash overflow chain
+ * hj_HashTable hash table for the hashjoin
+ * hj_CurBucketNo bucket# for current outer tuple
+ * hj_CurTuple last inner tuple matched to current outer
+ * tuple, or NULL if starting search
+ * (CurBucketNo and CurTuple are meaningless
+ * unless OuterTupleSlot is nonempty!)
* hj_InnerHashKey the inner hash key in the hashjoin condition
- * hj_OuterBatches file descriptors for outer batches
- * hj_InnerBatches file descriptors for inner batches
- * hj_OuterReadPos current read position of outer batch
- * hj_OuterReadBlk current read block of outer batch
* hj_OuterTupleSlot tuple slot for outer tuples
* hj_HashTupleSlot tuple slot for hashed tuples
- *
- *
- *
- * JoinState information
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * hj_NullInnerTupleSlot prepared null tuple for left outer joins
+ * hj_NeedNewOuter true if need new outer tuple on next call
+ * hj_MatchedOuter true if found a join match for current outer
+ * hj_hashdone true if hash-table-build phase is done
* ----------------
*/
typedef struct HashJoinState
{
JoinState jstate; /* its first field is NodeTag */
HashJoinTable hj_HashTable;
- IpcMemoryId hj_HashTableShmId;
- HashBucket hj_CurBucket;
- HeapTuple hj_CurTuple;
- OverflowTuple hj_CurOTuple;
- Var *hj_InnerHashKey;
- File *hj_OuterBatches;
- File *hj_InnerBatches;
- char *hj_OuterReadPos;
- int hj_OuterReadBlk;
+ int hj_CurBucketNo;
+ HashJoinTuple hj_CurTuple;
+ Node *hj_InnerHashKey;
TupleTableSlot *hj_OuterTupleSlot;
TupleTableSlot *hj_HashTupleSlot;
+ TupleTableSlot *hj_NullInnerTupleSlot;
+ bool hj_NeedNewOuter;
+ bool hj_MatchedOuter;
+ bool hj_hashdone;
} HashJoinState;
* MaterialState information
*
* materialize nodes are used to materialize the results
- * of a subplan into a temporary relation.
- *
- * Flag indicated whether subplan has been materialized
- * TempRelation temporary relation containing result of executing
- * the subplan.
+ * of a subplan into a temporary file.
*
- * CommonScanState information
- *
- * currentRelation relation descriptor of sorted relation
- * currentScanDesc current scan descriptor for scan
- * ScanTupleSlot pointer to slot in tuple table holding scan tuple
- *
- * CommonState information
+ * csstate.css_ScanTupleSlot refers to output of underlying plan.
*
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * tuplestorestate private state of tuplestore.c
* ----------------
*/
typedef struct MaterialState
{
CommonScanState csstate; /* its first field is NodeTag */
- bool mat_Flag;
- Relation mat_TempRelation;
+ void *tuplestorestate;
} MaterialState;
/* ---------------------
* AggregateState information
*
- * done indicated whether aggregate has been materialized
+ * csstate.css_ScanTupleSlot refers to output of underlying plan.
+ *
+ * Note: the associated ExprContext contains ecxt_aggvalues and ecxt_aggnulls
+ * arrays, which hold the computed agg values for the current input group
+ * during evaluation of an Agg node's output tuple(s).
* -------------------------
*/
+typedef struct AggStatePerAggData *AggStatePerAgg; /* private in nodeAgg.c */
+
typedef struct AggState
{
CommonScanState csstate; /* its first field is NodeTag */
- bool agg_done;
+ List *aggs; /* all Aggref nodes in targetlist & quals */
+ int numaggs; /* length of list (could be zero!) */
+ AggStatePerAgg peragg; /* per-Aggref working state */
+ MemoryContext tup_cxt; /* context for per-output-tuple
+ * expressions */
+ MemoryContext agg_cxt[2]; /* pair of expression eval memory contexts */
+ int which_cxt; /* 0 or 1, indicates current agg_cxt */
+ bool agg_done; /* indicates completion of Agg scan */
} AggState;
/* ---------------------
* GroupState information
- *
* -------------------------
*/
typedef struct GroupState
{
CommonScanState csstate; /* its first field is NodeTag */
+ FmgrInfo *eqfunctions; /* per-field lookup data for equality fns */
bool grp_useFirstTuple; /* first tuple not processed yet */
bool grp_done;
HeapTuple grp_firstTuple;
/* ----------------
* SortState information
*
- *| sort nodes are really just a kind of a scan since
- *| we implement sorts by retrieving the entire subplan
- *| into a temp relation, sorting the temp relation into
- *| another sorted relation, and then preforming a simple
- *| unqualified sequential scan on the sorted relation..
- *| -cim 10/15/89
- *
- * Flag indicated whether relation has been sorted
- * Keys scan key structures used to keep info on sort keys
- * TempRelation temporary relation containing result of executing
- * the subplan.
- *
- * CommonScanState information
- *
- * currentRelation relation descriptor of sorted relation
- * currentScanDesc current scan descriptor for scan
- * ScanTupleSlot pointer to slot in tuple table holding scan tuple
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * sort_Done indicates whether sort has been performed yet
+ * tuplesortstate private state of tuplesort.c
* ----------------
*/
typedef struct SortState
{
CommonScanState csstate; /* its first field is NodeTag */
- bool sort_Flag;
- ScanKey sort_Keys;
- bool cleaned;
+ bool sort_Done;
+ void *tuplesortstate;
} SortState;
/* ----------------
* Unique nodes are used "on top of" sort nodes to discard
* duplicate tuples returned from the sort phase. Basically
* all it does is compare the current tuple from the subplan
- * with the previously fetched tuple stored in OuterTuple and
- * if the two are identical, then we just fetch another tuple
- * from the sort and try again.
+ * with the previously fetched tuple stored in priorTuple.
+ * If the two are identical in all interesting fields, then
+ * we just fetch another tuple from the sort and try again.
+ * ----------------
+ */
+typedef struct UniqueState
+{
+ CommonState cstate; /* its first field is NodeTag */
+ FmgrInfo *eqfunctions; /* per-field lookup data for equality fns */
+ HeapTuple priorTuple; /* most recently returned tuple, or NULL */
+ MemoryContext tempContext; /* short-term context for comparisons */
+} UniqueState;
+
+/* ----------------
+ * SetOpState information
*
- * CommonState 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.
+ * ----------------
+ */
+typedef struct SetOpState
+{
+ CommonState cstate; /* 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 */
+ long numOutput; /* number of dups left to output */
+ MemoryContext tempContext; /* short-term context for comparisons */
+} SetOpState;
+
+/* ----------------
+ * LimitState information
*
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * Limit nodes are used to enforce LIMIT/OFFSET clauses.
+ * They just select the desired subrange of their subplan's output.
+ *
+ * offset is the number of initial tuples to skip (0 does nothing).
+ * count is the number of tuples to return after skipping the offset tuples.
+ * If no limit count was specified, count is undefined and noCount is true.
* ----------------
*/
-typedef CommonState UniqueState;
+typedef struct LimitState
+{
+ CommonState cstate; /* its first field is NodeTag */
+ long offset; /* current OFFSET value */
+ long count; /* current COUNT, if any */
+ long position; /* 1-based index of last tuple fetched */
+ bool parmsSet; /* have we calculated offset/limit yet? */
+ bool noCount; /* if true, ignore count */
+ bool atEnd; /* if true, we've reached EOF of subplan */
+} LimitState;
/* ----------------
* HashState information
*
- * hashBatches file descriptors for the batches
- *
- * CommonState information
- *
- * OuterTupleSlot pointer to slot containing current "outer" tuple
- * ResultTupleSlot pointer to slot in tuple table for projected tuple
- * ExprContext node's current expression context
- * ProjInfo info this node uses to form tuple projections
- * NumScanAttributes size of ScanAttributes array
- * ScanAttributes attribute numbers of interest in this tuple
+ * hashtable hash table for the hashjoin
* ----------------
*/
typedef struct HashState
{
CommonState cstate; /* its first field is NodeTag */
- File *hashBatches;
+ HashJoinTable hashtable;
} HashState;
#ifdef NOT_USED
*/
typedef struct TeeState
{
- CommonState cstate; /* its first field is NodeTag */
- int tee_leftPlace,
- tee_rightPlace,
- tee_lastPlace;
- char *tee_bufferRelname;
- Relation tee_bufferRel;
+ CommonState cstate; /* its first field is NodeTag */
+ int tee_leftPlace,
+ tee_rightPlace,
+ tee_lastPlace;
+ char *tee_bufferRelname;
+ Relation tee_bufferRel;
MemoryContext tee_mcxt;
- HeapScanDesc tee_leftScanDesc,
- tee_rightScanDesc;
-} TeeState;
+ HeapScanDesc tee_leftScanDesc,
+ tee_rightScanDesc;
+} TeeState;
#endif
-#endif /* EXECNODES_H */
+#endif /* EXECNODES_H */