]> granicus.if.org Git - postgresql/blobdiff - src/include/nodes/execnodes.h
Spell 'precedes', 'preceding' correctly in various places.
[postgresql] / src / include / nodes / execnodes.h
index 7cf450785c9bbe8db976b155a116825b3566aeec..97e76ccdfd5b8b929560fbbbcfd1ab8b257e168a 100644 (file)
 /*-------------------------------------------------------------------------
  *
- * execnodes.h--
- *    definitions for executor state nodes
+ * execnodes.h
+ *       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.8 1997/08/27 09:04:52 vadim 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
+ *       IndexInfo information
+ *
+ *             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;
+typedef struct IndexInfo
+{
+       NodeTag         type;
+       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
+ *       ExprContext
+ *
+ *             This class holds the "current context" information
+ *             needed to evaluate expressions for doing tuple qualifications
+ *             and tuple projections.  For example, if an expression refers
+ *             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 RelationInfo {
-    NodeTag            type;
-    Index               ri_RangeTableIndex;
-    Relation            ri_RelationDesc;
-    int                 ri_NumIndices;
-    RelationPtr         ri_IndexRelationDescs;
-    IndexInfo           **ri_IndexRelationInfo;
-} RelationInfo;
+typedef struct ExprContext
+{
+       NodeTag         type;
+       /* Tuples that Var nodes in expression may refer to */
+       TupleTableSlot *ecxt_scantuple;
+       TupleTableSlot *ecxt_innertuple;
+       TupleTableSlot *ecxt_outertuple;
+       /* 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;
 
-/* ----------------
- *    ExprContext
- *
- *      This class holds the "current context" information
- *      needed to evaluate expressions for doing tuple qualifications
- *     and tuple projections.  For example, if an expression refers
- *     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.
- * ----------------
+/*
+ * Set-result status returned by ExecEvalExpr()
  */
-typedef struct ExprContext {
-    NodeTag       type;
-    TupleTableSlot *ecxt_scantuple;
-    TupleTableSlot *ecxt_innertuple;
-    TupleTableSlot *ecxt_outertuple;
-    Relation       ecxt_relation;
-    Index          ecxt_relid;
-    ParamListInfo  ecxt_param_list_info;
-    List           *ecxt_range_table;
-    Datum         *ecxt_values;        /* precomputed values for aggreg */
-    char           *ecxt_nulls;         /* null flags for aggreg  values */
-} ExprContext;
+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
- *     on a tuple.  Nodes which need to do projections create one
- *     of these.  In theory, when a node wants to preform a projection
- *     it should just update this information as necessary and then
- *     call ExecProject().  -cim 6/3/91
- *
- *     targetlist      target list for projection
- *     len             length of target list
- *     tupValue        array of pointers to projection results
- *     exprContext     expression context for ExecTargetList
- *     slot            slot to place projection result in
+ *             ProjectionInfo node information
+ *
+ *             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 perform a projection
+ *             it should just update this information as necessary and then
+ *             call ExecProject().  -cim 6/3/91
+ *
+ *             targetlist              target list for projection
+ *             len                             length of target list
+ *             tupValue                array of pointers to projection results
+ *             exprContext             expression context for ExecTargetList
+ *             slot                    slot to place projection result in
  * ----------------
  */
