]> granicus.if.org Git - postgresql/blobdiff - src/include/nodes/primnodes.h
Change EXPLAIN output so that subplans and initplans (particularly CTEs)
[postgresql] / src / include / nodes / primnodes.h
index 0748eecae035d2531e2fbf60728278e69662de12..7fc7c00d63eb31914985c72682dddb1a71bb7558 100644 (file)
@@ -7,10 +7,10 @@
  *       and join trees.
  *
  *
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: primnodes.h,v 1.64 2002/06/20 20:29:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.148 2009/04/05 19:59:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "access/attnum.h"
 #include "nodes/pg_list.h"
 
-/* FunctionCache is declared in utils/fcache.h */
-typedef struct FunctionCache *FunctionCachePtr;
-
 
 /* ----------------------------------------------------------------
  *                                             node definitions
  * ----------------------------------------------------------------
  */
 
-/*--------------------
- * Resdom (Result Domain)
- *
- * Notes:
- * ressortgroupref is the parse/plan-time representation of ORDER BY and
- * GROUP BY items.     Targetlist entries with ressortgroupref=0 are not
- * sort/group items.  If ressortgroupref>0, then this item is an ORDER BY or
- * GROUP BY value.     No two entries in a targetlist may have the same nonzero
- * ressortgroupref --- but there is no particular meaning to the nonzero
- * values, except as tags.     (For example, one must not assume that lower
- * ressortgroupref means a more significant sort key.) The order of the
- * associated SortClause or GroupClause lists determine the semantics.
- *
- * reskey and reskeyop are the execution-time representation of sorting.
- * reskey must be zero in any non-sort-key item.  The reskey of sort key
- * targetlist items for a sort plan node is 1,2,...,n for the n sort keys.
- * The reskeyop of each such targetlist item is the sort operator's OID.
- * reskeyop will be zero in non-sort-key items.
- *
- * Both reskey and reskeyop are typically zero during parse/plan stages.
- * The executor does not pay any attention to ressortgroupref.
- *--------------------
- */
-typedef struct Resdom
-{
-       NodeTag         type;
-       AttrNumber      resno;                  /* attribute number */
-       Oid                     restype;                /* type of the value */
-       int32           restypmod;              /* type-specific modifier of the value */
-       char       *resname;            /* name of the resdom (could be NULL) */
-       Index           ressortgroupref;
-       /* nonzero if referenced by a sort/group clause */
-       Index           reskey;                 /* order of key in a sort (for those > 0) */
-       Oid                     reskeyop;               /* sort operator's Oid */
-       bool            resjunk;                /* set to true to eliminate the attribute
-                                                                * from final target list */
-} Resdom;
-
-/*
- * Fjoin
- */
-typedef struct Fjoin
-{
-       NodeTag         type;
-       bool            fj_initialized; /* true if the Fjoin has already been
-                                                                * initialized for the current target list
-                                                                * evaluation */
-       int                     fj_nNodes;              /* The number of Iter nodes returning sets
-                                                                * that the node will flatten */
-       List       *fj_innerNode;       /* exactly one Iter node.  We eval every
-                                                                * node in the outerList once then eval
-                                                                * the inner node to completion pair the
-                                                                * outerList result vector with each inner
-                                                                * result to form the full result.      When
-                                                                * the inner has been exhausted, we get
-                                                                * the next outer result vector and reset
-                                                                * the inner. */
-       DatumPtr        fj_results;             /* The complete (flattened) result vector */
-       BoolPtr         fj_alwaysDone;  /* a null vector to indicate sets with a
-                                                                * cardinality of 0, we treat them as the
-                                                                * set {NULL}. */
-} Fjoin;
-
-
 /*
  * Alias -
  *       specifies an alias for a range variable; the alias might also
  *       specify renaming of columns within the table.
+ *
+ * Note: colnames is a list of Value nodes (always strings).  In Alias structs
+ * associated with RTEs, there may be entries corresponding to dropped
+ * columns; these are normally empty strings ("").     See parsenodes.h for info.
  */
 typedef struct Alias
 {
        NodeTag         type;
        char       *aliasname;          /* aliased rel name (never qualified) */
        List       *colnames;           /* optional list of column aliases */
-       /* Note: colnames is a list of Value nodes (always strings) */
 } Alias;
 
 typedef enum InhOption
@@ -113,6 +49,15 @@ typedef enum InhOption
        INH_DEFAULT                                     /* Use current SQL_inheritance option */
 } InhOption;
 
+/* What to do at commit time for temporary relations */
+typedef enum OnCommitAction
+{
+       ONCOMMIT_NOOP,                          /* No ON COMMIT clause (do nothing) */
+       ONCOMMIT_PRESERVE_ROWS,         /* ON COMMIT PRESERVE ROWS (do nothing) */
+       ONCOMMIT_DELETE_ROWS,           /* ON COMMIT DELETE ROWS */
+       ONCOMMIT_DROP                           /* ON COMMIT DROP */
+} OnCommitAction;
+
 /*
  * RangeVar - range variable, used in FROM clauses
  *
@@ -127,12 +72,27 @@ typedef struct RangeVar
        char       *catalogname;        /* the catalog (database) name, or NULL */
        char       *schemaname;         /* the schema name, or NULL */
        char       *relname;            /* the relation/sequence name */
-       InhOption       inhOpt;                 /* expand rel by inheritance? 
-                                                                * recursively act on children? */
+       InhOption       inhOpt;                 /* expand rel by inheritance? recursively act
+                                                                * on children? */
        bool            istemp;                 /* is this a temp relation/sequence? */
        Alias      *alias;                      /* table alias & optional column aliases */
+       int                     location;               /* token location, or -1 if unknown */
 } RangeVar;
 
+/*
+ * IntoClause - target information for SELECT INTO and CREATE TABLE AS
+ */
+typedef struct IntoClause
+{
+       NodeTag         type;
+
+       RangeVar   *rel;                        /* target relation name */
+       List       *colNames;           /* column names to assign, or NIL */
+       List       *options;            /* options from WITH clause */
+       OnCommitAction onCommit;        /* what do we do at COMMIT? */
+       char       *tableSpaceName; /* table space to use, or NULL */
+} IntoClause;
+
 
 /* ----------------------------------------------------------------
  *                                     node types for executable expressions
@@ -140,64 +100,20 @@ typedef struct RangeVar
  */
 
 /*
- * Expr
+ * Expr - generic superclass for executable-expression nodes
+ *
+ * All node types that are used in executable expression trees should derive
+ * from Expr (that is, have Expr as their first field).  Since Expr only
+ * contains NodeTag, this is a formality, but it is an easy form of
+ * documentation.  See also the ExprState node types in execnodes.h.
  */
