gram.y 168 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.303 2002/04/17 20:57:56 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/makefuncs.h"
57
#include "nodes/params.h"
58
#include "nodes/parsenodes.h"
Bruce Momjian's avatar
Bruce Momjian committed
59
#include "parser/gramparse.h"
60
#include "storage/lmgr.h"
61
#include "utils/numeric.h"
62
#include "utils/datetime.h"
63

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

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

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

77

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

85
static Node *makeTypeCast(Node *arg, TypeName *typename);
86 87
static Node *makeStringConst(char *str, TypeName *typename);
static Node *makeFloatConst(char *str);
88
static Node *makeRowExpr(List *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
static bool set_name_needs_quotes(const char *name);
97

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

100 101
%}

102

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

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

126
	InsertStmt			*istmt;
127 128
}

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

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

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

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

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

158 159 160 161
%type <list>	user_list

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

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

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

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

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

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

179 180
%type <list>	func_name, handler_name, qual_Op, qual_all_Op, OptUseOp,
		opt_class
181

182 183
%type <range>	qualified_name, OptConstrFromTable

184
%type <str>		opt_id,
185
		all_Op, MathOp, opt_name, SpecialRuleRelation
186

187
%type <str>		opt_level, opt_encoding
188 189
%type <node>	grantee
%type <list>	grantee_list
190 191 192 193 194 195
%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
196

197
%type <list>	stmtblock, stmtmulti,
198
		OptTableElementList, OptInherit, definition, opt_distinct,
199
		opt_with, func_args, func_args_list, func_as,
200
		oper_argtypes, RuleActionList, RuleActionMulti,
201
		opt_column_list, columnList, opt_name_list,
202
		sort_clause, sortby_list, index_params, index_list, name_list,
203
		from_clause, from_list, opt_array_bounds, qualified_name_list,
204
		any_name, any_name_list, any_operator, expr_list, dotted_name, attrs,
205
		target_list, update_target_list, insert_column_list,
Bruce Momjian's avatar
Bruce Momjian committed
206
		insert_target_list,
207
		def_list, opt_indirection, group_clause, TriggerFuncArgs,
208
		select_limit, opt_select_limit
209

210 211
%type <range>	into_clause, OptTempTableName

212
%type <typnam>	func_arg, func_return, func_type, aggr_argtype
213

214
%type <boolean>	opt_arg, TriggerForOpt, TriggerForType, OptTemp, OptWithOids
215

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

221
%type <node>	join_outer, join_qual
222
%type <jtype>	join_type
223

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

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

233
%type <ival>	copy_dirn, direction, reindex_type, drop_type,
234
		opt_column, event, comment_type
235

Bruce Momjian's avatar
Bruce Momjian committed
236
%type <ival>	fetch_how_many
237

238 239
%type <node>	select_limit_value, select_offset_value

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

243
%type <istmt>	insert_rest
244

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

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

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

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

293 294 295
%type <list>	constraints_set_list
%type <boolean>	constraints_set_mode

296 297
%type <boolean> opt_as

298

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

305 306 307 308 309 310 311
/* 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
312 313
 * NOTE: don't forget to add new keywords to the appropriate one of
 * the reserved-or-not-so-reserved keyword lists, below.
314 315 316
 */

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

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

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

355 356 357 358 359 360
/* 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?
 */
361
%token	ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYSE, ANALYZE,
362
		BACKWARD, BEFORE, BINARY, BIT,
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
363
		CACHE, CHECKPOINT, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE,
364
		DATABASE, DELIMITERS, DO,
365
		EACH, ENCODING, EXCLUSIVE, EXPLAIN,
366
		FORCE, FORWARD, FREEZE, FUNCTION, HANDLER,
367
		ILIKE, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
368
		LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
369
		MAXVALUE, MINVALUE, MODE, MOVE,
370
		NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
371
		OFFSET, OIDS, OPERATOR, OWNER, PASSWORD, PROCEDURAL,
Hiroshi Inoue's avatar
Hiroshi Inoue committed
372
		REINDEX, RENAME, RESET, RETURNS, ROW, RULE,
373
		SEQUENCE, SETOF, SHARE, SHOW, START, STATEMENT,
374
		STATISTICS, STDIN, STDOUT, STORAGE, SYSID,
375
		TEMP, TEMPLATE, TOAST, TRUNCATE, TRUSTED, 
376
		UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
377

378 379 380 381 382 383
/* 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

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

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

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

422 423 424 425 426 427
/*
 *	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
428 429
				{ parsetree = $1; }
		;
430

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

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

506 507
/*****************************************************************************
 *
508
 * Create a new Postgres DBMS user
509 510 511 512
 *
 *
 *****************************************************************************/

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

/*****************************************************************************
 *
531
 * Alter a postgresql DBMS user
532 533 534 535
 *
 *
 *****************************************************************************/

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

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

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;
				}
		;


572 573
/*****************************************************************************
 *
574
 * Drop a postgresql DBMS user
575 576 577 578
 *
 *
 *****************************************************************************/

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

587 588 589 590 591 592 593 594 595 596 597 598 599
/*
 * 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);
				}
600 601 602 603 604 605 606 607 608 609 610 611
			  | ENCRYPTED PASSWORD Sconst
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "encryptedPassword";
				  $$->arg = (Node *)makeString($3);
				}
			  | UNENCRYPTED PASSWORD Sconst
                { 
				  $$ = makeNode(DefElem);
				  $$->defname = "unencryptedPassword";
				  $$->arg = (Node *)makeString($3);
				}
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 651 652
              | 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);
653
				}
654
        ;
655

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

666

667 668 669

/*****************************************************************************
 *
670
 * Create a postgresql group
671 672 673 674
 *
 *
 *****************************************************************************/

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

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

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

712 713 714

/*****************************************************************************
 *
715
 * Alter a postgresql group
716 717 718 719
 *
 *
 *****************************************************************************/

720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736
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;
				}
			;
737

738

739 740
/*****************************************************************************
 *
741
 * Drop a postgresql group
742 743 744 745 746
 *
 *
 *****************************************************************************/

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


755 756 757 758 759 760 761
/*****************************************************************************
 *
 * Manipulate a schema
 *
 *
 *****************************************************************************/

762
CreateSchemaStmt:  CREATE SCHEMA OptSchemaName AUTHORIZATION UserId OptSchemaEltList
763
				{
764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780
					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;
781
					$$ = (Node *)n;
782 783 784
				}
		;

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

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

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

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

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

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

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

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

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

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

914
				/* compute space needed; allow for quotes and comma */
915 916 917 918
				foreach (n, $1)
				{
					Value *p = (Value *) lfirst(n);
					Assert(IsA(p, String));
919
					slen += (strlen(p->val.str) + 3);
920 921 922 923 924 925
				}
				result = palloc(slen + 1);
				*result = '\0';
				foreach (n, $1)
				{
					Value *p = (Value *) lfirst(n);
926 927 928 929 930 931 932 933
					if (set_name_needs_quotes(p->val.str))
					{
						strcat(result, "\"");
						strcat(result, p->val.str);
						strcat(result, "\"");
					}
					else
						strcat(result, p->val.str);
934 935 936 937 938
					strcat(result, ",");
				}
				/* remove the trailing comma from the last element */
				*(result+strlen(result)-1) = '\0';
				$$ = result;
939
			}
940 941
		| DEFAULT							{ $$ = NULL; }
		;
942

943 944 945 946
opt_boolean:  TRUE_P						{ $$ = "true"; }
		| FALSE_P							{ $$ = "false"; }
		| ON								{ $$ = "on"; }
		| OFF								{ $$ = "off"; }
947 948
		;

949 950 951 952 953 954 955 956 957 958 959 960
/* 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);
961
				if ($3 != -1)
962 963 964 965 966
				{
					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);
				}
967 968 969 970 971
				$$ = (Node *)n;
			}
		| ConstInterval '(' Iconst ')' Sconst opt_interval
			{
				A_Const *n = (A_Const *) makeStringConst($5, $1);
972
				if ($6 != -1)
973 974 975 976 977
				{
					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);
				}
978
				else
979
				{
980
					n->typename->typmod = ((0x7FFF << 16) | $3);
981
				}
982

983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004
				$$ = (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)));
			}
1005 1006
		| DEFAULT							{ $$ = NULL; }
		| LOCAL								{ $$ = NULL; }
1007
		;
1008

1009 1010 1011
opt_encoding:  Sconst						{ $$ = $1; }
        | DEFAULT							{ $$ = NULL; }
        | /*EMPTY*/							{ $$ = NULL; }
1012 1013
        ;

1014
ColId_or_Sconst: ColId						{ $$ = $1; }
1015
		| SCONST							{ $$ = $1; }
1016
		;
1017 1018


1019
VariableShowStmt:  SHOW ColId
1020 1021 1022 1023 1024
				{
					VariableShowStmt *n = makeNode(VariableShowStmt);
					n->name  = $2;
					$$ = (Node *) n;
				}
1025 1026 1027 1028 1029 1030
		| SHOW TIME ZONE
				{
					VariableShowStmt *n = makeNode(VariableShowStmt);
					n->name  = "timezone";
					$$ = (Node *) n;
				}
1031 1032 1033 1034 1035 1036
		| SHOW ALL
				{
					VariableShowStmt *n = makeNode(VariableShowStmt);
					n->name  = "all";
					$$ = (Node *) n;
				}
1037 1038 1039 1040 1041 1042
		| SHOW TRANSACTION ISOLATION LEVEL
				{
					VariableShowStmt *n = makeNode(VariableShowStmt);
					n->name  = "XactIsoLevel";
					$$ = (Node *) n;
				}
1043 1044
		;

1045
VariableResetStmt:	RESET ColId
1046 1047 1048 1049 1050
				{
					VariableResetStmt *n = makeNode(VariableResetStmt);
					n->name  = $2;
					$$ = (Node *) n;
				}
1051 1052 1053 1054 1055 1056
		| RESET TIME ZONE
				{
					VariableResetStmt *n = makeNode(VariableResetStmt);
					n->name  = "timezone";
					$$ = (Node *) n;
				}
1057 1058 1059 1060 1061 1062
		| RESET TRANSACTION ISOLATION LEVEL
				{
					VariableResetStmt *n = makeNode(VariableResetStmt);
					n->name  = "XactIsoLevel";
					$$ = (Node *) n;
				}
1063 1064 1065 1066 1067 1068
		| RESET ALL
				{
					VariableResetStmt *n = makeNode(VariableResetStmt);
					n->name  = "all";
					$$ = (Node *) n;
				}
1069
		;
1070

1071

1072 1073 1074 1075 1076 1077 1078 1079 1080
ConstraintsSetStmt:	SET CONSTRAINTS constraints_set_list constraints_set_mode
				{
					ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt);
					n->constraints = $3;
					n->deferred    = $4;
					$$ = (Node *) n;
				}
		;

1081 1082
constraints_set_list:	ALL					{ $$ = NIL; }
		| name_list							{ $$ = $1; }
1083 1084
		;

1085 1086
constraints_set_mode:	DEFERRED			{ $$ = TRUE; }
		| IMMEDIATE							{ $$ = FALSE; }
1087 1088 1089
		;


Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
/*
 * Checkpoint statement
 */
CheckPointStmt: CHECKPOINT
				{
					CheckPointStmt *n = makeNode(CheckPointStmt);
					$$ = (Node *)n;
				}
			;

1100 1101
/*****************************************************************************
 *
1102
 *	ALTER TABLE variations
1103 1104 1105
 *
 *****************************************************************************/

1106
AlterTableStmt:
1107 1108
/* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
		ALTER TABLE relation_expr ADD opt_column columnDef
1109 1110 1111
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'A';
1112
					n->relation = $3;
1113
					n->def = $6;
1114 1115
					$$ = (Node *)n;
				}
1116 1117
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
		| ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default
1118 1119 1120
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'T';
1121
					n->relation = $3;
1122 1123
					n->name = $6;
					n->def = $7;
1124 1125
					$$ = (Node *)n;
				}
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> DROP NOT NULL */
                | ALTER TABLE relation_expr ALTER opt_column ColId DROP NOT NULL_P
                                {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'N';
                                        n->relation = $3;
                                        n->name = $6;
                                        $$ = (Node *)n;
                                }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET NOT NULL */
                | ALTER TABLE relation_expr ALTER opt_column ColId SET NOT NULL_P
                                {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'O';
                                        n->relation = $3;
                                        n->name = $6;
                                        $$ = (Node *)n;
                                }
1144 1145 1146 1147 1148
/* 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';
1149
					n->relation = $3;
1150 1151 1152 1153
					n->name = $6;
					n->def = (Node *) makeInteger($9);
					$$ = (Node *)n;
				}
1154 1155 1156 1157 1158
/* 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';
1159
					n->relation = $3;
1160 1161 1162 1163
					n->name = $6;
					n->def = (Node *) makeString($9);
					$$ = (Node *)n;
				}
1164 1165
/* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
		| ALTER TABLE relation_expr DROP opt_column ColId drop_behavior
1166 1167 1168
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'D';
1169
					n->relation = $3;
1170 1171
					n->name = $6;
					n->behavior = $7;
1172 1173
					$$ = (Node *)n;
				}
1174 1175
/* ALTER TABLE <relation> ADD CONSTRAINT ... */
		| ALTER TABLE relation_expr ADD TableConstraint
1176 1177 1178
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'C';
1179
					n->relation = $3;
1180
					n->def = $5;
1181 1182
					$$ = (Node *)n;
				}
1183 1184
/* ALTER TABLE <relation> DROP CONSTRAINT <name> {RESTRICT|CASCADE} */
		| ALTER TABLE relation_expr DROP CONSTRAINT name drop_behavior
1185 1186 1187
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'X';
1188
					n->relation = $3;
1189 1190
					n->name = $6;
					n->behavior = $7;
1191 1192
					$$ = (Node *)n;
				}
Jan Wieck's avatar
TOAST  
Jan Wieck committed
1193
/* ALTER TABLE <name> CREATE TOAST TABLE */
1194
		| ALTER TABLE qualified_name CREATE TOAST TABLE
Jan Wieck's avatar
TOAST  
Jan Wieck committed
1195 1196 1197
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'E';
1198 1199
					$3->inhOpt = INH_NO;
					n->relation = $3;
Jan Wieck's avatar
TOAST  
Jan Wieck committed
1200 1201
					$$ = (Node *)n;
				}
1202
/* ALTER TABLE <name> OWNER TO UserId */
1203
		| ALTER TABLE qualified_name OWNER TO UserId
1204 1205 1206
				{
					AlterTableStmt *n = makeNode(AlterTableStmt);
					n->subtype = 'U';
1207 1208
					$3->inhOpt = INH_NO;
					n->relation = $3;
1209 1210 1211
					n->name = $6;
					$$ = (Node *)n;
				}
1212
		;
1213

1214
alter_column_default:
1215 1216 1217 1218 1219 1220 1221 1222
		SET DEFAULT a_expr
			{
				/* Treat SET DEFAULT NULL the same as DROP DEFAULT */
				if (exprIsNullConstant($3))
					$$ = NULL;
				else
					$$ = $3;
			}
1223
		| DROP DEFAULT					{ $$ = NULL; }
1224 1225
        ;

1226 1227
drop_behavior: CASCADE					{ $$ = CASCADE; }
		| RESTRICT						{ $$ = RESTRICT; }
1228
        ;
1229

Tom Lane's avatar
Tom Lane committed
1230 1231 1232
opt_drop_behavior: CASCADE				{ $$ = CASCADE; }
		| RESTRICT						{ $$ = RESTRICT; }
		| /* EMPTY */					{ $$ = RESTRICT; /* default */ }
1233 1234
		;

1235

1236 1237

/*****************************************************************************
1238
 *
1239 1240
 *		QUERY :
 *				close <optname>
1241
 *
1242 1243
 *****************************************************************************/

1244
ClosePortalStmt:  CLOSE opt_id
1245 1246 1247 1248 1249 1250
				{
					ClosePortalStmt *n = makeNode(ClosePortalStmt);
					n->portalname = $2;
					$$ = (Node *)n;
				}
		;
1251

1252 1253 1254 1255
opt_id:  ColId									{ $$ = $1; }
		| /*EMPTY*/								{ $$ = NULL; }
		;

1256 1257 1258

/*****************************************************************************
 *
1259 1260 1261
 *		QUERY :
 *				COPY [BINARY] <relname> FROM/TO
 *				[USING DELIMITERS <delimiter>]
1262 1263 1264
 *
 *****************************************************************************/

1265
CopyStmt:  COPY opt_binary qualified_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
1266 1267 1268
				{
					CopyStmt *n = makeNode(CopyStmt);
					n->binary = $2;
1269
					n->relation = $3;
1270 1271 1272 1273
					n->oids = $4;
					n->direction = $5;
					n->filename = $6;
					n->delimiter = $7;
1274
					n->null_print = $8;
1275 1276 1277 1278 1279 1280
					$$ = (Node *)n;
				}
		;

copy_dirn:	TO
				{ $$ = TO; }
1281
		| FROM
1282 1283
				{ $$ = FROM; }
		;
1284

1285
/*
1286 1287
 * 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
1288
 * stdout. We silently correct the "typo".		 - AY 9/94
1289
 */
