From cf68a686a6368ebd6e9e37ded4481bf1bd4a8b8e Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 8 Mar 2002 04:37:18 +0000
Subject: [PATCH] Fix copying/equality-check bugs in GrantStmt and
 ConstraintsSetStmt, per reports from Fernando Nasser.  Also, rearrange order
 of declarations in parsenodes.h as suggested by Fernando.

---
 src/backend/commands/trigger.c |   11 +-
 src/backend/nodes/copyfuncs.c  |    6 +-
 src/backend/nodes/equalfuncs.c |    4 +-
 src/backend/parser/gram.y      |   36 +-
 src/include/nodes/parsenodes.h | 1865 ++++++++++++++++----------------
 5 files changed, 945 insertions(+), 977 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,1308 +102,1294 @@ typedef struct Query
 } Query;
 
 
-typedef enum InhOption
-{
-	INH_NO,						/* Do NOT scan child tables */
-	INH_YES,					/* DO scan child tables */
-	INH_DEFAULT					/* Use current SQL_inheritance option */
-} InhOption;
-
-/*****************************************************************************
- *		Other Statements (no optimizations required)
+/****************************************************************************
+ *	Supporting data structures for Parse Trees
  *
- *		Some of them require a little bit of transformation (which is also
- *		done by transformStmt). The whole structure is then passed on to
- *		ProcessUtility (by-passing the optimization step) as the utilityStmt
- *		field in Query.
- *****************************************************************************/
+ *	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.
+ ****************************************************************************/
 
-/* ----------------------
- *	Alter Table
- *
- * The fields are used in different ways by the different variants of
- * this command.
- * ----------------------
+/*
+ * TypeName - specifies a type in definitions
  */
-typedef struct AlterTableStmt
+typedef struct TypeName
 {
 	NodeTag		type;
-	char		subtype;		/*------------
-								 *	A = add column
-								 *	T = alter column default
-								 *	S = alter column statistics
-								 *  M = alter column storage
-								 *	D = drop column
-								 *	C = add constraint
-								 *	X = drop constraint
-								 *	E = create toast table
-								 *	U = change owner
-								 *------------
-								 */
-	char	   *relname;		/* table to work on */
-	InhOption	inhOpt;			/* recursively act on children? */
-	char	   *name;			/* column or constraint name to act on, or
-								 * new owner */
-	Node	   *def;			/* definition of new column or constraint */
-	int			behavior;		/* CASCADE or RESTRICT drop behavior */
-} AlterTableStmt;
+	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;
 
-/* ----------------------
- *		Grant Statement
- * ----------------------
+/*
+ * ParamNo - specifies a parameter reference
  */
-
-typedef struct GrantStmt
+typedef struct ParamNo
 {
 	NodeTag		type;
-	bool		is_grant;		/* not revoke */
-	int			objtype;
-	List	   *objects;
-	List	   *privileges;
-	List	   *grantees;
-} GrantStmt;
-
+	int			number;			/* the number of the parameter */
+	TypeName   *typename;		/* the typecast */
+	List	   *indirection;	/* array references */
+} ParamNo;
 
-typedef struct PrivGrantee
+/*
+ * A_Expr - binary expressions
+ */
+typedef struct A_Expr
 {
 	NodeTag		type;
-	char	   *username;		/* if both are NULL then PUBLIC */
-	char	   *groupname;
-} PrivGrantee;
-
+	int			oper;			/* type of operation (OP,OR,AND,NOT) */
+	char	   *opname;			/* name of operator */
+	Node	   *lexpr;			/* left argument */
+	Node	   *rexpr;			/* right argument */
+} A_Expr;
 
-typedef struct FuncWithArgs
+/*
+ * Attr -
+ *	  specifies an Attribute (ie. a Column); could have nested dots or
+ *	  array references.
+ *
+ */
+typedef struct Attr
 {
 	NodeTag		type;
-	char	   *funcname;
-	List	   *funcargs;
-} FuncWithArgs;
-
+	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;
 
-/* This is only used internally in gram.y. */
-typedef struct PrivTarget
+/*
+ * A_Const - a constant expression
+ */
+typedef struct A_Const
 {
 	NodeTag		type;
-	int			objtype;
-	List	   *objs;
-} PrivTarget;
-
+	Value		val;			/* the value (with the tag) */
+	TypeName   *typename;		/* typecast */
+} A_Const;
 
-/* ----------------------
- *		Close Portal Statement
- * ----------------------
+/*
+ * 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 ClosePortalStmt
+typedef struct TypeCast
 {
 	NodeTag		type;
-	char	   *portalname;		/* name of the portal (cursor) */
-} ClosePortalStmt;
+	Node	   *arg;			/* the expression being casted */
+	TypeName   *typename;		/* the target type */
+} TypeCast;
 
-/* ----------------------
- *		Copy Statement
- * ----------------------
+/*
+ * CaseExpr - a CASE expression
  */
-typedef struct CopyStmt
+typedef struct CaseExpr
 {
 	NodeTag		type;
-	bool		binary;			/* is a binary copy? */
-	char	   *relname;		/* the relation to copy */
-	bool		oids;			/* copy oid's? */
-	int			direction;		/* TO or FROM */
-	char	   *filename;		/* if NULL, use stdin/stdout */
-	char	   *delimiter;		/* delimiter character, \t by default */
-	char	   *null_print;		/* how to print NULLs, `\N' by default */
-} CopyStmt;
+	Oid			casetype;
+	Node	   *arg;			/* implicit equality comparison argument */
+	List	   *args;			/* the arguments (list of WHEN clauses) */
+	Node	   *defresult;		/* the default result (ELSE clause) */
+} CaseExpr;
 
-/* ----------------------
- *		Create Table Statement
- *
- * NOTE: in the raw gram.y output, ColumnDef, Constraint, and FkConstraint
- * nodes are intermixed in tableElts, and constraints is NIL.  After parse
- * analysis, tableElts contains just ColumnDefs, and constraints contains
- * just Constraint nodes (in fact, only CONSTR_CHECK nodes, in the present
- * implementation).
- * ----------------------
+/*
+ * CaseWhen - an argument to a CASE expression
  */
-typedef struct CreateStmt
+typedef struct CaseWhen
 {
 	NodeTag		type;
-	char	   *relname;		/* name of relation to create */
-	List	   *tableElts;		/* column definitions (list of ColumnDef) */
-	List	   *inhRelnames;	/* relations to inherit from (list of
-								 * T_String Values) */
-	List	   *constraints;	/* constraints (list of Constraint nodes) */
-	bool		istemp;			/* is this a temp table? */
-	bool		hasoids;		/* should it have OIDs? */
-} CreateStmt;
+	Node	   *expr;			/* comparison expression */
+	Node	   *result;			/* substitution result */
+} CaseWhen;
 