-typedef enum OpType
-{
-       OP_EXPR, FUNC_EXPR, OR_EXPR, AND_EXPR, NOT_EXPR, SUBPLAN_EXPR
-} OpType;
-
 typedef struct Expr
 {
        NodeTag         type;
-       Oid                     typeOid;                /* oid of the type of this expression */
-       OpType          opType;                 /* kind of expression */
-       Node       *oper;                       /* operator node if needed (Oper, Func, or
-                                                                * SubPlan) */
-       List       *args;                       /* arguments to this expression */
 } Expr;
 
 /*
- * Oper - Expr subnode for an OP_EXPR
- *
- * NOTE: in the good old days 'opno' used to be both (or either, or
- * neither) the pg_operator oid, and/or the pg_proc oid depending
- * on the postgres module in question (parser->pg_operator,
- * executor->pg_proc, planner->both), the mood of the programmer,
- * and the phase of the moon (rumors that it was also depending on the day
- * of the week are probably false). To make things even more postgres-like
- * (i.e. a mess) some comments were referring to 'opno' using the name
- * 'opid'. Anyway, now we have two separate fields, and of course that
- * immediately removes all bugs from the code...               [ sp :-) ].
- *
- * Note also that opid is not necessarily filled in immediately on creation
- * of the node.  The planner makes sure it is valid before passing the node
- * tree to the executor, but during parsing/planning opid is typically 0.
- */
-typedef struct Oper
-{
-       NodeTag         type;
-       Oid                     opno;                   /* PG_OPERATOR OID of the operator */
-       Oid                     opid;                   /* PG_PROC OID of underlying function */
-       Oid                     opresulttype;   /* PG_TYPE OID of result value */
-       bool            opretset;               /* true if operator returns set */
-       FunctionCachePtr op_fcache;     /* runtime state, else NULL */
-} Oper;
-
-/*
- * Func - Expr subnode for a FUNC_EXPR
- */
-typedef struct Func
-{
-       NodeTag         type;
-       Oid                     funcid;                 /* PG_PROC OID of the function */
-       Oid                     funcresulttype; /* PG_TYPE OID of result value */
-       bool            funcretset;             /* true if function returns set */
-       FunctionCachePtr func_fcache; /* runtime state, or NULL */
-} Func;
-
-/*
- * Var
+ * Var - expression node representing a variable (ie, a table column)
  *
  * Note: during parsing/planning, varnoold/varoattno are always just copies
  * of varno/varattno.  At the tail end of planning, Var nodes appearing in
@@ -216,23 +132,19 @@ typedef struct Func
 
 typedef struct Var
 {
-       NodeTag         type;
-       Index           varno;                  /* index of this var's relation in the
-                                                                * range table (could also be INNER or
-                                                                * OUTER) */
-       AttrNumber      varattno;               /* attribute number of this var, or zero
-                                                                * for all */
-       Oid                     vartype;                /* pg_type tuple OID for the type of this
-                                                                * var */
+       Expr            xpr;
+       Index           varno;                  /* index of this var's relation in the range
+                                                                * table (could also be INNER or OUTER) */
+       AttrNumber      varattno;               /* attribute number of this var, or zero for
+                                                                * all */
+       Oid                     vartype;                /* pg_type OID for the type of this var */
        int32           vartypmod;              /* pg_attribute typmod value */
-       Index           varlevelsup;
-
-       /*
-        * for subquery variables referencing outer relations; 0 in a normal
-        * var, >0 means N levels up
-        */
+       Index           varlevelsup;    /* for subquery variables referencing outer
+                                                                * relations; 0 in a normal var, >0 means N
+                                                                * levels up */
        Index           varnoold;               /* original value of varno, for debugging */
        AttrNumber      varoattno;              /* original value of varattno */
+       int                     location;               /* token location, or -1 if unknown */
 } Var;
 
 /*
@@ -240,55 +152,59 @@ typedef struct Var
  */
 typedef struct Const
 {
-       NodeTag         type;
-       Oid                     consttype;              /* PG_TYPE OID of the constant's value */
-       int                     constlen;               /* length in bytes of the constant's value */
+       Expr            xpr;
+       Oid                     consttype;              /* pg_type OID of the constant's datatype */
+       int32           consttypmod;    /* typmod value, if any */
+       int                     constlen;               /* typlen of the constant's datatype */
        Datum           constvalue;             /* the constant's value */
        bool            constisnull;    /* whether the constant is null (if true,
-                                                                * the other fields are undefined) */
-       bool            constbyval;             /* whether the information in constvalue
-                                                                * if passed by value.  If true, then all
-                                                                * the information is stored in the datum.
-                                                                * If false, then the datum contains a
-                                                                * pointer to the information. */
-       bool            constisset;             /* whether the const represents a set. The
-                                                                * const value corresponding will be the
-                                                                * query that defines the set. */
-       bool            constiscast;
+                                                                * constvalue is undefined) */
+       bool            constbyval;             /* whether this datatype is passed by value.
+                                                                * If true, then all the information is stored
+                                                                * in the Datum. If false, then the Datum
+                                                                * contains a pointer to the information. */
+       int                     location;               /* token location, or -1 if unknown */
 } Const;
 
 /* ----------------
  * Param
  *             paramkind - specifies the kind of parameter. The possible values
- *             for this field are specified in "params.h", and they are:
+ *             for this field are:
  *
- *             PARAM_NAMED: The parameter has a name, i.e. something
- *                             like `$.salary' or `$.foobar'.
- *                             In this case field `paramname' must be a valid Name.
+ *             PARAM_EXTERN:  The parameter value is supplied from outside the plan.
+ *                             Such parameters are numbered from 1 to n.
  *
- *             PARAM_NUM:       The parameter has only a numeric identifier,
- *                             i.e. something like `$1', `$2' etc.
- *                             The number is contained in the `paramid' field.
+ *             PARAM_EXEC:  The parameter is an internal executor parameter, used
+ *                             for passing values into and out of sub-queries.
+ *                             For historical reasons, such parameters are numbered from 0.
+ *                             These numbers are independent of PARAM_EXTERN numbers.
  *
- *             PARAM_NEW:       Used in PRS2 rule, similar to PARAM_NAMED.
- *                                      The `paramname' and `paramid' refer to the "NEW" tuple
- *                                      The `pramname' is the attribute name and `paramid'
- *                                      is the attribute number.
+ *             PARAM_SUBLINK:  The parameter represents an output column of a SubLink
+ *                             node's sub-select.  The column number is contained in the
+ *                             `paramid' field.  (This type of Param is converted to
+ *                             PARAM_EXEC during planning.)
  *
- *             PARAM_OLD:       Same as PARAM_NEW, but in this case we refer to
- *                             the "OLD" tuple.
+ * Note: currently, paramtypmod is valid for PARAM_SUBLINK Params, and for
+ * PARAM_EXEC Params generated from them; it is always -1 for PARAM_EXTERN
+ * params, since the APIs that supply values for such parameters don't carry
+ * any typmod info.
  * ----------------
  */