1290 1291 1292 1293
copy_file_name:  Sconst							{ $$ = $1; }
		| STDIN									{ $$ = NULL; }
		| STDOUT								{ $$ = NULL; }
		;
1294

1295 1296
opt_binary:  BINARY								{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
1297
		;
1298

1299
opt_with_copy:	WITH OIDS						{ $$ = TRUE; }
1300
		| /*EMPTY*/								{ $$ = FALSE; }
1301
		;
1302

1303 1304 1305
/*
 * the default copy delimiter is tab but the user can configure it
 */
Bruce Momjian's avatar
Bruce Momjian committed
1306
copy_delimiter:  opt_using DELIMITERS Sconst	{ $$ = $3; }
1307
		| /*EMPTY*/								{ $$ = "\t"; }
1308
		;
1309

Bruce Momjian's avatar
Bruce Momjian committed
1310 1311 1312 1313
opt_using:	USING								{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = TRUE; }
		;

1314 1315 1316
copy_null:  WITH NULL_P AS Sconst				{ $$ = $4; }
		| /*EMPTY*/								{ $$ = "\\N"; }
		;
1317 1318 1319

/*****************************************************************************
 *
1320 1321
 *		QUERY :
 *				CREATE relname
1322 1323 1324
 *
 *****************************************************************************/

1325
CreateStmt:  CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' OptInherit OptWithOids
1326 1327
				{
					CreateStmt *n = makeNode(CreateStmt);
1328 1329
					$4->istemp = $2;
					n->relation = $4;
1330
					n->tableElts = $6;
1331
					n->inhRelations = $8;
1332
					n->constraints = NIL;
1333
					n->hasoids = $9;
1334 1335 1336 1337
					$$ = (Node *)n;
				}
		;

1338 1339 1340 1341 1342 1343 1344 1345 1346
/*
 * 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
1347 1348 1349 1350
				{
					elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
					$$ = TRUE;
				}
1351
			| GLOBAL TEMP
1352
				{
1353 1354
					elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
					$$ = TRUE;
1355
				}
1356
			| /*EMPTY*/						{ $$ = FALSE; }
1357 1358
		;

1359
OptTableElementList:  OptTableElementList ',' OptTableElement
1360 1361 1362 1363 1364 1365 1366 1367 1368
				{
					if ($3 != NULL)
						$$ = lappend($1, $3);
					else
						$$ = $1;
				}
			| OptTableElement
				{
					if ($1 != NULL)
1369
						$$ = makeList1($1);
1370
					else
1371
						$$ = NIL;
1372
				}
1373
			| /*EMPTY*/							{ $$ = NIL; }
1374
		;
1375

1376 1377
OptTableElement:  columnDef						{ $$ = $1; }
			| TableConstraint					{ $$ = $1; }
1378
		;
1379

1380
columnDef:  ColId Typename ColQualList opt_collate
1381 1382 1383 1384 1385
				{
					ColumnDef *n = makeNode(ColumnDef);
					n->colname = $1;
					n->typename = $2;
					n->constraints = $3;
1386

1387
					if ($4 != NULL)
Bruce Momjian's avatar
Bruce Momjian committed
1388
						elog(NOTICE,"CREATE TABLE / COLLATE %s not yet implemented"
1389
							 "; clause ignored", $4);
1390

1391 1392 1393 1394
					$$ = (Node *)n;
				}
		;

1395 1396
ColQualList:  ColQualList ColConstraint		{ $$ = lappend($1, $2); }
			| /*EMPTY*/						{ $$ = NIL; }
1397 1398
		;

1399 1400
ColConstraint:
		CONSTRAINT name ColConstraintElem
1401
				{
Jan Wieck's avatar
Jan Wieck committed
1402 1403 1404 1405 1406
					switch (nodeTag($3))
					{
						case T_Constraint:
							{
								Constraint *n = (Constraint *)$3;
1407
								n->name = $2;
Jan Wieck's avatar
Jan Wieck committed
1408 1409 1410 1411 1412
							}
							break;
						case T_FkConstraint:
							{
								FkConstraint *n = (FkConstraint *)$3;
1413
								n->constr_name = $2;
Jan Wieck's avatar
Jan Wieck committed
1414 1415 1416 1417 1418 1419
							}
							break;
						default:
							break;
					}
					$$ = $3;
1420 1421 1422
				}
		| ColConstraintElem
				{ $$ = $1; }
1423
		| ConstraintAttr
1424 1425 1426 1427
				{ $$ = $1; }
		;

/* DEFAULT NULL is already the default for Postgres.
1428
 * But define it here and carry it forward into the system
1429 1430
 * to make it explicit.
 * - thomas 1998-09-13
1431
 *
1432 1433 1434 1435 1436
 * 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
1437 1438 1439 1440
 *
 * 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).
1441
 */
1442 1443
ColConstraintElem:
			  NOT NULL_P
1444
				{
1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461
					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;
1462 1463
				}
			| UNIQUE
1464 1465
				{
					Constraint *n = makeNode(Constraint);
1466
					n->contype = CONSTR_UNIQUE;
1467
					n->name = NULL;
1468 1469
					n->raw_expr = NULL;
					n->cooked_expr = NULL;
1470 1471 1472
					n->keys = NULL;
					$$ = (Node *)n;
				}
1473
			| PRIMARY KEY
1474
				{
1475 1476 1477 1478 1479 1480 1481
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_PRIMARY;
					n->name = NULL;
					n->raw_expr = NULL;
					n->cooked_expr = NULL;
					n->keys = NULL;
					$$ = (Node *)n;
1482
				}
1483
			| CHECK '(' a_expr ')'
1484 1485
				{
					Constraint *n = makeNode(Constraint);
1486
					n->contype = CONSTR_CHECK;
1487
					n->name = NULL;
1488
					n->raw_expr = $3;
1489
					n->cooked_expr = NULL;
1490 1491 1492
					n->keys = NULL;
					$$ = (Node *)n;
				}
1493 1494 1495 1496 1497
			| DEFAULT b_expr
				{
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_DEFAULT;
					n->name = NULL;
1498 1499
					if (exprIsNullConstant($2))
					{
1500
						/* DEFAULT NULL should be reported as empty expr */
1501 1502 1503 1504 1505 1506
						n->raw_expr = NULL;
					}
					else
					{
						n->raw_expr = $2;
					}
1507 1508 1509 1510
					n->cooked_expr = NULL;
					n->keys = NULL;
					$$ = (Node *)n;
				}
1511
			| REFERENCES qualified_name opt_column_list key_match key_actions 
1512
				{
Jan Wieck's avatar
Jan Wieck committed
1513 1514
					FkConstraint *n = makeNode(FkConstraint);
					n->constr_name		= NULL;
1515
					n->pktable			= $2;
Jan Wieck's avatar
Jan Wieck committed
1516 1517 1518 1519
					n->fk_attrs			= NIL;
					n->pk_attrs			= $3;
					n->match_type		= $4;
					n->actions			= $5;
1520 1521
					n->deferrable		= FALSE;
					n->initdeferred		= FALSE;
Jan Wieck's avatar
Jan Wieck committed
1522
					$$ = (Node *)n;
1523
				}
1524
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1525

1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537
/*
 * 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
1538 1539
				{
					Constraint *n = makeNode(Constraint);
1540
					n->contype = CONSTR_ATTR_DEFERRABLE;
1541 1542
					$$ = (Node *)n;
				}
1543
			| NOT DEFERRABLE
1544 1545
				{
					Constraint *n = makeNode(Constraint);
1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558
					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;
1559 1560
					$$ = (Node *)n;
				}
1561 1562
		;

1563

1564 1565 1566 1567 1568
/* 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
1569
				{
Jan Wieck's avatar
Jan Wieck committed
1570 1571 1572 1573 1574
					switch (nodeTag($3))
					{
						case T_Constraint:
							{
								Constraint *n = (Constraint *)$3;
1575
								n->name = $2;
Jan Wieck's avatar
Jan Wieck committed
1576 1577 1578 1579 1580
							}
							break;
						case T_FkConstraint:
							{
								FkConstraint *n = (FkConstraint *)$3;
1581
								n->constr_name = $2;
Jan Wieck's avatar
Jan Wieck committed
1582 1583 1584 1585 1586 1587
							}
							break;
						default:
							break;
					}
					$$ = $3;
1588
				}
1589 1590
		| ConstraintElem
				{ $$ = $1; }
1591 1592
		;

1593
ConstraintElem:  CHECK '(' a_expr ')'
1594
				{
1595 1596 1597
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_CHECK;
					n->name = NULL;
1598 1599
					n->raw_expr = $3;
					n->cooked_expr = NULL;
1600
					$$ = (Node *)n;
1601
				}
1602
		| UNIQUE '(' columnList ')'
1603 1604 1605 1606
				{
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_UNIQUE;
					n->name = NULL;
1607 1608
					n->raw_expr = NULL;
					n->cooked_expr = NULL;
1609 1610 1611
					n->keys = $3;
					$$ = (Node *)n;
				}
1612
		| PRIMARY KEY '(' columnList ')'
1613
				{
1614 1615 1616 1617 1618 1619
					Constraint *n = makeNode(Constraint);
					n->contype = CONSTR_PRIMARY;
					n->name = NULL;
					n->raw_expr = NULL;
					n->cooked_expr = NULL;
					n->keys = $4;
1620 1621
					$$ = (Node *)n;
				}
1622
		| FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list
1623
				key_match key_actions ConstraintAttributeSpec
Jan Wieck's avatar
Jan Wieck committed
1624 1625 1626
				{
					FkConstraint *n = makeNode(FkConstraint);
					n->constr_name		= NULL;
1627
					n->pktable			= $7;
Jan Wieck's avatar
Jan Wieck committed
1628 1629 1630 1631 1632 1633 1634
					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;
1635
				}
1636
		;
1637

1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655
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
1656 1657 1658 1659 1660 1661
key_match:  MATCH FULL
			{
				$$ = "FULL";
			}
		| MATCH PARTIAL
			{
1662
				elog(ERROR, "FOREIGN KEY/MATCH PARTIAL not yet implemented");
Jan Wieck's avatar
Jan Wieck committed
1663 1664 1665 1666 1667 1668
				$$ = "PARTIAL";
			}
		| /*EMPTY*/
			{
				$$ = "UNSPECIFIED";
			}
1669 1670
		;

1671 1672 1673 1674
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
1675
		| /*EMPTY*/						{ $$ = 0; }
1676 1677
		;

1678 1679 1680 1681
key_delete:  ON DELETE key_reference	{ $$ = $3 << FKCONSTR_ON_DELETE_SHIFT; }
		;

key_update:  ON UPDATE key_reference	{ $$ = $3 << FKCONSTR_ON_UPDATE_SHIFT; }
1682 1683
		;

Jan Wieck's avatar
Jan Wieck committed
1684 1685 1686 1687 1688
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; }
1689 1690
		;

1691
OptInherit:  INHERITS '(' qualified_name_list ')'	{ $$ = $3; }
1692
		| /*EMPTY*/									{ $$ = NIL; }
1693 1694
		;

1695 1696 1697 1698 1699 1700
OptWithOids:  WITH OIDS						{ $$ = TRUE; }
			| WITHOUT OIDS					{ $$ = FALSE; }
			| /*EMPTY*/						{ $$ = TRUE; }
		;


1701 1702 1703 1704 1705
/*
 * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
 * SELECT ... INTO.
 */

1706
CreateAsStmt:  CREATE OptTemp TABLE qualified_name OptCreateAs AS SelectStmt
1707
				{
1708 1709 1710 1711 1712 1713 1714
					/*
					 * 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.
					 */
1715
					SelectStmt *n = findLeftmostSelect((SelectStmt *) $7);
1716
					if (n->into != NULL)
1717
						elog(ERROR,"CREATE TABLE AS may not specify INTO");
1718
					$4->istemp = $2;
1719
					n->into = $4;
1720
					n->intoColNames = $5;
1721
					$$ = $7;
1722 1723 1724 1725
				}
		;

OptCreateAs:  '(' CreateAsList ')'				{ $$ = $2; }
1726
			| /*EMPTY*/							{ $$ = NIL; }
1727 1728 1729
		;

CreateAsList:  CreateAsList ',' CreateAsElement	{ $$ = lappend($1, $3); }
1730
			| CreateAsElement					{ $$ = makeList1($1); }
1731 1732 1733 1734 1735 1736 1737
		;

CreateAsElement:  ColId
				{
					ColumnDef *n = makeNode(ColumnDef);
					n->colname = $1;
					n->typename = NULL;
1738 1739
					n->raw_default = NULL;
					n->cooked_default = NULL;
1740 1741 1742 1743 1744 1745
					n->is_not_null = FALSE;
					n->constraints = NULL;
					$$ = (Node *)n;
				}
		;

1746

Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1747 1748
/*****************************************************************************
 *
1749 1750
 *		QUERY :
 *				CREATE SEQUENCE seqname
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1751 1752 1753
 *
 *****************************************************************************/

1754
CreateSeqStmt:  CREATE OptTemp SEQUENCE qualified_name OptSeqList
1755 1756
				{
					CreateSeqStmt *n = makeNode(CreateSeqStmt);
1757 1758
					$4->istemp = $2;
					n->sequence = $4;
1759
					n->options = $5;
1760 1761 1762
					$$ = (Node *)n;
				}
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1763

1764
OptSeqList:  OptSeqList OptSeqElem
1765
				{ $$ = lappend($1, $2); }
1766
			|	{ $$ = NIL; }
1767 1768
		;

1769
OptSeqElem:  CACHE NumericOnly
1770 1771
				{
					$$ = makeNode(DefElem);
1772
					$$->defname = "cache";
1773 1774
					$$->arg = (Node *)$2;
				}
1775
			| CYCLE
1776 1777
				{
					$$ = makeNode(DefElem);
1778
					$$->defname = "cycle";
1779 1780
					$$->arg = (Node *)NULL;
				}
1781
			| INCREMENT NumericOnly
1782 1783 1784 1785 1786
				{
					$$ = makeNode(DefElem);
					$$->defname = "increment";
					$$->arg = (Node *)$2;
				}
1787
			| MAXVALUE NumericOnly
1788 1789 1790 1791 1792
				{
					$$ = makeNode(DefElem);
					$$->defname = "maxvalue";
					$$->arg = (Node *)$2;
				}
1793
			| MINVALUE NumericOnly
1794 1795 1796 1797 1798
				{
					$$ = makeNode(DefElem);
					$$->defname = "minvalue";
					$$->arg = (Node *)$2;
				}
1799
			| START NumericOnly
1800 1801 1802 1803 1804 1805 1806
				{
					$$ = makeNode(DefElem);
					$$->defname = "start";
					$$->arg = (Node *)$2;
				}
		;

1807 1808
NumericOnly:  FloatOnly					{ $$ = $1; }
			| IntegerOnly				{ $$ = $1; }
1809
		;
1810 1811 1812 1813 1814 1815 1816 1817

FloatOnly:  FCONST
				{
					$$ = makeFloat($1);
				}
			| '-' FCONST
				{
					$$ = makeFloat($2);
1818
					doNegateFloat($$);
1819 1820 1821
				}
		;

1822 1823 1824 1825 1826 1827 1828 1829 1830
IntegerOnly:  Iconst
				{
					$$ = makeInteger($1);
				}
			| '-' Iconst
				{
					$$ = makeInteger($2);
					$$->val.ival = - $$->val.ival;
				}
1831
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1832

1833 1834 1835 1836 1837 1838 1839 1840
/*****************************************************************************
 *
 *		QUERIES :
 *				CREATE PROCEDURAL LANGUAGE ...
 *				DROP PROCEDURAL LANGUAGE ...
 *
 *****************************************************************************/

1841
CreatePLangStmt:  CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
1842
			HANDLER handler_name opt_lancompiler
1843 1844 1845 1846
			{
				CreatePLangStmt *n = makeNode(CreatePLangStmt);
				n->plname = $5;
				n->plhandler = $7;
1847
				n->plcompiler = $8;
1848 1849 1850 1851 1852
				n->pltrusted = $2;
				$$ = (Node *)n;
			}
		;

1853
opt_trusted:  TRUSTED			{ $$ = TRUE; }
1854
			| /*EMPTY*/			{ $$ = FALSE; }
1855
		;
1856

1857 1858 1859 1860 1861
/* This ought to be just func_name, but that causes reduce/reduce conflicts
 * (CREATE LANGUAGE is the only place where func_name isn't followed by '(').
 * Work around by using name and dotted_name separately.
 */
handler_name: name
1862
				{ $$ = makeList1(makeString($1)); }
1863
			| dotted_name
1864
				{ $$ = $1; }
1865 1866
		;

1867 1868
opt_lancompiler: LANCOMPILER Sconst { $$ = $2; }
			| /*EMPTY*/			{ $$ = ""; }
1869
		;
1870 1871

DropPLangStmt:  DROP opt_procedural LANGUAGE ColId_or_Sconst
1872 1873 1874 1875 1876 1877
			{
				DropPLangStmt *n = makeNode(DropPLangStmt);
				n->plname = $4;
				$$ = (Node *)n;
			}
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
1878