-/* ----------
- * Definitions for plain (non-FOREIGN KEY) constraints in CreateStmt
- *
- * XXX probably these ought to be unified with FkConstraints at some point?
- *
- * For constraints that use expressions (CONSTR_DEFAULT, CONSTR_CHECK)
- * we may have the expression in either "raw" form (an untransformed
- * parse tree) or "cooked" form (the nodeToString representation of
- * an executable expression tree), depending on how this Constraint
- * node was created (by parsing, or by inheritance from an existing
- * relation).  We should never have both in the same node!
+/* ----------------
+ * NullTest
  *
- * Constraint attributes (DEFERRABLE etc) are initially represented as
- * separate Constraint nodes for simplicity of parsing.  analyze.c makes
- * a pass through the constraints list to attach the info to the appropriate
- * FkConstraint node (and, perhaps, someday to other kinds of constraints).
- * ----------
+ * 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 ConstrType			/* types of constraints */
+typedef enum NullTestType
 {
-	CONSTR_NULL,				/* not SQL92, but a lot of people expect
-								 * it */
-	CONSTR_NOTNULL,
-	CONSTR_DEFAULT,
-	CONSTR_CHECK,
-	CONSTR_PRIMARY,
-	CONSTR_UNIQUE,
-	CONSTR_ATTR_DEFERRABLE,		/* attributes for previous constraint node */
-	CONSTR_ATTR_NOT_DEFERRABLE,
-	CONSTR_ATTR_DEFERRED,
-	CONSTR_ATTR_IMMEDIATE
-} ConstrType;
+	IS_NULL, IS_NOT_NULL
+} NullTestType;
 
-typedef struct Constraint
+typedef struct NullTest
 {
 	NodeTag		type;
-	ConstrType	contype;
-	char	   *name;			/* name, or NULL if unnamed */
-	Node	   *raw_expr;		/* expr, as untransformed parse tree */
-	char	   *cooked_expr;	/* expr, as nodeToString representation */
-	List	   *keys;			/* Ident nodes naming referenced column(s) */
-} Constraint;
-
+	Node	   *arg;			/* input expression */
+	NullTestType nulltesttype;	/* IS NULL, IS NOT NULL */
+} NullTest;
 
-/* ----------
- * Definitions for FOREIGN KEY constraints in CreateStmt
- * ----------
+/* ----------------
+ * 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.
+ * ----------------
  */
-#define FKCONSTR_ON_KEY_NOACTION		0x0000
-#define FKCONSTR_ON_KEY_RESTRICT		0x0001
-#define FKCONSTR_ON_KEY_CASCADE			0x0002
-#define FKCONSTR_ON_KEY_SETNULL			0x0004
-#define FKCONSTR_ON_KEY_SETDEFAULT		0x0008
 
-#define FKCONSTR_ON_DELETE_MASK			0x000F
-#define FKCONSTR_ON_DELETE_SHIFT		0
-
-#define FKCONSTR_ON_UPDATE_MASK			0x00F0
-#define FKCONSTR_ON_UPDATE_SHIFT		4
-
-typedef struct FkConstraint
+typedef enum BoolTestType
 {
-	NodeTag		type;
-	char	   *constr_name;	/* Constraint name */
-	char	   *pktable_name;	/* Primary key table name */
-	List	   *fk_attrs;		/* Attributes of foreign key */
-	List	   *pk_attrs;		/* Corresponding attrs in PK table */
-	char	   *match_type;		/* FULL or PARTIAL */
-	int32		actions;		/* ON DELETE/UPDATE actions */
-	bool		deferrable;		/* DEFERRABLE */
-	bool		initdeferred;	/* INITIALLY DEFERRED */
-} FkConstraint;
-
-
-/* ----------------------
- *		Create/Drop TRIGGER Statements
- * ----------------------
- */
+	IS_TRUE, IS_NOT_TRUE, IS_FALSE, IS_NOT_FALSE, IS_UNKNOWN, IS_NOT_UNKNOWN
+} BoolTestType;
 
-typedef struct CreateTrigStmt
+typedef struct BooleanTest
 {
 	NodeTag		type;
-	char	   *trigname;		/* TRIGGER' name */
-	char	   *relname;		/* triggered relation */
-	char	   *funcname;		/* function to call (or NULL) */
-	List	   *args;			/* list of (T_String) Values or NULL */
-	bool		before;			/* BEFORE/AFTER */
-	bool		row;			/* ROW/STATEMENT */
-	char		actions[4];		/* Insert, Update, Delete */
-	char	   *lang;			/* currently not used, always NULL */
-	char	   *text;			/* AS 'text' */
-	List	   *attr;			/* UPDATE OF a, b,... (NI) or NULL */
-	char	   *when;			/* WHEN 'a > 10 ...' (NI) or NULL */
-
-	/* The following are used for referential */
-	/* integrity constraint triggers */
-	bool		isconstraint;	/* This is an RI trigger */
-	bool		deferrable;		/* [NOT] DEFERRABLE */
-	bool		initdeferred;	/* INITIALLY {DEFERRED|IMMEDIATE} */
-	char	   *constrrelname;	/* opposite relation */
-} CreateTrigStmt;
+	Node	   *arg;			/* input expression */
+	BoolTestType booltesttype;	/* test type */
+} BooleanTest;
 
-typedef struct DropTrigStmt
+/*
+ * 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	   *trigname;		/* TRIGGER' name */
-	char	   *relname;		/* triggered relation */
-} DropTrigStmt;
-
+	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;
 
-/* ----------------------
- *		Create/Drop PROCEDURAL LANGUAGE Statement
- * ----------------------
+/*
+ * 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 CreatePLangStmt
+typedef struct Ident
 {
 	NodeTag		type;
-	char	   *plname;			/* PL name */
-	char	   *plhandler;		/* PL call handler function */
-	char	   *plcompiler;		/* lancompiler text */
-	bool		pltrusted;		/* PL is trusted */
-} CreatePLangStmt;
+	char	   *name;			/* its name */
+	List	   *indirection;	/* array references */
+	bool		isRel;			/* is this a relation or a column? */
+} Ident;
 
-typedef struct DropPLangStmt
+/*
+ * 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	   *plname;			/* PL name */
-} DropPLangStmt;
-
+	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;
 
-/* ----------------------
- *	Create/Alter/Drop User Statements
- * ----------------------
+/*
+ * A_Indices - array reference or bounds ([lidx:uidx] or [uidx])
  */
-typedef struct CreateUserStmt
+typedef struct A_Indices
 {
 	NodeTag		type;
-	char	   *user;			/* PostgreSQL user login name */
-	List	   *options;		/* List of DefElem nodes */
-} CreateUserStmt;
+	Node	   *lidx;			/* could be NULL */
+	Node	   *uidx;
+} A_Indices;
 
-typedef struct AlterUserStmt
+/*
+ * 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	   *user;			/* PostgreSQL user login name */
-	List	   *options;		/* List of DefElem nodes */
-} AlterUserStmt;
+	char	   *name;			/* column name or NULL */
+	List	   *indirection;	/* subscripts for destination column, or
+								 * NIL */
+	Node	   *val;			/* the value expression to compute or
+								 * assign */
+} ResTarget;
 