+typedef enum ParamKind
+{
+       PARAM_EXTERN,
+       PARAM_EXEC,
+       PARAM_SUBLINK
+} ParamKind;
+
 typedef struct Param
 {
-       NodeTag         type;
-       int                     paramkind;              /* specifies the kind of parameter.  See
-                                                                * above */
-       AttrNumber      paramid;                /* numeric identifier for literal-constant
-                                                                * parameters ("$1") */
-       char       *paramname;          /* attribute name for tuple-substitution
-                                                                * parameters ("$.foo") */
-       Oid                     paramtype;              /* PG_TYPE OID of the parameter's value */
+       Expr            xpr;
+       ParamKind       paramkind;              /* kind of parameter. See above */
+       int                     paramid;                /* numeric ID for parameter */
+       Oid                     paramtype;              /* pg_type OID of parameter's datatype */
+       int32           paramtypmod;    /* typmod value, if known */
+       int                     location;               /* token location, or -1 if unknown */
 } Param;
 
 /*
@@ -296,16 +212,184 @@ typedef struct Param
  */
 typedef struct Aggref
 {
-       NodeTag         type;
+       Expr            xpr;
        Oid                     aggfnoid;               /* pg_proc Oid of the aggregate */
        Oid                     aggtype;                /* type Oid of result of the aggregate */
-       Node       *target;                     /* expression we are aggregating on */
-       bool            aggstar;                /* TRUE if argument was really '*' */
+       List       *args;                       /* arguments to the aggregate */
+       Index           agglevelsup;    /* > 0 if agg belongs to outer query */
+       bool            aggstar;                /* TRUE if argument list was really '*' */
        bool            aggdistinct;    /* TRUE if it's agg(DISTINCT ...) */
-       int                     aggno;                  /* workspace for executor (see nodeAgg.c) */
+       int                     location;               /* token location, or -1 if unknown */
 } Aggref;
 
+/*
+ * WindowFunc
+ */
+typedef struct WindowFunc
+{
+       Expr            xpr;
+       Oid                     winfnoid;               /* pg_proc Oid of the function */
+       Oid                     wintype;                /* type Oid of result of the window function */
+       List       *args;                       /* arguments to the window function */
+       Index           winref;                 /* index of associated WindowClause */
+       bool            winstar;                /* TRUE if argument list was really '*' */
+       bool            winagg;                 /* is function a simple aggregate? */
+       int                     location;               /* token location, or -1 if unknown */
+} WindowFunc;
+
 /* ----------------
+ *     ArrayRef: describes an array subscripting operation
+ *
+ * An ArrayRef can describe fetching a single element from an array,
+ * fetching a subarray (array slice), storing a single element into
+ * an array, or storing a slice.  The "store" cases work with an
+ * initial array value and a source value that is inserted into the
+ * appropriate part of the array; the result of the operation is an
+ * entire new modified array value.
+ *
+ * If reflowerindexpr = NIL, then we are fetching or storing a single array
+ * element at the subscripts given by refupperindexpr. Otherwise we are
+ * fetching or storing an array slice, that is a rectangular subarray
+ * with lower and upper bounds given by the index expressions.
+ * reflowerindexpr must be the same length as refupperindexpr when it
+ * is not NIL.
+ *
+ * Note: the result datatype is the element type when fetching a single
+ * element; but it is the array type when doing subarray fetch or either
+ * type of store.
+ * ----------------
+ */
+typedef struct ArrayRef
+{
+       Expr            xpr;
+       Oid                     refarraytype;   /* type of the array proper */
+       Oid                     refelemtype;    /* type of the array elements */
+       int32           reftypmod;              /* typmod of the array (and elements too) */
+       List       *refupperindexpr;/* expressions that evaluate to upper array
+                                                                * indexes */
+       List       *reflowerindexpr;/* expressions that evaluate to lower array
+                                                                * indexes */
+       Expr       *refexpr;            /* the expression that evaluates to an array
+                                                                * value */
+       Expr       *refassgnexpr;       /* expression for the source value, or NULL if
+                                                                * fetch */
+} ArrayRef;
+
+/*
+ * CoercionContext - distinguishes the allowed set of type casts
+ *
+ * NB: ordering of the alternatives is significant; later (larger) values
+ * allow more casts than earlier ones.
+ */
+typedef enum CoercionContext
+{
+       COERCION_IMPLICIT,                      /* coercion in context of expression */
+       COERCION_ASSIGNMENT,            /* coercion in context of assignment */
+       COERCION_EXPLICIT                       /* explicit cast operation */
+} CoercionContext;
+
+/*
+ * CoercionForm - information showing how to display a function-call node
+ */
+typedef enum CoercionForm
+{
+       COERCE_EXPLICIT_CALL,           /* display as a function call */
+       COERCE_EXPLICIT_CAST,           /* display as an explicit cast */
+       COERCE_IMPLICIT_CAST,           /* implicit cast, so hide it */
+       COERCE_DONTCARE                         /* special case for planner */
+} CoercionForm;
+
+/*
+ * FuncExpr - expression node for a function call
+ */
+typedef struct FuncExpr
+{
+       Expr            xpr;
+       Oid                     funcid;                 /* PG_PROC OID of the function */
+       Oid                     funcresulttype; /* PG_TYPE OID of result value */
+       bool            funcretset;             /* true if function returns set */
+       CoercionForm funcformat;        /* how to display this function call */
+       List       *args;                       /* arguments to the function */
+       int                     location;               /* token location, or -1 if unknown */
+} FuncExpr;
+
+/*
+ * OpExpr - expression node for an operator invocation
+ *
+ * Semantically, this is essentially the same as a function call.
+ *
+ * Note that opfuncid is not necessarily filled in immediately on creation
+ * of the node.  The planner makes sure it is valid before passing the node
+ * tree to the executor, but during parsing/planning opfuncid can be 0.
+ */
+typedef struct OpExpr
+{
+       Expr            xpr;
+       Oid                     opno;                   /* PG_OPERATOR OID of the operator */
+       Oid                     opfuncid;               /* PG_PROC OID of underlying function */
+       Oid                     opresulttype;   /* PG_TYPE OID of result value */
+       bool            opretset;               /* true if operator returns set */
+       List       *args;                       /* arguments to the operator (1 or 2) */
+       int                     location;               /* token location, or -1 if unknown */
+} OpExpr;
+
+/*
+ * DistinctExpr - expression node for "x IS DISTINCT FROM y"
+ *
+ * Except for the nodetag, this is represented identically to an OpExpr
+ * referencing the "=" operator for x and y.
+ * We use "=", not the more obvious "<>", because more datatypes have "="
+ * than "<>".  This means the executor must invert the operator result.
+ * Note that the operator function won't be called at all if either input
+ * is NULL, since then the result can be determined directly.
+ */
+typedef OpExpr DistinctExpr;
+
+/*
+ * ScalarArrayOpExpr - expression node for "scalar op ANY/ALL (array)"
+ *
+ * The operator must yield boolean.  It is applied to the left operand
+ * and each element of the righthand array, and the results are combined
+ * with OR or AND (for ANY or ALL respectively).  The node representation
+ * is almost the same as for the underlying operator, but we need a useOr
+ * flag to remember whether it's ANY or ALL, and we don't have to store
+ * the result type because it must be boolean.
+ */
+typedef struct ScalarArrayOpExpr
+{
+       Expr            xpr;
+       Oid                     opno;                   /* PG_OPERATOR OID of the operator */
+       Oid                     opfuncid;               /* PG_PROC OID of underlying function */
+       bool            useOr;                  /* true for ANY, false for ALL */
+       List       *args;                       /* the scalar and array operands */
+       int                     location;               /* token location, or -1 if unknown */
+} ScalarArrayOpExpr;
+
+/*
+ * BoolExpr - expression node for the basic Boolean operators AND, OR, NOT
+ *
+ * Notice the arguments are given as a List.  For NOT, of course the list
+ * must always have exactly one element.  For AND and OR, the executor can
+ * handle any number of arguments.  The parser generally treats AND and OR
+ * as binary and so it typically only produces two-element lists, but the
+ * optimizer will flatten trees of AND and OR nodes to produce longer lists
+ * when possible.  There are also a few special cases where more arguments
+ * can appear before optimization.
+ */
+typedef enum BoolExprType
+{
+       AND_EXPR, OR_EXPR, NOT_EXPR
+} BoolExprType;
+
+typedef struct BoolExpr
+{
+       Expr            xpr;
+       BoolExprType boolop;
+       List       *args;                       /* arguments to this expression */
+       int                     location;               /* token location, or -1 if unknown */
+} BoolExpr;
+
+/*
  * SubLink
  *
  * A SubLink represents a subselect appearing in an expression, and in some
@@ -314,132 +398,190 @@ typedef struct Aggref
  *     EXISTS_SUBLINK          EXISTS(SELECT ...)
  *     ALL_SUBLINK                     (lefthand) op ALL (SELECT ...)
  *     ANY_SUBLINK                     (lefthand) op ANY (SELECT ...)
- *     MULTIEXPR_SUBLINK       (lefthand) op (SELECT ...)
+ *     ROWCOMPARE_SUBLINK      (lefthand) op (SELECT ...)
  *     EXPR_SUBLINK            (SELECT with single targetlist item ...)
- * For ALL, ANY, and MULTIEXPR, the lefthand is a list of expressions of the
- * same length as the subselect's targetlist.  MULTIEXPR will *always* have
+ *     ARRAY_SUBLINK           ARRAY(SELECT with single targetlist item ...)
+ *     CTE_SUBLINK                     WITH query (never actually part of an expression)
+ * For ALL, ANY, and ROWCOMPARE, the lefthand is a list of expressions of the
+ * same length as the subselect's targetlist.  ROWCOMPARE will *always* have
  * a list with more than one entry; if the subselect has just one target
  * then the parser will create an EXPR_SUBLINK instead (and any operator
  * above the subselect will be represented separately).  Note that both
- * MULTIEXPR and EXPR require the subselect to deliver only one row.
- * ALL, ANY, and MULTIEXPR require the combining operators to deliver boolean
- * results.  These are reduced to one result per row using OR or AND semantics
- * depending on the "useor" flag.  ALL and ANY combine the per-row results
- * using AND and OR semantics respectively.
- *
- * NOTE: lefthand and oper have varying meanings depending on where you look
- * in the parse/plan pipeline:
- * 1. gram.y delivers a list of the (untransformed) lefthand expressions in
- *       lefthand, and sets oper to a single A_Expr (not a list!) containing
- *       the string name of the operator, but no arguments.
- * 2. The parser's expression transformation transforms lefthand normally,
- *       and replaces oper with a list of Oper nodes, one per lefthand
- *       expression.  These nodes represent the parser's resolution of exactly
- *       which operator to apply to each pair of lefthand and targetlist
- *       expressions.  However, we have not constructed actual Expr trees for
- *       these operators yet.  This is the representation seen in saved rules
- *       and in the rewriter.
- * 3. Finally, the planner converts the oper list to a list of normal Expr
- *       nodes representing the application of the operator(s) to the lefthand
- *       expressions and values from the inner targetlist.  The inner
- *       targetlist items are represented by placeholder Param or Const nodes.
- *       The lefthand field is set to NIL, since its expressions are now in
- *       the Expr list.  This representation is passed to the executor.
- *
- * Planner routines that might see either representation 2 or 3 can tell
- * the difference by checking whether lefthand is NIL or not.  Also,
- * representation 2 appears in a "bare" SubLink, while representation 3 is
- * found in SubLinks that are children of SubPlan nodes.
- *
- * In EXISTS and EXPR SubLinks, both lefthand and oper are unused and are
- * always NIL. useor is not significant either for these sublink types.
- * ----------------
+ * ROWCOMPARE and EXPR require the subselect to deliver only one row.
+ * ALL, ANY, and ROWCOMPARE require the combining operators to deliver boolean
+ * results.  ALL and ANY combine the per-row results using AND and OR
+ * semantics respectively.
+ * ARRAY requires just one target column, and creates an array of the target
+ * column's type using any number of rows resulting from the subselect.
+ *
+ * SubLink is classed as an Expr node, but it is not actually executable;
+ * it must be replaced in the expression tree by a SubPlan node during
+ * planning.
+ *
+ * NOTE: in the raw output of gram.y, testexpr contains just the raw form
+ * of the lefthand expression (if any), and operName is the String name of
+ * the combining operator.     Also, subselect is a raw parsetree.  During parse
+ * analysis, the parser transforms testexpr into a complete boolean expression
+ * that compares the lefthand value(s) to PARAM_SUBLINK nodes representing the
+ * output columns of the subselect.  And subselect is transformed to a Query.
+ * This is the representation seen in saved rules and in the rewriter.
+ *
+ * In EXISTS, EXPR, and ARRAY SubLinks, testexpr and operName are unused and
+ * are always null.
+ *
+ * The CTE_SUBLINK case never occurs in actual SubLink nodes, but it is used
+ * in SubPlans generated for WITH subqueries.
  */
 typedef enum SubLinkType
 {
-       EXISTS_SUBLINK, ALL_SUBLINK, ANY_SUBLINK, MULTIEXPR_SUBLINK, EXPR_SUBLINK
+       EXISTS_SUBLINK,
+       ALL_SUBLINK,
+       ANY_SUBLINK,
+       ROWCOMPARE_SUBLINK,
+       EXPR_SUBLINK,
+       ARRAY_SUBLINK,
+       CTE_SUBLINK                                     /* for SubPlans only */
 } SubLinkType;
 
 
 typedef struct SubLink
 {
-       NodeTag         type;
-       SubLinkType subLinkType;        /* EXISTS, ALL, ANY, MULTIEXPR, EXPR */
-       bool            useor;                  /* TRUE to combine column results with
-                                                                * "OR" not "AND" */
-       List       *lefthand;           /* list of outer-query expressions on the
-                                                                * left */
-       List       *oper;                       /* list of Oper nodes for combining
-                                                                * operators */
+       Expr            xpr;
+       SubLinkType subLinkType;        /* see above */
+       Node       *testexpr;           /* outer-query test for ALL/ANY/ROWCOMPARE */
+       List       *operName;           /* originally specified operator name */
        Node       *subselect;          /* subselect as Query* or parsetree */
+       int                     location;               /* token location, or -1 if unknown */
 } SubLink;
 
