diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/trigger.c | 11 | ||||
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 6 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 4 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 36 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 1147 |
5 files changed, 586 insertions, 618 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 61a4eacbacc..e25b83b4556 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.104 2002/03/06 06:09:36 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.105 2002/03/08 04:37:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1781,6 +1781,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) foreach(l, stmt->constraints) { + char *cname = strVal(lfirst(l)); ScanKeyData skey; SysScanDesc tgscan; HeapTuple htup; @@ -1788,7 +1789,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) /* * Check that only named constraints are set explicitly */ - if (strcmp((char *) lfirst(l), "") == 0) + if (strlen(cname) == 0) elog(ERROR, "unnamed constraints cannot be set explicitly"); /* @@ -1798,7 +1799,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) (bits16) 0x0, (AttrNumber) Anum_pg_trigger_tgconstrname, (RegProcedure) F_NAMEEQ, - PointerGetDatum((char *) lfirst(l))); + PointerGetDatum(cname)); tgscan = systable_beginscan(tgrel, TriggerConstrNameIndex, true, SnapshotNow, 1, &skey); @@ -1822,7 +1823,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD && pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL) elog(ERROR, "Constraint '%s' is not deferrable", - (char *) lfirst(l)); + cname); constr_oid = htup->t_data->t_oid; loid = lappendi(loid, constr_oid); @@ -1835,7 +1836,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) * Not found ? */ if (!found) - elog(ERROR, "Constraint '%s' does not exist", (char *) lfirst(l)); + elog(ERROR, "Constraint '%s' does not exist", cname); } heap_close(tgrel, AccessShareLock); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 234fd95ba26..ae9ac430456 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.167 2002/03/07 16:35:34 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.168 2002/03/08 04:37:16 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1898,7 +1898,7 @@ _copyGrantStmt(GrantStmt *from) newnode->is_grant = from->is_grant; newnode->objtype = from->objtype; Node_Copy(from, newnode, objects); - Node_Copy(from, newnode, privileges); + newnode->privileges = listCopy(from->privileges); Node_Copy(from, newnode, grantees); return newnode; @@ -1924,8 +1924,6 @@ _copyFuncWithArgs(FuncWithArgs *from) if (from->funcname) newnode->funcname = pstrdup(from->funcname); - else - newnode->funcname = NULL; Node_Copy(from, newnode, funcargs); return newnode; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 03ce9510ad7..b9269c5a834 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.115 2002/03/07 16:35:34 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.116 2002/03/08 04:37:16 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -763,7 +763,7 @@ _equalGrantStmt(GrantStmt *a, GrantStmt *b) return false; if (!equal(a->objects, b->objects)) return false; - if (!equal(a->privileges, b->privileges)) + if (!equali(a->privileges, b->privileges)) return false; if (!equal(a->grantees, b->grantees)) return false; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 2b1edd266ee..c166a744592 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.287 2002/03/07 16:35:35 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.288 2002/03/08 04:37:17 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -286,7 +286,6 @@ static void doNegateFloat(Value *v); ConstraintTimeSpec %type <list> constraints_set_list -%type <list> constraints_set_namelist %type <boolean> constraints_set_mode /* @@ -1034,37 +1033,12 @@ ConstraintsSetStmt: SET CONSTRAINTS constraints_set_list constraints_set_mode } ; - -constraints_set_list: ALL - { - $$ = NIL; - } - | constraints_set_namelist - { - $$ = $1; - } +constraints_set_list: ALL { $$ = NIL; } + | name_list { $$ = $1; } ; - -constraints_set_namelist: ColId - { - $$ = makeList1($1); - } - | constraints_set_namelist ',' ColId - { - $$ = lappend($1, $3); - } - ; - - -constraints_set_mode: DEFERRED - { - $$ = TRUE; - } - | IMMEDIATE - { - $$ = FALSE; - } +constraints_set_mode: DEFERRED { $$ = TRUE; } + | IMMEDIATE { $$ = FALSE; } ; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index c154913c2ba..996c2b9c738 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.158 2002/03/07 16:35:40 momjian Exp $ + * $Id: parsenodes.h,v 1.159 2002/03/08 04:37:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,6 +16,15 @@ #include "nodes/primnodes.h" + +typedef enum InhOption +{ + INH_NO, /* Do NOT scan child tables */ + INH_YES, /* DO scan child tables */ + INH_DEFAULT /* Use current SQL_inheritance option */ +} InhOption; + + /***************************************************************************** * Query Tree *****************************************************************************/ @@ -93,12 +102,563 @@ typedef struct Query } Query; -typedef enum InhOption +/**************************************************************************** + * Supporting data structures for Parse Trees + * + * Most of these node types appear in raw parsetrees output by the grammar, + * and get transformed to something else by the analyzer. A few of them + * are used as-is in transformed querytrees. + ****************************************************************************/ + +/* + * TypeName - specifies a type in definitions + */ +typedef struct TypeName { - INH_NO, /* Do NOT scan child tables */ - INH_YES, /* DO scan child tables */ - INH_DEFAULT /* Use current SQL_inheritance option */ -} InhOption; + NodeTag type; + char *name; /* name of the type */ + bool timezone; /* timezone specified? */ + bool setof; /* is a set? */ + int32 typmod; /* type modifier */ + List *arrayBounds; /* array bounds */ + char *attrname; /* field name when using %TYPE */ +} TypeName; + +/* + * ParamNo - specifies a parameter reference + */ +typedef struct ParamNo +{ + NodeTag type; + int number; /* the number of the parameter */ + TypeName *typename; /* the typecast */ + List *indirection; /* array references */ +} ParamNo; + +/* + * A_Expr - binary expressions + */ +typedef struct A_Expr +{ + NodeTag type; + int oper; /* type of operation (OP,OR,AND,NOT) */ + char *opname; /* name of operator */ + Node *lexpr; /* left argument */ + Node *rexpr; /* right argument */ +} A_Expr; + +/* + * Attr - + * specifies an Attribute (ie. a Column); could have nested dots or + * array references. + * + */ +typedef struct Attr +{ + NodeTag type; + char *relname; /* name of relation (can be "*") */ + ParamNo *paramNo; /* or a parameter */ + List *attrs; /* attributes (possibly nested); list of + * Values (strings) */ + List *indirection; /* array refs (list of A_Indices') */ +} Attr; + +/* + * A_Const - a constant expression + */ +typedef struct A_Const +{ + NodeTag type; + Value val; /* the value (with the tag) */ + TypeName *typename; /* typecast */ +} A_Const; + +/* + * TypeCast - a CAST expression + * + * NOTE: for mostly historical reasons, A_Const and ParamNo parsenodes contain + * room for a TypeName; we only generate a separate TypeCast node if the + * argument to be casted is neither of those kinds of nodes. In theory either + * representation would work, but it is convenient (especially for A_Const) + * to have the target type immediately available. + */ +typedef struct TypeCast +{ + NodeTag type; + Node *arg; /* the expression being casted */ + TypeName *typename; /* the target type */ +} 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; + +/* + * 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. + */ +typedef struct ColumnDef +{ + NodeTag type; + char *colname; /* name of column */ + TypeName *typename; /* type of column */ + 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 */ +} ColumnDef; + +/* + * Ident - + * an identifier (could be an attribute or a relation name). Depending + * on the context at transformStmt time, the identifier is treated as + * either a relation name (in which case, isRel will be set) or an + * attribute (in which case, it will be transformed into an Attr). + */ +typedef struct Ident +{ + NodeTag type; + char *name; /* its name */ + List *indirection; /* array references */ + bool isRel; /* is this a relation or a column? */ +} Ident; + +/* + * FuncCall - a function or aggregate invocation + * + * agg_star indicates we saw a 'foo(*)' construct, while agg_distinct + * indicates we saw 'foo(DISTINCT ...)'. In either case, the construct + * *must* be an aggregate call. Otherwise, it might be either an + * aggregate or some other kind of function. + */ +typedef struct FuncCall +{ + NodeTag type; + char *funcname; /* name of function */ + List *args; /* the arguments (list of exprs) */ + bool agg_star; /* argument was really '*' */ + bool agg_distinct; /* arguments were labeled DISTINCT */ +} FuncCall; + +/* + * A_Indices - array reference or bounds ([lidx:uidx] or [uidx]) + */ +typedef struct A_Indices +{ + NodeTag type; + Node *lidx; /* could be NULL */ + Node *uidx; +} A_Indices; + +/* + * ResTarget - + * result target (used in target list of pre-transformed Parse trees) + * + * In a SELECT or INSERT target list, 'name' is either NULL or + * the column name assigned to the value. (If there is an 'AS ColumnLabel' + * clause, the grammar sets 'name' from it; otherwise 'name' is initially NULL + * and is filled in during the parse analysis phase.) + * The 'indirection' field is not used at all. + * + * In an UPDATE target list, 'name' is the name of the destination column, + * and 'indirection' stores any subscripts attached to the destination. + * That is, our representation is UPDATE table SET name [indirection] = val. + */ +typedef struct ResTarget +{ + NodeTag type; + char *name; /* column name or NULL */ + List *indirection; /* subscripts for destination column, or + * NIL */ + Node *val; /* the value expression to compute or + * assign */ +} ResTarget; + +/* + * SortGroupBy - for ORDER BY clause + */ +typedef struct SortGroupBy +{ + NodeTag type; + char *useOp; /* operator to use */ + Node *node; /* Expression */ +} SortGroupBy; + +/* + * RangeVar - range variable, used in FROM clauses + */ +typedef struct RangeVar +{ + NodeTag type; + char *relname; /* the relation name */ + InhOption inhOpt; /* expand rel by inheritance? */ + Attr *name; /* optional table alias & column aliases */ +} RangeVar; + +/* + * RangeSubselect - subquery appearing in a FROM clause + */ +typedef struct RangeSubselect +{ + NodeTag type; + Node *subquery; /* the untransformed sub-select clause */ + Attr *name; /* table alias & optional column aliases */ +} RangeSubselect; + +/* + * IndexElem - index parameters (used in CREATE INDEX) + * + * For a plain index, each 'name' is an attribute name in the heap relation, + * and 'args' is NIL. For a functional index, only one IndexElem is allowed. + * It has name = name of function and args = list of attribute names that + * are the function's arguments. + */ +typedef struct IndexElem +{ + NodeTag type; + char *name; /* name of attribute to index, or function */ + List *args; /* list of names of function arguments */ + char *class; /* name of desired opclass; NULL = default */ +} IndexElem; + +/* + * DefElem - + * a definition (used in definition lists in the form of defname = arg) + */ +typedef struct DefElem +{ + NodeTag type; + char *defname; + Node *arg; /* a (Value *) or a (TypeName *) */ +} 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. + * + * Currently we use the same node type for both plain relation references + * and sub-selects in the FROM clause. It might be cleaner to abstract + * the common fields into a "superclass" nodetype. + * + * alias is an Attr node representing the AS alias-clause attached to the + * FROM expression, or NULL if no clause. + * + * eref is the table reference name and column reference names (either + * real or aliases). Note that system columns (OID etc) are not included + * in the column list. + * eref->relname is required to be present, and should generally be used + * to identify the RTE for error messages etc. + * + * inh is TRUE for relation references that should be expanded to include + * inheritance children, if the rel has any. This *must* be FALSE for + * subquery RTEs. + * + * inFromCl marks those range variables that are listed in the FROM clause. + * In SQL, the query can only refer to range variables listed in the + * FROM clause, but POSTQUEL allows you to refer to tables not listed, + * in which case a range table entry will be generated. We still support + * this POSTQUEL feature, although there is some doubt whether it's + * convenient or merely confusing. The flag is needed since an + * implicitly-added RTE shouldn't change the namespace for unqualified + * column names processed later, and it also shouldn't affect the + * expansion of '*'. + * + * checkForRead, checkForWrite, and checkAsUser control run-time access + * permissions checks. A rel will be checked for read or write access + * (or both, or neither) per checkForRead and checkForWrite. If + * checkAsUser is not InvalidOid, then do the permissions checks using + * the access rights of that user, not the current effective user ID. + * (This allows rules to act as setuid gateways.) + *-------------------- + */ +typedef struct RangeTblEntry +{ + NodeTag type; + + /* + * Fields valid for a plain relation RTE (else NULL/zero): + */ + char *relname; /* real name of the relation */ + Oid relid; /* OID of the relation */ + + /* + * Fields valid for a subquery RTE (else NULL): + */ + Query *subquery; /* the sub-query */ + + /* + * Fields valid in all RTEs: + */ + Attr *alias; /* user-written alias clause, if any */ + Attr *eref; /* expanded reference names */ + bool inh; /* inheritance requested? */ + bool inFromCl; /* present in FROM clause */ + bool checkForRead; /* check rel for read access */ + bool checkForWrite; /* check rel for write access */ + Oid checkAsUser; /* if not zero, check access as this user */ +} RangeTblEntry; + +/* + * SortClause - + * representation of ORDER BY clauses + * + * tleSortGroupRef must match ressortgroupref of exactly one Resdom of the + * associated targetlist; that is the expression to be sorted (or grouped) by. + * sortop is the OID of the ordering operator. + * + * SortClauses are also used to identify Resdoms that we will do a "Unique" + * filter step on (for SELECT DISTINCT and SELECT DISTINCT ON). The + * distinctClause list is simply a copy of the relevant members of the + * sortClause list. Note that distinctClause can be a subset of sortClause, + * but cannot have members not present in sortClause; and the members that + * do appear must be in the same order as in sortClause. + */ +typedef struct SortClause +{ + NodeTag type; + Index tleSortGroupRef; /* reference into targetlist */ + Oid sortop; /* the sort operator to use */ +} SortClause; + +/* + * GroupClause - + * representation of GROUP BY clauses + * + * GroupClause is exactly like SortClause except for the nodetag value + * (it's probably not even really necessary to have two different + * nodetags...). We have routines that operate interchangeably on both. + */ +typedef SortClause GroupClause; + + +/***************************************************************************** + * Optimizable Statements + *****************************************************************************/ + +/* ---------------------- + * Insert Statement + * ---------------------- + */ +typedef struct InsertStmt +{ + NodeTag type; + char *relname; /* relation to insert into */ + List *cols; /* optional: names of the target columns */ + + /* + * An INSERT statement has *either* VALUES or SELECT, never both. If + * VALUES, a targetList is supplied (empty for DEFAULT VALUES). If + * SELECT, a complete SelectStmt (or set-operation tree) is supplied. + */ + List *targetList; /* the target list (of ResTarget) */ + Node *selectStmt; /* the source SELECT */ +} InsertStmt; + +/* ---------------------- + * Delete Statement + * ---------------------- + */ +typedef struct DeleteStmt +{ + NodeTag type; + char *relname; /* relation to delete from */ + Node *whereClause; /* qualifications */ + InhOption inhOpt; /* recursively act on children? */ +} DeleteStmt; + +/* ---------------------- + * Update Statement + * ---------------------- + */ +typedef struct UpdateStmt +{ + NodeTag type; + char *relname; /* relation to update */ + List *targetList; /* the target list (of ResTarget) */ + Node *whereClause; /* qualifications */ + List *fromClause; /* the from clause */ + InhOption inhOpt; /* recursively act on children? */ +} UpdateStmt; + +/* ---------------------- + * Select Statement + * + * A "simple" SELECT is represented in the output of gram.y by a single + * SelectStmt node. A SELECT construct containing set operators (UNION, + * INTERSECT, EXCEPT) is represented by a tree of SelectStmt nodes, in + * which the leaf nodes are component SELECTs and the internal nodes + * represent UNION, INTERSECT, or EXCEPT operators. Using the same node + * type for both leaf and internal nodes allows gram.y to stick ORDER BY, + * LIMIT, etc, clause values into a SELECT statement without worrying + * whether it is a simple or compound SELECT. + * ---------------------- + */ +typedef enum SetOperation +{ + SETOP_NONE = 0, + SETOP_UNION, + SETOP_INTERSECT, + SETOP_EXCEPT +} SetOperation; + +typedef struct SelectStmt +{ + NodeTag type; + + /* + * These fields are used only in "leaf" SelectStmts. + */ + List *distinctClause; /* NULL, list of DISTINCT ON exprs, or + * lcons(NIL,NIL) for all (SELECT + * DISTINCT) */ + char *into; /* name of table (for select into table) */ + bool istemp; /* into is a temp table? */ + List *intoColNames; /* column names for into table */ + List *targetList; /* the target list (of ResTarget) */ + List *fromClause; /* the FROM clause */ + Node *whereClause; /* WHERE qualification */ + List *groupClause; /* GROUP BY clauses */ + Node *havingClause; /* HAVING conditional-expression */ + + /* + * These fields are used in both "leaf" SelectStmts and upper-level + * SelectStmts. portalname/binary may only be set at the top level. + */ + List *sortClause; /* sort clause (a list of SortGroupBy's) */ + char *portalname; /* the portal (cursor) to create */ + bool binary; /* a binary (internal) portal? */ + Node *limitOffset; /* # of result tuples to skip */ + Node *limitCount; /* # of result tuples to return */ + List *forUpdate; /* FOR UPDATE clause */ + + /* + * These fields are used only in upper-level SelectStmts. + */ + SetOperation op; /* type of set op */ + bool all; /* ALL specified? */ + struct SelectStmt *larg; /* left child */ + struct SelectStmt *rarg; /* right child */ + /* Eventually add fields for CORRESPONDING spec here */ +} SelectStmt; + +/* ---------------------- + * Set Operation node for post-analysis query trees + * + * After parse analysis, a SELECT with set operations is represented by a + * top-level Query node containing the leaf SELECTs as subqueries in its + * range table. Its setOperations field shows the tree of set operations, + * with leaf SelectStmt nodes replaced by RangeTblRef nodes, and internal + * nodes replaced by SetOperationStmt nodes. + * ---------------------- + */ +typedef struct SetOperationStmt +{ + NodeTag type; + SetOperation op; /* type of set op */ + bool all; /* ALL specified? */ + Node *larg; /* left child */ + Node *rarg; /* right child */ + /* Eventually add fields for CORRESPONDING spec here */ + + /* Fields derived during parse analysis: */ + List *colTypes; /* integer list of OIDs of output column + * types */ +} SetOperationStmt; + /***************************************************************************** * Other Statements (no optimizations required) @@ -149,9 +709,9 @@ typedef struct GrantStmt NodeTag type; bool is_grant; /* not revoke */ int objtype; - List *objects; - List *privileges; - List *grantees; + List *objects; /* list of names (as Value strings) */ + List *privileges; /* integer list of privilege codes */ + List *grantees; /* list of PrivGrantee nodes */ } GrantStmt; @@ -167,7 +727,7 @@ typedef struct FuncWithArgs { NodeTag type; char *funcname; - List *funcargs; + List *funcargs; /* list of Typename nodes */ } FuncWithArgs; @@ -272,7 +832,6 @@ typedef struct Constraint List *keys; /* Ident nodes naming referenced column(s) */ } Constraint; - /* ---------- * Definitions for FOREIGN KEY constraints in CreateStmt * ---------- @@ -302,7 +861,6 @@ typedef struct FkConstraint bool initdeferred; /* INITIALLY DEFERRED */ } FkConstraint; - /* ---------------------- * Create/Drop TRIGGER Statements * ---------------------- @@ -338,7 +896,6 @@ typedef struct DropTrigStmt char *relname; /* triggered relation */ } DropTrigStmt; - /* ---------------------- * Create/Drop PROCEDURAL LANGUAGE Statement * ---------------------- @@ -358,7 +915,6 @@ typedef struct DropPLangStmt char *plname; /* PL name */ } DropPLangStmt; - /* ---------------------- * Create/Alter/Drop User Statements * ---------------------- @@ -391,7 +947,6 @@ typedef struct DropUserStmt List *users; /* List of users to remove */ } DropUserStmt; - /* ---------------------- * Create/Alter/Drop Group Statements * ---------------------- @@ -417,7 +972,6 @@ typedef struct DropGroupStmt char *name; } DropGroupStmt; - /* ---------------------- * Create SEQUENCE Statement * ---------------------- @@ -456,7 +1010,6 @@ typedef struct DefineStmt List *definition; /* a list of DefElem */ } DefineStmt; - /* ---------------------- * Drop Table|Sequence|View|Index|Rule|Type Statement * ---------------------- @@ -815,7 +1368,6 @@ typedef struct LockStmt int mode; /* lock mode */ } LockStmt; - /* ---------------------- * SET CONSTRAINTS Statement * ---------------------- @@ -823,7 +1375,7 @@ typedef struct LockStmt typedef struct ConstraintsSetStmt { NodeTag type; - List *constraints; + List *constraints; /* List of names as Value strings */ bool deferred; } ConstraintsSetStmt; @@ -840,561 +1392,4 @@ typedef struct ReindexStmt bool all; } ReindexStmt; - -/***************************************************************************** - * Optimizable Statements - *****************************************************************************/ - -/* ---------------------- - * Insert Statement - * ---------------------- - */ -typedef struct InsertStmt -{ - NodeTag type; - char *relname; /* relation to insert into */ - List *cols; /* optional: names of the target columns */ - - /* - * An INSERT statement has *either* VALUES or SELECT, never both. If - * VALUES, a targetList is supplied (empty for DEFAULT VALUES). If - * SELECT, a complete SelectStmt (or set-operation tree) is supplied. - */ - List *targetList; /* the target list (of ResTarget) */ - Node *selectStmt; /* the source SELECT */ -} InsertStmt; - -/* ---------------------- - * Delete Statement - * ---------------------- - */ -typedef struct DeleteStmt -{ - NodeTag type; - char *relname; /* relation to delete from */ - Node *whereClause; /* qualifications */ - InhOption inhOpt; /* recursively act on children? */ -} DeleteStmt; - -/* ---------------------- - * Update Statement - * ---------------------- - */ -typedef struct UpdateStmt -{ - NodeTag type; - char *relname; /* relation to update */ - List *targetList; /* the target list (of ResTarget) */ - Node *whereClause; /* qualifications */ - List *fromClause; /* the from clause */ - InhOption inhOpt; /* recursively act on children? */ -} UpdateStmt; - -/* ---------------------- - * Select Statement - * - * A "simple" SELECT is represented in the output of gram.y by a single - * SelectStmt node. A SELECT construct containing set operators (UNION, - * INTERSECT, EXCEPT) is represented by a tree of SelectStmt nodes, in - * which the leaf nodes are component SELECTs and the internal nodes - * represent UNION, INTERSECT, or EXCEPT operators. Using the same node - * type for both leaf and internal nodes allows gram.y to stick ORDER BY, - * LIMIT, etc, clause values into a SELECT statement without worrying - * whether it is a simple or compound SELECT. - * ---------------------- - */ -typedef enum SetOperation -{ - SETOP_NONE = 0, - SETOP_UNION, - SETOP_INTERSECT, - SETOP_EXCEPT -} SetOperation; - -typedef struct SelectStmt -{ - NodeTag type; - - /* - * These fields are used only in "leaf" SelectStmts. - */ - List *distinctClause; /* NULL, list of DISTINCT ON exprs, or - * lcons(NIL,NIL) for all (SELECT - * DISTINCT) */ - char *into; /* name of table (for select into table) */ - bool istemp; /* into is a temp table? */ - List *intoColNames; /* column names for into table */ - List *targetList; /* the target list (of ResTarget) */ - List *fromClause; /* the FROM clause */ - Node *whereClause; /* WHERE qualification */ - List *groupClause; /* GROUP BY clauses */ - Node *havingClause; /* HAVING conditional-expression */ - - /* - * These fields are used in both "leaf" SelectStmts and upper-level - * SelectStmts. portalname/binary may only be set at the top level. - */ - List *sortClause; /* sort clause (a list of SortGroupBy's) */ - char *portalname; /* the portal (cursor) to create */ - bool binary; /* a binary (internal) portal? */ - Node *limitOffset; /* # of result tuples to skip */ - Node *limitCount; /* # of result tuples to return */ - List *forUpdate; /* FOR UPDATE clause */ - - /* - * These fields are used only in upper-level SelectStmts. - */ - SetOperation op; /* type of set op */ - bool all; /* ALL specified? */ - struct SelectStmt *larg; /* left child */ - struct SelectStmt *rarg; /* right child */ - /* Eventually add fields for CORRESPONDING spec here */ -} SelectStmt; - -/* ---------------------- - * Set Operation node for post-analysis query trees - * - * After parse analysis, a SELECT with set operations is represented by a - * top-level Query node containing the leaf SELECTs as subqueries in its - * range table. Its setOperations field shows the tree of set operations, - * with leaf SelectStmt nodes replaced by RangeTblRef nodes, and internal - * nodes replaced by SetOperationStmt nodes. - * ---------------------- - */ -typedef struct SetOperationStmt -{ - NodeTag type; - SetOperation op; /* type of set op */ - bool all; /* ALL specified? */ - Node *larg; /* left child */ - Node *rarg; /* right child */ - /* Eventually add fields for CORRESPONDING spec here */ - - /* Fields derived during parse analysis: */ - List *colTypes; /* integer list of OIDs of output column - * types */ -} SetOperationStmt; - -/**************************************************************************** - * Supporting data structures for Parse Trees - * - * Most of these node types appear in raw parsetrees output by the grammar, - * and get transformed to something else by the analyzer. A few of them - * are used as-is in transformed querytrees. - ****************************************************************************/ - -/* - * TypeName - specifies a type in definitions - */ -typedef struct TypeName -{ - NodeTag type; - char *name; /* name of the type */ - bool timezone; /* timezone specified? */ - bool setof; /* is a set? */ - int32 typmod; /* type modifier */ - List *arrayBounds; /* array bounds */ - char *attrname; /* field name when using %TYPE */ -} TypeName; - -/* - * ParamNo - specifies a parameter reference - */ -typedef struct ParamNo -{ - NodeTag type; - int number; /* the number of the parameter */ - TypeName *typename; /* the typecast */ - List *indirection; /* array references */ -} ParamNo; - -/* - * A_Expr - binary expressions - */ -typedef struct A_Expr -{ - NodeTag type; - int oper; /* type of operation (OP,OR,AND,NOT) */ - char *opname; /* name of operator */ - Node *lexpr; /* left argument */ - Node *rexpr; /* right argument */ -} A_Expr; - -/* - * Attr - - * specifies an Attribute (ie. a Column); could have nested dots or - * array references. - * - */ -typedef struct Attr -{ - NodeTag type; - char *relname; /* name of relation (can be "*") */ - ParamNo *paramNo; /* or a parameter */ - List *attrs; /* attributes (possibly nested); list of - * Values (strings) */ - List *indirection; /* array refs (list of A_Indices') */ -} Attr; - -/* - * A_Const - a constant expression - */ -typedef struct A_Const -{ - NodeTag type; - Value val; /* the value (with the tag) */ - TypeName *typename; /* typecast */ -} A_Const; - -/* - * TypeCast - a CAST expression - * - * NOTE: for mostly historical reasons, A_Const and ParamNo parsenodes contain - * room for a TypeName; we only generate a separate TypeCast node if the - * argument to be casted is neither of those kinds of nodes. In theory either - * representation would work, but it is convenient (especially for A_Const) - * to have the target type immediately available. - */ -typedef struct TypeCast -{ - NodeTag type; - Node *arg; /* the expression being casted */ - TypeName *typename; /* the target type */ -} 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; - -/* - * 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. - */ -typedef struct ColumnDef -{ - NodeTag type; - char *colname; /* name of column */ - TypeName *typename; /* type of column */ - 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 */ -} ColumnDef; - -/* - * Ident - - * an identifier (could be an attribute or a relation name). Depending - * on the context at transformStmt time, the identifier is treated as - * either a relation name (in which case, isRel will be set) or an - * attribute (in which case, it will be transformed into an Attr). - */ -typedef struct Ident -{ - NodeTag type; - char *name; /* its name */ - List *indirection; /* array references */ - bool isRel; /* is this a relation or a column? */ -} Ident; - -/* - * FuncCall - a function or aggregate invocation - * - * agg_star indicates we saw a 'foo(*)' construct, while agg_distinct - * indicates we saw 'foo(DISTINCT ...)'. In either case, the construct - * *must* be an aggregate call. Otherwise, it might be either an - * aggregate or some other kind of function. - */ -typedef struct FuncCall -{ - NodeTag type; - char *funcname; /* name of function */ - List *args; /* the arguments (list of exprs) */ - bool agg_star; /* argument was really '*' */ - bool agg_distinct; /* arguments were labeled DISTINCT */ -} FuncCall; - -/* - * A_Indices - array reference or bounds ([lidx:uidx] or [uidx]) - */ -typedef struct A_Indices -{ - NodeTag type; - Node *lidx; /* could be NULL */ - Node *uidx; -} A_Indices; - -/* - * ResTarget - - * result target (used in target list of pre-transformed Parse trees) - * - * In a SELECT or INSERT target list, 'name' is either NULL or - * the column name assigned to the value. (If there is an 'AS ColumnLabel' - * clause, the grammar sets 'name' from it; otherwise 'name' is initially NULL - * and is filled in during the parse analysis phase.) - * The 'indirection' field is not used at all. - * - * In an UPDATE target list, 'name' is the name of the destination column, - * and 'indirection' stores any subscripts attached to the destination. - * That is, our representation is UPDATE table SET name [indirection] = val. - */ -typedef struct ResTarget -{ - NodeTag type; - char *name; /* column name or NULL */ - List *indirection; /* subscripts for destination column, or - * NIL */ - Node *val; /* the value expression to compute or - * assign */ -} ResTarget; - -/* - * SortGroupBy - for ORDER BY clause - */ -typedef struct SortGroupBy -{ - NodeTag type; - char *useOp; /* operator to use */ - Node *node; /* Expression */ -} SortGroupBy; - -/* - * RangeVar - range variable, used in FROM clauses - */ -typedef struct RangeVar -{ - NodeTag type; - char *relname; /* the relation name */ - InhOption inhOpt; /* expand rel by inheritance? */ - Attr *name; /* optional table alias & column aliases */ -} RangeVar; - -/* - * RangeSubselect - subquery appearing in a FROM clause - */ -typedef struct RangeSubselect -{ - NodeTag type; - Node *subquery; /* the untransformed sub-select clause */ - Attr *name; /* table alias & optional column aliases */ -} RangeSubselect; - -/* - * IndexElem - index parameters (used in CREATE INDEX) - * - * For a plain index, each 'name' is an attribute name in the heap relation, - * and 'args' is NIL. For a functional index, only one IndexElem is allowed. - * It has name = name of function and args = list of attribute names that - * are the function's arguments. - */ -typedef struct IndexElem -{ - NodeTag type; - char *name; /* name of attribute to index, or function */ - List *args; /* list of names of function arguments */ - char *class; /* name of desired opclass; NULL = default */ -} IndexElem; - -/* - * DefElem - - * a definition (used in definition lists in the form of defname = arg) - */ -typedef struct DefElem -{ - NodeTag type; - char *defname; - Node *arg; /* a (Value *) or a (TypeName *) */ -} 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. - * - * Currently we use the same node type for both plain relation references - * and sub-selects in the FROM clause. It might be cleaner to abstract - * the common fields into a "superclass" nodetype. - * - * alias is an Attr node representing the AS alias-clause attached to the - * FROM expression, or NULL if no clause. - * - * eref is the table reference name and column reference names (either - * real or aliases). Note that system columns (OID etc) are not included - * in the column list. - * eref->relname is required to be present, and should generally be used - * to identify the RTE for error messages etc. - * - * inh is TRUE for relation references that should be expanded to include - * inheritance children, if the rel has any. This *must* be FALSE for - * subquery RTEs. - * - * inFromCl marks those range variables that are listed in the FROM clause. - * In SQL, the query can only refer to range variables listed in the - * FROM clause, but POSTQUEL allows you to refer to tables not listed, - * in which case a range table entry will be generated. We still support - * this POSTQUEL feature, although there is some doubt whether it's - * convenient or merely confusing. The flag is needed since an - * implicitly-added RTE shouldn't change the namespace for unqualified - * column names processed later, and it also shouldn't affect the - * expansion of '*'. - * - * checkForRead, checkForWrite, and checkAsUser control run-time access - * permissions checks. A rel will be checked for read or write access - * (or both, or neither) per checkForRead and checkForWrite. If - * checkAsUser is not InvalidOid, then do the permissions checks using - * the access rights of that user, not the current effective user ID. - * (This allows rules to act as setuid gateways.) - *-------------------- - */ -typedef struct RangeTblEntry -{ - NodeTag type; - - /* - * Fields valid for a plain relation RTE (else NULL/zero): - */ - char *relname; /* real name of the relation */ - Oid relid; /* OID of the relation */ - - /* - * Fields valid for a subquery RTE (else NULL): - */ - Query *subquery; /* the sub-query */ - - /* - * Fields valid in all RTEs: - */ - Attr *alias; /* user-written alias clause, if any */ - Attr *eref; /* expanded reference names */ - bool inh; /* inheritance requested? */ - bool inFromCl; /* present in FROM clause */ - bool checkForRead; /* check rel for read access */ - bool checkForWrite; /* check rel for write access */ - Oid checkAsUser; /* if not zero, check access as this user */ -} RangeTblEntry; - -/* - * SortClause - - * representation of ORDER BY clauses - * - * tleSortGroupRef must match ressortgroupref of exactly one Resdom of the - * associated targetlist; that is the expression to be sorted (or grouped) by. - * sortop is the OID of the ordering operator. - * - * SortClauses are also used to identify Resdoms that we will do a "Unique" - * filter step on (for SELECT DISTINCT and SELECT DISTINCT ON). The - * distinctClause list is simply a copy of the relevant members of the - * sortClause list. Note that distinctClause can be a subset of sortClause, - * but cannot have members not present in sortClause; and the members that - * do appear must be in the same order as in sortClause. - */ -typedef struct SortClause -{ - NodeTag type; - Index tleSortGroupRef; /* reference into targetlist */ - Oid sortop; /* the sort operator to use */ -} SortClause; - -/* - * GroupClause - - * representation of GROUP BY clauses - * - * GroupClause is exactly like SortClause except for the nodetag value - * (it's probably not even really necessary to have two different - * nodetags...). We have routines that operate interchangeably on both. - */ -typedef SortClause GroupClause; - #endif /* PARSENODES_H */ |