gram.y 165 KB
Newer Older
1
%{
2

3
/*#define YYDEBUG 1*/
4
/*-------------------------------------------------------------------------
5
 *
6
 * gram.y
7
 *	  POSTGRES SQL YACC rules/actions
8
 *
9
 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
Bruce Momjian's avatar
Add:  
Bruce Momjian committed
10
 * Portions Copyright (c) 1994, Regents of the University of California
11 12 13
 *
 *
 * IDENTIFICATION
14
 *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.296 2002/03/22 02:56:33 tgl Exp $
15 16
 *
 * HISTORY
17 18 19
 *	  AUTHOR			DATE			MAJOR EVENT
 *	  Andrew Yu			Sept, 1994		POSTQUEL to SQL conversion
 *	  Andrew Yu			Oct, 1994		lispy code conversion
20 21
 *
 * NOTES
22 23
 *	  CAPITALS are used to represent terminal symbols.
 *	  non-capitals are used to represent non-terminals.
24 25
 *	  SQL92-specific syntax is separated from plain SQL/Postgres syntax
 *	  to help isolate the non-extensible portions of the parser.
26
 *
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
 *	  In general, nothing in this file should initiate database accesses
 *	  nor depend on changeable state (such as SET variables).  If you do
 *	  database accesses, your code will fail when we have aborted the
 *	  current transaction and are just parsing commands to find the next
 *	  ROLLBACK or COMMIT.  If you make use of SET variables, then you
 *	  will do the wrong thing in multi-query strings like this:
 *			SET SQL_inheritance TO off; SELECT * FROM foo;
 *	  because the entire string is parsed by gram.y before the SET gets
 *	  executed.  Anything that depends on the database or changeable state
 *	  should be handled inside parse_analyze() so that it happens at the
 *	  right time not the wrong time.  The handling of SQL_inheritance is
 *	  a good example.
 *
 * WARNINGS
 *	  If you use a list, make sure the datum is a node so that the printing
 *	  routines work.
 *
 *	  Sometimes we assign constants to makeStrings. Make sure we don't free
45
 *	  those.
46 47 48 49
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"
50

51 52
#include <ctype.h>

53
#include "access/htup.h"
54
#include "catalog/index.h"
Bruce Momjian's avatar
Bruce Momjian committed
55
#include "catalog/pg_type.h"
56
#include "nodes/params.h"
57
#include "nodes/parsenodes.h"
Bruce Momjian's avatar
Bruce Momjian committed
58
#include "parser/gramparse.h"
59
#include "storage/lmgr.h"
60
#include "utils/numeric.h"
61
#include "utils/datetime.h"
62

Marc G. Fournier's avatar
Marc G. Fournier committed
63
#ifdef MULTIBYTE
64
#include "mb/pg_wchar.h"
65
#else
Tatsuo Ishii's avatar
Tatsuo Ishii committed
66
#define GetStandardEncoding()	0		/* PG_SQL_ASCII */
67
#define GetStandardEncodingName()	"SQL_ASCII"
68 69
#endif

70 71
extern List *parsetree;			/* final parse result is delivered here */

72
static bool QueryIsRule = FALSE;
73 74
static Oid	*param_type_info;
static int	pfunc_num_args;
75

76

77
/*
78
 * If you need access to certain yacc-generated variables and find that
79 80 81 82 83
 * they're static by default, uncomment the next line.  (this is not a
 * problem, yet.)
 */
/*#define __YYSCLASS*/

84
static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
85
static Node *makeTypeCast(Node *arg, TypeName *typename);
86 87
static Node *makeStringConst(char *str, TypeName *typename);
static Node *makeFloatConst(char *str);
Bruce Momjian's avatar
Bruce Momjian committed
88
static Node *makeRowExpr(char *opr, List *largs, List *rargs);
89 90 91 92 93
static SelectStmt *findLeftmostSelect(SelectStmt *node);
static void insertSelectOptions(SelectStmt *stmt,
								List *sortClause, List *forUpdate,
								Node *limitOffset, Node *limitCount);
static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
94
static Node *doNegate(Node *n);
95
static void doNegateFloat(Value *v);
96

97 98
#define MASK(b) (1 << (b))

99 100
%}

101

102 103 104 105 106 107
%union
{
	int					ival;
	char				chr;
	char				*str;
	bool				boolean;
108
	JoinType			jtype;
109 110 111
	List				*list;
	Node				*node;
	Value				*value;
112
	ColumnRef			*columnref;
113 114 115 116

	TypeName			*typnam;
	DefElem				*defelt;
	SortGroupBy			*sortgroupby;
117
	JoinExpr			*jexpr;
118
	IndexElem			*ielem;
119
	Alias				*alias;
120 121 122
	RangeVar			*range;
	A_Indices			*aind;
	ResTarget			*target;
123
	PrivTarget			*privtarget;
124 125 126

	DefineStmt			*dstmt;
	RuleStmt			*rstmt;
127
	InsertStmt			*istmt;
128 129
}

130
%type <node>	stmt, schema_stmt,
131 132
		AlterDatabaseSetStmt, AlterGroupStmt, AlterSchemaStmt, AlterTableStmt,
		AlterUserStmt, AlterUserSetStmt, AnalyzeStmt,
133
		ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt,
134
		CopyStmt, CreateAsStmt, CreateDomainStmt, CreateGroupStmt, CreatePLangStmt,
135
		CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt,
Tom Lane's avatar
Tom Lane committed
136
		CreateUserStmt, CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt,
137
		DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt,
138
		DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
139
		GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt,
140
		NotifyStmt, OptimizableStmt, ProcedureStmt, ReindexStmt,
141
		RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt,
142
		RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty,
143
		RuleStmt, SelectStmt, TransactionStmt, TruncateStmt,
144
		UnlistenStmt, UpdateStmt, VacuumStmt, VariableResetStmt,
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
145
		VariableSetStmt, VariableShowStmt, ViewStmt, CheckPointStmt
146

147 148
%type <node>	select_no_parens, select_with_parens, select_clause,
				simple_select
149

150
%type <node>    alter_column_default
Tom Lane's avatar
Tom Lane committed
151
%type <ival>    drop_behavior, opt_drop_behavior
152

153
%type <list>	createdb_opt_list, createdb_opt_item
154
%type <boolean>	opt_equal
155

156
%type <ival>	opt_lock, lock_type
157
%type <boolean>	opt_force, opt_or_replace
158

159 160 161 162
%type <list>	user_list

%type <list>	OptGroupList
%type <defelt>	OptGroupElem
163 164 165

%type <list>	OptUserList
%type <defelt>	OptUserElem
166

167 168 169
%type <str>		OptSchemaName
%type <list>	OptSchemaEltList

170 171
%type <boolean>	TriggerActionTime, TriggerForSpec, opt_trusted, opt_procedural
%type <str>		opt_lancompiler
172

173 174
%type <str>		TriggerEvents
%type <value>	TriggerFuncArg
175

176
%type <str>		relation_name, copy_file_name, copy_delimiter, copy_null,
177
		database_name, access_method_clause, access_method, attr_name,
178
		class, index_name, name, func_name, file_name
179

180 181
%type <range>	qualified_name, OptConstrFromTable

182
%type <str>		opt_id,
183
		all_Op, MathOp, opt_name,
184
		OptUseOp, opt_class, SpecialRuleRelation
185

186
%type <str>		opt_level, opt_encoding
187 188
%type <node>	grantee
%type <list>	grantee_list
189 190 191 192 193 194
%type <ival>	privilege
%type <list>	privileges, privilege_list
%type <privtarget> privilege_target
%type <node>	function_with_argtypes
%type <list>	function_with_argtypes_list
%type <chr>	TriggerOneEvent
195

196
%type <list>	stmtblock, stmtmulti,
197
		OptTableElementList, OptInherit, definition, opt_distinct,
198
		opt_with, func_args, func_args_list, func_as,
199
		oper_argtypes, RuleActionList, RuleActionMulti,
200
		opt_column_list, columnList, opt_name_list,
201
		sort_clause, sortby_list, index_params, index_list, name_list,
202 203 204
		from_clause, from_list, opt_array_bounds, qualified_name_list,
		expr_list, attrs, opt_attrs, target_list, update_target_list,
		insert_column_list,
205
		def_list, opt_indirection, group_clause, TriggerFuncArgs,
206
		select_limit, opt_select_limit
207

208 209
%type <range>	into_clause, OptTempTableName

210
%type <typnam>	func_arg, func_return, func_type, aggr_argtype
211

212
%type <boolean>	opt_arg, TriggerForOpt, TriggerForType, OptTemp, OptWithOids
213

214
%type <list>	for_update_clause, opt_for_update_clause, update_list
215
%type <boolean>	opt_all
216
%type <boolean>	opt_table
217
%type <boolean>	opt_chain, opt_trans
218

219
%type <node>	join_outer, join_qual
220
%type <jtype>	join_type
221

222
%type <list>	extract_list, position_list
223
%type <list>	substr_list, trim_list
224
%type <ival>	opt_interval
225
%type <node>	substr_from, substr_for
226

227
%type <boolean>	opt_binary, opt_using, opt_instead, opt_cursor
228
%type <boolean>	opt_with_copy, index_opt_unique, opt_verbose, opt_full
229
%type <boolean>	opt_freeze, analyze_keyword
230

231
%type <ival>	copy_dirn, direction, reindex_type, drop_type,
232
		opt_column, event, comment_type
233

Bruce Momjian's avatar
Bruce Momjian committed
234
%type <ival>	fetch_how_many
235

236 237
%type <node>	select_limit_value, select_offset_value

Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
238 239 240
%type <list>	OptSeqList
%type <defelt>	OptSeqElem

241
%type <istmt>	insert_rest
242

243
%type <node>	OptTableElement, ConstraintElem
244
%type <node>	columnDef
245
%type <defelt>	def_elem
246
%type <node>	def_arg, columnElem, where_clause, insert_column_item,
247
				a_expr, b_expr, c_expr, AexprConst,
248
				in_expr, having_clause
249
%type <list>	row_descriptor, row_list, in_expr_nodes
250
%type <node>	row_expr
251
%type <node>	case_expr, case_arg, when_clause, case_default
252
%type <boolean>	opt_empty_parentheses
253
%type <list>	when_clause_list
254
%type <ival>	sub_type
255 256
%type <list>	OptCreateAs, CreateAsList
%type <node>	CreateAsElement
257
%type <value>	NumericOnly, FloatOnly, IntegerOnly
258 259
%type <columnref>	columnref
%type <alias>	alias_clause
260
%type <sortgroupby>		sortby
261
%type <ielem>	index_elem, func_index
262 263 264
%type <node>	table_ref
%type <jexpr>	joined_table
%type <range>	relation_expr
265
%type <target>	target_el, update_target_el
266

267
%type <typnam>	Typename, SimpleTypename, ConstTypename
268 269
				GenericType, Numeric, Character, ConstDatetime, ConstInterval, Bit
%type <str>		character, bit
270
%type <str>		extract_arg
271
%type <str>		opt_charset, opt_collate
272 273
%type <str>		opt_float
%type <ival>	opt_numeric, opt_decimal
274
%type <boolean>	opt_varying, opt_timezone, opt_timezone_x
275

276
%type <ival>	Iconst
277
%type <str>		Sconst, comment_text
278
%type <str>		UserId, opt_boolean, var_value, ColId_or_Sconst
279 280
%type <str>		ColId, ColLabel, type_name, func_name_keyword
%type <str>		col_name_keyword, unreserved_keyword, reserved_keyword
281
%type <node>	zone_value
282

283
%type <node>	TableConstraint
284 285
%type <list>	ColQualList
%type <node>	ColConstraint, ColConstraintElem, ConstraintAttr
286
%type <ival>	key_actions, key_delete, key_update, key_reference
Jan Wieck's avatar
Jan Wieck committed
287
%type <str>		key_match
288 289
%type <ival>	ConstraintAttributeSpec, ConstraintDeferrabilitySpec,
				ConstraintTimeSpec
290

291 292 293
%type <list>	constraints_set_list
%type <boolean>	constraints_set_mode

294 295
%type <boolean> opt_as

296

297 298
/*
 * If you make any token changes, remember to:
299 300
 *		- use "yacc -d" and update parse.h
 *		- update the keyword table in parser/keywords.c
301 302
 */

303 304 305 306 307 308 309
/* Reserved word tokens
 * SQL92 syntax has many type-specific constructs.
 * So, go ahead and make these types reserved words,
 *  and call-out the syntax explicitly.
 * This gets annoying when trying to also retain Postgres' nice
 *  type-extensible features, but we don't really have a choice.
 * - thomas 1997-10-11
310 311
 * NOTE: don't forget to add new keywords to the appropriate one of
 * the reserved-or-not-so-reserved keyword lists, below.
312 313 314
 */

/* Keywords (in SQL92 reserved words) */
315
%token	ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC, AT, AUTHORIZATION,
316
		BEGIN_TRANS, BETWEEN, BOTH, BY,
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
317
		CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE, 
318
		COALESCE, COLLATE, COLUMN, COMMIT,
319
		CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT_DATE,
320
		CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
321 322
		DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC,
		DISTINCT, DOUBLE, DROP,
323
		ELSE, ENCRYPTED, END_TRANS, ESCAPE, EXCEPT, EXECUTE, EXISTS, EXTRACT,
324
		FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
325
		GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
326 327
		IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
		ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
328
		MATCH, MINUTE_P, MONTH_P, NAMES,
329
		NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
330
		OF, OLD, ON, ONLY, OPTION, OR, ORDER, OUTER_P, OVERLAPS,
331 332
		PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
		READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
333
		SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING,
334 335
		TABLE, TEMPORARY, THEN, TIME, TIMESTAMP,
		TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
336
		UNENCRYPTED, UNION, UNIQUE, UNKNOWN, UPDATE, USAGE, USER, USING,
337
		VALUES, VARCHAR, VARYING, VIEW,
338
		WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
339

340
/* Keywords (in SQL99 reserved words) */
341
%token	CHAIN, CHARACTERISTICS,
342 343 344 345
		DEFERRABLE, DEFERRED,
		IMMEDIATE, INITIALLY, INOUT,
		OFF, OUT,
		PATH_P, PENDANT,
346
		REPLACE, RESTRICT,
347 348
        TRIGGER,
		WITHOUT
349 350

/* Keywords (in SQL92 non-reserved words) */
351
%token	COMMITTED, SERIALIZABLE, TYPE_P, DOMAIN_P
352

353 354 355 356 357 358
/* Keywords for Postgres support (not in SQL92 reserved words)
 *
 * The CREATEDB and CREATEUSER tokens should go away
 * when some sort of pg_privileges relation is introduced.
 * - Todd A. Brandys 1998-01-01?
 */
359
%token	ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYSE, ANALYZE,
360
		BACKWARD, BEFORE, BINARY, BIT,
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
361
		CACHE, CHECKPOINT, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE,
362
		DATABASE, DELIMITERS, DO,
363
		EACH, ENCODING, EXCLUSIVE, EXPLAIN,
364
		FORCE, FORWARD, FREEZE, FUNCTION, HANDLER,
365
		ILIKE, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
366
		LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
367
		MAXVALUE, MINVALUE, MODE, MOVE,
368
		NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
369
		OFFSET, OIDS, OPERATOR, OWNER, PASSWORD, PROCEDURAL,
Hiroshi Inoue's avatar
Hiroshi Inoue committed
370
		REINDEX, RENAME, RESET, RETURNS, ROW, RULE,
371
		SEQUENCE, SETOF, SHARE, SHOW, START, STATEMENT,
372
		STATISTICS, STDIN, STDOUT, STORAGE, SYSID,
373
		TEMP, TEMPLATE, TOAST, TRUNCATE, TRUSTED, 
374
		UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
375

376 377 378 379 380 381
/* The grammar thinks these are keywords, but they are not in the keywords.c
 * list and so can never be entered directly.  The filter in parser.c
 * creates these tokens when required.
 */
%token			UNIONJOIN

382
/* Special keywords, not in the query language - see the "lex" file */
383
%token <str>	IDENT, FCONST, SCONST, BITCONST, Op
384 385
%token <ival>	ICONST, PARAM

386
/* these are not real. they are here so that they get generated as #define's*/
387
%token			OP
388

389
/* precedence: lowest to highest */
390 391 392
%left		UNION EXCEPT
%left		INTERSECT
%left		JOIN UNIONJOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
393 394 395 396
%left		OR
%left		AND
%right		NOT
%right		'='
397
%nonassoc	'<' '>'
398
%nonassoc	LIKE ILIKE
399
%nonassoc	ESCAPE
400
%nonassoc	OVERLAPS
401 402
%nonassoc	BETWEEN
%nonassoc	IN
403
%left		POSTFIXOP		/* dummy for postfix Op rules */
404
%left		Op				/* multi-character ops and user-defined operators */
405 406
%nonassoc	NOTNULL
%nonassoc	ISNULL
407
%nonassoc	IS NULL_P TRUE_P FALSE_P UNKNOWN	/* sets precedence for IS NULL, etc */
408
%left		'+' '-'
409 410
%left		'*' '/' '%'
%left		'^'
411
/* Unary Operators */
412
%left		AT ZONE			/* sets precedence for AT TIME ZONE */
413 414 415
%right		UMINUS
%left		'.'
%left		'[' ']'
416
%left		'(' ')'
417
%left		TYPECAST
418 419
%%

420 421 422 423 424 425
/*
 *	Handle comment-only lines, and ;; SELECT * FROM pg_class ;;;
 *	psql already handles such cases, but other interfaces don't.
 *	bjm 1999/10/05
 */
stmtblock:  stmtmulti
426 427
				{ parsetree = $1; }
		;
428

429
/* the thrashing around here is to discard "empty" statements... */
430
stmtmulti:  stmtmulti ';' stmt
431
				{ if ($3 != (Node *)NULL)
432 433 434 435
					$$ = lappend($1, $3);
				  else
					$$ = $1;
				}
436
		| stmt
437
				{ if ($1 != (Node *)NULL)
438
					$$ = makeList1($1);
439
				  else
440
					$$ = NIL;
441
				}
442
		;
443

444
stmt : AlterDatabaseSetStmt
445
		| AlterGroupStmt
446 447
		| AlterSchemaStmt
		| AlterTableStmt
448
		| AlterUserStmt
449
		| AlterUserSetStmt
450 451 452
		| ClosePortalStmt
		| CopyStmt
		| CreateStmt
453
		| CreateAsStmt
454
		| CreateDomainStmt
455
		| CreateSchemaStmt
456
		| CreateGroupStmt
457
		| CreateSeqStmt
458
		| CreatePLangStmt
459
		| CreateTrigStmt
460
		| CreateUserStmt
461 462
		| ClusterStmt
		| DefineStmt
463
		| DropStmt		
464
		| DropSchemaStmt
465
		| TruncateStmt
466
		| CommentStmt
467
		| DropGroupStmt
468
		| DropPLangStmt
469
		| DropTrigStmt
470
		| DropUserStmt
471 472 473 474 475
		| ExplainStmt
		| FetchStmt
		| GrantStmt
		| IndexStmt
		| ListenStmt
476
		| UnlistenStmt
477
		| LockStmt
478
		| NotifyStmt
479
		| ProcedureStmt
Hiroshi Inoue's avatar
Hiroshi Inoue committed
480
		| ReindexStmt
481 482 483 484 485 486 487 488 489 490 491
		| RemoveAggrStmt
		| RemoveOperStmt
		| RemoveFuncStmt
		| RenameStmt
		| RevokeStmt
		| OptimizableStmt
		| RuleStmt
		| TransactionStmt
		| ViewStmt
		| LoadStmt
		| CreatedbStmt
492
		| DropdbStmt
493
		| VacuumStmt
494
		| AnalyzeStmt
495 496 497
		| VariableSetStmt
		| VariableShowStmt
		| VariableResetStmt
498
		| ConstraintsSetStmt
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
499
		| CheckPointStmt
500 501
		| /*EMPTY*/
			{ $$ = (Node *)NULL; }
502
		;
503

504 505
/*****************************************************************************
 *
506
 * Create a new Postgres DBMS user
507 508 509 510
 *
 *
 *****************************************************************************/

511
CreateUserStmt:  CREATE USER UserId OptUserList 
512
				  {
513 514
					CreateUserStmt *n = makeNode(CreateUserStmt);
					n->user = $3;
515
					n->options = $4;
516
					$$ = (Node *)n;
517 518 519
				  }
                 | CREATE USER UserId WITH OptUserList
                  {
Bruce Momjian's avatar
Bruce Momjian committed
520 521
					CreateUserStmt *n = makeNode(CreateUserStmt);
					n->user = $3;
522
					n->options = $5;
Bruce Momjian's avatar
Bruce Momjian committed
523
					$$ = (Node *)n;
524
                  }                   
525
		;
526 527 528

/*****************************************************************************
 *
529
 * Alter a postgresql DBMS user
530 531 532 533
 *
 *
 *****************************************************************************/

534
AlterUserStmt:  ALTER USER UserId OptUserList
535
				 {
536 537
					AlterUserStmt *n = makeNode(AlterUserStmt);
					n->user = $3;
538
					n->options = $4;
Bruce Momjian's avatar
Bruce Momjian committed
539
					$$ = (Node *)n;
540 541 542
				 }
			    | ALTER USER UserId WITH OptUserList
				 {
Bruce Momjian's avatar
Bruce Momjian committed
543 544
					AlterUserStmt *n = makeNode(AlterUserStmt);
					n->user = $3;
545
					n->options = $5;
546
					$$ = (Node *)n;
547
				 }
548
		;
549

550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569

AlterUserSetStmt: ALTER USER UserId VariableSetStmt
				{
					AlterUserSetStmt *n = makeNode(AlterUserSetStmt);
					n->user = $3;
					n->variable = ((VariableSetStmt *)$4)->name;
					n->value = ((VariableSetStmt *)$4)->args;
					$$ = (Node *)n;
				}
				| ALTER USER UserId VariableResetStmt
				{
					AlterUserSetStmt *n = makeNode(AlterUserSetStmt);
					n->user = $3;
					n->variable = ((VariableResetStmt *)$4)->name;
					n->value = NULL;
					$$ = (Node *)n;
				}
		;


570 571
/*****************************************************************************
 *
572
 * Drop a postgresql DBMS user
573 574 575 576
 *
 *
 *****************************************************************************/

577
DropUserStmt:  DROP USER user_list
578 579
				{
					DropUserStmt *n = makeNode(DropUserStmt);
580
					n->users = $3;
581 582 583 584
					$$ = (Node *)n;
				}
		;

585 586 587 588 589 590 591 592 593 594 595 596 597
/*
 * Options for CREATE USER and ALTER USER
 */
OptUserList: OptUserList OptUserElem		{ $$ = lappend($1, $2); }
			| /* EMPTY */					{ $$ = NIL; }
		;

OptUserElem:  PASSWORD Sconst
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "password";
				  $$->arg = (Node *)makeString($2);
				}
598 599 600 601 602 603 604 605 606 607 608 609
			  | ENCRYPTED PASSWORD Sconst
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "encryptedPassword";
				  $$->arg = (Node *)makeString($3);
				}
			  | UNENCRYPTED PASSWORD Sconst
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "unencryptedPassword";
				  $$->arg = (Node *)makeString($3);
				}
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
              | SYSID Iconst
				{
				  $$ = makeNode(DefElem);
				  $$->defname = "sysid";
				  $$->arg = (Node *)makeInteger($2);
				}
              | CREATEDB
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "createdb";
				  $$->arg = (Node *)makeInteger(TRUE);
				}
              | NOCREATEDB
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "createdb";
				  $$->arg = (Node *)makeInteger(FALSE);
				}
              | CREATEUSER
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "createuser";
				  $$->arg = (Node *)makeInteger(TRUE);
				}
              | NOCREATEUSER
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "createuser";
				  $$->arg = (Node *)makeInteger(FALSE);
				}
              | IN GROUP user_list
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "groupElts";
				  $$->arg = (Node *)$3;
				}
              | VALID UNTIL Sconst
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "validUntil";
				  $$->arg = (Node *)makeString($3);
651
				}
652
        ;
653

654
user_list:  user_list ',' UserId
655
				{
656
					$$ = lappend($1, makeString($3));
657
				}
658
			| UserId
659
				{
660
					$$ = makeList1(makeString($1));
661 662 663
				}
		;

664

665 666 667

/*****************************************************************************
 *
668
 * Create a postgresql group
669 670 671 672
 *
 *
 *****************************************************************************/

673 674
CreateGroupStmt:  CREATE GROUP UserId OptGroupList
				   {
675 676
					CreateGroupStmt *n = makeNode(CreateGroupStmt);
					n->name = $3;
677
					n->options = $4;
678
					$$ = (Node *)n;
679 680 681
				   }
			      | CREATE GROUP UserId WITH OptGroupList
				   {
682 683
					CreateGroupStmt *n = makeNode(CreateGroupStmt);
					n->name = $3;
684
					n->options = $5;
685
					$$ = (Node *)n;
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700
				   }
		;

/*
 * Options for CREATE GROUP
 */
OptGroupList: OptGroupList OptGroupElem		{ $$ = lappend($1, $2); }
			| /* EMPTY */					{ $$ = NIL; }
		;

OptGroupElem:  USER user_list
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "userElts";
				  $$->arg = (Node *)$2;
701
				}
702
               | SYSID Iconst
703
				{
704 705 706
				  $$ = makeNode(DefElem);
				  $$->defname = "sysid";
				  $$->arg = (Node *)makeInteger($2);
707
				}
708
        ;
709

710 711 712

/*****************************************************************************
 *
713
 * Alter a postgresql group
714 715 716 717
 *
 *
 *****************************************************************************/

718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
AlterGroupStmt:  ALTER GROUP UserId ADD USER user_list
				{
					AlterGroupStmt *n = makeNode(AlterGroupStmt);
					n->name = $3;
					n->action = +1;
					n->listUsers = $6;
					$$ = (Node *)n;
				}
			| ALTER GROUP UserId DROP USER user_list
				{
					AlterGroupStmt *n = makeNode(AlterGroupStmt);
					n->name = $3;
					n->action = -1;
					n->listUsers = $6;
					$$ = (Node *)n;
				}
			;
735

736

737 738
/*****************************************************************************
 *
739
 * Drop a postgresql group
740 741 742 743 744
 *
 *
 *****************************************************************************/

DropGroupStmt: DROP GROUP UserId
745 746 747 748 749 750
				{
					DropGroupStmt *n = makeNode(DropGroupStmt);
					n->name = $3;
					$$ = (Node *)n;
				}
			;
751 752


753 754 755 756 757 758 759
/*****************************************************************************
 *
 * Manipulate a schema
 *
 *
 *****************************************************************************/

760
CreateSchemaStmt:  CREATE SCHEMA OptSchemaName AUTHORIZATION UserId OptSchemaEltList
761
				{
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
					CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
					/* One can omit the schema name or the authorization id... */
					if ($3 != NULL)
						n->schemaname = $3;
					else
						n->schemaname = $5;
					n->authid = $5;
					n->schemaElts = $6;
					$$ = (Node *)n;
				}
		| CREATE SCHEMA ColId OptSchemaEltList
				{
					CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
					/* ...but not both */
					n->schemaname = $3;
					n->authid = NULL;
					n->schemaElts = $4;
779
					$$ = (Node *)n;
780 781 782
				}
		;

783
AlterSchemaStmt:  ALTER SCHEMA ColId
784 785 786 787 788
				{
					elog(ERROR, "ALTER SCHEMA not yet supported");
				}
		;

789
DropSchemaStmt:  DROP SCHEMA ColId
790
				{
791
					elog(ERROR, "DROP SCHEMA not yet supported");
792
				}
793
		;
794

795 796 797 798 799 800 801
OptSchemaName: ColId								{ $$ = $1; }
		| /* EMPTY */								{ $$ = NULL; }
		;

OptSchemaEltList: OptSchemaEltList schema_stmt		{ $$ = lappend($1, $2); }
		| /* EMPTY */								{ $$ = NIL; }
		;
802

803 804 805 806 807 808 809 810
/*
 *	schema_stmt are the ones that can show up inside a CREATE SCHEMA
 *	statement (in addition to by themselves).
 */
schema_stmt: CreateStmt
		| GrantStmt
		| ViewStmt
		;
811

812
/*****************************************************************************
813
 *
814
 * Set PG internal variable
815
 *	  SET name TO 'var_value'
816 817
 * Include SQL92 syntax (thomas 1997-10-22):
 *    SET TIME ZONE 'var_value'
818
 *
819 820
 *****************************************************************************/

821
VariableSetStmt:  SET ColId TO var_value
822 823 824
				{
					VariableSetStmt *n = makeNode(VariableSetStmt);
					n->name  = $2;
825 826
					if ($4 != NULL)
						n->args = makeList1(makeStringConst($4, NULL));
827 828
					$$ = (Node *) n;
				}
829
		| SET ColId '=' var_value
830 831 832
				{
					VariableSetStmt *n = makeNode(VariableSetStmt);
					n->name  = $2;
833 834
					if ($4 != NULL)
						n->args = makeList1(makeStringConst($4, NULL));
835 836
					$$ = (Node *) n;
				}
837
		| SET TIME ZONE zone_value
838 839 840
				{
					VariableSetStmt *n = makeNode(VariableSetStmt);
					n->name  = "timezone";
841 842
					if ($4 != NULL)
						n->args = makeList1($4);
843 844
					$$ = (Node *) n;
				}
845
		| SET TRANSACTION ISOLATION LEVEL opt_level
846 847 848
				{
					VariableSetStmt *n = makeNode(VariableSetStmt);
					n->name  = "XactIsoLevel";
849
					n->args = makeList1(makeStringConst($5, NULL));
850 851
					$$ = (Node *) n;
				}
852 853 854
        | SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL opt_level
				{
					VariableSetStmt *n = makeNode(VariableSetStmt);
855
					n->name  = "default_transaction_isolation";
856
					n->args = makeList1(makeStringConst($8, NULL));
857 858
					$$ = (Node *) n;
				}
