/*-------------------------------------------------------------------------
 *
 * parsenodes.h--
 *    definitions for parse tree nodes
 *
 *
 * Copyright (c) 1994, Regents of the University of California
 *
 * $Id: parsenodes.h,v 1.9 1997/01/13 03:45:02 momjian Exp $
 *
 *-------------------------------------------------------------------------
 */
#ifndef	PARSENODES_H
#define	PARSENODES_H

#include <utils/tqual.h>
#include <nodes/primnodes.h>

/*****************************************************************************
 *  Query Tree 
 *****************************************************************************/

/*
 * Query -
 *    all statments are turned into a Query tree (via transformStmt)
 *    for further processing by the optimizer
 *    utility statements (i.e. non-optimizable statements)
 *    have the *utilityStmt field set.
 *
 * we need the isPortal flag because portal names can be null too; can
 * get rid of it if we support CURSOR as a commandType.
 *
 */
typedef struct Query {
    NodeTag 	type;
    
    CmdType 	commandType;	/* select|insert|update|delete|utility */
    
    Node  	*utilityStmt;   /* non-null if this is a non-optimizable
				   statement */
    
    int		resultRelation;	/* target relation (index to rtable) */
    char	*into;		/* portal (cursor) name */
    bool	isPortal;	/* is this a retrieve into portal? */
    bool	isBinary;	/* binary portal? */
    
    char  	*uniqueFlag;	/* NULL, '*', or Unique attribute name */
    List	*sortClause;	/* a list of SortClause's */
    
    List	*rtable;	/* list of range table entries */
    List	*targetList;	/* target list (of TargetEntry) */
    Node	*qual;		/* qualifications */

    List	*groupClause;	/* list of columns to specified in GROUP BY */
    Node	*havingQual;	/* qualification of each group */

    int		qry_numAgg;	/* number of aggregates in the target list */
    Aggreg	**qry_aggs;	/* the aggregates */
    
    /* internal to planner */
    List *base_relation_list_;	/* base relation list */
    List *join_relation_list_;	/* list of relations generated by joins */
    bool  query_is_archival_;	/* archival query flag */
} Query;


/*****************************************************************************
 *	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.
 *****************************************************************************/

/* ----------------------
 *	Add Column Statement
 * ----------------------
 */
typedef struct AddAttrStmt {
    NodeTag		type;
    char		*relname;	/* the relation to add attr */
    bool		inh;		/* add recursively to children? */
    struct ColumnDef	*colDef;	/* the attribute definition */
} AddAttrStmt;

/* ----------------------
 *	Change ACL Statement
 * ----------------------
 */
typedef struct ChangeACLStmt {
    NodeTag		type;
    struct AclItem	*aclitem;
    unsigned		modechg;
    List		*relNames;
} ChangeACLStmt;

/* ----------------------
 *	Close Portal Statement
 * ----------------------
 */
typedef struct ClosePortalStmt {
    NodeTag		type;
    char		*portalname;	/* name of the portal (cursor) */
} ClosePortalStmt;

/* ----------------------
 *	Copy Statement
 * ----------------------
 */
typedef struct CopyStmt {
    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*/
} CopyStmt;

/* ----------------------
 *	Create Table Statement
 * ----------------------
 */
typedef enum ArchType {
    ARCH_NONE, ARCH_LIGHT, ARCH_HEAVY	/* archive mode */
} ArchType;

typedef struct CreateStmt {
    NodeTag		type;
    char		*relname;	/* the relation to create */
    List		*tableElts;	/* column definitions
					   list of ColumnDef */
    List		*inhRelnames;	/* relations to inherit from
					   list of Value (string) */
    ArchType		archiveType;	/* archive mode (ARCH_NONE if none */
    int			location;	/* smgrid (-1 if none) */
    int			archiveLoc;	/* smgrid (-1 if none) */
} CreateStmt;

/* ----------------------
 *	Create Version Statement
 * ----------------------
 */