-typedef struct AlterUserSetStmt
+/*
+ * SortGroupBy - for ORDER BY clause
+ */
+typedef struct SortGroupBy
 {
 	NodeTag		type;
-	char	   *user;
-	char	   *variable;
-	List	   *value;
-} AlterUserSetStmt;
+	char	   *useOp;			/* operator to use */
+	Node	   *node;			/* Expression  */
+} SortGroupBy;
 
-typedef struct DropUserStmt
+/*
+ * RangeVar - range variable, used in FROM clauses
+ */
+typedef struct RangeVar
 {
 	NodeTag		type;
-	List	   *users;			/* List of users to remove */
-} DropUserStmt;
-
+	char	   *relname;		/* the relation name */
+	InhOption	inhOpt;			/* expand rel by inheritance? */
+	Attr	   *name;			/* optional table alias & column aliases */
+} RangeVar;
 
-/* ----------------------
- *		Create/Alter/Drop Group Statements
- * ----------------------
+/*
+ * RangeSubselect - subquery appearing in a FROM clause
  */
-typedef struct CreateGroupStmt
+typedef struct RangeSubselect
 {
 	NodeTag		type;
-	char	   *name;			/* name of the new group */
-	List	   *options;		/* List of DefElem nodes */
-} CreateGroupStmt;
+	Node	   *subquery;		/* the untransformed sub-select clause */
+	Attr	   *name;			/* table alias & optional column aliases */
+} RangeSubselect;
 
-typedef struct AlterGroupStmt
+/*
+ * 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 group to alter */
-	int			action;			/* +1 = add, -1 = drop user */
-	List	   *listUsers;		/* list of users to add/drop */
-} AlterGroupStmt;
+	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;
 
-typedef struct DropGroupStmt
+/*
+ * DefElem -
+ *	  a definition (used in definition lists in the form of defname = arg)
+ */
+typedef struct DefElem
 {
 	NodeTag		type;
-	char	   *name;
-} DropGroupStmt;
-
+	char	   *defname;
+	Node	   *arg;			/* a (Value *) or a (TypeName *) */
+} DefElem;
 
-/* ----------------------
- *		Create SEQUENCE Statement
- * ----------------------
- */
 
-typedef struct CreateSeqStmt
-{
-	NodeTag		type;
-	char	   *seqname;		/* the relation to create */
-	bool		istemp;			/* is this a temp sequence? */
-	List	   *options;
-} CreateSeqStmt;
+/****************************************************************************
+ *	Nodes for a Query tree
+ ****************************************************************************/
 
-/* ----------------------
- *		Create Version Statement
- * ----------------------
+/*
+ * 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 VersionStmt
+typedef struct TargetEntry
 {
 	NodeTag		type;
-	char	   *relname;		/* the new relation */
-	int			direction;		/* FORWARD | BACKWARD */
-	char	   *fromRelname;	/* relation to create a version */
-	char	   *date;			/* date of the snapshot */
-} VersionStmt;
+	Resdom	   *resdom;			/* fjoin overload this to be a list?? */
+	Fjoin	   *fjoin;
+	Node	   *expr;
+} TargetEntry;
 
-/* ----------------------
- *		Create {Operator|Type|Aggregate} Statement
- * ----------------------
+/*--------------------
+ * 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 DefineStmt
+typedef struct RangeTblEntry
 {
 	NodeTag		type;
-	int			defType;		/* OPERATOR|P_TYPE|AGGREGATE */
-	char	   *defname;
-	List	   *definition;		/* a list of DefElem */
-} DefineStmt;
 
+	/*
+	 * Fields valid for a plain relation RTE (else NULL/zero):
+	 */
+	char	   *relname;		/* real name of the relation */
+	Oid			relid;			/* OID of the relation */
 
-/* ----------------------
- *		Drop Table|Sequence|View|Index|Rule|Type Statement
- * ----------------------
- */
+	/*
+	 * Fields valid for a subquery RTE (else NULL):
+	 */
+	Query	   *subquery;		/* the sub-query */
 
-#define DROP_TABLE	  1
-#define DROP_SEQUENCE 2
-#define DROP_VIEW	  3
-#define DROP_INDEX	  4
-#define DROP_RULE	  5
-#define DROP_TYPE_P   6
+	/*
+	 * 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;
 
-typedef struct DropStmt
+/*
+ * 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;
-	List	   *names;
-	int			removeType;
-} DropStmt;
+	Index		tleSortGroupRef;	/* reference into targetlist */
+	Oid			sortop;			/* the sort operator to use */
+} SortClause;
 
-/* ----------------------
- *				Truncate Table Statement
- * ----------------------
+/*
+ * 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 struct TruncateStmt
-{
-	NodeTag		type;
-	char	   *relName;		/* relation to be truncated */
-} TruncateStmt;
+typedef SortClause GroupClause;
+
+
+/*****************************************************************************
+ *		Optimizable Statements
+ *****************************************************************************/
 
 /* ----------------------
- *				Comment On Statement
+ *		Insert Statement
  * ----------------------
  */
-typedef struct CommentStmt
+typedef struct InsertStmt
 {
 	NodeTag		type;
-	int			objtype;		/* Object's type */
-	char	   *objname;		/* Name of the object */
-	char	   *objproperty;	/* Property Id (such as column) */
-	List	   *objlist;		/* Arguments for VAL objects */
-	char	   *comment;		/* The comment to insert */
-} CommentStmt;
+	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;
 
 /* ----------------------
- *		Begin Recipe Statement
+ *		Delete Statement
  * ----------------------
  */
-typedef struct RecipeStmt
+typedef struct DeleteStmt
 {
 	NodeTag		type;
-	char	   *recipeName;		/* name of the recipe */
-} RecipeStmt;
+	char	   *relname;		/* relation to delete from */
+	Node	   *whereClause;	/* qualifications */
+	InhOption	inhOpt;			/* recursively act on children? */
+} DeleteStmt;
 
 /* ----------------------
- *		Fetch Statement
+ *		Update Statement
  * ----------------------
  */