-/* ----------------
- *     ArrayRef: describes an array subscripting operation
+/*
+ * SubPlan - executable expression node for a subplan (sub-SELECT)
  *
- * An ArrayRef can describe fetching a single element from an array,
- * fetching a subarray (array slice), storing a single element into
- * an array, or storing a slice.  The "store" cases work with an
- * initial array value and a source value that is inserted into the
- * appropriate part of the array; the result of the operation is an
- * entire new modified array value.
+ * The planner replaces SubLink nodes in expression trees with SubPlan
+ * nodes after it has finished planning the subquery.  SubPlan references
+ * a sub-plantree stored in the subplans list of the toplevel PlannedStmt.
+ * (We avoid a direct link to make it easier to copy expression trees
+ * without causing multiple processing of the subplan.)
  *
- * If reflowerindexpr = NIL, then we are fetching or storing a single array
- * element at the subscripts given by refupperindexpr. Otherwise we are
- * fetching or storing an array slice, that is a rectangular subarray
- * with lower and upper bounds given by the index expressions.
- * reflowerindexpr must be the same length as refupperindexpr when it
- * is not NIL.
+ * In an ordinary subplan, testexpr points to an executable expression
+ * (OpExpr, an AND/OR tree of OpExprs, or RowCompareExpr) for the combining
+ * operator(s); the left-hand arguments are the original lefthand expressions,
+ * and the right-hand arguments are PARAM_EXEC Param nodes representing the
+ * outputs of the sub-select.  (NOTE: runtime coercion functions may be
+ * inserted as well.)  This is just the same expression tree as testexpr in
+ * the original SubLink node, but the PARAM_SUBLINK nodes are replaced by
+ * suitably numbered PARAM_EXEC nodes.
  *
- * Note: array types can be fixed-length (refattrlength > 0), but only
- * when the element type is itself fixed-length.  Otherwise they are
- * varlena structures and have refattrlength = -1.     In any case,
- * an array type is never pass-by-value.
+ * If the sub-select becomes an initplan rather than a subplan, the executable
+ * expression is part of the outer plan's expression tree (and the SubPlan
+ * node itself is not, but rather is found in the outer plan's initPlan
+ * list).  In this case testexpr is NULL to avoid duplication.
  *
- * Note: currently, refelemtype is NOT the element type, but the array type,
- * when doing subarray fetch or either type of store.  It would be cleaner
- * to add more fields so we can distinguish the array element type from the
- * result type of the ArrayRef operator...
- * ----------------
+ * The planner also derives lists of the values that need to be passed into
+ * and out of the subplan.     Input values are represented as a list "args" of
+ * expressions to be evaluated in the outer-query context (currently these
+ * args are always just Vars, but in principle they could be any expression).
+ * The values are assigned to the global PARAM_EXEC params indexed by parParam
+ * (the parParam and args lists must have the same ordering).  setParam is a
+ * list of the PARAM_EXEC params that are computed by the sub-select, if it
+ * is an initplan; they are listed in order by sub-select output column
+ * position.  (parParam and setParam are integer Lists, not Bitmapsets,
+ * because their ordering is significant.)
+ *
+ * Also, the planner computes startup and per-call costs for use of the
+ * SubPlan.  Note that these include the cost of the subquery proper,
+ * evaluation of the testexpr if any, and any hashtable management overhead.
  */