859
		| SET NAMES opt_encoding
860 861 862
				{
					VariableSetStmt *n = makeNode(VariableSetStmt);
					n->name  = "client_encoding";
863 864
					if ($3 != NULL)
						n->args = makeList1(makeStringConst($3, NULL));
865 866
					$$ = (Node *) n;
				}
867
		| SET SESSION AUTHORIZATION ColId_or_Sconst
868 869 870
				{
					VariableSetStmt *n = makeNode(VariableSetStmt);
					n->name = "session_authorization";
871
					n->args = makeList1(makeStringConst($4, NULL));
872 873
					$$ = (Node *) n;
				}
874 875
		;

876
opt_level:  READ COMMITTED					{ $$ = "read committed"; }
877 878 879
		| SERIALIZABLE						{ $$ = "serializable"; }
		;

880 881 882 883 884 885 886 887 888 889
var_value:  opt_boolean						{ $$ = $1; }
		| SCONST							{ $$ = $1; }
		| ICONST
			{
				char	buf[64];
				sprintf(buf, "%d", $1);
				$$ = pstrdup(buf);
			}
		| '-' ICONST
			{
890 891 892 893
				char	buf[64];
				sprintf(buf, "%d", -($2));
				$$ = pstrdup(buf);
			}
894 895 896
		| FCONST							{ $$ = $1; }
		| '-' FCONST
			{
897 898 899 900 901
				char * s = palloc(strlen($2)+2);
				s[0] = '-';
				strcpy(s + 1, $2);
				$$ = s;
			}
902 903
		| name_list
			{
904 905 906
				List *n;
				int slen = 0;
				char *result;
907

908 909 910
				/* List of words? Then concatenate together */
				if ($1 == NIL)
					elog(ERROR, "SET must have at least one argument");
911

912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
				foreach (n, $1)
				{
					Value *p = (Value *) lfirst(n);
					Assert(IsA(p, String));
					/* keep track of room for string and trailing comma */
					slen += (strlen(p->val.str) + 1);
				}
				result = palloc(slen + 1);
				*result = '\0';
				foreach (n, $1)
				{
					Value *p = (Value *) lfirst(n);
					strcat(result, p->val.str);
					strcat(result, ",");
				}
				/* remove the trailing comma from the last element */
				*(result+strlen(result)-1) = '\0';
				$$ = result;
930
			}
931 932
		| DEFAULT							{ $$ = NULL; }
		;
933

934 935 936 937
opt_boolean:  TRUE_P						{ $$ = "true"; }
		| FALSE_P							{ $$ = "false"; }
		| ON								{ $$ = "on"; }
		| OFF								{ $$ = "off"; }
938 939
		;

940 941 942 943 944 945 946 947 948 949 950 951
/* Timezone values can be:
 * - a string such as 'pst8pdt'
 * - an integer or floating point number
 * - a time interval per SQL99
 */
zone_value:  Sconst
			{
				$$ = makeStringConst($1, NULL);
			}
		| ConstInterval Sconst opt_interval
			{
				A_Const *n = (A_Const *) makeStringConst($2, $1);
952
				if ($3 != -1)
953 954 955 956 957
				{
					if (($3 & ~(MASK(HOUR) | MASK(MINUTE))) != 0)
						elog(ERROR, "Time zone interval must be HOUR or HOUR TO MINUTE");
					n->typename->typmod = ((($3 & 0x7FFF) << 16) | 0xFFFF);
				}
958 959 960 961 962
				$$ = (Node *)n;
			}
		| ConstInterval '(' Iconst ')' Sconst opt_interval
			{
				A_Const *n = (A_Const *) makeStringConst($5, $1);
963
				if ($6 != -1)
964 965 966 967 968
				{
					if (($6 & ~(MASK(HOUR) | MASK(MINUTE))) != 0)
						elog(ERROR, "Time zone interval must be HOUR or HOUR TO MINUTE");
					n->typename->typmod = ((($6 & 0x7FFF) << 16) | $3);
				}
969
				else
970
				{
971
					n->typename->typmod = ((0x7FFF << 16) | $3);
972
				}
973

974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995
				$$ = (Node *)n;
			}
		| FCONST
			{
				$$ = makeFloatConst($1);
			}
		| '-' FCONST
			{
				$$ = doNegate(makeFloatConst($2));
			}
		| ICONST
			{
				char buf[64];
				sprintf(buf, "%d", $1);
				$$ = makeFloatConst(pstrdup(buf));
			}
		| '-' ICONST
			{
				char buf[64];
				sprintf(buf, "%d", $2);
				$$ = doNegate(makeFloatConst(pstrdup(buf)));
			}
996 997
		| DEFAULT							{ $$ = NULL; }
		| LOCAL								{ $$ = NULL; }
998
		;
999

1000 1001 1002
opt_encoding:  Sconst						{ $$ = $1; }
        | DEFAULT							{ $$ = NULL; }
        | /*EMPTY*/							{ $$ = NULL; }
1003 1004
        ;

1005
ColId_or_Sconst: ColId						{ $$ = $1; }
1006
		| SCONST							{ $$ = $1; }
1007
		;
1008 1009


1010
VariableShowStmt:  SHOW ColId
1011 1012 1013 1014 1015
				{
					VariableShowStmt *n = makeNode(VariableShowStmt);
					n->name  = $2;
					$$ = (Node *) n;
				}
1016 1017 1018 1019 1020 1021
		| SHOW TIME ZONE
				{
					VariableShowStmt *n = makeNode(VariableShowStmt);
					n->name  = "timezone";
					$$ = (Node *) n;
				}
1022 1023 1024 1025 1026 1027
		| SHOW ALL
				{
					VariableShowStmt *n = makeNode(VariableShowStmt);
					n->name  = "all";
					$$ = (Node *) n;
				}
1028 1029 1030 1031 1032 1033
		| SHOW TRANSACTION ISOLATION LEVEL
				{
					VariableShowStmt *n = makeNode(VariableShowStmt);
					n->name  = "XactIsoLevel";
					$$ = (Node *) n;
				}
1034 1035
		;

1036
VariableResetStmt:	RESET ColId
1037 1038 1039 1040 1041
				{
					VariableResetStmt *n = makeNode(VariableResetStmt);
					n->name  = $2;
					$$ = (Node *) n;
				}
1042 1043 1044 1045 1046 1047
		| RESET TIME ZONE
				{
					VariableResetStmt *n = makeNode(VariableResetStmt);
					n->name  = "timezone";
					$$ = (Node *) n;
				}
1048 1049 1050 1051 1052 1053
		| RESET TRANSACTION ISOLATION LEVEL
				{
					VariableResetStmt *n = makeNode(VariableResetStmt);
					n->name  = "XactIsoLevel";
					$$ = (Node *) n;
				}
1054 1055 1056 1057 1058 1059
		| RESET ALL
				{
					VariableResetStmt *n = makeNode(VariableResetStmt);
					n->name  = "all";
					$$ = (Node *) n;
				}
1060
		;
1061

1062

1063 1064 1065 1066 1067 1068 1069 1070 1071
ConstraintsSetStmt:	SET CONSTRAINTS constraints_set_list constraints_set_mode
				{
					ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt);
					n->constraints = $3;
					n->deferred    = $4;
					$$ = (Node *) n;
				}
		;

1072 1073
constraints_set_list:	ALL					{ $$ = NIL; }
		| name_list							{ $$ = $1; }
1074 1075
		;

1076 1077
constraints_set_mode:	DEFERRED			{ $$ = TRUE; }
		| IMMEDIATE							{ $$ = FALSE; }
1078 1079 1080
		;


Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
/*
 * Checkpoint statement
 */
CheckPointStmt: CHECKPOINT
				{
					CheckPointStmt *n = makeNode(CheckPointStmt);
					$$ = (Node *)n;
				}
			;

1091 1092
/*****************************************************************************
 *
1093
 *	ALTER TABLE variations
1094 1095 1096
 *
 *****************************************************************************/

1097
AlterTableStmt:
1098 1099
/* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
		ALTER TABLE relation_expr ADD opt_column columnDef
1100 1101 1102
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'A';
1103
					n->relation = $3;
1104
					n->def = $6;
1105 1106
					$$ = (Node *)n;
				}
1107 1108
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
		| ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default
1109 1110 1111
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'T';
1112
					n->relation = $3;
1113 1114
					n->name = $6;
					n->def = $7;
1115 1116
					$$ = (Node *)n;
				}
1117 1118 1119 1120 1121
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <Iconst> */
		| ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS Iconst
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'S';
1122
					n->relation = $3;
1123 1124 1125 1126
					n->name = $6;
					n->def = (Node *) makeInteger($9);
					$$ = (Node *)n;
				}
1127 1128 1129 1130 1131
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
        | ALTER TABLE relation_expr ALTER opt_column ColId SET STORAGE ColId
                {
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'M';
1132
					n->relation = $3;
1133 1134 1135 1136
					n->name = $6;
					n->def = (Node *) makeString($9);
					$$ = (Node *)n;
				}
1137 1138
/* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
		| ALTER TABLE relation_expr DROP opt_column ColId drop_behavior
1139 1140 1141
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'D';
1142
					n->relation = $3;
1143 1144
					n->name = $6;
					n->behavior = $7;
1145 1146
					$$ = (Node *)n;
				}
1147 1148
/* ALTER TABLE <relation> ADD CONSTRAINT ... */
		| ALTER TABLE relation_expr ADD TableConstraint
1149 1150 1151
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'C';
1152
					n->relation = $3;
1153
					n->def = $5;
1154 1155
					$$ = (Node *)n;
				}
1156 1157
/* ALTER TABLE <relation> DROP CONSTRAINT <name> {RESTRICT|CASCADE} */
		| ALTER TABLE relation_expr DROP CONSTRAINT name drop_behavior
1158 1159 1160
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'X';
1161
					n->relation = $3;
1162 1163
					n->name = $6;
					n->behavior = $7;
1164 1165
					$$ = (Node *)n;
				}
Jan Wieck's avatar
TOAST  
Jan Wieck committed
1166
/* ALTER TABLE <name> CREATE TOAST TABLE */
1167
		| ALTER TABLE qualified_name CREATE TOAST TABLE
Jan Wieck's avatar
TOAST  
Jan Wieck committed
1168 1169 1170
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'E';
1171 1172
					$3->inhOpt = INH_NO;
					n->relation = $3;
Jan Wieck's avatar
TOAST  
Jan Wieck committed
1173 1174
					$$ = (Node *)n;
				}
1175
/* ALTER TABLE <name> OWNER TO UserId */
1176
		| ALTER TABLE qualified_name OWNER TO UserId
1177 1178 1179
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'U';
1180 1181
					$3->inhOpt = INH_NO;
					n->relation = $3;
1182 1183 1184
					n->name = $6;
					$$ = (Node *)n;
				}
1185
		;
1186

1187
alter_column_default:
1188 1189 1190 1191 1192 1193 1194 1195
		SET DEFAULT a_expr
			{
				/* Treat SET DEFAULT NULL the same as DROP DEFAULT */
				if (exprIsNullConstant($3))
					$$ = NULL;
				else
					$$ = $3;
			}
1196
		| DROP DEFAULT					{ $$ = NULL; }
1197 1198
        ;

1199 1200
drop_behavior: CASCADE					{ $$ = CASCADE; }
		| RESTRICT						{ $$ = RESTRICT; }
1201
        ;
1202

Tom Lane's avatar
Tom Lane committed
1203 1204 1205
opt_drop_behavior: CASCADE				{ $$ = CASCADE; }
		| RESTRICT						{ $$ = RESTRICT; }
		| /* EMPTY */					{ $$ = RESTRICT; /* default */ }
1206 1207
		;

1208

1209 1210

/*****************************************************************************
1211
 *
1212 1213
 *		QUERY :
 *				close <optname>
1214
 *
1215 1216
 *****************************************************************************/

1217
ClosePortalStmt:  CLOSE opt_id
1218 1219 1220 1221 1222 1223
				{
					ClosePortalStmt *n = makeNode(ClosePortalStmt);
					n->portalname = $2;
					$$ = (Node *)n;
				}
		;
1224

1225 1226 1227 1228
opt_id:  ColId									{ $$ = $1; }
		| /*EMPTY*/								{ $$ = NULL; }
		;

1229 1230 1231

/*****************************************************************************
 *
1232 1233 1234
 *		QUERY :
 *				COPY [BINARY] <relname> FROM/TO
 *				[USING DELIMITERS <delimiter>]
1235 1236 1237
 *
 *****************************************************************************/

1238
CopyStmt:  COPY opt_binary qualified_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
1239 1240 1241
				{
					CopyStmt *n = makeNode(CopyStmt);
					n->binary = $2;
1242
					n->relation = $3;
1243 1244 1245 1246
					n->oids = $4;
					n->direction = $5;
					n->filename = $6;
					n->delimiter = $7;
1247
					n->null_print = $8;
1248 1249 1250 1251 1252 1253
					$$ = (Node *)n;
				}
		;

copy_dirn:	TO
				{ $$ = TO; }
1254
		| FROM
1255 1256
				{ $$ = FROM; }
		;
1257

1258
/*
1259 1260
 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
 * used depends on the direction. (It really doesn't make sense to copy from
1261
 * stdout. We silently correct the "typo".		 - AY 9/94
1262
 */
1263 1264 1265 1266
copy_file_name:  Sconst							{ $$ = $1; }
		| STDIN									{ $$ = NULL; }
		| STDOUT								{ $$ = NULL; }
		;
1267