-typedef struct ProjectionInfo {
-    NodeTag            type;
-    List               *pi_targetlist;
-    int                        pi_len;
-    Datum              *pi_tupValue;
-    ExprContext                *pi_exprContext;
-    TupleTableSlot     *pi_slot;
+typedef struct ProjectionInfo
+{
+       NodeTag         type;
+       List       *pi_targetlist;
+       int                     pi_len;
+       Datum      *pi_tupValue;
+       ExprContext *pi_exprContext;
+       TupleTableSlot *pi_slot;
 } ProjectionInfo;
 
 /* ----------------
- *    JunkFilter
- *
- *    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
- *
- *    targetList:      the original target list (including junk attributes).
- *    length:          the length of 'targetList'.
- *    tupType:         the tuple descriptor for the "original" tuple
- *                     (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
- *                     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.
+ *       JunkFilter
+ *
+ *       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 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'.
+ *       tupType:                      the tuple descriptor for the "original" tuple
+ *                                             (including the junk attributes).
+ *       cleanTargetList:      the "clean" target list (junk attributes removed).
+ *       cleanLength:          the length of 'cleanTargetList'
+ *       cleanTupType:         the tuple descriptor of the "clean" tuple (with
+ *                                             junk attributes removed).
+ *       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 {
-    NodeTag            type;
-    List               *jf_targetList;
-    int                        jf_length;
-    TupleDesc          jf_tupType;
-    List               *jf_cleanTargetList;
-    int                        jf_cleanLength;
-    TupleDesc          jf_cleanTupType;
-    AttrNumber         *jf_cleanMap;
+typedef struct JunkFilter
+{
+       NodeTag         type;
+       List       *jf_targetList;
+       int                     jf_length;
+       TupleDesc       jf_tupType;
+       List       *jf_cleanTargetList;
+       int                     jf_cleanLength;
+       TupleDesc       jf_cleanTupType;
+       AttrNumber *jf_cleanMap;
+       MemoryContext jf_junkContext;
+       TupleTableSlot *jf_resultSlot;
 } JunkFilter;
 
 /* ----------------
- *    EState information
- *
- *      direction                       direction of the scan
- *
- *      range_table                     array of scan relation information
- *
- *      result_relation_information     for update 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;
-    List                *es_range_table;
-    RelationInfo        *es_result_relation_info;
-    Relation            es_into_relation_descriptor;
-    ParamListInfo       es_param_list_info;
-    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) */
+ *       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
+ *
+ *             direction                                               direction of the scan
+ *
+ *             range_table                                             array of scan relation information
+ *
+ *             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
+ *
+ *             tupleTable                                              this is a pointer to an array
+ *                                                                             of pointers to tuples used by
+ *                                                                             the executor at any given moment.
+ * ----------------
+ */
+typedef struct EState
+{
+       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;
 } EState;
 
 /* ----------------
- *      Executor Type information needed by plannodes.h
- *
- *|     Note: the bogus classes CommonState and CommonScanState exist only
- *|           because our inheritance system only allows single inheritance
- *|           and we have to have unique slot names.  Hence two or more
- *|           classes which want to have a common slot must ALL inherit
- *|           the slot from some other class.  (This is a big hack to
- *|           allow our classes to share slot names..)
+ *             Executor Type information needed by plannodes.h
+ *
+ *|            Note: the bogus classes CommonState and CommonScanState exist only
+ *|                      because our inheritance system only allows single inheritance
+ *|                      and we have to have unique slot names.  Hence two or more
+ *|                      classes which want to have a common slot must ALL inherit
+ *|                      the slot from some other class.  (This is a big hack to
+ *|                      allow our classes to share slot names..)
  *|
- *|     Example:
- *|           the class Result and the class NestLoop nodes both want
- *|           a slot called "OuterTuple" so they both have to inherit
- *|           it from some other class.  In this case they inherit
- *|           it from CommonState.  "CommonState" and "CommonScanState" are
- *|           the best names I could come up with for this sort of
- *|           stuff.
+ *|            Example:
+ *|                      the class Result and the class NestLoop nodes both want
+ *|                      a slot called "OuterTuple" so they both have to inherit
+ *|                      it from some other class.  In this case they inherit
+ *|                      it from CommonState.  "CommonState" and "CommonScanState" are
+ *|                      the best names I could come up with for this sort of
+ *|                      stuff.
  *|
- *|           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
- *|           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
+ *|                      As a result, many classes have extra slots which they
+ *|                      don't use.  These slots are denoted (unused) in the
+ *|                      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
  * ----------------
  */
 
 /* ----------------------------------------------------------------
- *               Common Executor State Information
+ *                              Common Executor State Information
  * ----------------------------------------------------------------
  */
 
-/* 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...
+ *      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 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 expression-evaluation context
+ *             ProjInfo                   info this node uses to form tuple projections
+ *             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;
-    ProjectionInfo      *cs_ProjInfo;
-    bool                cs_TupFromTlist;
+typedef struct CommonState
+{
+       NodeTag         type;                   /* its first field is NodeTag */
+       TupleTableSlot *cs_OuterTupleSlot;
+       TupleTableSlot *cs_ResultTupleSlot;
+       ExprContext *cs_ExprContext;
+       ProjectionInfo *cs_ProjInfo;
+       bool            cs_TupFromTlist;
 } CommonState;
 
 
 /* ----------------------------------------------------------------
- *               Control Node State Information
+ *                              Control Node State Information
  * ----------------------------------------------------------------
  */
 
 /* ----------------
- *   ResultState information
- *
- *      done               flag which tells us to quit when we
- *                         have already returned a constant tuple.
- *
- *   CommonState information
+ *      ResultState 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
+ *             done                       flag which tells us to quit when we
+ *                                                have already returned a constant tuple.
  * ----------------
  */