-typedef struct FetchStmt
+typedef struct UpdateStmt
 {
 	NodeTag		type;
-	int			direction;		/* FORWARD or BACKWARD */
-	int			howMany;		/* amount to fetch ("ALL" --> 0) */
-	char	   *portalname;		/* name of portal (cursor) */
-	bool		ismove;			/* TRUE if MOVE */
-} FetchStmt;
+	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;
 
 /* ----------------------
- *		Create Index Statement
+ *		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 struct IndexStmt
+typedef enum SetOperation
+{
+	SETOP_NONE = 0,
+	SETOP_UNION,
+	SETOP_INTERSECT,
+	SETOP_EXCEPT
+} SetOperation;
+
+typedef struct SelectStmt
 {
 	NodeTag		type;
-	char	   *idxname;		/* name of the index */
-	char	   *relname;		/* name of relation to index on */
-	char	   *accessMethod;	/* name of access method (eg. btree) */
-	List	   *indexParams;	/* a list of IndexElem */
-	Node	   *whereClause;	/* qualification (partial-index predicate) */
-	List	   *rangetable;		/* range table for qual, filled in by
-								 * transformStmt() */
-	bool		unique;			/* is index unique? */
-	bool		primary;		/* is index on primary key? */
-} IndexStmt;
+
+	/*
+	 * 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;
 
 /* ----------------------
- *		Create Function Statement
+ *		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 ProcedureStmt
+typedef struct SetOperationStmt
 {
 	NodeTag		type;
-	bool		replace;		/* T => replace if already exists */
-	char	   *funcname;		/* name of function to create */
-	List	   *argTypes;		/* list of argument types (TypeName nodes) */
-	Node	   *returnType;		/* the return type (a TypeName node) */
-	List	   *withClause;		/* a list of DefElem */
-	List	   *as;				/* definition of function body */
-	char	   *language;		/* C, SQL, etc */
-} ProcedureStmt;
+	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)
+ *
+ *		Some of them require a little bit of transformation (which is also
+ *		done by transformStmt). The whole structure is then passed on to
+ *		ProcessUtility (by-passing the optimization step) as the utilityStmt
+ *		field in Query.
+ *****************************************************************************/
 
 /* ----------------------
- *		Drop Aggregate Statement
+ *	Alter Table
+ *
+ * The fields are used in different ways by the different variants of
+ * this command.
  * ----------------------
  */
-typedef struct RemoveAggrStmt
+typedef struct AlterTableStmt
 {
 	NodeTag		type;
-	char	   *aggname;		/* aggregate to drop */
-	Node	   *aggtype;		/* TypeName for input datatype, or NULL */
-} RemoveAggrStmt;
+	char		subtype;		/*------------
+								 *	A = add column
+								 *	T = alter column default
+								 *	S = alter column statistics
+								 *  M = alter column storage
+								 *	D = drop column
+								 *	C = add constraint
+								 *	X = drop constraint
+								 *	E = create toast table
+								 *	U = change owner
+								 *------------
+								 */
+	char	   *relname;		/* table to work on */
+	InhOption	inhOpt;			/* recursively act on children? */
+	char	   *name;			/* column or constraint name to act on, or
+								 * new owner */
+	Node	   *def;			/* definition of new column or constraint */
+	int			behavior;		/* CASCADE or RESTRICT drop behavior */
+} AlterTableStmt;
 
 /* ----------------------
- *		Drop Function Statement
+ *		Grant Statement
  * ----------------------
  */
-typedef struct RemoveFuncStmt
+
+typedef struct GrantStmt
 {
 	NodeTag		type;
-	char	   *funcname;		/* function to drop */
-	List	   *args;			/* types of the arguments */
-} RemoveFuncStmt;
+	bool		is_grant;		/* not revoke */
+	int			objtype;
+	List	   *objects;		/* list of names (as Value strings) */
+	List	   *privileges;		/* integer list of privilege codes */
+	List	   *grantees;		/* list of PrivGrantee nodes */
+} GrantStmt;
 
-/* ----------------------
- *		Drop Operator Statement
- * ----------------------
- */
-typedef struct RemoveOperStmt
+
+typedef struct PrivGrantee
 {
 	NodeTag		type;
-	char	   *opname;			/* operator to drop */
-	List	   *args;			/* types of the arguments */
-} RemoveOperStmt;
+	char	   *username;		/* if both are NULL then PUBLIC */
+	char	   *groupname;
+} PrivGrantee;
 
-/* ----------------------
- *		Alter Table Statement
- * ----------------------
- */
-typedef struct RenameStmt
+
+typedef struct FuncWithArgs
 {
 	NodeTag		type;
-	char	   *relname;		/* relation to be altered */
-	InhOption	inhOpt;			/* recursively act on children? */
-	char	   *column;			/* if NULL, rename the relation name to
-								 * the new name. Otherwise, rename this
-								 * column name. */
-	char	   *newname;		/* the new name */
-} RenameStmt;
+	char	   *funcname;
+	List	   *funcargs;		/* list of Typename nodes */
+} FuncWithArgs;
 
-/* ----------------------
- *		Create Rule Statement
- * ----------------------
- */
-typedef struct RuleStmt
+
+/* This is only used internally in gram.y. */
+typedef struct PrivTarget
 {
 	NodeTag		type;
-	char	   *rulename;		/* name of the rule */
-	Node	   *whereClause;	/* qualifications */
-	CmdType		event;			/* RETRIEVE */
-	struct Attr *object;		/* object affected */
-	bool		instead;		/* is a 'do instead'? */
-	List	   *actions;		/* the action statements */
-} RuleStmt;
+	int			objtype;
+	List	   *objs;
+} PrivTarget;
+
 
 /* ----------------------
- *		Notify Statement
+ *		Close Portal Statement
  * ----------------------
  */
-typedef struct NotifyStmt
+typedef struct ClosePortalStmt
 {
 	NodeTag		type;
-	char	   *relname;		/* relation to notify */
-} NotifyStmt;
+	char	   *portalname;		/* name of the portal (cursor) */
+} ClosePortalStmt;
 
 /* ----------------------
- *		Listen Statement
+ *		Copy Statement
  * ----------------------
  */
-typedef struct ListenStmt
+typedef struct CopyStmt
 {
 	NodeTag		type;
-	char	   *relname;		/* relation to listen on */
-} ListenStmt;
+	bool		binary;			/* is a binary copy? */
+	char	   *relname;		/* the relation to copy */
+	bool		oids;			/* copy oid's? */
+	int			direction;		/* TO or FROM */
+	char	   *filename;		/* if NULL, use stdin/stdout */
+	char	   *delimiter;		/* delimiter character, \t by default */
+	char	   *null_print;		/* how to print NULLs, `\N' by default */
+} CopyStmt;
 
 /* ----------------------
- *		Unlisten Statement
+ *		Create Table Statement
+ *
+ * NOTE: in the raw gram.y output, ColumnDef, Constraint, and FkConstraint
+ * nodes are intermixed in tableElts, and constraints is NIL.  After parse
+ * analysis, tableElts contains just ColumnDefs, and constraints contains
+ * just Constraint nodes (in fact, only CONSTR_CHECK nodes, in the present
+ * implementation).
  * ----------------------
  */
-typedef struct UnlistenStmt
+typedef struct CreateStmt
 {
 	NodeTag		type;
-	char	   *relname;		/* relation to unlisten on */
-} UnlistenStmt;
+	char	   *relname;		/* name of relation to create */
+	List	   *tableElts;		/* column definitions (list of ColumnDef) */
+	List	   *inhRelnames;	/* relations to inherit from (list of
+								 * T_String Values) */
+	List	   *constraints;	/* constraints (list of Constraint nodes) */
+	bool		istemp;			/* is this a temp table? */
+	bool		hasoids;		/* should it have OIDs? */
+} CreateStmt;
 