1268 1269
opt_binary:  BINARY								{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
1270
		;
1271

1272
opt_with_copy:	WITH OIDS						{ $$ = TRUE; }
1273
		| /*EMPTY*/								{ $$ = FALSE; }
1274
		;
1275

1276 1277 1278
/*
 * the default copy delimiter is tab but the user can configure it
 */
Bruce Momjian's avatar
Bruce Momjian committed
1279
copy_delimiter:  opt_using DELIMITERS Sconst	{ $$ = $3; }
1280
		| /*EMPTY*/								{ $$ = "\t"; }
1281
		;
1282

Bruce Momjian's avatar
Bruce Momjian committed
1283 1284 1285 1286
opt_using:	USING								{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = TRUE; }
		;

1287 1288 1289
copy_null:  WITH NULL_P AS Sconst				{ $$ = $4; }
		| /*EMPTY*/								{ $$ = "\\N"; }
		;
1290 1291 1292

/*****************************************************************************
 *
1293 1294
 *		QUERY :
 *				CREATE relname
1295 1296 1297
 *
 *****************************************************************************/

1298
CreateStmt:  CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' OptInherit OptWithOids
1299 1300
				{
					CreateStmt *n = makeNode(CreateStmt);
1301 1302
					$4->istemp = $2;
					n->relation = $4;
1303
					n->tableElts = $6;
1304
					n->inhRelations = $8;
1305
					n->constraints = NIL;
1306
					n->hasoids = $9;
1307 1308 1309 1310
					$$ = (Node *)n;
				}
		;

1311 1312 1313 1314 1315 1316 1317 1318 1319
/*
 * Redundancy here is needed to avoid shift/reduce conflicts,
 * since TEMP is not a reserved word.  See also OptTempTableName.
 */
OptTemp:      TEMPORARY						{ $$ = TRUE; }
			| TEMP							{ $$ = TRUE; }
			| LOCAL TEMPORARY				{ $$ = TRUE; }
			| LOCAL TEMP					{ $$ = TRUE; }
			| GLOBAL TEMPORARY
1320 1321 1322 1323
				{
					elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
					$$ = TRUE;
				}
1324
			| GLOBAL TEMP
1325
				{
1326 1327
					elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
					$$ = TRUE;
1328
				}
1329
			| /*EMPTY*/						{ $$ = FALSE; }
1330 1331
		;

1332
OptTableElementList:  OptTableElementList ',' OptTableElement
1333 1334 1335 1336 1337 1338 1339 1340 1341
				{
					if ($3 != NULL)
						$$ = lappend($1, $3);
					else
						$$ = $1;
				}
			| OptTableElement
				{
					if ($1 != NULL)
1342
						$$ = makeList1($1);
1343
					else
1344
						$$ = NIL;
1345
				}
1346
			| /*EMPTY*/							{ $$ = NIL; }
1347
		;
1348

1349 1350
OptTableElement:  columnDef						{ $$ = $1; }
			| TableConstraint					{ $$ = $1; }
1351
		;
1352

1353
columnDef:  ColId Typename ColQualList opt_collate
1354 1355 1356 1357 1358
				{
					ColumnDef *n = makeNode(ColumnDef);
					n->colname = $1;
					n->typename = $2;
					n->constraints = $3;
1359

1360
					if ($4 != NULL)
Bruce Momjian's avatar
Bruce Momjian committed
1361
						elog(NOTICE,"CREATE TABLE / COLLATE %s not yet implemented"
1362
							 "; clause ignored", $4);
1363

1364 1365 1366 1367
					$$ = (Node *)n;
				}
		;

1368 1369
ColQualList:  ColQualList ColConstraint		{ $$ = lappend($1, $2); }
			| /*EMPTY*/						{ $$ = NIL; }
1370 1371
		;

1372 1373
ColConstraint:
		CONSTRAINT name ColConstraintElem
1374
				{
Jan Wieck's avatar
Jan Wieck committed
1375 1376 1377 1378 1379
					switch (nodeTag($3))
					{
						case T_Constraint:
							{
								Constraint *n = (Constraint *)$3;
1380
								n->name = $2;
Jan Wieck's avatar
Jan Wieck committed
1381 1382 1383 1384 1385
							}
							break;
						case T_FkConstraint:
							{
								FkConstraint *n = (FkConstraint *)$3;
1386
								n->constr_name = $2;
Jan Wieck's avatar
Jan Wieck committed
1387 1388 1389 1390 1391 1392
							}
							break;
						default:
							break;
					}
					$$ = $3;
1393 1394 1395
				}
		| ColConstraintElem
				{ $$ = $1; }
1396
		| ConstraintAttr
1397 1398 1399 1400
				{ $$ = $1; }
		;

/* DEFAULT NULL is already the default for Postgres.
1401
 * But define it here and carry it forward into the system
1402 1403
 * to make it explicit.
 * - thomas 1998-09-13
1404
 *
1405 1406 1407 1408 1409
 * WITH NULL and NULL are not SQL92-standard syntax elements,
 * so leave them out. Use DEFAULT NULL to explicitly indicate
 * that a column may have that value. WITH NULL leads to
 * shift/reduce conflicts with WITH TIME ZONE anyway.
 * - thomas 1999-01-08
1410 1411 1412 1413
 *
 * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce
 * conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
 * or be part of a_expr NOT LIKE or similar constructs).
1414
 */
1415 1416
ColConstraintElem:
			  NOT NULL_P
1417
				{
1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_NOTNULL;
					n->name = NULL;
					n->raw_expr = NULL;
					n->cooked_expr = NULL;
					n->keys = NULL;
					$$ = (Node *)n;
				}
			| NULL_P
				{
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_NULL;
					n->name = NULL;
					n->raw_expr = NULL;
					n->cooked_expr = NULL;
					n->keys = NULL;
					$$ = (Node *)n;
1435 1436
				}
			| UNIQUE
1437 1438
				{
					Constraint *n = makeNode(Constraint);
1439
					n->contype = CONSTR_UNIQUE;
1440
					n->name = NULL;
1441 1442
					n->raw_expr = NULL;
					n->cooked_expr = NULL;
1443 1444 1445
					n->keys = NULL;
					$$ = (Node *)n;
				}
1446
			| PRIMARY KEY
1447
				{
1448 1449 1450 1451 1452 1453 1454
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_PRIMARY;
					n->name = NULL;
					n->raw_expr = NULL;
					n->cooked_expr = NULL;
					n->keys = NULL;
					$$ = (Node *)n;
1455
				}
1456
			| CHECK '(' a_expr ')'
1457 1458
				{
					Constraint *n = makeNode(Constraint);
1459
					n->contype = CONSTR_CHECK;
1460
					n->name = NULL;
1461
					n->raw_expr = $3;
1462
					n->cooked_expr = NULL;
1463 1464 1465
					n->keys = NULL;
					$$ = (Node *)n;
				}
1466 1467 1468 1469 1470
			| DEFAULT b_expr
				{
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_DEFAULT;
					n->name = NULL;
1471 1472
					if (exprIsNullConstant($2))
					{
1473
						/* DEFAULT NULL should be reported as empty expr */
1474 1475 1476 1477 1478 1479
						n->raw_expr = NULL;
					}
					else
					{
						n->raw_expr = $2;
					}
1480 1481 1482 1483
					n->cooked_expr = NULL;
					n->keys = NULL;
					$$ = (Node *)n;
				}
1484
			| REFERENCES qualified_name opt_column_list key_match key_actions 
1485
				{
Jan Wieck's avatar
Jan Wieck committed
1486 1487
					FkConstraint *n = makeNode(FkConstraint);
					n->constr_name		= NULL;
1488
					n->pktable			= $2;
Jan Wieck's avatar
Jan Wieck committed
1489 1490 1491 1492
					n->fk_attrs			= NIL;
					n->pk_attrs			= $3;
					n->match_type		= $4;
					n->actions			= $5;
1493 1494
					n->deferrable		= FALSE;
					n->initdeferred		= FALSE;
Jan Wieck's avatar
Jan Wieck committed
1495
					$$ = (Node *)n;
1496
				}
1497
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1498

1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510
/*
 * ConstraintAttr represents constraint attributes, which we parse as if
 * they were independent constraint clauses, in order to avoid shift/reduce
 * conflicts (since NOT might start either an independent NOT NULL clause
 * or an attribute).  analyze.c is responsible for attaching the attribute
 * information to the preceding "real" constraint node, and for complaining
 * if attribute clauses appear in the wrong place or wrong combinations.
 *
 * See also ConstraintAttributeSpec, which can be used in places where
 * there is no parsing conflict.
 */
ConstraintAttr: DEFERRABLE
1511 1512
				{
					Constraint *n = makeNode(Constraint);
1513
					n->contype = CONSTR_ATTR_DEFERRABLE;
1514 1515
					$$ = (Node *)n;
				}
1516
			| NOT DEFERRABLE
1517 1518
				{
					Constraint *n = makeNode(Constraint);
1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531
					n->contype = CONSTR_ATTR_NOT_DEFERRABLE;
					$$ = (Node *)n;
				}
			| INITIALLY DEFERRED
				{
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_ATTR_DEFERRED;
					$$ = (Node *)n;
				}
			| INITIALLY IMMEDIATE
				{
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_ATTR_IMMEDIATE;
1532 1533
					$$ = (Node *)n;
				}
1534 1535
		;

1536

1537 1538 1539 1540 1541
/* ConstraintElem specifies constraint syntax which is not embedded into
 *  a column definition. ColConstraintElem specifies the embedded form.
 * - thomas 1997-12-03
 */
TableConstraint:  CONSTRAINT name ConstraintElem
1542
				{
Jan Wieck's avatar
Jan Wieck committed
1543 1544 1545 1546 1547
					switch (nodeTag($3))
					{
						case T_Constraint:
							{
								Constraint *n = (Constraint *)$3;
1548
								n->name = $2;
Jan Wieck's avatar
Jan Wieck committed
1549 1550 1551 1552 1553
							}
							break;
						case T_FkConstraint:
							{
								FkConstraint *n = (FkConstraint *)$3;
1554
								n->constr_name = $2;
Jan Wieck's avatar
Jan Wieck committed
1555 1556 1557 1558 1559 1560
							}
							break;
						default:
							break;
					}
					$$ = $3;
1561
				}
1562 1563
		| ConstraintElem
				{ $$ = $1; }
1564 1565
		;

1566
ConstraintElem:  CHECK '(' a_expr ')'
1567
				{
1568 1569 1570
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_CHECK;
					n->name = NULL;
1571 1572
					n->raw_expr = $3;
					n->cooked_expr = NULL;
1573
					$$ = (Node *)n;
1574
				}
1575
		| UNIQUE '(' columnList ')'
1576 1577 1578 1579
				{
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_UNIQUE;
					n->name = NULL;
1580 1581
					n->raw_expr = NULL;
					n->cooked_expr = NULL;
1582 1583 1584
					n->keys = $3;
					$$ = (Node *)n;
				}
1585
		| PRIMARY KEY '(' columnList ')'
1586
				{
1587 1588 1589 1590 1591 1592
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_PRIMARY;
					n->name = NULL;
					n->raw_expr = NULL;
					n->cooked_expr = NULL;
					n->keys = $4;
1593 1594
					$$ = (Node *)n;
				}
1595
		| FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list
1596
				key_match key_actions ConstraintAttributeSpec
Jan Wieck's avatar
Jan Wieck committed
1597 1598 1599
				{
					FkConstraint *n = makeNode(FkConstraint);
					n->constr_name		= NULL;
1600
					n->pktable			= $7;
Jan Wieck's avatar
Jan Wieck committed
1601 1602 1603 1604 1605 1606 1607
					n->fk_attrs			= $4;
					n->pk_attrs			= $8;
					n->match_type		= $9;
					n->actions			= $10;
					n->deferrable		= ($11 & 1) != 0;
					n->initdeferred		= ($11 & 2) != 0;
					$$ = (Node *)n;
1608
				}
1609
		;
1610

1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628
opt_column_list:  '(' columnList ')'			{ $$ = $2; }
		| /*EMPTY*/								{ $$ = NIL; }
		;

columnList:  columnList ',' columnElem
				{ $$ = lappend($1, $3); }
		| columnElem
				{ $$ = makeList1($1); }
		;

columnElem:  ColId
				{
					Ident *id = makeNode(Ident);
					id->name = $1;
					$$ = (Node *)id;
				}
		;

Jan Wieck's avatar
Jan Wieck committed
1629 1630 1631 1632 1633 1634
key_match:  MATCH FULL
			{
				$$ = "FULL";
			}
		| MATCH PARTIAL
			{
1635
				elog(ERROR, "FOREIGN KEY/MATCH PARTIAL not yet implemented");
Jan Wieck's avatar
Jan Wieck committed
1636 1637 1638 1639 1640 1641
				$$ = "PARTIAL";
			}
		| /*EMPTY*/
			{
				$$ = "UNSPECIFIED";
			}
1642 1643
		;

1644 1645 1646 1647
key_actions:  key_delete				{ $$ = $1; }
		| key_update					{ $$ = $1; }
		| key_delete key_update			{ $$ = $1 | $2; }
		| key_update key_delete			{ $$ = $1 | $2; }
Jan Wieck's avatar
Jan Wieck committed
1648
		| /*EMPTY*/						{ $$ = 0; }
1649 1650
		;

1651 1652 1653 1654
key_delete:  ON DELETE key_reference	{ $$ = $3 << FKCONSTR_ON_DELETE_SHIFT; }
		;

key_update:  ON UPDATE key_reference	{ $$ = $3 << FKCONSTR_ON_UPDATE_SHIFT; }
1655 1656
		;

Jan Wieck's avatar
Jan Wieck committed
1657 1658 1659 1660 1661
key_reference:  NO ACTION				{ $$ = FKCONSTR_ON_KEY_NOACTION; }
		| RESTRICT						{ $$ = FKCONSTR_ON_KEY_RESTRICT; }
		| CASCADE						{ $$ = FKCONSTR_ON_KEY_CASCADE; }
		| SET NULL_P					{ $$ = FKCONSTR_ON_KEY_SETNULL; }
		| SET DEFAULT					{ $$ = FKCONSTR_ON_KEY_SETDEFAULT; }
1662 1663
		;

1664
OptInherit:  INHERITS '(' qualified_name_list ')'	{ $$ = $3; }
1665
		| /*EMPTY*/									{ $$ = NIL; }
1666 1667
		;

1668 1669 1670 1671 1672 1673
OptWithOids:  WITH OIDS						{ $$ = TRUE; }
			| WITHOUT OIDS					{ $$ = FALSE; }
			| /*EMPTY*/						{ $$ = TRUE; }
		;


1674 1675 1676 1677 1678
/*
 * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
 * SELECT ... INTO.
 */

1679
CreateAsStmt:  CREATE OptTemp TABLE qualified_name OptCreateAs AS SelectStmt
1680
				{
1681 1682 1683 1684 1685 1686 1687
					/*
					 * When the SelectStmt is a set-operation tree, we must
					 * stuff the INTO information into the leftmost component
					 * Select, because that's where analyze.c will expect
					 * to find it.  Similarly, the output column names must
					 * be attached to that Select's target list.
					 */
1688
					SelectStmt *n = findLeftmostSelect((SelectStmt *) $7);
1689
					if (n->into != NULL)
1690
						elog(ERROR,"CREATE TABLE AS may not specify INTO");
1691
					$4->istemp = $2;
1692
					n->into = $4;
1693
					n->intoColNames = $5;
1694
					$$ = $7;
1695 1696 1697 1698
				}
		;

OptCreateAs:  '(' CreateAsList ')'				{ $$ = $2; }
1699
			| /*EMPTY*/							{ $$ = NIL; }
1700 1701 1702
		;

CreateAsList:  CreateAsList ',' CreateAsElement	{ $$ = lappend($1, $3); }
1703
			| CreateAsElement					{ $$ = makeList1($1); }
1704 1705 1706 1707 1708 1709 1710
		;

CreateAsElement:  ColId
				{
					ColumnDef *n = makeNode(ColumnDef);
					n->colname = $1;
					n->typename = NULL;
1711 1712
					n->raw_default = NULL;
					n->cooked_default = NULL;
1713 1714 1715 1716 1717 1718
					n->is_not_null = FALSE;
					n->constraints = NULL;
					$$ = (Node *)n;
				}
		;

1719

Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1720 1721
/*****************************************************************************
 *
1722 1723
 *		QUERY :
 *				CREATE SEQUENCE seqname
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1724 1725 1726
 *
 *****************************************************************************/

1727
CreateSeqStmt:  CREATE OptTemp SEQUENCE qualified_name OptSeqList
1728 1729
				{
					CreateSeqStmt *n = makeNode(CreateSeqStmt);
1730 1731
					$4->istemp = $2;
					n->sequence = $4;
1732
					n->options = $5;
1733 1734 1735
					$$ = (Node *)n;
				}
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1736

1737
OptSeqList:  OptSeqList OptSeqElem
1738
				{ $$ = lappend($1, $2); }
1739
			|	{ $$ = NIL; }
1740 1741
		;

1742
OptSeqElem:  CACHE NumericOnly
1743 1744
				{
					$$ = makeNode(DefElem);
1745
					$$->defname = "cache";
1746 1747
					$$->arg = (Node *)$2;
				}
1748
			| CYCLE
1749 1750
				{
					$$ = makeNode(DefElem);
1751
					$$->defname = "cycle";
1752 1753
					$$->arg = (Node *)NULL;
				}
1754
			| INCREMENT NumericOnly
1755 1756 1757 1758 1759
				{
					$$ = makeNode(DefElem);
					$$->defname = "increment";
					$$->arg = (Node *)$2;
				}
1760
			| MAXVALUE NumericOnly
1761 1762 1763 1764 1765
				{
					$$ = makeNode(DefElem);
					$$->defname = "maxvalue";
					$$->arg = (Node *)$2;
				}
1766
			| MINVALUE NumericOnly
1767 1768 1769 1770 1771
				{
					$$ = makeNode(DefElem);
					$$->defname = "minvalue";
					$$->arg = (Node *)$2;
				}
1772
			| START NumericOnly
1773 1774 1775 1776 1777 1778 1779
				{
					$$ = makeNode(DefElem);
					$$->defname = "start";
					$$->arg = (Node *)$2;
				}
		;

1780 1781
NumericOnly:  FloatOnly					{ $$ = $1; }
			| IntegerOnly				{ $$ = $1; }
1782
		;
1783 1784 1785 1786 1787 1788 1789 1790

FloatOnly:  FCONST
				{
					$$ = makeFloat($1);
				}
			| '-' FCONST
				{
					$$ = makeFloat($2);
1791
					doNegateFloat($$);
1792 1793 1794
				}
		;

1795 1796 1797 1798 1799 1800 1801 1802 1803
IntegerOnly:  Iconst
				{
					$$ = makeInteger($1);
				}
			| '-' Iconst
				{
					$$ = makeInteger($2);
					$$->val.ival = - $$->val.ival;
				}
1804
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1805

1806 1807 1808 1809 1810 1811 1812 1813
/*****************************************************************************
 *
 *		QUERIES :
 *				CREATE PROCEDURAL LANGUAGE ...
 *				DROP PROCEDURAL LANGUAGE ...
 *
 *****************************************************************************/

1814 1815
CreatePLangStmt:  CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
			HANDLER func_name opt_lancompiler
1816 1817 1818 1819
			{
				CreatePLangStmt *n = makeNode(CreatePLangStmt);
				n->plname = $5;
				n->plhandler = $7;
1820
				n->plcompiler = $8;
1821 1822 1823 1824 1825
				n->pltrusted = $2;
				$$ = (Node *)n;
			}
		;

1826
opt_trusted:  TRUSTED			{ $$ = TRUE; }
1827
			| /*EMPTY*/			{ $$ = FALSE; }
1828
		;
1829

1830 1831
opt_lancompiler: LANCOMPILER Sconst { $$ = $2; }
			| /*EMPTY*/			{ $$ = ""; }
1832
		;
1833 1834

DropPLangStmt:  DROP opt_procedural LANGUAGE ColId_or_Sconst
1835 1836 1837 1838 1839 1840
			{
				DropPLangStmt *n = makeNode(DropPLangStmt);
				n->plname = $4;
				$$ = (Node *)n;
			}
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1841

1842 1843 1844 1845
opt_procedural: PROCEDURAL		{ $$ = TRUE; }
			| /*EMPTY*/			{ $$ = TRUE; }
		;
		
1846 1847
/*****************************************************************************
 *
1848 1849 1850
 *		QUERIES :
 *				CREATE TRIGGER ...
 *				DROP TRIGGER ...
1851 1852 1853
 *
 *****************************************************************************/

1854
CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1855
				qualified_name TriggerForSpec EXECUTE PROCEDURE
1856 1857 1858 1859
				name '(' TriggerFuncArgs ')'
				{
					CreateTrigStmt *n = makeNode(CreateTrigStmt);
					n->trigname = $3;
1860
					n->relation = $7;
1861 1862 1863 1864 1865
					n->funcname = $11;
					n->args = $13;
					n->before = $4;
					n->row = $8;
					memcpy (n->actions, $5, 4);
1866 1867 1868 1869 1870
					n->lang = NULL;		/* unused */
					n->text = NULL;		/* unused */
					n->attr = NULL;		/* unused */
					n->when = NULL;		/* unused */

1871 1872 1873
					n->isconstraint  = FALSE;
					n->deferrable    = FALSE;
					n->initdeferred  = FALSE;
1874
					n->constrrel = NULL;
1875 1876
					$$ = (Node *)n;
				}
1877
		| CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
1878
				qualified_name OptConstrFromTable 
1879
				ConstraintAttributeSpec
1880 1881 1882 1883
				FOR EACH ROW EXECUTE PROCEDURE name '(' TriggerFuncArgs ')'
				{
					CreateTrigStmt *n = makeNode(CreateTrigStmt);
					n->trigname = $4;
1884
					n->relation = $8;
Jan Wieck's avatar
Jan Wieck committed
1885 1886
					n->funcname = $16;
					n->args = $18;
1887 1888
					n->before = FALSE;
					n->row = TRUE;
1889
					memcpy (n->actions, $6, 4);
1890 1891 1892 1893 1894
					n->lang = NULL;		/* unused */
					n->text = NULL;		/* unused */
					n->attr = NULL;		/* unused */
					n->when = NULL;		/* unused */

1895
					n->isconstraint  = TRUE;
Jan Wieck's avatar
Jan Wieck committed
1896 1897
					n->deferrable = ($10 & 1) != 0;
					n->initdeferred = ($10 & 2) != 0;
1898

1899
					n->constrrel = $9;
1900 1901 1902 1903
					$$ = (Node *)n;
				}
		;

1904 1905
TriggerActionTime:  BEFORE						{ $$ = TRUE; }
			| AFTER								{ $$ = FALSE; }
1906 1907 1908
		;

TriggerEvents:	TriggerOneEvent
1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923
				{
					char *e = palloc (4);
					e[0] = $1; e[1] = 0; $$ = e;
				}
			| TriggerOneEvent OR TriggerOneEvent
				{
					char *e = palloc (4);
					e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
				}
			| TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
				{
					char *e = palloc (4);
					e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
					$$ = e;
				}
1924 1925
		;

1926 1927 1928
TriggerOneEvent:  INSERT					{ $$ = 'i'; }
			| DELETE						{ $$ = 'd'; }
			| UPDATE						{ $$ = 'u'; }
1929 1930
		;

1931
TriggerForSpec:  FOR TriggerForOpt TriggerForType
1932
				{
1933
					$$ = $3;
1934 1935
				}
		;
1936

1937 1938 1939 1940 1941 1942 1943 1944
TriggerForOpt:  EACH						{ $$ = TRUE; }
			| /*EMPTY*/						{ $$ = FALSE; }
		;

TriggerForType:  ROW						{ $$ = TRUE; }
			| STATEMENT						{ $$ = FALSE; }
		;

1945
TriggerFuncArgs:  TriggerFuncArg
1946
				{ $$ = makeList1($1); }
1947
			| TriggerFuncArgs ',' TriggerFuncArg
1948
				{ $$ = lappend($1, $3); }
1949
			| /*EMPTY*/
1950
				{ $$ = NIL; }
1951 1952
		;

1953
TriggerFuncArg:  ICONST
1954
				{
1955 1956
					char buf[64];
					sprintf (buf, "%d", $1);
1957 1958 1959 1960 1961 1962 1963 1964 1965 1966
					$$ = makeString(pstrdup(buf));
				}
			| FCONST
				{
					$$ = makeString($1);
				}
			| Sconst
				{
					$$ = makeString($1);
				}
1967 1968 1969 1970
			| BITCONST
				{
					$$ = makeString($1);
				}
1971 1972 1973
			| ColId
				{
					$$ = makeString($1);
1974
				}
1975
		;
1976

1977 1978
OptConstrFromTable:			/* Empty */
				{
1979
					$$ = NULL;
1980
				}
1981
		| FROM qualified_name
1982 1983 1984 1985 1986
				{
					$$ = $2;
				}
		;

1987 1988 1989
ConstraintAttributeSpec:  ConstraintDeferrabilitySpec
			{ $$ = $1; }
		| ConstraintDeferrabilitySpec ConstraintTimeSpec
Jan Wieck's avatar
Jan Wieck committed
1990
			{
1991 1992 1993
				if ($1 == 0 && $2 != 0)
					elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
				$$ = $1 | $2;
Jan Wieck's avatar
Jan Wieck committed
1994
			}
1995
		| ConstraintTimeSpec
Jan Wieck's avatar
Jan Wieck committed
1996 1997 1998 1999
			{
				if ($1 != 0)
					$$ = 3;
				else
2000
					$$ = 0;
Jan Wieck's avatar
Jan Wieck committed
2001
			}
2002
		| ConstraintTimeSpec ConstraintDeferrabilitySpec
Jan Wieck's avatar
Jan Wieck committed
2003 2004 2005 2006 2007
			{
				if ($2 == 0 && $1 != 0)
					elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
				$$ = $1 | $2;
			}
2008 2009
		| /* Empty */
			{ $$ = 0; }
2010 2011
		;

2012 2013 2014 2015
ConstraintDeferrabilitySpec: NOT DEFERRABLE
			{ $$ = 0; }
		| DEFERRABLE
			{ $$ = 1; }
Jan Wieck's avatar
Jan Wieck committed
2016 2017
		;

2018 2019 2020 2021
ConstraintTimeSpec: INITIALLY IMMEDIATE
			{ $$ = 0; }
		| INITIALLY DEFERRED
			{ $$ = 2; }
2022
		;
2023

2024

2025
DropTrigStmt:  DROP TRIGGER name ON qualified_name
2026 2027 2028
				{
					DropTrigStmt *n = makeNode(DropTrigStmt);
					n->trigname = $3;
2029
					n->relation = $5;
2030 2031 2032
					$$ = (Node *) n;
				}
		;
2033

2034

2035 2036
/*****************************************************************************
 *
2037
 *		QUERY :
2038
 *				define (aggregate,operator,type)
2039 2040 2041
 *
 *****************************************************************************/

2042
DefineStmt:  CREATE AGGREGATE func_name definition
2043
				{
2044
					DefineStmt *n = makeNode(DefineStmt);
2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061
					n->defType = AGGREGATE;
					n->defname = $3;
					n->definition = $4;
					$$ = (Node *)n;
				}
		| CREATE OPERATOR all_Op definition
				{
					DefineStmt *n = makeNode(DefineStmt);
					n->defType = OPERATOR;
					n->defname = $3;
					n->definition = $4;
					$$ = (Node *)n;
				}
		| CREATE TYPE_P name definition
				{
					DefineStmt *n = makeNode(DefineStmt);
					n->defType = TYPE_P;
2062 2063 2064
					n->defname = $3;
					n->definition = $4;
					$$ = (Node *)n;
2065 2066
				}
		;
2067

2068
definition:  '(' def_list ')'				{ $$ = $2; }
2069
		;
2070

2071
def_list:  def_elem							{ $$ = makeList1($1); }
2072
		| def_list ',' def_elem				{ $$ = lappend($1, $3); }
2073
		;
2074

Tom Lane's avatar
Tom Lane committed
2075
def_elem:  ColLabel '=' def_arg
2076 2077 2078 2079 2080
				{
					$$ = makeNode(DefElem);
					$$->defname = $1;
					$$->arg = (Node *)$3;
				}
Tom Lane's avatar
Tom Lane committed
2081
		| ColLabel
2082 2083 2084 2085 2086 2087 2088
				{
					$$ = makeNode(DefElem);
					$$->defname = $1;
					$$->arg = (Node *)NULL;
				}
		;

2089
/* Note: any simple identifier will be returned as a type name! */
2090
def_arg:  func_return  					{  $$ = (Node *)$1; }
2091
		| all_Op						{  $$ = (Node *)makeString($1); }
2092
		| NumericOnly					{  $$ = (Node *)$1; }
2093
		| Sconst						{  $$ = (Node *)makeString($1); }
2094
		;
2095 2096 2097 2098


/*****************************************************************************
 *
2099
 *		QUERY:
2100 2101
 *
 *		DROP itemtype itemname [, itemname ...]
2102 2103 2104
 *
 *****************************************************************************/

2105 2106 2107 2108
/* DropStmt needs to use qualified_name_list as many of the objects
 * are relations or other schema objects (names can be schema-qualified) */
 
DropStmt:  DROP drop_type qualified_name_list opt_drop_behavior
2109 2110
				{
					DropStmt *n = makeNode(DropStmt);
2111
					n->removeType = $2;
2112
					n->objects = $3;
2113
					n->behavior = $4;
2114 2115 2116
					$$ = (Node *)n;
				}
		;
2117

2118 2119 2120 2121 2122
drop_type: TABLE								{ $$ = DROP_TABLE; }
		| SEQUENCE								{ $$ = DROP_SEQUENCE; }
		| VIEW									{ $$ = DROP_VIEW; }
		| INDEX									{ $$ = DROP_INDEX; }
		| RULE									{ $$ = DROP_RULE; }
Tom Lane's avatar
Tom Lane committed
2123 2124
		| TYPE_P								{ $$ = DROP_TYPE; }
		| DOMAIN_P								{ $$ = DROP_DOMAIN; }
2125 2126
		;

2127 2128 2129 2130 2131 2132 2133
/*****************************************************************************
 *
 *		QUERY:
 *				truncate table relname
 *
 *****************************************************************************/

2134
TruncateStmt:  TRUNCATE opt_table qualified_name
2135 2136
				{
					TruncateStmt *n = makeNode(TruncateStmt);
2137
					n->relation = $3;
2138 2139 2140
					$$ = (Node *)n;
				}
			;
2141

2142 2143
/*****************************************************************************
 *
Bruce Momjian's avatar
Bruce Momjian committed
2144 2145 2146
 *  The COMMENT ON statement can take different forms based upon the type of
 *  the object associated with the comment. The form of the statement is:
 *
2147
 *  COMMENT ON [ [ DATABASE | DOMAIN | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] 
2148
 *               <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION 
Bruce Momjian's avatar
Bruce Momjian committed
2149 2150 2151
 *		 <funcname> (arg1, arg2, ...) | OPERATOR <op> 
 *		 (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
 *		 <relname> ] IS 'text'
2152 2153 2154
 *
 *****************************************************************************/
 
2155
CommentStmt:	COMMENT ON comment_type name IS comment_text
Bruce Momjian's avatar
Bruce Momjian committed
2156 2157 2158 2159 2160 2161 2162 2163 2164
			{
				CommentStmt *n = makeNode(CommentStmt);
				n->objtype = $3;
				n->objname = $4;
				n->objproperty = NULL;
				n->objlist = NULL;
				n->comment = $6;
				$$ = (Node *) n;
			}
2165
		| COMMENT ON COLUMN ColId '.' attr_name IS comment_text
2166
			{
2167 2168 2169 2170 2171 2172 2173 2174
				/*
				 * We can't use qualified_name here as the '.' causes a shift/red; 
				 * with ColId we do not test for NEW and OLD as table names, but it is OK
				 * as they would fail anyway as COMMENT cannot appear in a RULE.
				 * ColumnRef is also innapropriate as we don't take subscripts
				 * or '*' and have a very precise number of elements (2 or 3)
				 * so we do it from scratch.
				 */
2175
				CommentStmt *n = makeNode(CommentStmt);
2176
				n->objtype = COLUMN;
2177
				n->objschema = NULL;
Bruce Momjian's avatar
Bruce Momjian committed
2178 2179 2180
				n->objname = $4;
				n->objproperty = $6;
				n->objlist = NULL;
2181 2182 2183
				n->comment = $8;
				$$ = (Node *) n;
			}
2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194
		| COMMENT ON COLUMN ColId '.' ColId '.' attr_name IS comment_text
			{
				CommentStmt *n = makeNode(CommentStmt);
				n->objtype = COLUMN;
				n->objschema = $4;
				n->objname = $6;
				n->objproperty = $8;
				n->objlist = NULL;
				n->comment = $10;
				$$ = (Node *) n;
			}
2195
		| COMMENT ON AGGREGATE name '(' aggr_argtype ')' IS comment_text
Bruce Momjian's avatar
Bruce Momjian committed
2196
			{
2197
				CommentStmt *n = makeNode(CommentStmt);
2198
				n->objtype = AGGREGATE;
2199
				n->objschema = NULL;
2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210
				n->objname = $4;
				n->objproperty = NULL;
				n->objlist = makeList1($6);
				n->comment = $9;
				$$ = (Node *) n;
			}
		| COMMENT ON AGGREGATE name aggr_argtype IS comment_text
			{
				/* Obsolete syntax, but must support for awhile */
				CommentStmt *n = makeNode(CommentStmt);
				n->objtype = AGGREGATE;
2211
				n->objschema = NULL;
Bruce Momjian's avatar
Bruce Momjian committed
2212
				n->objname = $4;
2213 2214
				n->objproperty = NULL;
				n->objlist = makeList1($5);
Bruce Momjian's avatar
Bruce Momjian committed
2215 2216 2217
				n->comment = $7;
				$$ = (Node *) n;
			}
2218
		| COMMENT ON FUNCTION func_name func_args IS comment_text
Bruce Momjian's avatar
Bruce Momjian committed
2219 2220
			{
				CommentStmt *n = makeNode(CommentStmt);
2221
				n->objtype = FUNCTION;
2222
				n->objschema = NULL;
Bruce Momjian's avatar
Bruce Momjian committed
2223 2224 2225 2226 2227 2228
				n->objname = $4;
				n->objproperty = NULL;
				n->objlist = $5;
				n->comment = $7;
				$$ = (Node *) n;
			}
2229
		| COMMENT ON OPERATOR all_Op '(' oper_argtypes ')' IS comment_text
Bruce Momjian's avatar
Bruce Momjian committed
2230 2231
			{
				CommentStmt *n = makeNode(CommentStmt);
2232
				n->objtype = OPERATOR;
2233
				n->objschema = NULL;
Bruce Momjian's avatar
Bruce Momjian committed
2234 2235 2236 2237
				n->objname = $4;
				n->objproperty = NULL;
				n->objlist = $6;
				n->comment = $9;
2238 2239
				$$ = (Node *) n;
			}
2240
		| COMMENT ON TRIGGER name ON qualified_name IS comment_text
Bruce Momjian's avatar
Bruce Momjian committed
2241 2242
			{
				CommentStmt *n = makeNode(CommentStmt);
2243
				n->objtype = TRIGGER;
2244 2245
				/* NOTE: schemaname here refers to the table in objproperty */
				n->objschema = $6->schemaname;
Bruce Momjian's avatar
Bruce Momjian committed
2246
				n->objname = $4;
2247
				n->objproperty = $6->relname;
Bruce Momjian's avatar
Bruce Momjian committed
2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258
				n->objlist = NULL;
				n->comment = $8;
				$$ = (Node *) n;
			}
		;

comment_type:	DATABASE { $$ = DATABASE; }
		| INDEX { $$ = INDEX; }
		| RULE { $$ = RULE; }
		| SEQUENCE { $$ = SEQUENCE; }
		| TABLE { $$ = TABLE; }
2259
		| DOMAIN_P { $$ = TYPE_P; }
Bruce Momjian's avatar
Bruce Momjian committed
2260 2261 2262 2263
		| TYPE_P { $$ = TYPE_P; }
		| VIEW { $$ = VIEW; }
		;		

2264
comment_text:	Sconst { $$ = $1; }
2265
		| NULL_P { $$ = NULL; }
2266 2267
		;
		
2268 2269
/*****************************************************************************
 *
2270
 *		QUERY:
2271 2272 2273
 *			fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
 *			fetch [ forward | backward | absolute | relative ]
 *			      [ # | all | next | prior ] [ [ in | from ] <portalname> ]
2274 2275 2276
 *
 *****************************************************************************/

2277
FetchStmt:  FETCH direction fetch_how_many from_in name
2278 2279
				{
					FetchStmt *n = makeNode(FetchStmt);
2280 2281 2282
					if ($2 == RELATIVE)
					{
						if ($3 == 0)
2283
							elog(ERROR,"FETCH / RELATIVE at current position is not supported");
2284 2285 2286 2287 2288 2289 2290
						$2 = FORWARD;
					}
					if ($3 < 0)
					{
						$3 = -$3;
						$2 = (($2 == FORWARD)? BACKWARD: FORWARD);
					}
2291 2292
					n->direction = $2;
					n->howMany = $3;
2293
					n->portalname = $5;
2294
					n->ismove = FALSE;
2295 2296
					$$ = (Node *)n;
				}
2297
		| FETCH fetch_how_many from_in name
2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309
				{
					FetchStmt *n = makeNode(FetchStmt);
					if ($2 < 0)
					{
						n->howMany = -$2;
						n->direction = BACKWARD;
					}
					else
					{
						n->direction = FORWARD;
						n->howMany = $2;
					}
2310
					n->portalname = $4;
2311
					n->ismove = FALSE;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
2312 2313
					$$ = (Node *)n;
				}
2314
		| FETCH direction from_in name
2315 2316 2317 2318 2319 2320 2321 2322 2323
				{
					FetchStmt *n = makeNode(FetchStmt);
					if ($2 == RELATIVE)
					{
						$2 = FORWARD;
					}
					n->direction = $2;
					n->howMany = 1;
					n->portalname = $4;
2324
					n->ismove = FALSE;
2325 2326
					$$ = (Node *)n;
				}
2327
		| FETCH from_in name
2328 2329 2330 2331 2332
				{
					FetchStmt *n = makeNode(FetchStmt);
					n->direction = FORWARD;
					n->howMany = 1;
					n->portalname = $3;
2333
					n->ismove = FALSE;
2334 2335
					$$ = (Node *)n;
				}
2336
		| FETCH name
2337 2338 2339 2340 2341
				{
					FetchStmt *n = makeNode(FetchStmt);
					n->direction = FORWARD;
					n->howMany = 1;
					n->portalname = $2;
2342
					n->ismove = FALSE;
2343 2344 2345
					$$ = (Node *)n;
				}

2346
		| MOVE direction fetch_how_many from_in name
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
2347 2348
				{
					FetchStmt *n = makeNode(FetchStmt);
2349 2350 2351 2352 2353
					if ($3 < 0)
					{
						$3 = -$3;
						$2 = (($2 == FORWARD)? BACKWARD: FORWARD);
					}
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
2354 2355
					n->direction = $2;
					n->howMany = $3;
2356 2357 2358 2359
					n->portalname = $5;
					n->ismove = TRUE;
					$$ = (Node *)n;
				}
2360
		| MOVE fetch_how_many from_in name
2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372
				{
					FetchStmt *n = makeNode(FetchStmt);
					if ($2 < 0)
					{
						n->howMany = -$2;
						n->direction = BACKWARD;
					}
					else
					{
						n->direction = FORWARD;
						n->howMany = $2;
					}
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
2373
					n->portalname = $4;
2374
					n->ismove = TRUE;
2375 2376
					$$ = (Node *)n;
				}
2377
		| MOVE direction from_in name
2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394
				{
					FetchStmt *n = makeNode(FetchStmt);
					n->direction = $2;
					n->howMany = 1;
					n->portalname = $4;
					n->ismove = TRUE;
					$$ = (Node *)n;
				}
		|	MOVE from_in name
				{
					FetchStmt *n = makeNode(FetchStmt);
					n->direction = FORWARD;
					n->howMany = 1;
					n->portalname = $3;
					n->ismove = TRUE;
					$$ = (Node *)n;
				}
2395
		| MOVE name
2396 2397 2398 2399 2400 2401 2402 2403
				{
					FetchStmt *n = makeNode(FetchStmt);
					n->direction = FORWARD;
					n->howMany = 1;
					n->portalname = $2;
					n->ismove = TRUE;
					$$ = (Node *)n;
				}
2404 2405
		;

2406
direction:	FORWARD					{ $$ = FORWARD; }
2407 2408 2409 2410
		| BACKWARD						{ $$ = BACKWARD; }
		| RELATIVE						{ $$ = RELATIVE; }
		| ABSOLUTE
			{
Bruce Momjian's avatar
Bruce Momjian committed
2411
				elog(NOTICE,"FETCH / ABSOLUTE not supported, using RELATIVE");
2412 2413
				$$ = RELATIVE;
			}
2414
		;
2415

2416 2417
fetch_how_many:  Iconst					{ $$ = $1; }
		| '-' Iconst					{ $$ = - $2; }
2418
		| ALL							{ $$ = 0; /* 0 means fetch all tuples*/ }
2419 2420
		| NEXT							{ $$ = 1; }
		| PRIOR							{ $$ = -1; }
2421
		;
2422

2423 2424 2425
from_in:  IN 
	| FROM
	;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
2426

2427

2428 2429
/*****************************************************************************
 *
2430
 * GRANT and REVOKE statements
2431 2432 2433
 *
 *****************************************************************************/

2434
GrantStmt:  GRANT privileges ON privilege_target TO grantee_list opt_grant_grant_option
2435
				{
2436 2437 2438
					GrantStmt *n = makeNode(GrantStmt);
					n->is_grant = true;
					n->privileges = $2;
2439 2440 2441
					n->objtype = ($4)->objtype;
					n->objects = ($4)->objs;
					n->grantees = $6;
2442
					$$ = (Node*)n;
2443 2444
				}
		;
2445

2446
RevokeStmt:  REVOKE opt_revoke_grant_option privileges ON privilege_target FROM grantee_list
2447
				{
2448 2449 2450 2451 2452 2453 2454
					GrantStmt *n = makeNode(GrantStmt);
					n->is_grant = false;
					n->privileges = $3;
					n->objtype = ($5)->objtype;
					n->objects = ($5)->objs;
					n->grantees = $7;
					$$ = (Node *)n;
2455 2456 2457
				}
		;

2458 2459 2460 2461 2462

/* either ALL [PRIVILEGES] or a list of individual privileges */
privileges: privilege_list { $$ = $1; }
		| ALL { $$ = makeListi1(ALL); }
		| ALL PRIVILEGES { $$ = makeListi1(ALL); }
2463 2464
		;

2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484
privilege_list: privilege { $$ = makeListi1($1); }
		| privilege_list ',' privilege { $$ = lappendi($1, $3); }
		;

/* Not all of these privilege types apply to all objects, but that
   gets sorted out later. */
privilege: SELECT    { $$ = SELECT; }
		| INSERT     { $$ = INSERT; }
		| UPDATE     { $$ = UPDATE; }
		| DELETE     { $$ = DELETE; }
		| RULE       { $$ = RULE; }
		| REFERENCES { $$ = REFERENCES; }
		| TRIGGER    { $$ = TRIGGER; }
		| EXECUTE    { $$ = EXECUTE; }
		| USAGE      { $$ = USAGE; }
		;


/* Don't bother trying to fold the first two rules into one using
   opt_table.  You're going to get conflicts. */
2485
privilege_target: qualified_name_list
2486
				{
2487 2488 2489 2490
					PrivTarget *n = makeNode(PrivTarget);
					n->objtype = TABLE;
					n->objs = $1;
					$$ = n;
2491
				}
2492
			| TABLE qualified_name_list
2493
				{
2494 2495 2496 2497
					PrivTarget *n = makeNode(PrivTarget);
					n->objtype = TABLE;
					n->objs = $2;
					$$ = n;
2498
				}
2499
			| FUNCTION function_with_argtypes_list
2500
				{
2501 2502 2503 2504
					PrivTarget *n = makeNode(PrivTarget);
					n->objtype = FUNCTION;
					n->objs = $2;
					$$ = n;
2505
				}
2506
			| LANGUAGE name_list
2507
				{
2508 2509 2510 2511
					PrivTarget *n = makeNode(PrivTarget);
					n->objtype = LANGUAGE;
					n->objs = $2;
					$$ = n;
2512 2513 2514
				}
		;

2515 2516 2517 2518 2519

grantee_list: grantee					{ $$ = makeList1($1); }
		| grantee_list ',' grantee		{ $$ = lappend($1, $3); }
		;

2520 2521
grantee:  PUBLIC
				{
2522 2523 2524 2525
					PrivGrantee *n = makeNode(PrivGrantee);
					n->username = NULL;
					n->groupname = NULL;
					$$ = (Node *)n;
2526
				}
2527
		| GROUP ColId
2528
				{
2529 2530 2531 2532
					PrivGrantee *n = makeNode(PrivGrantee);
					n->username = NULL;
					n->groupname = $2;
					$$ = (Node *)n;
2533
				}
2534
		| ColId
2535
				{
2536 2537 2538 2539
					PrivGrantee *n = makeNode(PrivGrantee);
					n->username = $1;
					n->groupname = NULL;
					$$ = (Node *)n;
2540 2541
				}
		;
2542

2543

2544 2545 2546 2547 2548 2549
opt_grant_grant_option: WITH GRANT OPTION
				{
					elog(ERROR, "grant options are not implemented");
				}
		| /*EMPTY*/
		;
2550

2551
opt_revoke_grant_option: GRANT OPTION FOR
2552
				{
2553 2554
					elog(ERROR, "grant options are not implemented");
				}
2555
		| /*EMPTY*/
2556 2557
		;

2558

2559 2560 2561 2562 2563
function_with_argtypes_list: function_with_argtypes
				{ $$ = makeList1($1); }
		| function_with_argtypes_list ',' function_with_argtypes
				{ $$ = lappend($1, $3); }
		;
2564

2565
function_with_argtypes: func_name func_args
2566
				{
2567 2568 2569
					FuncWithArgs *n = makeNode(FuncWithArgs);
					n->funcname = $1;
					n->funcargs = $2;
2570
					$$ = (Node *)n;
2571 2572
				}
		;
2573

2574

2575 2576
/*****************************************************************************
 *
2577
 *		QUERY:
Bruce Momjian's avatar
Bruce Momjian committed
2578
 *				create index <indexname> on <relname>
2579 2580
 *				  [ using <access> ] "(" (<col> with <op>)+ ")"
 *				  [ where <predicate> ]
2581 2582 2583
 *
 *****************************************************************************/

2584
IndexStmt:	CREATE index_opt_unique INDEX index_name ON qualified_name
2585
			access_method_clause '(' index_params ')' where_clause
2586 2587 2588 2589
				{
					IndexStmt *n = makeNode(IndexStmt);
					n->unique = $2;
					n->idxname = $4;
2590
					n->relation = $6;
2591 2592
					n->accessMethod = $7;
					n->indexParams = $9;
2593
					n->whereClause = $11;
2594 2595 2596 2597
					$$ = (Node *)n;
				}
		;

2598 2599
index_opt_unique:  UNIQUE						{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
2600 2601
		;

2602
access_method_clause:  USING access_method		{ $$ = $2; }
2603 2604
		/* If btree changes as our default, update pg_get_indexdef() */
		| /*EMPTY*/								{ $$ = DEFAULT_INDEX_TYPE; }
2605
		;
2606

2607
index_params:  index_list						{ $$ = $1; }
2608
		| func_index							{ $$ = makeList1($1); }
2609 2610 2611
		;

index_list:  index_list ',' index_elem			{ $$ = lappend($1, $3); }
2612
		| index_elem							{ $$ = makeList1($1); }
2613 2614
		;

2615
func_index:  func_name '(' name_list ')' opt_class
2616 2617 2618 2619
				{
					$$ = makeNode(IndexElem);
					$$->name = $1;
					$$->args = $3;
2620
					$$->class = $5;
2621 2622 2623
				}
		  ;

2624
index_elem:  attr_name opt_class
2625 2626 2627 2628
				{
					$$ = makeNode(IndexElem);
					$$->name = $1;
					$$->args = NIL;
2629
					$$->class = $2;
2630 2631 2632
				}
		;

2633 2634 2635
opt_class:  class
				{
					/*
Tom Lane's avatar
Tom Lane committed
2636 2637 2638 2639 2640 2641 2642
					 * Release 7.0 removed network_ops, timespan_ops, and
					 * datetime_ops, so we suppress it from being passed to
					 * the parser so the default *_ops is used.  This can be
					 * removed in some later release.  bjm 2000/02/07
					 *
					 * Release 7.1 removes lztext_ops, so suppress that too
					 * for a while.  tgl 2000/07/30
2643 2644 2645 2646
					 *
					 * Release 7.2 renames timestamp_ops to timestamptz_ops,
					 * so suppress that too for awhile.  I'm starting to
					 * think we need a better approach.  tgl 2000/10/01
2647 2648 2649
					 */
					if (strcmp($1, "network_ops") != 0 &&
						strcmp($1, "timespan_ops") != 0 &&
Tom Lane's avatar
Tom Lane committed
2650
						strcmp($1, "datetime_ops") != 0 &&
2651 2652
						strcmp($1, "lztext_ops") != 0 &&
						strcmp($1, "timestamp_ops") != 0)
2653 2654 2655 2656
						$$ = $1;
					else
						$$ = NULL;
				}
2657
		| USING class							{ $$ = $2; }
2658 2659 2660
		| /*EMPTY*/								{ $$ = NULL; }
		;

2661 2662
/*****************************************************************************
 *
2663 2664
 *		QUERY:
 *				execute recipe <recipeName>
2665 2666 2667
 *
 *****************************************************************************/

Bruce Momjian's avatar
Bruce Momjian committed
2668
/* NOT USED
2669
RecipeStmt:  EXECUTE RECIPE recipe_name
2670
				{
2671
					RecipeStmt *n = makeNode(RecipeStmt);
2672 2673 2674 2675
					n->recipeName = $3;
					$$ = (Node *)n;
				}
		;
Bruce Momjian's avatar
Bruce Momjian committed
2676
*/
2677 2678 2679

/*****************************************************************************
 *
2680
 *		QUERY:
2681
 *				create [or replace] function <fname>
2682 2683 2684
 *						[(<type-1> { , <type-n>})]
 *						returns <type-r>
 *						as <filename or code in language as appropriate>
2685
 *						language <lang> [with parameters]
2686 2687 2688
 *
 *****************************************************************************/

2689
ProcedureStmt:	CREATE opt_or_replace FUNCTION func_name func_args
2690
			 RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with
2691 2692
				{
					ProcedureStmt *n = makeNode(ProcedureStmt);
2693 2694 2695 2696 2697 2698 2699
					n->replace = $2;
					n->funcname = $4;
					n->argTypes = $5;
					n->returnType = (Node *) $7;
					n->withClause = $12;
					n->as = $9;
					n->language = $11;
2700 2701 2702
					$$ = (Node *)n;
				};

2703 2704 2705 2706
opt_or_replace:  OR REPLACE						{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
		;

2707
opt_with:  WITH definition						{ $$ = $2; }
2708
		| /*EMPTY*/								{ $$ = NIL; }
2709 2710
		;

2711
func_args:  '(' func_args_list ')'				{ $$ = $2; }
2712
		| '(' ')'								{ $$ = NIL; }
2713
		;
2714

2715
func_args_list:  func_arg
2716
				{	$$ = makeList1($1); }
2717
		| func_args_list ',' func_arg
2718
				{	$$ = lappend($1, $3); }
2719 2720
		;

2721
func_arg:  opt_arg func_type
2722
				{
2723 2724 2725 2726
					/* We can catch over-specified arguments here if we want to,
					 * but for now better to silently swallow typmod, etc.
					 * - thomas 2000-03-22
					 */
2727 2728
					$$ = $2;
				}
2729
		| func_type
2730
				{
2731 2732
					$$ = $1;
				}
2733 2734
		;

2735 2736 2737 2738 2739 2740
opt_arg:  IN
				{
					$$ = FALSE;
				}
		| OUT
				{
2741
					elog(ERROR, "CREATE FUNCTION / OUT parameters are not supported");
2742 2743 2744 2745
					$$ = TRUE;
				}
		| INOUT
				{
2746
					elog(ERROR, "CREATE FUNCTION / INOUT parameters are not supported");
2747 2748 2749 2750
					$$ = FALSE;
				}
		;

2751
func_as: Sconst
2752
				{   $$ = makeList1(makeString($1)); }
2753
		| Sconst ',' Sconst
2754
				{ 	$$ = makeList2(makeString($1), makeString($3)); }
2755 2756
		;

2757
func_return:  func_type
2758
				{
2759 2760 2761 2762 2763 2764
					/* We can catch over-specified arguments here if we want to,
					 * but for now better to silently swallow typmod, etc.
					 * - thomas 2000-03-22
					 */
					$$ = $1;
				}
2765 2766
		;

2767 2768
/*
 * We would like to make the second production here be ColId '.' ColId etc,
2769
 * but that causes reduce/reduce conflicts.  type_name is next best choice.
2770
 */
2771 2772 2773 2774
func_type:	Typename
				{
					$$ = $1;
				}
2775
		| type_name '.' ColId '%' TYPE_P
2776 2777 2778 2779 2780 2781 2782
				{
					$$ = makeNode(TypeName);
					$$->name = $1;
					$$->typmod = -1;
					$$->attrname = $3;
				}
		;
2783 2784 2785

/*****************************************************************************
 *
2786
 *		QUERY:
2787
 *
2788
 *		DROP FUNCTION funcname (arg1, arg2, ...)
2789
 *		DROP AGGREGATE aggname (aggtype)
2790
 *		DROP OPERATOR opname (leftoperand_typ rightoperand_typ)
2791 2792 2793
 *
 *****************************************************************************/

2794
RemoveFuncStmt:  DROP FUNCTION func_name func_args
2795
				{
2796 2797 2798
					RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
					n->funcname = $3;
					n->args = $4;
2799 2800 2801 2802
					$$ = (Node *)n;
				}
		;

2803 2804 2805 2806 2807 2808 2809 2810
RemoveAggrStmt:  DROP AGGREGATE func_name '(' aggr_argtype ')'
				{
						RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
						n->aggname = $3;
						n->aggtype = (Node *) $5;
						$$ = (Node *)n;
				}
		| DROP AGGREGATE func_name aggr_argtype
2811
				{
2812
						/* Obsolete syntax, but must support for awhile */
2813 2814
						RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
						n->aggname = $3;
2815
						n->aggtype = (Node *) $4;
2816 2817 2818 2819
						$$ = (Node *)n;
				}
		;

2820
aggr_argtype:  Typename							{ $$ = $1; }
2821
		| '*'									{ $$ = NULL; }
2822
		;
2823

2824
RemoveOperStmt:  DROP OPERATOR all_Op '(' oper_argtypes ')'
2825 2826 2827 2828 2829 2830 2831
				{
					RemoveOperStmt *n = makeNode(RemoveOperStmt);
					n->opname = $3;
					n->args = $5;
					$$ = (Node *)n;
				}
		;
2832

2833
oper_argtypes:	Typename
2834
				{
Bruce Momjian's avatar
Bruce Momjian committed
2835
				   elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
2836
				}
2837 2838 2839 2840 2841 2842
		| Typename ',' Typename
				{ $$ = makeList2($1, $3); }
		| NONE ',' Typename			/* left unary */
				{ $$ = makeList2(NULL, $3); }
		| Typename ',' NONE			/* right unary */
				{ $$ = makeList2($1, NULL); }
2843
		;
2844

2845

Hiroshi Inoue's avatar
Hiroshi Inoue committed
2846 2847 2848 2849 2850 2851 2852 2853
/*****************************************************************************
 *
 *		QUERY:
 *
 *		REINDEX type <typename> [FORCE] [ALL]
 *
 *****************************************************************************/

2854
ReindexStmt:  REINDEX reindex_type qualified_name opt_force
Hiroshi Inoue's avatar
Hiroshi Inoue committed
2855 2856 2857
				{
					ReindexStmt *n = makeNode(ReindexStmt);
					n->reindexType = $2;
2858 2859 2860 2861 2862 2863 2864 2865 2866
					n->relation = $3;
					n->name = NULL;
					n->force = $4;
					$$ = (Node *)n;
				}
		| REINDEX DATABASE name opt_force
				{
					ReindexStmt *n = makeNode(ReindexStmt);
					n->reindexType = DATABASE;
Hiroshi Inoue's avatar
Hiroshi Inoue committed
2867
					n->name = $3;
2868
					n->relation = NULL;
Hiroshi Inoue's avatar
Hiroshi Inoue committed
2869 2870 2871 2872 2873
					n->force = $4;
					$$ = (Node *)n;
				}
		;

2874 2875
reindex_type:  INDEX								{  $$ = INDEX; }
		| TABLE										{  $$ = TABLE; }
Hiroshi Inoue's avatar
Hiroshi Inoue committed
2876
		;
2877

Hiroshi Inoue's avatar
Hiroshi Inoue committed
2878 2879 2880 2881 2882
opt_force:	FORCE									{  $$ = TRUE; }
		| /* EMPTY */								{  $$ = FALSE; }
		;


2883 2884
/*****************************************************************************
 *
2885 2886 2887
 *		QUERY:
 *				rename <attrname1> in <relname> [*] to <attrname2>
 *				rename <relname1> to <relname2>
2888
 *
2889 2890
 *****************************************************************************/

2891
RenameStmt:  ALTER TABLE relation_expr RENAME opt_column opt_name TO name
2892 2893
				{
					RenameStmt *n = makeNode(RenameStmt);
2894
					n->relation = $3;
2895 2896
					n->column = $6;
					n->newname = $8;
2897 2898 2899 2900 2901
					$$ = (Node *)n;
				}
		;

opt_name:  name							{ $$ = $1; }
2902
		| /*EMPTY*/						{ $$ = NULL; }
2903 2904 2905 2906 2907
		;

opt_column:  COLUMN						{ $$ = COLUMN; }
		| /*EMPTY*/						{ $$ = 0; }
		;
2908 2909 2910


/*****************************************************************************
2911
 *
2912
 *		QUERY:	Define Rewrite Rule
2913
 *
2914 2915
 *****************************************************************************/

2916
RuleStmt:  CREATE RULE name AS
2917
		   { QueryIsRule=TRUE; }
2918
		   ON event TO qualified_name where_clause
2919
		   DO opt_instead RuleActionList
2920 2921
				{
					RuleStmt *n = makeNode(RuleStmt);
2922
					n->relation = $9;
2923 2924
					n->rulename = $3;
					n->whereClause = $10;
2925
					n->event = $7;
2926 2927 2928
					n->instead = $12;
					n->actions = $13;
					$$ = (Node *)n;
2929
					QueryIsRule=FALSE;
2930 2931 2932
				}
		;

2933 2934 2935
RuleActionList:  NOTHING				{ $$ = NIL; }
		| RuleActionStmt				{ $$ = makeList1($1); }
		| '(' RuleActionMulti ')'		{ $$ = $2; } 
2936
		;
2937

2938 2939
/* the thrashing around here is to discard "empty" statements... */
RuleActionMulti:  RuleActionMulti ';' RuleActionStmtOrEmpty
2940
				{ if ($3 != (Node *) NULL)
2941
					$$ = lappend($1, $3);
2942 2943 2944 2945
				  else
					$$ = $1;
				}
		| RuleActionStmtOrEmpty
2946 2947
				{ if ($1 != (Node *) NULL)
					$$ = makeList1($1);
2948 2949 2950
				  else
					$$ = NIL;
				}
2951
		;
2952

2953
RuleActionStmt:	SelectStmt
2954
		| InsertStmt
2955 2956 2957 2958 2959
		| UpdateStmt
		| DeleteStmt
		| NotifyStmt
		;

2960 2961 2962 2963 2964
RuleActionStmtOrEmpty:	RuleActionStmt
		|	/*EMPTY*/
				{ $$ = (Node *)NULL; }
		;

2965
/* change me to select, update, etc. some day */
2966 2967 2968 2969 2970
event:	SELECT							{ $$ = CMD_SELECT; }
		| UPDATE						{ $$ = CMD_UPDATE; }
		| DELETE						{ $$ = CMD_DELETE; }
		| INSERT						{ $$ = CMD_INSERT; }
		 ;
2971

2972
opt_instead:  INSTEAD					{ $$ = TRUE; }
2973
		| /*EMPTY*/						{ $$ = FALSE; }
2974
		;
2975 2976 2977 2978


/*****************************************************************************
 *
2979
 *		QUERY:
2980
 *				NOTIFY <qualified_name>	can appear both in rule bodies and
2981
 *				as a query-level command
2982 2983 2984
 *
 *****************************************************************************/

2985
NotifyStmt:  NOTIFY qualified_name
2986 2987
				{
					NotifyStmt *n = makeNode(NotifyStmt);
2988
					n->relation = $2;
2989 2990 2991
					$$ = (Node *)n;
				}
		;
2992

2993
ListenStmt:  LISTEN qualified_name
2994 2995
				{
					ListenStmt *n = makeNode(ListenStmt);
2996
					n->relation = $2;
2997 2998
					$$ = (Node *)n;
				}
2999
		;
3000

3001
UnlistenStmt:  UNLISTEN qualified_name
3002 3003
				{
					UnlistenStmt *n = makeNode(UnlistenStmt);
3004
					n->relation = $2;
3005 3006
					$$ = (Node *)n;
				}
3007 3008 3009
		| UNLISTEN '*'
				{
					UnlistenStmt *n = makeNode(UnlistenStmt);
3010 3011 3012
					n->relation = makeNode(RangeVar);
					n->relation->relname = "*";
					n->relation->schemaname = NULL;
3013 3014
					$$ = (Node *)n;
				}
3015
		;
3016

3017 3018 3019

/*****************************************************************************
 *
3020
 *		Transactions:
3021
 *
3022 3023
 *      BEGIN / COMMIT / ROLLBACK
 *      (also older versions END / ABORT)
3024
 *
3025 3026
 *****************************************************************************/

3027
TransactionStmt: ABORT_TRANS opt_trans
3028 3029
				{
					TransactionStmt *n = makeNode(TransactionStmt);
3030
					n->command = ROLLBACK;
3031 3032
					$$ = (Node *)n;
				}
3033
		| BEGIN_TRANS opt_trans
3034 3035 3036 3037 3038
				{
					TransactionStmt *n = makeNode(TransactionStmt);
					n->command = BEGIN_TRANS;
					$$ = (Node *)n;
				}
3039
		| COMMIT opt_trans
3040 3041
				{
					TransactionStmt *n = makeNode(TransactionStmt);
3042
					n->command = COMMIT;
3043 3044
					$$ = (Node *)n;
				}
3045 3046 3047 3048 3049 3050
		| COMMIT opt_trans opt_chain
				{
					TransactionStmt *n = makeNode(TransactionStmt);
					n->command = COMMIT;
					$$ = (Node *)n;
				}
3051
		| END_TRANS opt_trans
3052 3053
				{
					TransactionStmt *n = makeNode(TransactionStmt);
3054
					n->command = COMMIT;
3055 3056
					$$ = (Node *)n;
				}
3057
		| ROLLBACK opt_trans
3058 3059
				{
					TransactionStmt *n = makeNode(TransactionStmt);
3060
					n->command = ROLLBACK;
3061 3062
					$$ = (Node *)n;
				}
3063 3064 3065 3066 3067 3068
		| ROLLBACK opt_trans opt_chain
				{
					TransactionStmt *n = makeNode(TransactionStmt);
					n->command = ROLLBACK;
					$$ = (Node *)n;
				}
3069
		;
3070

3071 3072 3073
opt_trans: WORK									{ $$ = TRUE; }
		| TRANSACTION							{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = TRUE; }
3074
		;
3075

3076 3077 3078 3079 3080 3081 3082 3083
opt_chain: AND NO CHAIN
				{ $$ = FALSE; }
		| AND CHAIN
				{
					/* SQL99 asks that conforming dbs reject AND CHAIN
					 * if they don't support it. So we can't just ignore it.
					 * - thomas 2000-08-06
					 */
3084
					elog(ERROR, "COMMIT / CHAIN not yet supported");
3085 3086 3087 3088
					$$ = TRUE;
				}
		;

3089 3090 3091

/*****************************************************************************
 *
3092 3093
 *		QUERY:
 *				define view <viewname> '('target-list ')' [where <quals> ]
3094 3095 3096
 *
 *****************************************************************************/

3097
ViewStmt:  CREATE VIEW qualified_name opt_column_list AS SelectStmt
3098 3099
				{
					ViewStmt *n = makeNode(ViewStmt);
3100
					n->view = $3;
3101
					n->aliases = $4;
3102
					n->query = (Query *) $6;
3103 3104 3105
					$$ = (Node *)n;
				}
		;
3106 3107 3108 3109


/*****************************************************************************
 *
3110 3111
 *		QUERY:
 *				load "filename"
3112 3113 3114
 *
 *****************************************************************************/

3115
LoadStmt:  LOAD file_name
3116 3117 3118 3119 3120 3121
				{
					LoadStmt *n = makeNode(LoadStmt);
					n->filename = $2;
					$$ = (Node *)n;
				}
		;
3122 3123 3124 3125


/*****************************************************************************
 *
3126 3127
 *		CREATE DATABASE
 *
3128 3129
 *****************************************************************************/

3130
CreatedbStmt:  CREATE DATABASE database_name WITH createdb_opt_list
3131
				{
3132
					CreatedbStmt *n = makeNode(CreatedbStmt);
3133
					List   *l;
3134

3135
					n->dbname = $3;
3136
					/* set default options */
3137
					n->dbowner = NULL;
3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156
					n->dbpath = NULL;
					n->dbtemplate = NULL;
					n->encoding = -1;
					/* process additional options */
					foreach(l, $5)
					{
						List   *optitem = (List *) lfirst(l);

						switch (lfirsti(optitem))
						{
							case 1:
								n->dbpath = (char *) lsecond(optitem);
								break;
							case 2:
								n->dbtemplate = (char *) lsecond(optitem);
								break;
							case 3:
								n->encoding = lfirsti(lnext(optitem));
								break;
3157 3158 3159
							case 4:
								n->dbowner = (char *) lsecond(optitem);
								break;
3160 3161
						}
					}
3162 3163
					$$ = (Node *)n;
				}
3164 3165 3166 3167
		| CREATE DATABASE database_name
				{
					CreatedbStmt *n = makeNode(CreatedbStmt);
					n->dbname = $3;
3168
					n->dbowner = NULL;
3169
					n->dbpath = NULL;
3170 3171
					n->dbtemplate = NULL;
					n->encoding = -1;
3172 3173 3174 3175
					$$ = (Node *)n;
				}
		;

3176 3177 3178 3179
createdb_opt_list:  createdb_opt_item
				{ $$ = makeList1($1); }
		| createdb_opt_list createdb_opt_item
				{ $$ = lappend($1, $2); }
3180 3181
		;

3182 3183 3184 3185
/*
 * createdb_opt_item returns 2-element lists, with the first element
 * being an integer code to indicate which item was specified.
 */
3186
createdb_opt_item:  LOCATION opt_equal Sconst
3187
				{
3188 3189
					$$ = lconsi(1, makeList1($3));
				}
3190
		| LOCATION opt_equal DEFAULT
3191
				{
3192
					$$ = lconsi(1, makeList1(NULL));
3193
				}
3194
		| TEMPLATE opt_equal name
3195 3196 3197
				{
					$$ = lconsi(2, makeList1($3));
				}
3198
		| TEMPLATE opt_equal DEFAULT
3199
				{
3200
					$$ = lconsi(2, makeList1(NULL));
3201
				}
3202
		| ENCODING opt_equal Sconst
3203 3204
				{
					int		encoding;
3205
#ifdef MULTIBYTE
3206 3207
					encoding = pg_char_to_encoding($3);
					if (encoding == -1)
3208
						elog(ERROR, "%s is not a valid encoding name", $3);
3209
#else
3210
					if (strcasecmp($3, GetStandardEncodingName()) != 0)
3211
						elog(ERROR, "Multi-byte support is not enabled");
3212
					encoding = GetStandardEncoding();
3213
#endif
3214
					$$ = lconsi(3, makeListi1(encoding));
3215
				}
3216
		| ENCODING opt_equal Iconst
3217
				{
3218
#ifdef MULTIBYTE
Tatsuo Ishii's avatar
Tatsuo Ishii committed
3219
					if (!pg_get_enconv_by_encoding($3))
3220
						elog(ERROR, "%d is not a valid encoding code", $3);
3221
#else
3222
					if ($3 != GetStandardEncoding())
3223
						elog(ERROR, "Multi-byte support is not enabled");
3224
#endif
3225
					$$ = lconsi(3, makeListi1($3));
3226
				}
3227
		| ENCODING opt_equal DEFAULT
3228
				{
3229
					$$ = lconsi(3, makeListi1(-1));
3230
				}
Bruce Momjian's avatar
Bruce Momjian committed
3231 3232 3233 3234 3235 3236 3237 3238
		| OWNER opt_equal name 
				{
					$$ = lconsi(4, makeList1($3));
				}
		| OWNER opt_equal DEFAULT
				{
					$$ = lconsi(4, makeList1(NULL));
				}
3239 3240
		;

Tom Lane's avatar
Tom Lane committed
3241 3242 3243 3244 3245 3246 3247 3248
/*
 *	Though the equals sign doesn't match other WITH options, pg_dump uses
 *  equals for backward compability, and it doesn't seem worth remove it.
 */
opt_equal: '='								{ $$ = TRUE; }
		| /*EMPTY*/							{ $$ = FALSE; }
		;

3249

3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273
/*****************************************************************************
 *
 *		ALTER DATABASE
 *
 *****************************************************************************/

AlterDatabaseSetStmt: ALTER DATABASE database_name VariableSetStmt
				{
					AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt);
					n->dbname = $3;
					n->variable = ((VariableSetStmt *)$4)->name;
					n->value = ((VariableSetStmt *)$4)->args;
					$$ = (Node *)n;
				}
				| ALTER DATABASE database_name VariableResetStmt
				{
					AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt);
					n->dbname = $3;
					n->variable = ((VariableResetStmt *)$4)->name;
					n->value = NULL;
					$$ = (Node *)n;
				}
		;

3274

3275 3276
/*****************************************************************************
 *
3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290
 *		DROP DATABASE
 *
 *****************************************************************************/

DropdbStmt:	DROP DATABASE database_name
				{
					DropdbStmt *n = makeNode(DropdbStmt);
					n->dbname = $3;
					$$ = (Node *)n;
				}
		;


/*****************************************************************************
3291
 *
3292
 * Manipulate a domain
3293 3294 3295
 *
 *****************************************************************************/

3296
CreateDomainStmt:  CREATE DOMAIN_P name opt_as Typename ColQualList opt_collate
3297
				{
3298 3299 3300 3301 3302 3303 3304 3305
					CreateDomainStmt *n = makeNode(CreateDomainStmt);
					n->domainname = $3;
					n->typename = $5;
					n->constraints = $6;
					
					if ($7 != NULL)
						elog(NOTICE,"CREATE DOMAIN / COLLATE %s not yet "
							"implemented; clause ignored", $7);
3306 3307 3308
					$$ = (Node *)n;
				}
		;
3309

3310 3311 3312
opt_as:	AS	{$$ = TRUE; }
	| /* EMPTY */	{$$ = FALSE; }
	;
3313

3314

3315 3316
/*****************************************************************************
 *
3317
 *		QUERY:
3318
 *				cluster <index_name> on <qualified_name>
3319 3320 3321
 *
 *****************************************************************************/

3322
ClusterStmt:  CLUSTER index_name ON qualified_name
3323 3324
				{
				   ClusterStmt *n = makeNode(ClusterStmt);
3325
				   n->relation = $4;
3326 3327 3328 3329
				   n->indexname = $2;
				   $$ = (Node*)n;
				}
		;
3330 3331 3332

/*****************************************************************************
 *
3333 3334
 *		QUERY:
 *				vacuum
3335
 *				analyze
3336 3337 3338
 *
 *****************************************************************************/

3339
VacuumStmt:  VACUUM opt_full opt_freeze opt_verbose
3340 3341
				{
					VacuumStmt *n = makeNode(VacuumStmt);
3342 3343
					n->vacuum = true;
					n->analyze = false;
3344
					n->full = $2;
3345 3346
					n->freeze = $3;
					n->verbose = $4;
3347
					n->relation = NULL;
3348
					n->va_cols = NIL;
3349 3350
					$$ = (Node *)n;
				}
3351
		| VACUUM opt_full opt_freeze opt_verbose qualified_name
3352 3353
				{
					VacuumStmt *n = makeNode(VacuumStmt);
3354 3355
					n->vacuum = true;
					n->analyze = false;
3356
					n->full = $2;
3357 3358
					n->freeze = $3;
					n->verbose = $4;
3359
					n->relation = $5;
3360 3361 3362
					n->va_cols = NIL;
					$$ = (Node *)n;
				}
3363
		| VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
3364
				{
3365
					VacuumStmt *n = (VacuumStmt *) $5;
3366
					n->vacuum = true;
3367
					n->full = $2;
3368 3369
					n->freeze = $3;
					n->verbose |= $4;
3370 3371 3372 3373
					$$ = (Node *)n;
				}
		;

3374 3375 3376 3377 3378
AnalyzeStmt:  analyze_keyword opt_verbose
				{
					VacuumStmt *n = makeNode(VacuumStmt);
					n->vacuum = false;
					n->analyze = true;
3379
					n->full = false;
3380
					n->freeze = false;
3381
					n->verbose = $2;
3382
					n->relation = NULL;
3383 3384 3385
					n->va_cols = NIL;
					$$ = (Node *)n;
				}
3386
		| analyze_keyword opt_verbose qualified_name opt_name_list
3387 3388 3389 3390
				{
					VacuumStmt *n = makeNode(VacuumStmt);
					n->vacuum = false;
					n->analyze = true;
3391
					n->full = false;
3392
					n->freeze = false;
3393
					n->verbose = $2;
3394
					n->relation = $3;
3395 3396 3397
					n->va_cols = $4;
					$$ = (Node *)n;
				}
3398 3399
		;

3400
analyze_keyword:  ANALYZE						{ $$ = TRUE; }
3401
		|	  ANALYSE /* British */				{ $$ = TRUE; }
3402
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
3403

3404 3405
opt_verbose:  VERBOSE							{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
3406
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
3407

3408 3409 3410 3411
opt_full:  FULL									{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
		;

3412 3413 3414 3415
opt_freeze:  FREEZE								{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
		;

3416 3417
opt_name_list:  '(' name_list ')'				{ $$ = $2; }
		| /*EMPTY*/								{ $$ = NIL; }
3418
		;
3419

3420

3421 3422
/*****************************************************************************
 *
3423 3424
 *		QUERY:
 *				EXPLAIN query
3425
 *				EXPLAIN ANALYZE query
3426 3427 3428
 *
 *****************************************************************************/

3429
ExplainStmt:  EXPLAIN opt_verbose OptimizableStmt
3430 3431 3432
				{
					ExplainStmt *n = makeNode(ExplainStmt);
					n->verbose = $2;
3433
					n->analyze = FALSE;
3434 3435 3436
					n->query = (Query*)$3;
					$$ = (Node *)n;
				}
3437 3438 3439 3440 3441 3442 3443 3444
			| EXPLAIN analyze_keyword opt_verbose OptimizableStmt
				{
					ExplainStmt *n = makeNode(ExplainStmt);
					n->verbose = $3;
					n->analyze = TRUE;
					n->query = (Query*)$4;
					$$ = (Node *)n;
				}
3445
		;
3446

3447

3448
/*****************************************************************************
3449 3450 3451 3452 3453 3454 3455 3456
 *																			 *
 *		Optimizable Stmts:													 *
 *																			 *
 *		one of the five queries processed by the planner					 *
 *																			 *
 *		[ultimately] produces query-trees as specified						 *
 *		in the query-spec document in ~postgres/ref							 *
 *																			 *
3457 3458
 *****************************************************************************/

Bruce Momjian's avatar
Bruce Momjian committed
3459
OptimizableStmt:  SelectStmt
3460
		| CursorStmt
Bruce Momjian's avatar
Bruce Momjian committed
3461 3462
		| UpdateStmt
		| InsertStmt
3463 3464
		| DeleteStmt					/* by default all are $$=$1 */
		;
3465 3466 3467 3468


/*****************************************************************************
 *
3469 3470
 *		QUERY:
 *				INSERT STATEMENTS
3471
 *
3472 3473
 *****************************************************************************/

3474
InsertStmt:  INSERT INTO qualified_name insert_rest
3475
				{
3476
 					$4->relation = $3;
3477
					$$ = (Node *) $4;
3478 3479
				}
		;
3480

3481
insert_rest:  VALUES '(' target_list ')'
3482
				{
Bruce Momjian's avatar
Bruce Momjian committed
3483
					$$ = makeNode(InsertStmt);
3484
					$$->cols = NIL;
3485
					$$->targetList = $3;
3486
					$$->selectStmt = NULL;
3487
				}
3488 3489 3490
		| DEFAULT VALUES
				{
					$$ = makeNode(InsertStmt);
3491
					$$->cols = NIL;
3492
					$$->targetList = NIL;
3493 3494
					$$->selectStmt = NULL;
				}
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3495
		| SelectStmt
3496
				{
Bruce Momjian's avatar
Bruce Momjian committed
3497
					$$ = makeNode(InsertStmt);
3498
					$$->cols = NIL;
3499 3500
					$$->targetList = NIL;
					$$->selectStmt = $1;
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3501
				}
3502
		| '(' insert_column_list ')' VALUES '(' target_list ')'
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3503 3504 3505 3506
				{
					$$ = makeNode(InsertStmt);
					$$->cols = $2;
					$$->targetList = $6;
3507
					$$->selectStmt = NULL;
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3508
				}
3509
		| '(' insert_column_list ')' SelectStmt
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3510 3511 3512
				{
					$$ = makeNode(InsertStmt);
					$$->cols = $2;
3513 3514
					$$->targetList = NIL;
					$$->selectStmt = $4;
3515 3516 3517
				}
		;

3518
insert_column_list:  insert_column_list ',' insert_column_item
3519
				{ $$ = lappend($1, $3); }
3520
		| insert_column_item
3521
				{ $$ = makeList1($1); }
3522
		;
3523

3524
insert_column_item:  ColId opt_indirection
3525
				{
3526 3527 3528 3529 3530
					ResTarget *n = makeNode(ResTarget);
					n->name = $1;
					n->indirection = $2;
					n->val = NULL;
					$$ = (Node *)n;
3531 3532
				}
		;
3533

3534

3535 3536
/*****************************************************************************
 *
3537 3538
 *		QUERY:
 *				DELETE STATEMENTS
3539 3540
 *
 *****************************************************************************/
3541

3542
DeleteStmt:  DELETE FROM relation_expr where_clause
3543 3544
				{
					DeleteStmt *n = makeNode(DeleteStmt);
3545
					n->relation = $3;
3546
					n->whereClause = $4;
3547 3548 3549
					$$ = (Node *)n;
				}
		;
3550

3551
LockStmt:	LOCK_P opt_table qualified_name_list opt_lock
3552
				{
3553 3554
					LockStmt *n = makeNode(LockStmt);

3555
					n->relations = $3;
Bruce Momjian's avatar
Bruce Momjian committed
3556
					n->mode = $4;
3557 3558
					$$ = (Node *)n;
				}
3559
		;
3560

3561
opt_lock:  IN lock_type MODE	{ $$ = $2; }
3562 3563
		| /*EMPTY*/				{ $$ = AccessExclusiveLock; }
		;
3564

3565 3566 3567 3568 3569 3570 3571 3572
lock_type:  ACCESS SHARE		{ $$ = AccessShareLock; }
		| ROW SHARE				{ $$ = RowShareLock; }
		| ROW EXCLUSIVE			{ $$ = RowExclusiveLock; }
		| SHARE UPDATE EXCLUSIVE { $$ = ShareUpdateExclusiveLock; }
		| SHARE					{ $$ = ShareLock; }
		| SHARE ROW EXCLUSIVE	{ $$ = ShareRowExclusiveLock; }
		| EXCLUSIVE				{ $$ = ExclusiveLock; }
		| ACCESS EXCLUSIVE		{ $$ = AccessExclusiveLock; }
3573
		;
3574

3575

3576 3577
/*****************************************************************************
 *
3578
 *		QUERY:
Bruce Momjian's avatar
Bruce Momjian committed
3579
 *				UpdateStmt (UPDATE)
3580 3581 3582
 *
 *****************************************************************************/

3583
UpdateStmt:  UPDATE relation_expr
3584
			  SET update_target_list
3585 3586 3587
			  from_clause
			  where_clause
				{
Bruce Momjian's avatar
Bruce Momjian committed
3588
					UpdateStmt *n = makeNode(UpdateStmt);
3589
					n->relation = $2;
3590 3591 3592
					n->targetList = $4;
					n->fromClause = $5;
					n->whereClause = $6;
3593 3594 3595
					$$ = (Node *)n;
				}
		;
3596

3597 3598 3599

/*****************************************************************************
 *
3600 3601
 *		QUERY:
 *				CURSOR STATEMENTS
3602 3603
 *
 *****************************************************************************/
Jan Wieck's avatar
Jan Wieck committed
3604
CursorStmt:  DECLARE name opt_cursor CURSOR FOR SelectStmt
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3605
  				{
3606
 					SelectStmt *n = (SelectStmt *)$6;
3607 3608
					n->portalname = $2;
					n->binary = $3;
3609
					$$ = $6;
3610 3611
				}
		;
3612

3613 3614 3615 3616 3617 3618 3619
opt_cursor:  BINARY						{ $$ = TRUE; }
		| INSENSITIVE					{ $$ = FALSE; }
		| SCROLL						{ $$ = FALSE; }
		| INSENSITIVE SCROLL			{ $$ = FALSE; }
		| /*EMPTY*/						{ $$ = FALSE; }
		;

3620 3621
/*****************************************************************************
 *
3622 3623
 *		QUERY:
 *				SELECT STATEMENTS
3624 3625
 *
 *****************************************************************************/
3626

3627 3628 3629 3630 3631
/* A complete SELECT statement looks like this.
 *
 * The rule returns either a single SelectStmt node or a tree of them,
 * representing a set-operation tree.
 *
3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662
 * There is an ambiguity when a sub-SELECT is within an a_expr and there
 * are excess parentheses: do the parentheses belong to the sub-SELECT or
 * to the surrounding a_expr?  We don't really care, but yacc wants to know.
 * To resolve the ambiguity, we are careful to define the grammar so that
 * the decision is staved off as long as possible: as long as we can keep
 * absorbing parentheses into the sub-SELECT, we will do so, and only when
 * it's no longer possible to do that will we decide that parens belong to
 * the expression.  For example, in "SELECT (((SELECT 2)) + 3)" the extra
 * parentheses are treated as part of the sub-select.  The necessity of doing
 * it that way is shown by "SELECT (((SELECT 2)) UNION SELECT 2)".  Had we
 * parsed "((SELECT 2))" as an a_expr, it'd be too late to go back to the
 * SELECT viewpoint when we see the UNION.
 *
 * This approach is implemented by defining a nonterminal select_with_parens,
 * which represents a SELECT with at least one outer layer of parentheses,
 * and being careful to use select_with_parens, never '(' SelectStmt ')',
 * in the expression grammar.  We will then have shift-reduce conflicts
 * which we can resolve in favor of always treating '(' <select> ')' as
 * a select_with_parens.  To resolve the conflicts, the productions that
 * conflict with the select_with_parens productions are manually given
 * precedences lower than the precedence of ')', thereby ensuring that we
 * shift ')' (and then reduce to select_with_parens) rather than trying to
 * reduce the inner <select> nonterminal to something else.  We use UMINUS
 * precedence for this, which is a fairly arbitrary choice.
 *
 * To be able to define select_with_parens itself without ambiguity, we need
 * a nonterminal select_no_parens that represents a SELECT structure with no
 * outermost parentheses.  This is a little bit tedious, but it works.
 *
 * In non-expression contexts, we use SelectStmt which can represent a SELECT
 * with or without outer parentheses.
3663 3664
 */

3665 3666 3667 3668 3669
SelectStmt: select_no_parens			%prec UMINUS
		| select_with_parens			%prec UMINUS
		;

select_with_parens: '(' select_no_parens ')'
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3670
			{
3671
				$$ = $2;
3672
			}
3673
		| '(' select_with_parens ')'
3674 3675 3676 3677
			{
				$$ = $2;
			}
		;
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3678

3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698
select_no_parens: simple_select
			{
				$$ = $1;
			}
		| select_clause sort_clause opt_for_update_clause opt_select_limit
			{
				insertSelectOptions((SelectStmt *) $1, $2, $3,
									nth(0, $4), nth(1, $4));
				$$ = $1;
			}
		| select_clause for_update_clause opt_select_limit
			{
				insertSelectOptions((SelectStmt *) $1, NIL, $2,
									nth(0, $3), nth(1, $3));
				$$ = $1;
			}
		| select_clause select_limit
			{
				insertSelectOptions((SelectStmt *) $1, NIL, NIL,
									nth(0, $2), nth(1, $2));
3699
				$$ = $1;
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3700
			}
3701
		;
3702

3703
select_clause: simple_select
3704
		| select_with_parens
3705
		;
3706

3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721
/*
 * This rule parses SELECT statements that can appear within set operations,
 * including UNION, INTERSECT and EXCEPT.  '(' and ')' can be used to specify
 * the ordering of the set operations.  Without '(' and ')' we want the
 * operations to be ordered per the precedence specs at the head of this file.
 *
 * As with select_no_parens, simple_select cannot have outer parentheses,
 * but can have parenthesized subclauses.
 *
 * Note that sort clauses cannot be included at this level --- SQL92 requires
 *		SELECT foo UNION SELECT bar ORDER BY baz
 * to be parsed as
 *		(SELECT foo UNION SELECT bar) ORDER BY baz
 * not
 *		SELECT foo UNION (SELECT bar ORDER BY baz)
3722 3723 3724 3725
 * Likewise FOR UPDATE and LIMIT.  Therefore, those clauses are described
 * as part of the select_no_parens production, not simple_select.
 * This does not limit functionality, because you can reintroduce sort and
 * limit clauses inside parentheses.
3726 3727 3728 3729 3730 3731
 *
 * NOTE: only the leftmost component SelectStmt should have INTO.
 * However, this is not checked by the grammar; parse analysis must check it.
 */
simple_select: SELECT opt_distinct target_list
			 into_clause from_clause where_clause
3732
			 group_clause having_clause
3733
				{
Bruce Momjian's avatar
Bruce Momjian committed
3734
					SelectStmt *n = makeNode(SelectStmt);
3735
					n->distinctClause = $2;
3736
					n->targetList = $3;
3737
					n->into = $4;
3738
					n->intoColNames = NIL;
3739 3740 3741 3742 3743 3744
					n->fromClause = $5;
					n->whereClause = $6;
					n->groupClause = $7;
					n->havingClause = $8;
					$$ = (Node *)n;
				}
3745
		| select_clause UNION opt_all select_clause
3746
			{	
3747
				$$ = makeSetOp(SETOP_UNION, $3, $1, $4);
3748
			}
3749
		| select_clause INTERSECT opt_all select_clause
3750
			{
3751
				$$ = makeSetOp(SETOP_INTERSECT, $3, $1, $4);
3752
			}
3753
		| select_clause EXCEPT opt_all select_clause
3754
			{
3755
				$$ = makeSetOp(SETOP_EXCEPT, $3, $1, $4);
3756 3757
			}
		; 
3758

3759
into_clause:  INTO OptTempTableName		{ $$ = $2; }
3760
		| /*EMPTY*/		{ $$ = NULL; }
3761 3762 3763 3764 3765 3766
		;

/*
 * Redundancy here is needed to avoid shift/reduce conflicts,
 * since TEMP is not a reserved word.  See also OptTemp.
 */
3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787
OptTempTableName:  TEMPORARY opt_table qualified_name
				{ 
					$$ = $3;
					$$->istemp = true;
				}
			| TEMP opt_table qualified_name
				{ 
					$$ = $3;
					$$->istemp = true;
				}
			| LOCAL TEMPORARY opt_table qualified_name
				{ 
					$$ = $4;
					$$->istemp = true;
				}
			| LOCAL TEMP opt_table qualified_name
				{ 
					$$ = $4;
					$$->istemp = true;
				}
			| GLOBAL TEMPORARY opt_table qualified_name
3788 3789
				{
					elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
3790 3791
					$$ = $4;
					$$->istemp = true;
3792
				}
3793
			| GLOBAL TEMP opt_table qualified_name
3794 3795
				{
					elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807
					$$ = $4;
					$$->istemp = true;
				}
			| TABLE qualified_name
				{ 
					$$ = $2;
					$$->istemp = false;
				}
			| qualified_name
				{ 
					$$ = $1;
					$$->istemp = false;
3808
				}
3809 3810 3811 3812
		;

opt_table:  TABLE								{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
3813
		;
3814

3815
opt_all:  ALL									{ $$ = TRUE; }
3816 3817 3818
		| /*EMPTY*/								{ $$ = FALSE; }
		;

3819 3820 3821
/* We use (NIL) as a placeholder to indicate that all target expressions
 * should be placed in the DISTINCT list during parsetree analysis.
 */
3822
opt_distinct:  DISTINCT							{ $$ = makeList1(NIL); }
3823 3824 3825
		| DISTINCT ON '(' expr_list ')'			{ $$ = $4; }
		| ALL									{ $$ = NIL; }
		| /*EMPTY*/								{ $$ = NIL; }
3826
		;
3827

3828 3829
sort_clause:  ORDER BY sortby_list				{ $$ = $3; }
		;
3830

3831
sortby_list:  sortby							{ $$ = makeList1($1); }
3832
		| sortby_list ',' sortby				{ $$ = lappend($1, $3); }
3833
		;
3834

3835
sortby: a_expr OptUseOp
3836 3837
				{
					$$ = makeNode(SortGroupBy);
3838
					$$->node = $1;
3839 3840 3841 3842
					$$->useOp = $2;
				}
		;

3843
OptUseOp:  USING all_Op							{ $$ = $2; }
3844 3845 3846
		| ASC									{ $$ = "<"; }
		| DESC									{ $$ = ">"; }
		| /*EMPTY*/								{ $$ = "<"; /*default*/ }
3847
		;
3848

3849

3850
select_limit:	LIMIT select_limit_value OFFSET select_offset_value
3851
			{ $$ = makeList2($4, $2); }
3852
		| OFFSET select_offset_value LIMIT select_limit_value
3853
			{ $$ = makeList2($2, $4); }
3854 3855
		| LIMIT select_limit_value
			{ $$ = makeList2(NULL, $2); }
3856
		| OFFSET select_offset_value
3857
			{ $$ = makeList2($2, NULL); }
3858 3859 3860
		| LIMIT select_limit_value ',' select_offset_value
			/* Disabled because it was too confusing, bjm 2002-02-18 */
			{ elog(ERROR, "LIMIT #,# syntax not supported.\n\tUse separate LIMIT and OFFSET clauses."); }
3861 3862
		;

3863

3864 3865
opt_select_limit:	select_limit				{ $$ = $1; }
		| /* EMPTY */							{ $$ = makeList2(NULL,NULL); }
3866 3867
		;

3868
select_limit_value:  Iconst
3869 3870 3871
			{
				Const	*n = makeNode(Const);

3872 3873
				if ($1 < 0)
					elog(ERROR, "LIMIT must not be negative");
3874 3875 3876

				n->consttype	= INT4OID;
				n->constlen		= sizeof(int4);
3877
				n->constvalue	= Int32GetDatum($1);
3878 3879 3880 3881 3882 3883 3884 3885
				n->constisnull	= FALSE;
				n->constbyval	= TRUE;
				n->constisset	= FALSE;
				n->constiscast	= FALSE;
				$$ = (Node *)n;
			}
		| ALL
			{
3886
				/* LIMIT ALL is represented as a NULL constant */
3887 3888 3889 3890
				Const	*n = makeNode(Const);

				n->consttype	= INT4OID;
				n->constlen		= sizeof(int4);
3891 3892
				n->constvalue	= (Datum) 0;
				n->constisnull	= TRUE;
3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912
				n->constbyval	= TRUE;
				n->constisset	= FALSE;
				n->constiscast	= FALSE;
				$$ = (Node *)n;
			}
		| PARAM
			{
				Param	*n = makeNode(Param);

				n->paramkind	= PARAM_NUM;
				n->paramid		= $1;
				n->paramtype	= INT4OID;
				$$ = (Node *)n;
			}
		;

select_offset_value:	Iconst
			{
				Const	*n = makeNode(Const);

3913 3914 3915
				if ($1 < 0)
					elog(ERROR, "OFFSET must not be negative");

3916 3917
				n->consttype	= INT4OID;
				n->constlen		= sizeof(int4);
3918
				n->constvalue	= Int32GetDatum($1);
3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934
				n->constisnull	= FALSE;
				n->constbyval	= TRUE;
				n->constisset	= FALSE;
				n->constiscast	= FALSE;
				$$ = (Node *)n;
			}
		| PARAM
			{
				Param	*n = makeNode(Param);

				n->paramkind	= PARAM_NUM;
				n->paramid		= $1;
				n->paramtype	= INT4OID;
				$$ = (Node *)n;
			}
		;
3935

3936
/*
3937 3938
 *	jimmy bell-style recursive queries aren't supported in the
 *	current system.
3939
 *
3940 3941
 *	...however, recursive addattr and rename supported.  make special
 *	cases for these.
3942 3943
 */

3944
group_clause:  GROUP BY expr_list				{ $$ = $3; }
3945 3946
		| /*EMPTY*/								{ $$ = NIL; }
		;
3947

Bruce Momjian's avatar
Bruce Momjian committed
3948 3949
having_clause:  HAVING a_expr
				{
3950
					$$ = $2;
Bruce Momjian's avatar
Bruce Momjian committed
3951
				}
3952 3953
		| /*EMPTY*/								{ $$ = NULL; }
		;
3954

3955
for_update_clause:  FOR UPDATE update_list		{ $$ = $3; }
Jan Wieck's avatar
Jan Wieck committed
3956
		| FOR READ ONLY							{ $$ = NULL; }
3957 3958 3959
		;

opt_for_update_clause:	for_update_clause		{ $$ = $1; }
3960 3961 3962
		| /* EMPTY */							{ $$ = NULL; }
		;

3963
update_list:  OF name_list						{ $$ = $2; }
3964
		| /* EMPTY */							{ $$ = makeList1(NULL); }
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
3965
		;
3966

3967
/*****************************************************************************
3968
 *
3969
 *	clauses common to all Optimizable Stmts:
3970 3971
 *		from_clause		- allow list of both JOIN expressions and table names
 *		where_clause	- qualifications for joins or restrictions
3972
 *
3973 3974
 *****************************************************************************/

3975
from_clause:  FROM from_list					{ $$ = $2; }
3976 3977 3978
		| /*EMPTY*/								{ $$ = NIL; }
		;

3979
from_list:  from_list ',' table_ref				{ $$ = lappend($1, $3); }
3980
		| table_ref								{ $$ = makeList1($1); }
3981 3982
		;

3983 3984 3985 3986 3987 3988 3989 3990
/*
 * table_ref is where an alias clause can be attached.  Note we cannot make
 * alias_clause have an empty production because that causes parse conflicts
 * between table_ref := '(' joined_table ')' alias_clause
 * and joined_table := '(' joined_table ')'.  So, we must have the
 * redundant-looking productions here instead.
 */
table_ref:  relation_expr
3991
				{
3992
					$$ = (Node *) $1;
3993
				}
3994
		| relation_expr alias_clause
3995
				{
3996
					$1->alias = $2;
3997
					$$ = (Node *) $1;
3998
				}
3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015
		| select_with_parens
				{
					/*
					 * The SQL spec does not permit a subselect
					 * (<derived_table>) without an alias clause,
					 * so we don't either.  This avoids the problem
					 * of needing to invent a unique refname for it.
					 * That could be surmounted if there's sufficient
					 * popular demand, but for now let's just implement
					 * the spec and see if anyone complains.
					 * However, it does seem like a good idea to emit
					 * an error message that's better than "parse error".
					 */
					elog(ERROR, "sub-SELECT in FROM must have an alias"
						 "\n\tFor example, FROM (SELECT ...) [AS] foo");
					$$ = NULL;
				}
4016
		| select_with_parens alias_clause
4017
				{
4018
					RangeSubselect *n = makeNode(RangeSubselect);
4019
					n->subquery = $1;
4020
					n->alias = $2;
4021
					$$ = (Node *) n;
4022
				}
4023
		| joined_table
4024
				{
4025
					$$ = (Node *) $1;
4026
				}
4027
		| '(' joined_table ')' alias_clause
4028
				{
4029 4030
					$2->alias = $4;
					$$ = (Node *) $2;
4031 4032 4033
				}
		;

4034 4035 4036 4037 4038 4039 4040 4041 4042
/*
 * It may seem silly to separate joined_table from table_ref, but there is
 * method in SQL92's madness: if you don't do it this way you get reduce-
 * reduce conflicts, because it's not clear to the parser generator whether
 * to expect alias_clause after ')' or not.  For the same reason we must
 * treat 'JOIN' and 'join_type JOIN' separately, rather than allowing
 * join_type to expand to empty; if we try it, the parser generator can't
 * figure out when to reduce an empty join_type right after table_ref.
 *
4043
 * Note that a CROSS JOIN is the same as an unqualified
4044 4045
 * INNER JOIN, and an INNER JOIN/ON has the same shape
 * but a qualification expression to limit membership.
4046
 * A NATURAL JOIN implicitly matches column names between
4047 4048
 * tables and the shape is determined by which columns are
 * in common. We'll collect columns during the later transformations.
4049
 */
4050 4051 4052 4053 4054 4055

joined_table:  '(' joined_table ')'
				{
					$$ = $2;
				}
		| table_ref CROSS JOIN table_ref
4056
				{
4057
					/* CROSS JOIN is same as unqualified inner join */
4058
					JoinExpr *n = makeNode(JoinExpr);
4059 4060 4061 4062 4063 4064
					n->jointype = JOIN_INNER;
					n->isNatural = FALSE;
					n->larg = $1;
					n->rarg = $4;
					n->using = NIL;
					n->quals = NULL;
4065
					$$ = n;
4066
				}
4067
		| table_ref UNIONJOIN table_ref
4068
				{
4069 4070 4071
					/* UNION JOIN is made into 1 token to avoid shift/reduce
					 * conflict against regular UNION keyword.
					 */
4072
					JoinExpr *n = makeNode(JoinExpr);
4073 4074 4075 4076 4077 4078
					n->jointype = JOIN_UNION;
					n->isNatural = FALSE;
					n->larg = $1;
					n->rarg = $3;
					n->using = NIL;
					n->quals = NULL;
4079
					$$ = n;
4080
				}
4081
		| table_ref join_type JOIN table_ref join_qual
4082
				{
4083
					JoinExpr *n = makeNode(JoinExpr);
4084
					n->jointype = $2;
4085
					n->isNatural = FALSE;
4086 4087 4088 4089 4090 4091
					n->larg = $1;
					n->rarg = $4;
					if ($5 != NULL && IsA($5, List))
						n->using = (List *) $5;	/* USING clause */
					else
						n->quals = $5; /* ON clause */
4092
					$$ = n;
4093
				}
4094
		| table_ref JOIN table_ref join_qual
4095
				{
4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106
					/* letting join_type reduce to empty doesn't work */
					JoinExpr *n = makeNode(JoinExpr);
					n->jointype = JOIN_INNER;
					n->isNatural = FALSE;
					n->larg = $1;
					n->rarg = $3;
					if ($4 != NULL && IsA($4, List))
						n->using = (List *) $4;	/* USING clause */
					else
						n->quals = $4; /* ON clause */
					$$ = n;
4107
				}
4108
		| table_ref NATURAL join_type JOIN table_ref
4109
				{
4110 4111 4112 4113 4114 4115 4116 4117
					JoinExpr *n = makeNode(JoinExpr);
					n->jointype = $3;
					n->isNatural = TRUE;
					n->larg = $1;
					n->rarg = $5;
					n->using = NIL; /* figure out which columns later... */
					n->quals = NULL; /* fill later */
					$$ = n;
4118
				}
4119
		| table_ref NATURAL JOIN table_ref
4120
				{
4121
					/* letting join_type reduce to empty doesn't work */
4122
					JoinExpr *n = makeNode(JoinExpr);
4123 4124 4125 4126 4127 4128
					n->jointype = JOIN_INNER;
					n->isNatural = TRUE;
					n->larg = $1;
					n->rarg = $4;
					n->using = NIL; /* figure out which columns later... */
					n->quals = NULL; /* fill later */
4129
					$$ = n;
4130 4131
				}
		;
4132

4133 4134
alias_clause:  AS ColId '(' name_list ')'
				{
4135 4136 4137
					$$ = makeNode(Alias);
					$$->aliasname = $2;
					$$->colnames = $4;
4138 4139 4140
				}
		| AS ColId
				{
4141 4142
					$$ = makeNode(Alias);
					$$->aliasname = $2;
4143 4144 4145
				}
		| ColId '(' name_list ')'
				{
4146 4147 4148
					$$ = makeNode(Alias);
					$$->aliasname = $1;
					$$->colnames = $3;
4149 4150 4151
				}
		| ColId
				{
4152 4153
					$$ = makeNode(Alias);
					$$->aliasname = $1;
4154
				}
4155 4156
		;

4157 4158 4159 4160
join_type:  FULL join_outer						{ $$ = JOIN_FULL; }
		| LEFT join_outer						{ $$ = JOIN_LEFT; }
		| RIGHT join_outer						{ $$ = JOIN_RIGHT; }
		| INNER_P								{ $$ = JOIN_INNER; }
4161 4162
		;

4163
/* OUTER is just noise... */
4164
join_outer:  OUTER_P							{ $$ = NULL; }
4165
		| /*EMPTY*/								{ $$ = NULL; }
4166 4167
		;

4168 4169 4170 4171 4172
/* JOIN qualification clauses
 * Possibilities are:
 *  USING ( column list ) allows only unqualified column names,
 *                        which must match between tables.
 *  ON expr allows more general qualifications.
4173 4174
 *
 * We return USING as a List node, while an ON-expr will not be a List.
4175 4176
 */

4177 4178
join_qual:  USING '(' name_list ')'				{ $$ = (Node *) $3; }
		| ON a_expr								{ $$ = $2; }
4179 4180 4181
		;


4182
relation_expr:	qualified_name
4183
				{
4184
					/* default inheritance */
4185
					$$ = $1;
4186
					$$->inhOpt = INH_DEFAULT;
4187
					$$->alias = NULL;
4188
				}
4189
		| qualified_name '*'
4190
				{
4191
					/* inheritance query */
4192
					$$ = $1;
4193
					$$->inhOpt = INH_YES;
4194
					$$->alias = NULL;
4195
				}
4196
		| ONLY qualified_name
4197
				{
4198
					/* no inheritance */
4199
					$$ = $2;
4200
					$$->inhOpt = INH_NO;
4201
					$$->alias = NULL;
4202
                }
4203
		;
4204

4205 4206
where_clause:  WHERE a_expr						{ $$ = $2; }
		| /*EMPTY*/								{ $$ = NULL;  /* no qualifiers */ }
4207
		;
4208

4209

4210 4211 4212 4213 4214 4215 4216 4217 4218 4219
/*****************************************************************************
 *
 *	Type syntax
 *		SQL92 introduces a large amount of type-specific syntax.
 *		Define individual clauses to handle these cases, and use
 *		 the generic case to handle regular type-extensible Postgres syntax.
 *		- thomas 1997-10-10
 *
 *****************************************************************************/

4220
Typename:  SimpleTypename opt_array_bounds
4221 4222 4223
				{
					$$ = $1;
					$$->arrayBounds = $2;
4224
				}
4225
		| SETOF SimpleTypename
4226
				{
4227
					$$ = $2;
4228 4229 4230 4231
					$$->setof = TRUE;
				}
		;

4232 4233 4234 4235
opt_array_bounds:	opt_array_bounds '[' ']'
				{  $$ = lappend($1, makeInteger(-1)); }
		| opt_array_bounds '[' Iconst ']'
				{  $$ = lappend($1, makeInteger($3)); }
4236 4237 4238 4239
		| /*EMPTY*/
				{  $$ = NIL; }
		;

4240
SimpleTypename:  ConstTypename
4241 4242 4243
		| ConstInterval opt_interval
				{
					$$ = $1;
4244 4245
					if ($2 != -1)
						$$->typmod = ((($2 & 0x7FFF) << 16) | 0xFFFF);
4246 4247 4248 4249
				}
		| ConstInterval '(' Iconst ')' opt_interval
				{
					$$ = $1;
4250
					$$->typmod = ((($5 & 0x7FFF) << 16) | $3);
4251
				}
4252 4253
		;

4254
ConstTypename:  GenericType
4255
		| Numeric
4256
		| Bit
4257
		| Character
4258
		| ConstDatetime
4259
		;
4260

4261
GenericType:  type_name
4262
				{
4263 4264
					$$ = makeNode(TypeName);
					$$->name = xlateSqlType($1);
4265
					$$->typmod = -1;
4266 4267 4268 4269 4270
				}
		;

/* SQL92 numeric data types
 * Check FLOAT() precision limits assuming IEEE floating types.
4271
 * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
4272 4273 4274 4275 4276
 * - thomas 1997-09-18
 */
Numeric:  FLOAT opt_float
				{
					$$ = makeNode(TypeName);
4277
					$$->name = $2; /* already xlated */
4278
					$$->typmod = -1;
4279
				}
4280 4281 4282
		| DOUBLE PRECISION
				{
					$$ = makeNode(TypeName);
4283 4284
					$$->name = xlateSqlType("float8");
					$$->typmod = -1;
4285
				}
4286
		| DECIMAL opt_decimal
4287 4288
				{
					$$ = makeNode(TypeName);
4289
					$$->name = xlateSqlType("decimal");
4290 4291 4292
					$$->typmod = $2;
				}
		| DEC opt_decimal
4293
				{
4294
					$$ = makeNode(TypeName);
4295
					$$->name = xlateSqlType("decimal");
4296
					$$->typmod = $2;
4297 4298 4299 4300
				}
		| NUMERIC opt_numeric
				{
					$$ = makeNode(TypeName);
4301 4302
					$$->name = xlateSqlType("numeric");
					$$->typmod = $2;
4303 4304
				}
		;
4305

4306 4307 4308
opt_float:  '(' Iconst ')'
				{
					if ($2 < 1)
Bruce Momjian's avatar
Bruce Momjian committed
4309
						elog(ERROR,"precision for FLOAT must be at least 1");
4310 4311 4312 4313 4314
					else if ($2 < 7)
						$$ = xlateSqlType("float4");
					else if ($2 < 16)
						$$ = xlateSqlType("float8");
					else
Bruce Momjian's avatar
Bruce Momjian committed
4315
						elog(ERROR,"precision for FLOAT must be less than 16");
4316 4317 4318 4319 4320 4321 4322 4323 4324
				}
		| /*EMPTY*/
				{
					$$ = xlateSqlType("float8");
				}
		;

opt_numeric:  '(' Iconst ',' Iconst ')'
				{
4325
					if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
4326
						elog(ERROR,"NUMERIC precision %d must be between 1 and %d",
4327
							 $2, NUMERIC_MAX_PRECISION);
4328 4329
					if ($4 < 0 || $4 > $2)
						elog(ERROR,"NUMERIC scale %d must be between 0 and precision %d",
4330
							 $4,$2);
4331 4332

					$$ = (($2 << 16) | $4) + VARHDRSZ;
4333 4334 4335
				}
		| '(' Iconst ')'
				{
4336
					if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
4337
						elog(ERROR,"NUMERIC precision %d must be between 1 and %d",
4338
							 $2, NUMERIC_MAX_PRECISION);
4339 4340

					$$ = ($2 << 16) + VARHDRSZ;
4341 4342 4343
				}
		| /*EMPTY*/
				{
4344
					/* Insert "-1" meaning "no limit" */
4345
					$$ = -1;
4346 4347 4348 4349 4350
				}
		;

opt_decimal:  '(' Iconst ',' Iconst ')'
				{
4351
					if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
4352
						elog(ERROR,"DECIMAL precision %d must be between 1 and %d",
4353 4354 4355 4356 4357 4358
									$2, NUMERIC_MAX_PRECISION);
					if ($4 < 0 || $4 > $2)
						elog(ERROR,"DECIMAL scale %d must be between 0 and precision %d",
									$4,$2);

					$$ = (($2 << 16) | $4) + VARHDRSZ;
4359 4360 4361
				}
		| '(' Iconst ')'
				{
4362
					if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
4363
						elog(ERROR,"DECIMAL precision %d must be between 1 and %d",
4364 4365 4366
									$2, NUMERIC_MAX_PRECISION);

					$$ = ($2 << 16) + VARHDRSZ;
4367 4368 4369
				}
		| /*EMPTY*/
				{
4370
					/* Insert "-1" meaning "no limit" */
4371
					$$ = -1;
4372 4373 4374
				}
		;

4375

4376 4377 4378 4379 4380 4381 4382 4383 4384
/*
 * SQL92 bit-field data types
 * The following implements BIT() and BIT VARYING().
 */
Bit:  bit '(' Iconst ')'
				{
					$$ = makeNode(TypeName);
					$$->name = $1;
					if ($3 < 1)
4385 4386
						elog(ERROR,"length for type '%s' must be at least 1",
							 $1);
4387
					else if ($3 > (MaxAttrSize * BITS_PER_BYTE))
4388
						elog(ERROR,"length for type '%s' cannot exceed %d",
4389
							 $1, (MaxAttrSize * BITS_PER_BYTE));
4390 4391 4392 4393 4394 4395
					$$->typmod = $3;
				}
		| bit
				{
					$$ = makeNode(TypeName);
					$$->name = $1;
4396 4397 4398 4399 4400
					/* bit defaults to bit(1), varbit to no limit */
					if (strcmp($1, "bit") == 0)
						$$->typmod = 1;
					else
						$$->typmod = -1;
4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411
				}
		;

bit:  BIT opt_varying
				{
					char *type;

					if ($2) type = xlateSqlType("varbit");
					else type = xlateSqlType("bit");
					$$ = type;
				}
4412
		;
4413 4414


4415 4416
/*
 * SQL92 character data types
4417 4418
 * The following implements CHAR() and VARCHAR().
 */
4419
Character:  character '(' Iconst ')' opt_charset
4420 4421
				{
					$$ = makeNode(TypeName);
4422
					$$->name = $1;
4423
					if ($3 < 1)
4424 4425
						elog(ERROR,"length for type '%s' must be at least 1",
							 $1);
4426
					else if ($3 > MaxAttrSize)
4427 4428
						elog(ERROR,"length for type '%s' cannot exceed %d",
							 $1, MaxAttrSize);
4429

4430
					/* we actually implement these like a varlen, so
4431
					 * the first 4 bytes is the length. (the difference
4432 4433
					 * between these and "text" is that we blank-pad and
					 * truncate where necessary)
4434
					 */
4435
					$$->typmod = VARHDRSZ + $3;
4436 4437 4438 4439 4440 4441 4442 4443 4444 4445

					if (($5 != NULL) && (strcmp($5, "sql_text") != 0)) {
						char *type;

						type = palloc(strlen($$->name) + 1 + strlen($5) + 1);
						strcpy(type, $$->name);
						strcat(type, "_");
						strcat(type, $5);
						$$->name = xlateSqlType(type);
					};
4446
				}
4447
		| character opt_charset
4448 4449
				{
					$$ = makeNode(TypeName);
4450
					$$->name = $1;
4451 4452 4453 4454 4455
					/* char defaults to char(1), varchar to no limit */
					if (strcmp($1, "bpchar") == 0)
						$$->typmod = VARHDRSZ + 1;
					else
						$$->typmod = -1;
4456

4457 4458 4459 4460 4461 4462 4463 4464
					if (($2 != NULL) && (strcmp($2, "sql_text") != 0)) {
						char *type;

						type = palloc(strlen($$->name) + 1 + strlen($2) + 1);
						strcpy(type, $$->name);
						strcat(type, "_");
						strcat(type, $2);
						$$->name = xlateSqlType(type);
4465 4466
					};
				}
4467 4468 4469
		;

character:  CHARACTER opt_varying				{ $$ = xlateSqlType($2 ? "varchar": "bpchar"); }
4470
		| CHAR opt_varying						{ $$ = xlateSqlType($2 ? "varchar": "bpchar"); }
4471
		| VARCHAR								{ $$ = xlateSqlType("varchar"); }
4472 4473 4474
		| NATIONAL CHARACTER opt_varying		{ $$ = xlateSqlType($3 ? "varchar": "bpchar"); }
		| NATIONAL CHAR opt_varying				{ $$ = xlateSqlType($3 ? "varchar": "bpchar"); }
		| NCHAR opt_varying						{ $$ = xlateSqlType($2 ? "varchar": "bpchar"); }
4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488
		;

opt_varying:  VARYING							{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
		;

opt_charset:  CHARACTER SET ColId				{ $$ = $3; }
		| /*EMPTY*/								{ $$ = NULL; }
		;

opt_collate:  COLLATE ColId						{ $$ = $2; }
		| /*EMPTY*/								{ $$ = NULL; }
		;

4489
ConstDatetime:  TIMESTAMP '(' Iconst ')' opt_timezone_x
4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500
				{
					$$ = makeNode(TypeName);
					if ($5)
						$$->name = xlateSqlType("timestamptz");
					else
						$$->name = xlateSqlType("timestamp");
					/* XXX the timezone field seems to be unused
					 * - thomas 2001-09-06
					 */
					$$->timezone = $5;
					if (($3 < 0) || ($3 > 13))
4501 4502
						elog(ERROR,"TIMESTAMP(%d)%s precision must be between %d and %d",
							 $3, ($5 ? " WITH TIME ZONE": ""), 0, 13);
4503 4504
					$$->typmod = $3;
				}
4505
		| TIMESTAMP opt_timezone_x
4506 4507
				{
					$$ = makeNode(TypeName);
4508 4509 4510 4511 4512 4513 4514
					if ($2)
						$$->name = xlateSqlType("timestamptz");
					else
						$$->name = xlateSqlType("timestamp");
					/* XXX the timezone field seems to be unused
					 * - thomas 2001-09-06
					 */
4515
					$$->timezone = $2;
4516 4517 4518 4519 4520 4521
					/* SQL99 specified a default precision of six
					 * for schema definitions. But for timestamp
					 * literals we don't want to throw away precision
					 * so leave this as unspecified for now.
					 * Later, we may want a different production
					 * for schemas. - thomas 2001-12-07
4522
					 */
4523
					$$->typmod = -1;
4524 4525 4526 4527 4528 4529 4530 4531 4532
				}
		| TIME '(' Iconst ')' opt_timezone
				{
					$$ = makeNode(TypeName);
					if ($5)
						$$->name = xlateSqlType("timetz");
					else
						$$->name = xlateSqlType("time");
					if (($3 < 0) || ($3 > 13))
4533 4534
						elog(ERROR,"TIME(%d)%s precision must be between %d and %d",
							 $3, ($5 ? " WITH TIME ZONE": ""), 0, 13);
4535
					$$->typmod = $3;
4536
				}
4537
		| TIME opt_timezone
4538 4539
				{
					$$ = makeNode(TypeName);
4540 4541 4542 4543
					if ($2)
						$$->name = xlateSqlType("timetz");
					else
						$$->name = xlateSqlType("time");
4544
					/* SQL99 specified a default precision of zero.
4545 4546
					 * See comments for timestamp above on why we will
					 * leave this unspecified for now. - thomas 2001-12-07
4547
					 */
4548
					$$->typmod = -1;
4549
				}
4550 4551
		;

4552
ConstInterval:  INTERVAL
4553 4554 4555
				{
					$$ = makeNode(TypeName);
					$$->name = xlateSqlType("interval");
4556
					$$->typmod = -1;
4557
				}
4558
		;
4559

4560 4561 4562 4563 4564 4565 4566 4567 4568 4569
/* XXX Make the default be WITH TIME ZONE for 7.2 to help with database upgrades
 * but revert this back to WITHOUT TIME ZONE for 7.3.
 * Do this by simply reverting opt_timezone_x to opt_timezone - thomas 2001-09-06
 */

opt_timezone_x:  WITH TIME ZONE					{ $$ = TRUE; }
		| WITHOUT TIME ZONE						{ $$ = FALSE; }
		| /*EMPTY*/								{ $$ = TRUE; }
		;

4570
opt_timezone:  WITH TIME ZONE					{ $$ = TRUE; }
4571
		| WITHOUT TIME ZONE						{ $$ = FALSE; }
4572 4573 4574
		| /*EMPTY*/								{ $$ = FALSE; }
		;

4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588
opt_interval:  YEAR_P							{ $$ = MASK(YEAR); }
		| MONTH_P								{ $$ = MASK(MONTH); }
		| DAY_P									{ $$ = MASK(DAY); }
		| HOUR_P								{ $$ = MASK(HOUR); }
		| MINUTE_P								{ $$ = MASK(MINUTE); }
		| SECOND_P								{ $$ = MASK(SECOND); }
		| YEAR_P TO MONTH_P						{ $$ = MASK(YEAR) | MASK(MONTH); }
		| DAY_P TO HOUR_P						{ $$ = MASK(DAY) | MASK(HOUR); }
		| DAY_P TO MINUTE_P						{ $$ = MASK(DAY) | MASK(HOUR) | MASK(MINUTE); }
		| DAY_P TO SECOND_P						{ $$ = MASK(DAY) | MASK(HOUR) | MASK(MINUTE) | MASK(SECOND); }
		| HOUR_P TO MINUTE_P					{ $$ = MASK(HOUR) | MASK(MINUTE); }
		| HOUR_P TO SECOND_P					{ $$ = MASK(HOUR) | MASK(MINUTE) | MASK(SECOND); }
		| MINUTE_P TO SECOND_P					{ $$ = MASK(MINUTE) | MASK(SECOND); }
		| /*EMPTY*/								{ $$ = -1; }
4589 4590
		;

4591 4592 4593

/*****************************************************************************
 *
4594
 *	expression grammar
4595 4596 4597
 *
 *****************************************************************************/

4598 4599 4600 4601
/* Expressions using row descriptors
 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
 *  with singleton expressions.
 */
4602
row_expr: '(' row_descriptor ')' IN select_with_parens
4603
				{
4604 4605
					SubLink *n = makeNode(SubLink);
					n->lefthand = $2;
4606
					n->oper = (List *) makeA_Expr(OP, "=", NULL, NULL);
4607
					n->useor = FALSE;
4608
					n->subLinkType = ANY_SUBLINK;
4609
					n->subselect = $5;
4610
					$$ = (Node *)n;
4611
				}
4612
		| '(' row_descriptor ')' NOT IN select_with_parens
4613
				{
4614 4615
					SubLink *n = makeNode(SubLink);
					n->lefthand = $2;
4616
					n->oper = (List *) makeA_Expr(OP, "<>", NULL, NULL);
4617
					n->useor = TRUE;
4618
					n->subLinkType = ALL_SUBLINK;
4619
					n->subselect = $6;
4620 4621
					$$ = (Node *)n;
				}
4622
		| '(' row_descriptor ')' all_Op sub_type select_with_parens
4623 4624 4625
				{
					SubLink *n = makeNode(SubLink);
					n->lefthand = $2;
4626 4627
					n->oper = (List *) makeA_Expr(OP, $4, NULL, NULL);
					if (strcmp($4, "<>") == 0)
4628
						n->useor = TRUE;
4629
					else
4630
						n->useor = FALSE;
4631
					n->subLinkType = $5;
4632
					n->subselect = $6;
Bruce Momjian's avatar
Bruce Momjian committed
4633 4634
					$$ = (Node *)n;
				}
4635
		| '(' row_descriptor ')' all_Op select_with_parens
Bruce Momjian's avatar
Bruce Momjian committed
4636 4637 4638
				{
					SubLink *n = makeNode(SubLink);
					n->lefthand = $2;
4639 4640
					n->oper = (List *) makeA_Expr(OP, $4, NULL, NULL);
					if (strcmp($4, "<>") == 0)
4641
						n->useor = TRUE;
4642
					else
4643
						n->useor = FALSE;
4644
					n->subLinkType = MULTIEXPR_SUBLINK;
4645
					n->subselect = $5;
Bruce Momjian's avatar
Bruce Momjian committed
4646 4647
					$$ = (Node *)n;
				}
4648
		| '(' row_descriptor ')' all_Op '(' row_descriptor ')'
4649
				{
Bruce Momjian's avatar
Bruce Momjian committed
4650
					$$ = makeRowExpr($4, $2, $6);
4651
				}
4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668
		| '(' row_descriptor ')' OVERLAPS '(' row_descriptor ')'
				{
					FuncCall *n = makeNode(FuncCall);
					List *largs = $2;
					List *rargs = $6;
					n->funcname = xlateSqlFunc("overlaps");
					if (length(largs) == 1)
						largs = lappend(largs, $2);
					else if (length(largs) != 2)
						elog(ERROR, "Wrong number of parameters"
							 " on left side of OVERLAPS expression");
					if (length(rargs) == 1)
						rargs = lappend(rargs, $6);
					else if (length(rargs) != 2)
						elog(ERROR, "Wrong number of parameters"
							 " on right side of OVERLAPS expression");
					n->args = nconc(largs, rargs);
4669 4670
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
4671 4672
					$$ = (Node *)n;
				}
4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686
		;

row_descriptor:  row_list ',' a_expr
				{
					$$ = lappend($1, $3);
				}
		;

row_list:  row_list ',' a_expr
				{
					$$ = lappend($1, $3);
				}
		| a_expr
				{
4687
					$$ = makeList1($1);
4688 4689
				}
		;
4690

4691
sub_type:  ANY								{ $$ = ANY_SUBLINK; }
4692
		| SOME								{ $$ = ANY_SUBLINK; }
4693 4694 4695
		| ALL								{ $$ = ALL_SUBLINK; }
		;

4696 4697
all_Op:  Op | MathOp;

4698
MathOp:  '+'			{ $$ = "+"; }
4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710
		| '-'			{ $$ = "-"; }
		| '*'			{ $$ = "*"; }
		| '/'			{ $$ = "/"; }
		| '%'			{ $$ = "%"; }
		| '^'			{ $$ = "^"; }
		| '<'			{ $$ = "<"; }
		| '>'			{ $$ = ">"; }
		| '='			{ $$ = "="; }
		;

/*
 * General expressions
4711
 * This is the heart of the expression syntax.
4712 4713 4714 4715 4716 4717 4718 4719 4720 4721
 *
 * We have two expression types: a_expr is the unrestricted kind, and
 * b_expr is a subset that must be used in some places to avoid shift/reduce
 * conflicts.  For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
 * because that use of AND conflicts with AND as a boolean operator.  So,
 * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
 *
 * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
 * always be used by surrounding it with parens.
 *
4722
 * c_expr is all the productions that are common to a_expr and b_expr;
4723
 * it's factored out just to eliminate redundant coding.
4724
 */
4725
a_expr:  c_expr
4726
				{	$$ = $1;  }
4727
		| a_expr TYPECAST Typename
4728
				{	$$ = makeTypeCast($1, $3); }
4729 4730 4731 4732 4733 4734 4735 4736 4737
		| a_expr AT TIME ZONE c_expr
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = "timezone";
					n->args = makeList2($5, $1);
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
					$$ = (Node *) n;
				}
4738 4739 4740 4741 4742 4743 4744 4745 4746
		/*
		 * These operators must be called out explicitly in order to make use
		 * of yacc/bison's automatic operator-precedence handling.  All other
		 * operator names are handled by the generic productions using "Op",
		 * below; and all those operators will have the same precedence.
		 *
		 * If you add more explicitly-known operators, be sure to add them
		 * also to b_expr and to the MathOp list above.
		 */
4747
		| '+' a_expr					%prec UMINUS
4748
				{	$$ = makeA_Expr(OP, "+", NULL, $2); }
4749
		| '-' a_expr					%prec UMINUS
4750
				{	$$ = doNegate($2); }
Bruce Momjian's avatar
Bruce Momjian committed
4751
		| '%' a_expr
Bruce Momjian's avatar
Bruce Momjian committed
4752
				{	$$ = makeA_Expr(OP, "%", NULL, $2); }
Bruce Momjian's avatar
Bruce Momjian committed
4753 4754
		| '^' a_expr
				{	$$ = makeA_Expr(OP, "^", NULL, $2); }
Bruce Momjian's avatar
Bruce Momjian committed
4755
		| a_expr '%'
Bruce Momjian's avatar
Bruce Momjian committed
4756
				{	$$ = makeA_Expr(OP, "%", $1, NULL); }
Bruce Momjian's avatar
Bruce Momjian committed
4757 4758
		| a_expr '^'
				{	$$ = makeA_Expr(OP, "^", $1, NULL); }
4759 4760 4761 4762
		| a_expr '+' a_expr
				{	$$ = makeA_Expr(OP, "+", $1, $3); }
		| a_expr '-' a_expr
				{	$$ = makeA_Expr(OP, "-", $1, $3); }
4763 4764
		| a_expr '*' a_expr
				{	$$ = makeA_Expr(OP, "*", $1, $3); }
4765 4766
		| a_expr '/' a_expr
				{	$$ = makeA_Expr(OP, "/", $1, $3); }
4767 4768
		| a_expr '%' a_expr
				{	$$ = makeA_Expr(OP, "%", $1, $3); }
Bruce Momjian's avatar
Bruce Momjian committed
4769 4770
		| a_expr '^' a_expr
				{	$$ = makeA_Expr(OP, "^", $1, $3); }
4771 4772 4773 4774 4775
		| a_expr '<' a_expr
				{	$$ = makeA_Expr(OP, "<", $1, $3); }
		| a_expr '>' a_expr
				{	$$ = makeA_Expr(OP, ">", $1, $3); }
		| a_expr '=' a_expr
4776
				{	$$ = makeA_Expr(OP, "=", $1, $3); }
4777

4778
		| a_expr Op a_expr
4779
				{	$$ = makeA_Expr(OP, $2, $1, $3); }
4780 4781
		| Op a_expr
				{	$$ = makeA_Expr(OP, $1, NULL, $2); }
4782
		| a_expr Op					%prec POSTFIXOP
4783
				{	$$ = makeA_Expr(OP, $2, $1, NULL); }
4784

4785 4786 4787 4788 4789 4790
		| a_expr AND a_expr
				{	$$ = makeA_Expr(AND, NULL, $1, $3); }
		| a_expr OR a_expr
				{	$$ = makeA_Expr(OR, NULL, $1, $3); }
		| NOT a_expr
				{	$$ = makeA_Expr(NOT, NULL, NULL, $2); }
4791

4792
		| a_expr LIKE a_expr
4793
				{	$$ = makeA_Expr(OP, "~~", $1, $3); }
4794 4795 4796
		| a_expr LIKE a_expr ESCAPE a_expr
				{
					FuncCall *n = makeNode(FuncCall);
4797
					n->funcname = "like_escape";
4798
					n->args = makeList2($3, $5);
4799 4800
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
4801
					$$ = makeA_Expr(OP, "~~", $1, (Node *) n);
4802
				}
4803
		| a_expr NOT LIKE a_expr
4804
				{	$$ = makeA_Expr(OP, "!~~", $1, $4); }
4805 4806 4807
		| a_expr NOT LIKE a_expr ESCAPE a_expr
				{
					FuncCall *n = makeNode(FuncCall);
4808
					n->funcname = "like_escape";
4809
					n->args = makeList2($4, $6);
4810 4811
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
4812
					$$ = makeA_Expr(OP, "!~~", $1, (Node *) n);
4813 4814
				}
		| a_expr ILIKE a_expr
4815
				{	$$ = makeA_Expr(OP, "~~*", $1, $3); }
4816 4817 4818
		| a_expr ILIKE a_expr ESCAPE a_expr
				{
					FuncCall *n = makeNode(FuncCall);
4819
					n->funcname = "like_escape";
4820
					n->args = makeList2($3, $5);
4821 4822
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
4823
					$$ = makeA_Expr(OP, "~~*", $1, (Node *) n);
4824 4825
				}
		| a_expr NOT ILIKE a_expr
4826
				{	$$ = makeA_Expr(OP, "!~~*", $1, $4); }
4827 4828 4829
		| a_expr NOT ILIKE a_expr ESCAPE a_expr
				{
					FuncCall *n = makeNode(FuncCall);
4830
					n->funcname = "like_escape";
4831
					n->args = makeList2($4, $6);
4832 4833
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
4834
					$$ = makeA_Expr(OP, "!~~*", $1, (Node *) n);
4835
				}
4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846
		/* NullTest clause
		 * Define SQL92-style Null test clause.
		 * Allow two forms described in the standard:
		 *  a IS NULL
		 *  a IS NOT NULL
		 * Allow two SQL extensions
		 *  a ISNULL
		 *  a NOTNULL
		 * NOTE: this is not yet fully SQL-compatible, since SQL92
		 * allows a row constructor as argument, not just a scalar.
		 */
4847
		| a_expr ISNULL
4848 4849 4850 4851 4852 4853
				{
					NullTest *n = makeNode(NullTest);
					n->arg = $1;
					n->nulltesttype = IS_NULL;
					$$ = (Node *)n;
				}
4854
		| a_expr IS NULL_P
4855 4856 4857 4858 4859 4860
				{
					NullTest *n = makeNode(NullTest);
					n->arg = $1;
					n->nulltesttype = IS_NULL;
					$$ = (Node *)n;
				}
4861
		| a_expr NOTNULL
4862 4863 4864 4865 4866 4867
				{
					NullTest *n = makeNode(NullTest);
					n->arg = $1;
					n->nulltesttype = IS_NOT_NULL;
					$$ = (Node *)n;
				}
4868
		| a_expr IS NOT NULL_P
4869 4870 4871 4872 4873 4874
				{
					NullTest *n = makeNode(NullTest);
					n->arg = $1;
					n->nulltesttype = IS_NOT_NULL;
					$$ = (Node *)n;
				}
4875 4876 4877 4878
		/* IS TRUE, IS FALSE, etc used to be function calls
		 *  but let's make them expressions to allow the optimizer
		 *  a chance to eliminate them if a_expr is a constant string.
		 * - thomas 1997-12-22
4879 4880 4881 4882
		 *
		 *  Created BooleanTest Node type, and changed handling
		 *  for NULL inputs
		 * - jec 2001-06-18
4883
		 */
4884 4885
		| a_expr IS TRUE_P
				{
4886 4887 4888 4889
					BooleanTest *b = makeNode(BooleanTest);
					b->arg = $1;
					b->booltesttype = IS_TRUE;
					$$ = (Node *)b;
4890
				}
4891
		| a_expr IS NOT TRUE_P
4892
				{
4893 4894 4895 4896
					BooleanTest *b = makeNode(BooleanTest);
					b->arg = $1;
					b->booltesttype = IS_NOT_TRUE;
					$$ = (Node *)b;
4897
				}
4898
		| a_expr IS FALSE_P
4899
				{
4900 4901 4902 4903
					BooleanTest *b = makeNode(BooleanTest);
					b->arg = $1;
					b->booltesttype = IS_FALSE;
					$$ = (Node *)b;
4904
				}
4905
		| a_expr IS NOT FALSE_P
4906
				{
4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924
					BooleanTest *b = makeNode(BooleanTest);
					b->arg = $1;
					b->booltesttype = IS_NOT_FALSE;
					$$ = (Node *)b;
				}
		| a_expr IS UNKNOWN
				{
					BooleanTest *b = makeNode(BooleanTest);
					b->arg = $1;
					b->booltesttype = IS_UNKNOWN;
					$$ = (Node *)b;
				}
		| a_expr IS NOT UNKNOWN
				{
					BooleanTest *b = makeNode(BooleanTest);
					b->arg = $1;
					b->booltesttype = IS_NOT_UNKNOWN;
					$$ = (Node *)b;
4925
				}
4926
		| a_expr BETWEEN b_expr AND b_expr			%prec BETWEEN
4927 4928 4929 4930 4931
				{
					$$ = makeA_Expr(AND, NULL,
						makeA_Expr(OP, ">=", $1, $3),
						makeA_Expr(OP, "<=", $1, $5));
				}
4932
		| a_expr NOT BETWEEN b_expr AND b_expr		%prec BETWEEN
4933 4934 4935 4936 4937
				{
					$$ = makeA_Expr(OR, NULL,
						makeA_Expr(OP, "<", $1, $4),
						makeA_Expr(OP, ">", $1, $6));
				}
4938
		| a_expr IN in_expr
4939
				{
4940
					/* in_expr returns a SubLink or a list of a_exprs */
4941
					if (IsA($3, SubLink))
4942
					{
4943
							SubLink *n = (SubLink *)$3;
4944
							n->lefthand = makeList1($1);
4945
							n->oper = (List *) makeA_Expr(OP, "=", NULL, NULL);
4946
							n->useor = FALSE;
4947 4948
							n->subLinkType = ANY_SUBLINK;
							$$ = (Node *)n;
4949
					}
4950 4951 4952 4953
					else
					{
						Node *n = NULL;
						List *l;
4954
						foreach(l, (List *) $3)
4955 4956 4957 4958 4959 4960 4961 4962 4963
						{
							Node *cmp = makeA_Expr(OP, "=", $1, lfirst(l));
							if (n == NULL)
								n = cmp;
							else
								n = makeA_Expr(OR, NULL, n, cmp);
						}
						$$ = n;
					}
4964
				}
4965
		| a_expr NOT IN in_expr
4966
				{
4967
					/* in_expr returns a SubLink or a list of a_exprs */
4968
					if (IsA($4, SubLink))
4969
					{
4970
						SubLink *n = (SubLink *)$4;
4971
						n->lefthand = makeList1($1);
4972
						n->oper = (List *) makeA_Expr(OP, "<>", NULL, NULL);
4973
						n->useor = FALSE;
4974 4975 4976 4977 4978 4979 4980
						n->subLinkType = ALL_SUBLINK;
						$$ = (Node *)n;
					}
					else
					{
						Node *n = NULL;
						List *l;
4981
						foreach(l, (List *) $4)
4982 4983 4984 4985 4986 4987 4988 4989
						{
							Node *cmp = makeA_Expr(OP, "<>", $1, lfirst(l));
							if (n == NULL)
								n = cmp;
							else
								n = makeA_Expr(AND, NULL, n, cmp);
						}
						$$ = n;
4990 4991
					}
				}
4992
		| a_expr all_Op sub_type select_with_parens		%prec Op
Bruce Momjian's avatar
Bruce Momjian committed
4993 4994
				{
					SubLink *n = makeNode(SubLink);
4995
					n->lefthand = makeList1($1);
4996
					n->oper = (List *) makeA_Expr(OP, $2, NULL, NULL);
4997
					n->useor = FALSE; /* doesn't matter since only one col */
4998
					n->subLinkType = $3;
4999
					n->subselect = $4;
Bruce Momjian's avatar
Bruce Momjian committed
5000 5001
					$$ = (Node *)n;
				}
5002 5003
		| row_expr
				{	$$ = $1;  }
5004
		;
5005

5006 5007 5008 5009 5010
/*
 * Restricted expressions
 *
 * b_expr is a subset of the complete expression syntax defined by a_expr.
 *
5011
 * Presently, AND, NOT, IS, and IN are the a_expr keywords that would
5012 5013
 * cause trouble in the places where b_expr is used.  For simplicity, we
 * just eliminate all the boolean-keyword-operator productions from b_expr.
5014
 */
5015
b_expr:  c_expr
5016
				{	$$ = $1;  }
5017
		| b_expr TYPECAST Typename
5018
				{	$$ = makeTypeCast($1, $3); }
5019
		| '+' b_expr					%prec UMINUS
5020
				{	$$ = makeA_Expr(OP, "+", NULL, $2); }
5021
		| '-' b_expr					%prec UMINUS
5022
				{	$$ = doNegate($2); }
Bruce Momjian's avatar
Bruce Momjian committed
5023 5024
		| '%' b_expr
				{	$$ = makeA_Expr(OP, "%", NULL, $2); }
Bruce Momjian's avatar
Bruce Momjian committed
5025 5026
		| '^' b_expr
				{	$$ = makeA_Expr(OP, "^", NULL, $2); }
Bruce Momjian's avatar
Bruce Momjian committed
5027 5028
		| b_expr '%'
				{	$$ = makeA_Expr(OP, "%", $1, NULL); }
Bruce Momjian's avatar
Bruce Momjian committed
5029 5030
		| b_expr '^'
				{	$$ = makeA_Expr(OP, "^", $1, NULL); }
5031 5032 5033 5034
		| b_expr '+' b_expr
				{	$$ = makeA_Expr(OP, "+", $1, $3); }
		| b_expr '-' b_expr
				{	$$ = makeA_Expr(OP, "-", $1, $3); }
5035 5036
		| b_expr '*' b_expr
				{	$$ = makeA_Expr(OP, "*", $1, $3); }
5037 5038
		| b_expr '/' b_expr
				{	$$ = makeA_Expr(OP, "/", $1, $3); }
5039 5040
		| b_expr '%' b_expr
				{	$$ = makeA_Expr(OP, "%", $1, $3); }
5041 5042
		| b_expr '^' b_expr
				{	$$ = makeA_Expr(OP, "^", $1, $3); }
5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053
		| b_expr '<' b_expr
				{	$$ = makeA_Expr(OP, "<", $1, $3); }
		| b_expr '>' b_expr
				{	$$ = makeA_Expr(OP, ">", $1, $3); }
		| b_expr '=' b_expr
				{	$$ = makeA_Expr(OP, "=", $1, $3); }

		| b_expr Op b_expr
				{	$$ = makeA_Expr(OP, $2, $1, $3); }
		| Op b_expr
				{	$$ = makeA_Expr(OP, $1, NULL, $2); }
5054
		| b_expr Op					%prec POSTFIXOP
5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065
				{	$$ = makeA_Expr(OP, $2, $1, NULL); }
		;

/*
 * Productions that can be used in both a_expr and b_expr.
 *
 * Note: productions that refer recursively to a_expr or b_expr mostly
 * cannot appear here.  However, it's OK to refer to a_exprs that occur
 * inside parentheses, such as function arguments; that cannot introduce
 * ambiguity to the b_expr syntax.
 */
5066
c_expr:  columnref
5067
				{	$$ = (Node *) $1;  }
5068 5069 5070
		| AexprConst
				{	$$ = $1;  }
		| PARAM attrs opt_indirection
5071
				{
5072 5073 5074 5075 5076 5077 5078 5079
					/*
					 * PARAM without field names is considered a constant,
					 * but with 'em, it is not.  Not very consistent ...
					 */
					ParamRef *n = makeNode(ParamRef);
					n->number = $1;
					n->fields = $2;
					n->indirection = $3;
5080
					$$ = (Node *)n;
5081
				}
5082
		| '(' a_expr ')'
5083
				{	$$ = $2; }
5084 5085 5086 5087 5088 5089 5090 5091
		| '(' a_expr ')' attrs opt_indirection
				{
					ExprFieldSelect *n = makeNode(ExprFieldSelect);
					n->arg = $2;
					n->fields = $4;
					n->indirection = $5;
					$$ = (Node *)n;
				}
5092
		| CAST '(' a_expr AS Typename ')'
5093
				{	$$ = makeTypeCast($3, $5); }
5094 5095
		| case_expr
				{	$$ = $1; }
5096
		| func_name '(' ')'
5097 5098 5099 5100
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = $1;
					n->args = NIL;
5101 5102
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5103 5104
					$$ = (Node *)n;
				}
5105
		| func_name '(' expr_list ')'
5106 5107 5108 5109
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = $1;
					n->args = $3;
5110 5111
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5112 5113
					$$ = (Node *)n;
				}
5114 5115 5116 5117 5118
		| func_name '(' ALL expr_list ')'
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = $1;
					n->args = $4;
5119 5120
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5121 5122 5123 5124 5125 5126
					/* Ideally we'd mark the FuncCall node to indicate
					 * "must be an aggregate", but there's no provision
					 * for that in FuncCall at the moment.
					 */
					$$ = (Node *)n;
				}
5127 5128 5129 5130 5131
		| func_name '(' DISTINCT expr_list ')'
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = $1;
					n->args = $4;
5132 5133
					n->agg_star = FALSE;
					n->agg_distinct = TRUE;
5134 5135
					$$ = (Node *)n;
				}
5136 5137 5138 5139 5140 5141 5142 5143 5144 5145
		| func_name '(' '*' ')'
				{
					/*
					 * For now, we transform AGGREGATE(*) into AGGREGATE(1).
					 *
					 * This does the right thing for COUNT(*) (in fact,
					 * any certainly-non-null expression would do for COUNT),
					 * and there are no other aggregates in SQL92 that accept
					 * '*' as parameter.
					 *
5146 5147 5148
					 * The FuncCall node is also marked agg_star = true,
					 * so that later processing can detect what the argument
					 * really was.
5149 5150 5151 5152 5153 5154 5155
					 */
					FuncCall *n = makeNode(FuncCall);
					A_Const *star = makeNode(A_Const);

					star->val.type = T_Integer;
					star->val.val.ival = 1;
					n->funcname = $1;
5156
					n->args = makeList1(star);
5157 5158
					n->agg_star = TRUE;
					n->agg_distinct = FALSE;
5159 5160
					$$ = (Node *)n;
				}
5161
		| CURRENT_DATE opt_empty_parentheses
5162
				{
5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176
					/*
					 * Translate as "date('now'::text)".
					 *
					 * We cannot use "'now'::date" because coerce_type() will
					 * immediately reduce that to a constant representing
					 * today's date.  We need to delay the conversion until
					 * runtime, else the wrong things will happen when
					 * CURRENT_DATE is used in a column default value or rule.
					 *
					 * This could be simplified if we had a way to generate
					 * an expression tree representing runtime application
					 * of type-input conversion functions...
					 */
					A_Const *s = makeNode(A_Const);
5177
					TypeName *t = makeNode(TypeName);
5178
					TypeName *d = makeNode(TypeName);
5179

5180 5181 5182
					s->val.type = T_String;
					s->val.val.str = "now";
					s->typename = t;
5183

5184
					t->name = xlateSqlType("text");
5185
					t->setof = FALSE;
5186
					t->typmod = -1;
5187

5188 5189 5190
					d->name = xlateSqlType("date");
					d->setof = FALSE;
					d->typmod = -1;
5191

5192
					$$ = (Node *)makeTypeCast((Node *)s, d);
5193
				}
5194
		| CURRENT_TIME opt_empty_parentheses
5195
				{
5196
					/*
5197
					 * Translate as "timetz('now'::text)".
5198 5199 5200
					 * See comments for CURRENT_DATE.
					 */
					A_Const *s = makeNode(A_Const);
5201
					TypeName *t = makeNode(TypeName);
5202
					TypeName *d = makeNode(TypeName);
5203

5204 5205 5206
					s->val.type = T_String;
					s->val.val.str = "now";
					s->typename = t;
5207

5208
					t->name = xlateSqlType("text");
5209
					t->setof = FALSE;
5210
					t->typmod = -1;
5211

5212
					d->name = xlateSqlType("timetz");
5213
					d->setof = FALSE;
5214 5215 5216 5217 5218 5219
					/* SQL99 mandates a default precision of zero for TIME
					 * fields in schemas. However, for CURRENT_TIME
					 * let's preserve the microsecond precision we
					 * might see from the system clock. - thomas 2001-12-07
					 */
					d->typmod = 6;
5220

5221
					$$ = (Node *)makeTypeCast((Node *)s, d);
5222 5223 5224
				}
		| CURRENT_TIME '(' Iconst ')'
				{
5225
					/*
5226
					 * Translate as "timetz('now'::text)".
5227 5228
					 * See comments for CURRENT_DATE.
					 */
5229 5230
					A_Const *s = makeNode(A_Const);
					TypeName *t = makeNode(TypeName);
5231
					TypeName *d = makeNode(TypeName);
5232 5233 5234 5235 5236

					s->val.type = T_String;
					s->val.val.str = "now";
					s->typename = t;

5237
					t->name = xlateSqlType("text");
5238
					t->setof = FALSE;
5239
					t->typmod = -1;
5240

5241 5242 5243 5244 5245 5246
					d->name = xlateSqlType("timetz");
					d->setof = FALSE;
					if (($3 < 0) || ($3 > 13))
						elog(ERROR,"CURRENT_TIME(%d) precision must be between %d and %d",
							 $3, 0, 13);
					d->typmod = $3;
5247

5248
					$$ = (Node *)makeTypeCast((Node *)s, d);
5249
				}
5250
		| CURRENT_TIMESTAMP opt_empty_parentheses
5251
				{
5252
					/*
5253
					 * Translate as "timestamptz('now'::text)".
5254 5255 5256
					 * See comments for CURRENT_DATE.
					 */
					A_Const *s = makeNode(A_Const);
5257
					TypeName *t = makeNode(TypeName);
5258
					TypeName *d = makeNode(TypeName);
5259

5260 5261 5262
					s->val.type = T_String;
					s->val.val.str = "now";
					s->typename = t;
5263

5264
					t->name = xlateSqlType("text");
5265
					t->setof = FALSE;
5266
					t->typmod = -1;
5267

5268 5269
					d->name = xlateSqlType("timestamptz");
					d->setof = FALSE;
5270 5271 5272 5273 5274
					/* SQL99 mandates a default precision of 6 for timestamp.
					 * Also, that is about as precise as we will get since
					 * we are using a microsecond time interface.
					 * - thomas 2001-12-07
					 */
5275
					d->typmod = 6;
5276

5277
					$$ = (Node *)makeTypeCast((Node *)s, d);
5278 5279 5280
				}
		| CURRENT_TIMESTAMP '(' Iconst ')'
				{
5281
					/*
5282
					 * Translate as "timestamptz('now'::text)".
5283 5284
					 * See comments for CURRENT_DATE.
					 */
5285 5286
					A_Const *s = makeNode(A_Const);
					TypeName *t = makeNode(TypeName);
5287
					TypeName *d = makeNode(TypeName);
5288 5289 5290 5291 5292

					s->val.type = T_String;
					s->val.val.str = "now";
					s->typename = t;

5293
					t->name = xlateSqlType("text");
5294
					t->setof = FALSE;
5295
					t->typmod = -1;
5296

5297 5298 5299
					d->name = xlateSqlType("timestamptz");
					d->setof = FALSE;
					if (($3 < 0) || ($3 > 13))
5300
						elog(ERROR,"CURRENT_TIMESTAMP(%d) precision must be between %d and %d",
5301 5302
							 $3, 0, 13);
					d->typmod = $3;
5303

5304
					$$ = (Node *)makeTypeCast((Node *)s, d);
5305
				}
5306
		| CURRENT_USER opt_empty_parentheses
5307 5308
				{
					FuncCall *n = makeNode(FuncCall);
5309
					n->funcname = "current_user";
5310
					n->args = NIL;
5311 5312
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5313 5314
					$$ = (Node *)n;
				}
5315
		| SESSION_USER opt_empty_parentheses
5316 5317
				{
					FuncCall *n = makeNode(FuncCall);
5318
					n->funcname = "session_user";
5319
					n->args = NIL;
5320 5321
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5322 5323
					$$ = (Node *)n;
				}
5324
		| USER opt_empty_parentheses
5325 5326
				{
					FuncCall *n = makeNode(FuncCall);
5327
					n->funcname = "current_user";
5328
					n->args = NIL;
5329 5330
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5331 5332
					$$ = (Node *)n;
				}
5333 5334 5335 5336 5337
		| EXTRACT '(' extract_list ')'
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = "date_part";
					n->args = $3;
5338 5339
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5340 5341
					$$ = (Node *)n;
				}
