diff options
Diffstat (limited to 'src/include/nodes/primnodes.h')
-rw-r--r-- | src/include/nodes/primnodes.h | 485 |
1 files changed, 316 insertions, 169 deletions
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 11e74a8d92b..ec0ad4235c9 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -10,7 +10,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: primnodes.h,v 1.71 2002/11/30 21:25:06 tgl Exp $ + * $Id: primnodes.h,v 1.72 2002/12/12 15:49:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -67,31 +67,6 @@ typedef struct Resdom * 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 - @@ -140,96 +115,20 @@ typedef struct RangeVar */ /* - * CoercionContext - distinguishes the allowed set of type casts + * Expr - generic superclass for executable-expression nodes * - * NB: ordering of the alternatives is significant; later (larger) values - * allow more casts than earlier ones. + * 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 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 pathkeys */ -} CoercionForm; - -/* - * Expr - * - * Note: DISTINCT_EXPR implements the "x IS DISTINCT FROM y" construct. - * This is similar to an OP_EXPR, except for its handling of NULL inputs. - * The oper field is always an Oper node for 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.) - */ -typedef enum OpType -{ - OP_EXPR, DISTINCT_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 (or DISTINCT_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 */ - CoercionForm funcformat; /* how to display this function call */ - 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 @@ -248,7 +147,7 @@ typedef struct Func typedef struct Var { - NodeTag type; + Expr xpr; Index varno; /* index of this var's relation in the * range table (could also be INNER or * OUTER) */ @@ -272,7 +171,7 @@ typedef struct Var */ typedef struct Const { - NodeTag type; + Expr xpr; Oid consttype; /* PG_TYPE OID of the constant's datatype */ int constlen; /* typlen of the constant's datatype */ Datum constvalue; /* the constant's value */ @@ -300,12 +199,11 @@ typedef struct Const * * PARAM_EXEC: The parameter is an internal executor parameter. * It has a number contained in the `paramid' field. - * * ---------------- */ typedef struct Param { - NodeTag type; + Expr xpr; int paramkind; /* kind of parameter. See above */ AttrNumber paramid; /* numeric ID for parameter ("$1") */ char *paramname; /* name for parameter ("$.foo") */ @@ -317,16 +215,157 @@ 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 */ + Expr *target; /* expression we are aggregating on */ bool aggstar; /* TRUE if argument was really '*' */ bool aggdistinct; /* TRUE if it's agg(DISTINCT ...) */ + + /* XXX this should move to AggrefExprState: */ int aggno; /* workspace for executor (see nodeAgg.c) */ } Aggref; /* ---------------- + * 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: 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. + * + * Note: refrestype is NOT the element type, but the array type, + * when doing subarray fetch or either type of store. It might be a good + * idea to include a refelemtype field as well. + * ---------------- + */ +typedef struct ArrayRef +{ + Expr xpr; + Oid refrestype; /* type of the result of the ArrayRef + * operation */ + int refattrlength; /* typlen of array type */ + int refelemlength; /* typlen of the array element type */ + bool refelembyval; /* is the element type pass-by-value? */ + char refelemalign; /* typalign of the element type */ + 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 pathkeys */ +} 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 */ + + FunctionCachePtr func_fcache; /* XXX runtime state, or NULL */ +} 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 is typically 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) */ + + FunctionCachePtr op_fcache; /* XXX runtime state, else NULL */ +} 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; + +/* + * 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 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. + */ +typedef enum BoolExprType +{ + AND_EXPR, OR_EXPR, NOT_EXPR +} BoolExprType; + +typedef struct BoolExpr +{ + Expr xpr; + BoolExprType boolop; + List *args; /* arguments to this expression */ +} BoolExpr; + +/* ---------------- * SubLink * * A SubLink represents a subselect appearing in an expression, and in some @@ -348,19 +387,23 @@ typedef struct Aggref * depending on the "useor" flag. ALL and ANY combine the per-row results * using AND and OR semantics respectively. * + * SubLink is classed as an Expr node, but it is not actually executable; + * it must be replaced in the expression tree by a SubPlanExpr node during + * planning. + * * 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 + * and replaces oper with a list of OpExpr 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 + * expressions. However, we have not constructed complete Expr trees for + * these operations yet: the args fields of the OpExpr nodes are NIL. + * 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 OpExpr * 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 nodes. @@ -370,7 +413,7 @@ typedef struct Aggref * 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. + * found in SubLinks that are children of SubPlanExpr 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. @@ -384,62 +427,45 @@ typedef enum SubLinkType typedef struct SubLink { - NodeTag type; + Expr xpr; 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 */ + List *oper; /* list of OpExpr nodes for combining + * operators, or final list of executable + * expressions */ Node *subselect; /* subselect as Query* or parsetree */ } SubLink; -/* ---------------- - * 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: 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. +/* + * SubPlanExpr - executable expression node for a subplan (sub-SELECT) * - * Note: refrestype is NOT the element type, but the array type, - * when doing subarray fetch or either type of store. It might be a good - * idea to include a refelemtype field as well. - * ---------------- + * The planner replaces SubLink nodes in expression trees with SubPlanExpr + * nodes after it has finished planning the subquery. See notes above. */ -typedef struct ArrayRef +typedef struct SubPlanExpr { - NodeTag type; - Oid refrestype; /* type of the result of the ArrayRef - * operation */ - int refattrlength; /* typlen of array type */ - int refelemlength; /* typlen of the array element type */ - bool refelembyval; /* is the element type pass-by-value? */ - char refelemalign; /* typalign of the element type */ - 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; + Oid typeOid; /* PG_TYPE OID of the expression result */ + struct 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 input Params from parent plan */ + List *args; /* exprs to pass as parParam values */ + SubLink *sublink; /* SubLink node from parser; holds info + * about what to do with subselect's + * results */ + + struct SubPlanState *pstate; /* XXX TEMPORARY HACK */ +} SubPlanExpr; /* ---------------- * FieldSelect @@ -453,8 +479,8 @@ typedef struct ArrayRef 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) */ @@ -476,13 +502,134 @@ 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 */ } RelabelType; +/* + * CaseExpr - a CASE expression + */ +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) */ +} CaseExpr; + +/* + * CaseWhen - an argument to a CASE expression + */ +typedef struct CaseWhen +{ + Expr xpr; + Expr *expr; /* condition expression */ + Expr *result; /* substitution result */ +} CaseWhen; + +/* ---------------- + * NullTest + * + * NullTest represents the operation of testing a value for NULLness. + * Currently, we only support scalar input values, but eventually a + * row-constructor input should be supported. + * The appropriate test is performed and returned as a boolean Datum. + * ---------------- + */ + +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; + +/* + * ConstraintTest + * + * ConstraintTest represents the operation of testing a value to see whether + * it meets a constraint. If so, the input value is returned as the result; + * if not, an error is raised. + */ + +typedef enum ConstraintTestType +{ + CONSTR_TEST_NOTNULL, + CONSTR_TEST_CHECK +} ConstraintTestType; + +typedef struct ConstraintTest +{ + Expr xpr; + Expr *arg; /* input expression */ + ConstraintTestType testtype; /* test type */ + char *name; /* name of constraint (for error msgs) */ + char *domname; /* name of domain (for error messages) */ + Expr *check_expr; /* for CHECK test, a boolean expression */ +} ConstraintTest; + +/* + * Placeholder node for the value to be processed by a domains + * check constraint. This is effectively like a Param; could we use + * a Param node instead? + */ +typedef struct ConstraintTestValue +{ + Expr xpr; + Oid typeId; + int32 typeMod; +} ConstraintTestValue; + + +/* + * 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. + * + * The separation between TargetEntry and Resdom is historical. One of these + * days, Resdom should probably get folded into TargetEntry. + */ +typedef struct TargetEntry +{ + Expr xpr; + Resdom *resdom; /* descriptor for targetlist item */ + Expr *expr; /* expression to evaluate */ +} TargetEntry; + /* ---------------------------------------------------------------- * node types for join trees |