-/* ----------------------
- *		{Begin|Abort|End} Transaction Statement
- * ----------------------
+/* ----------
+ * Definitions for plain (non-FOREIGN KEY) constraints in CreateStmt
+ *
+ * XXX probably these ought to be unified with FkConstraints at some point?
+ *
+ * For constraints that use expressions (CONSTR_DEFAULT, CONSTR_CHECK)
+ * we may have the expression in either "raw" form (an untransformed
+ * parse tree) or "cooked" form (the nodeToString representation of
+ * an executable expression tree), depending on how this Constraint
+ * node was created (by parsing, or by inheritance from an existing
+ * relation).  We should never have both in the same node!
+ *
+ * Constraint attributes (DEFERRABLE etc) are initially represented as
+ * separate Constraint nodes for simplicity of parsing.  analyze.c makes
+ * a pass through the constraints list to attach the info to the appropriate
+ * FkConstraint node (and, perhaps, someday to other kinds of constraints).
+ * ----------
  */
-typedef struct TransactionStmt
+
+typedef enum ConstrType			/* types of constraints */
+{
+	CONSTR_NULL,				/* not SQL92, but a lot of people expect
+								 * it */
+	CONSTR_NOTNULL,
+	CONSTR_DEFAULT,
+	CONSTR_CHECK,
+	CONSTR_PRIMARY,
+	CONSTR_UNIQUE,
+	CONSTR_ATTR_DEFERRABLE,		/* attributes for previous constraint node */
+	CONSTR_ATTR_NOT_DEFERRABLE,
+	CONSTR_ATTR_DEFERRED,
+	CONSTR_ATTR_IMMEDIATE
+} ConstrType;
+
+typedef struct Constraint
 {
 	NodeTag		type;
-	int			command;		/* BEGIN|END|ABORT */
-} TransactionStmt;
+	ConstrType	contype;
+	char	   *name;			/* name, or NULL if unnamed */
+	Node	   *raw_expr;		/* expr, as untransformed parse tree */
+	char	   *cooked_expr;	/* expr, as nodeToString representation */
+	List	   *keys;			/* Ident nodes naming referenced column(s) */
+} Constraint;
 
-/* ----------------------
- *		Create View Statement
- * ----------------------
+/* ----------
+ * Definitions for FOREIGN KEY constraints in CreateStmt
+ * ----------
  */
-typedef struct ViewStmt
+#define FKCONSTR_ON_KEY_NOACTION		0x0000
+#define FKCONSTR_ON_KEY_RESTRICT		0x0001
+#define FKCONSTR_ON_KEY_CASCADE			0x0002
+#define FKCONSTR_ON_KEY_SETNULL			0x0004
+#define FKCONSTR_ON_KEY_SETDEFAULT		0x0008
+
+#define FKCONSTR_ON_DELETE_MASK			0x000F
+#define FKCONSTR_ON_DELETE_SHIFT		0
+
+#define FKCONSTR_ON_UPDATE_MASK			0x00F0
+#define FKCONSTR_ON_UPDATE_SHIFT		4
+
+typedef struct FkConstraint
 {
 	NodeTag		type;
-	char	   *viewname;		/* name of the view */
-	List	   *aliases;		/* target column names */
-	Query	   *query;			/* the SQL statement */
-} ViewStmt;
+	char	   *constr_name;	/* Constraint name */
+	char	   *pktable_name;	/* Primary key table name */
+	List	   *fk_attrs;		/* Attributes of foreign key */
+	List	   *pk_attrs;		/* Corresponding attrs in PK table */
+	char	   *match_type;		/* FULL or PARTIAL */
+	int32		actions;		/* ON DELETE/UPDATE actions */
+	bool		deferrable;		/* DEFERRABLE */
+	bool		initdeferred;	/* INITIALLY DEFERRED */
+} FkConstraint;
 
 /* ----------------------
- *		Load Statement
+ *		Create/Drop TRIGGER Statements
  * ----------------------
  */
-typedef struct LoadStmt
+
+typedef struct CreateTrigStmt
 {
 	NodeTag		type;
-	char	   *filename;		/* file to load */
-} LoadStmt;
+	char	   *trigname;		/* TRIGGER' name */
+	char	   *relname;		/* triggered relation */
+	char	   *funcname;		/* function to call (or NULL) */
+	List	   *args;			/* list of (T_String) Values or NULL */
+	bool		before;			/* BEFORE/AFTER */
+	bool		row;			/* ROW/STATEMENT */
+	char		actions[4];		/* Insert, Update, Delete */
+	char	   *lang;			/* currently not used, always NULL */
+	char	   *text;			/* AS 'text' */
+	List	   *attr;			/* UPDATE OF a, b,... (NI) or NULL */
+	char	   *when;			/* WHEN 'a > 10 ...' (NI) or NULL */
 
-/* ----------------------
- *		Createdb Statement
- * ----------------------
- */
-typedef struct CreatedbStmt
+	/* The following are used for referential */
+	/* integrity constraint triggers */
+	bool		isconstraint;	/* This is an RI trigger */
+	bool		deferrable;		/* [NOT] DEFERRABLE */
+	bool		initdeferred;	/* INITIALLY {DEFERRED|IMMEDIATE} */
+	char	   *constrrelname;	/* opposite relation */
+} CreateTrigStmt;
+
+typedef struct DropTrigStmt
 {
 	NodeTag		type;
-	char	   *dbname;			/* name of database to create */
-	char	   *dbowner;		/* name of owner (NULL = default) */
-	char	   *dbpath;			/* location of database (NULL = default) */
-	char	   *dbtemplate;		/* template to use (NULL = default) */
-	int			encoding;		/* MULTIBYTE encoding (-1 = use default) */
-} CreatedbStmt;
+	char	   *trigname;		/* TRIGGER' name */
+	char	   *relname;		/* triggered relation */
+} DropTrigStmt;
 
 /* ----------------------
- *	Alter Database
+ *		Create/Drop PROCEDURAL LANGUAGE Statement
  * ----------------------
  */
-typedef struct AlterDatabaseSetStmt
+typedef struct CreatePLangStmt
 {
 	NodeTag		type;
-	char	   *dbname;
-	char	   *variable;
-	List	   *value;
-} AlterDatabaseSetStmt;
+	char	   *plname;			/* PL name */
+	char	   *plhandler;		/* PL call handler function */
+	char	   *plcompiler;		/* lancompiler text */
+	bool		pltrusted;		/* PL is trusted */
+} CreatePLangStmt;
 