5342 5343
		| POSITION '(' position_list ')'
				{
5344
					/* position(A in B) is converted to position(B, A) */
5345
					FuncCall *n = makeNode(FuncCall);
5346
					n->funcname = "position";
5347
					n->args = $3;
5348 5349
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5350 5351 5352 5353
					$$ = (Node *)n;
				}
		| SUBSTRING '(' substr_list ')'
				{
5354
					/* substring(A from B for C) is converted to
5355 5356
					 * substring(A, B, C) - thomas 2000-11-28
					 */
5357
					FuncCall *n = makeNode(FuncCall);
5358
					n->funcname = "substring";
5359
					n->args = $3;
5360 5361
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5362 5363 5364 5365
					$$ = (Node *)n;
				}
		| TRIM '(' BOTH trim_list ')'
				{
5366 5367 5368
					/* various trim expressions are defined in SQL92
					 * - thomas 1997-07-19
					 */
5369 5370 5371
					FuncCall *n = makeNode(FuncCall);
					n->funcname = "btrim";
					n->args = $4;
5372 5373
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5374 5375 5376 5377 5378 5379 5380
					$$ = (Node *)n;
				}
		| TRIM '(' LEADING trim_list ')'
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = "ltrim";
					n->args = $4;
5381 5382
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5383 5384 5385 5386 5387 5388 5389
					$$ = (Node *)n;
				}
		| TRIM '(' TRAILING trim_list ')'
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = "rtrim";
					n->args = $4;