1879 1880 1881 1882
opt_procedural: PROCEDURAL		{ $$ = TRUE; }
			| /*EMPTY*/			{ $$ = TRUE; }
		;
		
1883 1884
/*****************************************************************************
 *
1885 1886 1887
 *		QUERIES :
 *				CREATE TRIGGER ...
 *				DROP TRIGGER ...
1888 1889 1890
 *
 *****************************************************************************/

1891
CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1892
				qualified_name TriggerForSpec EXECUTE PROCEDURE
1893
				func_name '(' TriggerFuncArgs ')'
1894 1895 1896
				{
					CreateTrigStmt *n = makeNode(CreateTrigStmt);
					n->trigname = $3;
1897
					n->relation = $7;
1898 1899 1900 1901 1902
					n->funcname = $11;
					n->args = $13;
					n->before = $4;
					n->row = $8;
					memcpy (n->actions, $5, 4);
1903 1904 1905 1906 1907
					n->lang = NULL;		/* unused */
					n->text = NULL;		/* unused */
					n->attr = NULL;		/* unused */
					n->when = NULL;		/* unused */

1908 1909 1910
					n->isconstraint  = FALSE;
					n->deferrable    = FALSE;
					n->initdeferred  = FALSE;
1911
					n->constrrel = NULL;
1912 1913
					$$ = (Node *)n;
				}
1914
		| CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
1915
				qualified_name OptConstrFromTable 
1916
				ConstraintAttributeSpec
1917 1918
				FOR EACH ROW EXECUTE PROCEDURE
				func_name '(' TriggerFuncArgs ')'
1919 1920 1921
				{
					CreateTrigStmt *n = makeNode(CreateTrigStmt);
					n->trigname = $4;
1922
					n->relation = $8;
Jan Wieck's avatar
Jan Wieck committed
1923 1924
					n->funcname = $16;
					n->args = $18;
1925 1926
					n->before = FALSE;
					n->row = TRUE;
1927
					memcpy (n->actions, $6, 4);
1928 1929 1930 1931 1932
					n->lang = NULL;		/* unused */
					n->text = NULL;		/* unused */
					n->attr = NULL;		/* unused */
					n->when = NULL;		/* unused */

1933
					n->isconstraint  = TRUE;
Jan Wieck's avatar
Jan Wieck committed
1934 1935
					n->deferrable = ($10 & 1) != 0;
					n->initdeferred = ($10 & 2) != 0;
1936

1937
					n->constrrel = $9;
1938 1939 1940 1941
					$$ = (Node *)n;
				}
		;

1942 1943
TriggerActionTime:  BEFORE						{ $$ = TRUE; }
			| AFTER								{ $$ = FALSE; }
1944 1945 1946
		;

TriggerEvents:	TriggerOneEvent
1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961
				{
					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;
				}
1962 1963
		;

1964 1965 1966
TriggerOneEvent:  INSERT					{ $$ = 'i'; }
			| DELETE						{ $$ = 'd'; }
			| UPDATE						{ $$ = 'u'; }
1967 1968
		;

1969
TriggerForSpec:  FOR TriggerForOpt TriggerForType
1970
				{
1971
					$$ = $3;
1972 1973
				}
		;
1974

1975 1976 1977 1978 1979 1980 1981 1982
TriggerForOpt:  EACH						{ $$ = TRUE; }
			| /*EMPTY*/						{ $$ = FALSE; }
		;

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

1983
TriggerFuncArgs:  TriggerFuncArg
1984
				{ $$ = makeList1($1); }
1985
			| TriggerFuncArgs ',' TriggerFuncArg
1986
				{ $$ = lappend($1, $3); }
1987
			| /*EMPTY*/
1988
				{ $$ = NIL; }
1989 1990
		;

1991
TriggerFuncArg:  ICONST
1992
				{
1993 1994
					char buf[64];
					sprintf (buf, "%d", $1);
1995 1996 1997 1998 1999 2000 2001 2002 2003 2004
					$$ = makeString(pstrdup(buf));
				}
			| FCONST
				{
					$$ = makeString($1);
				}
			| Sconst
				{
					$$ = makeString($1);
				}
2005 2006 2007 2008
			| BITCONST
				{
					$$ = makeString($1);
				}
2009 2010 2011
			| ColId
				{
					$$ = makeString($1);
2012
				}
2013
		;
2014

2015 2016
OptConstrFromTable:			/* Empty */
				{
2017
					$$ = NULL;
2018
				}
2019
		| FROM qualified_name
2020 2021 2022 2023 2024
				{
					$$ = $2;
				}
		;

2025 2026 2027
ConstraintAttributeSpec:  ConstraintDeferrabilitySpec
			{ $$ = $1; }
		| ConstraintDeferrabilitySpec ConstraintTimeSpec
Jan Wieck's avatar
Jan Wieck committed
2028
			{
2029 2030 2031
				if ($1 == 0 && $2 != 0)
					elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
				$$ = $1 | $2;
Jan Wieck's avatar
Jan Wieck committed
2032
			}
2033
		| ConstraintTimeSpec
Jan Wieck's avatar
Jan Wieck committed
2034 2035 2036 2037
			{
				if ($1 != 0)
					$$ = 3;
				else
2038
					$$ = 0;
Jan Wieck's avatar
Jan Wieck committed
2039
			}
2040
		| ConstraintTimeSpec ConstraintDeferrabilitySpec
Jan Wieck's avatar
Jan Wieck committed
2041 2042 2043 2044 2045
			{
				if ($2 == 0 && $1 != 0)
					elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
				$$ = $1 | $2;
			}
2046 2047
		| /* Empty */
			{ $$ = 0; }
2048 2049
		;

2050 2051 2052 2053
ConstraintDeferrabilitySpec: NOT DEFERRABLE
			{ $$ = 0; }
		| DEFERRABLE
			{ $$ = 1; }
Jan Wieck's avatar
Jan Wieck committed
2054 2055
		;

2056 2057 2058 2059
ConstraintTimeSpec: INITIALLY IMMEDIATE
			{ $$ = 0; }
		| INITIALLY DEFERRED
			{ $$ = 2; }
2060
		;
2061

2062

2063
DropTrigStmt:  DROP TRIGGER name ON qualified_name
2064 2065 2066
				{
					DropTrigStmt *n = makeNode(DropTrigStmt);
					n->trigname = $3;
2067
					n->relation = $5;
2068 2069 2070
					$$ = (Node *) n;
				}
		;
2071

2072

2073 2074
/*****************************************************************************
 *
2075
 *		QUERY :
2076
 *				define (aggregate,operator,type)
2077 2078 2079
 *
 *****************************************************************************/

2080
DefineStmt:  CREATE AGGREGATE func_name definition
2081
				{
2082
					DefineStmt *n = makeNode(DefineStmt);
2083
					n->defType = AGGREGATE;
2084
					n->defnames = $3;
2085 2086 2087
					n->definition = $4;
					$$ = (Node *)n;
				}
2088
		| CREATE OPERATOR any_operator definition
2089 2090 2091
				{
					DefineStmt *n = makeNode(DefineStmt);
					n->defType = OPERATOR;
2092
					n->defnames = $3;
2093 2094 2095
					n->definition = $4;
					$$ = (Node *)n;
				}
2096
		| CREATE TYPE_P any_name definition
2097 2098 2099
				{
					DefineStmt *n = makeNode(DefineStmt);
					n->defType = TYPE_P;
2100
					n->defnames = $3;
2101 2102
					n->definition = $4;
					$$ = (Node *)n;
2103 2104
				}
		;
2105

2106
definition:  '(' def_list ')'				{ $$ = $2; }
2107
		;
2108

2109
def_list:  def_elem							{ $$ = makeList1($1); }
2110
		| def_list ',' def_elem				{ $$ = lappend($1, $3); }
2111
		;
2112

Tom Lane's avatar
Tom Lane committed
2113
def_elem:  ColLabel '=' def_arg
2114 2115 2116 2117 2118
				{
					$$ = makeNode(DefElem);
					$$->defname = $1;
					$$->arg = (Node *)$3;
				}
Tom Lane's avatar
Tom Lane committed
2119
		| ColLabel
2120 2121 2122 2123 2124 2125 2126
				{
					$$ = makeNode(DefElem);
					$$->defname = $1;
					$$->arg = (Node *)NULL;
				}
		;

2127
/* Note: any simple identifier will be returned as a type name! */
2128
def_arg:  func_return  					{  $$ = (Node *)$1; }
2129
		| all_Op						{  $$ = (Node *)makeString($1); }
2130
		| NumericOnly					{  $$ = (Node *)$1; }
2131
		| Sconst						{  $$ = (Node *)makeString($1); }
2132
		;
2133 2134 2135 2136


/*****************************************************************************
 *
2137
 *		QUERY:
2138 2139
 *
 *		DROP itemtype itemname [, itemname ...]
2140 2141 2142
 *
 *****************************************************************************/

2143
DropStmt:  DROP drop_type any_name_list opt_drop_behavior
2144 2145
				{
					DropStmt *n = makeNode(DropStmt);
2146
					n->removeType = $2;
2147
					n->objects = $3;
2148
					n->behavior = $4;
2149 2150 2151
					$$ = (Node *)n;
				}
		;
2152

2153 2154 2155 2156 2157
drop_type: TABLE								{ $$ = DROP_TABLE; }
		| SEQUENCE								{ $$ = DROP_SEQUENCE; }
		| VIEW									{ $$ = DROP_VIEW; }
		| INDEX									{ $$ = DROP_INDEX; }
		| RULE									{ $$ = DROP_RULE; }
Tom Lane's avatar
Tom Lane committed
2158 2159
		| TYPE_P								{ $$ = DROP_TYPE; }
		| DOMAIN_P								{ $$ = DROP_DOMAIN; }
2160 2161
		;

2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173
any_name_list:  any_name
			{ $$ = makeList1($1); }
		| any_name_list ',' any_name
			{ $$ = lappend($1, $3); }
		;

any_name: ColId
			{ $$ = makeList1(makeString($1)); }
		| dotted_name
			{ $$ = $1; }
		;

2174 2175 2176 2177 2178 2179 2180
/*****************************************************************************
 *
 *		QUERY:
 *				truncate table relname
 *
 *****************************************************************************/

2181
TruncateStmt:  TRUNCATE opt_table qualified_name
2182 2183
				{
					TruncateStmt *n = makeNode(TruncateStmt);
2184
					n->relation = $3;
2185 2186 2187
					$$ = (Node *)n;
				}
			;
2188

2189 2190
/*****************************************************************************
 *
Bruce Momjian's avatar
Bruce Momjian committed
2191 2192 2193
 *  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:
 *
2194
 *  COMMENT ON [ [ DATABASE | DOMAIN | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] 
2195
 *               <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION 
Bruce Momjian's avatar
Bruce Momjian committed
2196 2197 2198
 *		 <funcname> (arg1, arg2, ...) | OPERATOR <op> 
 *		 (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
 *		 <relname> ] IS 'text'
2199 2200 2201
 *
 *****************************************************************************/
 
2202
CommentStmt:	COMMENT ON comment_type any_name IS comment_text
Bruce Momjian's avatar
Bruce Momjian committed
2203 2204 2205 2206
			{
				CommentStmt *n = makeNode(CommentStmt);
				n->objtype = $3;
				n->objname = $4;
2207
				n->objargs = NIL;
Bruce Momjian's avatar
Bruce Momjian committed
2208 2209 2210
				n->comment = $6;
				$$ = (Node *) n;
			}
2211
		| COMMENT ON AGGREGATE func_name '(' aggr_argtype ')' IS comment_text
Bruce Momjian's avatar
Bruce Momjian committed
2212
			{
2213
				CommentStmt *n = makeNode(CommentStmt);
2214 2215
				n->objtype = AGGREGATE;
				n->objname = $4;
2216
				n->objargs = makeList1($6);
2217 2218 2219 2220
				n->comment = $9;
				$$ = (Node *) n;
			}
		| COMMENT ON FUNCTION func_name func_args IS comment_text
Bruce Momjian's avatar
Bruce Momjian committed
2221 2222
			{
				CommentStmt *n = makeNode(CommentStmt);
2223
				n->objtype = FUNCTION;
Bruce Momjian's avatar
Bruce Momjian committed
2224
				n->objname = $4;
2225
				n->objargs = $5;
Bruce Momjian's avatar
Bruce Momjian committed
2226 2227 2228
				n->comment = $7;
				$$ = (Node *) n;
			}
2229
		| COMMENT ON OPERATOR any_operator '(' oper_argtypes ')' IS comment_text
Bruce Momjian's avatar
Bruce Momjian committed
2230 2231
			{
				CommentStmt *n = makeNode(CommentStmt);
2232
				n->objtype = OPERATOR;
2233
				n->objname = $4;
2234
				n->objargs = $6;
Bruce Momjian's avatar
Bruce Momjian committed
2235
				n->comment = $9;
2236 2237
				$$ = (Node *) n;
			}
2238
		| COMMENT ON TRIGGER name ON any_name IS comment_text
Bruce Momjian's avatar
Bruce Momjian committed
2239 2240
			{
				CommentStmt *n = makeNode(CommentStmt);
2241
				n->objtype = TRIGGER;
2242 2243
				n->objname = lappend($6, makeString($4));
				n->objargs = NIL;
Bruce Momjian's avatar
Bruce Momjian committed
2244 2245 2246 2247 2248
				n->comment = $8;
				$$ = (Node *) n;
			}
		;

2249 2250
comment_type:	COLUMN { $$ = COLUMN; }
		| DATABASE { $$ = DATABASE; }
Bruce Momjian's avatar
Bruce Momjian committed
2251 2252 2253 2254
		| INDEX { $$ = INDEX; }
		| RULE { $$ = RULE; }
		| SEQUENCE { $$ = SEQUENCE; }
		| TABLE { $$ = TABLE; }
2255
		| DOMAIN_P { $$ = TYPE_P; }
Bruce Momjian's avatar
Bruce Momjian committed
2256 2257 2258 2259
		| TYPE_P { $$ = TYPE_P; }
		| VIEW { $$ = VIEW; }
		;		

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

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

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

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

2412 2413
fetch_how_many:  Iconst					{ $$ = $1; }
		| '-' Iconst					{ $$ = - $2; }
2414
		| ALL							{ $$ = 0; /* 0 means fetch all tuples*/ }
2415 2416
		| NEXT							{ $$ = 1; }
		| PRIOR							{ $$ = -1; }
2417
		;
2418

2419 2420 2421
from_in:  IN 
	| FROM
	;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
2422

2423

2424 2425
/*****************************************************************************
 *
2426
 * GRANT and REVOKE statements
2427 2428 2429
 *
 *****************************************************************************/

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

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

2454 2455 2456 2457 2458

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

2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480
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. */
2481
privilege_target: qualified_name_list
2482
				{
2483 2484 2485 2486
					PrivTarget *n = makeNode(PrivTarget);
					n->objtype = TABLE;
					n->objs = $1;
					$$ = n;
2487
				}
2488
			| TABLE qualified_name_list
2489
				{
2490 2491 2492 2493
					PrivTarget *n = makeNode(PrivTarget);
					n->objtype = TABLE;
					n->objs = $2;
					$$ = n;
2494
				}
2495
			| FUNCTION function_with_argtypes_list
2496
				{
2497 2498 2499 2500
					PrivTarget *n = makeNode(PrivTarget);
					n->objtype = FUNCTION;
					n->objs = $2;
					$$ = n;
2501
				}
2502
			| LANGUAGE name_list
2503
				{
2504 2505 2506 2507
					PrivTarget *n = makeNode(PrivTarget);
					n->objtype = LANGUAGE;
					n->objs = $2;
					$$ = n;
2508 2509 2510
				}
		;

2511 2512 2513 2514 2515

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

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

2539

2540 2541 2542 2543 2544 2545
opt_grant_grant_option: WITH GRANT OPTION
				{
					elog(ERROR, "grant options are not implemented");
				}
		| /*EMPTY*/
		;
2546

2547
opt_revoke_grant_option: GRANT OPTION FOR
2548
				{
2549 2550
					elog(ERROR, "grant options are not implemented");
				}
2551
		| /*EMPTY*/
2552 2553
		;

2554

2555 2556 2557 2558 2559
function_with_argtypes_list: function_with_argtypes
				{ $$ = makeList1($1); }
		| function_with_argtypes_list ',' function_with_argtypes
				{ $$ = lappend($1, $3); }
		;
2560

2561
function_with_argtypes: func_name func_args
2562
				{
2563 2564 2565
					FuncWithArgs *n = makeNode(FuncWithArgs);
					n->funcname = $1;
					n->funcargs = $2;
2566
					$$ = (Node *)n;
2567 2568
				}
		;
2569

2570

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

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