-typedef struct ResultState {
-    CommonState                cstate;         /* its first field is NodeTag */
-    int                rs_done;
+typedef struct ResultState
+{
+       CommonState cstate;                     /* its first field is NodeTag */
+       bool            rs_done;
+       bool            rs_checkqual;
 } 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
- *      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
+ *      AppendState information
+ *
+ *             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
  * ----------------
  */
-typedef struct AppendState {
-    CommonState                cstate;         /* its first field is NodeTag */
-    int                        as_whichplan;
-    int                        as_nplans;
-    bool               *as_initialized;
-    List               *as_rtentries;
-    List                *as_result_relation_info_list;
-    List                *as_junkFilter_list;
+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;
 } AppendState;
 
 /* ----------------------------------------------------------------
- *               Scan State Information
+ *                              Scan State Information
  * ----------------------------------------------------------------
  */
 
 /* ----------------
- *   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 information
  *
- *      currentRelation    relation being scanned
- *      currentScanDesc    current scan descriptor for scan
- *      ScanTupleSlot      pointer to slot in tuple table holding scan tuple
+ *             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.
  *
- *   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
+ *             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
  * ----------------
  */
-typedef struct CommonScanState {
-    CommonState                cstate;         /* its first field is NodeTag */
-    Relation           css_currentRelation;
-    HeapScanDesc       css_currentScanDesc;
-    TupleTableSlot     *css_ScanTupleSlot;
+typedef struct CommonScanState
+{
+       CommonState cstate;                     /* its first field is NodeTag */
+       Relation        css_currentRelation;
+       HeapScanDesc css_currentScanDesc;
+       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
- *
- *      IndexPtr           current index in use
- *      NumIndices         number of indices in this scan
- *      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
- *      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
+ *      IndexScanState information
+ *
+ *             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.
+ *
+ *             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
  * ----------------
  */
-typedef struct IndexScanState {
-    CommonState                cstate;         /* its first field is NodeTag */
-    int                        iss_NumIndices;
-    int                        iss_IndexPtr;
-    ScanKey            *iss_ScanKeys;
-    int                        *iss_NumScanKeys;
-    Pointer            iss_RuntimeKeyInfo;
-    RelationPtr                iss_RelationDescs;
-    IndexScanDescPtr   iss_ScanDescs;
+typedef struct IndexScanState
+{
+       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
+ *                              Join State Information
  * ----------------------------------------------------------------
  */
 
 /* ----------------
- *   JoinState 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;
+typedef CommonState JoinState;
 
 /* ----------------
- *   NestLoopState information
- *
- *      PortalFlag         Set to enable portals to work.
- *
- *   JoinState information
- *
- *   CommonState information
+ *      NestLoopState 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;
+typedef struct NestLoopState
+{
+       JoinState       jstate;                 /* its first field is NodeTag */
+       bool            nl_NeedNewOuter;
+       bool            nl_MatchedOuter;
+       TupleTableSlot *nl_NullInnerTupleSlot;
 } NestLoopState;
 
 /* ----------------
- *   MergeJoinState information
- *
- *      OSortopI           outerKey1 sortOp innerKey1 ...
- *      ISortopO           innerkey1 sortOp outerkey1 ...
- *      JoinState          current "state" of join. see executor.h
- *      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
+ *      MergeJoinState information
+ *
+ *             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
+ *             NullOuterTupleSlot prepared null tuple for right outer joins
+ *             NullInnerTupleSlot prepared null tuple for left outer joins
  * ----------------
  */
-typedef struct MergeJoinState {
-    JoinState     jstate;              /* its first field is NodeTag */
-    List           *mj_OSortopI;
-    List           *mj_ISortopO;
-    int            mj_JoinState;
-    TupleTableSlot *mj_MarkedTupleSlot;
+typedef struct MergeJoinState
+{
+       JoinState       jstate;                 /* its first field is NodeTag */
+       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_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
+ *      HashJoinState information
+ *
+ *             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_OuterTupleSlot               tuple slot for outer tuples
+ *             hj_HashTupleSlot                tuple slot for hashed tuples
+ *             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;
-    TupleTableSlot     *hj_OuterTupleSlot;
-    TupleTableSlot     *hj_HashTupleSlot;
+typedef struct HashJoinState
+{
+       JoinState       jstate;                 /* its first field is NodeTag */
+       HashJoinTable hj_HashTable;
+       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;
 
 
 /* ----------------------------------------------------------------
- *               Materialization State Information
+ *                              Materialization State Information
  * ----------------------------------------------------------------
  */
 
 /* ----------------
- *   MaterialState information
+ *      MaterialState information
  *
- *      materialize nodes are used to materialize the results
- *      of a subplan into a temporary relation.
+ *             materialize nodes are used to materialize the results
+ *             of a subplan into a temporary file.
  *
- *      Flag            indicated whether subplan has been materialized
- *      TempRelation    temporary relation containing result of executing
- *                      the subplan.
+ *             csstate.css_ScanTupleSlot refers to output of underlying plan.
  *
- *   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
+ *             tuplestorestate         private state of tuplestore.c
  * ----------------
  */
-typedef struct MaterialState {
-    CommonScanState    csstate;        /* its first field is NodeTag */
-    bool               mat_Flag;
-    Relation           mat_TempRelation;
+typedef struct MaterialState
+{
+       CommonScanState csstate;        /* its first field is NodeTag */
+       void       *tuplestorestate;
 } MaterialState;
 
 /* ---------------------
- *  AggregateState information
+ *     AggregateState information
+ *
+ *     csstate.css_ScanTupleSlot refers to output of underlying plan.
  *
- *      done            indicated whether aggregate has been materialized
+ *     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 AggState {
-    CommonScanState    csstate;        /* its first field is NodeTag */
-    bool               agg_done;
+typedef struct AggStatePerAggData *AggStatePerAgg;             /* private in nodeAgg.c */
+
+typedef struct AggState
+{
+       CommonScanState csstate;        /* its first field is NodeTag */
+       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
- *
+ *     GroupState information
  * -------------------------
  */
-typedef struct GroupState {
-    CommonScanState    csstate;        /* its first field is NodeTag */
-    bool               grp_useLastTuple; /* last tuple not processed yet */
-    bool               grp_done;
-    TupleTableSlot     *grp_lastSlot;
+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;
 } GroupState;
 
 /* ----------------
- *   SortState information
- *
- *|     sort nodes are really just a kind of a scan since
- *|     we implement sorts by retrieveing 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
+ *      SortState information
+ *
+ *             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;
+typedef struct SortState
+{
+       CommonScanState csstate;        /* its first field is NodeTag */
+       bool            sort_Done;
+       void       *tuplesortstate;
 } SortState;
 
 /* ----------------
- *   UniqueState information
- *
- *      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.
- *
- *   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
+ *      UniqueState information
+ *
+ *             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 priorTuple.
+ *             If the two are identical in all interesting fields, then
+ *             we just fetch another tuple from the sort and try again.
  * ----------------
  */
-typedef        CommonState     UniqueState;
+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
+ *
+ *             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;
 
 /* ----------------
- *   HashState information
+ *      LimitState information
  *
- *     hashBatches        file descriptors for the batches
+ *             Limit nodes are used to enforce LIMIT/OFFSET clauses.
+ *             They just select the desired subrange of their subplan's output.
  *
- *   CommonState information
+ * 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 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
  *
- *      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;
+typedef struct HashState
+{
+       CommonState cstate;                     /* its first field is NodeTag */
+       HashJoinTable hashtable;
 } HashState;
 
+#ifdef NOT_USED
 /* -----------------------
- *  TeeState information
- *    leftPlace  :    next item in the queue unseen by the left parent
- *    rightPlace :    next item in the queue unseen by the right parent
- *    lastPlace  :    last item in the queue 
- *    bufferRelname :  name of the relation used as the buffer queue
- *    bufferRel     :  the relation used as the buffer queue
- *    mcxt          :  for now, tee's have their own memory context
- *                     may be cleaned up later if portals are cleaned up
- *  
- * initially, a Tee starts with [left/right]Place variables set to  -1.
+ *     TeeState information
+ *       leftPlace  :    next item in the queue unseen by the left parent
+ *       rightPlace :    next item in the queue unseen by the right parent
+ *       lastPlace  :    last item in the queue
+ *       bufferRelname :  name of the relation used as the buffer queue
+ *       bufferRel             :  the relation used as the buffer queue
+ *       mcxt                  :  for now, tee's have their own memory context
+ *                                        may be cleaned up later if portals are cleaned up
+ *
+ * initially, a Tee starts with [left/right]Place variables set to     -1.
  * on cleanup, queue is free'd when both leftPlace and rightPlace = -1
- * ------------------------- 
+ * -------------------------
 */
-typedef struct TeeState {
-    CommonState          cstate; /* its first field is NodeTag */
-    int                  tee_leftPlace;
-    int                  tee_rightPlace;
-    int                  tee_lastPlace;
-    char                 *tee_bufferRelname;
-    Relation             tee_bufferRel;
-    MemoryContext        tee_mcxt;                                  
-    HeapScanDesc         tee_leftScanDesc;
-    HeapScanDesc         tee_rightScanDesc;
-} TeeState;
-
-#endif /* EXECNODES_H */
+typedef struct TeeState
+{
+       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;
+#endif
+
+#endif   /* EXECNODES_H */