5390 5391
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5392 5393 5394 5395 5396 5397 5398
					$$ = (Node *)n;
				}
		| TRIM '(' trim_list ')'
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = "btrim";
					n->args = $3;
5399 5400
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5401 5402
					$$ = (Node *)n;
				}
5403
		| select_with_parens			%prec UMINUS
5404 5405 5406 5407
				{
					SubLink *n = makeNode(SubLink);
					n->lefthand = NIL;
					n->oper = NIL;
5408
					n->useor = FALSE;
5409
					n->subLinkType = EXPR_SUBLINK;
5410
					n->subselect = $1;
5411 5412
					$$ = (Node *)n;
				}
5413
		| EXISTS select_with_parens
5414 5415 5416 5417
				{
					SubLink *n = makeNode(SubLink);
					n->lefthand = NIL;
					n->oper = NIL;
5418
					n->useor = FALSE;
5419
					n->subLinkType = EXISTS_SUBLINK;
5420
					n->subselect = $2;
5421 5422
					$$ = (Node *)n;
				}
5423 5424
		;

5425 5426 5427 5428
/*
 * Supporting nonterminals for expressions.
 */

5429
opt_indirection:	opt_indirection '[' a_expr ']'
5430 5431 5432
				{
					A_Indices *ai = makeNode(A_Indices);
					ai->lidx = NULL;
5433 5434
					ai->uidx = $3;
					$$ = lappend($1, ai);
5435
				}