2594 2595
index_opt_unique:  UNIQUE						{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
2596 2597
		;

2598
access_method_clause:  USING access_method		{ $$ = $2; }
2599 2600
		/* If btree changes as our default, update pg_get_indexdef() */
		| /*EMPTY*/								{ $$ = DEFAULT_INDEX_TYPE; }
2601
		;
2602

2603
index_params:  index_list						{ $$ = $1; }
2604
		| func_index							{ $$ = makeList1($1); }
2605 2606 2607
		;

index_list:  index_list ',' index_elem			{ $$ = lappend($1, $3); }
2608
		| index_elem							{ $$ = makeList1($1); }
2609 2610
		;

2611
func_index:  func_name '(' name_list ')' opt_class
2612 2613
				{
					$$ = makeNode(IndexElem);
2614 2615
					$$->name = NULL;
					$$->funcname = $1;
2616
					$$->args = $3;
2617
					$$->opclass = $5;
2618 2619 2620
				}
		  ;

2621
index_elem:  attr_name opt_class
2622 2623 2624
				{
					$$ = makeNode(IndexElem);
					$$->name = $1;
2625
					$$->funcname = NIL;
2626
					$$->args = NIL;
2627
					$$->opclass = $2;
2628 2629 2630
				}
		;

2631
opt_class:  any_name
2632 2633
				{
					/*
Tom Lane's avatar
Tom Lane committed
2634 2635 2636 2637 2638 2639 2640
					 * 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
2641 2642 2643 2644
					 *
					 * 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
2645
					 */
2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658
					if (length($1) == 1)
					{
						char   *claname = strVal(lfirst($1));

						if (strcmp(claname, "network_ops") != 0 &&
							strcmp(claname, "timespan_ops") != 0 &&
							strcmp(claname, "datetime_ops") != 0 &&
							strcmp(claname, "lztext_ops") != 0 &&
							strcmp(claname, "timestamp_ops") != 0)
							$$ = $1;
						else
							$$ = NIL;
					}
2659
					else
2660
						$$ = $1;
2661
				}
2662 2663
		| USING any_name						{ $$ = $2; }
		| /*EMPTY*/								{ $$ = NIL; }
2664 2665
		;

2666 2667
/*****************************************************************************
 *
2668 2669
 *		QUERY:
 *				execute recipe <recipeName>
2670 2671 2672
 *
 *****************************************************************************/

Bruce Momjian's avatar
Bruce Momjian committed
2673
/* NOT USED
2674
RecipeStmt:  EXECUTE RECIPE recipe_name
2675
				{
2676
					RecipeStmt *n = makeNode(RecipeStmt);
2677 2678 2679 2680
					n->recipeName = $3;
					$$ = (Node *)n;
				}
		;
Bruce Momjian's avatar
Bruce Momjian committed
2681
*/
2682 2683 2684

/*****************************************************************************
 *
2685
 *		QUERY:
2686
 *				create [or replace] function <fname>
2687 2688 2689
 *						[(<type-1> { , <type-n>})]
 *						returns <type-r>
 *						as <filename or code in language as appropriate>
2690
 *						language <lang> [with parameters]
2691 2692 2693
 *
 *****************************************************************************/

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

2708 2709 2710 2711
opt_or_replace:  OR REPLACE						{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
		;

2712
opt_with:  WITH definition						{ $$ = $2; }
2713
		| /*EMPTY*/								{ $$ = NIL; }
2714 2715
		;

2716
func_args:  '(' func_args_list ')'				{ $$ = $2; }
2717
		| '(' ')'								{ $$ = NIL; }
2718
		;
2719

2720
func_args_list:  func_arg
2721
				{	$$ = makeList1($1); }
2722
		| func_args_list ',' func_arg
2723
				{	$$ = lappend($1, $3); }
2724 2725
		;

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

2740 2741 2742 2743 2744 2745
opt_arg:  IN
				{
					$$ = FALSE;
				}
		| OUT
				{
2746
					elog(ERROR, "CREATE FUNCTION / OUT parameters are not supported");
2747 2748 2749 2750
					$$ = TRUE;
				}
		| INOUT
				{
2751
					elog(ERROR, "CREATE FUNCTION / INOUT parameters are not supported");
2752 2753 2754 2755
					$$ = FALSE;
				}
		;

2756
func_as: Sconst
2757
				{   $$ = makeList1(makeString($1)); }
2758
		| Sconst ',' Sconst
2759
				{ 	$$ = makeList2(makeString($1), makeString($3)); }
2760 2761
		;

2762
func_return:  func_type
2763
				{
2764 2765 2766 2767 2768 2769
					/* 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;
				}
2770 2771
		;

2772
/*
2773
 * We would like to make the second production here be ColId attrs etc,
2774
 * but that causes reduce/reduce conflicts.  type_name is next best choice.
2775
 */
2776 2777 2778 2779
func_type:	Typename
				{
					$$ = $1;
				}
2780
		| type_name attrs '%' TYPE_P
2781 2782
				{
					$$ = makeNode(TypeName);
2783 2784
					$$->names = lcons(makeString($1), $2);
					$$->pct_type = true;
2785 2786 2787
					$$->typmod = -1;
				}
		;
2788 2789 2790

/*****************************************************************************
 *
2791
 *		QUERY:
2792
 *
2793
 *		DROP FUNCTION funcname (arg1, arg2, ...)
2794
 *		DROP AGGREGATE aggname (aggtype)
2795
 *		DROP OPERATOR opname (leftoperand_typ rightoperand_typ)
2796 2797 2798
 *
 *****************************************************************************/

2799
RemoveFuncStmt:  DROP FUNCTION func_name func_args
2800
				{
2801 2802 2803
					RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
					n->funcname = $3;
					n->args = $4;
2804 2805 2806 2807
					$$ = (Node *)n;
				}
		;

2808 2809 2810 2811
RemoveAggrStmt:  DROP AGGREGATE func_name '(' aggr_argtype ')'
				{
						RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
						n->aggname = $3;
2812
						n->aggtype = $5;
2813 2814 2815 2816
						$$ = (Node *)n;
				}
		;

2817
aggr_argtype:  Typename							{ $$ = $1; }
2818
		| '*'									{ $$ = NULL; }
2819
		;
2820

2821
RemoveOperStmt:  DROP OPERATOR any_operator '(' oper_argtypes ')'
2822 2823 2824 2825 2826 2827 2828
				{
					RemoveOperStmt *n = makeNode(RemoveOperStmt);
					n->opname = $3;
					n->args = $5;
					$$ = (Node *)n;
				}
		;
2829

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

2842 2843 2844 2845 2846 2847
any_operator: all_Op
			{ $$ = makeList1(makeString($1)); }
		| ColId '.' any_operator
			{ $$ = lcons(makeString($1), $3); }
		;

2848

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

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

2877 2878
reindex_type:  INDEX								{  $$ = INDEX; }
		| TABLE										{  $$ = TABLE; }
Hiroshi Inoue's avatar
Hiroshi Inoue committed
2879
		;
2880

Hiroshi Inoue's avatar
Hiroshi Inoue committed
2881 2882 2883 2884 2885
opt_force:	FORCE									{  $$ = TRUE; }
		| /* EMPTY */								{  $$ = FALSE; }
		;


2886 2887
/*****************************************************************************
 *
2888 2889 2890
 *		QUERY:
 *				rename <attrname1> in <relname> [*] to <attrname2>
 *				rename <relname1> to <relname2>
2891
 *
2892 2893
 *****************************************************************************/

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

opt_name:  name							{ $$ = $1; }
2905
		| /*EMPTY*/						{ $$ = NULL; }
2906 2907 2908 2909 2910
		;

opt_column:  COLUMN						{ $$ = COLUMN; }
		| /*EMPTY*/						{ $$ = 0; }
		;
2911 2912 2913


/*****************************************************************************
2914
 *
2915
 *		QUERY:	Define Rewrite Rule
2916
 *
2917 2918
 *****************************************************************************/

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

2936 2937 2938
RuleActionList:  NOTHING				{ $$ = NIL; }
		| RuleActionStmt				{ $$ = makeList1($1); }
		| '(' RuleActionMulti ')'		{ $$ = $2; } 
2939
		;
2940

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

2956
RuleActionStmt:	SelectStmt
2957
		| InsertStmt
2958 2959 2960 2961 2962
		| UpdateStmt
		| DeleteStmt
		| NotifyStmt
		;

2963 2964 2965 2966 2967
RuleActionStmtOrEmpty:	RuleActionStmt
		|	/*EMPTY*/
				{ $$ = (Node *)NULL; }
		;

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

2975
opt_instead:  INSTEAD					{ $$ = TRUE; }
2976
		| /*EMPTY*/						{ $$ = FALSE; }
2977
		;
2978 2979 2980 2981


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

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

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

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

3020 3021 3022

/*****************************************************************************
 *
3023
 *		Transactions:
3024
 *
3025 3026
 *      BEGIN / COMMIT / ROLLBACK
 *      (also older versions END / ABORT)
3027
 *
3028 3029
 *****************************************************************************/

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

3074 3075 3076
opt_trans: WORK									{ $$ = TRUE; }
		| TRANSACTION							{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = TRUE; }
3077
		;
3078

3079 3080 3081 3082 3083 3084 3085 3086
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
					 */
3087
					elog(ERROR, "COMMIT / CHAIN not yet supported");
3088 3089 3090 3091
					$$ = TRUE;
				}
		;

3092 3093 3094

/*****************************************************************************
 *
3095 3096
 *		QUERY:
 *				define view <viewname> '('target-list ')' [where <quals> ]
3097 3098 3099
 *
 *****************************************************************************/

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


/*****************************************************************************
 *
3113 3114
 *		QUERY:
 *				load "filename"
3115 3116 3117
 *
 *****************************************************************************/

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


/*****************************************************************************
 *
3129 3130
 *		CREATE DATABASE
 *
3131 3132
 *****************************************************************************/

3133
CreatedbStmt:  CREATE DATABASE database_name WITH createdb_opt_list
3134
				{
3135
					CreatedbStmt *n = makeNode(CreatedbStmt);
3136
					List   *l;
3137

3138
					n->dbname = $3;
3139
					/* set default options */
3140
					n->dbowner = NULL;
3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159
					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;
3160 3161 3162
							case 4:
								n->dbowner = (char *) lsecond(optitem);
								break;
3163 3164
						}
					}
3165 3166
					$$ = (Node *)n;
				}
3167 3168 3169 3170
		| CREATE DATABASE database_name
				{
					CreatedbStmt *n = makeNode(CreatedbStmt);
					n->dbname = $3;
3171
					n->dbowner = NULL;
3172
					n->dbpath = NULL;
3173 3174
					n->dbtemplate = NULL;
					n->encoding = -1;
3175 3176 3177 3178
					$$ = (Node *)n;
				}
		;

3179 3180 3181 3182
createdb_opt_list:  createdb_opt_item
				{ $$ = makeList1($1); }
		| createdb_opt_list createdb_opt_item
				{ $$ = lappend($1, $2); }
3183 3184
		;

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

Tom Lane's avatar
Tom Lane committed
3244 3245 3246 3247 3248 3249 3250 3251
/*
 *	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; }
		;

3252

3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276
/*****************************************************************************
 *
 *		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;
				}
		;

3277

3278 3279
/*****************************************************************************
 *
3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293
 *		DROP DATABASE
 *
 *****************************************************************************/

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


/*****************************************************************************
3294
 *
3295
 * Manipulate a domain
3296 3297 3298
 *
 *****************************************************************************/

3299
CreateDomainStmt:  CREATE DOMAIN_P any_name opt_as Typename ColQualList opt_collate
3300
				{
3301 3302 3303 3304 3305 3306 3307 3308
					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);
3309 3310 3311
					$$ = (Node *)n;
				}
		;
3312

3313 3314 3315
opt_as:	AS	{$$ = TRUE; }
	| /* EMPTY */	{$$ = FALSE; }
	;
3316

3317

3318 3319
/*****************************************************************************
 *
3320
 *		QUERY:
3321
 *				cluster <index_name> on <qualified_name>
3322 3323 3324
 *
 *****************************************************************************/

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

/*****************************************************************************
 *
3336 3337
 *		QUERY:
 *				vacuum
3338
 *				analyze
3339 3340 3341
 *
 *****************************************************************************/

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

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

3403
analyze_keyword:  ANALYZE						{ $$ = TRUE; }
3404
		|	  ANALYSE /* British */				{ $$ = TRUE; }
3405
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
3406

3407 3408
opt_verbose:  VERBOSE							{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
3409
		;
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
3410

3411 3412 3413 3414
opt_full:  FULL									{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
		;

3415 3416 3417 3418
opt_freeze:  FREEZE								{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
		;

3419 3420
opt_name_list:  '(' name_list ')'				{ $$ = $2; }
		| /*EMPTY*/								{ $$ = NIL; }
3421
		;
3422

3423

3424 3425
/*****************************************************************************
 *
3426 3427
 *		QUERY:
 *				EXPLAIN query
3428
 *				EXPLAIN ANALYZE query
3429 3430 3431
 *
 *****************************************************************************/

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

3450

3451
/*****************************************************************************
3452 3453 3454 3455 3456 3457 3458 3459
 *																			 *
 *		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							 *
 *																			 *
3460 3461
 *****************************************************************************/

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


/*****************************************************************************
 *
3472 3473
 *		QUERY:
 *				INSERT STATEMENTS
3474
 *
3475 3476
 *****************************************************************************/

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

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

3521
insert_column_list:  insert_column_list ',' insert_column_item
3522
				{ $$ = lappend($1, $3); }
3523
		| insert_column_item
3524
				{ $$ = makeList1($1); }
3525
		;
3526

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

3537

3538 3539
/*****************************************************************************
 *
3540 3541
 *		QUERY:
 *				DELETE STATEMENTS
3542 3543
 *
 *****************************************************************************/
3544

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

3554
LockStmt:	LOCK_P opt_table qualified_name_list opt_lock
3555
				{
3556 3557
					LockStmt *n = makeNode(LockStmt);

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

3564
opt_lock:  IN lock_type MODE	{ $$ = $2; }
3565 3566
		| /*EMPTY*/				{ $$ = AccessExclusiveLock; }
		;
3567

3568 3569 3570 3571 3572 3573 3574 3575
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; }
3576
		;
3577

3578

3579 3580
/*****************************************************************************
 *
3581
 *		QUERY:
Bruce Momjian's avatar
Bruce Momjian committed
3582
 *				UpdateStmt (UPDATE)
3583 3584 3585
 *
 *****************************************************************************/

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

3600 3601 3602

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

3616 3617 3618 3619 3620 3621 3622
opt_cursor:  BINARY						{ $$ = TRUE; }
		| INSENSITIVE					{ $$ = FALSE; }
		| SCROLL						{ $$ = FALSE; }
		| INSENSITIVE SCROLL			{ $$ = FALSE; }
		| /*EMPTY*/						{ $$ = FALSE; }
		;

3623 3624
/*****************************************************************************
 *
3625 3626
 *		QUERY:
 *				SELECT STATEMENTS
3627 3628
 *
 *****************************************************************************/
3629

3630 3631 3632 3633 3634
/* 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.
 *
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 3663 3664 3665
 * 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.
3666 3667
 */

3668 3669 3670 3671 3672
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
3673
			{
3674
				$$ = $2;
3675
			}
3676
		| '(' select_with_parens ')'
3677 3678 3679 3680
			{
				$$ = $2;
			}
		;
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3681

3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701
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));
3702
				$$ = $1;
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
3703
			}
3704
		;
3705

3706
select_clause: simple_select
3707
		| select_with_parens
3708
		;
3709

3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724
/*
 * 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)
3725 3726 3727 3728
 * 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.
3729 3730 3731 3732 3733 3734
 *
 * 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
3735
			 group_clause having_clause
3736
				{
Bruce Momjian's avatar
Bruce Momjian committed
3737
					SelectStmt *n = makeNode(SelectStmt);
3738
					n->distinctClause = $2;
3739
					n->targetList = $3;
3740
					n->into = $4;
3741
					n->intoColNames = NIL;
3742 3743 3744 3745 3746 3747
					n->fromClause = $5;
					n->whereClause = $6;
					n->groupClause = $7;
					n->havingClause = $8;
					$$ = (Node *)n;
				}
3748
		| select_clause UNION opt_all select_clause
3749
			{	
3750
				$$ = makeSetOp(SETOP_UNION, $3, $1, $4);
3751
			}
3752
		| select_clause INTERSECT opt_all select_clause
3753
			{
3754
				$$ = makeSetOp(SETOP_INTERSECT, $3, $1, $4);
3755
			}
3756
		| select_clause EXCEPT opt_all select_clause
3757
			{
3758
				$$ = makeSetOp(SETOP_EXCEPT, $3, $1, $4);
3759 3760
			}
		; 
3761

3762
into_clause:  INTO OptTempTableName		{ $$ = $2; }
3763
		| /*EMPTY*/		{ $$ = NULL; }
3764 3765 3766 3767 3768 3769
		;

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

opt_table:  TABLE								{ $$ = TRUE; }
		| /*EMPTY*/								{ $$ = FALSE; }
3816
		;
3817

3818
opt_all:  ALL									{ $$ = TRUE; }
3819 3820 3821
		| /*EMPTY*/								{ $$ = FALSE; }
		;

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

3831 3832
sort_clause:  ORDER BY sortby_list				{ $$ = $3; }
		;
3833

3834
sortby_list:  sortby							{ $$ = makeList1($1); }
3835
		| sortby_list ',' sortby				{ $$ = lappend($1, $3); }