-/* ----------------------
- *		Dropdb Statement
- * ----------------------
- */
-typedef struct DropdbStmt
+typedef struct DropPLangStmt
 {
 	NodeTag		type;
-	char	   *dbname;			/* database to drop */
-} DropdbStmt;
+	char	   *plname;			/* PL name */
+} DropPLangStmt;
 
 /* ----------------------
- *		Cluster Statement (support pbrown's cluster index implementation)
+ *	Create/Alter/Drop User Statements
  * ----------------------
  */
-typedef struct ClusterStmt
+typedef struct CreateUserStmt
 {
 	NodeTag		type;
-	char	   *relname;		/* relation being indexed */
-	char	   *indexname;		/* original index defined */
-} ClusterStmt;
+	char	   *user;			/* PostgreSQL user login name */
+	List	   *options;		/* List of DefElem nodes */
+} CreateUserStmt;
 
-/* ----------------------
- *		Vacuum and Analyze Statements
- *
- * Even though these are nominally two statements, it's convenient to use
- * just one node type for both.
- * ----------------------
- */
-typedef struct VacuumStmt
+typedef struct AlterUserStmt
 {
 	NodeTag		type;
-	bool		vacuum;			/* do VACUUM step */
-	bool		full;			/* do FULL (non-concurrent) vacuum */
-	bool		analyze;		/* do ANALYZE step */
-	bool		freeze;			/* early-freeze option */
-	bool		verbose;		/* print progress info */
-	char	   *vacrel;			/* name of single table to process, or
-								 * NULL */
-	List	   *va_cols;		/* list of column names, or NIL for all */
-} VacuumStmt;
+	char	   *user;			/* PostgreSQL user login name */
+	List	   *options;		/* List of DefElem nodes */
+} AlterUserStmt;
 
-/* ----------------------
- *		Explain Statement
- * ----------------------
- */
-typedef struct ExplainStmt
+typedef struct AlterUserSetStmt
 {
 	NodeTag		type;
-	Query	   *query;			/* the query */
-	bool		verbose;		/* print plan info */
-	bool		analyze;		/* get statistics by executing plan */
-} ExplainStmt;
+	char	   *user;
+	char	   *variable;
+	List	   *value;
+} AlterUserSetStmt;
 
-/* ----------------------
- * Checkpoint Statement
- * ----------------------
- */
-typedef struct CheckPointStmt
+typedef struct DropUserStmt
 {
 	NodeTag		type;
-} CheckPointStmt;
+	List	   *users;			/* List of users to remove */
+} DropUserStmt;
 
 /* ----------------------
- * Set Statement
+ *		Create/Alter/Drop Group Statements
  * ----------------------
  */
-
-typedef struct VariableSetStmt
+typedef struct CreateGroupStmt
 {
 	NodeTag		type;
-	char	   *name;
-	List	   *args;
-} VariableSetStmt;
+	char	   *name;			/* name of the new group */
+	List	   *options;		/* List of DefElem nodes */
+} CreateGroupStmt;
 
-/* ----------------------
- * Show Statement
- * ----------------------
- */
+typedef struct AlterGroupStmt
+{
+	NodeTag		type;
+	char	   *name;			/* name of group to alter */
+	int			action;			/* +1 = add, -1 = drop user */
+	List	   *listUsers;		/* list of users to add/drop */
+} AlterGroupStmt;
 
-typedef struct VariableShowStmt
+typedef struct DropGroupStmt
 {
 	NodeTag		type;
 	char	   *name;
-} VariableShowStmt;
+} DropGroupStmt;
 
 /* ----------------------
- * Reset Statement
+ *		Create SEQUENCE Statement
  * ----------------------
  */
 
-typedef struct VariableResetStmt
+typedef struct CreateSeqStmt
 {
 	NodeTag		type;
-	char	   *name;
-} VariableResetStmt;
+	char	   *seqname;		/* the relation to create */
+	bool		istemp;			/* is this a temp sequence? */
+	List	   *options;
+} CreateSeqStmt;
 
 /* ----------------------
- *		LOCK Statement
+ *		Create Version Statement
  * ----------------------
  */
-typedef struct LockStmt
+typedef struct VersionStmt
 {
 	NodeTag		type;
-	List	   *rellist;		/* relations to lock */
-	int			mode;			/* lock mode */
-} LockStmt;
-
+	char	   *relname;		/* the new relation */
+	int			direction;		/* FORWARD | BACKWARD */
+	char	   *fromRelname;	/* relation to create a version */
+	char	   *date;			/* date of the snapshot */
+} VersionStmt;
 
 /* ----------------------
- *		SET CONSTRAINTS Statement
+ *		Create {Operator|Type|Aggregate} Statement
  * ----------------------
  */
-typedef struct ConstraintsSetStmt
+typedef struct DefineStmt
 {
 	NodeTag		type;
-	List	   *constraints;
-	bool		deferred;
-} ConstraintsSetStmt;
+	int			defType;		/* OPERATOR|P_TYPE|AGGREGATE */
+	char	   *defname;
+	List	   *definition;		/* a list of DefElem */
+} DefineStmt;
 
 /* ----------------------
- *		REINDEX Statement
+ *		Drop Table|Sequence|View|Index|Rule|Type Statement
  * ----------------------
  */
-typedef struct ReindexStmt
-{
-	NodeTag		type;
-	int			reindexType;	/* INDEX|TABLE|DATABASE */
-	const char *name;			/* name to reindex */
-	bool		force;
-	bool		all;
-} ReindexStmt;
 
+#define DROP_TABLE	  1
+#define DROP_SEQUENCE 2
+#define DROP_VIEW	  3
+#define DROP_INDEX	  4
+#define DROP_RULE	  5
+#define DROP_TYPE_P   6
 
-/*****************************************************************************
- *		Optimizable Statements
- *****************************************************************************/
+typedef struct DropStmt
+{
+	NodeTag		type;
+	List	   *names;
+	int			removeType;
+} DropStmt;
 
 /* ----------------------
- *		Insert Statement
+ *				Truncate Table Statement
  * ----------------------
  */
-typedef struct InsertStmt
+typedef struct TruncateStmt
 {
 	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;
+	char	   *relName;		/* relation to be truncated */
+} TruncateStmt;
 
 /* ----------------------
- *		Delete Statement
+ *				Comment On Statement
  * ----------------------
  */
-typedef struct DeleteStmt
+typedef struct CommentStmt
 {
 	NodeTag		type;
-	char	   *relname;		/* relation to delete from */
-	Node	   *whereClause;	/* qualifications */
-	InhOption	inhOpt;			/* recursively act on children? */
-} DeleteStmt;
+	int			objtype;		/* Object's type */
+	char	   *objname;		/* Name of the object */
+	char	   *objproperty;	/* Property Id (such as column) */
+	List	   *objlist;		/* Arguments for VAL objects */
+	char	   *comment;		/* The comment to insert */
+} CommentStmt;
 
 /* ----------------------
- *		Update Statement
+ *		Begin Recipe Statement
  * ----------------------
  */