5436
		| opt_indirection '[' a_expr ':' a_expr ']'
5437 5438
				{
					A_Indices *ai = makeNode(A_Indices);
5439 5440 5441
					ai->lidx = $3;
					ai->uidx = $5;
					$$ = lappend($1, ai);
5442
				}
5443
		| /*EMPTY*/
5444 5445
				{	$$ = NIL; }
		;
5446

5447
expr_list:  a_expr
5448
				{ $$ = makeList1($1); }
5449
		| expr_list ',' a_expr
5450
				{ $$ = lappend($1, $3); }
5451
		| expr_list USING a_expr
5452 5453
				{ $$ = lappend($1, $3); }
		;
5454

5455
extract_list:  extract_arg FROM a_expr
5456 5457 5458 5459
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_String;
					n->val.val.str = $1;
5460
					$$ = makeList2((Node *) n, $3);
5461
				}
5462
		| /*EMPTY*/
5463 5464
				{	$$ = NIL; }
		;
5465

5466 5467 5468 5469
/* Allow delimited string SCONST in extract_arg as an SQL extension.
 * - thomas 2001-04-12
 */

5470 5471 5472 5473 5474 5475 5476 5477
extract_arg:  IDENT						{ $$ = $1; }
		| YEAR_P						{ $$ = "year"; }
		| MONTH_P						{ $$ = "month"; }
		| DAY_P							{ $$ = "day"; }
		| HOUR_P						{ $$ = "hour"; }
		| MINUTE_P						{ $$ = "minute"; }
		| SECOND_P						{ $$ = "second"; }
		| SCONST						{ $$ = $1; }