-typedef struct ArrayRef
+typedef struct SubPlan
 {
-       NodeTag         type;
-       int                     refattrlength;  /* typlen of array type */
-       int                     refelemlength;  /* typlen of the array element type */
-       Oid                     refelemtype;    /* type of the result of the ArrayRef
-                                                                * operation */
-       bool            refelembyval;   /* is the element type pass-by-value? */
-       List       *refupperindexpr;/* expressions that evaluate to upper
-                                                                * array indexes */
-       List       *reflowerindexpr;/* expressions that evaluate to lower
-                                                                * array indexes */
-       Node       *refexpr;            /* the expression that evaluates to an
-                                                                * array value */
-       Node       *refassgnexpr;       /* expression for the source value, or
-                                                                * NULL if fetch */
-} ArrayRef;
+       Expr            xpr;
+       /* Fields copied from original SubLink: */
+       SubLinkType subLinkType;        /* see above */
+       /* The combining operators, transformed to an executable expression: */
+       Node       *testexpr;           /* OpExpr or RowCompareExpr expression tree */
+       List       *paramIds;           /* IDs of Params embedded in the above */
+       /* Identification of the Plan tree to use: */
+       int                     plan_id;                /* Index (from 1) in PlannedStmt.subplans */
+       /* Identification of the SubPlan for EXPLAIN and debugging purposes: */
+       char       *plan_name;          /* A name assigned during planning */
+       /* Extra data useful for determining subplan's output type: */
+       Oid                     firstColType;   /* Type of first column of subplan result */
+       int32           firstColTypmod; /* Typmod of first column of subplan result */
+       /* Information about execution strategy: */
+       bool            useHashTable;   /* TRUE to store subselect output in a hash
+                                                                * table (implies we are doing "IN") */
+       bool            unknownEqFalse; /* TRUE if it's okay to return FALSE when the
+                                                                * spec result is UNKNOWN; this allows much
+                                                                * simpler handling of null values */
+       /* Information for passing params into and out of the subselect: */
+       /* setParam and parParam are lists of integers (param IDs) */
+       List       *setParam;           /* initplan subqueries have to set these
+                                                                * Params for parent plan */
+       List       *parParam;           /* indices of input Params from parent plan */
+       List       *args;                       /* exprs to pass as parParam values */
+       /* Estimated execution costs: */
+       Cost            startup_cost;   /* one-time setup cost */
+       Cost            per_call_cost;  /* cost for each subplan evaluation */
+} SubPlan;
+
+/*
+ * AlternativeSubPlan - expression node for a choice among SubPlans
+ *
+ * The subplans are given as a List so that the node definition need not
+ * change if there's ever more than two alternatives.  For the moment,
+ * though, there are always exactly two; and the first one is the fast-start
+ * plan.
+ */
+typedef struct AlternativeSubPlan
+{
+       Expr            xpr;
+       List       *subplans;           /* SubPlan(s) with equivalent results */
+} AlternativeSubPlan;
 
 /* ----------------
  * FieldSelect
  *
  * FieldSelect represents the operation of extracting one field from a tuple
- * value.  At runtime, the input expression is expected to yield a Datum
- * that contains a pointer-to-TupleTableSlot.  The specified field number
- * is extracted and returned as a Datum.
+ * value.  At runtime, the input expression is expected to yield a rowtype
+ * Datum.  The specified field number is extracted and returned as a Datum.
  * ----------------
  */
 
 typedef struct FieldSelect
 {
-       NodeTag         type;
-       Node       *arg;                        /* input expression */
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
        AttrNumber      fieldnum;               /* attribute number of field to extract */
        Oid                     resulttype;             /* type of the field (result type of this
                                                                 * node) */
        int32           resulttypmod;   /* output typmod (usually -1) */
 } FieldSelect;
 
+/* ----------------
+ * FieldStore
+ *
+ * FieldStore represents the operation of modifying one field in a tuple
+ * value, yielding a new tuple value (the input is not touched!).  Like
+ * the assign case of ArrayRef, this is used to implement UPDATE of a
+ * portion of a column.
+ *
+ * A single FieldStore can actually represent updates of several different
+ * fields.     The parser only generates FieldStores with single-element lists,
+ * but the planner will collapse multiple updates of the same base column
+ * into one FieldStore.
+ * ----------------
+ */
+
+typedef struct FieldStore
+{
+       Expr            xpr;
+       Expr       *arg;                        /* input tuple value */
+       List       *newvals;            /* new value(s) for field(s) */
+       List       *fieldnums;          /* integer list of field attnums */
+       Oid                     resulttype;             /* type of result (same as type of arg) */
+       /* Like RowExpr, we deliberately omit a typmod here */
+} FieldStore;
+
 /* ----------------
  * RelabelType
  *
@@ -455,12 +597,487 @@ typedef struct FieldSelect
 
 typedef struct RelabelType
 {
-       NodeTag         type;
-       Node       *arg;                        /* input expression */
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
        Oid                     resulttype;             /* output type of coercion expression */
        int32           resulttypmod;   /* output typmod (usually -1) */
