diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-12-12 15:49:42 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-12-12 15:49:42 +0000 |
commit | a0bf885f9eaccadd23b766ecbc064f17f06ae883 (patch) | |
tree | 62b65e5cf1a8ec02ece3a98c15457ddff018bb94 /src/include | |
parent | debb072886efcb15e7f0825e35b168afe316d37d (diff) | |
download | postgresql-a0bf885f9eaccadd23b766ecbc064f17f06ae883.tar.gz postgresql-a0bf885f9eaccadd23b766ecbc064f17f06ae883.zip |
Phase 2 of read-only-plans project: restructure expression-tree nodes
so that all executable expression nodes inherit from a common supertype
Expr. This is somewhat of an exercise in code purity rather than any
real functional advance, but getting rid of the extra Oper or Func node
formerly used in each operator or function call should provide at least
a little space and speed improvement.
initdb forced by changes in stored-rules representation.
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/catalog/catversion.h | 4 | ||||
-rw-r--r-- | src/include/executor/nodeSubplan.h | 4 | ||||
-rw-r--r-- | src/include/nodes/makefuncs.h | 13 | ||||
-rw-r--r-- | src/include/nodes/nodeFuncs.h | 4 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 37 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 201 | ||||
-rw-r--r-- | src/include/nodes/plannodes.h | 29 | ||||
-rw-r--r-- | src/include/nodes/primnodes.h | 485 | ||||
-rw-r--r-- | src/include/nodes/relation.h | 4 | ||||
-rw-r--r-- | src/include/optimizer/clauses.h | 29 | ||||
-rw-r--r-- | src/include/optimizer/paths.h | 4 | ||||
-rw-r--r-- | src/include/optimizer/planmain.h | 4 |
12 files changed, 412 insertions, 406 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 8cb41a9290b..fa313187330 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.168 2002/12/06 05:20:24 momjian Exp $ + * $Id: catversion.h,v 1.169 2002/12/12 15:49:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200212061 +#define CATALOG_VERSION_NO 200212101 #endif diff --git a/src/include/executor/nodeSubplan.h b/src/include/executor/nodeSubplan.h index c573cf900df..e025c9de696 100644 --- a/src/include/executor/nodeSubplan.h +++ b/src/include/executor/nodeSubplan.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: nodeSubplan.h,v 1.12 2002/12/05 15:50:38 tgl Exp $ + * $Id: nodeSubplan.h,v 1.13 2002/12/12 15:49:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,7 +16,7 @@ #include "nodes/execnodes.h" -extern SubPlanState *ExecInitSubPlan(SubPlan *node, EState *estate); +extern SubPlanState *ExecInitSubPlan(SubPlanExpr *node, EState *estate); extern Datum ExecSubPlan(SubPlanState *node, List *pvar, ExprContext *econtext, bool *isNull); extern void ExecEndSubPlan(SubPlanState *node); diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h index 68f0dcda49a..d1f4ebfc400 100644 --- a/src/include/nodes/makefuncs.h +++ b/src/include/nodes/makefuncs.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: makefuncs.h,v 1.42 2002/11/25 21:29:42 tgl Exp $ + * $Id: makefuncs.h,v 1.43 2002/12/12 15:49:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -22,18 +22,13 @@ extern A_Expr *makeA_Expr(int oper, List *name, Node *lexpr, Node *rexpr); extern A_Expr *makeSimpleA_Expr(int oper, const char *name, Node *lexpr, Node *rexpr); -extern Oper *makeOper(Oid opno, - Oid opid, - Oid opresulttype, - bool opretset); - extern Var *makeVar(Index varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Index varlevelsup); -extern TargetEntry *makeTargetEntry(Resdom *resdom, Node *expr); +extern TargetEntry *makeTargetEntry(Resdom *resdom, Expr *expr); extern Resdom *makeResdom(AttrNumber resno, Oid restype, @@ -49,9 +44,11 @@ extern Const *makeConst(Oid consttype, extern Const *makeNullConst(Oid consttype); +extern Expr *makeBoolExpr(BoolExprType boolop, List *args); + extern Alias *makeAlias(const char *aliasname, List *colnames); -extern RelabelType *makeRelabelType(Node *arg, Oid rtype, int32 rtypmod, +extern RelabelType *makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, CoercionForm rformat); extern RangeVar *makeRangeVar(char *schemaname, char *relname); diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h index 7db0525bad8..99e1a62542c 100644 --- a/src/include/nodes/nodeFuncs.h +++ b/src/include/nodes/nodeFuncs.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: nodeFuncs.h,v 1.17 2002/06/20 20:29:51 momjian Exp $ + * $Id: nodeFuncs.h,v 1.18 2002/12/12 15:49:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,6 +19,6 @@ extern bool single_node(Node *node); extern bool var_is_outer(Var *var); extern bool var_is_rel(Var *var); -extern Oper *replace_opid(Oper *oper); +extern void set_opfuncid(OpExpr *opexpr); #endif /* NODEFUNCS_H */ diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 2f3e71407aa..aacdf60dd9a 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: nodes.h,v 1.129 2002/12/06 05:00:31 momjian Exp $ + * $Id: nodes.h,v 1.130 2002/12/12 15:49:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -62,7 +62,6 @@ typedef enum NodeTag T_Hash, T_SetOp, T_Limit, - T_SubPlan, /* * TAGS FOR PLAN STATE NODES (execnodes.h) @@ -96,21 +95,32 @@ typedef enum NodeTag * TAGS FOR PRIMITIVE NODES (primnodes.h) */ T_Resdom = 300, - T_Fjoin, + T_Alias, + T_RangeVar, T_Expr, T_Var, - T_Oper, T_Const, T_Param, T_Aggref, + T_ArrayRef, + T_FuncExpr, + T_OpExpr, + T_DistinctExpr, + T_BoolExpr, T_SubLink, - T_Func, + T_SubPlanExpr, T_FieldSelect, - T_ArrayRef, T_RelabelType, + T_CaseExpr, + T_CaseWhen, + T_NullTest, + T_BooleanTest, + T_ConstraintTest, + T_ConstraintTestValue, + T_TargetEntry, T_RangeTblRef, - T_FromExpr, T_JoinExpr, + T_FromExpr, /* * TAGS FOR PLANNER NODES (relation.h) @@ -183,7 +193,6 @@ typedef enum NodeTag T_ViewStmt, T_LoadStmt, T_CreateDomainStmt, - T_DomainConstraintValue, T_CreatedbStmt, T_DropdbStmt, T_VacuumStmt, @@ -228,30 +237,22 @@ typedef enum NodeTag T_ResTarget, T_TypeCast, T_SortGroupBy, - T_Alias, - T_RangeVar, T_RangeSubselect, T_RangeFunction, T_TypeName, - T_IndexElem, T_ColumnDef, + T_IndexElem, T_Constraint, T_DefElem, - T_TargetEntry, T_RangeTblEntry, T_SortClause, T_GroupClause, - T_NullTest, - T_BooleanTest, - T_ConstraintTest, - T_ConstraintTestValue, - T_CaseExpr, - T_CaseWhen, T_FkConstraint, T_PrivGrantee, T_FuncWithArgs, T_PrivTarget, T_InsertDefault, + T_DomainConstraintValue, T_CreateOpClassItem, T_CompositeTypeStmt, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 5201e1bb0e7..f2d92431b71 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.221 2002/12/06 05:00:32 momjian Exp $ + * $Id: parsenodes.h,v 1.222 2002/12/12 15:49:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -34,7 +34,7 @@ typedef enum QuerySource /* * Query - - * all statments are turned into a Query tree (via transformStmt) + * all statements are turned into a Query tree (via transformStmt) * for further processing by the optimizer * utility statements (i.e. non-optimizable statements) * have the *utilityStmt field set. @@ -202,145 +202,6 @@ typedef struct TypeCast } TypeCast; /* - * CaseExpr - a CASE expression - */ -typedef struct CaseExpr -{ - NodeTag type; - Oid casetype; - Node *arg; /* implicit equality comparison argument */ - List *args; /* the arguments (list of WHEN clauses) */ - Node *defresult; /* the default result (ELSE clause) */ -} CaseExpr; - -/* - * CaseWhen - an argument to a CASE expression - */ -typedef struct CaseWhen -{ - NodeTag type; - Node *expr; /* comparison expression */ - Node *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 -{ - NodeTag type; - Node *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 -{ - NodeTag type; - Node *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 -{ - NodeTag type; - Node *arg; /* input expression */ - ConstraintTestType testtype; /* test type */ - char *name; /* name of constraint (for error msgs) */ - char *domname; /* name of domain (for error messages) */ - Node *check_expr; /* for CHECK test, a boolean expression */ -} ConstraintTest; - -/* - * Placeholder node for the value to be processed by a domains - * check constraint. - */ -typedef struct DomainConstraintValue -{ - NodeTag type; -} DomainConstraintValue; - -typedef struct ConstraintTestValue -{ - NodeTag type; - Oid typeId; - int32 typeMod; -} ConstraintTestValue; - -/* - * ColumnDef - column definition (used in various creates) - * - * If the column has a default value, we may have the value expression - * in either "raw" form (an untransformed parse tree) or "cooked" form - * (the nodeToString representation of an executable expression tree), - * depending on how this ColumnDef node was created (by parsing, or by - * inheritance from an existing relation). We should never have both - * in the same node! - * - * The constraints list may contain a CONSTR_DEFAULT item in a raw - * parsetree produced by gram.y, but transformCreateStmt will remove - * the item and set raw_default instead. CONSTR_DEFAULT items - * should not appear in any subsequent processing. - * - * The "support" field, if not null, denotes a supporting relation that - * should be linked by an internal dependency to the column. Currently - * this is only used to link a SERIAL column's sequence to the column. - */ -typedef struct ColumnDef -{ - NodeTag type; - char *colname; /* name of column */ - TypeName *typename; /* type of column */ - int inhcount; /* number of times column is inherited */ - bool is_local; /* column has local (non-inherited) def'n */ - bool is_not_null; /* NOT NULL constraint specified? */ - Node *raw_default; /* default value (untransformed parse - * tree) */ - char *cooked_default; /* nodeToString representation */ - List *constraints; /* other constraints on column */ - RangeVar *support; /* supporting relation, if any */ -} ColumnDef; - -/* * FuncCall - a function or aggregate invocation * * agg_star indicates we saw a 'foo(*)' construct, while agg_distinct @@ -415,6 +276,15 @@ typedef struct InsertDefault } InsertDefault; /* + * Empty node used as raw-parse-tree representation of VALUE keyword + * for domain check constraints. + */ +typedef struct DomainConstraintValue +{ + NodeTag type; +} DomainConstraintValue; + +/* * SortGroupBy - for ORDER BY clause */ typedef struct SortGroupBy @@ -447,6 +317,40 @@ typedef struct RangeFunction } RangeFunction; /* + * ColumnDef - column definition (used in various creates) + * + * If the column has a default value, we may have the value expression + * in either "raw" form (an untransformed parse tree) or "cooked" form + * (the nodeToString representation of an executable expression tree), + * depending on how this ColumnDef node was created (by parsing, or by + * inheritance from an existing relation). We should never have both + * in the same node! + * + * The constraints list may contain a CONSTR_DEFAULT item in a raw + * parsetree produced by gram.y, but transformCreateStmt will remove + * the item and set raw_default instead. CONSTR_DEFAULT items + * should not appear in any subsequent processing. + * + * The "support" field, if not null, denotes a supporting relation that + * should be linked by an internal dependency to the column. Currently + * this is only used to link a SERIAL column's sequence to the column. + */ +typedef struct ColumnDef +{ + NodeTag type; + char *colname; /* name of column */ + TypeName *typename; /* type of column */ + int inhcount; /* number of times column is inherited */ + bool is_local; /* column has local (non-inherited) def'n */ + bool is_not_null; /* NOT NULL constraint specified? */ + Node *raw_default; /* default value (untransformed parse + * tree) */ + char *cooked_default; /* nodeToString representation */ + List *constraints; /* other constraints on column */ + RangeVar *support; /* supporting relation, if any */ +} ColumnDef; + +/* * IndexElem - index parameters (used in CREATE INDEX) * * For a plain index, each 'name' is an attribute name in the heap relation; @@ -479,21 +383,6 @@ typedef struct DefElem * Nodes for a Query tree ****************************************************************************/ -/* - * TargetEntry - - * a target entry (used in the transformed target list) - * - * one of resdom or fjoin is not NULL. a target list is - * ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...) - */ -typedef struct TargetEntry -{ - NodeTag type; - Resdom *resdom; /* fjoin overload this to be a list?? */ - Fjoin *fjoin; - Node *expr; -} TargetEntry; - /*-------------------- * RangeTblEntry - * A range table is a List of RangeTblEntry nodes. diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 097f8d93b13..67a4d48782f 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: plannodes.h,v 1.62 2002/12/05 15:50:39 tgl Exp $ + * $Id: plannodes.h,v 1.63 2002/12/12 15:49:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -375,31 +375,4 @@ typedef struct Limit Node *limitCount; /* COUNT parameter, or NULL if none */ } Limit; -/* --------------------- - * SubPlan node - * - * XXX Perhaps does not belong in this file? It's not really a Plan node. - * Should we make it inherit from Plan anyway? - * --------------------- - */ -typedef struct SubPlan -{ - NodeTag type; - Plan *plan; /* subselect plan itself */ - int plan_id; /* dummy thing because of we haven't equal - * funcs for plan nodes... actually, we - * could put *plan itself somewhere else - * (TopPlan node ?)... */ - List *rtable; /* range table for subselect */ - /* setParam and parParam are lists of integers (param IDs) */ - List *setParam; /* non-correlated EXPR & EXISTS subqueries - * have to set some Params for paren Plan */ - List *parParam; /* indices of corr. Vars from parent plan */ - SubLink *sublink; /* SubLink node from parser; holds info - * about what to do with subselect's - * results */ - - struct SubPlanState *pstate; /* XXX TEMPORARY HACK */ -} SubPlan; - #endif /* PLANNODES_H */ 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 diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 333ca0b695b..6da47683e6e 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: relation.h,v 1.73 2002/12/05 15:50:39 tgl Exp $ + * $Id: relation.h,v 1.74 2002/12/12 15:49:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -295,7 +295,7 @@ typedef struct PathKeyItem /* * key typically points to a Var node, ie a relation attribute, but it - * can also point to a Func clause representing the value indexed by a + * can also point to a FuncExpr clause representing the value indexed by a * functional index. Someday we might allow arbitrary expressions as * path keys, so don't assume more than you must. */ diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h index da0fe4c5102..8da7a8688ef 100644 --- a/src/include/optimizer/clauses.h +++ b/src/include/optimizer/clauses.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: clauses.h,v 1.56 2002/12/01 21:05:14 tgl Exp $ + * $Id: clauses.h,v 1.57 2002/12/12 15:49:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,23 +16,28 @@ #include "nodes/relation.h" -extern Expr *make_clause(int type, Node *oper, List *args); -extern bool is_opclause(Node *clause); -extern Expr *make_opclause(Oper *op, Var *leftop, Var *rightop); + +#define is_opclause(clause) ((clause) != NULL && IsA(clause, OpExpr)) +#define is_funcclause(clause) ((clause) != NULL && IsA(clause, FuncExpr)) +#define is_subplan(clause) ((clause) != NULL && IsA(clause, SubPlanExpr)) + + +extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset, + Expr *leftop, Expr *rightop); extern Var *get_leftop(Expr *clause); extern Var *get_rightop(Expr *clause); -extern bool is_funcclause(Node *clause); -extern Expr *make_funcclause(Func *func, List *funcargs); - -extern bool or_clause(Node *clause); -extern Expr *make_orclause(List *orclauses); +extern Expr *make_funcclause(Oid funcid, Oid funcresulttype, bool funcretset, + CoercionForm funcformat, List *funcargs); extern bool not_clause(Node *clause); extern Expr *make_notclause(Expr *notclause); extern Expr *get_notclausearg(Expr *notclause); +extern bool or_clause(Node *clause); +extern Expr *make_orclause(List *orclauses); + extern bool and_clause(Node *clause); extern Expr *make_andclause(List *andclauses); extern Node *make_and_qual(Node *qual1, Node *qual2); @@ -60,7 +65,7 @@ extern bool has_distinct_on_clause(Query *query); extern void clause_get_relids_vars(Node *clause, Relids *relids, List **vars); extern int NumRelids(Node *clause); -extern void CommuteClause(Expr *clause); +extern void CommuteClause(OpExpr *clause); extern Node *eval_const_expressions(Node *node); @@ -78,8 +83,4 @@ extern bool query_tree_walker(Query *query, bool (*walker) (), extern void query_tree_mutator(Query *query, Node *(*mutator) (), void *context, int flags); -#define is_subplan(clause) ((clause) != NULL && \ - IsA(clause, Expr) && \ - ((Expr *) (clause))->opType == SUBPLAN_EXPR) - #endif /* CLAUSES_H */ diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index b03ce0453e6..06f585f7220 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: paths.h,v 1.61 2002/11/24 21:52:15 tgl Exp $ + * $Id: paths.h,v 1.62 2002/12/12 15:49:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -42,8 +42,6 @@ extern void debug_print_rel(Query *root, RelOptInfo *rel); extern void create_index_paths(Query *root, RelOptInfo *rel); extern Path *best_inner_indexscan(Query *root, RelOptInfo *rel, Relids outer_relids, JoinType jointype); -extern Oid indexable_operator(Expr *clause, Oid opclass, - bool indexkey_on_left); extern List *extract_or_indexqual_conditions(RelOptInfo *rel, IndexOptInfo *index, Expr *orsubclause); diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h index ecd7bca6042..134adad9b60 100644 --- a/src/include/optimizer/planmain.h +++ b/src/include/optimizer/planmain.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: planmain.h,v 1.63 2002/11/21 00:42:19 tgl Exp $ + * $Id: planmain.h,v 1.64 2002/12/12 15:49:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -68,6 +68,6 @@ extern void set_plan_references(Plan *plan, List *rtable); extern List *join_references(List *clauses, List *rtable, List *outer_tlist, List *inner_tlist, Index acceptable_rel); -extern void fix_opids(Node *node); +extern void fix_opfuncids(Node *node); #endif /* PLANMAIN_H */ |