3836
		;
3837

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

3846 3847 3848 3849 3850 3851 3852 3853
OptUseOp:  USING qual_all_Op
				{ $$ = $2; }
		| ASC
				{ $$ = makeList1(makeString("<")); }
		| DESC
				{ $$ = makeList1(makeString(">")); }
		| /*EMPTY*/
				{ $$ = makeList1(makeString("<"));	/*default*/ }
3854
		;
3855

3856

3857
select_limit:	LIMIT select_limit_value OFFSET select_offset_value
3858
			{ $$ = makeList2($4, $2); }
3859
		| OFFSET select_offset_value LIMIT select_limit_value
3860
			{ $$ = makeList2($2, $4); }
3861 3862
		| LIMIT select_limit_value
			{ $$ = makeList2(NULL, $2); }
3863
		| OFFSET select_offset_value
3864
			{ $$ = makeList2($2, NULL); }
3865 3866 3867
		| 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."); }
3868 3869
		;

3870

3871 3872
opt_select_limit:	select_limit				{ $$ = $1; }
		| /* EMPTY */							{ $$ = makeList2(NULL,NULL); }
3873 3874
		;

3875
select_limit_value:  Iconst
3876 3877 3878
			{
				Const	*n = makeNode(Const);

3879 3880
				if ($1 < 0)
					elog(ERROR, "LIMIT must not be negative");
3881 3882 3883

				n->consttype	= INT4OID;
				n->constlen		= sizeof(int4);
3884
				n->constvalue	= Int32GetDatum($1);
3885 3886 3887 3888 3889 3890 3891 3892
				n->constisnull	= FALSE;
				n->constbyval	= TRUE;
				n->constisset	= FALSE;
				n->constiscast	= FALSE;
				$$ = (Node *)n;
			}
		| ALL
			{
3893
				/* LIMIT ALL is represented as a NULL constant */
3894 3895 3896 3897
				Const	*n = makeNode(Const);

				n->consttype	= INT4OID;
				n->constlen		= sizeof(int4);
3898 3899
				n->constvalue	= (Datum) 0;
				n->constisnull	= TRUE;
3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919
				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);

3920 3921 3922
				if ($1 < 0)
					elog(ERROR, "OFFSET must not be negative");

3923 3924
				n->consttype	= INT4OID;
				n->constlen		= sizeof(int4);
3925
				n->constvalue	= Int32GetDatum($1);
3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941
				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;
			}
		;
3942

3943
/*
3944 3945
 *	jimmy bell-style recursive queries aren't supported in the
 *	current system.
3946
 *
3947 3948
 *	...however, recursive addattr and rename supported.  make special
 *	cases for these.
3949 3950
 */

3951
group_clause:  GROUP BY expr_list				{ $$ = $3; }
3952 3953
		| /*EMPTY*/								{ $$ = NIL; }
		;
3954

Bruce Momjian's avatar
Bruce Momjian committed
3955 3956
having_clause:  HAVING a_expr
				{
3957
					$$ = $2;
Bruce Momjian's avatar
Bruce Momjian committed
3958
				}
3959 3960
		| /*EMPTY*/								{ $$ = NULL; }
		;
3961

3962
for_update_clause:  FOR UPDATE update_list		{ $$ = $3; }
Jan Wieck's avatar
Jan Wieck committed
3963
		| FOR READ ONLY							{ $$ = NULL; }
3964 3965 3966
		;

opt_for_update_clause:	for_update_clause		{ $$ = $1; }
3967 3968 3969
		| /* EMPTY */							{ $$ = NULL; }
		;

3970
update_list:  OF name_list						{ $$ = $2; }
3971
		| /* EMPTY */							{ $$ = makeList1(NULL); }
Vadim B. Mikheev's avatar
Vadim B. Mikheev committed
3972
		;
3973

3974
/*****************************************************************************
3975
 *
3976
 *	clauses common to all Optimizable Stmts:
3977 3978
 *		from_clause		- allow list of both JOIN expressions and table names
 *		where_clause	- qualifications for joins or restrictions
3979
 *
3980 3981
 *****************************************************************************/

3982
from_clause:  FROM from_list					{ $$ = $2; }
3983 3984 3985
		| /*EMPTY*/								{ $$ = NIL; }
		;

3986
from_list:  from_list ',' table_ref				{ $$ = lappend($1, $3); }
3987
		| table_ref								{ $$ = makeList1($1); }
3988 3989
		;

3990 3991 3992 3993 3994 3995 3996 3997
/*
 * 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
3998
				{
3999
					$$ = (Node *) $1;
4000
				}
4001
		| relation_expr alias_clause
4002
				{
4003
					$1->alias = $2;
4004
					$$ = (Node *) $1;
4005
				}
4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022
		| 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;
				}
4023
		| select_with_parens alias_clause
4024
				{
4025
					RangeSubselect *n = makeNode(RangeSubselect);
4026
					n->subquery = $1;
4027
					n->alias = $2;
4028
					$$ = (Node *) n;
4029
				}
4030
		| joined_table
4031
				{
4032
					$$ = (Node *) $1;
4033
				}
4034
		| '(' joined_table ')' alias_clause
4035
				{
4036 4037
					$2->alias = $4;
					$$ = (Node *) $2;
4038 4039 4040
				}
		;

4041 4042 4043 4044 4045 4046 4047 4048 4049
/*
 * 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.
 *
4050
 * Note that a CROSS JOIN is the same as an unqualified
4051 4052
 * INNER JOIN, and an INNER JOIN/ON has the same shape
 * but a qualification expression to limit membership.
4053
 * A NATURAL JOIN implicitly matches column names between
4054 4055
 * tables and the shape is determined by which columns are
 * in common. We'll collect columns during the later transformations.
4056
 */
4057 4058 4059 4060 4061 4062

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

4140 4141
alias_clause:  AS ColId '(' name_list ')'
				{
4142 4143 4144
					$$ = makeNode(Alias);
					$$->aliasname = $2;
					$$->colnames = $4;
4145 4146 4147
				}
		| AS ColId
				{
4148 4149
					$$ = makeNode(Alias);
					$$->aliasname = $2;
4150 4151 4152
				}
		| ColId '(' name_list ')'
				{
4153 4154 4155
					$$ = makeNode(Alias);
					$$->aliasname = $1;
					$$->colnames = $3;
4156 4157 4158
				}
		| ColId
				{
4159 4160
					$$ = makeNode(Alias);
					$$->aliasname = $1;
4161
				}
4162 4163
		;

4164 4165 4166 4167
join_type:  FULL join_outer						{ $$ = JOIN_FULL; }
		| LEFT join_outer						{ $$ = JOIN_LEFT; }
		| RIGHT join_outer						{ $$ = JOIN_RIGHT; }
		| INNER_P								{ $$ = JOIN_INNER; }
4168 4169
		;

4170
/* OUTER is just noise... */
4171
join_outer:  OUTER_P							{ $$ = NULL; }
4172
		| /*EMPTY*/								{ $$ = NULL; }
4173 4174
		;

4175 4176 4177 4178 4179
/* JOIN qualification clauses
 * Possibilities are:
 *  USING ( column list ) allows only unqualified column names,
 *                        which must match between tables.
 *  ON expr allows more general qualifications.
4180 4181
 *
 * We return USING as a List node, while an ON-expr will not be a List.
4182 4183
 */

4184 4185
join_qual:  USING '(' name_list ')'				{ $$ = (Node *) $3; }
		| ON a_expr								{ $$ = $2; }
4186 4187 4188
		;


4189
relation_expr:	qualified_name
4190
				{
4191
					/* default inheritance */
4192
					$$ = $1;
4193
					$$->inhOpt = INH_DEFAULT;
4194
					$$->alias = NULL;
4195
				}
4196
		| qualified_name '*'
4197
				{
4198
					/* inheritance query */
4199
					$$ = $1;
4200
					$$->inhOpt = INH_YES;
4201
					$$->alias = NULL;
4202
				}
4203
		| ONLY qualified_name
4204
				{
4205
					/* no inheritance */
4206
					$$ = $2;
4207
					$$->inhOpt = INH_NO;
4208
					$$->alias = NULL;
4209
                }
4210
		;
4211

4212 4213
where_clause:  WHERE a_expr						{ $$ = $2; }
		| /*EMPTY*/								{ $$ = NULL;  /* no qualifiers */ }
4214
		;
4215

4216

4217 4218 4219 4220 4221 4222 4223 4224 4225 4226
/*****************************************************************************
 *
 *	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
 *
 *****************************************************************************/

4227
Typename:  SimpleTypename opt_array_bounds
4228 4229 4230
				{
					$$ = $1;
					$$->arrayBounds = $2;
4231
				}
4232
		| SETOF SimpleTypename
4233
				{
4234
					$$ = $2;
4235 4236 4237 4238
					$$->setof = TRUE;
				}
		;

4239 4240 4241 4242
opt_array_bounds:	opt_array_bounds '[' ']'
				{  $$ = lappend($1, makeInteger(-1)); }
		| opt_array_bounds '[' Iconst ']'
				{  $$ = lappend($1, makeInteger($3)); }
4243 4244 4245 4246
		| /*EMPTY*/
				{  $$ = NIL; }
		;

4247 4248 4249 4250 4251 4252 4253 4254
/*
 * XXX ideally, the production for a qualified typename should be ColId attrs
 * (there's no obvious reason why the first name should need to be restricted)
 * and should be an alternative of GenericType (so that it can be used to
 * specify a type for a literal in AExprConst).  However doing either causes
 * reduce/reduce conflicts that I haven't been able to find a workaround
 * for.  FIXME later.
 */
4255
SimpleTypename:  ConstTypename
4256 4257 4258
		| ConstInterval opt_interval
				{
					$$ = $1;
4259 4260
					if ($2 != -1)
						$$->typmod = ((($2 & 0x7FFF) << 16) | 0xFFFF);
4261 4262 4263 4264
				}
		| ConstInterval '(' Iconst ')' opt_interval
				{
					$$ = $1;
4265
					$$->typmod = ((($5 & 0x7FFF) << 16) | $3);
4266
				}
4267 4268 4269 4270 4271 4272
		| type_name attrs
				{
					$$ = makeNode(TypeName);
					$$->names = lcons(makeString($1), $2);
					$$->typmod = -1;
				}
4273 4274
		;

4275
ConstTypename:  GenericType
4276
		| Numeric
4277
		| Bit
4278
		| Character
4279
		| ConstDatetime
4280
		;
4281

4282
GenericType:  type_name
4283
				{
4284
					$$ = makeTypeName(xlateSqlType($1));
4285 4286 4287 4288 4289
				}
		;

/* SQL92 numeric data types
 * Check FLOAT() precision limits assuming IEEE floating types.
4290
 * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
4291 4292 4293 4294
 * - thomas 1997-09-18
 */
Numeric:  FLOAT opt_float
				{
4295
					$$ = makeTypeName($2); /* already xlated */
4296
				}
4297 4298
		| DOUBLE PRECISION
				{
4299
					$$ = makeTypeName(xlateSqlType("float8"));
4300
				}
4301
		| DECIMAL opt_decimal
4302
				{
4303
					$$ = makeTypeName(xlateSqlType("decimal"));
4304 4305 4306
					$$->typmod = $2;
				}
		| DEC opt_decimal
4307
				{
4308
					$$ = makeTypeName(xlateSqlType("decimal"));
4309
					$$->typmod = $2;
4310 4311 4312
				}
		| NUMERIC opt_numeric
				{
4313
					$$ = makeTypeName(xlateSqlType("numeric"));
4314
					$$->typmod = $2;
4315 4316
				}
		;
4317

4318 4319 4320
opt_float:  '(' Iconst ')'
				{
					if ($2 < 1)
Bruce Momjian's avatar
Bruce Momjian committed
4321
						elog(ERROR,"precision for FLOAT must be at least 1");
4322 4323 4324 4325 4326
					else if ($2 < 7)
						$$ = xlateSqlType("float4");
					else if ($2 < 16)
						$$ = xlateSqlType("float8");
					else
Bruce Momjian's avatar
Bruce Momjian committed
4327
						elog(ERROR,"precision for FLOAT must be less than 16");
4328 4329 4330 4331 4332 4333 4334 4335 4336
				}
		| /*EMPTY*/
				{
					$$ = xlateSqlType("float8");
				}
		;

opt_numeric:  '(' Iconst ',' Iconst ')'
				{
4337
					if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
4338
						elog(ERROR,"NUMERIC precision %d must be between 1 and %d",
4339
							 $2, NUMERIC_MAX_PRECISION);
4340 4341
					if ($4 < 0 || $4 > $2)
						elog(ERROR,"NUMERIC scale %d must be between 0 and precision %d",
4342
							 $4,$2);
4343 4344

					$$ = (($2 << 16) | $4) + VARHDRSZ;
4345 4346 4347
				}
		| '(' Iconst ')'
				{
4348
					if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
4349
						elog(ERROR,"NUMERIC precision %d must be between 1 and %d",
4350
							 $2, NUMERIC_MAX_PRECISION);
4351 4352

					$$ = ($2 << 16) + VARHDRSZ;
4353 4354 4355
				}
		| /*EMPTY*/
				{
4356
					/* Insert "-1" meaning "no limit" */
4357
					$$ = -1;
4358 4359 4360 4361 4362
				}
		;

opt_decimal:  '(' Iconst ',' Iconst ')'
				{
4363
					if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
4364
						elog(ERROR,"DECIMAL precision %d must be between 1 and %d",
4365 4366 4367 4368 4369 4370
									$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;
4371 4372 4373
				}
		| '(' Iconst ')'
				{
4374
					if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
4375
						elog(ERROR,"DECIMAL precision %d must be between 1 and %d",
4376 4377 4378
									$2, NUMERIC_MAX_PRECISION);

					$$ = ($2 << 16) + VARHDRSZ;
4379 4380 4381
				}
		| /*EMPTY*/
				{
4382
					/* Insert "-1" meaning "no limit" */
4383
					$$ = -1;
4384 4385 4386
				}
		;

4387

4388 4389 4390 4391 4392 4393
/*
 * SQL92 bit-field data types
 * The following implements BIT() and BIT VARYING().
 */
Bit:  bit '(' Iconst ')'
				{
4394
					$$ = makeTypeName($1);
4395
					if ($3 < 1)
4396 4397
						elog(ERROR,"length for type '%s' must be at least 1",
							 $1);
4398
					else if ($3 > (MaxAttrSize * BITS_PER_BYTE))
4399
						elog(ERROR,"length for type '%s' cannot exceed %d",
4400
							 $1, (MaxAttrSize * BITS_PER_BYTE));
4401 4402 4403 4404
					$$->typmod = $3;
				}
		| bit
				{
4405
					$$ = makeTypeName($1);
4406 4407 4408 4409 4410
					/* bit defaults to bit(1), varbit to no limit */
					if (strcmp($1, "bit") == 0)
						$$->typmod = 1;
					else
						$$->typmod = -1;
4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421
				}
		;

bit:  BIT opt_varying
				{
					char *type;

					if ($2) type = xlateSqlType("varbit");
					else type = xlateSqlType("bit");
					$$ = type;
				}
4422
		;
4423 4424


4425 4426
/*
 * SQL92 character data types
4427 4428
 * The following implements CHAR() and VARCHAR().
 */
4429
Character:  character '(' Iconst ')' opt_charset
4430
				{
4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443
					if (($5 != NULL) && (strcmp($5, "sql_text") != 0))
					{
						char *type;

						type = palloc(strlen($1) + 1 + strlen($5) + 1);
						strcpy(type, $1);
						strcat(type, "_");
						strcat(type, $5);
						$1 = xlateSqlType(type);
					}

					$$ = makeTypeName($1);

4444
					if ($3 < 1)
4445 4446
						elog(ERROR,"length for type '%s' must be at least 1",
							 $1);
4447
					else if ($3 > MaxAttrSize)
4448 4449
						elog(ERROR,"length for type '%s' cannot exceed %d",
							 $1, MaxAttrSize);
4450

4451
					/* we actually implement these like a varlen, so
4452
					 * the first 4 bytes is the length. (the difference
4453 4454
					 * between these and "text" is that we blank-pad and
					 * truncate where necessary)
4455
					 */
4456
					$$->typmod = VARHDRSZ + $3;
4457
				}
4458
		| character opt_charset
4459
				{
4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472
					if (($2 != NULL) && (strcmp($2, "sql_text") != 0))
					{
						char *type;

						type = palloc(strlen($1) + 1 + strlen($2) + 1);
						strcpy(type, $1);
						strcat(type, "_");
						strcat(type, $2);
						$1 = xlateSqlType(type);
					}

					$$ = makeTypeName($1);

4473 4474 4475 4476 4477
					/* char defaults to char(1), varchar to no limit */
					if (strcmp($1, "bpchar") == 0)
						$$->typmod = VARHDRSZ + 1;
					else
						$$->typmod = -1;
4478
				}
4479 4480 4481
		;

character:  CHARACTER opt_varying				{ $$ = xlateSqlType($2 ? "varchar": "bpchar"); }
4482
		| CHAR opt_varying						{ $$ = xlateSqlType($2 ? "varchar": "bpchar"); }
4483
		| VARCHAR								{ $$ = xlateSqlType("varchar"); }
4484 4485 4486
		| NATIONAL CHARACTER opt_varying		{ $$ = xlateSqlType($3 ? "varchar": "bpchar"); }
		| NATIONAL CHAR opt_varying				{ $$ = xlateSqlType($3 ? "varchar": "bpchar"); }
		| NCHAR opt_varying						{ $$ = xlateSqlType($2 ? "varchar": "bpchar"); }
4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500
		;

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

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

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

4501
ConstDatetime:  TIMESTAMP '(' Iconst ')' opt_timezone_x
4502 4503
				{
					if ($5)
4504
						$$ = makeTypeName(xlateSqlType("timestamptz"));
4505
					else
4506
						$$ = makeTypeName(xlateSqlType("timestamp"));
4507 4508 4509 4510 4511
					/* XXX the timezone field seems to be unused
					 * - thomas 2001-09-06
					 */
					$$->timezone = $5;
					if (($3 < 0) || ($3 > 13))
4512 4513
						elog(ERROR,"TIMESTAMP(%d)%s precision must be between %d and %d",
							 $3, ($5 ? " WITH TIME ZONE": ""), 0, 13);
4514 4515
					$$->typmod = $3;
				}
4516
		| TIMESTAMP opt_timezone_x
4517
				{
4518
					if ($2)
4519
						$$ = makeTypeName(xlateSqlType("timestamptz"));
4520
					else
4521
						$$ = makeTypeName(xlateSqlType("timestamp"));
4522 4523 4524
					/* XXX the timezone field seems to be unused
					 * - thomas 2001-09-06
					 */
4525
					$$->timezone = $2;
4526 4527 4528 4529 4530 4531
					/* 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
4532
					 */
4533
					$$->typmod = -1;
4534 4535 4536 4537
				}
		| TIME '(' Iconst ')' opt_timezone
				{
					if ($5)
4538
						$$ = makeTypeName(xlateSqlType("timetz"));
4539
					else
4540
						$$ = makeTypeName(xlateSqlType("time"));
4541
					if (($3 < 0) || ($3 > 13))
4542 4543
						elog(ERROR,"TIME(%d)%s precision must be between %d and %d",
							 $3, ($5 ? " WITH TIME ZONE": ""), 0, 13);
4544
					$$->typmod = $3;
4545
				}
4546
		| TIME opt_timezone
4547
				{
4548
					if ($2)
4549
						$$ = makeTypeName(xlateSqlType("timetz"));
4550
					else
4551
						$$ = makeTypeName(xlateSqlType("time"));
4552
					/* SQL99 specified a default precision of zero.
4553 4554
					 * See comments for timestamp above on why we will
					 * leave this unspecified for now. - thomas 2001-12-07
4555
					 */
4556
					$$->typmod = -1;
4557
				}
4558 4559
		;

4560
ConstInterval:  INTERVAL
4561
				{
4562
					$$ = makeTypeName(xlateSqlType("interval"));
4563
				}
4564
		;
4565

4566 4567 4568 4569 4570 4571 4572 4573 4574 4575
/* 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; }
		;

4576
opt_timezone:  WITH TIME ZONE					{ $$ = TRUE; }
4577
		| WITHOUT TIME ZONE						{ $$ = FALSE; }
4578 4579 4580
		| /*EMPTY*/								{ $$ = FALSE; }
		;

4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594
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; }
4595 4596
		;

