text: /*-------------------------------------------------------------------------
   *
   * plannodes.h
   *	  definitions for query plan nodes
   *
   *
   * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
   *
   * $PostgreSQL: pgsql/src/include/nodes/plannodes.h,v 1.110 2009/06/11 14:49:11 momjian Exp $
   *
   *-------------------------------------------------------------------------
   */
  #ifndef PLANNODES_H
  #define PLANNODES_H
  
  #include "access/sdir.h"
  #include "nodes/bitmapset.h"
  #include "nodes/primnodes.h"
  #include "storage/itemptr.h"
  
  
  /* ----------------------------------------------------------------
   *						node definitions
   * ----------------------------------------------------------------
   */
  
  /* ----------------
   *		PlannedStmt node
   *
   * The output of the planner is a Plan tree headed by a PlannedStmt node.
   * PlannedStmt holds the "one time" information needed by the executor.
   * ----------------
   */
  typedef struct PlannedStmt
  {
  	NodeTag		type;
  
  	CmdType		commandType;	/* select|insert|update|delete */
  
  	bool		canSetTag;		/* do I set the command result tag? */
  
  	bool		transientPlan;	/* redo plan when TransactionXmin changes? */
  
  	struct Plan *planTree;		/* tree of Plan nodes */
  
  	List	   *rtable;			/* list of RangeTblEntry nodes */
  
  	/* rtable indexes of target relations for INSERT/UPDATE/DELETE */
  	List	   *resultRelations;	/* integer list of RT indexes, or NIL */
  
  	Node	   *utilityStmt;	/* non-null if this is DECLARE CURSOR */
  
  	IntoClause *intoClause;		/* target for SELECT INTO / CREATE TABLE AS */
  
  	List	   *subplans;		/* Plan trees for SubPlan expressions */
  
  	Bitmapset  *rewindPlanIDs;	/* indices of subplans that require REWIND */
  
  	/*
  	 * If the query has a returningList then the planner will store a list of
  	 * processed targetlists (one per result relation) here.  We must have a
  	 * separate RETURNING targetlist for each result rel because column
  	 * numbers may vary within an inheritance tree.  In the targetlists, Vars
  	 * referencing the result relation will have their original varno and
  	 * varattno, while Vars referencing other rels will be converted to have
  	 * varno OUTER and varattno referencing a resjunk entry in the top plan
  	 * node's targetlist.
  	 */
  	List	   *returningLists; /* list of lists of TargetEntry, or NIL */
  
  	List	   *rowMarks;		/* a list of RowMarkClause's */
  
  	List	   *relationOids;	/* OIDs of relations the plan depends on */
  
  	List	   *invalItems;		/* other dependencies, as PlanInvalItems */
  
  	int			nParamExec;		/* number of PARAM_EXEC Params used */
  } PlannedStmt;
  
  /* macro for fetching the Plan associated with a SubPlan node */
  #define exec_subplan_get_plan(plannedstmt, subplan) \
  	((Plan *) list_nth((plannedstmt)->subplans, (subplan)->plan_id - 1))
  
  
  /* ----------------
   *		Plan node
   *
   * All plan nodes "derive" from the Plan structure by having the
   * Plan structure as the first field.  This ensures that everything works
   * when nodes are cast to Plan's.  (node pointers are frequently cast to Plan*
   * when passed around generically in the executor)
   *
   * We never actually instantiate any Plan nodes; this is just the common
   * abstract superclass for all Plan-type nodes.
   * ----------------
   */
  typedef struct Plan
  {
  	NodeTag		type;
  
  	/*
  	 * estimated execution costs for plan (see costsize.c for more info)
  	 */
  	Cost		startup_cost;	/* cost expended before fetching any tuples */
  	Cost		total_cost;		/* total cost (assuming all tuples fetched) */
  
  	/*
  	 * planner's estimate of result size of this plan step
  	 */
  	double		plan_rows;		/* number of rows plan is expected to emit */
  	int			plan_width;		/* average row width in bytes */
  
  	/*
  	 * Common structural data for all Plan types.
  	 */
  	List	   *targetlist;		/* target list to be computed at this node */
  	List	   *qual;			/* implicitly-ANDed qual conditions */
  	struct Plan *lefttree;		/* input plan tree(s) */
  	struct Plan *righttree;
  	List	   *initPlan;		/* Init Plan nodes (un-correlated expr
  								 * subselects) */
  
  	/*
  	 * Information for management of parameter-change-driven rescanning
  	 *
  	 * extParam includes the paramIDs of all external PARAM_EXEC params
  	 * affecting this plan node or its children.  setParam params from the
  	 * node's initPlans are not included, but their extParams are.
  	 *
  	 * allParam includes all the extParam paramIDs, plus the IDs of local
  	 * params that affect the node (i.e., the setParams of its initplans).
  	 * These are _all_ the PARAM_EXEC params that affect this node.
  	 */
  	Bitmapset  *extParam;
  	Bitmapset  *allParam;
  } Plan;
  
  /* ----------------
   *	these are are defined to avoid confusion problems with "left"
   *	and "right" and "inner" and "outer".  The convention is that
   *	the "left" plan is the "outer" plan and the "right" plan is
   *	the inner plan, but these make the code more readable.
   * ----------------
   */
  #define innerPlan(node)			(((Plan *)(node))->righttree)
  #define outerPlan(node)			(((Plan *)(node))->lefttree)
  
  
  /* ----------------
   *	 Result node -
   *		If no outer plan, evaluate a variable-free targetlist.
   *		If outer plan, return tuples from outer plan (after a level of
   *		projection as shown by targetlist).
   *
   * If resconstantqual isn't NULL, it represents a one-time qualification
   * test (i.e., one that doesn't depend on any variables from the outer plan,
   * so needs to be evaluated only once).
   * ----------------
   */
  typedef struct Result
  {
  	Plan		plan;
  	Node	   *resconstantqual;
  } Result;
  
  /* ----------------
   *	 Append node -
   *		Generate the concatenation of the results of sub-plans.
   *
   * Append nodes are sometimes used to switch between several result relations
   * (when the target of an UPDATE or DELETE is an inheritance set).	Such a
   * node will have isTarget true.  The Append executor is then responsible
   * for updating the executor state to point at the correct target relation
   * whenever it switches subplans.
   * ----------------
   */
  typedef struct Append
  {
  	Plan		plan;
  	List	   *appendplans;
  	bool		isTarget;
  } Append;
  
  /* ----------------
   *	RecursiveUnion node -
   *		Generate a recursive union of two subplans.
   *
   * The "outer" subplan is always the non-recursive term, and the "inner"
   * subplan is the recursive term.
   * ----------------
   */
  typedef struct RecursiveUnion
  {
  	Plan		plan;
  	int			wtParam;		/* ID of Param representing work table */
  	/* Remaining fields are zero/null in UNION ALL case */
  	int			numCols;		/* number of columns to check for
  								 * duplicate-ness */
  	AttrNumber *dupColIdx;		/* their indexes in the target list */
  	Oid		   *dupOperators;	/* equality operators to compare with */
  	long		numGroups;		/* estimated number of groups in input */
  } RecursiveUnion;
  
  /* ----------------
   *	 BitmapAnd node -
   *		Generate the intersection of the results of sub-plans.
   *
   * The subplans must be of types that yield tuple bitmaps.	The targetlist
   * and qual fields of the plan are unused and are always NIL.
   * ----------------
   */
  typedef struct BitmapAnd
  {
  	Plan		plan;
  	List	   *bitmapplans;
  } BitmapAnd;
  
  /* ----------------
   *	 BitmapOr node -
   *		Generate the union of the results of sub-plans.
   *
   * The subplans must be of types that yield tuple bitmaps.	The targetlist
   * and qual fields of the plan are unused and are always NIL.
   * ----------------
   */
  typedef struct BitmapOr
  {
  	Plan		plan;
  	List	   *bitmapplans;
  } BitmapOr;
  
  /*
   * ==========
   * Scan nodes
   * ==========
   */
  typedef struct Scan
  {
  	Plan		plan;
  	Index		scanrelid;		/* relid is index into the range table */
  } Scan;
  
  /* ----------------
   *		sequential scan node
   * ----------------
   */
  typedef Scan SeqScan;
  
  /* ----------------
   *		index scan node
   *
   * indexqualorig is an implicitly-ANDed list of index qual expressions, each
   * in the same form it appeared in the query WHERE condition.  Each should
   * be of the form (indexkey OP comparisonval) or (comparisonval OP indexkey).
   * The indexkey is a Var or expression referencing column(s) of the index's
   * base table.	The comparisonval might be any expression, but it won't use
   * any columns of the base table.
   *
   * indexqual has the same form, but the expressions have been commuted if
   * necessary to put the indexkeys on the left, and the indexkeys are replaced
   * by Var nodes identifying the index columns (varattno is the index column
   * position, not the base table's column, even though varno is for the base
   * table).	This is a bit hokey ... would be cleaner to use a special-purpose
   * node type that could not be mistaken for a regular Var.	But it will do
   * for now.
   * ----------------
   */
  typedef struct IndexScan
  {
  	Scan		scan;
  	Oid			indexid;		/* OID of index to scan */
  	List	   *indexqual;		/* list of index quals (OpExprs) */
  	List	   *indexqualorig;	/* the same in original form */
  	ScanDirection indexorderdir;	/* forward or backward or don't care */
  } IndexScan;
  
  /* ----------------
   *		bitmap index scan node
   *
   * BitmapIndexScan delivers a bitmap of potential tuple locations;
   * it does not access the heap itself.	The bitmap is used by an
   * ancestor BitmapHeapScan node, possibly after passing through
   * intermediate BitmapAnd and/or BitmapOr nodes to combine it with
   * the results of other BitmapIndexScans.
   *
   * The fields have the same meanings as for IndexScan, except we don't
   * store a direction flag because direction is uninteresting.
   *
   * In a BitmapIndexScan plan node, the targetlist and qual fields are
   * not used and are always NIL.  The indexqualorig field is unused at
   * run time too, but is saved for the benefit of EXPLAIN.
   * ----------------
   */
  typedef struct BitmapIndexScan
  {
  	Scan		scan;
  	Oid			indexid;		/* OID of index to scan */
  	List	   *indexqual;		/* list of index quals (OpExprs) */
  	List	   *indexqualorig;	/* the same in original form */
  } BitmapIndexScan;
  
  /* ----------------
   *		bitmap sequential scan node
   *
   * This needs a copy of the qual conditions being used by the input index
   * scans because there are various cases where we need to recheck the quals;
   * for example, when the bitmap is lossy about the specific rows on a page
   * that meet the index condition.
   * ----------------
   */
  typedef struct BitmapHeapScan
  {
  	Scan		scan;
  	List	   *bitmapqualorig; /* index quals, in standard expr form */
  } BitmapHeapScan;
  
  /* ----------------
   *		tid scan node
   *
   * tidquals is an implicitly OR'ed list of qual expressions of the form
   * "CTID = pseudoconstant" or "CTID = ANY(pseudoconstant_array)".
   * ----------------
   */
  typedef struct TidScan
  {
  	Scan		scan;
  	List	   *tidquals;		/* qual(s) involving CTID = something */
  } TidScan;
  
  /* ----------------
   *		subquery scan node
   *
   * SubqueryScan is for scanning the output of a sub-query in the range table.
   * We often need an extra plan node above the sub-query's plan to perform
   * expression evaluations (which we can't push into the sub-query without
   * risking changing its semantics).  Although we are not scanning a physical
   * relation, we make this a descendant of Scan anyway for code-sharing
   * purposes.
   *
   * Note: we store the sub-plan in the type-specific subplan field, not in
   * the generic lefttree field as you might expect.	This is because we do
   * not want plan-tree-traversal routines to recurse into the subplan without
   * knowing that they are changing Query contexts.
   *
   * Note: subrtable is used just to carry the subquery rangetable from
   * createplan.c to setrefs.c; it should always be NIL by the time the
   * executor sees the plan.
   * ----------------
   */
  typedef struct SubqueryScan
  {
  	Scan		scan;
  	Plan	   *subplan;
  	List	   *subrtable;		/* temporary workspace for planner */
  } SubqueryScan;
  
  /* ----------------
   *		FunctionScan node
   * ----------------
   */
  typedef struct FunctionScan
  {
  	Scan		scan;
  	Node	   *funcexpr;		/* expression tree for func call */
  	List	   *funccolnames;	/* output column names (string Value nodes) */
  	List	   *funccoltypes;	/* OID list of column type OIDs */
  	List	   *funccoltypmods; /* integer list of column typmods */
  } FunctionScan;
  
  /* ----------------
   *		ValuesScan node
   * ----------------
   */
  typedef struct ValuesScan
  {
  	Scan		scan;
  	List	   *values_lists;	/* list of expression lists */
  } ValuesScan;
  
  /* ----------------
   *		CteScan node
   * ----------------
   */
  typedef struct CteScan
  {
  	Scan		scan;
  	int			ctePlanId;		/* ID of init SubPlan for CTE */
  	int			cteParam;		/* ID of Param representing CTE output */
  } CteScan;
  
  /* ----------------
   *		WorkTableScan node
   * ----------------
   */
  typedef struct WorkTableScan
  {
  	Scan		scan;
  	int			wtParam;		/* ID of Param representing work table */
  } WorkTableScan;
  
  
  /*
   * ==========
   * Join nodes
   * ==========
   */
  
  /* ----------------
   *		Join node
   *
   * jointype:	rule for joining tuples from left and right subtrees
   * joinqual:	qual conditions that came from JOIN/ON or JOIN/USING
   *				(plan.qual contains conditions that came from WHERE)
   *
   * When jointype is INNER, joinqual and plan.qual are semantically
   * interchangeable.  For OUTER jointypes, the two are *not* interchangeable;
   * only joinqual is used to determine whether a match has been found for
   * the purpose of deciding whether to generate null-extended tuples.
   * (But plan.qual is still applied before actually returning a tuple.)
   * For an outer join, only joinquals are allowed to be used as the merge
   * or hash condition of a merge or hash join.
   * ----------------
   */
  typedef struct Join
  {
  	Plan		plan;
  	JoinType	jointype;
  	List	   *joinqual;		/* JOIN quals (in addition to plan.qual) */
  } Join;
  
  /* ----------------
   *		nest loop join node
   * ----------------
   */
  typedef struct NestLoop
  {
  	Join		join;
  } NestLoop;
  
  /* ----------------
   *		merge join node
   *
   * The expected ordering of each mergeable column is described by a btree
   * opfamily OID, a direction (BTLessStrategyNumber or BTGreaterStrategyNumber)
   * and a nulls-first flag.	Note that the two sides of each mergeclause may
   * be of different datatypes, but they are ordered the same way according to
   * the common opfamily.  The operator in each mergeclause must be an equality
   * operator of the indicated opfamily.
   * ----------------
   */
  typedef struct MergeJoin
  {
  	Join		join;
  	List	   *mergeclauses;	/* mergeclauses as expression trees */
  	/* these are arrays, but have the same length as the mergeclauses list: */
  	Oid		   *mergeFamilies;	/* per-clause OIDs of btree opfamilies */
  	int		   *mergeStrategies;	/* per-clause ordering (ASC or DESC) */
  	bool	   *mergeNullsFirst;	/* per-clause nulls ordering */
  } MergeJoin;
  
  /* ----------------
   *		hash join node
   * ----------------
   */
  typedef struct HashJoin
  {
  	Join		join;
  	List	   *hashclauses;
  } HashJoin;
  
  /* ----------------
   *		materialization node
   * ----------------
   */
  typedef struct Material
  {
  	Plan		plan;
  } Material;
  
  /* ----------------
   *		sort node
   * ----------------
   */
  typedef struct Sort
  {
  	Plan		plan;
  	int			numCols;		/* number of sort-key columns */
  	AttrNumber *sortColIdx;		/* their indexes in the target list */
  	Oid		   *sortOperators;	/* OIDs of operators to sort them by */
  	bool	   *nullsFirst;		/* NULLS FIRST/LAST directions */
  } Sort;
  
  /* ---------------
   *	 group node -
   *		Used for queries with GROUP BY (but no aggregates) specified.
   *		The input must be presorted according to the grouping columns.
   * ---------------
   */
  typedef struct Group
  {
  	Plan		plan;
  	int			numCols;		/* number of grouping columns */
  	AttrNumber *grpColIdx;		/* their indexes in the target list */
  	Oid		   *grpOperators;	/* equality operators to compare with */
  } Group;
  
  /* ---------------
   *		aggregate node
   *
   * An Agg node implements plain or grouped aggregation.  For grouped
   * aggregation, we can work with presorted input or unsorted input;
   * the latter strategy uses an internal hashtable.
   *
   * Notice the lack of any direct info about the aggregate functions to be
   * computed.  They are found by scanning the node's tlist and quals during
   * executor startup.  (It is possible that there are no aggregate functions;
   * this could happen if they get optimized away by constant-folding, or if
   * we are using the Agg node to implement hash-based grouping.)
   * ---------------
   */
  typedef enum AggStrategy
  {
  	AGG_PLAIN,					/* simple agg across all input rows */
  	AGG_SORTED,					/* grouped agg, input must be sorted */
  	AGG_HASHED					/* grouped agg, use internal hashtable */
  } AggStrategy;
  
  typedef struct Agg
  {
  	Plan		plan;
  	AggStrategy aggstrategy;
  	int			numCols;		/* number of grouping columns */
  	AttrNumber *grpColIdx;		/* their indexes in the target list */
  	Oid		   *grpOperators;	/* equality operators to compare with */
  	long		numGroups;		/* estimated number of groups in input */
  } Agg;
  
  /* ----------------
   *		window aggregate node
   * ----------------
   */
  typedef struct WindowAgg
  {
  	Plan		plan;
  	Index		winref;			/* ID referenced by window functions */
  	int			partNumCols;	/* number of columns in partition clause */
  	AttrNumber *partColIdx;		/* their indexes in the target list */
  	Oid		   *partOperators;	/* equality operators for partition columns */
  	int			ordNumCols;		/* number of columns in ordering clause */
  	AttrNumber *ordColIdx;		/* their indexes in the target list */
  	Oid		   *ordOperators;	/* equality operators for ordering columns */
  	int			frameOptions;	/* frame_clause options, see WindowDef */
  } WindowAgg;
  
  /* ----------------
   *		unique node
   * ----------------
   */
  typedef struct Unique
  {
  	Plan		plan;
  	int			numCols;		/* number of columns to check for uniqueness */
  	AttrNumber *uniqColIdx;		/* their indexes in the target list */
  	Oid		   *uniqOperators;	/* equality operators to compare with */
  } Unique;
  
  /* ----------------
   *		hash build node
   *
   * If the executor is supposed to try to apply skew join optimization, then
   * skewTable/skewColumn identify the outer relation's join key column, from
   * which the relevant MCV statistics can be fetched.  Also, its type
   * information is provided to save a lookup.
   * ----------------
   */
  typedef struct Hash
  {
  	Plan		plan;
  	Oid			skewTable;		/* outer join key's table OID, or InvalidOid */
  	AttrNumber	skewColumn;		/* outer join key's column #, or zero */
  	Oid			skewColType;	/* datatype of the outer key column */
  	int32		skewColTypmod;	/* typmod of the outer key column */
  	/* all other info is in the parent HashJoin node */
  } Hash;
  
  /* ----------------
   *		setop node
   * ----------------
   */
  typedef enum SetOpCmd
  {
  	SETOPCMD_INTERSECT,
  	SETOPCMD_INTERSECT_ALL,
  	SETOPCMD_EXCEPT,
  	SETOPCMD_EXCEPT_ALL
  } SetOpCmd;
  
  typedef enum SetOpStrategy
  {
  	SETOP_SORTED,				/* input must be sorted */
  	SETOP_HASHED				/* use internal hashtable */
  } SetOpStrategy;
  
  typedef struct SetOp
  {
  	Plan		plan;
  	SetOpCmd	cmd;			/* what to do */
  	SetOpStrategy strategy;		/* how to do it */
  	int			numCols;		/* number of columns to check for
  								 * duplicate-ness */
  	AttrNumber *dupColIdx;		/* their indexes in the target list */
  	Oid		   *dupOperators;	/* equality operators to compare with */
  	AttrNumber	flagColIdx;		/* where is the flag column, if any */
  	int			firstFlag;		/* flag value for first input relation */
  	long		numGroups;		/* estimated number of groups in input */
  } SetOp;
  
  /* ----------------
   *		limit node
   *
   * Note: as of Postgres 8.2, the offset and count expressions are expected
   * to yield int8, rather than int4 as before.
   * ----------------
   */
  typedef struct Limit
  {
  	Plan		plan;
  	Node	   *limitOffset;	/* OFFSET parameter, or NULL if none */
  	Node	   *limitCount;		/* COUNT parameter, or NULL if none */
  } Limit;
  
  
  /*
   * Plan invalidation info
   *
   * We track the objects on which a PlannedStmt depends in two ways:
   * relations are recorded as a simple list of OIDs, and everything else
   * is represented as a list of PlanInvalItems.	A PlanInvalItem is designed
   * to be used with the syscache invalidation mechanism, so it identifies a
   * system catalog entry by cache ID and tuple TID.
   */
  typedef struct PlanInvalItem
  {
  	NodeTag		type;
  	int			cacheId;		/* a syscache ID, see utils/syscache.h */
  	ItemPointerData tupleId;	/* TID of the object's catalog tuple */
  } PlanInvalItem;
  
  #endif   /* PLANNODES_H */
  