-typedef struct UpdateStmt
+typedef struct RecipeStmt
 {
 	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;
+	char	   *recipeName;		/* name of the recipe */
+} RecipeStmt;
 
 /* ----------------------
- *		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.
+ *		Fetch Statement
  * ----------------------
  */
-typedef enum SetOperation
-{
-	SETOP_NONE = 0,
-	SETOP_UNION,
-	SETOP_INTERSECT,
-	SETOP_EXCEPT
-} SetOperation;
-
-typedef struct SelectStmt
+typedef struct FetchStmt
 {
 	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;
+	int			direction;		/* FORWARD or BACKWARD */
+	int			howMany;		/* amount to fetch ("ALL" --> 0) */
+	char	   *portalname;		/* name of portal (cursor) */
+	bool		ismove;			/* TRUE if MOVE */
+} FetchStmt;
 
 /* ----------------------
- *		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.
+ *		Create Index Statement
  * ----------------------
  */
-typedef struct SetOperationStmt
+typedef struct IndexStmt
 {
 	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.
- ****************************************************************************/
+	char	   *idxname;		/* name of the index */
+	char	   *relname;		/* name of relation to index on */
+	char	   *accessMethod;	/* name of access method (eg. btree) */
+	List	   *indexParams;	/* a list of IndexElem */
+	Node	   *whereClause;	/* qualification (partial-index predicate) */
+	List	   *rangetable;		/* range table for qual, filled in by
+								 * transformStmt() */
+	bool		unique;			/* is index unique? */
+	bool		primary;		/* is index on primary key? */
+} IndexStmt;
 
-/*
- * TypeName - specifies a type in definitions
+/* ----------------------
+ *		Create Function Statement
+ * ----------------------
  */
-typedef struct TypeName
+typedef struct ProcedureStmt
 {
 	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;
+	bool		replace;		/* T => replace if already exists */
+	char	   *funcname;		/* name of function to create */
+	List	   *argTypes;		/* list of argument types (TypeName nodes) */
+	Node	   *returnType;		/* the return type (a TypeName node) */
+	List	   *withClause;		/* a list of DefElem */
+	List	   *as;				/* definition of function body */
+	char	   *language;		/* C, SQL, etc */
+} ProcedureStmt;
 
-/*
- * ParamNo - specifies a parameter reference
+/* ----------------------
+ *		Drop Aggregate Statement
+ * ----------------------
  */
-typedef struct ParamNo
+typedef struct RemoveAggrStmt
 {
 	NodeTag		type;
-	int			number;			/* the number of the parameter */
-	TypeName   *typename;		/* the typecast */
-	List	   *indirection;	/* array references */
-} ParamNo;
+	char	   *aggname;		/* aggregate to drop */
+	Node	   *aggtype;		/* TypeName for input datatype, or NULL */
+} RemoveAggrStmt;
 
-/*
- * A_Expr - binary expressions
+/* ----------------------
+ *		Drop Function Statement
+ * ----------------------
  */
-typedef struct A_Expr
+typedef struct RemoveFuncStmt
 {
 	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;
+	char	   *funcname;		/* function to drop */
+	List	   *args;			/* types of the arguments */
+} RemoveFuncStmt;
 
-/*
- * Attr -
- *	  specifies an Attribute (ie. a Column); could have nested dots or
- *	  array references.
- *
+/* ----------------------
+ *		Drop Operator Statement
+ * ----------------------
  */
-typedef struct Attr
+typedef struct RemoveOperStmt
 {
 	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;
+	char	   *opname;			/* operator to drop */
+	List	   *args;			/* types of the arguments */
+} RemoveOperStmt;
 
-/*
- * A_Const - a constant expression
+/* ----------------------
+ *		Alter Table Statement
+ * ----------------------
  */
-typedef struct A_Const
+typedef struct RenameStmt
 {
 	NodeTag		type;
-	Value		val;			/* the value (with the tag) */
-	TypeName   *typename;		/* typecast */
-} A_Const;
+	char	   *relname;		/* relation to be altered */
+	InhOption	inhOpt;			/* recursively act on children? */
+	char	   *column;			/* if NULL, rename the relation name to
+								 * the new name. Otherwise, rename this
+								 * column name. */
+	char	   *newname;		/* the new name */
+} RenameStmt;
 
-/*
- * 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.
+/* ----------------------
+ *		Create Rule Statement
+ * ----------------------
  */
-typedef struct TypeCast
+typedef struct RuleStmt
 {
 	NodeTag		type;
-	Node	   *arg;			/* the expression being casted */
-	TypeName   *typename;		/* the target type */
-} TypeCast;
+	char	   *rulename;		/* name of the rule */
+	Node	   *whereClause;	/* qualifications */
+	CmdType		event;			/* RETRIEVE */
+	struct Attr *object;		/* object affected */
+	bool		instead;		/* is a 'do instead'? */
+	List	   *actions;		/* the action statements */
+} RuleStmt;
 
-/*
- * CaseExpr - a CASE expression
+/* ----------------------
+ *		Notify Statement
+ * ----------------------
  */
-typedef struct CaseExpr
+typedef struct NotifyStmt
 {
 	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;
+	char	   *relname;		/* relation to notify */
+} NotifyStmt;
 
-/*
- * CaseWhen - an argument to a CASE expression
+/* ----------------------
+ *		Listen Statement
+ * ----------------------
  */
-typedef struct CaseWhen
+typedef struct ListenStmt
 {
 	NodeTag		type;
-	Node	   *expr;			/* comparison expression */
-	Node	   *result;			/* substitution result */
-} CaseWhen;
+	char	   *relname;		/* relation to listen on */
+} ListenStmt;
 
-/* ----------------
- * 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.
- * ----------------
+/* ----------------------
+ *		Unlisten Statement
+ * ----------------------
  */
-
-typedef enum NullTestType
+typedef struct UnlistenStmt
 {
-	IS_NULL, IS_NOT_NULL
-} NullTestType;
+	NodeTag		type;
+	char	   *relname;		/* relation to unlisten on */
+} UnlistenStmt;
 
-typedef struct NullTest
+/* ----------------------
+ *		{Begin|Abort|End} Transaction Statement
+ * ----------------------
+ */
+typedef struct TransactionStmt
 {
 	NodeTag		type;
-	Node	   *arg;			/* input expression */
-	NullTestType nulltesttype;	/* IS NULL, IS NOT NULL */
-} NullTest;
+	int			command;		/* BEGIN|END|ABORT */
+} TransactionStmt;
 
-/* ----------------
- * 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.
- * ----------------
+/* ----------------------
+ *		Create View Statement
+ * ----------------------
  */
-
-typedef enum BoolTestType
+typedef struct ViewStmt
 {
-	IS_TRUE, IS_NOT_TRUE, IS_FALSE, IS_NOT_FALSE, IS_UNKNOWN, IS_NOT_UNKNOWN
-} BoolTestType;
+	NodeTag		type;
+	char	   *viewname;		/* name of the view */
+	List	   *aliases;		/* target column names */
+	Query	   *query;			/* the SQL statement */
+} ViewStmt;
 
