* definitions for query plan nodes
*
*
- * Copyright (c) 1994, Regents of the University of California
+ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: plannodes.h,v 1.34 1999/11/23 20:07:02 momjian Exp $
+ * $Id: plannodes.h,v 1.65 2003/05/06 00:20:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PLANNODES_H
#define PLANNODES_H
-#include "nodes/execnodes.h"
-
-/* ----------------------------------------------------------------
- * Executor State types are used in the plannode structures
- * so we have to include their definitions too.
- *
- * Node Type node information used by executor
- *
- * control nodes
- *
- * Result ResultState resstate;
- * Append AppendState appendstate;
- *
- * scan nodes
- *
- * Scan *** CommonScanState scanstate;
- * IndexScan IndexScanState indxstate;
- *
- * (*** nodes which inherit Scan also inherit scanstate)
- *
- * join nodes
- *
- * NestLoop NestLoopState nlstate;
- * MergeJoin MergeJoinState mergestate;
- * HashJoin HashJoinState hashjoinstate;
- *
- * materialize nodes
- *
- * Material MaterialState matstate;
- * Sort SortState sortstate;
- * Unique UniqueState uniquestate;
- * Hash HashState hashstate;
- *
- * ----------------------------------------------------------------
- */
+#include "access/sdir.h"
+#include "nodes/bitmapset.h"
+#include "nodes/primnodes.h"
/* ----------------------------------------------------------------
/* ----------------
* 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;
- Cost cost;
- int plan_size;
- int plan_width;
- int plan_tupperpage;
- EState *state; /* at execution time, state's of
- * individual nodes point to one EState
- * for the whole top-level plan */
- List *targetlist;
- List *qual; /* Node* or List* ?? */
- struct Plan *lefttree;
+
+ /*
+ * 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 *extParam; /* indices of _all_ _external_ PARAM_EXEC
- * for this plan in global
- * es_param_exec_vals. Params from
- * setParam from initPlan-s are not
- * included, but their execParam-s are
- * here!!! */
- List *locParam; /* someones from setParam-s */
- List *chgParam; /* list of changed ones from the above */
List *initPlan; /* Init Plan nodes (un-correlated expr
* subselects) */
- List *subPlan; /* Other SubPlan nodes */
+
+ /*
+ * 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;
/*
* We really need in some TopPlan node to store range table and
#define outerPlan(node) (((Plan *)(node))->lefttree)
-/*
- * ===============
- * Top-level nodes
- * ===============
- */
-
-/* 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 */
-
-
/* ----------------
- * result node -
- * returns tuples from outer plan that satisfy the qualifications
+ * 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;
- ResultState *resstate;
} Result;
/* ----------------
- * append node
+ * 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;
- List *unionrtables; /* List of range tables, one for each
- * union query. */
- Index inheritrelid; /* The range table has to be changed for
- * inheritance. */
- List *inheritrtable;
- AppendState *appendstate;
+ bool isTarget;
} Append;
/*
{
Plan plan;
Index scanrelid; /* relid is index into the range table */
- CommonScanState *scanstate;
} Scan;
/* ----------------
List *indxid;
List *indxqual;
List *indxqualorig;
- ScanDirection indxorderdir;
- IndexScanState *indxstate;
+ ScanDirection indxorderdir;
} IndexScan;
/* ----------------
- * tid scan node
+ * tid scan node
* ----------------
*/
typedef struct TidScan
{
- Scan scan;
- bool needRescan;
- List *tideval;
- TidScanState *tidstate;
+ Scan scan;
+ List *tideval;
} TidScan;
-/*
+/* ----------------
+ * subquery scan node
+ *
+ * SubqueryScan is for scanning the output of a sub-query in the range table.
+ * We need a special plan node above the sub-query's plan as a place to switch
+ * execution contexts. 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.
+ * ----------------
+ */
+typedef struct SubqueryScan
+{
+ Scan scan;
+ Plan *subplan;
+} SubqueryScan;
+
+/* ----------------
+ * FunctionScan node
+ * ----------------
+ */
+typedef struct FunctionScan
+{
+ Scan scan;
+ /* no other fields needed at present */
+} FunctionScan;
+
+/*
* ==========
* 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 Plan 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;
- NestLoopState *nlstate;
} NestLoop;
/* ----------------
{
Join join;
List *mergeclauses;
- MergeJoinState *mergestate;
} MergeJoin;
/* ----------------
{
Join join;
List *hashclauses;
- Oid hashjoinop;
- HashJoinState *hashjoinstate;
- bool hashdone;
} HashJoin;
-/* ---------------
- * aggregate node
- * ---------------
+/* ----------------
+ * materialization node
+ * ----------------
*/
-typedef struct Agg
+typedef struct Material
{
Plan plan;
- AggState *aggstate;
-} Agg;
+} 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 */
+} Sort;
/* ---------------
* group node -
- * use for queries with GROUP BY specified.
- *
- * If tuplePerGroup is true, one tuple (with group columns only) is
- * returned for each group and NULL is returned when there are no more
- * groups. Otherwise, all the tuples of a group are returned with a
- * NULL returned at the end of each group. (see nodeGroup.c for details)
+ * 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;
- bool tuplePerGroup; /* what tuples to return (see above) */
- int numCols; /* number of group columns */
- AttrNumber *grpColIdx; /* index into the target list */
- GroupState *grpstate;
+ int numCols; /* number of grouping columns */
+ AttrNumber *grpColIdx; /* their indexes in the target list */
} Group;
-/*
- * ==========
- * Noname nodes
- * ==========
- */
-typedef struct Noname
-{
- Plan plan;
- Oid nonameid;
- int keycount;
-} Noname;
-
-/* ----------------
- * materialization node
- * ----------------
+/* ---------------
+ * 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 struct Material
+typedef enum AggStrategy
{
- Plan plan; /* noname node flattened out */
- Oid nonameid;
- int keycount;
- MaterialState *matstate;
-} Material;
+ AGG_PLAIN, /* simple agg across all input rows */
+ AGG_SORTED, /* grouped agg, input must be sorted */
+ AGG_HASHED /* grouped agg, use internal hashtable */
+} AggStrategy;
-/* ----------------
- * sort node
- * ----------------
- */
-typedef struct Sort
+typedef struct Agg
{
- Plan plan; /* noname node flattened out */
- Oid nonameid;
- int keycount;
- SortState *sortstate;
-} Sort;
+ Plan plan;
+ AggStrategy aggstrategy;
+ int numCols; /* number of grouping columns */
+ AttrNumber *grpColIdx; /* their indexes in the target list */
+ long numGroups; /* estimated number of groups in input */
+} Agg;
/* ----------------
* unique node
*/
typedef struct Unique
{
- Plan plan; /* noname node flattened out */
- Oid nonameid;
- int keycount;
- char *uniqueAttr; /* NULL if all attrs, or unique attribute
- * name */
- AttrNumber uniqueAttrNum; /* attribute number of attribute to select
- * distinct on */
- UniqueState *uniquestate;
+ Plan plan;
+ int numCols; /* number of columns to check for
+ * uniqueness */
+ AttrNumber *uniqColIdx; /* indexes into the target list */
} Unique;
/* ----------------
typedef struct Hash
{
Plan plan;
- Var *hashkey;
- HashState *hashstate;
+ List *hashkeys;
} Hash;
-#ifdef NOT_USED
-/* -------------------
- * Tee node information
- *
- * leftParent : the left parent of this node
- * rightParent: the right parent of this node
- * -------------------
-*/
-typedef struct Tee
+/* ----------------
+ * setop node
+ * ----------------
+ */
+typedef enum SetOpCmd
+{
+ SETOPCMD_INTERSECT,
+ SETOPCMD_INTERSECT_ALL,
+ SETOPCMD_EXCEPT,
+ SETOPCMD_EXCEPT_ALL
+} SetOpCmd;
+
+typedef struct SetOp
{
Plan plan;
- Plan *leftParent;
- Plan *rightParent;
- TeeState *teestate;
- char *teeTableName; /* the name of the table to materialize
- * the tee into */
- List *rtentries; /* the range table for the plan below the
- * Tee may be different than the parent
- * plans */
-} Tee;
-
-#endif
-
-/* ---------------------
- * SubPlan node
- * ---------------------
+ SetOpCmd cmd; /* what to do */
+ int numCols; /* number of columns to check for
+ * duplicate-ness */
+ AttrNumber *dupColIdx; /* indexes into the target list */
+ AttrNumber flagColIdx;
+} SetOp;
+
+/* ----------------
+ * limit node
+ * ----------------
*/
-typedef struct SubPlan
+typedef struct Limit
{
- NodeTag type;
- Plan *plan; /* subselect plan itself */
- int plan_id; /* dummy thing because of we haven't equal
- * funcs for plan nodes... actually, we
- * could put *plan itself somewhere else
- * (TopPlan node ?)... */
- List *rtable; /* range table for subselect */
- /* setParam and parParam are lists of integers (param IDs) */
- List *setParam; /* non-correlated EXPR & EXISTS subqueries
- * have to set some Params for paren Plan */
- List *parParam; /* indices of corr. Vars from parent plan */
- SubLink *sublink; /* SubLink node from parser; holds info about
- * what to do with subselect's results */
- /*
- * Remaining fields are working state for executor; not used in planning
- */
- bool shutdown; /* TRUE = need to shutdown plan */
- HeapTuple curTuple; /* copy of most recent tuple from subplan */
-} SubPlan;
+ Plan plan;
+ Node *limitOffset; /* OFFSET parameter, or NULL if none */
+ Node *limitCount; /* COUNT parameter, or NULL if none */
+} Limit;
-#endif /* PLANNODES_H */
+#endif /* PLANNODES_H */