* and join trees.
*
*
- * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.128 2007/03/17 00:11:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.148 2009/04/05 19:59:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* 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;
/*
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 */
+ char *tableSpaceName; /* table space to use, or NULL */
} IntoClause;
* 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;
/*
* 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;
/* ----------------
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;
/*
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 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
*
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;
/*
*
* 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 is typically 0.
+ * tree to the executor, but during parsing/planning opfuncid can be 0.
*/
typedef struct OpExpr
{
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;
/*
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;
/*
*
* 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 treats AND and OR as binary
- * and so it only produces two-element lists, but the optimizer will flatten
- * trees of AND and OR nodes to produce longer lists when possible.
+ * 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
{
Expr xpr;
BoolExprType boolop;
List *args; /* arguments to this expression */
+ int location; /* token location, or -1 if unknown */
} BoolExpr;
/*
* ROWCOMPARE_SUBLINK (lefthand) op (SELECT ...)
* EXPR_SUBLINK (SELECT with single targetlist item ...)
* 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
* 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 one or more rows resulting from the subselect.
+ * 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
*
* 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
{
ANY_SUBLINK,
ROWCOMPARE_SUBLINK,
EXPR_SUBLINK,
- ARRAY_SUBLINK
+ ARRAY_SUBLINK,
+ CTE_SUBLINK /* for SubPlans only */
} SubLinkType;
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;
/*
*
* 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). In this case testexpr is NULL to avoid duplication.
+ * node itself is not, but rather is found in the outer plan's initPlan
+ * list). In this case testexpr is NULL to avoid duplication.
*
* 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
* 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 SubPlan
{
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 */
- /* Extra data saved for the convenience of exprType(): */
+ /* 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") */
* 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
*
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
*
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;
/*----------
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;
/*
Expr xpr;
Expr *expr; /* condition expression */
Expr *result; /* substitution result */
+ int location; /* token location, or -1 if unknown */
} CaseWhen;
/*
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;
/*
* 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
{
* 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;
/*
Expr xpr;
Oid coalescetype; /* type of expression result */
List *args; /* the arguments */
+ int location; /* token location, or -1 if unknown */
} CoalesceExpr;
/*
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;
/*
XmlOptionType xmloption; /* DOCUMENT or CONTENT */
Oid type; /* target type for XMLSERIALIZE */
int32 typmod;
+ int location; /* token location, or -1 if unknown */
} XmlExpr;
/*
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;
/*
Expr xpr;
Oid typeId; /* type for substituted value */
int32 typeMod; /* typemod for substituted value */
+ int location; /* token location, or -1 if unknown */
} CoerceToDomainValue;
/*
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)
* a specific system-generated name (such as "ctid") or NULL; anything else
* risks confusing ExecGetJunkAttribute!
*
- * ressortgroupref is used in the 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.
+ * 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
*
* 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.
+ * 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
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;
/*----------