4597 4598 4599

/*****************************************************************************
 *
4600
 *	expression grammar
4601 4602 4603
 *
 *****************************************************************************/

4604 4605 4606 4607
/* Expressions using row descriptors
 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
 *  with singleton expressions.
 */
4608
row_expr: '(' row_descriptor ')' IN select_with_parens
4609
				{
4610 4611
					SubLink *n = makeNode(SubLink);
					n->lefthand = $2;
4612
					n->oper = (List *) makeSimpleA_Expr(OP, "=", NULL, NULL);
4613
					n->useor = FALSE;
4614
					n->subLinkType = ANY_SUBLINK;
4615
					n->subselect = $5;
4616
					$$ = (Node *)n;
4617
				}
4618
		| '(' row_descriptor ')' NOT IN select_with_parens
4619
				{
4620 4621
					SubLink *n = makeNode(SubLink);
					n->lefthand = $2;
4622
					n->oper = (List *) makeSimpleA_Expr(OP, "<>", NULL, NULL);
4623
					n->useor = TRUE;
4624
					n->subLinkType = ALL_SUBLINK;
4625
					n->subselect = $6;
4626 4627
					$$ = (Node *)n;
				}
4628
		| '(' row_descriptor ')' qual_all_Op sub_type select_with_parens	%prec Op
4629 4630 4631
				{
					SubLink *n = makeNode(SubLink);
					n->lefthand = $2;
4632
					n->oper = (List *) makeA_Expr(OP, $4, NULL, NULL);
4633
					if (strcmp(strVal(llast($4)), "<>") == 0)
4634
						n->useor = TRUE;
4635
					else
4636
						n->useor = FALSE;
4637
					n->subLinkType = $5;
4638
					n->subselect = $6;
Bruce Momjian's avatar
Bruce Momjian committed
4639 4640
					$$ = (Node *)n;
				}
4641
		| '(' row_descriptor ')' qual_all_Op select_with_parens		%prec Op
Bruce Momjian's avatar
Bruce Momjian committed
4642 4643 4644
				{
					SubLink *n = makeNode(SubLink);
					n->lefthand = $2;
4645
					n->oper = (List *) makeA_Expr(OP, $4, NULL, NULL);
4646
					if (strcmp(strVal(llast($4)), "<>") == 0)
4647
						n->useor = TRUE;
4648
					else
4649
						n->useor = FALSE;
4650
					n->subLinkType = MULTIEXPR_SUBLINK;
4651
					n->subselect = $5;
Bruce Momjian's avatar
Bruce Momjian committed
4652 4653
					$$ = (Node *)n;
				}
4654
		| '(' row_descriptor ')' qual_all_Op '(' row_descriptor ')'		%prec Op
4655
				{
Bruce Momjian's avatar
Bruce Momjian committed
4656
					$$ = makeRowExpr($4, $2, $6);
4657
				}
4658 4659 4660 4661 4662
		| '(' row_descriptor ')' OVERLAPS '(' row_descriptor ')'
				{
					FuncCall *n = makeNode(FuncCall);
					List *largs = $2;
					List *rargs = $6;
4663
					n->funcname = SystemFuncName("overlaps");
4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674
					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);
4675 4676
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
4677 4678
					$$ = (Node *)n;
				}
4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692
		;

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

row_list:  row_list ',' a_expr
				{
					$$ = lappend($1, $3);
				}
		| a_expr
				{
4693
					$$ = makeList1($1);
4694 4695
				}
		;
4696

4697
sub_type:  ANY								{ $$ = ANY_SUBLINK; }
4698
		| SOME								{ $$ = ANY_SUBLINK; }
4699 4700 4701
		| ALL								{ $$ = ALL_SUBLINK; }
		;

4702 4703
all_Op:  Op | MathOp;

4704
MathOp:  '+'			{ $$ = "+"; }
4705 4706 4707 4708 4709 4710 4711 4712 4713 4714
		| '-'			{ $$ = "-"; }
		| '*'			{ $$ = "*"; }
		| '/'			{ $$ = "/"; }
		| '%'			{ $$ = "%"; }
		| '^'			{ $$ = "^"; }
		| '<'			{ $$ = "<"; }
		| '>'			{ $$ = ">"; }
		| '='			{ $$ = "="; }
		;

4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726
qual_Op:  Op
			{ $$ = makeList1(makeString($1)); }
		|  OPERATOR '(' any_operator ')'
			{ $$ = $3; }
		;

qual_all_Op:  all_Op
			{ $$ = makeList1(makeString($1)); }
		|  OPERATOR '(' any_operator ')'
			{ $$ = $3; }
		;

4727 4728
/*
 * General expressions
4729
 * This is the heart of the expression syntax.
4730 4731 4732 4733 4734 4735 4736 4737 4738 4739
 *
 * 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.
 *
4740
 * c_expr is all the productions that are common to a_expr and b_expr;
4741
 * it's factored out just to eliminate redundant coding.
4742
 */
4743
a_expr:  c_expr
4744
				{	$$ = $1;  }
4745
		| a_expr TYPECAST Typename
4746
				{	$$ = makeTypeCast($1, $3); }
4747 4748 4749
		| a_expr AT TIME ZONE c_expr
				{
					FuncCall *n = makeNode(FuncCall);
4750
					n->funcname = SystemFuncName("timezone");
4751 4752 4753 4754 4755
					n->args = makeList2($5, $1);
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
					$$ = (Node *) n;
				}
4756 4757 4758 4759 4760 4761 4762 4763 4764
		/*
		 * 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.
		 */
4765
		| '+' a_expr					%prec UMINUS
4766
				{	$$ = (Node *) makeSimpleA_Expr(OP, "+", NULL, $2); }
4767
		| '-' a_expr					%prec UMINUS
4768
				{	$$ = doNegate($2); }
Bruce Momjian's avatar
Bruce Momjian committed
4769
		| '%' a_expr
4770
				{	$$ = (Node *) makeSimpleA_Expr(OP, "%", NULL, $2); }
Bruce Momjian's avatar
Bruce Momjian committed
4771
		| '^' a_expr
4772
				{	$$ = (Node *) makeSimpleA_Expr(OP, "^", NULL, $2); }
Bruce Momjian's avatar
Bruce Momjian committed
4773
		| a_expr '%'
4774
				{	$$ = (Node *) makeSimpleA_Expr(OP, "%", $1, NULL); }
Bruce Momjian's avatar
Bruce Momjian committed
4775
		| a_expr '^'
4776
				{	$$ = (Node *) makeSimpleA_Expr(OP, "^", $1, NULL); }
4777
		| a_expr '+' a_expr
4778
				{	$$ = (Node *) makeSimpleA_Expr(OP, "+", $1, $3); }
4779
		| a_expr '-' a_expr
4780
				{	$$ = (Node *) makeSimpleA_Expr(OP, "-", $1, $3); }
4781
		| a_expr '*' a_expr
4782
				{	$$ = (Node *) makeSimpleA_Expr(OP, "*", $1, $3); }
4783
		| a_expr '/' a_expr
4784
				{	$$ = (Node *) makeSimpleA_Expr(OP, "/", $1, $3); }
4785
		| a_expr '%' a_expr
4786
				{	$$ = (Node *) makeSimpleA_Expr(OP, "%", $1, $3); }
Bruce Momjian's avatar
Bruce Momjian committed
4787
		| a_expr '^' a_expr
4788
				{	$$ = (Node *) makeSimpleA_Expr(OP, "^", $1, $3); }
4789
		| a_expr '<' a_expr
4790
				{	$$ = (Node *) makeSimpleA_Expr(OP, "<", $1, $3); }
4791
		| a_expr '>' a_expr
4792
				{	$$ = (Node *) makeSimpleA_Expr(OP, ">", $1, $3); }
4793
		| a_expr '=' a_expr
4794
				{	$$ = (Node *) makeSimpleA_Expr(OP, "=", $1, $3); }
4795

4796 4797 4798 4799 4800 4801
		| a_expr qual_Op a_expr				%prec Op
				{	$$ = (Node *) makeA_Expr(OP, $2, $1, $3); }
		| qual_Op a_expr					%prec Op
				{	$$ = (Node *) makeA_Expr(OP, $1, NULL, $2); }
		| a_expr qual_Op					%prec POSTFIXOP
				{	$$ = (Node *) makeA_Expr(OP, $2, $1, NULL); }
4802

4803
		| a_expr AND a_expr
4804
				{	$$ = (Node *) makeA_Expr(AND, NIL, $1, $3); }
4805
		| a_expr OR a_expr
4806
				{	$$ = (Node *) makeA_Expr(OR, NIL, $1, $3); }
4807
		| NOT a_expr
4808
				{	$$ = (Node *) makeA_Expr(NOT, NIL, NULL, $2); }
4809

4810
		| a_expr LIKE a_expr
4811
				{	$$ = (Node *) makeSimpleA_Expr(OP, "~~", $1, $3); }
4812 4813 4814
		| a_expr LIKE a_expr ESCAPE a_expr
				{
					FuncCall *n = makeNode(FuncCall);
4815
					n->funcname = SystemFuncName("like_escape");
4816
					n->args = makeList2($3, $5);
4817 4818
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
4819
					$$ = (Node *) makeSimpleA_Expr(OP, "~~", $1, (Node *) n);
4820
				}
4821
		| a_expr NOT LIKE a_expr
4822
				{	$$ = (Node *) makeSimpleA_Expr(OP, "!~~", $1, $4); }
4823 4824 4825
		| a_expr NOT LIKE a_expr ESCAPE a_expr
				{
					FuncCall *n = makeNode(FuncCall);
4826
					n->funcname = SystemFuncName("like_escape");
4827
					n->args = makeList2($4, $6);
4828 4829
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
4830
					$$ = (Node *) makeSimpleA_Expr(OP, "!~~", $1, (Node *) n);
4831 4832
				}
		| a_expr ILIKE a_expr
4833
				{	$$ = (Node *) makeSimpleA_Expr(OP, "~~*", $1, $3); }
4834 4835 4836
		| a_expr ILIKE a_expr ESCAPE a_expr
				{
					FuncCall *n = makeNode(FuncCall);
4837
					n->funcname = SystemFuncName("like_escape");
4838
					n->args = makeList2($3, $5);
4839 4840
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
4841
					$$ = (Node *) makeSimpleA_Expr(OP, "~~*", $1, (Node *) n);
4842 4843
				}
		| a_expr NOT ILIKE a_expr
4844
				{	$$ = (Node *) makeSimpleA_Expr(OP, "!~~*", $1, $4); }
4845 4846 4847
		| a_expr NOT ILIKE a_expr ESCAPE a_expr
				{
					FuncCall *n = makeNode(FuncCall);
4848
					n->funcname = SystemFuncName("like_escape");
4849
					n->args = makeList2($4, $6);
4850 4851
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
4852
					$$ = (Node *) makeSimpleA_Expr(OP, "!~~*", $1, (Node *) n);
4853
				}
4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864
		/* 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.
		 */
4865
		| a_expr ISNULL
4866 4867 4868 4869 4870 4871
				{
					NullTest *n = makeNode(NullTest);
					n->arg = $1;
					n->nulltesttype = IS_NULL;
					$$ = (Node *)n;
				}
4872
		| a_expr IS NULL_P
4873 4874 4875 4876 4877 4878
				{
					NullTest *n = makeNode(NullTest);
					n->arg = $1;
					n->nulltesttype = IS_NULL;
					$$ = (Node *)n;
				}
4879
		| a_expr NOTNULL
4880 4881 4882 4883 4884 4885
				{
					NullTest *n = makeNode(NullTest);
					n->arg = $1;
					n->nulltesttype = IS_NOT_NULL;
					$$ = (Node *)n;
				}
4886
		| a_expr IS NOT NULL_P
4887 4888 4889 4890 4891 4892
				{
					NullTest *n = makeNode(NullTest);
					n->arg = $1;
					n->nulltesttype = IS_NOT_NULL;
					$$ = (Node *)n;
				}
4893 4894 4895 4896
		/* 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
4897 4898 4899 4900
		 *
		 *  Created BooleanTest Node type, and changed handling
		 *  for NULL inputs
		 * - jec 2001-06-18
4901
		 */
4902 4903
		| a_expr IS TRUE_P
				{
4904 4905 4906 4907
					BooleanTest *b = makeNode(BooleanTest);
					b->arg = $1;
					b->booltesttype = IS_TRUE;
					$$ = (Node *)b;
4908
				}
4909
		| a_expr IS NOT TRUE_P
4910
				{
4911 4912 4913 4914
					BooleanTest *b = makeNode(BooleanTest);
					b->arg = $1;
					b->booltesttype = IS_NOT_TRUE;
					$$ = (Node *)b;
4915
				}
4916
		| a_expr IS FALSE_P
4917
				{
4918 4919 4920 4921
					BooleanTest *b = makeNode(BooleanTest);
					b->arg = $1;
					b->booltesttype = IS_FALSE;
					$$ = (Node *)b;
4922
				}
4923
		| a_expr IS NOT FALSE_P
4924
				{
4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942
					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;
4943
				}
4944
		| a_expr BETWEEN b_expr AND b_expr			%prec BETWEEN
4945
				{
4946 4947 4948
					$$ = (Node *) makeA_Expr(AND, NIL,
						(Node *) makeSimpleA_Expr(OP, ">=", $1, $3),
						(Node *) makeSimpleA_Expr(OP, "<=", $1, $5));
4949
				}
4950
		| a_expr NOT BETWEEN b_expr AND b_expr		%prec BETWEEN
4951
				{
4952 4953 4954
					$$ = (Node *) makeA_Expr(OR, NIL,
						(Node *) makeSimpleA_Expr(OP, "<", $1, $4),
						(Node *) makeSimpleA_Expr(OP, ">", $1, $6));
4955
				}
4956
		| a_expr IN in_expr