5478 5479
		;

5480 5481 5482
/* position_list uses b_expr not a_expr to avoid conflict with general IN */

position_list:  b_expr IN b_expr
5483
				{	$$ = makeList2($3, $1); }
5484
		| /*EMPTY*/
5485 5486
				{	$$ = NIL; }
		;
5487

5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498
/* SUBSTRING() arguments
 * SQL9x defines a specific syntax for arguments to SUBSTRING():
 * o substring(text from int for int)
 * o substring(text from int) get entire string from starting point "int"
 * o substring(text for int) get first "int" characters of string
 * We also want to implement generic substring functions which accept
 * the usual generic list of arguments. So we will accept both styles
 * here, and convert the SQL9x style to the generic list for further
 * processing. - thomas 2000-11-28
 */
substr_list:  a_expr substr_from substr_for
5499
				{
5500
					$$ = makeList3($1, $2, $3);
5501
				}
5502 5503 5504 5505 5506 5507 5508 5509 5510
		| a_expr substr_for substr_from
				{
					$$ = makeList3($1, $3, $2);
				}
		| a_expr substr_from
				{
					$$ = makeList2($1, $2);
				}
		| a_expr substr_for
5511 5512 5513 5514
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_Integer;
					n->val.val.ival = 1;
5515 5516 5517 5518 5519
					$$ = makeList3($1, (Node *)n, $2);
				}
		| expr_list
				{
					$$ = $1;
5520
				}
5521 5522
		| /*EMPTY*/
				{	$$ = NIL; }
5523
		;
5524

5525 5526 5527 5528 5529
substr_from:  FROM a_expr
				{	$$ = $2; }
		;

substr_for:  FOR a_expr
5530 5531
				{	$$ = $2; }
		;
5532

5533
trim_list:  a_expr FROM expr_list
5534
				{ $$ = lappend($3, $1); }
5535
		| FROM expr_list
5536
				{ $$ = $2; }
5537
		| expr_list
5538 5539
				{ $$ = $1; }
		;
5540

5541
in_expr:  select_with_parens
5542
				{
5543 5544 5545
					SubLink *n = makeNode(SubLink);
					n->subselect = $1;
					$$ = (Node *)n;
5546
				}
5547 5548
		| '(' in_expr_nodes ')'
				{	$$ = (Node *)$2; }
5549
		;
5550

5551
in_expr_nodes:  a_expr
5552
				{	$$ = makeList1($1); }
5553 5554
		| in_expr_nodes ',' a_expr
				{	$$ = lappend($1, $3); }
5555
		;
5556

5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583
/* Case clause
 * Define SQL92-style case clause.
 * Allow all four forms described in the standard:
 * - Full specification
 *  CASE WHEN a = b THEN c ... ELSE d END
 * - Implicit argument
 *  CASE a WHEN b THEN c ... ELSE d END
 * - Conditional NULL
 *  NULLIF(x,y)
 *  same as CASE WHEN x = y THEN NULL ELSE x END
 * - Conditional substitution from list, use first non-null argument
 *  COALESCE(a,b,...)
 * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
 * - thomas 1998-11-09
 */
case_expr:  CASE case_arg when_clause_list case_default END_TRANS
				{
					CaseExpr *c = makeNode(CaseExpr);
					c->arg = $2;
					c->args = $3;
					c->defresult = $4;
					$$ = (Node *)c;
				}
		| NULLIF '(' a_expr ',' a_expr ')'
				{
					CaseExpr *c = makeNode(CaseExpr);
					CaseWhen *w = makeNode(CaseWhen);
5584 5585 5586 5587 5588 5589
/*
					A_Const *n = makeNode(A_Const);
					n->val.type = T_Null;
					w->result = (Node *)n;
*/
					w->expr = makeA_Expr(OP, "=", $3, $5);
5590
					c->args = makeList1(w);
5591 5592 5593 5594 5595 5596 5597 5598 5599
					c->defresult = $3;
					$$ = (Node *)c;
				}
		| COALESCE '(' expr_list ')'
				{
					CaseExpr *c = makeNode(CaseExpr);
					List *l;
					foreach (l,$3)
					{
5600 5601 5602 5603 5604
						CaseWhen *w = makeNode(CaseWhen);
						NullTest *n = makeNode(NullTest);
						n->arg = lfirst(l);
						n->nulltesttype = IS_NOT_NULL;
						w->expr = (Node *) n;
5605 5606 5607 5608 5609 5610 5611 5612 5613 5614
						w->result = lfirst(l);
						c->args = lappend(c->args, w);
					}
					$$ = (Node *)c;
				}
		;

when_clause_list:  when_clause_list when_clause
				{ $$ = lappend($1, $2); }
		| when_clause
5615
				{ $$ = makeList1($1); }
5616 5617
		;

5618
when_clause:  WHEN a_expr THEN a_expr
5619 5620 5621 5622 5623 5624 5625 5626
				{
					CaseWhen *w = makeNode(CaseWhen);
					w->expr = $2;
					w->result = $4;
					$$ = (Node *)w;
				}
		;

5627
case_default:  ELSE a_expr						{ $$ = $2; }
5628 5629 5630
		| /*EMPTY*/								{ $$ = NULL; }
		;

5631 5632
case_arg:  a_expr
				{	$$ = $1; }
5633 5634 5635 5636
		| /*EMPTY*/
				{	$$ = NULL; }
		;

5637 5638 5639 5640 5641 5642
/*
 * columnref starts with relation_name not ColId, so that OLD and NEW
 * references can be accepted.  Note that when there are more than two
 * dotted names, the first name is not actually a relation name...
 */
columnref: relation_name opt_indirection
5643
				{
5644 5645 5646
					$$ = makeNode(ColumnRef);
					$$->fields = makeList1(makeString($1));
					$$->indirection = $2;
5647
				}
5648
		| relation_name attrs opt_indirection
5649
				{
5650 5651 5652
					$$ = makeNode(ColumnRef);
					$$->fields = lcons(makeString($1), $2);
					$$->indirection = $3;
5653 5654 5655
				}
		;

5656
attrs:	  opt_attrs '.' attr_name
5657
				{ $$ = lappend($1, makeString($3)); }
5658
		| opt_attrs '.' '*'
5659 5660 5661
				{ $$ = lappend($1, makeString("*")); }
		;

5662 5663 5664 5665 5666 5667
opt_attrs: /*EMPTY*/
				{ $$ = NIL; }
		| opt_attrs '.' attr_name
				{ $$ = lappend($1, makeString($3)); }
		;

5668 5669
opt_empty_parentheses: '(' ')' { $$ = TRUE; }
					| /*EMPTY*/ { $$ = TRUE; }
5670
		;
5671 5672 5673

/*****************************************************************************
 *
5674
 *	target lists
5675 5676 5677
 *
 *****************************************************************************/

5678
/* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
5679

5680
target_list:  target_list ',' target_el
5681
				{	$$ = lappend($1, $3);  }
5682
		| target_el
5683
				{	$$ = makeList1($1);  }
5684
		;
5685 5686

/* AS is not optional because shift/red conflict with unary ops */
5687
target_el:  a_expr AS ColLabel
5688 5689 5690
				{
					$$ = makeNode(ResTarget);
					$$->name = $3;
5691
					$$->indirection = NIL;
5692 5693
					$$->val = (Node *)$1;
				}
5694
		| a_expr
5695 5696 5697
				{
					$$ = makeNode(ResTarget);
					$$->name = NULL;
5698
					$$->indirection = NIL;
5699 5700 5701 5702
					$$->val = (Node *)$1;
				}
		| '*'
				{
5703 5704 5705
					ColumnRef *n = makeNode(ColumnRef);
					n->fields = makeList1(makeString("*"));
					n->indirection = NIL;
5706 5707
					$$ = makeNode(ResTarget);
					$$->name = NULL;
5708 5709
					$$->indirection = NIL;
					$$->val = (Node *)n;
5710 5711 5712
				}
		;

5713 5714 5715 5716 5717
/* Target list as found in UPDATE table SET ... */

update_target_list:  update_target_list ',' update_target_el
				{	$$ = lappend($1,$3);  }
		| update_target_el
5718
				{	$$ = makeList1($1);  }
5719 5720
		;

5721
update_target_el:  ColId opt_indirection '=' a_expr
5722 5723 5724 5725 5726 5727
				{
					$$ = makeNode(ResTarget);
					$$->name = $1;
					$$->indirection = $2;
					$$->val = (Node *)$4;
				}
5728 5729
		;

5730 5731 5732 5733 5734 5735
/*****************************************************************************
 *
 *	Names and constants
 *
 *****************************************************************************/

5736 5737 5738 5739 5740 5741
relation_name:	SpecialRuleRelation
				{
					$$ = $1;
				}
		| ColId
				{
5742
					$$ = $1;
5743 5744
				}
		;
5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780
		
qualified_name_list:  qualified_name
				{	$$ = makeList1($1); }
		| qualified_name_list ',' qualified_name
				{	$$ = lappend($1, $3); }
		;

qualified_name: ColId
				{
					$$ = makeNode(RangeVar);
					$$->catalogname = NULL;
					$$->schemaname = NULL;
					$$->relname = $1;
				}
		| ColId '.' ColId
				{
					$$ = makeNode(RangeVar);
					$$->catalogname = NULL;
					$$->schemaname = $1;
					$$->relname = $3;
				}
		| ColId '.' ColId '.' ColId
				{
					$$ = makeNode(RangeVar);
					$$->catalogname = $1;
					$$->schemaname = $3;
					$$->relname = $5;
				}
		;

name_list:  name
				{	$$ = makeList1(makeString($1)); }
		| name_list ',' name
				{	$$ = lappend($1, makeString($3)); }
		;

5781

5782
name:					ColId			{ $$ = $1; };
5783
database_name:			ColId			{ $$ = $1; };
5784
access_method:			ColId			{ $$ = $1; };
5785
attr_name:				ColId			{ $$ = $1; };
5786
class:					ColId			{ $$ = $1; };
5787
index_name:				ColId			{ $$ = $1; };
5788
file_name:				Sconst			{ $$ = $1; };
5789

5790 5791 5792
/* Constants
 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
 */
5793
AexprConst:  Iconst
5794 5795 5796 5797 5798 5799 5800 5801 5802 5803
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_Integer;
					n->val.val.ival = $1;
					$$ = (Node *)n;
				}
		| FCONST
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_Float;
5804
					n->val.val.str = $1;
5805 5806 5807 5808 5809 5810 5811 5812 5813
					$$ = (Node *)n;
				}
		| Sconst
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_String;
					n->val.val.str = $1;
					$$ = (Node *)n;
				}
5814 5815 5816 5817 5818 5819 5820
		| BITCONST
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_BitString;
					n->val.val.str = $1;
					$$ = (Node *)n;
				}
5821
		/* This rule formerly used Typename,
5822 5823 5824 5825
		 * but that causes reduce conflicts with subscripted column names.
		 * Now, separate into ConstTypename and ConstInterval,
		 * to allow implementing the SQL92 syntax for INTERVAL literals.
		 * - thomas 2000-06-24
5826
		 */
5827 5828 5829 5830 5831 5832 5833 5834 5835
		| ConstTypename Sconst
				{
					A_Const *n = makeNode(A_Const);
					n->typename = $1;
					n->val.type = T_String;
					n->val.val.str = $2;
					$$ = (Node *)n;
				}
		| ConstInterval Sconst opt_interval
5836 5837 5838 5839 5840
				{
					A_Const *n = makeNode(A_Const);
					n->typename = $1;
					n->val.type = T_String;
					n->val.val.str = $2;
5841 5842 5843
					/* precision is not specified, but fields may be... */
					if ($3 != -1)
						n->typename->typmod = ((($3 & 0x7FFF) << 16) | 0xFFFF);
5844 5845 5846 5847 5848 5849 5850 5851
					$$ = (Node *)n;
				}
		| ConstInterval '(' Iconst ')' Sconst opt_interval
				{
					A_Const *n = makeNode(A_Const);
					n->typename = $1;
					n->val.type = T_String;
					n->val.val.str = $5;
5852 5853 5854
					/* precision specified, and fields may be... */
					n->typename->typmod = ((($6 & 0x7FFF) << 16) | $3);

5855 5856
					$$ = (Node *)n;
				}
5857 5858 5859 5860 5861 5862 5863 5864
		| PARAM opt_indirection
				{
					ParamRef *n = makeNode(ParamRef);
					n->number = $1;
					n->fields = NIL;
					n->indirection = $2;
					$$ = (Node *)n;
				}
5865 5866 5867 5868 5869
		| TRUE_P
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_String;
					n->val.val.str = "t";
5870 5871
					n->typename = makeNode(TypeName);
					n->typename->name = xlateSqlType("bool");