typedef struct VersionStmt {
    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;

/* ----------------------
 *	Create {Operator|Type|Aggregate} Statement
 * ----------------------
 */
typedef struct DefineStmt {
    NodeTag		type;
    int			defType;	/* OPERATOR|P_TYPE|AGGREGATE*/
    char		*defname;
    List		*definition;	/* a list of DefElem */
} DefineStmt;

/* ----------------------
 *	Drop Table Statement
 * ----------------------
 */
typedef struct DestroyStmt {
    NodeTag		type;
    List		*relNames;	/* relations to be dropped */
} DestroyStmt;

/* ----------------------
 *	Extend Index Statement
 * ----------------------
 */
typedef struct ExtendStmt {
    NodeTag		type;
    char		*idxname;	/* name of the index */
    Node		*whereClause;	/* qualifications */
    List		*rangetable;	/* range table, filled in
					   by transformStmt() */
} ExtendStmt;

/* ----------------------
 *	Begin Recipe Statement
 * ----------------------
 */
typedef struct RecipeStmt {
    NodeTag		type;
    char		*recipeName;	/* name of the recipe*/
} RecipeStmt;

/* ----------------------
 *	Fetch Statement
 * ----------------------
 */
typedef struct FetchStmt {
    NodeTag		type;
    int			direction;	/* FORWARD or BACKWARD */
    int		        howMany;	/* amount to fetch ("ALL" --> 0) */
    char		*portalname;	/* name of portal (cursor) */
} FetchStmt;

/* ----------------------
 *	Create Index Statement
 * ----------------------
 */
typedef struct IndexStmt {
    NodeTag		type;
    char		*idxname;	/* name of the index */
    char		*relname;	/* name of relation to index on */
    char		*accessMethod;	/* name of acess methood (eg. btree) */
    List		*indexParams;	/* a list of IndexElem */
    List		*withClause;	/* a list of ParamString */
    Node		*whereClause;	/* qualifications */
    List		*rangetable;	/* range table, filled in
					   by transformStmt() */
    bool                *lossy;         /* is index lossy? */
    bool                unique;         /* is index unique? */
} IndexStmt;

/* ----------------------
 *	Move Statement (Not implemented)
 * ----------------------
 */
typedef struct MoveStmt {
    NodeTag		type;
    int			direction;	/* FORWARD or BACKWARD */
    bool		to;
    int			where;
    char		*portalname;
} MoveStmt;

/* ----------------------
 *	Create Function Statement
 * ----------------------
 */
typedef struct ProcedureStmt {
    NodeTag		type;
    char		*funcname;	/* name of function to create */
    List		*defArgs;	/* list of definitions
					   a list of strings (as Value *) */
    Node		*returnType;	/* the return type (as a string or
					   a TypeName (ie.setof) */
    List		*withClause;	/* a list of ParamString */
    char		*as;		/* the SQL statement or filename */
    char		*language;	/* C or SQL */
} ProcedureStmt;

/* ----------------------
 *	Purge Statement
 * ----------------------
 */
typedef struct PurgeStmt {
    NodeTag		type;
    char		*relname;	/* relation to purge */
    char		*beforeDate;	/* purge before this date */
    char		*afterDate;	/* purge after this date */
} PurgeStmt;

/* ----------------------
 *	Drop Function Statement
 * ----------------------
 */
typedef struct RemoveFuncStmt {
    NodeTag		type;
    char		*funcname;	/* function to drop */
    List		*args;		/* types of the arguments */
} RemoveFuncStmt;

/* ----------------------
 *	Drop Operator Statement
 * ----------------------
 */
typedef struct RemoveOperStmt {
    NodeTag		type;
    char		*opname;	/* operator to drop */
    List		*args;		/* types of the arguments */
} RemoveOperStmt;

/* ----------------------
 *	Drop {Aggregate|Type|Index|Rule|View} Statement
 * ----------------------
 */
typedef struct RemoveStmt {
    NodeTag		type;
    int 		removeType;	/* AGGREGATE|P_TYPE|INDEX|RULE|VIEW */
    char		*name;		/* name to drop */
} RemoveStmt;

/* ----------------------
 *	Alter Table Statement
 * ----------------------
 */
typedef struct RenameStmt {
    NodeTag		type;
    char		*relname;	/* relation to be altered */
    bool		inh;		/* recursively alter children? */
    char		*column;	/* if NULL, rename the relation name
					   to the new name. Otherwise, rename
					   this column name. */
    char		*newname;	/* the new name */
} RenameStmt;

/* ----------------------
 *	Create Rule Statement
 * ----------------------
 */
typedef struct RuleStmt {
    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;

/* ----------------------
 *	Notify Statement
 * ----------------------
 */
typedef struct NotifyStmt {
    NodeTag		type;
    char		*relname;	/* relation to notify */
} NotifyStmt;

/* ----------------------
 *	Listen Statement
 * ----------------------
 */
typedef struct ListenStmt {
    NodeTag		type;
    char		*relname;	/* relation to listen on */
} ListenStmt;

/* ----------------------
 *	{Begin|Abort|End} Transaction Statement
 * ----------------------
 */
typedef struct TransactionStmt {
    NodeTag		type;
    int			command;	/* BEGIN|END|ABORT */
} TransactionStmt;

/* ----------------------
 *	Create View Statement
 * ----------------------
 */
typedef struct ViewStmt {
    NodeTag		type;
    char		*viewname;	/* name of the view */
    Query		*query;		/* the SQL statement */
} ViewStmt;

/* ----------------------
 *	Load Statement
 * ----------------------
 */
typedef struct LoadStmt {
    NodeTag		type;
    char		*filename;	/* file to load */
} LoadStmt;

/* ----------------------
 *	Createdb Statement
 * ----------------------
 */
typedef struct CreatedbStmt {
    NodeTag		type;
    char		*dbname;	/* database to create */
} CreatedbStmt;

/* ----------------------
 *	Destroydb Statement
 * ----------------------
 */
typedef struct DestroydbStmt {
    NodeTag		type;
    char		*dbname;	/* database to drop */
} DestroydbStmt;

/* ----------------------
 *	Cluster Statement (support pbrown's cluster index implementation)
 * ----------------------
 */
typedef struct ClusterStmt {
    NodeTag		type;
    char		*relname;	/* relation being indexed */
    char		*indexname;	/* original index defined */
} ClusterStmt;

/* ----------------------
 *	Vacuum Statement
 * ----------------------
 */
typedef struct VacuumStmt {
    NodeTag		type;
    bool		verbose;	/* print status info */
    char		*vacrel;	/* table to vacuum */
} VacuumStmt;

/* ----------------------
 *	Explain Statement
 * ----------------------
 */
typedef struct ExplainStmt {
    NodeTag		type;
    Query		*query;		/* the query */
    List		*options;
} ExplainStmt;


/*****************************************************************************
 *	Optimizable Statements
 *****************************************************************************/

/* ----------------------
 *	Insert Statement
 * ----------------------
 */
typedef struct AppendStmt {
    NodeTag		type;
    char		*relname;	/* relation to insert into */
    List		*cols;		/* names of the columns */
    List		*targetList;	/* the target list (of ResTarget) */
    List		*fromClause;	/* the from clause */
    Node		*whereClause;	/* qualifications */
} AppendStmt;

/* ----------------------
 *	Delete Statement
 * ----------------------
 */
typedef struct DeleteStmt {
    NodeTag		type;
    char		*relname;	/* relation to delete from */
    Node		*whereClause;	/* qualifications */
} DeleteStmt;

/* ----------------------
 *	Update Statement
 * ----------------------
 */
typedef struct ReplaceStmt {
    NodeTag		type;
    char		*relname;	/* relation to update */
    List		*targetList;	/* the target list (of ResTarget) */
    Node		*whereClause;	/* qualifications */
    List		*fromClause;	/* the from clause */
} ReplaceStmt;

/* ----------------------
 *	Create Cursor Statement
 * ----------------------
 */
typedef struct CursorStmt {
    NodeTag		type;
    char		*portalname;	/* the portal (cursor) to create */
    bool		binary;		/* a binary (internal) portal? */
    char		*unique;	/* NULL, "*", or unique attribute name */
    List		*targetList;	/* the target list (of ResTarget) */
    List		*fromClause;	/* the from clause */
    Node		*whereClause;	/* qualifications */
    List              *groupClause;   /* group by clause */
    List		*sortClause;	/* sort clause (a list of SortGroupBy's) */
} CursorStmt;    

/* ----------------------
 *	Select Statement
 * ----------------------
 */
typedef struct RetrieveStmt {
    NodeTag		type;
    char                *unique;  /* NULL, '*', or unique attribute name */
    char		*into;		/* name of table (for select into
					   table) */
    List		*targetList;	/* the target list (of ResTarget) */
    List		*fromClause;	/* the from clause */
    Node		*whereClause;	/* qualifications */
    List		*groupClause;	/* group by clause */
    Node		*havingClause;	/* having conditional-expression */
    List		*sortClause;	/* sort clause (a list of SortGroupBy's) */
} RetrieveStmt;    


/****************************************************************************
 *  Supporting data structures for Parse Trees
 ****************************************************************************/

/*
 * TypeName - specifies a type in definitions
 */
typedef struct TypeName {
    NodeTag		type;
    char		*name;		/* name of the type */
    bool		setof;		/* is a set? */
    List		*arrayBounds;	/* array bounds */
    int			typlen;		/* length for char() and varchar() */
} TypeName;

/*
 * ParamNo - specifies a parameter reference
 */
typedef struct ParamNo {
    NodeTag		type;
    int			number;		/* the number of the parameter */
    TypeName		*typename;	/* the typecast */
} ParamNo;

/*
 * A_Expr - binary expressions
 */
typedef struct A_Expr {
    NodeTag		type;
    int			oper;		/* type of operation
					   {OP,OR,AND,NOT,ISNULL,NOTNULL} */
    char		*opname;	/* name of operator/function */
    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;

/*
 * ColumnDef - column definition (used in various creates)
 */
typedef struct ColumnDef {
    NodeTag		type;
    char		*colname;	/* name of column */
    TypeName		*typename;	/* type of 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 a relation - filled in by
					   transformExpr() */
} Ident;

/*
 * FuncCall - a function/aggregate invocation
 */
typedef struct FuncCall {
    NodeTag		type;
    char		*funcname;	/* name of function */
    List		*args;		/* the arguments (list of exprs) */
} 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)
 */
typedef struct ResTarget {
    NodeTag		type;
    char		*name;		/* name of the result column */
    List		*indirection;	/* array references */
    Node		*val;		/* the value of the result
					   (A_Expr or Attr) (or A_Const) */
} ResTarget;

/*
 * ParamString - used in with clauses
 */
typedef struct ParamString {
    NodeTag		type;
    char		*name;
    char		*val;
} ParamString;

/*
 * TimeRange - specifies a time range
 */
typedef struct TimeRange {
    NodeTag		type;
    char		*startDate;
    char		*endDate;	/* snapshot if NULL */
} TimeRange;

/*
 * RelExpr - relation expressions
 */
typedef struct RelExpr {
    NodeTag		type;
    char		*relname;	/* the relation name */
    bool		inh;		/* inheritance query */
    TimeRange		*timeRange;	/* the time range */
} RelExpr;

/*
 * SortGroupBy - for order by clause
 */
typedef struct SortGroupBy {
    NodeTag		type;
    int			resno;		/* target number */
    char                *range;
    char		*name;		/* name of column to sort on */
    char		*useOp;		/* operator to use */
} SortGroupBy;

/*
 * RangeVar - range variable, used in from clauses
 */
typedef struct RangeVar {
    NodeTag		type;
    RelExpr		*relExpr;	/* the relation expression */
    char		*name;		/* the name to be referenced
					   (optional) */
} RangeVar;

/*
 * IndexElem - index parameters (used in create index)
 */
typedef struct IndexElem {
    NodeTag		type;
    char		*name;		/* name of index */
    List		*args;		/* if not NULL, function index */
    char 		*class;
    TypeName            *tname;         /* type of index's keys (optional) */
} 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;		/* can be a list too */
} TargetEntry;

/*
 * RangeTblEntry -
 *    used in range tables. Some of the following are only used in one of
 *    the parsing, optimizing, execution stages.
 *
 *    inFromCl marks those range variables that are listed in the from clause.
 *    In SQL, the targetlist can only refer to range variables listed in the
 *    from clause but POSTQUEL allows you to refer to tables not specified, in
 *    which case a range table entry will be generated. We use POSTQUEL
 *    semantics which is more powerful. However, we need SQL semantics in
 *    some cases (eg. when expanding a '*')
 */
typedef struct RangeTblEntry {
    NodeTag		type;
    char                *relname;	/* real name of the relation */
    TimeRange		*timeRange;	/* time range */
    char		*refname;	/* the reference name (specified in
					   the from clause) */
    Oid			relid;		
    bool		inh;		/* inheritance? */
    bool		archive;	/* filled in by plan_archive */
    bool		inFromCl;	/* comes from From Clause */
    TimeQual		timeQual;	/* filled in by pg_plan */
} RangeTblEntry;

/*
 * SortClause -
 *     used in the sort clause for retrieves and cursors
 */
typedef struct SortClause {
    NodeTag		type;
    Resdom		*resdom;	/* attributes in tlist to be sorted */
    Oid			opoid;		/* sort operators */
} SortClause;

/*
 * GroupClause -
 *     used in the GROUP BY clause
 */
typedef struct GroupClause {
    NodeTag		type;
    Var			*grpAttr;	/* attributes to group on */
    Oid			grpOpoid;	/* the sort operator to use */
} GroupClause;

#endif	/* PARSENODES_H */