4957
				{
4958
					/* in_expr returns a SubLink or a list of a_exprs */
4959
					if (IsA($3, SubLink))
4960
					{
4961
							SubLink *n = (SubLink *)$3;
4962
							n->lefthand = makeList1($1);
4963 4964
							n->oper = (List *) makeSimpleA_Expr(OP, "=",
																NULL, NULL);
4965
							n->useor = FALSE;
4966 4967
							n->subLinkType = ANY_SUBLINK;
							$$ = (Node *)n;
4968
					}
4969 4970 4971 4972
					else
					{
						Node *n = NULL;
						List *l;
4973
						foreach(l, (List *) $3)
4974
						{
4975 4976 4977
							Node *cmp;
							cmp = (Node *) makeSimpleA_Expr(OP, "=",
															$1, lfirst(l));
4978 4979 4980
							if (n == NULL)
								n = cmp;
							else
4981
								n = (Node *) makeA_Expr(OR, NIL, n, cmp);
4982 4983 4984
						}
						$$ = n;
					}
4985
				}
4986
		| a_expr NOT IN in_expr
4987
				{
4988
					/* in_expr returns a SubLink or a list of a_exprs */
4989
					if (IsA($4, SubLink))
4990
					{
4991
						SubLink *n = (SubLink *)$4;
4992
						n->lefthand = makeList1($1);
4993 4994
						n->oper = (List *) makeSimpleA_Expr(OP, "<>",
															NULL, NULL);
4995
						n->useor = FALSE;
4996 4997 4998 4999 5000 5001 5002
						n->subLinkType = ALL_SUBLINK;
						$$ = (Node *)n;
					}
					else
					{
						Node *n = NULL;
						List *l;
5003
						foreach(l, (List *) $4)
5004
						{
5005 5006 5007
							Node *cmp;
							cmp = (Node *) makeSimpleA_Expr(OP, "<>",
															$1, lfirst(l));
5008 5009 5010
							if (n == NULL)
								n = cmp;
							else
5011
								n = (Node *) makeA_Expr(AND, NIL, n, cmp);
5012 5013
						}
						$$ = n;
5014 5015
					}
				}
5016
		| a_expr qual_all_Op sub_type select_with_parens		%prec Op
Bruce Momjian's avatar
Bruce Momjian committed
5017 5018
				{
					SubLink *n = makeNode(SubLink);
5019
					n->lefthand = makeList1($1);
5020
					n->oper = (List *) makeA_Expr(OP, $2, NULL, NULL);
5021
					n->useor = FALSE; /* doesn't matter since only one col */
5022
					n->subLinkType = $3;
5023
					n->subselect = $4;
Bruce Momjian's avatar
Bruce Momjian committed
5024 5025
					$$ = (Node *)n;
				}
5026 5027
		| row_expr
				{	$$ = $1;  }
5028
		;
5029

5030 5031 5032 5033 5034
/*
 * Restricted expressions
 *
 * b_expr is a subset of the complete expression syntax defined by a_expr.
 *
5035
 * Presently, AND, NOT, IS, and IN are the a_expr keywords that would
5036 5037
 * cause trouble in the places where b_expr is used.  For simplicity, we
 * just eliminate all the boolean-keyword-operator productions from b_expr.
5038
 */
5039
b_expr:  c_expr
5040
				{	$$ = $1;  }
5041
		| b_expr TYPECAST Typename
5042
				{	$$ = makeTypeCast($1, $3); }
5043
		| '+' b_expr					%prec UMINUS
5044
				{	$$ = (Node *) makeSimpleA_Expr(OP, "+", NULL, $2); }
5045
		| '-' b_expr					%prec UMINUS
5046
				{	$$ = doNegate($2); }
Bruce Momjian's avatar
Bruce Momjian committed
5047
		| '%' b_expr
5048
				{	$$ = (Node *) makeSimpleA_Expr(OP, "%", NULL, $2); }
Bruce Momjian's avatar
Bruce Momjian committed
5049
		| '^' b_expr
5050
				{	$$ = (Node *) makeSimpleA_Expr(OP, "^", NULL, $2); }
Bruce Momjian's avatar
Bruce Momjian committed
5051
		| b_expr '%'
5052
				{	$$ = (Node *) makeSimpleA_Expr(OP, "%", $1, NULL); }
Bruce Momjian's avatar
Bruce Momjian committed
5053
		| b_expr '^'
5054
				{	$$ = (Node *) makeSimpleA_Expr(OP, "^", $1, NULL); }
5055
		| b_expr '+' b_expr
5056
				{	$$ = (Node *) makeSimpleA_Expr(OP, "+", $1, $3); }
5057
		| b_expr '-' b_expr
5058
				{	$$ = (Node *) makeSimpleA_Expr(OP, "-", $1, $3); }
5059
		| b_expr '*' b_expr
5060
				{	$$ = (Node *) makeSimpleA_Expr(OP, "*", $1, $3); }
5061
		| b_expr '/' b_expr
5062
				{	$$ = (Node *) makeSimpleA_Expr(OP, "/", $1, $3); }
5063
		| b_expr '%' b_expr
5064
				{	$$ = (Node *) makeSimpleA_Expr(OP, "%", $1, $3); }
5065
		| b_expr '^' b_expr
5066
				{	$$ = (Node *) makeSimpleA_Expr(OP, "^", $1, $3); }
5067
		| b_expr '<' b_expr
5068
				{	$$ = (Node *) makeSimpleA_Expr(OP, "<", $1, $3); }
5069
		| b_expr '>' b_expr
5070
				{	$$ = (Node *) makeSimpleA_Expr(OP, ">", $1, $3); }
5071
		| b_expr '=' b_expr
5072
				{	$$ = (Node *) makeSimpleA_Expr(OP, "=", $1, $3); }
5073

5074 5075 5076 5077 5078 5079
		| b_expr qual_Op b_expr				%prec Op
				{	$$ = (Node *) makeA_Expr(OP, $2, $1, $3); }
		| qual_Op b_expr					%prec Op
				{	$$ = (Node *) makeA_Expr(OP, $1, NULL, $2); }
		| b_expr qual_Op					%prec POSTFIXOP
				{	$$ = (Node *) makeA_Expr(OP, $2, $1, NULL); }
5080 5081 5082 5083 5084 5085 5086 5087 5088 5089
		;

/*
 * 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.
 */
5090
c_expr:  columnref
5091
				{	$$ = (Node *) $1;  }
5092 5093 5094
		| AexprConst
				{	$$ = $1;  }
		| PARAM attrs opt_indirection
5095
				{
5096 5097 5098 5099 5100 5101 5102 5103
					/*
					 * 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;
5104
					$$ = (Node *)n;
5105
				}
5106
		| '(' a_expr ')'
5107
				{	$$ = $2; }
5108 5109 5110 5111 5112 5113 5114 5115
		| '(' a_expr ')' attrs opt_indirection
				{
					ExprFieldSelect *n = makeNode(ExprFieldSelect);
					n->arg = $2;
					n->fields = $4;
					n->indirection = $5;
					$$ = (Node *)n;
				}
5116
		| CAST '(' a_expr AS Typename ')'
5117
				{	$$ = makeTypeCast($3, $5); }
5118 5119
		| case_expr
				{	$$ = $1; }
5120
		| func_name '(' ')'
5121 5122 5123 5124
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = $1;
					n->args = NIL;
5125 5126
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5127 5128
					$$ = (Node *)n;
				}
5129
		| func_name '(' expr_list ')'
5130 5131 5132 5133
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = $1;
					n->args = $3;
5134 5135
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5136 5137
					$$ = (Node *)n;
				}
5138 5139 5140 5141 5142
		| func_name '(' ALL expr_list ')'
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = $1;
					n->args = $4;
5143 5144
					n->agg_star = FALSE;
					n->agg_distinct = FALSE;
5145 5146 5147 5148 5149 5150
					/* 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;
				}
5151 5152 5153 5154 5155
		| func_name '(' DISTINCT expr_list ')'
				{
					FuncCall *n = makeNode(FuncCall);
					n->funcname = $1;
					n->args = $4;
5156 5157
					n->agg_star = FALSE;
					n->agg_distinct = TRUE;
5158 5159
					$$ = (Node *)n;
				}
5160 5161 5162 5163 5164 5165 5166 5167 5168 5169
		| 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.
					 *
5170 5171 5172
					 * The FuncCall node is also marked agg_star = true,
					 * so that later processing can detect what the argument
					 * really was.
5173 5174 5175 5176 5177 5178 5179
					 */
					FuncCall *n = makeNode(FuncCall);
					A_Const *star = makeNode(A_Const);

					star->val.type = T_Integer;
					star->val.val.ival = 1;
					n->funcname = $1;
5180
					n->args = makeList1(star);
5181 5182
					n->agg_star = TRUE;
					n->agg_distinct = FALSE;
5183 5184
					$$ = (Node *)n;
				}
5185
		| CURRENT_DATE opt_empty_parentheses
5186
				{
5187
					/*
5188
					 * Translate as "'now'::text::date".
5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200
					 *
					 * 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);
5201
					TypeName *d;
5202

5203 5204
					s->val.type = T_String;
					s->val.val.str = "now";
5205
					s->typename = makeTypeName(xlateSqlType("text"));
5206

5207
					d = makeTypeName(xlateSqlType("date"));
5208

5209
					$$ = (Node *)makeTypeCast((Node *)s, d);
5210
				}
5211
		| CURRENT_TIME opt_empty_parentheses
5212
				{
5213
					/*
5214
					 * Translate as "'now'::text::timetz".
5215 5216 5217
					 * See comments for CURRENT_DATE.
					 */
					A_Const *s = makeNode(A_Const);
5218
					TypeName *d;
5219

5220 5221
					s->val.type = T_String;
					s->val.val.str = "now";
5222
					s->typename = makeTypeName(xlateSqlType("text"));
5223

5224
					d = makeTypeName(xlateSqlType("timetz"));
5225 5226 5227 5228 5229 5230
					/* 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;
5231

5232
					$$ = (Node *)makeTypeCast((Node *)s, d);
5233 5234 5235
				}
		| CURRENT_TIME '(' Iconst ')'
				{
5236
					/*
5237
					 * Translate as "'now'::text::timetz(n)".
5238 5239
					 * See comments for CURRENT_DATE.
					 */
5240
					A_Const *s = makeNode(A_Const);
5241
					TypeName *d;
5242 5243 5244

					s->val.type = T_String;
					s->val.val.str = "now";
5245 5246
					s->typename = makeTypeName(xlateSqlType("text"));
					d = makeTypeName(xlateSqlType("timetz"));
5247 5248 5249 5250
					if (($3 < 0) || ($3 > 13))
						elog(ERROR,"CURRENT_TIME(%d) precision must be between %d and %d",
							 $3, 0, 13);
					d->typmod = $3;
5251

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

5263 5264
					s->val.type = T_String;
					s->val.val.str = "now";
5265
					s->typename = makeTypeName(xlateSqlType("text"));
5266

5267
					d = makeTypeName(xlateSqlType("timestamptz"));
5268 5269 5270 5271 5272
					/* 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
					 */
5273
					d->typmod = 6;
5274

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

					s->val.type = T_String;
					s->val.val.str = "now";
5288
					s->typename = makeTypeName(xlateSqlType("text"));
5289

5290
					d = makeTypeName(xlateSqlType("timestamptz"));
5291
					if (($3 < 0) || ($3 > 13))
5292
						elog(ERROR,"CURRENT_TIMESTAMP(%d) precision must be between %d and %d",
5293 5294
							 $3, 0, 13);
					d->typmod = $3;
5295

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

5417 5418 5419 5420
/*
 * Supporting nonterminals for expressions.
 */

5421
opt_indirection:	opt_indirection '[' a_expr ']'
5422 5423 5424
				{
					A_Indices *ai = makeNode(A_Indices);
					ai->lidx = NULL;
5425 5426
					ai->uidx = $3;
					$$ = lappend($1, ai);
5427
				}
5428
		| opt_indirection '[' a_expr ':' a_expr ']'
5429 5430
				{
					A_Indices *ai = makeNode(A_Indices);
5431 5432 5433
					ai->lidx = $3;
					ai->uidx = $5;
					$$ = lappend($1, ai);
5434
				}
5435
		| /*EMPTY*/
5436 5437
				{	$$ = NIL; }
		;
5438

5439
expr_list:  a_expr
5440
				{ $$ = makeList1($1); }
5441
		| expr_list ',' a_expr
5442
				{ $$ = lappend($1, $3); }
5443
		| expr_list USING a_expr
5444 5445
				{ $$ = lappend($1, $3); }
		;
5446

5447
extract_list:  extract_arg FROM a_expr
5448 5449 5450 5451
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_String;
					n->val.val.str = $1;
5452
					$$ = makeList2((Node *) n, $3);
5453
				}
5454
		| /*EMPTY*/
5455 5456
				{	$$ = NIL; }
		;
5457

5458 5459 5460 5461
/* Allow delimited string SCONST in extract_arg as an SQL extension.
 * - thomas 2001-04-12
 */

5462 5463 5464 5465 5466 5467 5468 5469
extract_arg:  IDENT						{ $$ = $1; }
		| YEAR_P						{ $$ = "year"; }
		| MONTH_P						{ $$ = "month"; }
		| DAY_P							{ $$ = "day"; }
		| HOUR_P						{ $$ = "hour"; }
		| MINUTE_P						{ $$ = "minute"; }
		| SECOND_P						{ $$ = "second"; }
		| SCONST						{ $$ = $1; }
5470 5471
		;

5472 5473 5474
/* position_list uses b_expr not a_expr to avoid conflict with general IN */

position_list:  b_expr IN b_expr
5475
				{	$$ = makeList2($3, $1); }
5476
		| /*EMPTY*/
5477 5478
				{	$$ = NIL; }
		;
5479

5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490
/* 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
5491
				{
5492
					$$ = makeList3($1, $2, $3);
5493
				}
5494 5495 5496 5497 5498 5499 5500 5501 5502
		| a_expr substr_for substr_from
				{
					$$ = makeList3($1, $3, $2);
				}
		| a_expr substr_from
				{
					$$ = makeList2($1, $2);
				}
		| a_expr substr_for
5503 5504 5505 5506
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_Integer;
					n->val.val.ival = 1;
5507 5508 5509 5510 5511
					$$ = makeList3($1, (Node *)n, $2);
				}
		| expr_list
				{
					$$ = $1;
5512
				}
5513 5514
		| /*EMPTY*/
				{	$$ = NIL; }
5515
		;
5516

5517 5518 5519 5520 5521
substr_from:  FROM a_expr
				{	$$ = $2; }
		;

substr_for:  FOR a_expr
5522 5523
				{	$$ = $2; }
		;
5524

5525
trim_list:  a_expr FROM expr_list
5526
				{ $$ = lappend($3, $1); }
5527
		| FROM expr_list
5528
				{ $$ = $2; }
5529
		| expr_list
5530 5531
				{ $$ = $1; }
		;
5532

5533
in_expr:  select_with_parens
5534
				{
5535 5536 5537
					SubLink *n = makeNode(SubLink);
					n->subselect = $1;
					$$ = (Node *)n;
5538
				}
5539 5540
		| '(' in_expr_nodes ')'
				{	$$ = (Node *)$2; }
5541
		;
5542

5543
in_expr_nodes:  a_expr
5544
				{	$$ = makeList1($1); }
5545 5546
		| in_expr_nodes ',' a_expr
				{	$$ = lappend($1, $3); }
5547
		;
5548

5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575
/* 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);
5576 5577 5578

					w->expr = (Node *) makeSimpleA_Expr(OP, "=", $3, $5);
					/* w->result is left NULL */
5579
					c->args = makeList1(w);