-typedef struct BooleanTest
+/* ----------------------
+ *		Load Statement
+ * ----------------------
+ */
+typedef struct LoadStmt
 {
 	NodeTag		type;
-	Node	   *arg;			/* input expression */
-	BoolTestType booltesttype;	/* test type */
-} BooleanTest;
+	char	   *filename;		/* file to load */
+} LoadStmt;
 
-/*
- * 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.
+/* ----------------------
+ *		Createdb Statement
+ * ----------------------
  */
-typedef struct ColumnDef
+typedef struct CreatedbStmt
 {
 	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;
+	char	   *dbname;			/* name of database to create */
+	char	   *dbowner;		/* name of owner (NULL = default) */
+	char	   *dbpath;			/* location of database (NULL = default) */
+	char	   *dbtemplate;		/* template to use (NULL = default) */
+	int			encoding;		/* MULTIBYTE encoding (-1 = use default) */
+} CreatedbStmt;
 
-/*
- * 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).
+/* ----------------------
+ *	Alter Database
+ * ----------------------
  */
-typedef struct Ident
+typedef struct AlterDatabaseSetStmt
 {
 	NodeTag		type;
-	char	   *name;			/* its name */
-	List	   *indirection;	/* array references */
-	bool		isRel;			/* is this a relation or a column? */
-} Ident;
+	char	   *dbname;
+	char	   *variable;
+	List	   *value;
+} AlterDatabaseSetStmt;
 
-/*
- * 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.
+/* ----------------------
+ *		Dropdb Statement
+ * ----------------------
  */
-typedef struct FuncCall
+typedef struct DropdbStmt
 {
 	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;
+	char	   *dbname;			/* database to drop */
+} DropdbStmt;
 
-/*
- * A_Indices - array reference or bounds ([lidx:uidx] or [uidx])
+/* ----------------------
+ *		Cluster Statement (support pbrown's cluster index implementation)
+ * ----------------------
  */
-typedef struct A_Indices
+typedef struct ClusterStmt
 {
 	NodeTag		type;
-	Node	   *lidx;			/* could be NULL */
-	Node	   *uidx;
-} A_Indices;
+	char	   *relname;		/* relation being indexed */
+	char	   *indexname;		/* original index defined */
+} ClusterStmt;
 
-/*
- * 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.
+/* ----------------------
+ *		Vacuum and Analyze Statements
  *
- * 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.
+ * Even though these are nominally two statements, it's convenient to use
+ * just one node type for both.
+ * ----------------------
  */
-typedef struct ResTarget
+typedef struct VacuumStmt
 {
 	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;
+	bool		vacuum;			/* do VACUUM step */
+	bool		full;			/* do FULL (non-concurrent) vacuum */
+	bool		analyze;		/* do ANALYZE step */
+	bool		freeze;			/* early-freeze option */
+	bool		verbose;		/* print progress info */
+	char	   *vacrel;			/* name of single table to process, or
+								 * NULL */
+	List	   *va_cols;		/* list of column names, or NIL for all */
+} VacuumStmt;
 
-/*
- * SortGroupBy - for ORDER BY clause
+/* ----------------------
+ *		Explain Statement
+ * ----------------------
  */
-typedef struct SortGroupBy
+typedef struct ExplainStmt
 {
 	NodeTag		type;
-	char	   *useOp;			/* operator to use */
-	Node	   *node;			/* Expression  */
-} SortGroupBy;
+	Query	   *query;			/* the query */
+	bool		verbose;		/* print plan info */
+	bool		analyze;		/* get statistics by executing plan */
+} ExplainStmt;
 
-/*
- * RangeVar - range variable, used in FROM clauses
+/* ----------------------
+ * Checkpoint Statement
+ * ----------------------
  */
-typedef struct RangeVar
+typedef struct CheckPointStmt
 {
 	NodeTag		type;
-	char	   *relname;		/* the relation name */
-	InhOption	inhOpt;			/* expand rel by inheritance? */
-	Attr	   *name;			/* optional table alias & column aliases */
-} RangeVar;
+} CheckPointStmt;
 
-/*
- * RangeSubselect - subquery appearing in a FROM clause
+/* ----------------------
+ * Set Statement
+ * ----------------------
  */
-typedef struct RangeSubselect
+
+typedef struct VariableSetStmt
 {
 	NodeTag		type;
-	Node	   *subquery;		/* the untransformed sub-select clause */
-	Attr	   *name;			/* table alias & optional column aliases */
-} RangeSubselect;
+	char	   *name;
+	List	   *args;
+} VariableSetStmt;
 
-/*
- * 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.
+/* ----------------------
+ * Show Statement
+ * ----------------------
  */
-typedef struct IndexElem
+
+typedef struct VariableShowStmt
 {
 	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;
+	char	   *name;
+} VariableShowStmt;
 
-/*
- * DefElem -
- *	  a definition (used in definition lists in the form of defname = arg)
+/* ----------------------
+ * Reset Statement
+ * ----------------------
  */
-typedef struct DefElem
+
+typedef struct VariableResetStmt
 {
 	NodeTag		type;
-	char	   *defname;
-	Node	   *arg;			/* a (Value *) or a (TypeName *) */
-} DefElem;
-
-
-/****************************************************************************
- *	Nodes for a Query tree
- ****************************************************************************/
+	char	   *name;
+} VariableResetStmt;
 
-/*
- * 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) ...)
+/* ----------------------
+ *		LOCK Statement
+ * ----------------------
  */
-typedef struct TargetEntry
+typedef struct LockStmt
 {
 	NodeTag		type;
-	Resdom	   *resdom;			/* fjoin overload this to be a list?? */
-	Fjoin	   *fjoin;
-	Node	   *expr;
-} TargetEntry;
+	List	   *rellist;		/* relations to lock */
+	int			mode;			/* lock mode */
+} LockStmt;
 
-/*--------------------
- * 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.)
- *--------------------
+/* ----------------------
+ *		SET CONSTRAINTS Statement
+ * ----------------------
  */
-typedef struct RangeTblEntry
+typedef struct ConstraintsSetStmt
 {
 	NodeTag		type;
+	List	   *constraints;	/* List of names as Value strings */
+	bool		deferred;
+} ConstraintsSetStmt;
 
-	/*
-	 * 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.
+/* ----------------------
+ *		REINDEX Statement
+ * ----------------------
  */
-typedef struct SortClause
+typedef struct ReindexStmt
 {
 	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;
+	int			reindexType;	/* INDEX|TABLE|DATABASE */
+	const char *name;			/* name to reindex */
+	bool		force;
+	bool		all;
+} ReindexStmt;
 
 #endif   /* PARSENODES_H */
-- 
GitLab