+       CoercionForm relabelformat; /* how to display this node */
+       int                     location;               /* token location, or -1 if unknown */
 } RelabelType;
 
+/* ----------------
+ * CoerceViaIO
+ *
+ * CoerceViaIO represents a type coercion between two types whose textual
+ * representations are compatible, implemented by invoking the source type's
+ * typoutput function then the destination type's typinput function.
+ * ----------------
+ */
+
+typedef struct CoerceViaIO
+{
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
+       Oid                     resulttype;             /* output type of coercion */
+       /* output typmod is not stored, but is presumed -1 */
+       CoercionForm coerceformat;      /* how to display this node */
+       int                     location;               /* token location, or -1 if unknown */
+} CoerceViaIO;
+
+/* ----------------
+ * ArrayCoerceExpr
+ *
+ * ArrayCoerceExpr represents a type coercion from one array type to another,
+ * which is implemented by applying the indicated element-type coercion
+ * function to each element of the source array.  If elemfuncid is InvalidOid
+ * then the element types are binary-compatible, but the coercion still
+ * requires some effort (we have to fix the element type ID stored in the
+ * array header).
+ * ----------------
+ */
+
+typedef struct ArrayCoerceExpr
+{
+       Expr            xpr;
+       Expr       *arg;                        /* input expression (yields an array) */
+       Oid                     elemfuncid;             /* OID of element coercion function, or 0 */
+       Oid                     resulttype;             /* output type of coercion (an array type) */
+       int32           resulttypmod;   /* output typmod (also element typmod) */
+       bool            isExplicit;             /* conversion semantics flag to pass to func */
+       CoercionForm coerceformat;      /* how to display this node */
+       int                     location;               /* token location, or -1 if unknown */
+} ArrayCoerceExpr;
+
+/* ----------------
+ * ConvertRowtypeExpr
+ *
+ * ConvertRowtypeExpr represents a type coercion from one composite type
+ * to another, where the source type is guaranteed to contain all the columns
+ * needed for the destination type plus possibly others; the columns need not
+ * be in the same positions, but are matched up by name.  This is primarily
+ * used to convert a whole-row value of an inheritance child table into a
+ * valid whole-row value of its parent table's rowtype.
+ * ----------------
+ */
+
+typedef struct ConvertRowtypeExpr
+{
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
+       Oid                     resulttype;             /* output type (always a composite type) */
+       /* result typmod is not stored, but must be -1; see RowExpr comments */
+       CoercionForm convertformat; /* how to display this node */
+       int                     location;               /* token location, or -1 if unknown */
+} ConvertRowtypeExpr;
+
+/*----------
+ * CaseExpr - a CASE expression
+ *
+ * We support two distinct forms of CASE expression:
+ *             CASE WHEN boolexpr THEN expr [ WHEN boolexpr THEN expr ... ]
+ *             CASE testexpr WHEN compexpr THEN expr [ WHEN compexpr THEN expr ... ]
+ * These are distinguishable by the "arg" field being NULL in the first case
+ * and the testexpr in the second case.
+ *
+ * In the raw grammar output for the second form, the condition expressions
+ * of the WHEN clauses are just the comparison values. Parse analysis
+ * converts these to valid boolean expressions of the form
+ *             CaseTestExpr '=' compexpr
+ * where the CaseTestExpr node is a placeholder that emits the correct
+ * value at runtime.  This structure is used so that the testexpr need be
+ * evaluated only once.  Note that after parse analysis, the condition
+ * expressions always yield boolean.
+ *
+ * Note: we can test whether a CaseExpr has been through parse analysis
+ * yet by checking whether casetype is InvalidOid or not.
+ *----------
+ */
+typedef struct CaseExpr
+{
+       Expr            xpr;
+       Oid                     casetype;               /* type of expression result */
+       Expr       *arg;                        /* implicit equality comparison argument */
+       List       *args;                       /* the arguments (list of WHEN clauses) */
+       Expr       *defresult;          /* the default result (ELSE clause) */
+       int                     location;               /* token location, or -1 if unknown */
+} CaseExpr;
+
+/*
+ * CaseWhen - one arm of a CASE expression
+ */
+typedef struct CaseWhen
+{
+       Expr            xpr;
+       Expr       *expr;                       /* condition expression */
+       Expr       *result;                     /* substitution result */
+       int                     location;               /* token location, or -1 if unknown */
+} CaseWhen;
+
+/*
+ * Placeholder node for the test value to be processed by a CASE expression.
+ * This is effectively like a Param, but can be implemented more simply
+ * since we need only one replacement value at a time.
+ *
+ * We also use this in nested UPDATE expressions.
+ * See transformAssignmentIndirection().
+ */
+typedef struct CaseTestExpr
+{
+       Expr            xpr;
+       Oid                     typeId;                 /* type for substituted value */
+       int32           typeMod;                /* typemod for substituted value */
+} CaseTestExpr;
+
+/*
+ * ArrayExpr - an ARRAY[] expression
+ *
+ * Note: if multidims is false, the constituent expressions all yield the
+ * scalar type identified by element_typeid.  If multidims is true, the
+ * constituent expressions all yield arrays of element_typeid (ie, the same
+ * type as array_typeid); at runtime we must check for compatible subscripts.
+ */
+typedef struct ArrayExpr
+{
+       Expr            xpr;
+       Oid                     array_typeid;   /* type of expression result */
+       Oid                     element_typeid; /* common type of array elements */
+       List       *elements;           /* the array elements or sub-arrays */
+       bool            multidims;              /* true if elements are sub-arrays */
+       int                     location;               /* token location, or -1 if unknown */
+} ArrayExpr;
+
+/*
+ * RowExpr - a ROW() expression
+ *
+ * Note: the list of fields must have a one-for-one correspondence with
+ * physical fields of the associated rowtype, although it is okay for it
+ * to be shorter than the rowtype.     That is, the N'th list element must
+ * match up with the N'th physical field.  When the N'th physical field
+ * is a dropped column (attisdropped) then the N'th list element can just
+ * be a NULL constant. (This case can only occur for named composite types,
+ * not RECORD types, since those are built from the RowExpr itself rather
+ * than vice versa.)  It is important not to assume that length(args) is
+ * the same as the number of columns logically present in the rowtype.
+ *
+ * colnames is NIL in a RowExpr built from an ordinary ROW() expression.
+ * It is provided in cases where we expand a whole-row Var into a RowExpr,
+ * to retain the column alias names of the RTE that the Var referenced
+ * (which would otherwise be very difficult to extract from the parsetree).
+ * Like the args list, it is one-for-one with physical fields of the rowtype.
+ */
+typedef struct RowExpr
+{
+       Expr            xpr;
+       List       *args;                       /* the fields */
+       Oid                     row_typeid;             /* RECORDOID or a composite type's ID */
+
+       /*
+        * Note: we deliberately do NOT store a typmod.  Although a typmod will be
+        * associated with specific RECORD types at runtime, it will differ for
+        * different backends, and so cannot safely be stored in stored
+        * parsetrees.  We must assume typmod -1 for a RowExpr node.
+        */
+       CoercionForm row_format;        /* how to display this node */
+       List       *colnames;           /* list of String, or NIL */
+       int                     location;               /* token location, or -1 if unknown */
+} RowExpr;
+
+/*
+ * RowCompareExpr - row-wise comparison, such as (a, b) <= (1, 2)
+ *
+ * We support row comparison for any operator that can be determined to
+ * act like =, <>, <, <=, >, or >= (we determine this by looking for the
+ * operator in btree opfamilies).  Note that the same operator name might
+ * map to a different operator for each pair of row elements, since the
+ * element datatypes can vary.
+ *
+ * A RowCompareExpr node is only generated for the < <= > >= cases;
+ * the = and <> cases are translated to simple AND or OR combinations
+ * of the pairwise comparisons.  However, we include = and <> in the
+ * RowCompareType enum for the convenience of parser logic.
+ */
+typedef enum RowCompareType
+{
+       /* Values of this enum are chosen to match btree strategy numbers */
+       ROWCOMPARE_LT = 1,                      /* BTLessStrategyNumber */
+       ROWCOMPARE_LE = 2,                      /* BTLessEqualStrategyNumber */
+       ROWCOMPARE_EQ = 3,                      /* BTEqualStrategyNumber */
+       ROWCOMPARE_GE = 4,                      /* BTGreaterEqualStrategyNumber */
+       ROWCOMPARE_GT = 5,                      /* BTGreaterStrategyNumber */
+       ROWCOMPARE_NE = 6                       /* no such btree strategy */
+} RowCompareType;
+
+typedef struct RowCompareExpr
+{
+       Expr            xpr;
+       RowCompareType rctype;          /* LT LE GE or GT, never EQ or NE */
+       List       *opnos;                      /* OID list of pairwise comparison ops */
+       List       *opfamilies;         /* OID list of containing operator families */
+       List       *largs;                      /* the left-hand input arguments */
+       List       *rargs;                      /* the right-hand input arguments */
+} RowCompareExpr;
+
+/*
+ * CoalesceExpr - a COALESCE expression
+ */
+typedef struct CoalesceExpr
+{
+       Expr            xpr;
+       Oid                     coalescetype;   /* type of expression result */
+       List       *args;                       /* the arguments */
+       int                     location;               /* token location, or -1 if unknown */
+} CoalesceExpr;
+
+/*
+ * MinMaxExpr - a GREATEST or LEAST function
+ */
+typedef enum MinMaxOp
+{
+       IS_GREATEST,
+       IS_LEAST
+} MinMaxOp;
+
+typedef struct MinMaxExpr
+{
+       Expr            xpr;
+       Oid                     minmaxtype;             /* common type of arguments and result */
+       MinMaxOp        op;                             /* function to execute */
+       List       *args;                       /* the arguments */
+       int                     location;               /* token location, or -1 if unknown */
+} MinMaxExpr;
+
+/*
+ * XmlExpr - various SQL/XML functions requiring special grammar productions
+ *
+ * 'name' carries the "NAME foo" argument (already XML-escaped).
+ * 'named_args' and 'arg_names' represent an xml_attribute list.
+ * 'args' carries all other arguments.
+ */
+typedef enum XmlExprOp
+{
+       IS_XMLCONCAT,                           /* XMLCONCAT(args) */
+       IS_XMLELEMENT,                          /* XMLELEMENT(name, xml_attributes, args) */
+       IS_XMLFOREST,                           /* XMLFOREST(xml_attributes) */
+       IS_XMLPARSE,                            /* XMLPARSE(text, is_doc, preserve_ws) */
+       IS_XMLPI,                                       /* XMLPI(name [, args]) */
+       IS_XMLROOT,                                     /* XMLROOT(xml, version, standalone) */
+       IS_XMLSERIALIZE,                        /* XMLSERIALIZE(is_document, xmlval) */
+       IS_DOCUMENT                                     /* xmlval IS DOCUMENT */
+} XmlExprOp;
+
+typedef enum
+{
+       XMLOPTION_DOCUMENT,
+       XMLOPTION_CONTENT
+} XmlOptionType;
+
+typedef struct XmlExpr
+{
+       Expr            xpr;
+       XmlExprOp       op;                             /* xml function ID */
+       char       *name;                       /* name in xml(NAME foo ...) syntaxes */
+       List       *named_args;         /* non-XML expressions for xml_attributes */
+       List       *arg_names;          /* parallel list of Value strings */
+       List       *args;                       /* list of expressions */
+       XmlOptionType xmloption;        /* DOCUMENT or CONTENT */
+       Oid                     type;                   /* target type for XMLSERIALIZE */
+       int32           typmod;
+       int                     location;               /* token location, or -1 if unknown */
+} XmlExpr;
+
+/*
+ * NullIfExpr - a NULLIF expression
+ *
+ * Like DistinctExpr, this is represented the same as an OpExpr referencing
+ * the "=" operator for x and y.
+ */
+typedef OpExpr NullIfExpr;
+
+/* ----------------
+ * NullTest
+ *
+ * NullTest represents the operation of testing a value for NULLness.
+ * The appropriate test is performed and returned as a boolean Datum.
+ *
+ * NOTE: the semantics of this for rowtype inputs are noticeably different
+ * from the scalar case.  It would probably be a good idea to include an
+ * "argisrow" flag in the struct to reflect that, but for the moment,
+ * we do not do so to avoid forcing an initdb during 8.2beta.
+ * ----------------
+ */
+
+typedef enum NullTestType
+{
+       IS_NULL, IS_NOT_NULL
+} NullTestType;
+
+typedef struct NullTest
+{
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
+       NullTestType nulltesttype;      /* IS NULL, IS NOT NULL */
+} NullTest;
+
+/*
+ * BooleanTest
+ *
+ * BooleanTest represents the operation of determining whether a boolean
+ * is TRUE, FALSE, or UNKNOWN (ie, NULL).  All six meaningful combinations
+ * are supported.  Note that a NULL input does *not* cause a NULL result.
+ * The appropriate test is performed and returned as a boolean Datum.
+ */
+
+typedef enum BoolTestType
+{
+       IS_TRUE, IS_NOT_TRUE, IS_FALSE, IS_NOT_FALSE, IS_UNKNOWN, IS_NOT_UNKNOWN
+} BoolTestType;
+
+typedef struct BooleanTest
+{
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
+       BoolTestType booltesttype;      /* test type */
+} BooleanTest;
+
+/*
+ * CoerceToDomain
+ *
+ * CoerceToDomain represents the operation of coercing a value to a domain
+ * type.  At runtime (and not before) the precise set of constraints to be
+ * checked will be determined. If the value passes, it is returned as the
+ * result; if not, an error is raised. Note that this is equivalent to
+ * RelabelType in the scenario where no constraints are applied.
+ */
+typedef struct CoerceToDomain
+{
+       Expr            xpr;
+       Expr       *arg;                        /* input expression */
+       Oid                     resulttype;             /* domain type ID (result type) */
+       int32           resulttypmod;   /* output typmod (currently always -1) */
+       CoercionForm coercionformat;    /* how to display this node */
+       int                     location;               /* token location, or -1 if unknown */
+} CoerceToDomain;
+
+/*
+ * Placeholder node for the value to be processed by a domain's check
+ * constraint. This is effectively like a Param, but can be implemented more
+ * simply since we need only one replacement value at a time.
+ *
+ * Note: the typeId/typeMod will be set from the domain's base type, not
+ * the domain itself.  This is because we shouldn't consider the value to
+ * be a member of the domain if we haven't yet checked its constraints.
+ */
+typedef struct CoerceToDomainValue
+{
+       Expr            xpr;
+       Oid                     typeId;                 /* type for substituted value */
+       int32           typeMod;                /* typemod for substituted value */
+       int                     location;               /* token location, or -1 if unknown */
+} CoerceToDomainValue;
+
+/*
+ * Placeholder node for a DEFAULT marker in an INSERT or UPDATE command.
+ *
+ * This is not an executable expression: it must be replaced by the actual
+ * column default expression during rewriting. But it is convenient to
+ * treat it as an expression node during parsing and rewriting.
+ */
+typedef struct SetToDefault
+{
+       Expr            xpr;
+       Oid                     typeId;                 /* type for substituted value */
+       int32           typeMod;                /* typemod for substituted value */
+       int                     location;               /* token location, or -1 if unknown */
+} SetToDefault;
+
+/*
+ * Node representing [WHERE] CURRENT OF cursor_name
+ *
+ * CURRENT OF is a bit like a Var, in that it carries the rangetable index
+ * of the target relation being constrained; this aids placing the expression
+ * correctly during planning.  We can assume however that its "levelsup" is
+ * always zero, due to the syntactic constraints on where it can appear.
+ *
+ * The referenced cursor can be represented either as a hardwired string
+ * or as a reference to a run-time parameter of type REFCURSOR.  The latter
+ * case is for the convenience of plpgsql.
+ */
+typedef struct CurrentOfExpr
+{
+       Expr            xpr;
+       Index           cvarno;                 /* RT index of target relation */
+       char       *cursor_name;        /* name of referenced cursor, or NULL */
+       int                     cursor_param;   /* refcursor parameter number, or 0 */
+} CurrentOfExpr;
+
+/*--------------------
+ * TargetEntry -
+ *        a target entry (used in query target lists)
+ *
+ * Strictly speaking, a TargetEntry isn't an expression node (since it can't
+ * be evaluated by ExecEvalExpr).  But we treat it as one anyway, since in
+ * very many places it's convenient to process a whole query targetlist as a
+ * single expression tree.
+ *
+ * In a SELECT's targetlist, resno should always be equal to the item's
+ * ordinal position (counting from 1). However, in an INSERT or UPDATE
+ * targetlist, resno represents the attribute number of the destination
+ * column for the item; so there may be missing or out-of-order resnos.
+ * It is even legal to have duplicated resnos; consider
+ *             UPDATE table SET arraycol[1] = ..., arraycol[2] = ..., ...
+ * The two meanings come together in the executor, because the planner
+ * transforms INSERT/UPDATE tlists into a normalized form with exactly
+ * one entry for each column of the destination table. Before that's
+ * happened, however, it is risky to assume that resno == position.
+ * Generally get_tle_by_resno() should be used rather than list_nth()
+ * to fetch tlist entries by resno, and only in SELECT should you assume
+ * that resno is a unique identifier.
+ *
+ * resname is required to represent the correct column name in non-resjunk
+ * entries of top-level SELECT targetlists, since it will be used as the
+ * column title sent to the frontend.  In most other contexts it is only
+ * a debugging aid, and may be wrong or even NULL.     (In particular, it may
+ * be wrong in a tlist from a stored rule, if the referenced column has been
+ * renamed by ALTER TABLE since the rule was made.     Also, the planner tends
+ * to store NULL rather than look up a valid name for tlist entries in
+ * non-toplevel plan nodes.)  In resjunk entries, resname should be either
+ * a specific system-generated name (such as "ctid") or NULL; anything else
+ * risks confusing ExecGetJunkAttribute!
+ *
+ * ressortgroupref is used in the representation of ORDER BY, GROUP BY, and
+ * DISTINCT items.  Targetlist entries with ressortgroupref=0 are not
+ * sort/group items.  If ressortgroupref>0, then this item is an ORDER BY,
+ * GROUP BY, and/or DISTINCT target value.  No two entries in a targetlist
+ * may have the same nonzero ressortgroupref --- but there is no particular
+ * meaning to the nonzero values, except as tags.  (For example, one must
+ * not assume that lower ressortgroupref means a more significant sort key.)
+ * The order of the associated SortGroupClause lists determine the semantics.
+ *
+ * resorigtbl/resorigcol identify the source of the column, if it is a
+ * simple reference to a column of a base table (or view).     If it is not
+ * a simple reference, these fields are zeroes.
+ *
+ * If resjunk is true then the column is a working column (such as a sort key)
+ * that should be removed from the final output of the query.  Resjunk columns
+ * must have resnos that cannot duplicate any regular column's resno.  Also
+ * note that there are places that assume resjunk columns come after non-junk
+ * columns.
+ *--------------------
+ */
+typedef struct TargetEntry
+{
+       Expr            xpr;
+       Expr       *expr;                       /* expression to evaluate */
+       AttrNumber      resno;                  /* attribute number (see notes above) */
+       char       *resname;            /* name of the column (could be NULL) */
+       Index           ressortgroupref;/* nonzero if referenced by a sort/group
+                                                                * clause */
+       Oid                     resorigtbl;             /* OID of column's source table */
+       AttrNumber      resorigcol;             /* column's number in source table */
+       bool            resjunk;                /* set to true to eliminate the attribute from
+                                                                * final target list */
+} TargetEntry;
+
 
 /* ----------------------------------------------------------------
  *                                     node types for join trees
@@ -470,12 +1087,7 @@ typedef struct RelabelType
  * or qualified join.  Also, FromExpr nodes can appear to denote an
  * ordinary cross-product join ("FROM foo, bar, baz WHERE ...").
  * FromExpr is like a JoinExpr of jointype JOIN_INNER, except that it
- * may have any number of child nodes, not just two.  Also, there is an
- * implementation-defined difference: the planner is allowed to join the
- * children of a FromExpr using whatever join order seems good to it.
- * At present, JoinExpr nodes are always joined in exactly the order
- * implied by the jointree structure (except the planner may choose to
- * swap inner and outer members of a join pair).
+ * may have any number of child nodes, not just two.
  *
  * NOTE: the top level of a Query's jointree is always a FromExpr.
  * Even if the jointree contains no rels, there will be a FromExpr.
@@ -527,8 +1139,10 @@ typedef struct RangeTblRef
  * restricts visibility of the tables/columns inside it.
  *
  * During parse analysis, an RTE is created for the Join, and its index
- * is filled into rtindex.  This RTE is present mainly so that Vars can
- * be created that refer to the outputs of the join.
+ * is filled into rtindex.     This RTE is present mainly so that Vars can
+ * be created that refer to the outputs of the join.  The planner sometimes
+ * generates JoinExprs internally; these can have rtindex = 0 if there are
+ * no join alias variables referencing such joins.
  *----------
  */
 typedef struct JoinExpr
@@ -541,7 +1155,7 @@ typedef struct JoinExpr
        List       *using;                      /* USING clause, if any (list of String) */
        Node       *quals;                      /* qualifiers on join, if any */
        Alias      *alias;                      /* user-written alias clause, if any */
-       int                     rtindex;                /* RT index assigned for join */
+       int                     rtindex;                /* RT index assigned for join, or 0 */
 } JoinExpr;
 
 /*----------