5580 5581 5582 5583 5584 5585 5586 5587 5588
					c->defresult = $3;
					$$ = (Node *)c;
				}
		| COALESCE '(' expr_list ')'
				{
					CaseExpr *c = makeNode(CaseExpr);
					List *l;
					foreach (l,$3)
					{
5589 5590 5591 5592 5593
						CaseWhen *w = makeNode(CaseWhen);
						NullTest *n = makeNode(NullTest);
						n->arg = lfirst(l);
						n->nulltesttype = IS_NOT_NULL;
						w->expr = (Node *) n;
5594 5595 5596 5597 5598 5599 5600 5601 5602 5603
						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
5604
				{ $$ = makeList1($1); }
5605 5606
		;

5607
when_clause:  WHEN a_expr THEN a_expr
5608 5609 5610 5611 5612 5613 5614 5615
				{
					CaseWhen *w = makeNode(CaseWhen);
					w->expr = $2;
					w->result = $4;
					$$ = (Node *)w;
				}
		;

5616
case_default:  ELSE a_expr						{ $$ = $2; }
5617 5618 5619
		| /*EMPTY*/								{ $$ = NULL; }
		;

5620 5621
case_arg:  a_expr
				{	$$ = $1; }
5622 5623 5624 5625
		| /*EMPTY*/
				{	$$ = NULL; }
		;

5626 5627 5628 5629 5630 5631
/*
 * 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
5632
				{
5633 5634 5635
					$$ = makeNode(ColumnRef);
					$$->fields = makeList1(makeString($1));
					$$->indirection = $2;
5636
				}
5637
		| dotted_name opt_indirection
5638
				{
5639
					$$ = makeNode(ColumnRef);
5640 5641
					$$->fields = $1;
					$$->indirection = $2;
5642 5643 5644
				}
		;

5645 5646
dotted_name: relation_name attrs
				{ $$ = lcons(makeString($1), $2); }
5647 5648
		;

5649 5650 5651 5652 5653 5654
attrs:  '.' attr_name
				{ $$ = makeList1(makeString($2)); }
		| '.' '*'
				{ $$ = makeList1(makeString("*")); }
		| '.' attr_name attrs
				{ $$ = lcons(makeString($2), $3); }
5655 5656
		;

5657 5658
opt_empty_parentheses: '(' ')' { $$ = TRUE; }
					| /*EMPTY*/ { $$ = TRUE; }
5659
		;
5660 5661 5662

/*****************************************************************************
 *
5663
 *	target lists
5664 5665 5666
 *
 *****************************************************************************/

5667
/* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
5668

5669
target_list:  target_list ',' target_el
5670
				{	$$ = lappend($1, $3);  }
5671
		| target_el
5672
				{	$$ = makeList1($1);  }
5673
		;
5674 5675

/* AS is not optional because shift/red conflict with unary ops */
5676
target_el:  a_expr AS ColLabel
5677 5678 5679
				{
					$$ = makeNode(ResTarget);
					$$->name = $3;
5680
					$$->indirection = NIL;
5681 5682
					$$->val = (Node *)$1;
				}
5683
		| a_expr
5684 5685 5686
				{
					$$ = makeNode(ResTarget);
					$$->name = NULL;
5687
					$$->indirection = NIL;
5688 5689 5690 5691
					$$->val = (Node *)$1;
				}
		| '*'
				{
5692 5693 5694
					ColumnRef *n = makeNode(ColumnRef);
					n->fields = makeList1(makeString("*"));
					n->indirection = NIL;
5695 5696
					$$ = makeNode(ResTarget);
					$$->name = NULL;
5697 5698
					$$->indirection = NIL;
					$$->val = (Node *)n;
5699 5700 5701
				}
		;

5702 5703 5704 5705 5706
/* Target list as found in UPDATE table SET ... */

update_target_list:  update_target_list ',' update_target_el
				{	$$ = lappend($1,$3);  }
		| update_target_el
5707
				{	$$ = makeList1($1);  }
5708 5709
		;

5710
update_target_el:  ColId opt_indirection '=' a_expr
5711 5712 5713 5714 5715 5716
				{
					$$ = makeNode(ResTarget);
					$$->name = $1;
					$$->indirection = $2;
					$$->val = (Node *)$4;
				}
5717 5718
		;

Bruce Momjian's avatar
Bruce Momjian committed
5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735
insert_target_list:  insert_target_list ',' insert_target_el
				{	$$ = lappend($1, $3);  }
		| insert_target_el
				{	$$ = makeList1($1);  }
		;

insert_target_el:  target_el	{	$$ = $1;  }
				| DEFAULT		{	
									InsertDefault *def = makeNode(InsertDefault);
									$$ = makeNode(ResTarget);
									$$->name = NULL;
									$$->indirection = NULL;
									$$->val = (Node *)def;
								}
				;


5736 5737 5738 5739 5740 5741
/*****************************************************************************
 *
 *	Names and constants
 *
 *****************************************************************************/

5742 5743 5744 5745 5746 5747
relation_name:	SpecialRuleRelation
				{
					$$ = $1;
				}
		| ColId
				{
5748
					$$ = $1;
5749 5750
				}
		;
5751

5752
qualified_name_list:  qualified_name
5753
				{ $$ = makeList1($1); }
5754
		| qualified_name_list ',' qualified_name
5755
				{ $$ = lappend($1, $3); }
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 5781 5782 5783 5784 5785 5786
		;

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)); }
		;

5787

5788
name:					ColId			{ $$ = $1; };
5789
database_name:			ColId			{ $$ = $1; };
5790
access_method:			ColId			{ $$ = $1; };
5791
attr_name:				ColId			{ $$ = $1; };
5792
index_name:				ColId			{ $$ = $1; };
5793
file_name:				Sconst			{ $$ = $1; };
5794

5795
func_name: function_name
5796
			{ $$ = makeList1(makeString(xlateSqlFunc($1))); }
5797 5798 5799 5800 5801
		| dotted_name
			{ $$ = $1; }
		;


5802 5803 5804
/* Constants
 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
 */
5805
AexprConst:  Iconst
5806 5807 5808 5809 5810 5811 5812 5813 5814 5815
				{
					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;
5816
					n->val.val.str = $1;
5817 5818 5819 5820 5821 5822 5823 5824 5825
					$$ = (Node *)n;
				}
		| Sconst
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_String;
					n->val.val.str = $1;
					$$ = (Node *)n;
				}
5826 5827 5828 5829 5830 5831 5832
		| BITCONST
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_BitString;
					n->val.val.str = $1;
					$$ = (Node *)n;
				}
5833
		/* This rule formerly used Typename,
5834 5835 5836 5837
		 * 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
5838
		 */
5839 5840 5841 5842 5843 5844 5845 5846 5847
		| 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
5848 5849 5850 5851 5852
				{
					A_Const *n = makeNode(A_Const);
					n->typename = $1;
					n->val.type = T_String;
					n->val.val.str = $2;
5853 5854 5855
					/* precision is not specified, but fields may be... */
					if ($3 != -1)
						n->typename->typmod = ((($3 & 0x7FFF) << 16) | 0xFFFF);
5856 5857 5858 5859 5860 5861 5862 5863
					$$ = (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;
5864 5865 5866
					/* precision specified, and fields may be... */
					n->typename->typmod = ((($6 & 0x7FFF) << 16) | $3);

5867 5868
					$$ = (Node *)n;
				}
5869 5870 5871 5872 5873 5874 5875 5876
		| PARAM opt_indirection
				{
					ParamRef *n = makeNode(ParamRef);
					n->number = $1;
					n->fields = NIL;
					n->indirection = $2;
					$$ = (Node *)n;
				}
5877 5878 5879 5880 5881
		| TRUE_P
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_String;
					n->val.val.str = "t";
5882
					n->typename = makeTypeName(xlateSqlType("bool"));
5883 5884 5885 5886 5887 5888 5889
					$$ = (Node *)n;
				}
		| FALSE_P
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_String;
					n->val.val.str = "f";
5890
					n->typename = makeTypeName(xlateSqlType("bool"));
5891 5892
					$$ = (Node *)n;
				}
5893 5894 5895 5896 5897 5898
		| NULL_P
				{
					A_Const *n = makeNode(A_Const);
					n->val.type = T_Null;
					$$ = (Node *)n;
				}
5899
		;
5900

5901 5902
Iconst:  ICONST							{ $$ = $1; };
Sconst:  SCONST							{ $$ = $1; };
5903
UserId:  ColId							{ $$ = $1; };
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
/*
 * 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.
 */
5931 5932 5933
function_name:  IDENT					{ $$ = $1; }
		| unreserved_keyword			{ $$ = $1; }
		| func_name_keyword				{ $$ = $1; }
5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946
		;

/* 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; }
		;


5947 5948
/*
 * Keyword classification lists.  Generally, every keyword present in
5949
 * the Postgres grammar should appear in exactly one of these lists.
5950
 *
5951 5952 5953
 * 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.
5954
 */
5955

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

6115
/* Column identifier --- keywords that can be column, table, etc names.
6116
 *
6117 6118 6119
 * 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.
6120
 *
6121 6122 6123
 * 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.
6124
 */
6125 6126
col_name_keyword:
		  BIT							{ $$ = "bit"; }
6127 6128
		| CHAR							{ $$ = "char"; }
		| CHARACTER						{ $$ = "character"; }
6129
		| COALESCE						{ $$ = "coalesce"; }
6130 6131
		| DEC							{ $$ = "dec"; }
		| DECIMAL						{ $$ = "decimal"; }
6132 6133
		| EXISTS						{ $$ = "exists"; }
		| EXTRACT						{ $$ = "extract"; }
6134 6135 6136 6137
		| FLOAT							{ $$ = "float"; }
		| INTERVAL						{ $$ = "interval"; }
		| NCHAR							{ $$ = "nchar"; }
		| NONE							{ $$ = "none"; }
6138
		| NULLIF						{ $$ = "nullif"; }
6139
		| NUMERIC						{ $$ = "numeric"; }
6140
		| POSITION						{ $$ = "position"; }
6141
		| SETOF							{ $$ = "setof"; }
6142
		| SUBSTRING						{ $$ = "substring"; }
6143 6144
		| TIME							{ $$ = "time"; }
		| TIMESTAMP						{ $$ = "timestamp"; }
6145
		| TRIM							{ $$ = "trim"; }
6146 6147 6148
		| VARCHAR						{ $$ = "varchar"; }
		;

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

6257

6258
SpecialRuleRelation:  OLD
6259 6260
				{
					if (QueryIsRule)
6261
						$$ = "*OLD*";
6262
					else
6263
						elog(ERROR,"OLD used in non-rule query");
6264 6265 6266 6267 6268 6269
				}
		| NEW
				{
					if (QueryIsRule)
						$$ = "*NEW*";
					else
Bruce Momjian's avatar
Bruce Momjian committed
6270
						elog(ERROR,"NEW used in non-rule query");
6271 6272
				}
		;
6273 6274 6275

%%

6276 6277 6278 6279
static Node *
makeTypeCast(Node *arg, TypeName *typename)
{
	/*
6280
	 * If arg is an A_Const, just stick the typename into the
6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299
	 * 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;
	}
}

6300 6301 6302 6303
static Node *
makeStringConst(char *str, TypeName *typename)
{
	A_Const *n = makeNode(A_Const);
6304

6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315
	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);
6316

6317 6318
	n->val.type = T_Float;
	n->val.val.str = str;
6319
	n->typename = makeTypeName(xlateSqlType("float"));
6320 6321 6322 6323

	return (Node *)n;
}

Bruce Momjian's avatar
Bruce Momjian committed
6324 6325
/* makeRowExpr()
 * Generate separate operator nodes for a single row descriptor expression.
6326 6327
 * Perhaps this should go deeper in the parser someday...
 * - thomas 1997-12-22
Bruce Momjian's avatar
Bruce Momjian committed
6328 6329
 */
static Node *
6330
makeRowExpr(List *opr, List *largs, List *rargs)
Bruce Momjian's avatar
Bruce Momjian committed
6331 6332 6333
{
	Node *expr = NULL;
	Node *larg, *rarg;
6334
	char *oprname;
Bruce Momjian's avatar
Bruce Momjian committed
6335 6336

	if (length(largs) != length(rargs))
6337
		elog(ERROR, "Unequal number of entries in row expression");
Bruce Momjian's avatar
Bruce Momjian committed
6338 6339

	if (lnext(largs) != NIL)
6340
		expr = makeRowExpr(opr, lnext(largs), lnext(rargs));
Bruce Momjian's avatar
Bruce Momjian committed
6341 6342 6343 6344

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

6345 6346 6347 6348 6349 6350 6351
	oprname = strVal(llast(opr));

	if ((strcmp(oprname, "=") == 0) ||
		(strcmp(oprname, "<") == 0) ||
		(strcmp(oprname, "<=") == 0) ||
		(strcmp(oprname, ">") == 0) ||
		(strcmp(oprname, ">=") == 0))
Bruce Momjian's avatar
Bruce Momjian committed
6352 6353
	{
		if (expr == NULL)
6354
			expr = (Node *) makeA_Expr(OP, opr, larg, rarg);
Bruce Momjian's avatar
Bruce Momjian committed
6355
		else
6356 6357 6358
			expr = (Node *) makeA_Expr(AND, NIL, expr,
									   (Node *) makeA_Expr(OP, opr,
														   larg, rarg));
Bruce Momjian's avatar
Bruce Momjian committed
6359
	}
6360
	else if (strcmp(oprname, "<>") == 0)
Bruce Momjian's avatar
Bruce Momjian committed
6361 6362
	{
		if (expr == NULL)
6363
			expr = (Node *) makeA_Expr(OP, opr, larg, rarg);
Bruce Momjian's avatar
Bruce Momjian committed
6364
		else
6365 6366 6367
			expr = (Node *) makeA_Expr(OR, NIL, expr,
									   (Node *) makeA_Expr(OP, opr,
														   larg, rarg));
Bruce Momjian's avatar
Bruce Momjian committed
6368 6369 6370
	}
	else
	{
6371 6372
		elog(ERROR, "Operator '%s' not implemented for row expressions",
			 oprname);
Bruce Momjian's avatar
Bruce Momjian committed
6373 6374 6375 6376 6377
	}

	return expr;
}

6378
/* findLeftmostSelect()
6379
 *		Find the leftmost component SelectStmt in a set-operation parsetree.
6380 6381
 */
static SelectStmt *
6382
findLeftmostSelect(SelectStmt *node)
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 6436 6437 6438 6439
	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;
6440 6441
}

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

/* xlateSqlType()
 * Convert alternate type names to internal Postgres types.
6469
 *
6470 6471
 * NOTE: these conversions are only applied to unqualified type names.
 *
6472 6473 6474
 * 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.)
6475 6476 6477
 *
 * 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
6478 6479 6480 6481
 *
 * 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
6482
 */
6483
char *
6484 6485
xlateSqlType(char *name)
{
6486 6487
	if ((strcmp(name,"int") == 0)
		|| (strcmp(name,"integer") == 0))
6488
		return "int4";
6489
	else if (strcmp(name, "smallint") == 0)
6490
		return "int2";
6491 6492
	else if (strcmp(name, "bigint") == 0)
		return "int8";
6493 6494 6495
	else if (strcmp(name, "real") == 0)
		return "float4";
	else if (strcmp(name, "float") == 0)
6496
		return "float8";
6497
	else if (strcmp(name, "decimal") == 0)
6498
		return "numeric";
6499
	else if (strcmp(name, "datetime") == 0)
6500
		return "timestamp";
6501
	else if (strcmp(name, "timespan") == 0)
6502
		return "interval";
Tom Lane's avatar
Tom Lane committed
6503 6504
	else if (strcmp(name, "lztext") == 0)
		return "text";
6505
	else if (strcmp(name, "boolean") == 0)
6506
		return "bool";
6507 6508
	else
		return name;
6509
} /* xlateSqlType() */
6510

6511 6512 6513 6514 6515 6516 6517 6518
/* SystemFuncName()
 *	Build a properly-qualified reference to a built-in function.
 */
List *
SystemFuncName(char *name)
{
	return makeList2(makeString("pg_catalog"), makeString(name));
}
6519

6520 6521
void parser_init(Oid *typev, int nargs)
{
6522
	QueryIsRule = FALSE;
6523 6524 6525 6526
	/*
	 * Keep enough information around to fill out the type of param nodes
	 * used in postquel functions
	 */
6527
	param_type_info = typev;
6528
	pfunc_num_args = nargs;
6529 6530 6531 6532
}

Oid param_type(int t)
{
6533
	if ((t > pfunc_num_args) || (t <= 0))
6534 6535 6536
		return InvalidOid;
	return param_type_info[t - 1];
}
6537

6538 6539 6540
/*
 * Test whether an a_expr is a plain NULL constant or not.
 */
6541
bool
6542 6543 6544 6545 6546 6547 6548 6549
exprIsNullConstant(Node *arg)
{
	if (arg && IsA(arg, A_Const))
	{
		A_Const *con = (A_Const *) arg;

		if (con->val.type == T_Null &&
			con->typename == NULL)
6550
			return TRUE;
6551
	}
6552
	return FALSE;
6553 6554
}

6555
/*
6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566
 * 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.
6567
 */
6568 6569
static Node *
doNegate(Node *n)
6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581
{
	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)
		{
6582
			doNegateFloat(&con->val);
6583 6584 6585 6586
			return n;
		}
	}

6587
	return (Node *) makeSimpleA_Expr(OP, "-", NULL, n);
6588
}
6589 6590 6591 6592 6593 6594 6595 6596 6597 6598

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

	Assert(IsA(v, Float));
	if (*oldval == '+')
		oldval++;
	if (*oldval == '-')
6599
		v->val.str = oldval+1;	/* just strip the '-' */
6600 6601 6602 6603 6604 6605 6606 6607 6608
	else
	{
		char   *newval = (char *) palloc(strlen(oldval) + 2);

		*newval = '-';
		strcpy(newval+1, oldval);
		v->val.str = newval;
	}
}
6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630

/*
 * Decide whether to put double quotes around a name appearing in a SET
 * name_list.  Presently, do so if the name contains whitespace, commas,
 * or uppercase characters.  (This is correct assuming that the result
 * will be deparsed by SplitIdentifierString or similar logic.)
 */
static bool
set_name_needs_quotes(const char *name)
{
	if (*name == '\0')
		return true;			/* empty name does need quotes */
	while (*name)
	{
		if (*name == ',' ||
			isspace((unsigned char) *name) ||
			isupper((unsigned char) *name))
			return true;
		name++;
	}
	return false;
}