5872
					n->typename->typmod = -1;
5873 5874 5875 5876 5877 5878 5879
					$$ = (Node *)n;
				}
		| FALSE_P
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_String;
					n->val.val.str = "f";
5880 5881
					n->typename = makeNode(TypeName);
					n->typename->name = xlateSqlType("bool");
5882
					n->typename->typmod = -1;
5883 5884
					$$ = (Node *)n;
				}
5885 5886 5887 5888 5889 5890
		| NULL_P
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_Null;
					$$ = (Node *)n;
				}
5891
		;
5892

5893 5894
Iconst:  ICONST							{ $$ = $1; };
Sconst:  SCONST							{ $$ = $1; };
5895
UserId:  ColId							{ $$ = $1; };
5896

5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938
/*
 * Name classification hierarchy.
 *
 * IDENT is the lexeme returned by the lexer for identifiers that match
 * no known keyword.  In most cases, we can accept certain keywords as
 * names, not only IDENTs.  We prefer to accept as many such keywords
 * as possible to minimize the impact of "reserved words" on programmers.
 * So, we divide names into several possible classes.  The classification
 * is chosen in part to make keywords acceptable as names wherever possible.
 */

/* Column identifier --- names that can be column, table, etc names.
 */
ColId:  IDENT							{ $$ = $1; }
		| unreserved_keyword			{ $$ = $1; }
		| col_name_keyword				{ $$ = $1; }
		;

/* Type identifier --- names that can be type names.
 */
type_name:  IDENT						{ $$ = $1; }
		| unreserved_keyword			{ $$ = $1; }
		;

/* Function identifier --- names that can be function names.
 */
func_name:  IDENT						{ $$ = xlateSqlFunc($1); }
		| unreserved_keyword			{ $$ = xlateSqlFunc($1); }
		| func_name_keyword				{ $$ = xlateSqlFunc($1); }
		;

/* Column label --- allowed labels in "AS" clauses.
 * This presently includes *all* Postgres keywords.
 */
ColLabel:  IDENT						{ $$ = $1; }
		| unreserved_keyword			{ $$ = $1; }
		| col_name_keyword				{ $$ = $1; }
		| func_name_keyword				{ $$ = $1; }
		| reserved_keyword				{ $$ = $1; }
		;


5939 5940
/*
 * Keyword classification lists.  Generally, every keyword present in
5941
 * the Postgres grammar should appear in exactly one of these lists.
5942
 *
5943 5944 5945
 * Put a new keyword into the first list that it can go into without causing
 * shift or reduce conflicts.  The earlier lists define "less reserved"
 * categories of keywords.
5946
 */
5947

5948
/* "Unreserved" keywords --- available for use as any kind of name.
5949
 */
5950 5951
unreserved_keyword:
		  ABORT_TRANS					{ $$ = "abort"; }
5952
		| ABSOLUTE						{ $$ = "absolute"; }
5953
		| ACCESS						{ $$ = "access"; }
5954
		| ACTION						{ $$ = "action"; }
5955
		| ADD							{ $$ = "add"; }
5956 5957
		| AFTER							{ $$ = "after"; }
		| AGGREGATE						{ $$ = "aggregate"; }
5958
		| ALTER							{ $$ = "alter"; }
5959
		| AT							{ $$ = "at"; }
5960 5961
		| BACKWARD						{ $$ = "backward"; }
		| BEFORE						{ $$ = "before"; }
5962 5963
		| BEGIN_TRANS					{ $$ = "begin"; }
		| BY							{ $$ = "by"; }
5964
		| CACHE							{ $$ = "cache"; }
5965
		| CASCADE						{ $$ = "cascade"; }
5966
		| CHAIN							{ $$ = "chain"; }
5967
		| CHARACTERISTICS				{ $$ = "characteristics"; }
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
5968
		| CHECKPOINT					{ $$ = "checkpoint"; }
5969
		| CLOSE							{ $$ = "close"; }
5970
		| CLUSTER						{ $$ = "cluster"; }
5971
		| COMMENT						{ $$ = "comment"; }
5972
		| COMMIT						{ $$ = "commit"; }
5973
		| COMMITTED						{ $$ = "committed"; }
5974
		| CONSTRAINTS					{ $$ = "constraints"; }
5975
		| COPY							{ $$ = "copy"; }
5976 5977
		| CREATEDB						{ $$ = "createdb"; }
		| CREATEUSER					{ $$ = "createuser"; }
5978
		| CURSOR						{ $$ = "cursor"; }
5979
		| CYCLE							{ $$ = "cycle"; }
5980
		| DATABASE						{ $$ = "database"; }
5981
		| DAY_P							{ $$ = "day"; }
5982
		| DECLARE						{ $$ = "declare"; }
5983
		| DEFERRED						{ $$ = "deferred"; }
5984
		| DELETE						{ $$ = "delete"; }
5985
		| DELIMITERS					{ $$ = "delimiters"; }
5986
		| DOMAIN_P						{ $$ = "domain"; }
5987
		| DOUBLE						{ $$ = "double"; }
5988
		| DROP							{ $$ = "drop"; }
5989
		| EACH							{ $$ = "each"; }
5990
		| ENCODING						{ $$ = "encoding"; }
5991
		| ENCRYPTED						{ $$ = "encrypted"; }
5992
		| ESCAPE						{ $$ = "escape"; }
5993
		| EXCLUSIVE						{ $$ = "exclusive"; }
5994
		| EXECUTE						{ $$ = "execute"; }
5995
		| EXPLAIN						{ $$ = "explain"; }
5996
		| FETCH							{ $$ = "fetch"; }
Hiroshi Inoue's avatar
Hiroshi Inoue committed
5997
		| FORCE							{ $$ = "force"; }
5998
		| FORWARD						{ $$ = "forward"; }
5999
		| FUNCTION						{ $$ = "function"; }
6000
		| GLOBAL						{ $$ = "global"; }
6001
		| HANDLER						{ $$ = "handler"; }
6002
		| HOUR_P						{ $$ = "hour"; }
6003
		| IMMEDIATE						{ $$ = "immediate"; }
6004
		| INCREMENT						{ $$ = "increment"; }
6005
		| INDEX							{ $$ = "index"; }
6006
		| INHERITS						{ $$ = "inherits"; }
6007
		| INOUT							{ $$ = "inout"; }
6008
		| INSENSITIVE					{ $$ = "insensitive"; }
6009
		| INSERT						{ $$ = "insert"; }
6010
		| INSTEAD						{ $$ = "instead"; }
6011
		| ISOLATION						{ $$ = "isolation"; }
6012 6013
		| KEY							{ $$ = "key"; }
		| LANGUAGE						{ $$ = "language"; }
6014
		| LANCOMPILER					{ $$ = "lancompiler"; }
6015
		| LEVEL							{ $$ = "level"; }
6016 6017 6018
		| LISTEN						{ $$ = "listen"; }
		| LOAD							{ $$ = "load"; }
		| LOCAL							{ $$ = "local"; }
6019
		| LOCATION						{ $$ = "location"; }
6020
		| LOCK_P						{ $$ = "lock"; }
6021
		| MATCH							{ $$ = "match"; }
6022
		| MAXVALUE						{ $$ = "maxvalue"; }
6023
		| MINUTE_P						{ $$ = "minute"; }
6024
		| MINVALUE						{ $$ = "minvalue"; }
6025
		| MODE							{ $$ = "mode"; }
6026 6027
		| MONTH_P						{ $$ = "month"; }
		| MOVE							{ $$ = "move"; }
6028
		| NAMES							{ $$ = "names"; }
6029
		| NATIONAL						{ $$ = "national"; }
6030
		| NEXT							{ $$ = "next"; }
6031
		| NO							{ $$ = "no"; }
6032 6033 6034
		| NOCREATEDB					{ $$ = "nocreatedb"; }
		| NOCREATEUSER					{ $$ = "nocreateuser"; }
		| NOTHING						{ $$ = "nothing"; }
6035
		| NOTIFY						{ $$ = "notify"; }
6036
		| OF							{ $$ = "of"; }
6037
		| OIDS							{ $$ = "oids"; }
6038 6039
		| OPERATOR						{ $$ = "operator"; }
		| OPTION						{ $$ = "option"; }
6040
		| OUT							{ $$ = "out"; }
6041
		| OWNER							{ $$ = "owner"; }
6042
		| PARTIAL						{ $$ = "partial"; }
6043
		| PASSWORD						{ $$ = "password"; }
6044
		| PATH_P						{ $$ = "path"; }
6045
		| PENDANT						{ $$ = "pendant"; }
6046
		| PRECISION						{ $$ = "precision"; }
6047
		| PRIOR							{ $$ = "prior"; }
6048
		| PRIVILEGES					{ $$ = "privileges"; }
6049
		| PROCEDURAL					{ $$ = "procedural"; }
6050
		| PROCEDURE						{ $$ = "procedure"; }
6051
		| READ							{ $$ = "read"; }
6052
		| REINDEX						{ $$ = "reindex"; }
6053
		| RELATIVE						{ $$ = "relative"; }
6054
		| RENAME						{ $$ = "rename"; }
6055
		| REPLACE						{ $$ = "replace"; }
6056
		| RESET							{ $$ = "reset"; }
6057
		| RESTRICT						{ $$ = "restrict"; }
6058
		| RETURNS						{ $$ = "returns"; }
6059 6060
		| REVOKE						{ $$ = "revoke"; }
		| ROLLBACK						{ $$ = "rollback"; }
6061
		| ROW							{ $$ = "row"; }
6062
		| RULE							{ $$ = "rule"; }
6063
		| SCHEMA						{ $$ = "schema"; }
6064
		| SCROLL						{ $$ = "scroll"; }
6065
		| SECOND_P						{ $$ = "second"; }
6066
		| SESSION						{ $$ = "session"; }
6067
		| SEQUENCE						{ $$ = "sequence"; }
6068
		| SERIALIZABLE					{ $$ = "serializable"; }
6069
		| SET							{ $$ = "set"; }
6070
		| SHARE							{ $$ = "share"; }
6071
		| SHOW							{ $$ = "show"; }
6072
		| START							{ $$ = "start"; }
6073
		| STATEMENT						{ $$ = "statement"; }
6074
		| STATISTICS					{ $$ = "statistics"; }
6075 6076
		| STDIN							{ $$ = "stdin"; }
		| STDOUT						{ $$ = "stdout"; }
6077
        | STORAGE                       { $$ = "storage"; }
6078
		| SYSID							{ $$ = "sysid"; }
6079
		| TEMP							{ $$ = "temp"; }
6080
		| TEMPLATE						{ $$ = "template"; }
6081
		| TEMPORARY						{ $$ = "temporary"; }
Jan Wieck's avatar
TOAST  
Jan Wieck committed
6082
		| TOAST							{ $$ = "toast"; }
6083
		| TRANSACTION					{ $$ = "transaction"; }
6084
		| TRIGGER						{ $$ = "trigger"; }
6085
		| TRUNCATE						{ $$ = "truncate"; }
6086
		| TRUSTED						{ $$ = "trusted"; }
6087
		| TYPE_P						{ $$ = "type"; }
6088
		| UNENCRYPTED					{ $$ = "unencrypted"; }
6089
		| UNKNOWN						{ $$ = "unknown"; }
6090 6091 6092
		| UNLISTEN						{ $$ = "unlisten"; }
		| UNTIL							{ $$ = "until"; }
		| UPDATE						{ $$ = "update"; }
6093
		| USAGE							{ $$ = "usage"; }
6094
		| VACUUM						{ $$ = "vacuum"; }
6095
		| VALID							{ $$ = "valid"; }
6096 6097
		| VALUES						{ $$ = "values"; }
		| VARYING						{ $$ = "varying"; }
6098
		| VERSION						{ $$ = "version"; }
6099 6100
		| VIEW							{ $$ = "view"; }
		| WITH							{ $$ = "with"; }
6101
		| WITHOUT						{ $$ = "without"; }
6102
		| WORK							{ $$ = "work"; }
6103
		| YEAR_P						{ $$ = "year"; }
6104
		| ZONE							{ $$ = "zone"; }
6105 6106
		;

6107
/* Column identifier --- keywords that can be column, table, etc names.
6108
 *
6109 6110 6111
 * Many of these keywords will in fact be recognized as type or function
 * names too; but they have special productions for the purpose, and so
 * can't be treated as "generic" type or function names.
6112
 *
6113 6114 6115
 * The type names appearing here are not usable as function names
 * because they can be followed by '(' in typename productions, which
 * looks too much like a function call for an LR(1) parser.
6116
 */
6117 6118
col_name_keyword:
		  BIT							{ $$ = "bit"; }
6119 6120
		| CHAR							{ $$ = "char"; }
		| CHARACTER						{ $$ = "character"; }
6121
		| COALESCE						{ $$ = "coalesce"; }
6122 6123
		| DEC							{ $$ = "dec"; }
		| DECIMAL						{ $$ = "decimal"; }
6124 6125
		| EXISTS						{ $$ = "exists"; }
		| EXTRACT						{ $$ = "extract"; }
6126 6127 6128 6129
		| FLOAT							{ $$ = "float"; }
		| INTERVAL						{ $$ = "interval"; }
		| NCHAR							{ $$ = "nchar"; }
		| NONE							{ $$ = "none"; }
6130
		| NULLIF						{ $$ = "nullif"; }
6131
		| NUMERIC						{ $$ = "numeric"; }
6132
		| POSITION						{ $$ = "position"; }
6133
		| SETOF							{ $$ = "setof"; }
6134
		| SUBSTRING						{ $$ = "substring"; }
6135 6136
		| TIME							{ $$ = "time"; }
		| TIMESTAMP						{ $$ = "timestamp"; }
6137
		| TRIM							{ $$ = "trim"; }
6138 6139 6140
		| VARCHAR						{ $$ = "varchar"; }
		;

6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151
/* Function identifier --- keywords that can be function names.
 *
 * Most of these are keywords that are used as operators in expressions;
 * in general such keywords can't be column names because they would be
 * ambiguous with variables, but they are unambiguous as function identifiers.
 *
 * Do not include POSITION, SUBSTRING, etc here since they have explicit
 * productions in a_expr to support the goofy SQL9x argument syntax.
 *  - thomas 2000-11-28
 */
func_name_keyword:
6152 6153
		  AUTHORIZATION					{ $$ = "authorization"; }
		| BETWEEN						{ $$ = "between"; }
6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175
		| BINARY						{ $$ = "binary"; }
		| CROSS							{ $$ = "cross"; }
		| FREEZE						{ $$ = "freeze"; }
		| FULL							{ $$ = "full"; }
		| ILIKE							{ $$ = "ilike"; }
		| IN							{ $$ = "in"; }
		| INNER_P						{ $$ = "inner"; }
		| IS							{ $$ = "is"; }
		| ISNULL						{ $$ = "isnull"; }
		| JOIN							{ $$ = "join"; }
		| LEFT							{ $$ = "left"; }
		| LIKE							{ $$ = "like"; }
		| NATURAL						{ $$ = "natural"; }
		| NOTNULL						{ $$ = "notnull"; }
		| OUTER_P						{ $$ = "outer"; }
		| OVERLAPS						{ $$ = "overlaps"; }
		| PUBLIC						{ $$ = "public"; }
		| RIGHT							{ $$ = "right"; }
		| VERBOSE						{ $$ = "verbose"; }
		;

/* Reserved keyword --- these keywords are usable only as a ColLabel.
6176 6177
 *
 * Keywords appear here if they could not be distinguished from variable,
6178 6179
 * type, or function names in some contexts.  Don't put things here unless
 * forced to.
6180
 */
6181 6182
reserved_keyword:
		  ALL							{ $$ = "all"; }
6183
		| ANALYSE						{ $$ = "analyse"; } /* British */
6184
		| ANALYZE						{ $$ = "analyze"; }
6185
		| AND							{ $$ = "and"; }
6186
		| ANY							{ $$ = "any"; }
6187
		| AS							{ $$ = "as"; }
6188 6189
		| ASC							{ $$ = "asc"; }
		| BOTH							{ $$ = "both"; }
6190
		| CASE							{ $$ = "case"; }
6191 6192 6193 6194
		| CAST							{ $$ = "cast"; }
		| CHECK							{ $$ = "check"; }
		| COLLATE						{ $$ = "collate"; }
		| COLUMN						{ $$ = "column"; }
6195
		| CONSTRAINT					{ $$ = "constraint"; }
6196
		| CREATE						{ $$ = "create"; }
6197 6198 6199
		| CURRENT_DATE					{ $$ = "current_date"; }
		| CURRENT_TIME					{ $$ = "current_time"; }
		| CURRENT_TIMESTAMP				{ $$ = "current_timestamp"; }
6200
		| CURRENT_USER					{ $$ = "current_user"; }
6201
		| DEFAULT						{ $$ = "default"; }
6202
		| DEFERRABLE					{ $$ = "deferrable"; }
6203 6204
		| DESC							{ $$ = "desc"; }
		| DISTINCT						{ $$ = "distinct"; }
6205
		| DO							{ $$ = "do"; }
6206 6207
		| ELSE							{ $$ = "else"; }
		| END_TRANS						{ $$ = "end"; }
6208
		| EXCEPT						{ $$ = "except"; }
6209
		| FALSE_P						{ $$ = "false"; }
6210
		| FOR							{ $$ = "for"; }
6211
		| FOREIGN						{ $$ = "foreign"; }
6212
		| FROM							{ $$ = "from"; }
6213
		| GRANT							{ $$ = "grant"; }
6214
		| GROUP							{ $$ = "group"; }
6215
		| HAVING						{ $$ = "having"; }
6216
		| INITIALLY						{ $$ = "initially"; }
6217
		| INTERSECT						{ $$ = "intersect"; }
6218 6219
		| INTO							{ $$ = "into"; }
		| LEADING						{ $$ = "leading"; }
6220
		| LIMIT							{ $$ = "limit"; }
6221
		| NEW							{ $$ = "new"; }
6222 6223
		| NOT							{ $$ = "not"; }
		| NULL_P						{ $$ = "null"; }
6224
		| OFF							{ $$ = "off"; }
6225
		| OFFSET						{ $$ = "offset"; }
6226
		| OLD							{ $$ = "old"; }
6227
		| ON							{ $$ = "on"; }
6228
		| ONLY							{ $$ = "only"; }
6229
		| OR							{ $$ = "or"; }
6230
		| ORDER							{ $$ = "order"; }
6231 6232 6233
		| PRIMARY						{ $$ = "primary"; }
		| REFERENCES					{ $$ = "references"; }
		| SELECT						{ $$ = "select"; }
6234
		| SESSION_USER					{ $$ = "session_user"; }
6235
		| SOME							{ $$ = "some"; }
6236
		| TABLE							{ $$ = "table"; }
6237
		| THEN							{ $$ = "then"; }
6238
		| TO							{ $$ = "to"; }
6239
		| TRAILING						{ $$ = "trailing"; }
6240
		| TRUE_P						{ $$ = "true"; }
6241
		| UNION							{ $$ = "union"; }
6242
		| UNIQUE						{ $$ = "unique"; }
6243
		| USER							{ $$ = "user"; }
6244
		| USING							{ $$ = "using"; }
6245
		| WHEN							{ $$ = "when"; }
6246
		| WHERE							{ $$ = "where"; }
6247
		;
6248

6249

6250
SpecialRuleRelation:  OLD
6251 6252
				{
					if (QueryIsRule)
6253
						$$ = "*OLD*";
6254
					else
6255
						elog(ERROR,"OLD used in non-rule query");
6256 6257 6258 6259 6260 6261
				}
		| NEW
				{
					if (QueryIsRule)
						$$ = "*NEW*";
					else
Bruce Momjian's avatar
Bruce Momjian committed
6262
						elog(ERROR,"NEW used in non-rule query");
6263 6264
				}
		;
6265 6266 6267

%%

6268 6269
static Node *
makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
6270
{
6271 6272 6273 6274 6275 6276
	A_Expr *a = makeNode(A_Expr);
	a->oper = oper;
	a->opname = opname;
	a->lexpr = lexpr;
	a->rexpr = rexpr;
	return (Node *)a;
6277 6278
}

6279 6280 6281 6282
static Node *
makeTypeCast(Node *arg, TypeName *typename)
{
	/*
6283
	 * If arg is an A_Const, just stick the typename into the
6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302
	 * field reserved for it --- unless there's something there already!
	 * (We don't want to collapse x::type1::type2 into just x::type2.)
	 * Otherwise, generate a TypeCast node.
	 */
	if (IsA(arg, A_Const) &&
		((A_Const *) arg)->typename == NULL)
	{
		((A_Const *) arg)->typename = typename;
		return arg;
	}
	else
	{
		TypeCast *n = makeNode(TypeCast);
		n->arg = arg;
		n->typename = typename;
		return (Node *) n;
	}
}

6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327
static Node *
makeStringConst(char *str, TypeName *typename)
{
	A_Const *n = makeNode(A_Const);
	n->val.type = T_String;
	n->val.val.str = str;
	n->typename = typename;

	return (Node *)n;
}

static Node *
makeFloatConst(char *str)
{
	A_Const *n = makeNode(A_Const);
	TypeName *t = makeNode(TypeName);
	n->val.type = T_Float;
	n->val.val.str = str;
	t->name = xlateSqlType("float");
	t->typmod = -1;
	n->typename = t;

	return (Node *)n;
}

Bruce Momjian's avatar
Bruce Momjian committed
6328 6329
/* makeRowExpr()
 * Generate separate operator nodes for a single row descriptor expression.
6330 6331
 * Perhaps this should go deeper in the parser someday...
 * - thomas 1997-12-22
Bruce Momjian's avatar
Bruce Momjian committed
6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373
 */
static Node *
makeRowExpr(char *opr, List *largs, List *rargs)
{
	Node *expr = NULL;
	Node *larg, *rarg;

	if (length(largs) != length(rargs))
		elog(ERROR,"Unequal number of entries in row expression");

	if (lnext(largs) != NIL)
		expr = makeRowExpr(opr,lnext(largs),lnext(rargs));

	larg = lfirst(largs);
	rarg = lfirst(rargs);

	if ((strcmp(opr, "=") == 0)
	 || (strcmp(opr, "<") == 0)
	 || (strcmp(opr, "<=") == 0)
	 || (strcmp(opr, ">") == 0)
	 || (strcmp(opr, ">=") == 0))
	{
		if (expr == NULL)
			expr = makeA_Expr(OP, opr, larg, rarg);
		else
			expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
	}
	else if (strcmp(opr, "<>") == 0)
	{
		if (expr == NULL)
			expr = makeA_Expr(OP, opr, larg, rarg);
		else
			expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
	}
	else
	{
		elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
	}

	return expr;
}

6374
/* findLeftmostSelect()
6375
 *		Find the leftmost component SelectStmt in a set-operation parsetree.
6376 6377
 */
static SelectStmt *
6378
findLeftmostSelect(SelectStmt *node)
6379
{
6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435
	while (node && node->op != SETOP_NONE)
		node = node->larg;
	Assert(node && IsA(node, SelectStmt) && node->larg == NULL);
	return node;
}

/* insertSelectOptions()
 *		Insert ORDER BY, etc into an already-constructed SelectStmt.
 *
 * This routine is just to avoid duplicating code in SelectStmt productions.
 */
static void
insertSelectOptions(SelectStmt *stmt,
					List *sortClause, List *forUpdate,
					Node *limitOffset, Node *limitCount)
{
	/*
	 * Tests here are to reject constructs like
	 *	(SELECT foo ORDER BY bar) ORDER BY baz
	 */
	if (sortClause)
	{
		if (stmt->sortClause)
			elog(ERROR, "Multiple ORDER BY clauses not allowed");
		stmt->sortClause = sortClause;
	}
	if (forUpdate)
	{
		if (stmt->forUpdate)
			elog(ERROR, "Multiple FOR UPDATE clauses not allowed");
		stmt->forUpdate = forUpdate;
	}
	if (limitOffset)
	{
		if (stmt->limitOffset)
			elog(ERROR, "Multiple OFFSET clauses not allowed");
		stmt->limitOffset = limitOffset;
	}
	if (limitCount)
	{
		if (stmt->limitCount)
			elog(ERROR, "Multiple LIMIT clauses not allowed");
		stmt->limitCount = limitCount;
	}
}

static Node *
makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg)
{
	SelectStmt *n = makeNode(SelectStmt);

	n->op = op;
	n->all = all;
	n->larg = (SelectStmt *) larg;
	n->rarg = (SelectStmt *) rarg;
	return (Node *) n;
6436 6437 6438
}


6439
/* xlateSqlFunc()
6440 6441
 * Convert alternate function names to internal Postgres functions.
 *
6442 6443
 * Do not convert "float", since that is handled elsewhere
 *  for FLOAT(p) syntax.
6444
 *
6445 6446
 * Converting "datetime" to "timestamp" and "timespan" to "interval"
 * is a temporary expedient for pre-7.0 to 7.0 compatibility;
6447
 * these should go away for v7.1.
6448
 */
6449
char *
6450 6451
xlateSqlFunc(char *name)
{
6452
	if (strcmp(name,"character_length") == 0)
6453
		return "char_length";
6454
	else if (strcmp(name,"datetime") == 0)
6455
		return "timestamp";
6456
	else if (strcmp(name,"timespan") == 0)
6457
		return "interval";
6458 6459 6460 6461 6462 6463
	else
		return name;
} /* xlateSqlFunc() */

/* xlateSqlType()
 * Convert alternate type names to internal Postgres types.
6464 6465 6466 6467
 *
 * NB: do NOT put "char" -> "bpchar" here, because that renders it impossible
 * to refer to our single-byte char type, even with quotes.  (Without quotes,
 * CHAR is a keyword, and the code above produces "bpchar" for it.)
6468 6469 6470
 *
 * Convert "datetime" and "timespan" to allow a transition to SQL92 type names.
 * Remove this translation for v7.1 - thomas 2000-03-25
Tom Lane's avatar
Tom Lane committed
6471 6472 6473 6474
 *
 * Convert "lztext" to "text" to allow forward compatibility for anyone using
 * the undocumented "lztext" type in 7.0.  This can go away in 7.2 or later
 * - tgl 2000-07-30
6475
 */
6476
char *
6477 6478
xlateSqlType(char *name)
{
6479 6480
	if ((strcmp(name,"int") == 0)
		|| (strcmp(name,"integer") == 0))
6481
		return "int4";
6482
	else if (strcmp(name, "smallint") == 0)
6483
		return "int2";
6484 6485
	else if (strcmp(name, "bigint") == 0)
		return "int8";
6486 6487 6488
	else if (strcmp(name, "real") == 0)
		return "float4";
	else if (strcmp(name, "float") == 0)
6489
		return "float8";
6490
	else if (strcmp(name, "decimal") == 0)
6491
		return "numeric";
6492
	else if (strcmp(name, "datetime") == 0)
6493
		return "timestamp";
6494
	else if (strcmp(name, "timespan") == 0)
6495
		return "interval";
Tom Lane's avatar
Tom Lane committed
6496 6497
	else if (strcmp(name, "lztext") == 0)
		return "text";
6498
	else if (strcmp(name, "boolean") == 0)
6499
		return "bool";
6500 6501
	else
		return name;
6502
} /* xlateSqlType() */
6503

6504

6505 6506
void parser_init(Oid *typev, int nargs)
{
6507
	QueryIsRule = FALSE;
6508 6509 6510 6511
	/*
	 * Keep enough information around to fill out the type of param nodes
	 * used in postquel functions
	 */
6512
	param_type_info = typev;
6513
	pfunc_num_args = nargs;
6514 6515 6516 6517
}

Oid param_type(int t)
{
6518
	if ((t > pfunc_num_args) || (t <= 0))
6519 6520 6521
		return InvalidOid;
	return param_type_info[t - 1];
}
6522

6523 6524 6525
/*
 * Test whether an a_expr is a plain NULL constant or not.
 */
6526
bool
6527 6528 6529 6530 6531 6532 6533 6534
exprIsNullConstant(Node *arg)
{
	if (arg && IsA(arg, A_Const))
	{
		A_Const *con = (A_Const *) arg;

		if (con->val.type == T_Null &&
			con->typename == NULL)
6535
			return TRUE;
6536
	}
6537
	return FALSE;
6538 6539
}

6540
/*
6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551
 * doNegate --- handle negation of a numeric constant.
 *
 * Formerly, we did this here because the optimizer couldn't cope with
 * indexquals that looked like "var = -4" --- it wants "var = const"
 * and a unary minus operator applied to a constant didn't qualify.
 * As of Postgres 7.0, that problem doesn't exist anymore because there
 * is a constant-subexpression simplifier in the optimizer.  However,
 * there's still a good reason for doing this here, which is that we can
 * postpone committing to a particular internal representation for simple
 * negative constants.  It's better to leave "-123.456" in string form
 * until we know what the desired type is.
6552
 */
6553 6554
static Node *
doNegate(Node *n)
6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566
{
	if (IsA(n, A_Const))
	{
		A_Const *con = (A_Const *)n;

		if (con->val.type == T_Integer)
		{
			con->val.val.ival = -con->val.val.ival;
			return n;
		}
		if (con->val.type == T_Float)
		{
6567
			doNegateFloat(&con->val);
6568 6569 6570 6571 6572 6573
			return n;
		}
	}

	return makeA_Expr(OP, "-", NULL, n);
}
6574 6575 6576 6577 6578 6579 6580 6581 6582 6583

static void
doNegateFloat(Value *v)
{
	char   *oldval = v->val.str;

	Assert(IsA(v, Float));
	if (*oldval == '+')
		oldval++;
	if (*oldval == '-')
6584
		v->val.str = oldval+1;	/* just strip the '-' */
6585 6586 6587 6588 6589 6590 6591 6592 6593
	else
	{
		char   *newval = (char *) palloc(strlen(oldval) + 2);

		*newval = '-';
		strcpy(newval+1, oldval);
		v->val.str = newval;
	}
}