preproc.y 165 KB
Newer Older
1 2
/* Copyright comment */
%{
3
#include "postgres_fe.h"
4 5

#include "extern.h"
6

7 8 9
/*
 * Variables containing simple states.
 */
10
int	struct_level = 0;
Michael Meskes's avatar
Michael Meskes committed
11
int	braces_open; /* brace level counter */
12
char	errortext[128];
Michael Meskes's avatar
Michael Meskes committed
13
char	*connection = NULL;
Michael Meskes's avatar
Michael Meskes committed
14
char 	*input_filename = NULL;
Michael Meskes's avatar
Michael Meskes committed
15

16
static int      QueryIsRule = 0, FoundInto = 0;
Michael Meskes's avatar
Michael Meskes committed
17
static int	initializer = 0;
18
static struct this_type actual_type[STRUCT_DEPTH];
19
static char     *actual_storage[STRUCT_DEPTH];
Michael Meskes's avatar
Michael Meskes committed
20
static char     *actual_startline[STRUCT_DEPTH];
21

22
/* temporarily store struct members while creating the data structure */
23
struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
24

25 26 27
struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}};
struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};

28 29
struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}};

Michael Meskes's avatar
Michael Meskes committed
30 31 32
/*
 * Handle parsing errors and warnings
 */
Michael Meskes's avatar
Michael Meskes committed
33
void
Michael Meskes's avatar
Michael Meskes committed
34 35 36 37
mmerror(enum errortype type, char * error)
{
    switch(type)
    {
38
	case ET_NOTICE: 
Michael Meskes's avatar
Michael Meskes committed
39 40 41 42 43 44 45 46 47 48 49 50
		fprintf(stderr, "%s:%d: WARNING: %s\n", input_filename, yylineno, error); 
		break;
	case ET_ERROR:
		fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
		ret_value = PARSE_ERROR;
		break;
	case ET_FATAL:
		fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
		exit(PARSE_ERROR);
    }
}

Michael Meskes's avatar
Michael Meskes committed
51 52 53 54
/*
 * string concatenation
 */

Marc G. Fournier's avatar
Marc G. Fournier committed
55
static char *
56
cat2_str(char *str1, char *str2)
Marc G. Fournier's avatar
Marc G. Fournier committed
57 58 59 60 61 62
{ 
	char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);

	strcpy(res_str, str1);
	strcat(res_str, " ");
	strcat(res_str, str2);
63 64
	free(str1);
	free(str2);
Marc G. Fournier's avatar
Marc G. Fournier committed
65 66 67 68
	return(res_str);
}

static char *
Michael Meskes's avatar
Michael Meskes committed
69 70 71 72 73
cat_str(int count, ...)
{
	va_list		args;
	int 		i; 
	char		*res_str;
Marc G. Fournier's avatar
Marc G. Fournier committed
74

Michael Meskes's avatar
Michael Meskes committed
75
	va_start(args, count);
Marc G. Fournier's avatar
Marc G. Fournier committed
76

Michael Meskes's avatar
Michael Meskes committed
77 78 79 80 81 82 83 84 85
	res_str = va_arg(args, char *);

	/* now add all other strings */
	for (i = 1; i < count; i++)
		res_str = cat2_str(res_str, va_arg(args, char *));

	va_end(args);

	return(res_str);
Marc G. Fournier's avatar
Marc G. Fournier committed
86 87
}

Michael Meskes's avatar
Michael Meskes committed
88
char *
Michael Meskes's avatar
Michael Meskes committed
89 90
make_str(const char *str)
{
91
	char * res_str = (char *)mm_alloc(strlen(str) + 1);
Michael Meskes's avatar
Michael Meskes committed
92 93 94

	strcpy(res_str, str);
	return res_str;
Marc G. Fournier's avatar
Marc G. Fournier committed
95 96 97
}

static char *
Michael Meskes's avatar
Michael Meskes committed
98 99 100 101 102 103
make2_str(char *str1, char *str2)
{ 
	char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);

	strcpy(res_str, str1);
	strcat(res_str, str2);
104 105
	free(str1);
	free(str2);
Michael Meskes's avatar
Michael Meskes committed
106 107
	return(res_str);
}
Marc G. Fournier's avatar
Marc G. Fournier committed
108 109

static char *
Michael Meskes's avatar
Michael Meskes committed
110 111 112 113 114 115
make3_str(char *str1, char *str2, char *str3)
{ 
	char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1);

	strcpy(res_str, str1);
	strcat(res_str, str2);
Marc G. Fournier's avatar
Marc G. Fournier committed
116
	strcat(res_str, str3);
117 118 119
	free(str1);
	free(str2);
	free(str3);
Michael Meskes's avatar
Michael Meskes committed
120 121
	return(res_str);
}
Marc G. Fournier's avatar
Marc G. Fournier committed
122 123 124 125 126 127 128 129 130 131 132

static char *
make_name(void)
{
	char * name = (char *)mm_alloc(yyleng + 1);

	strncpy(name, yytext, yyleng);
	name[yyleng] = '\0';
	return(name);
}

133 134 135
%}

%union {
Marc G. Fournier's avatar
Marc G. Fournier committed
136
	double                  dval;
137
	int                     ival;
Marc G. Fournier's avatar
Marc G. Fournier committed
138 139
	char *                  str;
	struct when             action;
140
	struct index		index;
Marc G. Fournier's avatar
Marc G. Fournier committed
141
	int			tagname;
142
	struct this_type	type;
Marc G. Fournier's avatar
Marc G. Fournier committed
143
	enum ECPGttype		type_enum;
Michael Meskes's avatar
Michael Meskes committed
144
	enum ECPGdtype		dtype_enum;
Michael Meskes's avatar
Michael Meskes committed
145
	struct fetch_desc	descriptor;
146 147
}

Marc G. Fournier's avatar
Marc G. Fournier committed
148
/* special embedded SQL token */
149
%token		SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK 
150 151
%token		SQL_CALL SQL_CARDINALITY SQL_CONNECT SQL_CONNECTION 
%token		SQL_CONTINUE SQL_COUNT
Michael Meskes's avatar
Michael Meskes committed
152
%token		SQL_DATA SQL_DATETIME_INTERVAL_CODE SQL_DATETIME_INTERVAL_PRECISION
Michael Meskes's avatar
Michael Meskes committed
153 154
%token		SQL_DEALLOCATE SQL_DESCRIPTOR SQL_DISCONNECT SQL_ENUM 
%token		SQL_FOUND SQL_FREE SQL_GET SQL_GO SQL_GOTO
Michael Meskes's avatar
Michael Meskes committed
155 156 157
%token		SQL_IDENTIFIED SQL_INDICATOR SQL_INT SQL_KEY_MEMBER 
%token		SQL_LENGTH SQL_LONG
%token		SQL_NAME SQL_NULLABLE
Michael Meskes's avatar
Michael Meskes committed
158
%token		SQL_OCTET_LENGTH SQL_OPEN SQL_PREPARE
Michael Meskes's avatar
Michael Meskes committed
159 160 161
%token		SQL_RELEASE SQL_REFERENCE SQL_RETURNED_LENGTH
%token		SQL_RETURNED_OCTET_LENGTH
%token		SQL_SCALE SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL 
Michael Meskes's avatar
Michael Meskes committed
162
%token		SQL_SQLERROR SQL_SQLPRINT
163
%token		SQL_SQLWARNING SQL_START SQL_STOP SQL_STRUCT SQL_UNSIGNED
Michael Meskes's avatar
Michael Meskes committed
164
%token		SQL_VALUE SQL_VAR SQL_WHENEVER
Marc G. Fournier's avatar
Marc G. Fournier committed
165 166

/* C token */
167 168 169 170
%token		S_ADD S_AND S_ANYTHING S_AUTO S_CONST S_DEC S_DIV S_DOTPOINT
%token		S_EQUAL S_EXTERN S_INC S_LSHIFT
%token		S_MEMPOINT S_MEMBER S_MOD S_MUL S_NEQUAL S_OR
%token		S_REGISTER S_RSHIFT S_STATIC S_SUB S_VOLATILE
Marc G. Fournier's avatar
Marc G. Fournier committed
171 172 173 174 175

/* I need this and don't know where it is defined inside the backend */
%token		TYPECAST

/* Keywords (in SQL92 reserved words) */
176
%token  ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC, AT, AUTHORIZATION, 
Marc G. Fournier's avatar
Marc G. Fournier committed
177
                BEGIN_TRANS, BETWEEN, BOTH, BY,
Michael Meskes's avatar
Michael Meskes committed
178 179
                CASCADE, CASE, CAST, CHAIN, CHAR, CHARACTER,
		CHARACTERISTICS, CHECK, CLOSE,
180
		COALESCE, COLLATE, COLUMN, COMMIT, 
Michael Meskes's avatar
Michael Meskes committed
181 182
                CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT, CURRENT_DATE,
                CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
Michael Meskes's avatar
Michael Meskes committed
183
                DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
184
                ELSE, ENCRYPTED, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
185
                FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
Michael Meskes's avatar
Michael Meskes committed
186
                GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
Michael Meskes's avatar
Michael Meskes committed
187
                IN, INNER_P, INOUT, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
188
                ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
189
                MATCH, MINUTE_P, MONTH_P, NAMES,
190
                NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
Michael Meskes's avatar
Michael Meskes committed
191 192
                OF, OFF, OLD, ON, ONLY, OPTION, OR, ORDER, OUT, OUTER_P, OVERLAPS,
                PARTIAL, PATH_P, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
193
                READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
Michael Meskes's avatar
Michael Meskes committed
194
                SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING,
Michael Meskes's avatar
Michael Meskes committed
195 196
                TABLE, TEMPORARY, THEN, TIME, TIMESTAMP
		TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
197
                UNENCRYPTED, UNION, UNIQUE, UNKNOWN, UPDATE, USER, USING,
Marc G. Fournier's avatar
Marc G. Fournier committed
198
                VALUES, VARCHAR, VARYING, VIEW,
Michael Meskes's avatar
Michael Meskes committed
199
                WHEN, WHERE, WITH, WITHOUT, WORK, YEAR_P, ZONE
Marc G. Fournier's avatar
Marc G. Fournier committed
200 201

/* Keywords (in SQL3 reserved words) */
Michael Meskes's avatar
Michael Meskes committed
202 203 204
%token DEFERRABLE, DEFERRED,
               IMMEDIATE, INITIALLY,
               PENDANT,
205
               REPLACE, RESTRICT,
Michael Meskes's avatar
Michael Meskes committed
206
               TRIGGER
Marc G. Fournier's avatar
Marc G. Fournier committed
207 208

/* Keywords (in SQL92 non-reserved words) */
Michael Meskes's avatar
Michael Meskes committed
209
%token  COMMITTED, SERIALIZABLE, TYPE_P
Marc G. Fournier's avatar
Marc G. Fournier committed
210

211 212 213 214 215 216
/* 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?
 */
217 218 219
%token  ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYSE, ANALYZE,
		BACKWARD, BEFORE, BINARY, BIT, CACHE, CHECKPOINT, CLUSTER,
		COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE, DATABASE,
220 221
		DELIMITERS, DO, EACH, ENCODING, EXCLUSIVE, EXPLAIN,
		FORCE, FORWARD, FREEZE, FUNCTION, HANDLER, INCREMENT,
222 223 224
		INDEX, INHERITS, INSTEAD, ISNULL, LANCOMPILER, LIMIT,
		LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE,
		MINVALUE, MODE, MOVE, NEW, NOCREATEDB, NOCREATEUSER,
225 226
		NONE, NOTHING, NOTIFY, NOTNULL, OFFSET, OIDS,
		OPERATOR, OWNER, PASSWORD, PROCEDURAL, REINDEX, RENAME, RESET,
227
		RETURNS, ROW, RULE, SEQUENCE, SETOF, SHARE,
228
		SHOW, START, STATEMENT, STATISTICS, STDIN, STDOUT, SYSID TEMP,
229
		TEMPLATE, TOAST, TRUNCATE, TRUSTED, UNLISTEN, UNTIL, VACUUM,
230
		VALID, VERBOSE, VERSION
Marc G. Fournier's avatar
Marc G. Fournier committed
231

232 233 234 235 236 237
/* 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
                
Marc G. Fournier's avatar
Marc G. Fournier committed
238
/* Special keywords, not in the query language - see the "lex" file */
Michael Meskes's avatar
Michael Meskes committed
239
%token <str>    IDENT SCONST Op CSTRING CVARIABLE CPP_LINE IP BITCONST
Marc G. Fournier's avatar
Marc G. Fournier committed
240 241 242 243 244 245
%token <ival>   ICONST PARAM
%token <dval>   FCONST

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

Michael Meskes's avatar
Michael Meskes committed
246
/* precedence: lowest to highest */
247 248 249
%left		UNION EXCEPT
%left		INTERSECT
%left		JOIN UNIONJOIN CROSS LEFT FULL RIGHT INNER_P NATURAL 
Marc G. Fournier's avatar
Marc G. Fournier committed
250 251 252 253 254
%left		OR
%left		AND
%right		NOT
%right		'='
%nonassoc	'<' '>'
Michael Meskes's avatar
Michael Meskes committed
255
%nonassoc	LIKE ILIKE
256
%nonassoc	ESCAPE
Michael Meskes's avatar
Michael Meskes committed
257
%nonassoc	OVERLAPS
Marc G. Fournier's avatar
Marc G. Fournier committed
258 259
%nonassoc	BETWEEN
%nonassoc	IN
260
%left           POSTFIXOP              		/* dummy for postfix Op rules */    
Michael Meskes's avatar
Michael Meskes committed
261
%left		Op				/* multi-character ops and user-defined operators */
Marc G. Fournier's avatar
Marc G. Fournier committed
262 263
%nonassoc	NOTNULL
%nonassoc	ISNULL
264
%nonassoc	IS NULL_P TRUE_P FALSE_P UNKNOWN
Marc G. Fournier's avatar
Marc G. Fournier committed
265
%left		'+' '-'
Michael Meskes's avatar
Michael Meskes committed
266
%left		'*' '/' '%'
Michael Meskes's avatar
Michael Meskes committed
267
%left		'^'
Marc G. Fournier's avatar
Marc G. Fournier committed
268
/* Unary Operators */
269
%left           AT ZONE
Marc G. Fournier's avatar
Marc G. Fournier committed
270 271 272
%right		UMINUS
%left		'.'
%left		'[' ']'
273
%left		'(' ')'
Michael Meskes's avatar
Michael Meskes committed
274
%left		TYPECAST
Marc G. Fournier's avatar
Marc G. Fournier committed
275

276
%type  <str>	Iconst Fconst Sconst TransactionStmt CreateStmt UserId
Marc G. Fournier's avatar
Marc G. Fournier committed
277
%type  <str>	CreateAsElement OptCreateAs CreateAsList CreateAsStmt
278
%type  <str>	key_reference comment_text ConstraintDeferrabilitySpec
Michael Meskes's avatar
Michael Meskes committed
279
%type  <str>    key_match ColLabel SpecialRuleRelation ColId columnDef
Michael Meskes's avatar
Michael Meskes committed
280
%type  <str>    ColConstraint ColConstraintElem drop_type Bitconst
Marc G. Fournier's avatar
Marc G. Fournier committed
281
%type  <str>    OptTableElementList OptTableElement TableConstraint
282
%type  <str>    ConstraintElem key_actions ColQualList TypeFuncId DropSchemaStmt
Michael Meskes's avatar
Michael Meskes committed
283
%type  <str>    target_list target_el update_target_list alias_clause
Michael Meskes's avatar
Michael Meskes committed
284
%type  <str>    update_target_el opt_id relation_name database_name
Marc G. Fournier's avatar
Marc G. Fournier committed
285
%type  <str>    access_method attr_name class index_name name func_name
Michael Meskes's avatar
Michael Meskes committed
286
%type  <str>    file_name AexprConst ParamNo c_expr ConstTypename
Michael Meskes's avatar
Michael Meskes committed
287
%type  <str>	in_expr_nodes a_expr b_expr TruncateStmt CommentStmt
Marc G. Fournier's avatar
Marc G. Fournier committed
288
%type  <str> 	opt_indirection expr_list extract_list extract_arg
289
%type  <str>	position_list substr_list substr_from alter_column_default
Michael Meskes's avatar
Michael Meskes committed
290
%type  <str>	trim_list in_expr substr_for attr attrs drop_behavior
291
%type  <str>	Typename SimpleTypename Generic Numeric opt_float opt_numeric
Marc G. Fournier's avatar
Marc G. Fournier committed
292
%type  <str> 	opt_decimal Character character opt_varying opt_charset
293
%type  <str>	opt_collate opt_timezone opt_interval table_ref
Michael Meskes's avatar
Michael Meskes committed
294
%type  <str>	row_expr row_descriptor row_list ConstDatetime opt_chain
295
%type  <str>	SelectStmt into_clause OptTemp ConstraintAttributeSpec
Michael Meskes's avatar
Michael Meskes committed
296
%type  <str>	opt_table opt_all sort_clause sortby_list ConstraintAttr 
297
%type  <str>	sortby OptUseOp relation_name_list name_list ColId_or_Sconst
Michael Meskes's avatar
Michael Meskes committed
298
%type  <str>	group_clause having_clause from_clause opt_distinct
Michael Meskes's avatar
Michael Meskes committed
299
%type  <str>	join_outer where_clause relation_expr sub_type opt_arg
300
%type  <str>	opt_column_list insert_rest InsertStmt OptimizableStmt
Marc G. Fournier's avatar
Marc G. Fournier committed
301
%type  <str>    columnList DeleteStmt LockStmt UpdateStmt CursorStmt
Michael Meskes's avatar
Michael Meskes committed
302
%type  <str>    NotifyStmt columnElem copy_dirn UnlistenStmt copy_null
Marc G. Fournier's avatar
Marc G. Fournier committed
303
%type  <str>    copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
Michael Meskes's avatar
Michael Meskes committed
304
%type  <str>    opt_with_copy FetchStmt direction fetch_how_many from_in
305
%type  <str>    ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
306
%type  <str>    opt_full func_arg OptWithOids opt_freeze opt_ecpg_into
307
%type  <str>    analyze_keyword opt_name_list ExplainStmt index_params
Michael Meskes's avatar
Michael Meskes committed
308 309
%type  <str>    index_list func_index index_elem opt_class access_method_clause
%type  <str>    index_opt_unique IndexStmt func_return ConstInterval
Michael Meskes's avatar
Michael Meskes committed
310
%type  <str>    func_args_list func_args opt_with ProcedureStmt def_arg
311
%type  <str>    def_elem def_list definition DefineStmt select_with_parens
Michael Meskes's avatar
Michael Meskes committed
312
%type  <str>    opt_instead event event_object RuleActionList opt_using
Michael Meskes's avatar
Michael Meskes committed
313
%type  <str>	RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type
314
%type  <str>    RuleStmt opt_column opt_name oper_argtypes NumConst
315
%type  <str>    MathOp RemoveFuncStmt aggr_argtype for_update_clause
316
%type  <str>    RemoveAggrStmt opt_procedural select_no_parens
317
%type  <str>    RemoveOperStmt RenameStmt all_Op opt_Trusted opt_lancompiler 
Marc G. Fournier's avatar
Marc G. Fournier committed
318
%type  <str>    VariableSetStmt var_value zone_value VariableShowStmt
Michael Meskes's avatar
Michael Meskes committed
319
%type  <str>    VariableResetStmt AlterTableStmt DropUserStmt from_list
320
%type  <str>    opt_trans user_list OptUserList OptUserElem
Marc G. Fournier's avatar
Marc G. Fournier committed
321 322
%type  <str>    CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
%type  <str>    OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
323
%type  <str>	DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
324
%type  <str>    TriggerActionTime CreateTrigStmt DropPLangStmt 
325
%type  <str>    CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
Tom Lane's avatar
Tom Lane committed
326
%type  <str>    ViewStmt LoadStmt CreatedbStmt createdb_opt_item
327
%type  <str>	createdb_opt_list opt_encoding OptInherit
328
%type  <str>    DropdbStmt ClusterStmt grantee RevokeStmt Bit bit
329
%type  <str>	GrantStmt privileges operation_commalist operation PosAllConst
330
%type  <str>	opt_with_grant opt_cursor ConstraintsSetStmt AllConst
331
%type  <str>	case_expr when_clause_list case_default case_arg when_clause
Michael Meskes's avatar
Michael Meskes committed
332
%type  <str>    select_clause opt_select_limit select_limit_value ConstraintTimeSpec
333
%type  <str>    select_offset_value ReindexStmt join_type opt_boolean
334
%type  <str>	join_qual update_list AlterSchemaStmt joined_table
335
%type  <str>	opt_level opt_lock lock_type OptGroupList OptGroupElem
336 337
%type  <str>    OptConstrFromTable OptTempTableName StringConst
%type  <str>    constraints_set_list constraints_set_namelist
Michael Meskes's avatar
Michael Meskes committed
338
%type  <str>	constraints_set_mode comment_type opt_empty_parentheses
Michael Meskes's avatar
Michael Meskes committed
339
%type  <str>	CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
340
%type  <str>	opt_force key_update CreateSchemaStmt PosIntStringConst
341
%type  <str>    IntConst PosIntConst grantee_list func_type opt_or_replace
342
%type  <str>    select_limit opt_for_update_clause CheckPointStmt
Marc G. Fournier's avatar
Marc G. Fournier committed
343

Michael Meskes's avatar
Michael Meskes committed
344
%type  <str>	ECPGWhenever ECPGConnect connection_target ECPGOpen
345
%type  <str>	indicator ECPGExecute ECPGPrepare ecpg_using ecpg_into
Michael Meskes's avatar
Michael Meskes committed
346 347
%type  <str>    storage_clause opt_initializer c_anything blockstart
%type  <str>    blockend variable_list variable c_thing c_term
348
%type  <str>	opt_pointer ECPGDisconnect dis_name storage_modifier
Michael Meskes's avatar
Michael Meskes committed
349
%type  <str>	stmt ECPGRelease execstring server_name
Michael Meskes's avatar
Michael Meskes committed
350
%type  <str>	connection_object opt_server opt_port c_stuff opt_reference
351
%type  <str>    user_name opt_user char_variable ora_user ident
352
%type  <str>	quoted_ident_stringvar
Michael Meskes's avatar
Michael Meskes committed
353
%type  <str>    db_prefix server opt_options opt_connection_name c_list
Michael Meskes's avatar
Michael Meskes committed
354
%type  <str>	ECPGSetConnection cpp_line ECPGTypedef c_args ECPGKeywords
355
%type  <str>	enum_type civar civarind ECPGCursorStmt ECPGDeallocate
Michael Meskes's avatar
Michael Meskes committed
356
%type  <str>	ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
Michael Meskes's avatar
Michael Meskes committed
357
%type  <str>    struct_type s_struct declaration declarations variable_declarations
Michael Meskes's avatar
Michael Meskes committed
358
%type  <str>    s_union union_type ECPGSetAutocommit on_off
Michael Meskes's avatar
Michael Meskes committed
359
%type  <str>	ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol
360
%type  <str>	ECPGGetDescriptorHeader ECPGTypeFuncId ECPGColId ECPGColLabel
361
%type  <str>	ECPGTypeName variablelist cvariable
Michael Meskes's avatar
Michael Meskes committed
362

363
%type  <descriptor> ECPGGetDescriptor
364

365
%type  <type_enum> simple_type signed_type unsigned_type
Marc G. Fournier's avatar
Marc G. Fournier committed
366

Michael Meskes's avatar
Michael Meskes committed
367 368
%type  <dtype_enum> descriptor_item desc_header_item

Michael Meskes's avatar
Michael Meskes committed
369
%type  <type>	type
370

Marc G. Fournier's avatar
Marc G. Fournier committed
371 372
%type  <action> action

Michael Meskes's avatar
Michael Meskes committed
373
%type  <index>	opt_array_bounds opt_type_array_bounds
374

Michael Meskes's avatar
Michael Meskes committed
375
%type  <ival>	Iresult
376 377

%token YYERROR_VERBOSE
Marc G. Fournier's avatar
Marc G. Fournier committed
378 379 380 381 382 383
%%
prog: statements;

statements: /* empty */
	| statements statement

Michael Meskes's avatar
Michael Meskes committed
384
statement: ecpgstart opt_at stmt ';'	{ connection = NULL; }
Michael Meskes's avatar
Michael Meskes committed
385
	| ecpgstart stmt ';'
Marc G. Fournier's avatar
Marc G. Fournier committed
386
	| ECPGDeclaration
387 388
	| c_thing 			{ fprintf(yyout, "%s", $1); free($1); }
	| cpp_line			{ fprintf(yyout, "%s", $1); free($1); }
389 390
	| blockstart			{ fputs($1, yyout); free($1); }
	| blockend			{ fputs($1, yyout); free($1); }
Michael Meskes's avatar
Michael Meskes committed
391
	;
392

393
opt_at:	AT connection_target	{ connection = $2; };
394

395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
stmt:  AlterSchemaStmt 			{ output_statement($1, 0, connection); }
		| AlterTableStmt	{ output_statement($1, 0, connection); }
		| AlterGroupStmt	{ output_statement($1, 0, connection); }
		| AlterUserStmt		{ output_statement($1, 0, connection); }
		| ClosePortalStmt	{ output_statement($1, 0, connection); }
		| CommentStmt		{ output_statement($1, 0, connection); }
		| CopyStmt		{ output_statement($1, 0, connection); }
		| CreateStmt		{ output_statement($1, 0, connection); }
		| CreateAsStmt		{ output_statement($1, 0, connection); }
		| CreateSchemaStmt   	{ output_statement($1, 0, connection); }
		| CreateGroupStmt	{ output_statement($1, 0, connection); }
		| CreateSeqStmt		{ output_statement($1, 0, connection); }
		| CreatePLangStmt	{ output_statement($1, 0, connection); }
		| CreateTrigStmt	{ output_statement($1, 0, connection); }
		| CreateUserStmt	{ output_statement($1, 0, connection); }
  		| ClusterStmt		{ output_statement($1, 0, connection); }
		| DefineStmt 		{ output_statement($1, 0, connection); }
		| DropStmt		{ output_statement($1, 0, connection); }
		| DropSchemaStmt	{ output_statement($1, 0, connection); }
		| TruncateStmt		{ output_statement($1, 0, connection); }
		| DropGroupStmt		{ output_statement($1, 0, connection); }
		| DropPLangStmt		{ output_statement($1, 0, connection); }
		| DropTrigStmt		{ output_statement($1, 0, connection); }
		| DropUserStmt		{ output_statement($1, 0, connection); }
		| ExplainStmt		{ output_statement($1, 0, connection); }
		| FetchStmt		{ output_statement($1, 1, connection); }
		| GrantStmt		{ output_statement($1, 0, connection); }
		| IndexStmt		{ output_statement($1, 0, connection); }
		| ListenStmt		{ output_statement($1, 0, connection); }
		| UnlistenStmt		{ output_statement($1, 0, connection); }
		| LockStmt		{ output_statement($1, 0, connection); }
		| NotifyStmt		{ output_statement($1, 0, connection); }
		| ProcedureStmt		{ output_statement($1, 0, connection); }
		| ReindexStmt		{ output_statement($1, 0, connection); }
		| RemoveAggrStmt	{ output_statement($1, 0, connection); }
		| RemoveOperStmt	{ output_statement($1, 0, connection); }
		| RemoveFuncStmt	{ output_statement($1, 0, connection); }
		| RenameStmt		{ output_statement($1, 0, connection); }
		| RevokeStmt		{ output_statement($1, 0, connection); }
434
                | OptimizableStmt	{
435
						if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
Michael Meskes's avatar
Michael Meskes committed
436
							output_simple_statement($1);
437
						else
438
							output_statement($1, 1, connection);
439
					}
440
		| RuleStmt		{ output_statement($1, 0, connection); }
Marc G. Fournier's avatar
Marc G. Fournier committed
441
		| TransactionStmt	{
Michael Meskes's avatar
Michael Meskes committed
442 443
						fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
						whenever_action(2);
444
						free($1);
Marc G. Fournier's avatar
Marc G. Fournier committed
445
					}
446 447 448 449 450 451 452 453 454 455 456
		| ViewStmt		{ output_statement($1, 0, connection); }
		| LoadStmt		{ output_statement($1, 0, connection); }
		| CreatedbStmt		{ output_statement($1, 0, connection); }
		| DropdbStmt		{ output_statement($1, 0, connection); }
		| VacuumStmt		{ output_statement($1, 0, connection); }
		| AnalyzeStmt		{ output_statement($1, 0, connection); }
		| VariableSetStmt	{ output_statement($1, 0, connection); }
		| VariableShowStmt	{ output_statement($1, 0, connection); }
		| VariableResetStmt	{ output_statement($1, 0, connection); }
		| ConstraintsSetStmt	{ output_statement($1, 0, connection); }
		| CheckPointStmt	{ output_statement($1, 0, connection); }
457
		| ECPGAllocateDescr	{	fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
Michael Meskes's avatar
Michael Meskes committed
458 459 460
								whenever_action(0);
								free($1);
							}
Marc G. Fournier's avatar
Marc G. Fournier committed
461
		| ECPGConnect		{
462
						if (connection)
Michael Meskes's avatar
Michael Meskes committed
463
							mmerror(ET_ERROR, "no at option for connect statement.\n");
464

465
						fprintf(yyout, "{ ECPGconnect(__LINE__, %s, %d); ", $1, autocommit);
466 467 468

				                reset_variables();

Michael Meskes's avatar
Michael Meskes committed
469
						whenever_action(2);
470 471
						free($1);
					} 
472
		| ECPGCursorStmt	{
Michael Meskes's avatar
Michael Meskes committed
473
						output_simple_statement($1);
474 475
					}
		| ECPGDeallocate	{
476
						if (connection)
Michael Meskes's avatar
Michael Meskes committed
477
							mmerror(ET_ERROR, "no at option for connect statement.\n");
478

Michael Meskes's avatar
Michael Meskes committed
479
						fputc('{', yyout);
480
						fputs($1, yyout);
Michael Meskes's avatar
Michael Meskes committed
481
						whenever_action(2);
482 483
						free($1);
					}
484
		| ECPGDeallocateDescr	{	fprintf(yyout,"ECPGdeallocate_desc(__LINE__, %s);",$1);
Michael Meskes's avatar
Michael Meskes committed
485 486 487
									whenever_action(0);
									free($1);
								}
488
		| ECPGDeclare		{
Michael Meskes's avatar
Michael Meskes committed
489
						output_simple_statement($1);
490
					}
491
		| ECPGDisconnect	{
492
						if (connection)
Michael Meskes's avatar
Michael Meskes committed
493
							mmerror(ET_ERROR, "no at option for disconnect statement.\n");
494

Michael Meskes's avatar
Michael Meskes committed
495
						fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);", $1); 
Michael Meskes's avatar
Michael Meskes committed
496
						whenever_action(2);
497
						free($1);
Marc G. Fournier's avatar
Marc G. Fournier committed
498
					} 
499
		| ECPGExecute		{	output_statement($1, 0, connection); }
500
		| ECPGFree		{
Michael Meskes's avatar
Michael Meskes committed
501 502
						fprintf(yyout, "{ ECPGdeallocate(__LINE__, \"%s\");", $1);

Michael Meskes's avatar
Michael Meskes committed
503
						whenever_action(2);
504
						free($1);
Marc G. Fournier's avatar
Marc G. Fournier committed
505
					}
Michael Meskes's avatar
Michael Meskes committed
506
		| ECPGGetDescriptor	{	
Michael Meskes's avatar
Michael Meskes committed
507 508 509 510
						lookup_descriptor($1.name, connection);
						output_get_descr($1.name, $1.str);
						free($1.name);
						free($1.str);
Michael Meskes's avatar
Michael Meskes committed
511 512
					}
		| ECPGGetDescriptorHeader	{	
Michael Meskes's avatar
Michael Meskes committed
513
						lookup_descriptor($1, connection);
Michael Meskes's avatar
Michael Meskes committed
514
						output_get_descr_header($1);
Michael Meskes's avatar
Michael Meskes committed
515
						free($1);
Michael Meskes's avatar
Michael Meskes committed
516
					}
517 518
		| ECPGOpen		{	
						struct cursor *ptr;
Michael Meskes's avatar
Michael Meskes committed
519 520
						struct arguments *p;
 
521 522 523 524 525 526 527 528 529
						for (ptr = cur; ptr != NULL; ptr=ptr->next)
						{
					               if (strcmp(ptr->name, $1) == 0)
						       		break;
						}
						
						if (ptr == NULL)
						{
							sprintf(errortext, "trying to open undeclared cursor %s\n", $1);
Michael Meskes's avatar
Michael Meskes committed
530
							mmerror(ET_ERROR, errortext);
531
						}
Michael Meskes's avatar
Michael Meskes committed
532 533

						/* merge variables given in prepare statement with those given here */
Michael Meskes's avatar
Michael Meskes committed
534 535
						for (p = ptr->argsinsert; p; p = p->next)
							append_variable(&argsinsert, p->variable, p->indicator); 
Michael Meskes's avatar
Michael Meskes committed
536

Michael Meskes's avatar
Michael Meskes committed
537 538
						for (p = ptr->argsresult; p; p = p->next)
							add_variable(&argsresult, p->variable, p->indicator); 
Michael Meskes's avatar
Michael Meskes committed
539

540
						output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL);
541
					}
542
		| ECPGPrepare		{
543
						if (connection)
Michael Meskes's avatar
Michael Meskes committed
544
							mmerror(ET_ERROR, "no at option for set connection statement.\n");
545

Michael Meskes's avatar
Michael Meskes committed
546 547
						fprintf(yyout, "{ ECPGprepare(__LINE__, %s);", $1); 
						whenever_action(2);
548 549
						free($1);
					}
550
		| ECPGRelease		{ /* output already done */ }
Michael Meskes's avatar
Michael Meskes committed
551
		| ECPGSetAutocommit     {
Michael Meskes's avatar
Michael Meskes committed
552 553
						fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
						whenever_action(2);
Michael Meskes's avatar
Michael Meskes committed
554 555
                                       		free($1);
					}
556
		| ECPGSetConnection     {
557
						if (connection)
Michael Meskes's avatar
Michael Meskes committed
558
							mmerror(ET_ERROR, "no at option for set connection statement.\n");
559

Michael Meskes's avatar
Michael Meskes committed
560 561
						fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
						whenever_action(2);
562 563
                                       		free($1);
					}
564
		| ECPGTypedef		{
565
						if (connection)
Michael Meskes's avatar
Michael Meskes committed
566
							mmerror(ET_ERROR, "no at option for typedef statement.\n");
567

Michael Meskes's avatar
Michael Meskes committed
568
						output_simple_statement($1);
569 570
					}
		| ECPGVar		{
571
						if (connection)
Michael Meskes's avatar
Michael Meskes committed
572
							mmerror(ET_ERROR, "no at option for var statement.\n");
573

Michael Meskes's avatar
Michael Meskes committed
574
						output_simple_statement($1);
575
					}
Marc G. Fournier's avatar
Marc G. Fournier committed
576
		| ECPGWhenever		{
577
						if (connection)
Michael Meskes's avatar
Michael Meskes committed
578
							mmerror(ET_ERROR, "no at option for whenever statement.\n");
579

Michael Meskes's avatar
Michael Meskes committed
580
						output_simple_statement($1);
Marc G. Fournier's avatar
Marc G. Fournier committed
581
					}
582 583
		;

Marc G. Fournier's avatar
Marc G. Fournier committed
584 585 586 587 588 589 590 591 592 593 594 595

/*
 * We start with a lot of stuff that's very similar to the backend's parsing
 */

/*****************************************************************************
 *
 * Create a new Postgres DBMS user
 *
 *
 *****************************************************************************/

596 597 598 599 600
CreateUserStmt: CREATE USER UserId OptUserList
		{
			$$ = cat_str(3, make_str("create user"), $3, $4);
		}
              | CREATE USER UserId WITH OptUserList
Michael Meskes's avatar
Michael Meskes committed
601
		{
602
			$$ = cat_str(4, make_str("create user"), $3, make_str("with"), $5);
Michael Meskes's avatar
Michael Meskes committed
603
		}
Marc G. Fournier's avatar
Marc G. Fournier committed
604 605 606 607
		;

/*****************************************************************************
 *
Michael Meskes's avatar
Michael Meskes committed
608
 * Alter a postgresql DBMS user
Marc G. Fournier's avatar
Marc G. Fournier committed
609 610 611 612
 *
 *
 *****************************************************************************/

613 614 615 616 617 618 619 620
AlterUserStmt: ALTER USER UserId OptUserList
		{
			$$ = cat_str(3, make_str("alter user"), $3, $4);
		}
              | ALTER USER UserId WITH OptUserList
		{
			$$ = cat_str(4, make_str("alter user"), $3, make_str("with"), $5);
		}
Marc G. Fournier's avatar
Marc G. Fournier committed
621 622 623 624
		;

/*****************************************************************************
 *
Michael Meskes's avatar
Michael Meskes committed
625
 * Drop a postgresql DBMS user
Marc G. Fournier's avatar
Marc G. Fournier committed
626 627 628 629
 *
 *
 *****************************************************************************/

Michael Meskes's avatar
Michael Meskes committed
630
DropUserStmt:  DROP USER user_list
Marc G. Fournier's avatar
Marc G. Fournier committed
631
				{
Michael Meskes's avatar
Michael Meskes committed
632
					$$ = cat2_str(make_str("drop user"), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
633 634 635
				}
		;

636 637 638 639 640
/*
 * Options for CREATE USER and ALTER USER
 */
OptUserList: OptUserList OptUserElem		{ $$ = cat2_str($1, $2); }
			| /* EMPTY */					{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
641 642
		;

643 644 645 646 647
OptUserElem:  PASSWORD Sconst
                { 
					$$ = cat2_str(make_str("password"), $2);
				}
              | SYSID Iconst
Marc G. Fournier's avatar
Marc G. Fournier committed
648
				{
649 650 651 652
					$$ = cat2_str(make_str("sysid"), $2);
				}
              | CREATEDB
                { 
Michael Meskes's avatar
Michael Meskes committed
653
					$$ = make_str("createdb");
Marc G. Fournier's avatar
Marc G. Fournier committed
654
				}
655 656
              | NOCREATEDB
                { 
Michael Meskes's avatar
Michael Meskes committed
657
					$$ = make_str("nocreatedb");
Marc G. Fournier's avatar
Marc G. Fournier committed
658
				}
659 660
              | CREATEUSER
                { 
Michael Meskes's avatar
Michael Meskes committed
661
					$$ = make_str("createuser");
Marc G. Fournier's avatar
Marc G. Fournier committed
662
				}
663 664
              | NOCREATEUSER
                { 
Michael Meskes's avatar
Michael Meskes committed
665
					$$ = make_str("nocreateuser");
Marc G. Fournier's avatar
Marc G. Fournier committed
666
				}
667 668 669 670 671 672 673 674 675
              | IN GROUP user_list
                { 
					$$ = cat2_str(make_str("in group"), $3); 
				}
              | VALID UNTIL Sconst
                { 
					$$ = cat2_str(make_str("valid until"), $3); 
				}
        ;
Marc G. Fournier's avatar
Marc G. Fournier committed
676

Michael Meskes's avatar
Michael Meskes committed
677
user_list:  user_list ',' UserId
Marc G. Fournier's avatar
Marc G. Fournier committed
678
				{
Michael Meskes's avatar
Michael Meskes committed
679
					$$ = cat_str(3, $1, make_str(","), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
680 681 682 683 684 685 686
				}
			| UserId
				{
					$$ = $1;
				}
		;

Michael Meskes's avatar
Michael Meskes committed
687 688 689

/*****************************************************************************
 *
Michael Meskes's avatar
Michael Meskes committed
690
 * Create a postgresql group
Michael Meskes's avatar
Michael Meskes committed
691 692 693
 *
 *
 ****************************************************************************/
694
CreateGroupStmt:  CREATE GROUP UserId OptGroupList
695
				{
696
					$$ = cat_str(3, make_str("create group"), $3, $4);
697
				}
698
			| CREATE GROUP UserId WITH OptGroupList
699 700 701
				{
					$$ = cat_str(4, make_str("create group"), $3, make_str("with"), $5);
				}
702 703 704 705 706 707 708 709 710 711 712 713 714 715
		;

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

OptGroupElem:  USER user_list
                { 
					$$ = cat2_str(make_str("user"), $2);
				}
               | SYSID Iconst
716
				{
717
					$$ = cat2_str(make_str("sysid"), $2);
718
				}
719
        ;
Michael Meskes's avatar
Michael Meskes committed
720 721 722 723


/*****************************************************************************
 *
Michael Meskes's avatar
Michael Meskes committed
724
 * Alter a postgresql group
Michael Meskes's avatar
Michael Meskes committed
725 726 727
 *
 *
 *****************************************************************************/
Michael Meskes's avatar
Michael Meskes committed
728
AlterGroupStmt: ALTER GROUP UserId ADD USER user_list
Michael Meskes's avatar
Michael Meskes committed
729 730 731
                {
			$$ = cat_str(4, make_str("alter group"), $3, make_str("add user"), $6);
                }
Michael Meskes's avatar
Michael Meskes committed
732
                | ALTER GROUP UserId DROP USER user_list
Michael Meskes's avatar
Michael Meskes committed
733 734 735 736 737 738 739
                {
			$$ = cat_str(4, make_str("alter group"), $3, make_str("drop user"), $6);
                }
                ;

/*****************************************************************************
 *
Michael Meskes's avatar
Michael Meskes committed
740
 * Drop a postgresql group
Michael Meskes's avatar
Michael Meskes committed
741 742 743 744 745 746 747 748 749
 *
 *
 *****************************************************************************/
DropGroupStmt: DROP GROUP UserId
               {
			$$ = cat2_str(make_str("drop group"), $3);
               }
               ;

Michael Meskes's avatar
Michael Meskes committed
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774
/*****************************************************************************
 *
 * Manipulate a schema
 *
 *
 *****************************************************************************/
 
CreateSchemaStmt:  CREATE SCHEMA UserId 
		{
			$$ = cat2_str(make_str("create scheme"), $3);
		}
		;

AlterSchemaStmt:  ALTER SCHEMA UserId 
		{
			$$ = cat2_str(make_str("alter scheme"), $3);
		}
		;

DropSchemaStmt:  DROP SCHEMA UserId 
		{
			$$ = cat2_str(make_str("drop scheme"), $3);
		}
		;

Marc G. Fournier's avatar
Marc G. Fournier committed
775 776 777 778 779 780 781 782 783 784 785
/*****************************************************************************
 *
 * Set PG internal variable
 *	  SET name TO 'var_value'
 * Include SQL92 syntax (thomas 1997-10-22):
 *    SET TIME ZONE 'var_value'
 *
 *****************************************************************************/

VariableSetStmt:  SET ColId TO var_value
				{
Michael Meskes's avatar
Michael Meskes committed
786
					$$ = cat_str(4, make_str("set"), $2, make_str("to"), $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
787 788 789
				}
		| SET ColId '=' var_value
				{
Michael Meskes's avatar
Michael Meskes committed
790
					$$ = cat_str(4, make_str("set"), $2, make_str("="), $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
791 792 793
				}
		| SET TIME ZONE zone_value
				{
Michael Meskes's avatar
Michael Meskes committed
794
					$$ = cat2_str(make_str("set time zone"), $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
795
				}
Michael Meskes's avatar
Michael Meskes committed
796
		| SET TRANSACTION ISOLATION LEVEL opt_level
797
				{
Michael Meskes's avatar
Michael Meskes committed
798
					$$ = cat2_str(make_str("set transaction isolation level"), $5);
799
				}
800 801 802 803
		| SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL opt_level
				{
					$$ = cat2_str(make_str("set session characteristics as transaction isolation level"), $8);
				}
Michael Meskes's avatar
Michael Meskes committed
804
		| SET NAMES opt_encoding
805
                                {
Michael Meskes's avatar
Michael Meskes committed
806
					$$ = cat2_str(make_str("set names"), $3);
807
                                }
808 809 810 811
		| SET SESSION AUTHORIZATION ColId_or_Sconst 
                                {
					$$ = cat2_str(make_str("set session authorization"), $4);
                                }
812
                ;
Marc G. Fournier's avatar
Marc G. Fournier committed
813

Michael Meskes's avatar
Michael Meskes committed
814 815
opt_level:  READ COMMITTED      { $$ = make_str("read committed"); }
               | SERIALIZABLE   { $$ = make_str("serializable"); }
Michael Meskes's avatar
Michael Meskes committed
816 817 818
               ;


Michael Meskes's avatar
Michael Meskes committed
819
var_value:  opt_boolean		{ $$ = $1; }
820
		| AllConst		{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
821 822 823 824 825 826
		| name_list		{ 
					  if (strlen($1) == 0)
						mmerror(ET_ERROR, "SET must have at least one argument.");

					  $$ = $1;
					}
Michael Meskes's avatar
Michael Meskes committed
827 828 829 830 831 832 833
 		| DEFAULT		{ $$ = make_str("default"); }
		;

opt_boolean:  TRUE_P 		{ $$ = make_str("true"); }
		| FALSE_P	{ $$ = make_str("false"); }
		| ON		{ $$ = make_str("on"); }
		| OFF		{ $$ = make_str("off"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
834 835
		;

836 837 838 839 840
/* Timezone values can be:
* - a string such as 'pst8pdt'
* - an integer or floating point number
* - a time interval per SQL99
*/
841
zone_value:  AllConst		{ $$ = $1; }
842 843 844 845 846 847 848 849
		| ConstInterval StringConst opt_interval
					{
					  $$ = cat_str(3, $1, $2, $3); 
					}
		| ConstInterval '(' PosIntConst ')' StringConst opt_interval
					{
					  $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6);
					}
Michael Meskes's avatar
Michael Meskes committed
850 851
		| DEFAULT		{ $$ = make_str("default"); }
		| LOCAL			{ $$ = make_str("local"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
852 853
		;

854
opt_encoding:	StringConst	 	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
855 856 857 858
		| DEFAULT       { $$ = make_str("default"); }
		| /*EMPTY*/     { $$ = EMPTY; }
		;

859
ColId_or_Sconst: ColId		{ $$ = $1; }
860
		| StringConst	{ $$ = $1; }
861 862
		;

Marc G. Fournier's avatar
Marc G. Fournier committed
863 864
VariableShowStmt:  SHOW ColId
				{
Michael Meskes's avatar
Michael Meskes committed
865
					$$ = cat2_str(make_str("show"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
866 867 868
				}
		| SHOW TIME ZONE
				{
Michael Meskes's avatar
Michael Meskes committed
869
					$$ = make_str("show time zone");
Marc G. Fournier's avatar
Marc G. Fournier committed
870
				}
871 872 873 874
		| SHOW ALL
				{
					$$ = make_str("show all");
				}
875 876
		| SHOW TRANSACTION ISOLATION LEVEL
				{
Michael Meskes's avatar
Michael Meskes committed
877
					$$ = make_str("show transaction isolation level");
878
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
879 880 881 882
		;

VariableResetStmt:	RESET ColId
				{
Michael Meskes's avatar
Michael Meskes committed
883
					$$ = cat2_str(make_str("reset"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
884 885 886
				}
		| RESET TIME ZONE
				{
Michael Meskes's avatar
Michael Meskes committed
887
					$$ = make_str("reset time zone");
Marc G. Fournier's avatar
Marc G. Fournier committed
888
				}
889 890
		| RESET TRANSACTION ISOLATION LEVEL
				{
Michael Meskes's avatar
Michael Meskes committed
891
					$$ = make_str("reset transaction isolation level");
892
				}
893 894 895 896
		| RESET ALL
                                {
                                        $$ = make_str("reset all");
                                }
Marc G. Fournier's avatar
Marc G. Fournier committed
897 898
		;

Michael Meskes's avatar
Michael Meskes committed
899 900
ConstraintsSetStmt:    SET CONSTRAINTS constraints_set_list constraints_set_mode
                               {
Michael Meskes's avatar
Michael Meskes committed
901
					$$ = cat_str(3, make_str("set constraints"), $3, $4);
Michael Meskes's avatar
Michael Meskes committed
902 903 904 905 906
                               }
               ;

constraints_set_list:  ALL
                               {
Michael Meskes's avatar
Michael Meskes committed
907
                                       $$ = make_str("all");
Michael Meskes's avatar
Michael Meskes committed
908 909 910 911 912 913 914 915
                               }
               | constraints_set_namelist
                               {
                                       $$ = $1;
                               }
               ;


916
constraints_set_namelist:      ColId
Michael Meskes's avatar
Michael Meskes committed
917 918 919
                               {
                                       $$ = $1;
                               }
920
               | constraints_set_namelist ',' ColId
Michael Meskes's avatar
Michael Meskes committed
921
                               {
Michael Meskes's avatar
Michael Meskes committed
922
                                       $$ = cat_str(3, $1, make_str(","), $3);
Michael Meskes's avatar
Michael Meskes committed
923 924 925 926 927
                               }
               ;

constraints_set_mode:  DEFERRED
                               {
Michael Meskes's avatar
Michael Meskes committed
928
                                       $$ = make_str("deferred");
Michael Meskes's avatar
Michael Meskes committed
929 930 931
                               }
               | IMMEDIATE
                               {
Michael Meskes's avatar
Michael Meskes committed
932
                                       $$ = make_str("immediate");
Michael Meskes's avatar
Michael Meskes committed
933 934
                               }
               ;
Marc G. Fournier's avatar
Marc G. Fournier committed
935

936 937 938 939 940 941 942
/*
 * Checkpoint statement
 */
CheckPointStmt: CHECKPOINT     { $$= make_str("checkpoint"); }
                        ;  


Marc G. Fournier's avatar
Marc G. Fournier committed
943
/*****************************************************************************
Michael Meskes's avatar
Michael Meskes committed
944 945
 *
 *	ALTER TABLE variations
Marc G. Fournier's avatar
Marc G. Fournier committed
946 947 948
 *
 *****************************************************************************/

Michael Meskes's avatar
Michael Meskes committed
949
AlterTableStmt:
950 951 952 953 954 955 956
/* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
        ALTER TABLE relation_expr ADD opt_column columnDef
		{
			$$ = cat_str(5, make_str("alter table"), $3, make_str("add"), $5, $6);
		}
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
	| ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default
Michael Meskes's avatar
Michael Meskes committed
957
		{
958
			$$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, $7);
Michael Meskes's avatar
Michael Meskes committed
959
		}
960 961
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <Iconst> */
	| ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS Iconst
Michael Meskes's avatar
Michael Meskes committed
962
		{
963
			$$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set statistics"), $9);
Michael Meskes's avatar
Michael Meskes committed
964
		}
965 966
/* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
	| ALTER TABLE relation_expr DROP opt_column ColId drop_behavior
Michael Meskes's avatar
Michael Meskes committed
967
		{
968
			$$ = cat_str(6, make_str("alter table"), $3, make_str("drop"), $5, $6, $7);
Michael Meskes's avatar
Michael Meskes committed
969
		}
970 971
/* ALTER TABLE <relation> ADD CONSTRAINT ... */
	| ALTER TABLE relation_expr ADD TableConstraint
Michael Meskes's avatar
Michael Meskes committed
972
		{
973
			$$ = cat_str(4, make_str("alter table"), $3, make_str("add"), $5);
Michael Meskes's avatar
Michael Meskes committed
974
		}
975 976
/* ALTER TABLE <relation> DROP CONSTRAINT ... */
	| ALTER TABLE relation_expr DROP CONSTRAINT name drop_behavior
Michael Meskes's avatar
Michael Meskes committed
977
		{
978
			$$ = cat_str(5, make_str("alter table"), $3, make_str("drop constraint"), $6, $7);
Michael Meskes's avatar
Michael Meskes committed
979
		}
980 981 982 983 984
/* ALTER TABLE <name> OWNER TO UserId */     
	| ALTER TABLE relation_name OWNER TO UserId   
		{
			$$ = cat_str(4, make_str("alter table"), $3, make_str("owner to"), $6);
		}
Marc G. Fournier's avatar
Marc G. Fournier committed
985 986
		;

987
alter_column_default:
Michael Meskes's avatar
Michael Meskes committed
988
        SET DEFAULT a_expr	{ $$ = cat2_str(make_str("set default"), $3); }
Michael Meskes's avatar
Michael Meskes committed
989 990 991 992 993 994
        | DROP DEFAULT          { $$ = make_str("drop default"); }
        ;

drop_behavior: CASCADE { $$ = make_str("cascade"); }
               | RESTRICT { $$ = make_str("restrict"); }
        ;
Marc G. Fournier's avatar
Marc G. Fournier committed
995 996 997 998 999 1000 1001 1002 1003 1004

/*****************************************************************************
 *
 *		QUERY :
 *				close <optname>
 *
 *****************************************************************************/

ClosePortalStmt:  CLOSE opt_id
				{
Michael Meskes's avatar
Michael Meskes committed
1005
					$$ = cat2_str(make_str("close"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
1006 1007 1008
				}
		;

Michael Meskes's avatar
Michael Meskes committed
1009 1010 1011
opt_id:  ColId		{ $$ = $1; }
	| /*EMPTY*/	{ $$ = NULL; }
	;
Marc G. Fournier's avatar
Marc G. Fournier committed
1012 1013 1014 1015 1016 1017 1018 1019 1020

/*****************************************************************************
 *
 *		QUERY :
 *				COPY [BINARY] <relname> FROM/TO
 *				[USING DELIMITERS <delimiter>]
 *
 *****************************************************************************/

Michael Meskes's avatar
Michael Meskes committed
1021
CopyStmt:  COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
Marc G. Fournier's avatar
Marc G. Fournier committed
1022
				{
Michael Meskes's avatar
Michael Meskes committed
1023
					$$ = cat_str(8, make_str("copy"), $2, $3, $4, $5, $6, $7, $8);
Marc G. Fournier's avatar
Marc G. Fournier committed
1024 1025 1026 1027
				}
		;

copy_dirn:	TO
Michael Meskes's avatar
Michael Meskes committed
1028
				{ $$ = make_str("to"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1029
		| FROM
Michael Meskes's avatar
Michael Meskes committed
1030
				{ $$ = make_str("from"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1031 1032 1033 1034 1035 1036 1037
		;

/*
 * 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
 * stdout. We silently correct the "typo".		 - AY 9/94
 */
1038
copy_file_name:  StringConst					{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
1039 1040
		| STDIN					{ $$ = make_str("stdin"); }
		| STDOUT				{ $$ = make_str("stdout"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1041 1042
		;

Michael Meskes's avatar
Michael Meskes committed
1043
opt_binary:  BINARY					{ $$ = make_str("binary"); }
Michael Meskes's avatar
Michael Meskes committed
1044
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1045 1046
		;

Michael Meskes's avatar
Michael Meskes committed
1047
opt_with_copy:	WITH OIDS				{ $$ = make_str("with oids"); }
Michael Meskes's avatar
Michael Meskes committed
1048
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1049 1050 1051 1052 1053
		;

/*
 * the default copy delimiter is tab but the user can configure it
 */
1054
copy_delimiter:  opt_using DELIMITERS StringConst		{ $$ = cat_str(3, $1, make_str("delimiters"), $3); }
Michael Meskes's avatar
Michael Meskes committed
1055
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1056 1057
		;

Michael Meskes's avatar
Michael Meskes committed
1058
opt_using:	USING		{ $$ = make_str("using"); }
Michael Meskes's avatar
Michael Meskes committed
1059
		| /* EMPTY */	{ $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
1060 1061
		;

1062
copy_null:	WITH NULL_P AS StringConst	{ $$ = cat2_str(make_str("with null as"), $4); }
Michael Meskes's avatar
Michael Meskes committed
1063 1064
		| /* EMPTY */   { $$ = EMPTY; }
		;
Marc G. Fournier's avatar
Marc G. Fournier committed
1065 1066 1067 1068 1069 1070 1071 1072

/*****************************************************************************
 *
 *		QUERY :
 *				CREATE relname
 *
 *****************************************************************************/

1073
CreateStmt:  CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
1074
				OptInherit OptWithOids
Marc G. Fournier's avatar
Marc G. Fournier committed
1075
				{
1076
					$$ = cat_str(9, make_str("create"), $2, make_str("table"), $4, make_str("("), $6, make_str(")"), $8, $9);
Marc G. Fournier's avatar
Marc G. Fournier committed
1077 1078 1079
				}
		;

Michael Meskes's avatar
Michael Meskes committed
1080 1081 1082 1083
/*
 * Redundancy here is needed to avoid shift/reduce conflicts,
 * since TEMP is not a reserved word.  See also OptTempTableName.
 */
Michael Meskes's avatar
Michael Meskes committed
1084

Michael Meskes's avatar
Michael Meskes committed
1085 1086 1087 1088 1089
OptTemp:  	TEMPORARY		{ $$ = make_str("temporary"); }
		| TEMP			{ $$ = make_str("temp"); }
		| LOCAL TEMPORARY	{ $$ = make_str("local temporary"); }
		| LOCAL TEMP		{ $$ = make_str("local temp"); }
		| GLOBAL TEMPORARY	{
1090
					  mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
Michael Meskes's avatar
Michael Meskes committed
1091 1092 1093
					  $$ = make_str("global temporary");
					}
		| GLOBAL TEMP		{
1094
					  mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
Michael Meskes's avatar
Michael Meskes committed
1095 1096 1097
					  $$ = make_str("global temp");
					}
		| /*EMPTY*/		{ $$ = EMPTY; }
1098 1099
		;

Marc G. Fournier's avatar
Marc G. Fournier committed
1100 1101
OptTableElementList:  OptTableElementList ',' OptTableElement
				{
Michael Meskes's avatar
Michael Meskes committed
1102
					$$ = cat_str(3, $1, make_str(","), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
1103 1104 1105 1106 1107
				}
			| OptTableElement
				{
					$$ = $1;
				}
Michael Meskes's avatar
Michael Meskes committed
1108
			| /*EMPTY*/	{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1109 1110 1111 1112 1113 1114
		;

OptTableElement:  columnDef		{ $$ = $1; }
			| TableConstraint	{ $$ = $1; }
		;

Michael Meskes's avatar
Michael Meskes committed
1115
columnDef:  ColId Typename ColQualList opt_collate
Marc G. Fournier's avatar
Marc G. Fournier committed
1116
				{
Michael Meskes's avatar
Michael Meskes committed
1117 1118
					if (strlen($4) > 0)
					{
1119
 						sprintf(errortext, "Currently unsupported CREATE TABLE / COLLATE %s will be passed to backend", $4);
1120
 						mmerror(ET_NOTICE, errortext);
Michael Meskes's avatar
Michael Meskes committed
1121 1122
					}
					$$ = cat_str(4, $1, $2, $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
1123 1124 1125
				}
		;

Michael Meskes's avatar
Michael Meskes committed
1126
ColQualList:  ColQualList ColConstraint	{ $$ = cat2_str($1,$2); }
Michael Meskes's avatar
Michael Meskes committed
1127
			| /*EMPTY*/	{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1128 1129
		;

Michael Meskes's avatar
Michael Meskes committed
1130
ColConstraint:	CONSTRAINT name ColConstraintElem
Marc G. Fournier's avatar
Marc G. Fournier committed
1131
				{
Michael Meskes's avatar
Michael Meskes committed
1132
					$$ = cat_str(3, make_str("constraint"), $2, $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
1133 1134 1135
				}
		| ColConstraintElem
				{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
1136 1137
		| ConstraintAttr
				{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
1138 1139 1140 1141
		;

/* DEFAULT NULL is already the default for Postgres.
 * But define it here and carry it forward into the system
1142 1143
 * to make it explicit.
 * - thomas 1998-09-13
Michael Meskes's avatar
Michael Meskes committed
1144
 *
1145 1146 1147 1148 1149
 * 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
1150
 */
Michael Meskes's avatar
Michael Meskes committed
1151 1152 1153 1154 1155 1156 1157 1158 1159
ColConstraintElem: 	NOT NULL_P
				{
					$$ = make_str("not null");
				}
			| NULL_P
				{
					$$ = make_str("null");
				}
			| UNIQUE
Michael Meskes's avatar
Michael Meskes committed
1160 1161 1162
				{
					$$ = make_str("unique");
				}
Michael Meskes's avatar
Michael Meskes committed
1163
			| PRIMARY KEY
Michael Meskes's avatar
Michael Meskes committed
1164
				{
Michael Meskes's avatar
Michael Meskes committed
1165
					$$ = make_str("primary key");
Michael Meskes's avatar
Michael Meskes committed
1166
				}
Michael Meskes's avatar
Michael Meskes committed
1167
			| CHECK '(' a_expr ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
1168
				{
Michael Meskes's avatar
Michael Meskes committed
1169
					$$ = cat_str(3, make_str("check ("), $3, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
1170
				}
Michael Meskes's avatar
Michael Meskes committed
1171
			| DEFAULT b_expr
Marc G. Fournier's avatar
Marc G. Fournier committed
1172
				{
Michael Meskes's avatar
Michael Meskes committed
1173
					$$ = cat2_str(make_str("default"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
1174
				}
Michael Meskes's avatar
Michael Meskes committed
1175 1176 1177 1178 1179
			|  REFERENCES ColId opt_column_list key_match key_actions 
				{
					$$ = cat_str(5, make_str("references"), $2, $3, $4, $5);  
				}
			;
Michael Meskes's avatar
Michael Meskes committed
1180

Michael Meskes's avatar
Michael Meskes committed
1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196
/*
 * 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		{ $$ = make_str("deferrable"); }
		| NOT DEFERRABLE	{ $$ = make_str("not deferrable"); }
		| INITIALLY DEFERRED	{ $$ = make_str("initially deferred"); }
		| INITIALLY IMMEDIATE	{ $$ = make_str("initially immediate"); }
		;
Michael Meskes's avatar
Michael Meskes committed
1197

Marc G. Fournier's avatar
Marc G. Fournier committed
1198 1199 1200 1201 1202 1203
/* 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
				{
Michael Meskes's avatar
Michael Meskes committed
1204
						$$ = cat_str(3, make_str("constraint"), $2, $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
1205 1206 1207 1208 1209
				}
		| ConstraintElem
				{ $$ = $1; }
		;

Michael Meskes's avatar
Michael Meskes committed
1210
ConstraintElem:  CHECK '(' a_expr ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
1211
				{
Michael Meskes's avatar
Michael Meskes committed
1212
					$$ = cat_str(3, make_str("check("), $3, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
1213 1214 1215
				}
		| UNIQUE '(' columnList ')'
				{
Michael Meskes's avatar
Michael Meskes committed
1216
					$$ = cat_str(3, make_str("unique("), $3, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
1217
				}
Michael Meskes's avatar
Michael Meskes committed
1218
		| PRIMARY KEY '(' columnList ')'
Michael Meskes's avatar
Michael Meskes committed
1219
				{
Michael Meskes's avatar
Michael Meskes committed
1220
					$$ = cat_str(3, make_str("primary key("), $4, make_str(")"));
Michael Meskes's avatar
Michael Meskes committed
1221 1222
				}
		| FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list
Michael Meskes's avatar
Michael Meskes committed
1223
			key_match key_actions ConstraintAttributeSpec
Marc G. Fournier's avatar
Marc G. Fournier committed
1224
				{
Michael Meskes's avatar
Michael Meskes committed
1225
					$$ = cat_str(8, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10, $11);
Marc G. Fournier's avatar
Marc G. Fournier committed
1226 1227 1228
				}
		;

Michael Meskes's avatar
Michael Meskes committed
1229 1230
key_match:  MATCH FULL
		{
Michael Meskes's avatar
Michael Meskes committed
1231
			 $$ = make_str("match full");
Michael Meskes's avatar
Michael Meskes committed
1232 1233 1234
		}
		| MATCH PARTIAL		
		{
1235
			mmerror(ET_NOTICE, "Currently unsupported FOREIGN KEY/MATCH PARTIAL will be passed to backend");
Michael Meskes's avatar
Michael Meskes committed
1236
			$$ = make_str("match partial");
Michael Meskes's avatar
Michael Meskes committed
1237 1238 1239 1240 1241
		}
		| /*EMPTY*/
		{
			$$ = EMPTY;
		}
Marc G. Fournier's avatar
Marc G. Fournier committed
1242 1243
		;

Michael Meskes's avatar
Michael Meskes committed
1244 1245 1246 1247
key_actions:  key_delete		{ $$ = $1; }
		| key_update		{ $$ = $1; }
		| key_delete key_update	{ $$ = cat2_str($1, $2); }
		| key_update key_delete	{ $$ = cat2_str($1, $2); }
Michael Meskes's avatar
Michael Meskes committed
1248
		| /*EMPTY*/		{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1249 1250
		;

Michael Meskes's avatar
Michael Meskes committed
1251 1252 1253
key_delete: ON DELETE key_reference	{ $$ = cat2_str(make_str("on delete"), $3); }

key_update: ON UPDATE key_reference	{ $$ = cat2_str(make_str("on update"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1254

Michael Meskes's avatar
Michael Meskes committed
1255 1256 1257 1258 1259
key_reference:  NO ACTION	{ $$ = make_str("no action"); }
		| RESTRICT	{ $$ = make_str("restrict"); }
		| CASCADE	{ $$ = make_str("cascade"); }
		| SET DEFAULT	{ $$ = make_str("set default"); }
		| SET NULL_P	{ $$ = make_str("set null"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1260 1261
		;

Michael Meskes's avatar
Michael Meskes committed
1262 1263
OptInherit:  INHERITS '(' relation_name_list ')'                { $$ = cat_str(3, make_str("inherits ("), $3, make_str(")")); }
                | /*EMPTY*/					{ $$ = EMPTY; }
1264 1265 1266 1267 1268 1269 1270
                ;

OptWithOids:  WITH OIDS						{ $$ = make_str("with oids"); }
			| WITHOUT OIDS					{ $$ = make_str("without oids"); }
			| /*EMPTY*/						{ $$ = EMPTY; }
		;

Marc G. Fournier's avatar
Marc G. Fournier committed
1271

Michael Meskes's avatar
Michael Meskes committed
1272 1273 1274 1275 1276
/*
 * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
 * SELECT ... INTO.
 */

1277 1278
CreateAsStmt:  CREATE OptTemp TABLE relation_name OptCreateAs AS
		{ FoundInto = 0; } SelectStmt
Marc G. Fournier's avatar
Marc G. Fournier committed
1279
		{
Michael Meskes's avatar
Michael Meskes committed
1280
			if (FoundInto == 1)
1281
				mmerror(ET_ERROR, "CREATE TABLE / AS SELECT may not specify INTO");
Michael Meskes's avatar
Michael Meskes committed
1282

1283
			$$ = cat_str(7, make_str("create"), $2, make_str("table"), $4, $5, make_str("as"), $8); 
Marc G. Fournier's avatar
Marc G. Fournier committed
1284 1285 1286
		}
		;

Michael Meskes's avatar
Michael Meskes committed
1287
OptCreateAs:  '(' CreateAsList ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
Michael Meskes's avatar
Michael Meskes committed
1288
			| /*EMPTY*/ { $$ = EMPTY; }	
Marc G. Fournier's avatar
Marc G. Fournier committed
1289 1290
		;

Michael Meskes's avatar
Michael Meskes committed
1291
CreateAsList:  CreateAsList ',' CreateAsElement	{ $$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304
			| CreateAsElement	{ $$ = $1; }
		;

CreateAsElement:  ColId { $$ = $1; }
		;

/*****************************************************************************
 *
 *		QUERY :
 *				CREATE SEQUENCE seqname
 *
 *****************************************************************************/

1305
CreateSeqStmt:  CREATE OptTemp SEQUENCE relation_name OptSeqList
Marc G. Fournier's avatar
Marc G. Fournier committed
1306
				{
1307
					$$ = cat_str(4, make_str("create sequence"), $2, $4, $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
1308 1309 1310 1311
				}
		;

OptSeqList:  OptSeqList OptSeqElem
1312
				{ $$ = cat2_str($1, $2); }
Michael Meskes's avatar
Michael Meskes committed
1313
			|	{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1314 1315
		;

1316
OptSeqElem:  CACHE NumConst
Marc G. Fournier's avatar
Marc G. Fournier committed
1317
				{
Michael Meskes's avatar
Michael Meskes committed
1318
					$$ = cat2_str(make_str("cache"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
1319 1320 1321
				}
			| CYCLE
				{
Michael Meskes's avatar
Michael Meskes committed
1322
					$$ = make_str("cycle");
Marc G. Fournier's avatar
Marc G. Fournier committed
1323
				}
1324
			| INCREMENT NumConst
Marc G. Fournier's avatar
Marc G. Fournier committed
1325
				{
Michael Meskes's avatar
Michael Meskes committed
1326
					$$ = cat2_str(make_str("increment"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
1327
				}
1328
			| MAXVALUE NumConst
Marc G. Fournier's avatar
Marc G. Fournier committed
1329
				{
Michael Meskes's avatar
Michael Meskes committed
1330
					$$ = cat2_str(make_str("maxvalue"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
1331
				}
1332
			| MINVALUE NumConst
Marc G. Fournier's avatar
Marc G. Fournier committed
1333
				{
Michael Meskes's avatar
Michael Meskes committed
1334
					$$ = cat2_str(make_str("minvalue"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
1335
				}
1336
			| START NumConst
Marc G. Fournier's avatar
Marc G. Fournier committed
1337
				{
Michael Meskes's avatar
Michael Meskes committed
1338
					$$ = cat2_str(make_str("start"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349
				}
		;

/*****************************************************************************
 *
 *		QUERIES :
 *				CREATE PROCEDURAL LANGUAGE ...
 *				DROP PROCEDURAL LANGUAGE ...
 *
 *****************************************************************************/

1350 1351
CreatePLangStmt:  CREATE opt_Trusted opt_procedural LANGUAGE ColId_or_Sconst
			HANDLER func_name opt_lancompiler
Marc G. Fournier's avatar
Marc G. Fournier committed
1352
			{
1353
				$$ = cat_str(8, make_str("create"), $2, $3, make_str("language"), $5, make_str("handler"), $7, $8);
Marc G. Fournier's avatar
Marc G. Fournier committed
1354 1355 1356
			}
		;

1357
opt_Trusted:		TRUSTED { $$ = make_str("trusted"); }
Michael Meskes's avatar
Michael Meskes committed
1358
			|	{ $$ = EMPTY; }
1359
			;
Marc G. Fournier's avatar
Marc G. Fournier committed
1360

1361 1362 1363 1364
opt_lancompiler: LANCOMPILER StringConst 	{ $$ = cat2_str(make_str("lancompiler"), $2); }
                        | /*EMPTY*/              { $$ = ""; }
			;

1365
DropPLangStmt:  DROP opt_procedural LANGUAGE StringConst
Marc G. Fournier's avatar
Marc G. Fournier committed
1366
			{
1367
				$$ = cat_str(4, make_str("drop"), $2, make_str("language"), $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
1368 1369 1370
			}
		;

1371 1372 1373 1374
opt_procedural: PROCEDURAL             { $$ = make_str("prcedural"); }
                       | /*EMPTY*/     { $$ = EMPTY; }
               ;

Marc G. Fournier's avatar
Marc G. Fournier committed
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386
/*****************************************************************************
 *
 *		QUERIES :
 *				CREATE TRIGGER ...
 *				DROP TRIGGER ...
 *
 *****************************************************************************/

CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
				relation_name TriggerForSpec EXECUTE PROCEDURE
				name '(' TriggerFuncArgs ')'
				{
Michael Meskes's avatar
Michael Meskes committed
1387
					$$ = cat_str(12, make_str("create trigger"), $3, $4, $5, make_str("on"), $7, $8, make_str("execute procedure"), $11, make_str("("), $13, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
1388
				}
Michael Meskes's avatar
Michael Meskes committed
1389
	|	CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
Michael Meskes's avatar
Michael Meskes committed
1390
                                relation_name OptConstrFromTable
Michael Meskes's avatar
Michael Meskes committed
1391
				ConstraintAttributeSpec
Michael Meskes's avatar
Michael Meskes committed
1392 1393 1394
                                FOR EACH ROW EXECUTE PROCEDURE
				name '(' TriggerFuncArgs ')'
				{
Michael Meskes's avatar
Michael Meskes committed
1395
					$$ = cat_str(13, make_str("create constraint trigger"), $4, make_str("after"), $6, make_str("on"), $8, $9, $10, make_str("for each row execute procedure"), $16, make_str("("), $18, make_str(")"));
Michael Meskes's avatar
Michael Meskes committed
1396
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
1397 1398
		;

Michael Meskes's avatar
Michael Meskes committed
1399 1400
TriggerActionTime:  BEFORE				{ $$ = make_str("before"); }
			| AFTER				{ $$ = make_str("after"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1401 1402 1403 1404 1405 1406 1407 1408
		;

TriggerEvents:	TriggerOneEvent
				{
					$$ = $1;
				}
			| TriggerOneEvent OR TriggerOneEvent
				{
Michael Meskes's avatar
Michael Meskes committed
1409
					$$ = cat_str(3, $1, make_str("or"), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
1410 1411 1412
				}
			| TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
				{
Michael Meskes's avatar
Michael Meskes committed
1413
					$$ = cat_str(5, $1, make_str("or"), $3, make_str("or"), $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
1414 1415 1416
				}
		;

Michael Meskes's avatar
Michael Meskes committed
1417 1418 1419
TriggerOneEvent:  INSERT				{ $$ = make_str("insert"); }
			| DELETE			{ $$ = make_str("delete"); }
			| UPDATE			{ $$ = make_str("update"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1420 1421 1422 1423
		;

TriggerForSpec:  FOR TriggerForOpt TriggerForType
				{
Michael Meskes's avatar
Michael Meskes committed
1424
					$$ = cat_str(3, make_str("for"), $2, $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
1425 1426 1427
				}
		;

Michael Meskes's avatar
Michael Meskes committed
1428
TriggerForOpt:  EACH					{ $$ = make_str("each"); }
Michael Meskes's avatar
Michael Meskes committed
1429
			| /*EMPTY*/			{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1430 1431
		;

Michael Meskes's avatar
Michael Meskes committed
1432 1433
TriggerForType:  ROW					{ $$ = make_str("row"); }
			| STATEMENT			{ $$ = make_str("statement"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1434 1435 1436
		;

TriggerFuncArgs:  TriggerFuncArg
1437
				{ $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1438
			| TriggerFuncArgs ',' TriggerFuncArg
Michael Meskes's avatar
Michael Meskes committed
1439
				{ $$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1440
			| /*EMPTY*/
Michael Meskes's avatar
Michael Meskes committed
1441
				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1442 1443
		;

1444
TriggerFuncArg:  PosAllConst
Marc G. Fournier's avatar
Marc G. Fournier committed
1445
				{
1446
					$$ = $1;
Marc G. Fournier's avatar
Marc G. Fournier committed
1447
				}
Michael Meskes's avatar
Michael Meskes committed
1448
			| ColId		{  $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1449 1450
		;

Michael Meskes's avatar
Michael Meskes committed
1451 1452
OptConstrFromTable:                     /* Empty */
                                {
Michael Meskes's avatar
Michael Meskes committed
1453
                                        $$ = EMPTY;
Michael Meskes's avatar
Michael Meskes committed
1454 1455 1456
                                }
                | FROM relation_name
                                {
Michael Meskes's avatar
Michael Meskes committed
1457
                                        $$ = cat2_str(make_str("from"), $2);
Michael Meskes's avatar
Michael Meskes committed
1458 1459 1460
                                }
                ;

Michael Meskes's avatar
Michael Meskes committed
1461
ConstraintAttributeSpec: ConstraintDeferrabilitySpec
Michael Meskes's avatar
Michael Meskes committed
1462
                { 	$$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
1463 1464
	| ConstraintDeferrabilitySpec ConstraintTimeSpec
		{	
Michael Meskes's avatar
Michael Meskes committed
1465 1466 1467
			if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 )
				mmerror(ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");

Michael Meskes's avatar
Michael Meskes committed
1468
			$$ = cat2_str($1, $2);
Michael Meskes's avatar
Michael Meskes committed
1469
		}
Michael Meskes's avatar
Michael Meskes committed
1470 1471 1472
	| ConstraintTimeSpec
		{ 	$$ = $1; }
	| ConstraintTimeSpec ConstraintDeferrabilitySpec
Michael Meskes's avatar
Michael Meskes committed
1473 1474 1475 1476 1477 1478 1479 1480
		{
			if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
				mmerror(ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");

                	$$ = cat2_str($1, $2);
		}
	;

Michael Meskes's avatar
Michael Meskes committed
1481
ConstraintDeferrabilitySpec: NOT DEFERRABLE	{ $$ = make_str("not deferrable"); }
Michael Meskes's avatar
Michael Meskes committed
1482
	                | DEFERRABLE	{ $$ = make_str("deferrable"); }
Michael Meskes's avatar
Michael Meskes committed
1483 1484
                ;

Michael Meskes's avatar
Michael Meskes committed
1485
ConstraintTimeSpec: INITIALLY IMMEDIATE		{ $$ = make_str("initially immediate"); }
1486
                | INITIALLY DEFERRED	{ $$ = make_str("initially deferred"); }
Michael Meskes's avatar
Michael Meskes committed
1487 1488
                ;

Marc G. Fournier's avatar
Marc G. Fournier committed
1489 1490
DropTrigStmt:  DROP TRIGGER name ON relation_name
				{
Michael Meskes's avatar
Michael Meskes committed
1491
					$$ = cat_str(4, make_str("drop trigger"), $3, make_str("on"), $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
1492 1493 1494 1495 1496 1497 1498 1499 1500 1501
				}
		;

/*****************************************************************************
 *
 *		QUERY :
 *				define (type,operator,aggregate)
 *
 *****************************************************************************/

1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513
DefineStmt:  CREATE AGGREGATE func_name definition
		{
			$$ = cat_str(3, make_str("create aggregate"), $3, $4);
		}
                | CREATE OPERATOR all_Op definition
		{
			$$ = cat_str(3, make_str("create operator"), $3, $4);
		}
                | CREATE TYPE_P name definition  
		{
			$$ = cat_str(3, make_str("create type"), $3, $4);
		}
Marc G. Fournier's avatar
Marc G. Fournier committed
1514 1515
		;

Michael Meskes's avatar
Michael Meskes committed
1516
definition:  '(' def_list ')'				{ $$ = cat_str(3, make_str("("), $2, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1517 1518 1519
		;

def_list:  def_elem					{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
1520
		| def_list ',' def_elem			{ $$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1521 1522
		;

1523
def_elem:  ColLabel '=' def_arg	{
Michael Meskes's avatar
Michael Meskes committed
1524
					$$ = cat_str(3, $1, make_str("="), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
1525
				}
1526
		| ColLabel
Marc G. Fournier's avatar
Marc G. Fournier committed
1527 1528 1529 1530 1531
				{
					$$ = $1;
				}
		;

1532
/* Note: any simple identifier will be returned as a type name! */
Michael Meskes's avatar
Michael Meskes committed
1533
def_arg:  func_return		{  $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1534
		| all_Op	{  $$ = $1; }
1535
		| AllConst	{  $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1536 1537 1538 1539 1540
		;

/*****************************************************************************
 *
 *		QUERY:
1541 1542
 *
 *             DROP itemtype itemname [, itemname ...]       
Marc G. Fournier's avatar
Marc G. Fournier committed
1543 1544 1545
 *
 *****************************************************************************/

1546
DropStmt:  DROP drop_type relation_name_list
Marc G. Fournier's avatar
Marc G. Fournier committed
1547
				{
1548
					$$ = cat_str(3, make_str("drop"), $2, $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
1549 1550 1551
				}
		;

1552 1553 1554 1555 1556 1557 1558 1559
drop_type:	TABLE		{ $$ = make_str("table"); }
	|	SEQUENCE	{ $$ = make_str("sequence"); }
	|	VIEW		{ $$ = make_str("view"); }
	|	INDEX		{ $$ = make_str("index"); }
	|	RULE		{ $$ = make_str("rule"); }
	|	TYPE_P		{ $$ = make_str("type"); }
	;

Michael Meskes's avatar
Michael Meskes committed
1560 1561 1562 1563 1564 1565
/*****************************************************************************
 *
 *             QUERY:
 *                             truncate table relname
 *
 *****************************************************************************/
Michael Meskes's avatar
Michael Meskes committed
1566
TruncateStmt:  TRUNCATE opt_table relation_name
Michael Meskes's avatar
Michael Meskes committed
1567
                               {
Michael Meskes's avatar
Michael Meskes committed
1568
					$$ = cat2_str(make_str("truncate table"), $3);
Michael Meskes's avatar
Michael Meskes committed
1569 1570
                               }
                       ;
Marc G. Fournier's avatar
Marc G. Fournier committed
1571 1572 1573 1574

/*****************************************************************************
 *
 *		QUERY:
1575 1576 1577
 *                     fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
 *                     fetch [ forward | backward | absolute | relative ]
 *                           [ # | all | next | prior ] [ [ in | from ] <portalname> ]
Marc G. Fournier's avatar
Marc G. Fournier committed
1578 1579 1580
 *
 *****************************************************************************/

1581
FetchStmt: FETCH direction fetch_how_many from_in name ecpg_into
Marc G. Fournier's avatar
Marc G. Fournier committed
1582
				{
Michael Meskes's avatar
Michael Meskes committed
1583 1584
					if (strcmp($2, "relative") == 0 && atol($3) == 0L)
						mmerror(ET_ERROR, "FETCH/RELATIVE at current position is not supported");
1585

Michael Meskes's avatar
Michael Meskes committed
1586 1587
					$$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5);
				}
1588
		| FETCH fetch_how_many from_in name ecpg_into
Michael Meskes's avatar
Michael Meskes committed
1589
  				{
Michael Meskes's avatar
Michael Meskes committed
1590
					$$ = cat_str(4, make_str("fetch"), $2, $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
1591
				}
1592
		| FETCH direction from_in name ecpg_into
Michael Meskes's avatar
Michael Meskes committed
1593
  				{
Michael Meskes's avatar
Michael Meskes committed
1594
					$$ = cat_str(4, make_str("fetch"), $2, $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
1595
				}
1596
		| FETCH from_in name ecpg_into
Michael Meskes's avatar
Michael Meskes committed
1597 1598 1599
  				{
					$$ = cat_str(3, make_str("fetch"), $2, $3);
				}
1600
		| FETCH name ecpg_into
Michael Meskes's avatar
Michael Meskes committed
1601 1602 1603
  				{
					$$ = cat2_str(make_str("fetch"), $2);
				}
Michael Meskes's avatar
Michael Meskes committed
1604
		| MOVE direction fetch_how_many from_in name
Michael Meskes's avatar
Michael Meskes committed
1605 1606 1607
				{
					$$ = cat_str(5, make_str("move"), $2, $3, $4, $5);
				}
Michael Meskes's avatar
Michael Meskes committed
1608
		| MOVE fetch_how_many from_in name
Michael Meskes's avatar
Michael Meskes committed
1609 1610 1611
				{
					$$ = cat_str(4, make_str("move"), $2, $3, $4);
				}
Michael Meskes's avatar
Michael Meskes committed
1612
		| MOVE direction from_in name
Michael Meskes's avatar
Michael Meskes committed
1613 1614 1615
				{
					$$ = cat_str(4, make_str("move"), $2, $3, $4);
				}
Michael Meskes's avatar
Michael Meskes committed
1616
		| MOVE from_in name
Michael Meskes's avatar
Michael Meskes committed
1617 1618 1619
				{
					$$ = cat_str(3, make_str("move"), $2, $3);
				}
Michael Meskes's avatar
Michael Meskes committed
1620
		| MOVE name
Michael Meskes's avatar
Michael Meskes committed
1621 1622 1623
				{
					$$ = cat2_str(make_str("move"), $2);
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
1624 1625
		;

Michael Meskes's avatar
Michael Meskes committed
1626
direction:	FORWARD		{ $$ = make_str("forward"); }
Michael Meskes's avatar
Michael Meskes committed
1627 1628
		| BACKWARD	{ $$ = make_str("backward"); }
		| RELATIVE      { $$ = make_str("relative"); }
Michael Meskes's avatar
Michael Meskes committed
1629
                | ABSOLUTE	{
1630
					mmerror(ET_NOTICE, "Currently unsupported FETCH/ABSOLUTE will be passed to backend, backend will use RELATIVE");
Michael Meskes's avatar
Michael Meskes committed
1631
					$$ = make_str("absolute");
1632
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
1633 1634
		;

1635
fetch_how_many:   IntConst        { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
1636 1637 1638
		| ALL		{ $$ = make_str("all"); }
		| NEXT		{ $$ = make_str("next"); }
		| PRIOR		{ $$ = make_str("prior"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1639 1640
		;

Michael Meskes's avatar
Michael Meskes committed
1641 1642 1643
from_in:   IN 	{ $$ = make_str("in"); }
	| FROM	{ $$ = make_str("from"); }
	;
Marc G. Fournier's avatar
Marc G. Fournier committed
1644

Michael Meskes's avatar
Michael Meskes committed
1645 1646
/*****************************************************************************
 *
Michael Meskes's avatar
Michael Meskes committed
1647 1648 1649 1650
 *  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:
 *
 *  COMMENT ON [ [ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ]
1651
 *               <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION
Michael Meskes's avatar
Michael Meskes committed
1652 1653 1654
 *              <funcname> (arg1, arg2, ...) | OPERATOR <op>
 *              (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
 *              <relname> ] IS 'text'
Michael Meskes's avatar
Michael Meskes committed
1655 1656
 *
 *****************************************************************************/
Michael Meskes's avatar
Michael Meskes committed
1657
CommentStmt:   COMMENT ON comment_type name IS comment_text
Michael Meskes's avatar
Michael Meskes committed
1658
                        {
Michael Meskes's avatar
Michael Meskes committed
1659
                                $$ = cat_str(5, make_str("comment on"), $3, $4, make_str("is"), $6);
Michael Meskes's avatar
Michael Meskes committed
1660
                        }
1661
                | COMMENT ON COLUMN relation_name '.' attr_name IS comment_text
Michael Meskes's avatar
Michael Meskes committed
1662
                        { 
1663
                                $$ = cat_str(6, make_str("comment on column"), $4, make_str("."), $6, make_str("is"), $8);
Michael Meskes's avatar
Michael Meskes committed
1664
			}
1665
                | COMMENT ON AGGREGATE name '(' aggr_argtype ')' IS comment_text
Michael Meskes's avatar
Michael Meskes committed
1666
                        {
1667
                                $$ = cat_str(6, make_str("comment on aggregate"), $4, make_str("("), $6, make_str(") is"), $9);
Michael Meskes's avatar
Michael Meskes committed
1668
			}
1669 1670 1671 1672 1673
                | COMMENT ON AGGREGATE name aggr_argtype IS comment_text
                        {
                                $$ = cat_str(5, make_str("comment on aggregate"), $4, $5, make_str("is"), $7);
			}
		| COMMENT ON FUNCTION func_name func_args IS comment_text
Michael Meskes's avatar
Michael Meskes committed
1674
			{
1675
                                $$ = cat_str(5, make_str("comment on function"), $4, $5, make_str("is"), $7);
Michael Meskes's avatar
Michael Meskes committed
1676
			}
1677
		| COMMENT ON OPERATOR all_Op '(' oper_argtypes ')' IS comment_text
Michael Meskes's avatar
Michael Meskes committed
1678
			{
1679
				$$ = cat_str(6, make_str("comment on operator"), $4, make_str("("), $6, make_str(") is"), $9);
Michael Meskes's avatar
Michael Meskes committed
1680
			}
1681
		| COMMENT ON TRIGGER name ON relation_name IS comment_text
Michael Meskes's avatar
Michael Meskes committed
1682
                        {
1683
                                $$ = cat_str(6, make_str("comment on trigger"), $4, make_str("on"), $6, make_str("is"), $8);
Michael Meskes's avatar
Michael Meskes committed
1684 1685
			}
			;
Michael Meskes's avatar
Michael Meskes committed
1686

Michael Meskes's avatar
Michael Meskes committed
1687 1688 1689 1690 1691 1692 1693
comment_type:  DATABASE 	{ $$ = make_str("database"); }
                | INDEX		{ $$ = make_str("idnex"); }
                | RULE		{ $$ = make_str("rule"); }
                | SEQUENCE	{ $$ = make_str("sequence"); }
                | TABLE		{ $$ = make_str("table"); }
                | TYPE_P	{ $$ = make_str("type"); }
                | VIEW		{ $$ = make_str("view"); }
Michael Meskes's avatar
Michael Meskes committed
1694 1695
		;

1696
comment_text:    StringConst		{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
1697
               | NULL_P		{ $$ = make_str("null"); }
Michael Meskes's avatar
Michael Meskes committed
1698 1699
               ;

Marc G. Fournier's avatar
Marc G. Fournier committed
1700 1701 1702
/*****************************************************************************
 *
 *		QUERY:
1703
 * GRANT [privileges] ON [TABLE] relation_name_list TO [GROUP] grantee, ...
Marc G. Fournier's avatar
Marc G. Fournier committed
1704 1705 1706
 *
 *****************************************************************************/

1707
GrantStmt:  GRANT privileges ON opt_table relation_name_list TO grantee_list opt_with_grant
Marc G. Fournier's avatar
Marc G. Fournier committed
1708
				{
1709
					$$ = cat_str(8, make_str("grant"), $2, make_str("on"), $4, $5, make_str("to"), $7, $8);
Marc G. Fournier's avatar
Marc G. Fournier committed
1710 1711 1712 1713 1714
				}
		;

privileges:  ALL PRIVILEGES
				{
Michael Meskes's avatar
Michael Meskes committed
1715
				 $$ = make_str("all privileges");
Marc G. Fournier's avatar
Marc G. Fournier committed
1716 1717 1718
				}
		| ALL
				{
Michael Meskes's avatar
Michael Meskes committed
1719
				 $$ = make_str("all");
Marc G. Fournier's avatar
Marc G. Fournier committed
1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732
				}
		| operation_commalist
				{
				 $$ = $1;
				}
		;

operation_commalist:  operation
				{
						$$ = $1;
				}
		| operation_commalist ',' operation
				{
Michael Meskes's avatar
Michael Meskes committed
1733
						$$ = cat_str(3, $1, make_str(","), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
1734 1735 1736 1737 1738
				}
		;

operation:  SELECT
				{
Michael Meskes's avatar
Michael Meskes committed
1739
						$$ = make_str("select");
Marc G. Fournier's avatar
Marc G. Fournier committed
1740 1741 1742
				}
		| INSERT
				{
Michael Meskes's avatar
Michael Meskes committed
1743
						$$ = make_str("insert");
Marc G. Fournier's avatar
Marc G. Fournier committed
1744 1745 1746
				}
		| UPDATE
				{
Michael Meskes's avatar
Michael Meskes committed
1747
						$$ = make_str("update");
Marc G. Fournier's avatar
Marc G. Fournier committed
1748 1749 1750
				}
		| DELETE
				{
Michael Meskes's avatar
Michael Meskes committed
1751
						$$ = make_str("delete");
Marc G. Fournier's avatar
Marc G. Fournier committed
1752 1753 1754
				}
		| RULE
				{
Michael Meskes's avatar
Michael Meskes committed
1755
						$$ = make_str("rule");
Marc G. Fournier's avatar
Marc G. Fournier committed
1756
				}
1757 1758 1759 1760 1761 1762 1763 1764
		| REFERENCES
				{
						$$ = make_str("references");
				}
		| TRIGGER
				{
						$$ = make_str("trigger");
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
1765 1766 1767 1768
		;

grantee:  PUBLIC
				{
Michael Meskes's avatar
Michael Meskes committed
1769
						$$ = make_str("public");
Marc G. Fournier's avatar
Marc G. Fournier committed
1770 1771 1772
				}
		| GROUP ColId
				{
Michael Meskes's avatar
Michael Meskes committed
1773
						$$ = cat2_str(make_str("group"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
1774 1775 1776 1777 1778 1779 1780
				}
		| ColId
				{
						$$ = $1;
				}
		;

1781 1782 1783 1784
grantee_list: grantee  				{ $$ = $1; }
		| grantee_list ',' grantee 	{ $$ = cat_str(3, $1, make_str(","), $3); }
		;

1785 1786 1787 1788 1789
opt_with_grant:  WITH GRANT OPTION
                                {
					mmerror(ET_NOTICE, "Currently unsupported GRANT/WITH GRANT OPTION will be passed to backend");
					$$ = make_str("with grant option");
				}
1790
		| /*EMPTY*/ { $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1791 1792 1793 1794 1795 1796
		;


/*****************************************************************************
 *
 *		QUERY:
1797
 * REVOKE privileges ON [TABLE relation_name_list FROM [user], ...
Marc G. Fournier's avatar
Marc G. Fournier committed
1798 1799 1800
 *
 *****************************************************************************/

1801
RevokeStmt:  REVOKE privileges ON opt_table relation_name_list FROM grantee_list
Marc G. Fournier's avatar
Marc G. Fournier committed
1802
				{
1803
					$$ = cat_str(8, make_str("revoke"), $2, make_str("on"), $4, $5, make_str("from"), $7);
Marc G. Fournier's avatar
Marc G. Fournier committed
1804 1805 1806 1807 1808 1809 1810 1811 1812
				}
		;



/*****************************************************************************
 *
 *		QUERY:
 *				create index <indexname> on <relname>
1813 1814
 *				  [ using <access> ] "(" (<col> with <op>)+ ")"
 *				  [ where <predicate> ]
Marc G. Fournier's avatar
Marc G. Fournier committed
1815 1816 1817 1818
 *
 *****************************************************************************/

IndexStmt:	CREATE index_opt_unique INDEX index_name ON relation_name
1819
			access_method_clause '(' index_params ')' where_clause
Marc G. Fournier's avatar
Marc G. Fournier committed
1820
				{
1821
					$$ = cat_str(11, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11);
Marc G. Fournier's avatar
Marc G. Fournier committed
1822 1823 1824
				}
		;

Michael Meskes's avatar
Michael Meskes committed
1825
index_opt_unique:  UNIQUE	{ $$ = make_str("unique"); }
Michael Meskes's avatar
Michael Meskes committed
1826
		| /*EMPTY*/	{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1827 1828
		;

Michael Meskes's avatar
Michael Meskes committed
1829
access_method_clause:  USING access_method	{ $$ = cat2_str(make_str("using"), $2); }
Michael Meskes's avatar
Michael Meskes committed
1830
		| /*EMPTY*/			{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1831 1832 1833 1834 1835 1836
		;

index_params:  index_list			{ $$ = $1; }
		| func_index			{ $$ = $1; }
		;

Michael Meskes's avatar
Michael Meskes committed
1837
index_list:  index_list ',' index_elem		{ $$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1838 1839 1840
		| index_elem			{ $$ = $1; }
		;

Michael Meskes's avatar
Michael Meskes committed
1841
func_index:  func_name '(' name_list ')' opt_class
Marc G. Fournier's avatar
Marc G. Fournier committed
1842
				{
Michael Meskes's avatar
Michael Meskes committed
1843
					$$ = cat_str(5, $1, make_str("("), $3, ")", $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
1844 1845 1846
				}
		  ;

Michael Meskes's avatar
Michael Meskes committed
1847
index_elem:  attr_name opt_class
Marc G. Fournier's avatar
Marc G. Fournier committed
1848
				{
Michael Meskes's avatar
Michael Meskes committed
1849
					$$ = cat2_str($1, $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
1850 1851 1852
				}
		;

Michael Meskes's avatar
Michael Meskes committed
1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870
opt_class:  class			{
					 /*
                                          * 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
                                          */
					 if (strcmp($1, "network_ops") != 0 &&
					     strcmp($1, "timespan_ops") != 0 && 
					     strcmp($1, "datetime_ops") != 0 &&
					     strcmp($1, "lztext_ops") != 0)
						$$ = $1;
					 else
						$$ = EMPTY;
					}
Michael Meskes's avatar
Michael Meskes committed
1871
		| USING class			{ $$ = cat2_str(make_str("using"), $2); }
Michael Meskes's avatar
Michael Meskes committed
1872
		| /*EMPTY*/			{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1873 1874 1875 1876 1877 1878 1879 1880 1881
		;


/*****************************************************************************
 *
 *		QUERY:
 *				execute recipe <recipeName>
 *
 *****************************************************************************/
Michael Meskes's avatar
Michael Meskes committed
1882
/* NOT USED
Marc G. Fournier's avatar
Marc G. Fournier committed
1883 1884
RecipeStmt:  EXECUTE RECIPE recipe_name
				{
Michael Meskes's avatar
Michael Meskes committed
1885
					$$ = cat2_str(make_str("execute recipe"), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
1886 1887
				}
		;
Michael Meskes's avatar
Michael Meskes committed
1888
*/
Marc G. Fournier's avatar
Marc G. Fournier committed
1889 1890 1891
/*****************************************************************************
 *
 *		QUERY:
1892 1893 1894 1895 1896
 *				create [or replace] function <fname>
 *						[(<type-1> { , <type-n>})]
 *						returns <type-r>
 *						as <filename or code in language as appropriate>
 *						language <lang> [with parameters]
Marc G. Fournier's avatar
Marc G. Fournier committed
1897 1898 1899
 *
 *****************************************************************************/

1900
ProcedureStmt:	CREATE opt_or_replace FUNCTION func_name func_args
1901
			 RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with
Marc G. Fournier's avatar
Marc G. Fournier committed
1902
				{
1903
					$$ = cat_str(12, make_str("create"), $2, make_str("function"), $4, $5, make_str("returns"), $7, make_str("as"), $9, make_str("language"), $11, $12);
Marc G. Fournier's avatar
Marc G. Fournier committed
1904 1905
				}

1906 1907 1908 1909
opt_or_replace:  OR REPLACE				{ $$ = make_str("or replace"); }
		| /*EMPTY*/						{ $$ = EMPTY; }
		;

Michael Meskes's avatar
Michael Meskes committed
1910
opt_with:  WITH definition			{ $$ = cat2_str(make_str("with"), $2); }
Michael Meskes's avatar
Michael Meskes committed
1911
		| /*EMPTY*/			{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
1912 1913
		;

Michael Meskes's avatar
Michael Meskes committed
1914 1915
func_args:  '(' func_args_list ')'		{ $$ = cat_str(3, make_str("("), $2, make_str(")")); }
		| '(' ')'			{ $$ = make_str("()"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1916 1917
		;

Michael Meskes's avatar
Michael Meskes committed
1918 1919
func_args_list:  func_arg				{ $$ = $1; }
		| func_args_list ',' func_arg
Michael Meskes's avatar
Michael Meskes committed
1920
				{	$$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
1921 1922
		;

1923
func_arg:  opt_arg func_type
Michael Meskes's avatar
Michael Meskes committed
1924 1925 1926 1927 1928
                               {
                                       /* We can catch over-specified arguments here if we want to,
                                        * but for now better to silently swallow typmod, etc.
                                        * - thomas 2000-03-22
                                        */
Michael Meskes's avatar
Michael Meskes committed
1929
                                       $$ = cat2_str($1, $2);
Michael Meskes's avatar
Michael Meskes committed
1930
                               }
1931
		| func_type
Michael Meskes's avatar
Michael Meskes committed
1932 1933 1934
				{
					$$ = $1;
				}
Michael Meskes's avatar
Michael Meskes committed
1935 1936
               ;

Michael Meskes's avatar
Michael Meskes committed
1937 1938
opt_arg:  IN    { $$ = make_str("in"); }
	| OUT	{ 
1939
		  mmerror(ET_NOTICE, "Currently unsupported CREATE FUNCTION/OUT will be passed to backend");
Michael Meskes's avatar
Michael Meskes committed
1940 1941 1942 1943

	 	  $$ = make_str("out");
		}
	| INOUT	{ 
1944
		  mmerror(ET_NOTICE, "Currently unsupported CREATE FUNCTION/INOUT will be passed to backend");
Michael Meskes's avatar
Michael Meskes committed
1945

1946
	 	  $$ = make_str("inout");
Michael Meskes's avatar
Michael Meskes committed
1947 1948 1949
		}
	;

1950 1951
func_as: StringConst				{ $$ = $1; }
		| StringConst ',' StringConst	{ $$ = cat_str(3, $1, make_str(","), $3); }
1952

1953
func_return:  func_type
Michael Meskes's avatar
Michael Meskes committed
1954 1955 1956 1957 1958 1959 1960
				{
                                       /* 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;
                                }
Marc G. Fournier's avatar
Marc G. Fournier committed
1961 1962
		;

1963 1964 1965 1966
func_type:	Typename
				{
					$$ = $1;
				}
1967
		| TypeFuncId '.' ColId '%' TYPE_P   
1968 1969 1970 1971 1972
				{
					$$ = cat_str(4, $1, make_str("."), $3, make_str("% type"));
				}
		;

Marc G. Fournier's avatar
Marc G. Fournier committed
1973 1974 1975 1976
/*****************************************************************************
 *
 *		QUERY:
 *
1977
 *             DROP FUNCTION funcname (arg1, arg2, ...)
1978
 *             DROP AGGREGATE aggname (aggtype)
1979
 *             DROP OPERATOR opname (leftoperand_typ rightoperand_typ) 
Marc G. Fournier's avatar
Marc G. Fournier committed
1980 1981 1982
 *
 *****************************************************************************/

1983
RemoveFuncStmt:  DROP FUNCTION func_name func_args   
Marc G. Fournier's avatar
Marc G. Fournier committed
1984
				{
1985
					$$ = cat_str(3, make_str("drop function"), $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
1986 1987 1988
				}
		;

1989 1990 1991 1992 1993
RemoveAggrStmt:  DROP AGGREGATE func_name '(' aggr_argtype ')'
				{
						$$ = cat_str(5, make_str("drop aggregate"), $3, make_str("("), $5, make_str(")"));
				}
		| DROP AGGREGATE func_name aggr_argtype
Marc G. Fournier's avatar
Marc G. Fournier committed
1994
				{
1995
						/* Obsolete syntax, but must support for awhile */
Michael Meskes's avatar
Michael Meskes committed
1996
						$$ = cat_str(3, make_str("drop aggregate"), $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
1997 1998 1999
				}
		;

2000
aggr_argtype:  Typename			{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
2001
		| '*'			{ $$ = make_str("*"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
2002 2003 2004 2005 2006
		;


RemoveOperStmt:  DROP OPERATOR all_Op '(' oper_argtypes ')'
				{
Michael Meskes's avatar
Michael Meskes committed
2007
					$$ = cat_str(5, make_str("drop operator"), $3, make_str("("), $5, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
2008 2009 2010
				}
		;

2011
oper_argtypes:	Typename
Marc G. Fournier's avatar
Marc G. Fournier committed
2012
				{
Michael Meskes's avatar
Michael Meskes committed
2013
				   mmerror(ET_ERROR, "parser: argument type missing (use NONE for unary operators)");
Marc G. Fournier's avatar
Marc G. Fournier committed
2014
				}
2015
		| Typename ',' Typename
Michael Meskes's avatar
Michael Meskes committed
2016
				{ $$ = cat_str(3, $1, make_str(","), $3); }
2017
		| NONE ',' Typename			/* left unary */
Michael Meskes's avatar
Michael Meskes committed
2018
				{ $$ = cat2_str(make_str("none,"), $3); }
2019
		| Typename ',' NONE			/* right unary */
Michael Meskes's avatar
Michael Meskes committed
2020
				{ $$ = cat2_str($1, make_str(", none")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
2021 2022
		;

Michael Meskes's avatar
Michael Meskes committed
2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041
/*****************************************************************************
 *
 *              QUERY:
 *
 *              REINDEX type <typename> [FORCE] [ALL]
 *
 *****************************************************************************/
ReindexStmt:  REINDEX reindex_type name opt_force
                                {
					$$ = cat_str(4, make_str("reindex"), $2, $3, $4);
				}

reindex_type:   INDEX		{ $$ = make_str("index"); }
                | TABLE		{ $$ = make_str("table"); }
                | DATABASE	{ $$ = make_str("database"); }
                ;
opt_force:      FORCE		{ $$ = make_str("force"); }
                | /* EMPTY */	{ $$ = EMPTY; }
                ;
Marc G. Fournier's avatar
Marc G. Fournier committed
2042 2043 2044 2045 2046 2047 2048 2049 2050

/*****************************************************************************
 *
 *		QUERY:
 *				rename <attrname1> in <relname> [*] to <attrname2>
 *				rename <relname1> to <relname2>
 *
 *****************************************************************************/

2051
RenameStmt:  ALTER TABLE relation_expr RENAME opt_column opt_name TO name
Marc G. Fournier's avatar
Marc G. Fournier committed
2052
				{
2053
					$$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8);
Marc G. Fournier's avatar
Marc G. Fournier committed
2054 2055 2056 2057
				}
		;

opt_name:  name							{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
2058
		| /*EMPTY*/					{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2059 2060
		;

Michael Meskes's avatar
Michael Meskes committed
2061
opt_column:  COLUMN					{ $$ = make_str("column"); }
Michael Meskes's avatar
Michael Meskes committed
2062
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077
		;


/*****************************************************************************
 *
 *		QUERY:	Define Rewrite Rule , Define Tuple Rule
 *				Define Rule <old rules >
 *
 *		only rewrite rule is supported -- ay 9/94
 *
 *****************************************************************************/

RuleStmt:  CREATE RULE name AS
		   { QueryIsRule=1; }
		   ON event TO event_object where_clause
2078
		   DO opt_instead RuleActionList
Marc G. Fournier's avatar
Marc G. Fournier committed
2079
				{
2080
					QueryIsRule=0;
Michael Meskes's avatar
Michael Meskes committed
2081
					$$ = cat_str(10, make_str("create rule"), $3, make_str("as on"), $7, make_str("to"), $9, $10, make_str("do"), $12, $13);
Marc G. Fournier's avatar
Marc G. Fournier committed
2082 2083 2084
				}
		;

Michael Meskes's avatar
Michael Meskes committed
2085
RuleActionList:  NOTHING                               { $$ = make_str("nothing"); }
2086
               | RuleActionStmt                        { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
2087 2088
               | '[' RuleActionMulti ']'               { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
               | '(' RuleActionMulti ')'               { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2089
                ;
Marc G. Fournier's avatar
Marc G. Fournier committed
2090

Michael Meskes's avatar
Michael Meskes committed
2091 2092
/* the thrashing around here is to discard "empty" statements... */
RuleActionMulti:  RuleActionMulti ';' RuleActionStmtOrEmpty
Michael Meskes's avatar
Michael Meskes committed
2093
                                {  $$ = cat_str(3, $1, make_str(";"), $3); }
Michael Meskes's avatar
Michael Meskes committed
2094
		| RuleActionStmtOrEmpty
Michael Meskes's avatar
Michael Meskes committed
2095
				{ $$ = cat2_str($1, make_str(";")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
2096 2097
		;

2098
RuleActionStmt:   SelectStmt
2099
		| InsertStmt
2100 2101 2102 2103
                | UpdateStmt
                | DeleteStmt
		| NotifyStmt
                ;
Michael Meskes's avatar
Michael Meskes committed
2104
RuleActionStmtOrEmpty: RuleActionStmt	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
2105
               |       /*EMPTY*/        { $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
2106
               ;
2107

Marc G. Fournier's avatar
Marc G. Fournier committed
2108 2109
event_object:  relation_name '.' attr_name
				{
Michael Meskes's avatar
Michael Meskes committed
2110
					$$ = make3_str($1, make_str("."), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
2111 2112 2113 2114 2115 2116 2117 2118
				}
		| relation_name
				{
					$$ = $1;
				}
		;

/* change me to select, update, etc. some day */
Michael Meskes's avatar
Michael Meskes committed
2119 2120 2121 2122
event:	SELECT					{ $$ = make_str("select"); }
		| UPDATE			{ $$ = make_str("update"); }
		| DELETE			{ $$ = make_str("delete"); }
		| INSERT			{ $$ = make_str("insert"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
2123 2124
		 ;

Michael Meskes's avatar
Michael Meskes committed
2125
opt_instead:  INSTEAD					{ $$ = make_str("instead"); }
Michael Meskes's avatar
Michael Meskes committed
2126
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139
		;


/*****************************************************************************
 *
 *		QUERY:
 *				NOTIFY <relation_name>	can appear both in rule bodies and
 *				as a query-level command
 *
 *****************************************************************************/

NotifyStmt:  NOTIFY relation_name
				{
Michael Meskes's avatar
Michael Meskes committed
2140
					$$ = cat2_str(make_str("notify"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
2141 2142 2143 2144 2145
				}
		;

ListenStmt:  LISTEN relation_name
				{
Michael Meskes's avatar
Michael Meskes committed
2146
					$$ = cat2_str(make_str("listen"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
2147 2148 2149
                                }
;

2150 2151
UnlistenStmt:  UNLISTEN relation_name
				{
Michael Meskes's avatar
Michael Meskes committed
2152
					$$ = cat2_str(make_str("unlisten"), $2);
2153
                                }
2154 2155
		| UNLISTEN '*'
				{
Michael Meskes's avatar
Michael Meskes committed
2156
					$$ = make_str("unlisten *");
2157
                                }
2158 2159
;

Marc G. Fournier's avatar
Marc G. Fournier committed
2160 2161 2162 2163
/*****************************************************************************
 *
 *              Transactions:
 *
Michael Meskes's avatar
Michael Meskes committed
2164 2165
 *	  BEGIN / COMMIT / ROLLBACK
 *      (also older versions END / ABORT)
Marc G. Fournier's avatar
Marc G. Fournier committed
2166 2167
 *
 *****************************************************************************/
Michael Meskes's avatar
Michael Meskes committed
2168 2169 2170
TransactionStmt:  ABORT_TRANS opt_trans	{ $$ = make_str("rollback"); }
	| BEGIN_TRANS opt_trans		{ $$ = make_str("begin transaction"); }
	| COMMIT opt_trans		{ $$ = make_str("commit"); }
Michael Meskes's avatar
Michael Meskes committed
2171 2172 2173 2174 2175
	| COMMIT opt_trans opt_chain	{ $$ = cat2_str(make_str("commit"), $3); }
	| END_TRANS opt_trans		{ $$ = make_str("commit"); }
	| ROLLBACK opt_trans		{ $$ = make_str("rollback"); }
	| ROLLBACK opt_trans opt_chain	{ $$ = cat2_str(make_str("rollback"), $3); }
	;
2176 2177 2178 2179 2180

opt_trans: WORK 	{ $$ = ""; }
	| TRANSACTION	{ $$ = ""; }
	| /*EMPTY*/	{ $$ = ""; }
                ;
Marc G. Fournier's avatar
Marc G. Fournier committed
2181

Michael Meskes's avatar
Michael Meskes committed
2182 2183
opt_chain: AND NO CHAIN 	{ $$ = make_str("and no chain"); }
	| AND CHAIN		{
2184
				  mmerror(ET_NOTICE, "Currently unsupported COMMIT/CHAIN will be passed to backend");
Michael Meskes's avatar
Michael Meskes committed
2185 2186 2187 2188 2189

				  $$ = make_str("and chain");
				}
	;

Marc G. Fournier's avatar
Marc G. Fournier committed
2190 2191 2192 2193 2194 2195 2196
/*****************************************************************************
 *
 *		QUERY:
 *				define view <viewname> '('target-list ')' [where <quals> ]
 *
 *****************************************************************************/

Michael Meskes's avatar
Michael Meskes committed
2197
ViewStmt:  CREATE VIEW name opt_column_list AS SelectStmt
Marc G. Fournier's avatar
Marc G. Fournier committed
2198
				{
Michael Meskes's avatar
Michael Meskes committed
2199
					$$ = cat_str(5, make_str("create view"), $3, $4, make_str("as"), $6);
Marc G. Fournier's avatar
Marc G. Fournier committed
2200 2201 2202 2203 2204 2205 2206
				}
		;


/*****************************************************************************
 *
 *		QUERY:
Michael Meskes's avatar
Michael Meskes committed
2207
 *				load make_str("filename")
Marc G. Fournier's avatar
Marc G. Fournier committed
2208 2209 2210 2211 2212
 *
 *****************************************************************************/

LoadStmt:  LOAD file_name
				{
Michael Meskes's avatar
Michael Meskes committed
2213
					$$ = cat2_str(make_str("load"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
2214 2215 2216 2217 2218 2219
				}
		;


/*****************************************************************************
 *
Michael Meskes's avatar
Michael Meskes committed
2220 2221
 *		CREATE DATABASE
 *
Marc G. Fournier's avatar
Marc G. Fournier committed
2222 2223 2224
 *
 *****************************************************************************/

Michael Meskes's avatar
Michael Meskes committed
2225
CreatedbStmt:  CREATE DATABASE database_name WITH createdb_opt_list
Michael Meskes's avatar
Michael Meskes committed
2226
			{
Tom Lane's avatar
Tom Lane committed
2227
				$$ = cat_str(4, make_str("create database"), $3, make_str("with"), $5);
Michael Meskes's avatar
Michael Meskes committed
2228
			}
2229
		| CREATE DATABASE database_name
Michael Meskes's avatar
Michael Meskes committed
2230 2231 2232
       			{
				$$ = cat2_str(make_str("create database"), $3);
			}
Marc G. Fournier's avatar
Marc G. Fournier committed
2233 2234
		;

Michael Meskes's avatar
Michael Meskes committed
2235 2236 2237 2238 2239
createdb_opt_list:  createdb_opt_item
                               { $$ = $1; }
                | createdb_opt_list createdb_opt_item
                               { $$ = cat2_str($1, $2); }
                ;                
Marc G. Fournier's avatar
Marc G. Fournier committed
2240

Michael Meskes's avatar
Michael Meskes committed
2241 2242 2243 2244 2245
createdb_opt_item:  LOCATION '=' StringConst	{ $$ = cat2_str(make_str("location ="), $3); }
		| LOCATION '=' DEFAULT		{ $$ = make_str("location = default"); }
		| TEMPLATE '=' name  		{ $$ = cat2_str(make_str("template ="), $3); }
		| TEMPLATE '=' DEFAULT		{ $$ = make_str("template = default"); }
		| ENCODING '=' PosIntStringConst  
Michael Meskes's avatar
Michael Meskes committed
2246 2247 2248 2249 2250 2251 2252
			{
				$$ = cat2_str(make_str("encoding ="), $3);
			}
		| ENCODING '=' DEFAULT
			{
				$$ = make_str("encoding = default");
			}
2253 2254
                ;

Marc G. Fournier's avatar
Marc G. Fournier committed
2255 2256
/*****************************************************************************
 *
Michael Meskes's avatar
Michael Meskes committed
2257 2258
 *		DROP DATABASE
 *
Marc G. Fournier's avatar
Marc G. Fournier committed
2259 2260 2261
 *
 *****************************************************************************/

2262
DropdbStmt:	DROP DATABASE database_name
Marc G. Fournier's avatar
Marc G. Fournier committed
2263
				{
Michael Meskes's avatar
Michael Meskes committed
2264
					$$ = cat2_str(make_str("drop database"), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277
				}
		;


/*****************************************************************************
 *
 *		QUERY:
 *				cluster <index_name> on <relation_name>
 *
 *****************************************************************************/

ClusterStmt:  CLUSTER index_name ON relation_name
				{
Michael Meskes's avatar
Michael Meskes committed
2278
				   $$ = cat_str(4, make_str("cluster"), $2, make_str("on"), $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
2279 2280 2281 2282 2283 2284 2285 2286
				}
		;


/*****************************************************************************
 *
 *		QUERY:
 *				vacuum
2287
 *				analyze
Marc G. Fournier's avatar
Marc G. Fournier committed
2288 2289 2290
 *
 *****************************************************************************/

2291
VacuumStmt:  VACUUM opt_full opt_freeze opt_verbose
2292
				{
2293
					$$ = cat_str(4, make_str("vacuum"), $2, $3, $4);
2294
				}
2295
		| VACUUM opt_full opt_freeze opt_verbose relation_name
Marc G. Fournier's avatar
Marc G. Fournier committed
2296
				{
2297
					$$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
2298
				}
2299
		| VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
Marc G. Fournier's avatar
Marc G. Fournier committed
2300
				{
2301
					$$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
2302 2303 2304
				}
		;

2305 2306 2307 2308 2309 2310 2311 2312
AnalyzeStmt:  analyze_keyword opt_verbose
				{
					$$ = cat_str(2, $1, $2);
				}
		| analyze_keyword opt_verbose relation_name opt_name_list
				{
					$$ = cat_str(4, $1, $2, $3, $4);
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
2313 2314
		;

2315 2316
analyze_keyword:  ANALYZE					{ $$ = make_str("analyze"); }
		| ANALYSE							{ $$ = make_str("analyse"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
2317 2318
		;

2319
opt_verbose:  VERBOSE					{ $$ = make_str("verbose"); }
2320 2321 2322 2323 2324
		| /*EMPTY*/						{ $$ = EMPTY; }
		;

opt_full:  FULL							{ $$ = make_str("full"); }
		| /*EMPTY*/						{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2325 2326
		;

2327 2328 2329 2330
opt_freeze:  FREEZE						{ $$ = make_str("freeze"); }
		| /*EMPTY*/					{ $$ = EMPTY; }
		;

2331 2332
opt_name_list:  '(' name_list ')'		{ $$ = cat_str(3, make_str("("), $2, make_str(")")); }
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344
		;


/*****************************************************************************
 *
 *		QUERY:
 *				EXPLAIN query
 *
 *****************************************************************************/

ExplainStmt:  EXPLAIN opt_verbose OptimizableStmt
				{
Michael Meskes's avatar
Michael Meskes committed
2345
					$$ = cat_str(3, make_str("explain"), $2, $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
2346
				}
2347 2348 2349 2350
		| EXPLAIN analyze_keyword opt_verbose OptimizableStmt
				{
					$$ = cat_str(4, make_str("explain"), $2, $3, $4);
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364
		;


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

2365 2366 2367 2368 2369
OptimizableStmt:  SelectStmt
		| CursorStmt
		| UpdateStmt
		| InsertStmt
		| DeleteStmt
Marc G. Fournier's avatar
Marc G. Fournier committed
2370 2371 2372 2373 2374 2375 2376 2377 2378 2379
		;


/*****************************************************************************
 *
 *		QUERY:
 *				INSERT STATEMENTS
 *
 *****************************************************************************/

2380 2381
/* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
 * originally. When the second rule of 'insert_rest' was changed to use
Tom Lane's avatar
Tom Lane committed
2382
 * the new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/reduce
2383 2384 2385
 * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to accept
 * the same statements without any shift/reduce conflicts */
InsertStmt:  INSERT INTO relation_name insert_rest
Marc G. Fournier's avatar
Marc G. Fournier committed
2386
				{
Michael Meskes's avatar
Michael Meskes committed
2387
					$$ = cat_str(3, make_str("insert into"), $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
2388 2389 2390
				}
		;

Michael Meskes's avatar
Michael Meskes committed
2391
insert_rest:  VALUES '(' target_list ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
2392
				{
Michael Meskes's avatar
Michael Meskes committed
2393
					$$ = cat_str(3, make_str("values("), $3, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
2394
				}
2395 2396
		| DEFAULT VALUES
				{
Michael Meskes's avatar
Michael Meskes committed
2397
					$$ = make_str("default values");
2398
				}
2399
		| SelectStmt
Marc G. Fournier's avatar
Marc G. Fournier committed
2400
				{
2401
					$$ = $1;
2402
				}
Michael Meskes's avatar
Michael Meskes committed
2403
		| '(' columnList ')' VALUES '(' target_list ')'
2404
				{
Michael Meskes's avatar
Michael Meskes committed
2405
					$$ = cat_str(5, make_str("("), $2, make_str(") values ("), $6, make_str(")"));
2406 2407 2408
				}
		| '(' columnList ')' SelectStmt
				{
Michael Meskes's avatar
Michael Meskes committed
2409
					$$ = cat_str(4, make_str("("), $2, make_str(")"), $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
2410 2411 2412
				}
		;

Michael Meskes's avatar
Michael Meskes committed
2413
opt_column_list:  '(' columnList ')'			{ $$ = cat_str(3, make_str("("), $2, make_str(")")); }
Michael Meskes's avatar
Michael Meskes committed
2414
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2415 2416 2417 2418
		;

columnList:
		  columnList ',' columnElem
Michael Meskes's avatar
Michael Meskes committed
2419
				{ $$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
2420 2421 2422 2423 2424 2425
		| columnElem
				{ $$ = $1; }
		;

columnElem:  ColId opt_indirection
				{
2426
					$$ = cat2_str($1, $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437
				}
		;


/*****************************************************************************
 *
 *		QUERY:
 *				DELETE STATEMENTS
 *
 *****************************************************************************/

2438
DeleteStmt:  DELETE FROM relation_expr where_clause
Marc G. Fournier's avatar
Marc G. Fournier committed
2439
				{
2440
					$$ = cat_str(3, make_str("delete from"), $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
2441 2442 2443
				}
		;

2444
LockStmt:  LOCK_P opt_table relation_name_list opt_lock
2445
				{
Michael Meskes's avatar
Michael Meskes committed
2446
					$$ = cat_str(4, make_str("lock"), $2, $3, $4);
2447
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
2448 2449
		;

Michael Meskes's avatar
Michael Meskes committed
2450
opt_lock:  IN lock_type MODE            { $$ = cat_str(3, make_str("in"), $2, make_str("mode")); }
Michael Meskes's avatar
Michael Meskes committed
2451
                | /*EMPTY*/             { $$ = EMPTY;}
2452 2453
                ;

2454 2455 2456 2457 2458 2459 2460 2461 2462
lock_type:  ACCESS SHARE		{ $$ = make_str("access share"); }
		| ROW SHARE				{ $$ = make_str("access share"); }
		| ROW EXCLUSIVE			{ $$ = make_str("row exclusive"); }
		| SHARE UPDATE EXCLUSIVE { $$ = make_str("share update exclusive"); }
		| SHARE					{ $$ = make_str("share"); }
		| SHARE ROW EXCLUSIVE	{ $$ = make_str("share row exclusive"); }
		| EXCLUSIVE				{ $$ = make_str("exclusive"); }
		| ACCESS EXCLUSIVE		{ $$ = make_str("access exclusive"); }
		;
Marc G. Fournier's avatar
Marc G. Fournier committed
2463 2464 2465 2466 2467 2468 2469 2470

/*****************************************************************************
 *
 *		QUERY:
 *				UpdateStmt (UPDATE)
 *
 *****************************************************************************/

2471
UpdateStmt:  UPDATE relation_expr
Michael Meskes's avatar
Michael Meskes committed
2472
			  SET update_target_list
Marc G. Fournier's avatar
Marc G. Fournier committed
2473 2474 2475
			  from_clause
			  where_clause
				{
2476
					$$ = cat_str(6, make_str("update"), $2, make_str("set"), $4, $5, $6);
Marc G. Fournier's avatar
Marc G. Fournier committed
2477 2478 2479 2480 2481 2482 2483 2484 2485 2486
				}
		;


/*****************************************************************************
 *
 *		QUERY:
 *				CURSOR STATEMENTS
 *
 *****************************************************************************/
2487
CursorStmt:  DECLARE name opt_cursor CURSOR FOR SelectStmt
Marc G. Fournier's avatar
Marc G. Fournier committed
2488
				{
2489 2490 2491 2492 2493 2494
					struct cursor *ptr, *this;
	
					for (ptr = cur; ptr != NULL; ptr = ptr->next)
					{
						if (strcmp($2, ptr->name) == 0)
						{
2495
						        /* re-definition is a bug */
2496
							sprintf(errortext, "cursor %s already defined", $2);
Michael Meskes's avatar
Michael Meskes committed
2497
							mmerror(ET_ERROR, errortext);
2498 2499 2500 2501 2502 2503 2504 2505
				                }
        				}
                        
        				this = (struct cursor *) mm_alloc(sizeof(struct cursor));

			        	/* initial definition */
				        this->next = cur;
				        this->name = $2;
2506
					this->connection = connection;
2507
				        this->command =  cat_str(5, make_str("declare"), mm_strdup($2), $3, make_str("cursor for"), $6);
2508 2509 2510 2511 2512 2513
					this->argsinsert = argsinsert;
					this->argsresult = argsresult;
					argsinsert = argsresult = NULL;
											
			        	cur = this;
					
Michael Meskes's avatar
Michael Meskes committed
2514
					$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
Marc G. Fournier's avatar
Marc G. Fournier committed
2515 2516 2517
				}
		;

Michael Meskes's avatar
Michael Meskes committed
2518 2519 2520 2521
opt_cursor:  BINARY             	{ $$ = make_str("binary"); }
               | INSENSITIVE		{ $$ = make_str("insensitive"); }
               | SCROLL        		{ $$ = make_str("scroll"); }
               | INSENSITIVE SCROLL	{ $$ = make_str("insensitive scroll"); }
Michael Meskes's avatar
Michael Meskes committed
2522
               | /*EMPTY*/      	{ $$ = EMPTY; }
2523 2524
               ;

Marc G. Fournier's avatar
Marc G. Fournier committed
2525 2526 2527 2528 2529 2530 2531
/*****************************************************************************
 *
 *		QUERY:
 *				SELECT STATEMENTS
 *
 *****************************************************************************/

2532 2533 2534 2535 2536 2537 2538
SelectStmt: select_no_parens                    %prec UMINUS
		{ $$ = $1; }
	|	select_with_parens		%prec UMINUS
		{ $$ = $1; }
	;

select_with_parens: '(' select_no_parens ')' 
2539
                        {
2540
                                $$ = cat_str(3, make_str("("), $2, make_str(")"));
2541
                        }
2542
                | '(' select_with_parens ')'
2543 2544 2545 2546 2547 2548 2549 2550 2551 2552
                        {
                                $$ = cat_str(3, make_str("("), $2, make_str(")"));
                        }
                ;       

select_no_parens:      simple_select
			{
				$$ = $1;
			}
		| select_clause sort_clause opt_for_update_clause opt_select_limit
Michael Meskes's avatar
Michael Meskes committed
2553
			{
2554
				$$ = cat_str(4, $1, $2, $3, $4);
Michael Meskes's avatar
Michael Meskes committed
2555
			}
2556 2557 2558 2559 2560 2561 2562 2563
		| select_clause for_update_clause opt_select_limit
			{
				$$ = cat_str(3, $1, $2, $3);
			}
		| select_clause select_limit  
			{
				$$ = cat2_str($1, $2);
			}
Marc G. Fournier's avatar
Marc G. Fournier committed
2564

2565
select_clause: simple_select
2566
                        {
2567 2568
                                $$ = $1;

2569
                        }
2570
                | select_with_parens 
2571
                        {
2572
				$$ = $1; 
2573
                        }
Marc G. Fournier's avatar
Marc G. Fournier committed
2574 2575
		;

2576 2577
simple_select:     SELECT opt_distinct target_list
                         into_clause from_clause where_clause
2578
                         group_clause having_clause
Marc G. Fournier's avatar
Marc G. Fournier committed
2579
				{
Michael Meskes's avatar
Michael Meskes committed
2580
					$$ = cat_str(8, make_str("select"), $2, $3, $4, $5, $6, $7, $8);
Marc G. Fournier's avatar
Marc G. Fournier committed
2581
				}
2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593
				| select_clause UNION opt_all select_clause
				{
					$$ = cat_str(4, $1, make_str("union"), $3, $4); 
				}
				| select_clause INTERSECT opt_all select_clause 
		                { 
					$$ = cat_str(4, $1, make_str("intersect"), $3, $4);
				}
				| select_clause EXCEPT opt_all select_clause 
		                { 
                		    $$ = cat_str(4, $1, make_str("except"), $3, $4);
                		} 
Marc G. Fournier's avatar
Marc G. Fournier committed
2594 2595
		;

2596
into_clause:  INTO OptTempTableName	{
Michael Meskes's avatar
Michael Meskes committed
2597 2598 2599
						FoundInto = 1;
						$$= cat2_str(make_str("into"), $2);
					}
2600 2601
		| ecpg_into		{ $$ = EMPTY; }
		| /*EMPTY*/             { $$ = EMPTY; } 
Marc G. Fournier's avatar
Marc G. Fournier committed
2602 2603
		;

Michael Meskes's avatar
Michael Meskes committed
2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628
/*
 * Redundancy here is needed to avoid shift/reduce conflicts,
 * since TEMP is not a reserved word.  See also OptTemp.
 *
 * The result is a cons cell (not a true list!) containing
 * a boolean and a table name.
 */
OptTempTableName:  TEMPORARY opt_table relation_name
			{
				$$ = cat_str(3, make_str("temporary"), $2, $3);
			}
                       | TEMP opt_table relation_name
			{
				$$ = cat_str(3, make_str("temp"), $2, $3);
			}
                       | LOCAL TEMPORARY opt_table relation_name
			{
				$$ = cat_str(3, make_str("local temporary"), $3, $4);
			}
                       | LOCAL TEMP opt_table relation_name
			{
				$$ = cat_str(3, make_str("local temp"), $3, $4);
			}
                       | GLOBAL TEMPORARY opt_table relation_name
                        {
2629
				mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
Michael Meskes's avatar
Michael Meskes committed
2630 2631 2632 2633
				$$ = cat_str(3, make_str("global temporary"), $3, $4);
                        }
                       | GLOBAL TEMP opt_table relation_name
                        {
2634
				mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
Michael Meskes's avatar
Michael Meskes committed
2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646
				$$ = cat_str(3, make_str("global temp"), $3, $4);
                        }
                       | TABLE relation_name
			{
				$$ = cat2_str(make_str("table"), $2);
			}
                       | relation_name
			{
				$$ = $1;
			}
                ;

Michael Meskes's avatar
Michael Meskes committed
2647
opt_table:  TABLE					{ $$ = make_str("table"); }
Michael Meskes's avatar
Michael Meskes committed
2648
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2649 2650
		;

Michael Meskes's avatar
Michael Meskes committed
2651
opt_all:  ALL						{ $$ = make_str("all"); }
Michael Meskes's avatar
Michael Meskes committed
2652
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2653 2654
		;

Michael Meskes's avatar
Michael Meskes committed
2655 2656
opt_distinct:  DISTINCT					{ $$ = make_str("distinct"); }
		| DISTINCT ON '(' expr_list ')'   	{ $$ = cat_str(3, make_str("distinct on ("), $4, make_str(")")); }
Michael Meskes's avatar
Michael Meskes committed
2657
		| ALL					{ $$ = make_str("all"); }
Michael Meskes's avatar
Michael Meskes committed
2658
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2659 2660
		;

Michael Meskes's avatar
Michael Meskes committed
2661 2662 2663
sort_clause:  ORDER BY sortby_list	{ 
						$$ = cat2_str(make_str("order by"), $3);
					}
Marc G. Fournier's avatar
Marc G. Fournier committed
2664 2665 2666
		;

sortby_list:  sortby					{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
2667
		| sortby_list ',' sortby		{ $$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
2668 2669
		;

2670
sortby: a_expr OptUseOp
Marc G. Fournier's avatar
Marc G. Fournier committed
2671
				{
2672 2673
					 $$ = cat2_str($1, $2);
                                }
Marc G. Fournier's avatar
Marc G. Fournier committed
2674 2675
		;

Michael Meskes's avatar
Michael Meskes committed
2676 2677 2678
OptUseOp:  USING all_Op				{ $$ = cat2_str(make_str("using"), $2); }
		| ASC				{ $$ = make_str("asc"); }
		| DESC				{ $$ = make_str("desc"); }
Michael Meskes's avatar
Michael Meskes committed
2679
		| /*EMPTY*/			{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2680 2681
		;

Michael Meskes's avatar
Michael Meskes committed
2682
select_limit:      LIMIT select_limit_value OFFSET select_offset_value
Michael Meskes's avatar
Michael Meskes committed
2683
                       { $$ = cat_str(4, make_str("limit"), $2, make_str("offset"), $4); }
Michael Meskes's avatar
Michael Meskes committed
2684
		| OFFSET select_offset_value LIMIT select_limit_value
Michael Meskes's avatar
Michael Meskes committed
2685
                       { $$ = cat_str(4, make_str("offset"), $2, make_str("limit"), $4); }
Michael Meskes's avatar
Michael Meskes committed
2686 2687 2688
                | LIMIT select_limit_value
                       { $$ = cat2_str(make_str("limit"), $2); }
                | OFFSET select_offset_value
Michael Meskes's avatar
Michael Meskes committed
2689
                       { $$ = cat2_str(make_str("offset"), $2); }
Michael Meskes's avatar
Michael Meskes committed
2690 2691 2692 2693 2694 2695
		| LIMIT select_limit_value ',' select_offset_value
                       { $$ = cat_str(4, make_str("limit"), $2, make_str(","), $4); }
                       /* enable this in 7.3, bjm 2001-10-22
		       { mmerror(ET_NOTICE, "No longer supported LIMIT #,# syntax passed to backend."); }
                       */
                ;
2696

2697 2698 2699 2700 2701 2702 2703 2704 2705
opt_select_limit:	select_limit	{ $$ = $1; }  
			| /*EMPTY*/     { $$ = EMPTY; } 
			;

select_limit_value:	PosIntConst	{ 
						if (atoi($1) < 0)
							mmerror(ET_ERROR, "LIMIT must not be negative");
						$$ = $1;
					}
Michael Meskes's avatar
Michael Meskes committed
2706
	          	| ALL	{ $$ = make_str("all"); }
2707 2708 2709
			| PARAM { $$ = make_name(); }
               ;

2710 2711 2712 2713 2714
select_offset_value:  	PosIntConst	{
						if (atoi($1) < 0)
							mmerror(ET_ERROR, "OFFSET must not be negative");
						$$ = $1;
					}
2715 2716 2717
			| PARAM { $$ = make_name(); }
               ;

Marc G. Fournier's avatar
Marc G. Fournier committed
2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729
/*
 *	jimmy bell-style recursive queries aren't supported in the
 *	current system.
 *
 *	...however, recursive addattr and rename supported.  make special
 *	cases for these.
 */
relation_name_list:  name_list { $$ = $1; };

name_list:  name
				{	$$ = $1; }
		| name_list ',' name
Michael Meskes's avatar
Michael Meskes committed
2730
				{	$$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
2731 2732
		;

Michael Meskes's avatar
Michael Meskes committed
2733
group_clause:  GROUP BY expr_list			{ $$ = cat2_str(make_str("group by"), $3); }
Michael Meskes's avatar
Michael Meskes committed
2734
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2735 2736 2737 2738
		;

having_clause:  HAVING a_expr
				{
Michael Meskes's avatar
Michael Meskes committed
2739
					$$ = cat2_str(make_str("having"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
2740
				}
Michael Meskes's avatar
Michael Meskes committed
2741
		| /*EMPTY*/		{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2742 2743
		;

2744 2745
for_update_clause:  FOR UPDATE update_list
		{
Michael Meskes's avatar
Michael Meskes committed
2746
                	$$ = make_str("for update"); 
2747
		}
Michael Meskes's avatar
Michael Meskes committed
2748 2749
		| FOR READ ONLY
		{
Michael Meskes's avatar
Michael Meskes committed
2750
			$$ = make_str("for read only");
Michael Meskes's avatar
Michael Meskes committed
2751
		}
2752 2753 2754 2755
		;

opt_for_update_clause: for_update_clause                { $$ = $1; }
		| /* EMPTY */				{ $$ = EMPTY; }
2756
                ;
2757

2758
update_list:  OF name_list
2759
              {
Michael Meskes's avatar
Michael Meskes committed
2760
			$$ = cat2_str(make_str("of"), $2);
2761 2762 2763
	      }
              | /* EMPTY */
              {
Michael Meskes's avatar
Michael Meskes committed
2764
                        $$ = EMPTY;
2765 2766
              }
              ;
Marc G. Fournier's avatar
Marc G. Fournier committed
2767 2768 2769 2770

/*****************************************************************************
 *
 *	clauses common to all Optimizable Stmts:
Michael Meskes's avatar
Michael Meskes committed
2771 2772
 *		from_clause	- allow list of both JOIN expressions and table names
 *		where_clause	- qualifications for joins or restrictions
Marc G. Fournier's avatar
Marc G. Fournier committed
2773 2774 2775
 *
 *****************************************************************************/

Michael Meskes's avatar
Michael Meskes committed
2776 2777 2778 2779
from_clause:    FROM from_list		{ $$ = cat2_str(make_str("from"), $2); }
		| /* EMPTY */		{ $$ = EMPTY; }
		;

2780 2781
from_list:  from_list ',' table_ref	{ $$ = cat_str(3, $1, make_str(","), $3); }
                | table_ref		{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
2782 2783
                ;

2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795
/*
 * 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 
                {
                	$$ = $1;
                }
	| relation_expr alias_clause 
2796
		{
2797
			$$= cat2_str($1, $2);
2798
		}
2799 2800 2801 2802 2803
	| select_with_parens
		{
			mmerror(ET_ERROR, "sub-SELECT in FROM must have an alias");	
		}
	| select_with_parens alias_clause 
2804
		{
2805
			$$=cat2_str($1, $2);
2806
		}
2807 2808 2809 2810 2811 2812
	| joined_table  
		{
                        $$ = $1;
                }  
	| '(' joined_table ')' alias_clause   
                {
2813
                        $$=cat_str(4, make_str("("), $2, make_str(")"), $4);
2814 2815
                }             
	;
2816

2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832
/*
 * 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.
 *                                                        
 * Note that a CROSS JOIN is the same as an unqualified       
 * INNER JOIN, and an INNER JOIN/ON has the same shape
 * but a qualification expression to limit membership.
 * A NATURAL JOIN implicitly matches column names between
 * tables and the shape is determined by which columns are
 * in common. We'll collect columns during the later transformations.
 */       
2833

2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861
joined_table:  '(' joined_table ')'   
		{
                	$$ = cat_str(3, make_str("("), $2, make_str(")"));
                } 
		| table_ref CROSS JOIN table_ref 
		{
			$$ = cat_str(3, $1, make_str("cross join"), $4);
		}
		| table_ref UNIONJOIN table_ref    
                {
                        $$ = cat_str(3, $1, make_str("unionjoin"), $3);
                }                                 
		| table_ref join_type JOIN table_ref join_qual 
                {
                        $$ = cat_str(5, $1, $2, make_str("join"), $4, $5);
                }   
		| table_ref JOIN table_ref join_qual   
                {
                        $$ = cat_str(4, $1, make_str("join"), $3, $4);
                }   
		| table_ref NATURAL join_type JOIN table_ref   
		{
                        $$ = cat_str(5, $1, make_str("natural"), $3, make_str("join"), $5);
                }  
		| table_ref NATURAL JOIN table_ref     
		{
                        $$ = cat_str(3, $1, make_str("natural join"), $4);
                }  
2862 2863
                ;

Michael Meskes's avatar
Michael Meskes committed
2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878
alias_clause:  AS ColId '(' name_list ')'
			{ $$ = cat_str(5, make_str("as"), $2, make_str("("), $4, make_str(")")); }
		| AS ColId
			{ $$ = cat2_str(make_str("as"), $2); }
		| ColId '(' name_list ')'
			{ $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
		| ColId
			{ $$ = $1; }
		;

join_type:  FULL join_outer		{ $$ = cat2_str(make_str("full"), $2); }
		| LEFT join_outer	{ $$ = cat2_str(make_str("left"), $2); }
                | RIGHT join_outer      { $$ = cat2_str(make_str("right"), $2); }
                | INNER_P               { $$ = make_str("inner"); }
		;
Marc G. Fournier's avatar
Marc G. Fournier committed
2879

2880
/* OUTER is just noise... */
Michael Meskes's avatar
Michael Meskes committed
2881
join_outer:  OUTER_P				{ $$ = make_str("outer"); }
Michael Meskes's avatar
Michael Meskes committed
2882
		| /*EMPTY*/			{ $$ = EMPTY;  /* no qualifiers */ }
Marc G. Fournier's avatar
Marc G. Fournier committed
2883 2884
		;

2885 2886 2887 2888 2889 2890
/* JOIN qualification clauses
 * Possibilities are:
 *  USING ( column list ) allows only unqualified column names,
 *                        which must match between tables.
 *  ON expr allows more general qualifications.
 */
Marc G. Fournier's avatar
Marc G. Fournier committed
2891

2892
join_qual:  USING '(' name_list ')'                   { $$ = cat_str(3, make_str("using ("), $3, make_str(")")); }
Michael Meskes's avatar
Michael Meskes committed
2893
               | ON a_expr			       { $$ = cat2_str(make_str("on"), $2); }
2894 2895
                ;

Marc G. Fournier's avatar
Marc G. Fournier committed
2896 2897 2898 2899 2900
relation_expr:	relation_name
				{
					/* normal relations */
					$$ = $1;
				}
2901
		| relation_name '*'
Marc G. Fournier's avatar
Marc G. Fournier committed
2902 2903
				{
					/* inheritance query */
Michael Meskes's avatar
Michael Meskes committed
2904
					$$ = cat2_str($1, make_str("*"));
Marc G. Fournier's avatar
Marc G. Fournier committed
2905
				}
2906
		| ONLY relation_name
2907 2908
				{
					/* inheritance query */
Michael Meskes's avatar
Michael Meskes committed
2909
            			        $$ = cat2_str(make_str("ONLY "), $2);
2910
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
2911

2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936
where_clause:  WHERE a_expr			{ $$ = cat2_str(make_str("where"), $2); }
		| /*EMPTY*/				{ $$ = EMPTY;  /* no qualifiers */ }
		;

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

Typename:  SimpleTypename opt_array_bounds
				{
					$$ = cat2_str($1, $2.str);
				}
		| SETOF SimpleTypename
				{
					$$ = cat2_str(make_str("setof"), $2);
				}
		;


Michael Meskes's avatar
Michael Meskes committed
2937
opt_array_bounds:  '[' ']' opt_array_bounds
2938 2939 2940
			{
                            $$.index1 = 0;
                            $$.index2 = $3.index1;
Michael Meskes's avatar
Michael Meskes committed
2941
                            $$.str = cat2_str(make_str("[]"), $3.str);
2942
                        }
Michael Meskes's avatar
Michael Meskes committed
2943
		| '[' Iresult ']' opt_array_bounds
2944
			{
Michael Meskes's avatar
Michael Meskes committed
2945 2946 2947 2948
			    char *txt = mm_alloc(20L);

			    sprintf (txt, "%d", $2);
                            $$.index1 = $2;
2949
                            $$.index2 = $4.index1;
Michael Meskes's avatar
Michael Meskes committed
2950
                            $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
2951
                        }
Marc G. Fournier's avatar
Marc G. Fournier committed
2952
		| /* EMPTY */
2953 2954 2955
			{
                            $$.index1 = -1;
                            $$.index2 = -1;
Michael Meskes's avatar
Michael Meskes committed
2956
                            $$.str= EMPTY;
2957
                        }
Marc G. Fournier's avatar
Marc G. Fournier committed
2958 2959
		;

2960
Iresult:	PosIntConst		{ $$ = atol($1); }
Michael Meskes's avatar
Michael Meskes committed
2961
	|	'(' Iresult ')'		{ $$ = $2; }
Michael Meskes's avatar
Michael Meskes committed
2962 2963 2964 2965 2966 2967
	|	Iresult '+' Iresult	{ $$ = $1 + $3; }
	|	Iresult '-' Iresult	{ $$ = $1 - $3; }
	|	Iresult '*' Iresult	{ $$ = $1 * $3; }
	|	Iresult '/' Iresult	{ $$ = $1 / $3; }
	|	Iresult '%' Iresult	{ $$ = $1 % $3; }
	;
Michael Meskes's avatar
Michael Meskes committed
2968

2969 2970 2971
SimpleTypename:  ConstTypename					{ $$ = $1; }
               | ConstInterval opt_interval			{ $$ = cat2_str($1, $2); }
	       | ConstInterval '(' PosIntConst ')' opt_interval	{ $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
Michael Meskes's avatar
Michael Meskes committed
2972 2973
               ;  

2974
ConstTypename:  Generic	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
2975
		| ConstDatetime	{ $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2976
		| Numeric	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
2977
		| Bit		{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
2978
		| Character	{ $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2979 2980
		;

2981 2982
Generic:  TypeFuncId			{ $$ = $1; }
		| ECPGTypeName			{ $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2983 2984 2985 2986
		;

/* SQL92 numeric data types
 * Check FLOAT() precision limits assuming IEEE floating types.
2987
 * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
Marc G. Fournier's avatar
Marc G. Fournier committed
2988 2989 2990 2991
 * - thomas 1997-09-18
 */
Numeric:  FLOAT opt_float
				{
Michael Meskes's avatar
Michael Meskes committed
2992
					$$ = cat2_str(make_str("float"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
2993 2994 2995
				}
		| DOUBLE PRECISION
				{
Michael Meskes's avatar
Michael Meskes committed
2996
					$$ = make_str("double precision");
Marc G. Fournier's avatar
Marc G. Fournier committed
2997 2998 2999
				}
		| DECIMAL opt_decimal
				{
Michael Meskes's avatar
Michael Meskes committed
3000
					$$ = cat2_str(make_str("decimal"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3001
				}
Michael Meskes's avatar
Michael Meskes committed
3002 3003 3004 3005
		| DEC opt_decimal
				{
					$$ = cat2_str(make_str("dec"), $2);
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
3006 3007
		| NUMERIC opt_numeric
				{
Michael Meskes's avatar
Michael Meskes committed
3008
					$$ = cat2_str(make_str("numeric"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3009 3010 3011
				}
		;

3012
opt_float:  '(' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3013
				{
Michael Meskes's avatar
Michael Meskes committed
3014
					$$ = cat_str(3, make_str("("), $2, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3015 3016 3017
				}
		| /*EMPTY*/
				{
Michael Meskes's avatar
Michael Meskes committed
3018
					$$ = EMPTY;
Marc G. Fournier's avatar
Marc G. Fournier committed
3019 3020 3021
				}
		;

3022
opt_numeric:  '(' PosIntConst ',' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3023
				{
Michael Meskes's avatar
Michael Meskes committed
3024
					$$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3025
				}
3026
		| '(' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3027
				{
Michael Meskes's avatar
Michael Meskes committed
3028
					$$ = cat_str(3, make_str("("), $2, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3029 3030 3031
				}
		| /*EMPTY*/
				{
Michael Meskes's avatar
Michael Meskes committed
3032
					$$ = EMPTY;
Marc G. Fournier's avatar
Marc G. Fournier committed
3033 3034 3035
				}
		;

3036
opt_decimal:  '(' PosIntConst ',' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3037
				{
Michael Meskes's avatar
Michael Meskes committed
3038
					$$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3039
				}
3040
		| '(' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3041
				{
Michael Meskes's avatar
Michael Meskes committed
3042
					$$ = cat_str(3, make_str("("), $2, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3043 3044 3045
				}
		| /*EMPTY*/
				{
Michael Meskes's avatar
Michael Meskes committed
3046
					$$ = EMPTY;
Marc G. Fournier's avatar
Marc G. Fournier committed
3047 3048 3049
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3050 3051 3052 3053
/*
 * SQL92 bit-field data types
 * The following implements BIT() and BIT VARYING().
 */
3054
Bit:  bit '(' PosIntConst ')'
3055 3056 3057
				{
					$$ = cat_str(4, $1, make_str("("), $3, make_str(")"));
				}
Michael Meskes's avatar
Michael Meskes committed
3058
                | bit
3059 3060
				{
					$$ = $1;
Michael Meskes's avatar
Michael Meskes committed
3061 3062 3063 3064 3065 3066 3067 3068
				}
		;

bit:  BIT opt_varying
				{
					$$ = cat2_str(make_str("bit"), $2);
				}

Michael Meskes's avatar
Michael Meskes committed
3069 3070
/* 
 * SQL92 character data types
Marc G. Fournier's avatar
Marc G. Fournier committed
3071 3072 3073
 * The following implements CHAR() and VARCHAR().
 *								- ay 6/95
 */
Michael Meskes's avatar
Michael Meskes committed
3074
Character:  character '(' PosIntConst ')' opt_charset
Marc G. Fournier's avatar
Marc G. Fournier committed
3075
				{
Michael Meskes's avatar
Michael Meskes committed
3076
					$$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
3077
				}
Michael Meskes's avatar
Michael Meskes committed
3078
		| character opt_charset
Marc G. Fournier's avatar
Marc G. Fournier committed
3079
				{
Michael Meskes's avatar
Michael Meskes committed
3080
					$$ = cat2_str($1, $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3081 3082 3083
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3084
character:  CHARACTER opt_varying 
Marc G. Fournier's avatar
Marc G. Fournier committed
3085
				{
Michael Meskes's avatar
Michael Meskes committed
3086
					$$ = cat2_str(make_str("character"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3087
				}
Michael Meskes's avatar
Michael Meskes committed
3088 3089 3090 3091 3092
		| CHAR opt_varying			{ $$ = cat2_str(make_str("char"), $2); }
		| VARCHAR				{ $$ = make_str("varchar"); }
		| NATIONAL CHARACTER opt_varying	{ $$ = cat2_str(make_str("national character"), $3); }
		| NATIONAL CHAR opt_varying 		{ $$ = cat2_str(make_str("national char"), $3); }
		| NCHAR opt_varying			{ $$ = cat2_str(make_str("nchar"), $2); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3093 3094
		;

Michael Meskes's avatar
Michael Meskes committed
3095
opt_varying:  VARYING			{ $$ = make_str("varying"); }
Michael Meskes's avatar
Michael Meskes committed
3096
		| /*EMPTY*/			{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3097 3098
		;

Michael Meskes's avatar
Michael Meskes committed
3099
opt_charset:  CHARACTER SET ColId	{ $$ = cat2_str(make_str("character set"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3100
		| /*EMPTY*/				{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3101 3102
		;

Michael Meskes's avatar
Michael Meskes committed
3103
opt_collate:  COLLATE ColId		{ $$ = cat2_str(make_str("collate"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3104
		| /*EMPTY*/					{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3105 3106
		;

3107
ConstDatetime:  TIMESTAMP '(' PosIntConst ')' opt_timezone
Michael Meskes's avatar
Michael Meskes committed
3108 3109 3110
				{
					$$ = cat_str(4, make_str("timestamp("), $3, make_str(")"), $5);
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
3111 3112
		| TIMESTAMP opt_timezone
				{
Michael Meskes's avatar
Michael Meskes committed
3113
					$$ = cat2_str(make_str("timestamp"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3114
				}
Michael Meskes's avatar
Michael Meskes committed
3115 3116 3117 3118
		| TIME '(' PosIntConst ')' opt_timezone
				{
					$$ = cat_str(4, make_str("time("), $3, make_str(")"), $5);
				}
Michael Meskes's avatar
Michael Meskes committed
3119
		| TIME opt_timezone
Marc G. Fournier's avatar
Marc G. Fournier committed
3120
				{
Michael Meskes's avatar
Michael Meskes committed
3121
					$$ = cat2_str(make_str("time"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3122
				}
Michael Meskes's avatar
Michael Meskes committed
3123 3124
		;

3125
ConstInterval:	INTERVAL
Marc G. Fournier's avatar
Marc G. Fournier committed
3126
				{
3127
					$$ = make_str("interval");
Marc G. Fournier's avatar
Marc G. Fournier committed
3128 3129 3130
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3131
opt_timezone:  WITH TIME ZONE				{ $$ = make_str("with time zone"); }
Michael Meskes's avatar
Michael Meskes committed
3132
		| WITHOUT TIME ZONE				{ $$ = make_str("without time zone"); }
Michael Meskes's avatar
Michael Meskes committed
3133
		| /*EMPTY*/					{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3134 3135
		;

3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149
opt_interval:  YEAR_P				{ $$ = make_str("year"); }
		| MONTH_P			{ $$ = make_str("month"); }
		| DAY_P				{ $$ = make_str("day"); }
		| HOUR_P			{ $$ = make_str("hour"); }
		| MINUTE_P			{ $$ = make_str("minute"); }
		| SECOND_P			{ $$ = make_str("second"); }
		| YEAR_P TO MONTH_P		{ $$ = make_str("year to month"); }
		| DAY_P TO HOUR_P		{ $$ = make_str("day to hour"); }
		| DAY_P TO MINUTE_P		{ $$ = make_str("day to minute"); }
		| DAY_P TO SECOND_P		{ $$ = make_str("day to second"); }
		| HOUR_P TO MINUTE_P		{ $$ = make_str("hour to minute"); }
		| MINUTE_P TO SECOND_P		{ $$ = make_str("minute to second"); }
		| HOUR_P TO SECOND_P		{ $$ = make_str("hour to second"); }
		| /*EMPTY*/			{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3150 3151 3152 3153 3154
		;


/*****************************************************************************
 *
Michael Meskes's avatar
Michael Meskes committed
3155
 *	expression grammar
Marc G. Fournier's avatar
Marc G. Fournier committed
3156 3157 3158 3159 3160 3161 3162
 *
 *****************************************************************************/

/* Expressions using row descriptors
 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
 *  with singleton expressions.
 */
3163
row_expr: '(' row_descriptor ')' IN select_with_parens
Marc G. Fournier's avatar
Marc G. Fournier committed
3164
				{
3165
					$$ = cat_str(4, make_str("("), $2, make_str(") in "), $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
3166
				}
3167
		| '(' row_descriptor ')' NOT IN select_with_parens
Marc G. Fournier's avatar
Marc G. Fournier committed
3168
				{
3169
					$$ = cat_str(4, make_str("("), $2, make_str(") not in "), $6);
Marc G. Fournier's avatar
Marc G. Fournier committed
3170
				}
3171
		| '(' row_descriptor ')' all_Op sub_type select_with_parens
Marc G. Fournier's avatar
Marc G. Fournier committed
3172
				{
3173
					$$ = cat_str(6, make_str("("), $2, make_str(")"), $4, $5, $6);
Marc G. Fournier's avatar
Marc G. Fournier committed
3174
				}
3175
		| '(' row_descriptor ')' all_Op select_with_parens
Marc G. Fournier's avatar
Marc G. Fournier committed
3176
				{
3177
					$$ = cat_str(5, make_str("("), $2, make_str(")"), $4, $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
3178
				}
Michael Meskes's avatar
Michael Meskes committed
3179
		| '(' row_descriptor ')' all_Op '(' row_descriptor ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3180
				{
Michael Meskes's avatar
Michael Meskes committed
3181
					$$ = cat_str(7, make_str("("), $2, make_str(")"), $4, make_str("("), $6, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3182
				}
Michael Meskes's avatar
Michael Meskes committed
3183 3184 3185 3186
		| '(' row_descriptor ')' OVERLAPS '(' row_descriptor ')'
				{
					$$ = cat_str(5, make_str("("), $2, make_str(") overlaps ("), $6, make_str(")"));
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
3187 3188 3189 3190
		;

row_descriptor:  row_list ',' a_expr
				{
Michael Meskes's avatar
Michael Meskes committed
3191
					$$ = cat_str(3, $1, make_str(","), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3192 3193 3194
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3195
sub_type:  ANY                  { $$ = make_str("ANY"); }
Michael Meskes's avatar
Michael Meskes committed
3196
         | SOME                 { $$ = make_str("SOME"); }
Michael Meskes's avatar
Michael Meskes committed
3197
         | ALL                  { $$ = make_str("ALL"); }
3198 3199 3200
              ;


Marc G. Fournier's avatar
Marc G. Fournier committed
3201 3202
row_list:  row_list ',' a_expr
				{
Michael Meskes's avatar
Michael Meskes committed
3203
					$$ = cat_str(3, $1, make_str(","), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3204 3205 3206 3207 3208 3209 3210
				}
		| a_expr
				{
					$$ = $1;
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3211 3212
all_Op:  Op | MathOp;

Michael Meskes's avatar
Michael Meskes committed
3213 3214 3215 3216 3217 3218 3219 3220 3221
MathOp:	'+'				{ $$ = make_str("+"); }
		| '-'			{ $$ = make_str("-"); }
		| '*'			{ $$ = make_str("*"); }
		| '%'			{ $$ = make_str("%"); }
                | '^'                   { $$ = make_str("^"); }
		| '/'			{ $$ = make_str("/"); }
		| '<'			{ $$ = make_str("<"); }
		| '>'			{ $$ = make_str(">"); }
		| '='			{ $$ = make_str("="); }
Michael Meskes's avatar
Michael Meskes committed
3222 3223
		;

3224
/* General expressions
Marc G. Fournier's avatar
Marc G. Fournier committed
3225
 * This is the heart of the expression syntax.
Michael Meskes's avatar
Michael Meskes committed
3226 3227 3228 3229 3230 3231 3232 3233 3234 3235
 *
 * 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.
 *
Michael Meskes's avatar
Michael Meskes committed
3236
 * c_expr is all the productions that are common to a_expr and b_expr;
Michael Meskes's avatar
Michael Meskes committed
3237
 * it's factored out just to eliminate redundant coding.
Marc G. Fournier's avatar
Marc G. Fournier committed
3238 3239
 */

Michael Meskes's avatar
Michael Meskes committed
3240
a_expr:  c_expr
Michael Meskes's avatar
Michael Meskes committed
3241 3242
				{	$$ = $1; }
		| a_expr TYPECAST Typename
Michael Meskes's avatar
Michael Meskes committed
3243
				{	$$ = cat_str(3, $1, make_str("::"), $3); }
3244 3245
		| a_expr AT TIME ZONE c_expr 
				{	$$ = cat_str(3, $1, make_str("at time zone"), $5); }
Michael Meskes's avatar
Michael Meskes committed
3246 3247 3248 3249 3250 3251 3252 3253 3254
		/*
                 * 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.
                 */
Michael Meskes's avatar
Michael Meskes committed
3255 3256
		| '+' a_expr %prec UMINUS
				{	$$ = cat2_str(make_str("+"), $2); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3257
		| '-' a_expr %prec UMINUS
Michael Meskes's avatar
Michael Meskes committed
3258
				{	$$ = cat2_str(make_str("-"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3259
		| '%' a_expr
Michael Meskes's avatar
Michael Meskes committed
3260
				{       $$ = cat2_str(make_str("%"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3261
		| '^' a_expr
Michael Meskes's avatar
Michael Meskes committed
3262
				{       $$ = cat2_str(make_str("^"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3263
		| a_expr '%'
Michael Meskes's avatar
Michael Meskes committed
3264
				{       $$ = cat2_str($1, make_str("%")); }
Michael Meskes's avatar
Michael Meskes committed
3265
		| a_expr '^'
Michael Meskes's avatar
Michael Meskes committed
3266
				{       $$ = cat2_str($1, make_str("^")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3267
		| a_expr '+' a_expr
Michael Meskes's avatar
Michael Meskes committed
3268
				{	$$ = cat_str(3, $1, make_str("+"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3269
		| a_expr '-' a_expr
Michael Meskes's avatar
Michael Meskes committed
3270
				{	$$ = cat_str(3, $1, make_str("-"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3271
		| a_expr '*' a_expr
Michael Meskes's avatar
Michael Meskes committed
3272
				{	$$ = cat_str(3, $1, make_str("*"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3273
		| a_expr '/' a_expr
Michael Meskes's avatar
Michael Meskes committed
3274
				{	$$ = cat_str(3, $1, make_str("/"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3275
		| a_expr '%' a_expr
Michael Meskes's avatar
Michael Meskes committed
3276
				{	$$ = cat_str(3, $1, make_str("%"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3277
		| a_expr '^' a_expr
Michael Meskes's avatar
Michael Meskes committed
3278
				{	$$ = cat_str(3, $1, make_str("^"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3279
		| a_expr '<' a_expr
Michael Meskes's avatar
Michael Meskes committed
3280
				{	$$ = cat_str(3, $1, make_str("<"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3281
		| a_expr '>' a_expr
Michael Meskes's avatar
Michael Meskes committed
3282
				{	$$ = cat_str(3, $1, make_str(">"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3283
		| a_expr '=' a_expr
Michael Meskes's avatar
Michael Meskes committed
3284
				{	$$ = cat_str(3, $1, make_str("="), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3285
		| a_expr Op a_expr
Michael Meskes's avatar
Michael Meskes committed
3286
				{	$$ = cat_str(3, $1, $2, $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3287
		| Op a_expr
3288
				{	$$ = cat2_str($1, $2); }
3289
		| a_expr Op		%prec POSTFIXOP
3290
				{	$$ = cat2_str($1, $2); }
Michael Meskes's avatar
Michael Meskes committed
3291
		| a_expr AND a_expr
Michael Meskes's avatar
Michael Meskes committed
3292
				{	$$ = cat_str(3, $1, make_str("and"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3293
		| a_expr OR a_expr
Michael Meskes's avatar
Michael Meskes committed
3294
				{	$$ = cat_str(3, $1, make_str("or"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3295
		| NOT a_expr
Michael Meskes's avatar
Michael Meskes committed
3296
				{	$$ = cat2_str(make_str("not"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3297
		| a_expr LIKE a_expr
Michael Meskes's avatar
Michael Meskes committed
3298
				{	$$ = cat_str(3, $1, make_str("like"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3299 3300
		| a_expr LIKE a_expr ESCAPE a_expr
				{	$$ = cat_str(5, $1, make_str("like"), $3, make_str("escape"), $5); }
Michael Meskes's avatar
Michael Meskes committed
3301
		| a_expr NOT LIKE a_expr
Michael Meskes's avatar
Michael Meskes committed
3302
				{	$$ = cat_str(3, $1, make_str("not like"), $4); }
Michael Meskes's avatar
Michael Meskes committed
3303 3304 3305 3306 3307 3308 3309 3310 3311 3312
		| a_expr NOT LIKE a_expr ESCAPE a_expr
				{	$$ = cat_str(5, $1, make_str("not like"), $4, make_str("escape"), $6); }
		| a_expr ILIKE a_expr
				{	$$ = cat_str(3, $1, make_str("ilike"), $3); }
		| a_expr ILIKE a_expr ESCAPE a_expr
				{	$$ = cat_str(5, $1, make_str("ilike"), $3, make_str("escape"), $5); }
		| a_expr NOT ILIKE a_expr
				{	$$ = cat_str(3, $1, make_str("not ilike"), $4); }
		| a_expr NOT ILIKE a_expr ESCAPE a_expr
				{	$$ = cat_str(5, $1, make_str("not ilike"), $4, make_str("escape"), $6); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3313
		| a_expr ISNULL
Michael Meskes's avatar
Michael Meskes committed
3314
				{	$$ = cat2_str($1, make_str("isnull")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3315
		| a_expr IS NULL_P
Michael Meskes's avatar
Michael Meskes committed
3316
				{	$$ = cat2_str($1, make_str("is null")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3317
		| a_expr NOTNULL
Michael Meskes's avatar
Michael Meskes committed
3318
				{	$$ = cat2_str($1, make_str("notnull")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3319
		| a_expr IS NOT NULL_P
Michael Meskes's avatar
Michael Meskes committed
3320
				{	$$ = cat2_str($1, make_str("is not null")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3321 3322 3323 3324
		/* 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
3325 3326 3327 3328
		 *
		 *  Created BooleanTest Node type, and changed handling
		 *  for NULL inputs
		 * - jec 2001-06-18
Marc G. Fournier's avatar
Marc G. Fournier committed
3329 3330
		 */
		| a_expr IS TRUE_P
Michael Meskes's avatar
Michael Meskes committed
3331
				{	$$ = cat2_str($1, make_str("is true")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3332
		| a_expr IS NOT TRUE_P
Michael Meskes's avatar
Michael Meskes committed
3333
				{	$$ = cat2_str($1, make_str("is not true")); }
3334 3335 3336 3337 3338 3339 3340 3341
		| a_expr IS FALSE_P
				{	$$ = cat2_str($1, make_str("is false")); }
		| a_expr IS NOT FALSE_P
				{	$$ = cat2_str($1, make_str("is not false")); }
		| a_expr IS UNKNOWN
				{	$$ = cat2_str($1, make_str("is unknown")); }
		| a_expr IS NOT UNKNOWN
				{	$$ = cat2_str($1, make_str("is not unknown")); }
3342
		| a_expr BETWEEN b_expr AND b_expr	%prec BETWEEN
Marc G. Fournier's avatar
Marc G. Fournier committed
3343
				{
Michael Meskes's avatar
Michael Meskes committed
3344
					$$ = cat_str(5, $1, make_str("between"), $3, make_str("and"), $5); 
Marc G. Fournier's avatar
Marc G. Fournier committed
3345
				}
3346
		| a_expr NOT BETWEEN b_expr AND b_expr	%prec BETWEEN
Marc G. Fournier's avatar
Marc G. Fournier committed
3347
				{
Michael Meskes's avatar
Michael Meskes committed
3348
					$$ = cat_str(5, $1, make_str("not between"), $4, make_str("and"), $6); 
Marc G. Fournier's avatar
Marc G. Fournier committed
3349
				}
3350
		| a_expr IN in_expr 
Marc G. Fournier's avatar
Marc G. Fournier committed
3351
				{
3352
					$$ = cat_str(3, $1, make_str(" in"), $3); 
Marc G. Fournier's avatar
Marc G. Fournier committed
3353
				}
3354
		| a_expr NOT IN in_expr
Marc G. Fournier's avatar
Marc G. Fournier committed
3355
				{
3356
					$$ = cat_str(3, $1, make_str(" not in "), $4); 
Marc G. Fournier's avatar
Marc G. Fournier committed
3357
				}
3358
		| a_expr all_Op sub_type select_with_parens	%prec Op
Michael Meskes's avatar
Michael Meskes committed
3359
				{
3360
					$$ = cat_str(4, $1, $2, $3, $4); 
Michael Meskes's avatar
Michael Meskes committed
3361
				}
Michael Meskes's avatar
Michael Meskes committed
3362
		| row_expr
3363
				{       $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3364 3365
		;

3366
/* Restricted expressions
Michael Meskes's avatar
Michael Meskes committed
3367
 *
Marc G. Fournier's avatar
Marc G. Fournier committed
3368
 * b_expr is a subset of the complete expression syntax
Michael Meskes's avatar
Michael Meskes committed
3369
 *
Michael Meskes's avatar
Michael Meskes committed
3370
 * Presently, AND, NOT, IS and IN are the a_expr keywords that would
Michael Meskes's avatar
Michael Meskes committed
3371 3372
 * cause trouble in the places where b_expr is used.  For simplicity, we
 * just eliminate all the boolean-keyword-operator productions from b_expr.
Marc G. Fournier's avatar
Marc G. Fournier committed
3373
 */
Michael Meskes's avatar
Michael Meskes committed
3374
b_expr:  c_expr
Marc G. Fournier's avatar
Marc G. Fournier committed
3375
				{
Michael Meskes's avatar
Michael Meskes committed
3376
					$$ = $1;
Marc G. Fournier's avatar
Marc G. Fournier committed
3377
				}
Michael Meskes's avatar
Michael Meskes committed
3378
		| b_expr TYPECAST Typename
Marc G. Fournier's avatar
Marc G. Fournier committed
3379
				{
Michael Meskes's avatar
Michael Meskes committed
3380
					$$ = cat_str(3, $1, make_str("::"), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3381 3382
				}
		| '-' b_expr %prec UMINUS
Michael Meskes's avatar
Michael Meskes committed
3383
				{	$$ = cat2_str(make_str("-"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3384
		| '%' b_expr
Michael Meskes's avatar
Michael Meskes committed
3385
				{       $$ = cat2_str(make_str("%"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3386
		| '^' b_expr
Michael Meskes's avatar
Michael Meskes committed
3387
				{       $$ = cat2_str(make_str("^"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3388
		| b_expr '%'
Michael Meskes's avatar
Michael Meskes committed
3389
				{       $$ = cat2_str($1, make_str("%")); }
Michael Meskes's avatar
Michael Meskes committed
3390
		| b_expr '^'
Michael Meskes's avatar
Michael Meskes committed
3391
				{       $$ = cat2_str($1, make_str("^")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3392
		| b_expr '+' b_expr
Michael Meskes's avatar
Michael Meskes committed
3393
				{	$$ = cat_str(3, $1, make_str("+"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3394
		| b_expr '-' b_expr
Michael Meskes's avatar
Michael Meskes committed
3395
				{	$$ = cat_str(3, $1, make_str("-"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3396
		| b_expr '*' b_expr
Michael Meskes's avatar
Michael Meskes committed
3397
				{	$$ = cat_str(3, $1, make_str("*"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3398
		| b_expr '/' b_expr
Michael Meskes's avatar
Michael Meskes committed
3399
				{	$$ = cat_str(3, $1, make_str("/"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3400
		| b_expr '%' b_expr
Michael Meskes's avatar
Michael Meskes committed
3401
				{	$$ = cat_str(3, $1, make_str("%"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3402
		| b_expr '^' b_expr
Michael Meskes's avatar
Michael Meskes committed
3403
				{	$$ = cat_str(3, $1, make_str("^"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3404
		| b_expr '<' b_expr
Michael Meskes's avatar
Michael Meskes committed
3405
				{	$$ = cat_str(3, $1, make_str("<"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3406
		| b_expr '>' b_expr
Michael Meskes's avatar
Michael Meskes committed
3407
				{	$$ = cat_str(3, $1, make_str(">"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3408
		| b_expr '=' b_expr
Michael Meskes's avatar
Michael Meskes committed
3409
				{	$$ = cat_str(3, $1, make_str("="), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3410
		| b_expr Op b_expr
Michael Meskes's avatar
Michael Meskes committed
3411
				{	$$ = cat_str(3, $1, $2, $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3412
		| Op b_expr
3413
				{	$$ = cat2_str($1, $2); }
3414
		| b_expr Op		%prec POSTFIXOP
3415
				{	$$ = cat2_str($1, $2); }
Michael Meskes's avatar
Michael Meskes committed
3416 3417 3418 3419 3420 3421 3422 3423 3424 3425
		;

/*
 * 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.
 */
Michael Meskes's avatar
Michael Meskes committed
3426
c_expr:  attr
Michael Meskes's avatar
Michael Meskes committed
3427 3428 3429 3430 3431
				{	$$ = $1;  }
		| ColId opt_indirection
				{	$$ = cat2_str($1, $2);	}
		| AexprConst
				{	$$ = $1;  }
Michael Meskes's avatar
Michael Meskes committed
3432
		| '(' a_expr ')'
Michael Meskes's avatar
Michael Meskes committed
3433
				{	$$ = cat_str(3, make_str("("), $2, make_str(")")); }
Michael Meskes's avatar
Michael Meskes committed
3434
		| CAST '(' a_expr AS Typename ')'
Michael Meskes's avatar
Michael Meskes committed
3435
				{ 	$$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); }
Michael Meskes's avatar
Michael Meskes committed
3436 3437
		| case_expr
				{       $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3438
		| func_name '(' ')'
Michael Meskes's avatar
Michael Meskes committed
3439
				{	$$ = cat2_str($1, make_str("()"));  }
Marc G. Fournier's avatar
Marc G. Fournier committed
3440
		| func_name '(' expr_list ')'
Michael Meskes's avatar
Michael Meskes committed
3441
				{	$$ = cat_str(4, $1, make_str("("), $3, make_str(")"));  }
Michael Meskes's avatar
Michael Meskes committed
3442 3443
		| func_name '(' ALL expr_list ')'
				{	$$ = cat_str(4, $1, make_str("( all"), $4, make_str(")"));  }
Michael Meskes's avatar
Michael Meskes committed
3444 3445
		| func_name '(' DISTINCT expr_list ')'
				{	$$ = cat_str(4, $1, make_str("( distinct"), $4, make_str(")"));  }
Michael Meskes's avatar
Michael Meskes committed
3446
		| func_name '(' '*' ')'
Michael Meskes's avatar
Michael Meskes committed
3447
				{	$$ = cat2_str($1, make_str("(*)")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3448
		| CURRENT_DATE
Michael Meskes's avatar
Michael Meskes committed
3449
				{	$$ = make_str("current_date"); }
Michael Meskes's avatar
Michael Meskes committed
3450 3451
		| CURRENT_TIME opt_empty_parentheses
				{	$$ = cat2_str(make_str("current_time"), $2); }
3452
		| CURRENT_TIME '(' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3453
				{
Michael Meskes's avatar
Michael Meskes committed
3454
					$$ = make_str("current_time");
Marc G. Fournier's avatar
Marc G. Fournier committed
3455
				}
Michael Meskes's avatar
Michael Meskes committed
3456 3457
		| CURRENT_TIMESTAMP opt_empty_parentheses
				{	$$ = cat2_str(make_str("current_timestamp"), $2); }
3458
		| CURRENT_TIMESTAMP '(' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3459
				{
Michael Meskes's avatar
Michael Meskes committed
3460
					$$ = make_str("current_timestamp");
Marc G. Fournier's avatar
Marc G. Fournier committed
3461
				}
Michael Meskes's avatar
Michael Meskes committed
3462 3463 3464 3465 3466 3467
		| CURRENT_USER opt_empty_parentheses
				{	$$ = cat2_str(make_str("current_user"), $2); }
		| SESSION_USER opt_empty_parentheses
				{       $$ = cat2_str(make_str("session_user"), $2); }
		| USER opt_empty_parentheses
				{       $$ = cat2_str(make_str("user"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3468
		| EXTRACT '(' extract_list ')'
Michael Meskes's avatar
Michael Meskes committed
3469
				{	$$ = cat_str(3, make_str("extract("), $3, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3470
		| POSITION '(' position_list ')'
Michael Meskes's avatar
Michael Meskes committed
3471
				{	$$ = cat_str(3, make_str("position("), $3, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3472
		| SUBSTRING '(' substr_list ')'
Michael Meskes's avatar
Michael Meskes committed
3473
				{	$$ = cat_str(3, make_str("substring("), $3, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3474 3475
		/* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
		| TRIM '(' BOTH trim_list ')'
Michael Meskes's avatar
Michael Meskes committed
3476
				{	$$ = cat_str(3, make_str("trim(both"), $4, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3477
		| TRIM '(' LEADING trim_list ')'
Michael Meskes's avatar
Michael Meskes committed
3478
				{	$$ = cat_str(3, make_str("trim(leading"), $4, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3479
		| TRIM '(' TRAILING trim_list ')'
Michael Meskes's avatar
Michael Meskes committed
3480
				{	$$ = cat_str(3, make_str("trim(trailing"), $4, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3481
		| TRIM '(' trim_list ')'
Michael Meskes's avatar
Michael Meskes committed
3482
				{	$$ = cat_str(3, make_str("trim("), $3, make_str(")")); }
3483 3484 3485 3486
		| select_with_parens	%prec UMINUS 
				{	$$ = $1; }
		| EXISTS select_with_parens
				{	$$ = cat2_str(make_str("exists"), $2); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3487
		;
Michael Meskes's avatar
Michael Meskes committed
3488 3489 3490 3491 3492
/* 
 * This used to use ecpg_expr, but since there is no shift/reduce conflict
 * anymore, we can remove ecpg_expr. - MM
 */
opt_indirection:  '[' a_expr ']' opt_indirection
Marc G. Fournier's avatar
Marc G. Fournier committed
3493
				{
Michael Meskes's avatar
Michael Meskes committed
3494
					$$ = cat_str(4, make_str("["), $2, make_str("]"), $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
3495
				}
Michael Meskes's avatar
Michael Meskes committed
3496
		| '[' a_expr ':' a_expr ']' opt_indirection
Marc G. Fournier's avatar
Marc G. Fournier committed
3497
				{
Michael Meskes's avatar
Michael Meskes committed
3498
					$$ = cat_str(6, make_str("["), $2, make_str(":"), $4, make_str("]"), $6);
Marc G. Fournier's avatar
Marc G. Fournier committed
3499 3500
				}
		| /* EMPTY */
Michael Meskes's avatar
Michael Meskes committed
3501
				{	$$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3502 3503
		;

Michael Meskes's avatar
Michael Meskes committed
3504
expr_list:  a_expr
Marc G. Fournier's avatar
Marc G. Fournier committed
3505
				{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
3506
		| expr_list ',' a_expr
Michael Meskes's avatar
Michael Meskes committed
3507
				{ $$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3508
		| expr_list USING a_expr
Michael Meskes's avatar
Michael Meskes committed
3509
				{ $$ = cat_str(3, $1, make_str("using"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3510 3511 3512 3513
		;

extract_list:  extract_arg FROM a_expr
				{
Michael Meskes's avatar
Michael Meskes committed
3514
					$$ = cat_str(3, $1, make_str("from"), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3515 3516
				}
		| /* EMPTY */
Michael Meskes's avatar
Michael Meskes committed
3517
				{	$$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3518 3519
		;

Tom Lane's avatar
Tom Lane committed
3520 3521 3522 3523
/* Allow delimited string SCONST in extract_arg as an SQL extension.
 * - thomas 2001-04-12
 */

3524 3525 3526 3527 3528 3529 3530 3531
extract_arg:  IDENT						{ $$ = $1; }
		| YEAR_P						{ $$ = make_str("year"); }
		| MONTH_P						{ $$ = make_str("month"); }
		| DAY_P							{ $$ = make_str("day"); }
		| HOUR_P						{ $$ = make_str("hour"); }
		| MINUTE_P						{ $$ = make_str("minute"); }
		| SECOND_P						{ $$ = make_str("second"); }
		| StringConst					{ $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3532 3533
		;

Michael Meskes's avatar
Michael Meskes committed
3534 3535
/* position_list uses b_expr not a_expr to avoid conflict with general IN */
position_list:  b_expr IN b_expr
Michael Meskes's avatar
Michael Meskes committed
3536
				{	$$ = cat_str(3, $1, make_str("in"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3537
		| /* EMPTY */
Michael Meskes's avatar
Michael Meskes committed
3538
				{	$$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3539 3540
		;

3541
substr_list:  a_expr substr_from substr_for
Marc G. Fournier's avatar
Marc G. Fournier committed
3542
				{
Michael Meskes's avatar
Michael Meskes committed
3543
					$$ = cat_str(3, $1, $2, $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3544
				}
3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560
		| a_expr substr_for substr_from 
				{
                                        $$ = cat_str(3, $1, $2, $3);
                                }  
		| a_expr substr_from  
				{
                                        $$ = cat2_str($1, $2);
                                }  
		| a_expr substr_for
				{
                                        $$ = cat2_str($1, $2);
                                }  
		| expr_list
				{
					$$ = $1;
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
3561
		| /* EMPTY */
Michael Meskes's avatar
Michael Meskes committed
3562
				{	$$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3563 3564
		;

3565
substr_from:  FROM a_expr
Michael Meskes's avatar
Michael Meskes committed
3566
				{	$$ = cat2_str(make_str("from"), $2); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3567 3568
		;

3569
substr_for:  FOR a_expr
Michael Meskes's avatar
Michael Meskes committed
3570
				{	$$ = cat2_str(make_str("for"), $2); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3571 3572 3573
		;

trim_list:  a_expr FROM expr_list
Michael Meskes's avatar
Michael Meskes committed
3574
				{ $$ = cat_str(3, $1, make_str("from"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3575
		| FROM expr_list
Michael Meskes's avatar
Michael Meskes committed
3576
				{ $$ = cat2_str(make_str("from"), $2); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3577 3578 3579 3580
		| expr_list
				{ $$ = $1; }
		;

3581
in_expr:  select_with_parens
Marc G. Fournier's avatar
Marc G. Fournier committed
3582 3583 3584
				{
					$$ = $1;
				}
3585 3586
		| '(' in_expr_nodes ')'
				{	$$ = cat_str(3, make_str("("), $2, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3587 3588
		;

Michael Meskes's avatar
Michael Meskes committed
3589
in_expr_nodes:  a_expr
Marc G. Fournier's avatar
Marc G. Fournier committed
3590
				{	$$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
3591
		| in_expr_nodes ',' a_expr
Michael Meskes's avatar
Michael Meskes committed
3592
				{	$$ = cat_str(3, $1, make_str(","), $3);}
Marc G. Fournier's avatar
Marc G. Fournier committed
3593 3594
		;

3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610
/* 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
Michael Meskes's avatar
Michael Meskes committed
3611
                                { $$ = cat_str(5, make_str("case"), $2, $3, $4, make_str("end")); }
3612 3613
                | NULLIF '(' a_expr ',' a_expr ')'
                                {
Michael Meskes's avatar
Michael Meskes committed
3614
					$$ = cat_str(5, make_str("nullif("), $3, make_str(","), $5, make_str(")"));
3615 3616 3617
                                }
                | COALESCE '(' expr_list ')'
                                {
Michael Meskes's avatar
Michael Meskes committed
3618
					$$ = cat_str(3, make_str("coalesce("), $3, make_str(")"));
3619 3620 3621 3622 3623 3624 3625 3626 3627
				}
		;

when_clause_list:  when_clause_list when_clause
                               { $$ = cat2_str($1, $2); }
               | when_clause
                               { $$ = $1; }
               ;

Michael Meskes's avatar
Michael Meskes committed
3628
when_clause:  WHEN a_expr THEN a_expr
3629
                               {
Michael Meskes's avatar
Michael Meskes committed
3630
					$$ = cat_str(4, make_str("when"), $2, make_str("then"), $4);
3631 3632 3633
                               }
               ;

Michael Meskes's avatar
Michael Meskes committed
3634
case_default:  ELSE a_expr		{ $$ = cat2_str(make_str("else"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3635
               | /*EMPTY*/        	{ $$ = EMPTY; }
3636 3637
               ;

Michael Meskes's avatar
Michael Meskes committed
3638
case_arg:  a_expr              {
3639 3640 3641
                                       $$ = $1;
                               }
               | /*EMPTY*/
Michael Meskes's avatar
Michael Meskes committed
3642
                               {       $$ = EMPTY; }
3643 3644
               ;

Michael Meskes's avatar
Michael Meskes committed
3645
attr:  relation_name '.' attrs opt_indirection
Marc G. Fournier's avatar
Marc G. Fournier committed
3646
				{
Michael Meskes's avatar
Michael Meskes committed
3647
					$$ = cat_str(4, $1, make_str("."), $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
3648
				}
Michael Meskes's avatar
Michael Meskes committed
3649
		| ParamNo '.' attrs opt_indirection
Marc G. Fournier's avatar
Marc G. Fournier committed
3650
				{
Michael Meskes's avatar
Michael Meskes committed
3651
					$$ = cat_str(4, $1, make_str("."), $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
3652 3653 3654 3655 3656 3657
				}
		;

attrs:	  attr_name
				{ $$ = $1; }
		| attrs '.' attr_name
Michael Meskes's avatar
Michael Meskes committed
3658
				{ $$ = cat_str(3, $1, make_str("."), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3659
		| attrs '.' '*'
Michael Meskes's avatar
Michael Meskes committed
3660
				{ $$ = make2_str($1, make_str(".*")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3661 3662
		;

Michael Meskes's avatar
Michael Meskes committed
3663 3664
opt_empty_parentheses: '(' ')' 	{ $$ = make_str("()"); }
                | /*EMPTY*/ 	{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3665 3666 3667 3668 3669 3670 3671

/*****************************************************************************
 *
 *	target lists
 *
 *****************************************************************************/

Michael Meskes's avatar
Michael Meskes committed
3672 3673
/* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
target_list:  target_list ',' target_el
Michael Meskes's avatar
Michael Meskes committed
3674
				{	$$ = cat_str(3, $1, make_str(","), $3);  }
Michael Meskes's avatar
Michael Meskes committed
3675
		| target_el
Marc G. Fournier's avatar
Marc G. Fournier committed
3676 3677 3678 3679
				{	$$ = $1;  }
		;

/* AS is not optional because shift/red conflict with unary ops */
Michael Meskes's avatar
Michael Meskes committed
3680
target_el:  a_expr AS ColLabel
Marc G. Fournier's avatar
Marc G. Fournier committed
3681
				{
Michael Meskes's avatar
Michael Meskes committed
3682
					$$ = cat_str(3, $1, make_str("as"), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3683
				}
Michael Meskes's avatar
Michael Meskes committed
3684
		| a_expr
Marc G. Fournier's avatar
Marc G. Fournier committed
3685 3686 3687 3688 3689
				{
					$$ = $1;
				}
		| relation_name '.' '*'
				{
Michael Meskes's avatar
Michael Meskes committed
3690
					$$ = make2_str($1, make_str(".*"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3691 3692 3693
				}
		| '*'
				{
Michael Meskes's avatar
Michael Meskes committed
3694
					$$ = make_str("*");
Marc G. Fournier's avatar
Marc G. Fournier committed
3695 3696 3697
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3698 3699
/* Target list as found in UPDATE table SET ... */
update_target_list:  update_target_list ',' update_target_el
Michael Meskes's avatar
Michael Meskes committed
3700
				{	$$ = cat_str(3, $1, make_str(","),$3);  }
Michael Meskes's avatar
Michael Meskes committed
3701 3702
		| update_target_el
				{	$$ = $1;  }
Michael Meskes's avatar
Michael Meskes committed
3703
		| '*'		{ $$ = make_str("*"); }
Michael Meskes's avatar
Michael Meskes committed
3704 3705
		;

Michael Meskes's avatar
Michael Meskes committed
3706
update_target_el:  ColId opt_indirection '=' a_expr
Michael Meskes's avatar
Michael Meskes committed
3707
				{
Michael Meskes's avatar
Michael Meskes committed
3708
					$$ = cat_str(4, $1, $2, make_str("="), $4);
Michael Meskes's avatar
Michael Meskes committed
3709
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
3710 3711
		;

Michael Meskes's avatar
Michael Meskes committed
3712 3713 3714 3715 3716 3717
/*****************************************************************************
 *
 *     Names and constants
 *
 *****************************************************************************/

Marc G. Fournier's avatar
Marc G. Fournier committed
3718 3719 3720 3721 3722 3723
relation_name:	SpecialRuleRelation
				{
					$$ = $1;
				}
		| ColId
				{
3724
					$$ = $1;
Marc G. Fournier's avatar
Marc G. Fournier committed
3725 3726 3727
				}
		;

3728
name:				ColId			{ $$ = $1; };
Marc G. Fournier's avatar
Marc G. Fournier committed
3729
database_name:			ColId			{ $$ = $1; };
Michael Meskes's avatar
Michael Meskes committed
3730
access_method:			ColId			{ $$ = $1; };
Marc G. Fournier's avatar
Marc G. Fournier committed
3731
attr_name:				ColId			{ $$ = $1; };
Michael Meskes's avatar
Michael Meskes committed
3732
class:					ColId			{ $$ = $1; };
Marc G. Fournier's avatar
Marc G. Fournier committed
3733 3734
index_name:				ColId			{ $$ = $1; };

3735
file_name:				StringConst			{ $$ = $1; };
Marc G. Fournier's avatar
Marc G. Fournier committed
3736 3737 3738 3739

/* Constants
 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
 */
3740
AexprConst:  PosAllConst
Marc G. Fournier's avatar
Marc G. Fournier committed
3741 3742 3743
				{
					$$ = $1;
				}
3744
		| ConstTypename StringConst
Marc G. Fournier's avatar
Marc G. Fournier committed
3745
				{
3746
					$$ = cat2_str($1, $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3747
				}
3748
		| ConstInterval StringConst opt_interval 
Michael Meskes's avatar
Michael Meskes committed
3749 3750 3751
				{
					$$ = cat_str(3, $1, $2, $3);
				}
3752 3753 3754 3755
		| ConstInterval  '(' PosIntConst ')' StringConst opt_interval
				{
					$$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6);
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
3756 3757 3758 3759
		| ParamNo
				{	$$ = $1;  }
		| TRUE_P
				{
Michael Meskes's avatar
Michael Meskes committed
3760
					$$ = make_str("true");
Marc G. Fournier's avatar
Marc G. Fournier committed
3761 3762 3763
				}
		| FALSE_P
				{
Michael Meskes's avatar
Michael Meskes committed
3764
					$$ = make_str("false");
Marc G. Fournier's avatar
Marc G. Fournier committed
3765
				}
Michael Meskes's avatar
Michael Meskes committed
3766 3767 3768 3769
		| NULL_P
				{
					$$ = make_str("null");
				}
3770 3771
		| civarind
			        { $$ = make_str("?"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3772 3773
		;

3774
ParamNo:  PARAM opt_indirection
Marc G. Fournier's avatar
Marc G. Fournier committed
3775
				{
3776
					$$ = cat2_str(make_name(), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3777 3778 3779 3780
				}
		;

Iconst:  ICONST                                 { $$ = make_name();};
3781
Fconst:  FCONST                                 { $$ = make_name();};
Michael Meskes's avatar
Michael Meskes committed
3782
Bitconst:  BITCONST                             { $$ = make_name();};
Marc G. Fournier's avatar
Marc G. Fournier committed
3783 3784 3785 3786 3787 3788
Sconst:  SCONST                                 {
							$$ = (char *)mm_alloc(strlen($1) + 3);
							$$[0]='\'';
				     		        strcpy($$+1, $1);
							$$[strlen($1)+2]='\0';
							$$[strlen($1)+1]='\'';
3789
							free($1);
Marc G. Fournier's avatar
Marc G. Fournier committed
3790
						}
3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806
PosIntConst:	Iconst		{ $$ = $1; }
		| civar		{ $$ = make_str("?"); }
		;

IntConst:	PosIntConst		{ $$ = $1; }
		| '-' PosIntConst	{ $$ = cat2_str(make_str("-"), $2); }
		;

StringConst:	Sconst		{ $$ = $1; }
		| civar		{ $$ = make_str("?"); }
		;

PosIntStringConst:	Iconst		{ $$ = $1; }
			| Sconst          { $$ = $1; }  
			| civar		{ $$ = make_str("?"); }
			;
3807 3808 3809 3810 3811

NumConst:	Fconst        { $$ = $1; }
                | Iconst        { $$ = $1; }
                | '-' Fconst    { $$ = cat2_str(make_str("-"), $2); }
                | '-' Iconst    { $$ = cat2_str(make_str("-"), $2); }
3812 3813 3814
		| civar		{ $$ = make_str("?"); }
		;

3815 3816 3817 3818
AllConst:	Sconst		{ $$ = $1; }
		| NumConst	{ $$ = $1; }
		;

3819 3820 3821
PosAllConst:	Sconst  	{ $$ = $1; }
		| Fconst	{ $$ = $1; }
		| Iconst        { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
3822
		| Bitconst	{ $$ = $1; }
3823 3824 3825
		| civar 	{ $$ = make_str("?"); }
		;

Michael Meskes's avatar
Michael Meskes committed
3826
UserId:  ColId                                  { $$ = $1;};
Marc G. Fournier's avatar
Marc G. Fournier committed
3827

3828
SpecialRuleRelation:  OLD
Marc G. Fournier's avatar
Marc G. Fournier committed
3829
				{
3830
					if (!QueryIsRule)
3831
						mmerror(ET_ERROR, "OLD used in non-rule query");
3832 3833

					$$ = make_str("old");
Marc G. Fournier's avatar
Marc G. Fournier committed
3834 3835 3836
				}
		| NEW
				{
3837
					if (!QueryIsRule)
Michael Meskes's avatar
Michael Meskes committed
3838
						mmerror(ET_ERROR, "NEW used in non-rule query");
3839 3840

					$$ = make_str("new");
Marc G. Fournier's avatar
Marc G. Fournier committed
3841 3842 3843 3844 3845 3846 3847 3848 3849 3850
				}
		;

/*
 * and now special embedded SQL stuff
 */

/*
 * the exec sql connect statement: connect to the given database 
 */
3851 3852
ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
		{
Michael Meskes's avatar
Michael Meskes committed
3853
			$$ = cat_str(5, $3, make_str(","), $5, make_str(","), $4);
3854 3855 3856
                }
	| SQL_CONNECT TO DEFAULT
        	{
Michael Meskes's avatar
Michael Meskes committed
3857
                	$$ = make_str("NULL,NULL,NULL,\"DEFAULT\"");
3858 3859 3860 3861
                }
      /* also allow ORACLE syntax */
        | SQL_CONNECT ora_user
                {
Michael Meskes's avatar
Michael Meskes committed
3862
		       $$ = cat_str(3, make_str("NULL,"), $2, make_str(",NULL"));
3863 3864 3865 3866 3867 3868 3869
		}

connection_target: database_name opt_server opt_port
                {
		  /* old style: dbname[@server][:port] */
		  if (strlen($2) > 0 && *($2) != '@')
		  {
3870
		    sprintf(errortext, "Expected '@', found '%s'", $2);
Michael Meskes's avatar
Michael Meskes committed
3871
		    mmerror(ET_ERROR, errortext);
3872
		  }
3873

Michael Meskes's avatar
Michael Meskes committed
3874
		  $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
3875
		}
Michael Meskes's avatar
Michael Meskes committed
3876
        |  db_prefix ':' server opt_port '/' database_name opt_options
3877
                {
3878
		  /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
Michael Meskes's avatar
Michael Meskes committed
3879
                  if (strncmp($3, "//", strlen("//")) != 0)
3880
		  {
3881
		    sprintf(errortext, "Expected '://', found '%s'", $3);
Michael Meskes's avatar
Michael Meskes committed
3882
		    mmerror(ET_ERROR, errortext);
3883
		  }
3884

Michael Meskes's avatar
Michael Meskes committed
3885 3886 3887
		  if (strncmp($1, "unix", strlen("unix")) == 0 && 
			strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 &&
			strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0)
3888
		  {
Michael Meskes's avatar
Michael Meskes committed
3889
		    sprintf(errortext, "unix domain sockets only work on 'localhost' but not on '%9.9s'", $3 + strlen("//"));
Michael Meskes's avatar
Michael Meskes committed
3890
                    mmerror(ET_ERROR, errortext);
3891 3892
		  }

Michael Meskes's avatar
Michael Meskes committed
3893
		  if (strncmp($1, "unix", strlen("unix")) != 0 && strncmp($1, "tcp", strlen("tcp")) != 0)
3894 3895
		  {
		    sprintf(errortext, "only protocols 'tcp' and 'unix' are supported");
Michael Meskes's avatar
Michael Meskes committed
3896
                    mmerror(ET_ERROR, errortext);
3897
		  }
3898
	
Michael Meskes's avatar
Michael Meskes committed
3899
		  $$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6),  $7, make_str("\"")));
3900
		}
3901
	| StringConst
3902
		{
3903 3904
		  if ($1[0] == '\"')
			$$ = $1;
3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918
		  else if (strcmp($1, "?") == 0) /* variable */
                  {
                        enum ECPGttype typ = argsinsert->variable->type->typ;
 
                        /* if array see what's inside */
                        if (typ == ECPGt_array)
                                typ = argsinsert->variable->type->u.element->typ;
 
                        /* handle varchars */
                        if (typ == ECPGt_varchar)
                                $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
                        else
                                $$ = mm_strdup(argsinsert->variable->name);
                  }
3919 3920
		  else
			$$ = make3_str(make_str("\""), $1, make_str("\""));
3921
		}
3922 3923 3924 3925 3926

db_prefix: ident cvariable
                {
		  if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
		  {
3927
		    sprintf(errortext, "Expected 'postgresql', found '%s'", $2);
Michael Meskes's avatar
Michael Meskes committed
3928
		    mmerror(ET_ERROR, errortext);	
3929 3930
		  }

3931
		  if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
3932 3933
		  {
		    sprintf(errortext, "Illegal connection type %s", $1);
Michael Meskes's avatar
Michael Meskes committed
3934
		    mmerror(ET_ERROR, errortext);
3935 3936
		  }

Michael Meskes's avatar
Michael Meskes committed
3937
		  $$ = make3_str($1, make_str(":"), $2);
3938 3939 3940 3941
		}
        
server: Op server_name
                {
Michael Meskes's avatar
Michael Meskes committed
3942
		  if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
3943
		  {
3944
		    sprintf(errortext, "Expected '@' or '://', found '%s'", $1);
Michael Meskes's avatar
Michael Meskes committed
3945
		    mmerror(ET_ERROR, errortext);
3946 3947 3948 3949 3950 3951
		  }

		  $$ = make2_str($1, $2);
	        }

opt_server: server { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
3952
        | /* empty */ { $$ = EMPTY; }
3953 3954

server_name: ColId   { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
3955 3956
        | ColId '.' server_name { $$ = make3_str($1, make_str("."), $3); }
	| IP			{ $$ = make_name(); }
3957

3958
opt_port: ':' PosIntConst { $$ = make2_str(make_str(":"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3959
        | /* empty */ { $$ = EMPTY; }
3960 3961

opt_connection_name: AS connection_target { $$ = $2; }
Michael Meskes's avatar
Michael Meskes committed
3962
        | /* empty */ { $$ = make_str("NULL"); }
3963 3964

opt_user: USER ora_user { $$ = $2; }
Michael Meskes's avatar
Michael Meskes committed
3965
          | /* empty */ { $$ = make_str("NULL,NULL"); }
3966 3967 3968

ora_user: user_name
		{
Michael Meskes's avatar
Michael Meskes committed
3969
                        $$ = cat2_str($1, make_str(", NULL"));
3970
	        }
Michael Meskes's avatar
Michael Meskes committed
3971
	| user_name '/' user_name
3972
		{
Michael Meskes's avatar
Michael Meskes committed
3973
        		$$ = cat_str(3, $1, make_str(","), $3);
3974 3975 3976
                }
        | user_name SQL_IDENTIFIED BY user_name
                {
Michael Meskes's avatar
Michael Meskes committed
3977
        		$$ = cat_str(3, $1, make_str(","), $4);
3978 3979 3980
                }
        | user_name USING user_name
                {
Michael Meskes's avatar
Michael Meskes committed
3981
        		$$ = cat_str(3, $1, make_str(","), $3);
3982 3983
                }

3984 3985 3986 3987 3988 3989 3990 3991
user_name: UserId       {
			 if ($1[0] == '\"')
				$$ = $1;
			  else
				$$ = make3_str(make_str("\""), $1, make_str("\""));
			}
        | StringConst   { 
			  if ($1[0] == '\"')
3992
				$$ = $1;
3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006
			  else if (strcmp($1, "?") == 0) /* variable */
        	          {
                	        enum ECPGttype typ = argsinsert->variable->type->typ;
 
                        	/* if array see what's inside */
	                        if (typ == ECPGt_array)
        	                        typ = argsinsert->variable->type->u.element->typ;
 
                	        /* handle varchars */
                        	if (typ == ECPGt_varchar)
                                	$$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
	                        else
        	                        $$ = mm_strdup(argsinsert->variable->name);
                	  }
4007
			  else
Michael Meskes's avatar
Michael Meskes committed
4008
				$$ = make3_str(make_str("\""), $1, make_str("\""));
4009
			}
4010 4011 4012

char_variable: cvariable
		{ /* check if we have a char variable */
4013
			struct variable *p = find_variable($1);
4014 4015 4016 4017 4018 4019
			enum ECPGttype typ = p->type->typ;

			/* if array see what's inside */
			if (typ == ECPGt_array)
				typ = p->type->u.element->typ;

4020 4021 4022 4023 4024 4025 4026
                        switch (typ)
                        {
                            case ECPGt_char:
                            case ECPGt_unsigned_char:
                                $$ = $1;
                                break;
                            case ECPGt_varchar:
Michael Meskes's avatar
Michael Meskes committed
4027
                                $$ = make2_str($1, make_str(".arr"));
4028 4029
                                break;
                            default:
Michael Meskes's avatar
Michael Meskes committed
4030
                                mmerror(ET_ERROR, "invalid datatype");
4031 4032 4033 4034 4035 4036 4037
                                break;
                        }
		}

opt_options: Op ColId
		{
			if (strlen($1) == 0)
4038
				mmerror(ET_ERROR, "incomplete statement");
4039 4040 4041
				
			if (strcmp($1, "?") != 0)
			{
4042
				sprintf(errortext, "unrecognised token '%s'", $1);
Michael Meskes's avatar
Michael Meskes committed
4043
				mmerror(ET_ERROR, errortext);
4044 4045
			}
			
Michael Meskes's avatar
Michael Meskes committed
4046
			$$ = make2_str(make_str("?"), $2);
4047
		}
Michael Meskes's avatar
Michael Meskes committed
4048
	| /* empty */ { $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
4049
	;
4050

4051
/*
4052 4053
 * Declare a prepared cursor. The syntax is different from the standard
 * declare statement, so we create a new rule.
4054
 */
Michael Meskes's avatar
Michael Meskes committed
4055
ECPGCursorStmt:  DECLARE name opt_cursor CURSOR FOR ident
4056 4057 4058
				{
					struct cursor *ptr, *this;
					struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4059

4060 4061 4062 4063 4064 4065
					for (ptr = cur; ptr != NULL; ptr = ptr->next)
					{
						if (strcmp($2, ptr->name) == 0)
						{
						        /* re-definition is a bug */
							sprintf(errortext, "cursor %s already defined", $2);
Michael Meskes's avatar
Michael Meskes committed
4066
							mmerror(ET_ERROR, errortext);
4067 4068
				                }
        				}
4069

4070
        				this = (struct cursor *) mm_alloc(sizeof(struct cursor));
4071

4072 4073 4074
			        	/* initial definition */
				        this->next = cur;
				        this->name = $2;
4075
					this->connection = connection;
Michael Meskes's avatar
Michael Meskes committed
4076
				        this->command =  cat_str(4, make_str("declare"), mm_strdup($2), $3, make_str("cursor for ?"));
4077
					this->argsresult = NULL;
4078

4079 4080 4081 4082 4083
					thisquery->type = &ecpg_query;
					thisquery->brace_level = 0;
					thisquery->next = NULL;
					thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($6));
					sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $6);
4084

4085 4086
					this->argsinsert = NULL;
					add_variable(&(this->argsinsert), thisquery, &no_indicator); 
4087

4088 4089
			        	cur = this;
					
Michael Meskes's avatar
Michael Meskes committed
4090
					$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
Marc G. Fournier's avatar
Marc G. Fournier committed
4091
				}
4092
		;
Marc G. Fournier's avatar
Marc G. Fournier committed
4093

4094
/*
4095 4096
 * the exec sql deallocate prepare command to deallocate a previously
 * prepared statement
4097
 */
Michael Meskes's avatar
Michael Meskes committed
4098
ECPGDeallocate:	SQL_DEALLOCATE SQL_PREPARE ident	{ $$ = cat_str(3, make_str("ECPGdeallocate(__LINE__, \""), $3, make_str("\");")); };
4099

4100 4101 4102 4103
/*
 * variable declaration inside the exec sql declare block
 */
ECPGDeclaration: sql_startdeclare
4104
	{
4105 4106 4107 4108 4109 4110 4111
		fputs("/* exec sql begin declare section */", yyout);
	}
	variable_declarations sql_enddeclare
	{
		fprintf(yyout, "%s/* exec sql end declare section */", $3);
		free($3);
		output_line_number();
Michael Meskes's avatar
Michael Meskes committed
4112
	};
4113

Michael Meskes's avatar
Michael Meskes committed
4114
sql_startdeclare: ecpgstart BEGIN_TRANS DECLARE SQL_SECTION ';' {};
4115

Michael Meskes's avatar
Michael Meskes committed
4116
sql_enddeclare: ecpgstart END_TRANS DECLARE SQL_SECTION ';' {};
4117

Michael Meskes's avatar
Michael Meskes committed
4118 4119
variable_declarations:  /* empty */ { $$ = EMPTY; }
			| declarations { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
4120
			;
Michael Meskes's avatar
Michael Meskes committed
4121 4122 4123

declarations:  declaration { $$ = $1; }
			| declarations declaration { $$ = cat2_str($1, $2); }
Michael Meskes's avatar
Michael Meskes committed
4124
			;
4125

Michael Meskes's avatar
Michael Meskes committed
4126
declaration: storage_clause storage_modifier
4127
	{
Michael Meskes's avatar
Michael Meskes committed
4128
		actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2));
Michael Meskes's avatar
Michael Meskes committed
4129
		actual_startline[struct_level] = hashline_number();
4130 4131 4132
	}
	type
	{
Michael Meskes's avatar
Michael Meskes committed
4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143
		actual_type[struct_level].type_enum = $4.type_enum;
		actual_type[struct_level].type_dimension = $4.type_dimension;
		actual_type[struct_level].type_index = $4.type_index;

		/* we do not need the string "varchar" for output */
		/* so replace it with an empty string */
		if ($4.type_enum == ECPGt_varchar)
		{
			free($4.type_str);
			$4.type_str=EMPTY;
		}
4144 4145 4146
	}
	variable_list ';'
	{
Michael Meskes's avatar
Michael Meskes committed
4147
 		$$ = cat_str(6, actual_startline[struct_level], $1, $2, $4.type_str, $6, make_str(";\n"));
Michael Meskes's avatar
Michael Meskes committed
4148
	};
4149

Michael Meskes's avatar
Michael Meskes committed
4150
storage_clause : S_EXTERN	{ $$ = make_str("extern"); }
Michael Meskes's avatar
Michael Meskes committed
4151 4152 4153 4154 4155
        | S_STATIC		{ $$ = make_str("static"); }
        | S_REGISTER		{ $$ = make_str("register"); }
        | S_AUTO		{ $$ = make_str("auto"); }
        | /* empty */		{ $$ = EMPTY; }
	;
4156

Michael Meskes's avatar
Michael Meskes committed
4157 4158 4159 4160
storage_modifier : S_CONST       { $$ = make_str("const"); }
        | S_VOLATILE             { $$ = make_str("volatile"); }
        | /* empty */            { $$ = EMPTY; }
	;
Michael Meskes's avatar
Michael Meskes committed
4161

4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175
type: simple_type
		{
			$$.type_enum = $1;
			$$.type_str = mm_strdup(ECPGtype_name($1));
			$$.type_dimension = -1;
  			$$.type_index = -1;
		}
	| struct_type
		{
			$$.type_enum = ECPGt_struct;
			$$.type_str = $1;
			$$.type_dimension = -1;
  			$$.type_index = -1;
		}
4176 4177 4178 4179 4180 4181 4182
	| union_type
		{
			$$.type_enum = ECPGt_union;
			$$.type_str = $1;
			$$.type_dimension = -1;
  			$$.type_index = -1;
		}
4183 4184 4185 4186
	| enum_type
		{
			$$.type_str = $1;
			$$.type_enum = ECPGt_int;
Michael Meskes's avatar
Michael Meskes committed
4187
			$$.type_dimension = -1;
4188 4189
  			$$.type_index = -1;
		}
Michael Meskes's avatar
Michael Meskes committed
4190
	| ECPGColLabel
4191
		{
4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227
			/*
			 * Check for type names that the SQL grammar treats as
			 * unreserved keywords
			 */
			if (strcmp($1, "varchar") == 0)
			{
				$$.type_enum = ECPGt_varchar;
				$$.type_str = make_str("varchar");
				$$.type_dimension = -1;
				$$.type_index = -1;
			}
			else if (strcmp($1, "float") == 0)
			{
				$$.type_enum = ECPGt_float;
				$$.type_str = make_str("float");
				$$.type_dimension = -1;
				$$.type_index = -1;
			}
			else if (strcmp($1, "double") == 0)
			{
				$$.type_enum = ECPGt_double;
				$$.type_str = make_str("double");
				$$.type_dimension = -1;
				$$.type_index = -1;
			}
			else
			{
				/* this is for typedef'ed types */
				struct typedefs *this = get_typedef($1);

				$$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
				$$.type_enum = this->type->type_enum;
				$$.type_dimension = this->type->type_dimension;
				$$.type_index = this->type->type_index;
				struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
			}
4228
		}
Michael Meskes's avatar
Michael Meskes committed
4229
	;
4230

Michael Meskes's avatar
Michael Meskes committed
4231
enum_type: SQL_ENUM opt_symbol enum_definition
4232
	{
Michael Meskes's avatar
Michael Meskes committed
4233 4234 4235 4236 4237
		$$ = cat_str(3, make_str("enum"), $2, $3);
	}
	|  SQL_ENUM symbol
	{
		$$ = cat2_str(make_str("enum"), $2);
4238
	}
Michael Meskes's avatar
Michael Meskes committed
4239
	;
Michael Meskes's avatar
Michael Meskes committed
4240

Michael Meskes's avatar
Michael Meskes committed
4241
enum_definition: '{' c_list '}'	{ $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
4242 4243 4244 4245 4246

struct_type: s_struct '{' variable_declarations '}'
	{
	    ECPGfree_struct_member(struct_member_list[struct_level]);
	    free(actual_storage[struct_level--]);
Michael Meskes's avatar
Michael Meskes committed
4247
	    $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
Michael Meskes's avatar
Michael Meskes committed
4248
	};
4249

4250 4251 4252 4253
union_type: s_union '{' variable_declarations '}'
	{
	    ECPGfree_struct_member(struct_member_list[struct_level]);
	    free(actual_storage[struct_level--]);
Michael Meskes's avatar
Michael Meskes committed
4254
	    $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
Michael Meskes's avatar
Michael Meskes committed
4255
	};
4256

Michael Meskes's avatar
Michael Meskes committed
4257
s_struct: SQL_STRUCT opt_symbol
4258 4259 4260
        {
            struct_member_list[struct_level++] = NULL;
            if (struct_level >= STRUCT_DEPTH)
Michael Meskes's avatar
Michael Meskes committed
4261
                 mmerror(ET_ERROR, "Too many levels in nested structure definition");
Michael Meskes's avatar
Michael Meskes committed
4262 4263 4264 4265 4266

	    /* reset this variable so we see if there was */
	    /* an initializer specified */
	    initializer = 0;

Michael Meskes's avatar
Michael Meskes committed
4267
	    $$ = cat2_str(make_str("struct"), $2);
Michael Meskes's avatar
Michael Meskes committed
4268
	};
4269

Michael Meskes's avatar
Michael Meskes committed
4270
s_union: UNION opt_symbol
4271 4272 4273
        {
            struct_member_list[struct_level++] = NULL;
            if (struct_level >= STRUCT_DEPTH)
Michael Meskes's avatar
Michael Meskes committed
4274
                 mmerror(ET_ERROR, "Too many levels in nested structure definition");
Michael Meskes's avatar
Michael Meskes committed
4275 4276 4277 4278 4279

	    /* reset this variable so we see if there was */
	    /* an initializer specified */
	    initializer = 0;

Michael Meskes's avatar
Michael Meskes committed
4280
	    $$ = cat2_str(make_str("union"), $2);
Michael Meskes's avatar
Michael Meskes committed
4281
	};
4282

Michael Meskes's avatar
Michael Meskes committed
4283 4284 4285
simple_type: unsigned_type		{ $$=$1; }
	|	opt_signed signed_type	{ $$=$2; }
	;
4286

Michael Meskes's avatar
Michael Meskes committed
4287 4288 4289 4290 4291 4292
unsigned_type: SQL_UNSIGNED SQL_SHORT 				{ $$ = ECPGt_unsigned_short; }
		| SQL_UNSIGNED SQL_SHORT SQL_INT		{ $$ = ECPGt_unsigned_short; }
		| SQL_UNSIGNED 					{ $$ = ECPGt_unsigned_int; }
		| SQL_UNSIGNED SQL_INT				{ $$ = ECPGt_unsigned_int; }
		| SQL_UNSIGNED SQL_LONG				{ $$ = ECPGt_unsigned_long; }
		| SQL_UNSIGNED SQL_LONG SQL_INT			{ $$ = ECPGt_unsigned_long; }
4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306
		| SQL_UNSIGNED SQL_LONG SQL_LONG		{ 
#ifdef HAVE_LONG_LONG_INT_64
								  $$ = ECPGt_unsigned_long_long; 
#else
								  $$ = ECPGt_unsigned_long;
#endif
								}
		| SQL_UNSIGNED SQL_LONG SQL_LONG SQL_INT	{ 
#ifdef HAVE_LONG_LONG_INT_64
								  $$ = ECPGt_unsigned_long_long; 
#else
								  $$ = ECPGt_unsigned_long;
#endif
								}
Michael Meskes's avatar
Michael Meskes committed
4307 4308 4309 4310 4311 4312 4313 4314
	        | SQL_UNSIGNED CHAR				{ $$ = ECPGt_unsigned_char; }
		;

signed_type: SQL_SHORT          	{ $$ = ECPGt_short; }
           | SQL_SHORT SQL_INT  	{ $$ = ECPGt_short; }
           | SQL_INT            	{ $$ = ECPGt_int; }
           | SQL_LONG           	{ $$ = ECPGt_long; }
           | SQL_LONG SQL_INT   	{ $$ = ECPGt_long; }
4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328
           | SQL_LONG SQL_LONG		{ 
#ifdef HAVE_LONG_LONG_INT_64
								  $$ = ECPGt_long_long; 
#else
								  $$ = ECPGt_long;
#endif
								}
           | SQL_LONG SQL_LONG SQL_INT	{ 
#ifdef HAVE_LONG_LONG_INT_64
								  $$ = ECPGt_long_long; 
#else
								  $$ = ECPGt_long;
#endif
								}
4329
           | SQL_BOOL   		{ $$ = ECPGt_bool; }
Michael Meskes's avatar
Michael Meskes committed
4330
           | CHAR            		{ $$ = ECPGt_char; }
Michael Meskes's avatar
Michael Meskes committed
4331 4332 4333 4334 4335 4336
	   ;

opt_signed:	SQL_SIGNED
	|	/* EMPTY */
	;

4337 4338 4339 4340 4341 4342
variable_list: variable 
	{
		$$ = $1;
	}
	| variable_list ',' variable
	{
Michael Meskes's avatar
Michael Meskes committed
4343
		$$ = cat_str(3, $1, make_str(","), $3);
4344
	}
Michael Meskes's avatar
Michael Meskes committed
4345
	;
4346

Michael Meskes's avatar
Michael Meskes committed
4347
variable: opt_pointer ECPGColLabel opt_array_bounds opt_initializer
4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358
		{
			struct ECPGtype * type;
                        int dimension = $3.index1; /* dimension of array */
                        int length = $3.index2;    /* lenght of string */
                        char dim[14L], ascii_len[12];

			adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));

			switch (actual_type[struct_level].type_enum)
			{
			   case ECPGt_struct:
4359
			   case ECPGt_union:
4360
                               if (dimension < 0)
4361
                                   type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum);
4362
                               else
4363
                                   type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum), dimension); 
4364

Michael Meskes's avatar
Michael Meskes committed
4365
                               $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4366 4367
                               break;
                           case ECPGt_varchar:
Michael Meskes's avatar
Michael Meskes committed
4368
                               if (dimension < 0)
4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385
                                   type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
                               else
                                   type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);

                               switch(dimension)
                               {
                                  case 0:
				  case -1:
                                  case 1:
                                      *dim = '\0';
                                      break;
                                  default:
                                      sprintf(dim, "[%d]", dimension);
                                      break;
                               }
			       sprintf(ascii_len, "%d", length);

Michael Meskes's avatar
Michael Meskes committed
4386
                               if (length == 0)
Michael Meskes's avatar
Michael Meskes committed
4387
				   mmerror(ET_ERROR, "pointer to varchar are not implemented");
Michael Meskes's avatar
Michael Meskes committed
4388 4389

			       if (dimension == 0)
Michael Meskes's avatar
Michael Meskes committed
4390
				   $$ = cat_str(7, mm_strdup(actual_storage[struct_level]), make2_str(make_str(" struct varchar_"), mm_strdup($2)), make_str(" { int len; char arr["), mm_strdup(ascii_len), make_str("]; } *"), mm_strdup($2), $4);
Michael Meskes's avatar
Michael Meskes committed
4391
			       else
Michael Meskes's avatar
Michael Meskes committed
4392
                                   $$ = cat_str(8, mm_strdup(actual_storage[struct_level]), make2_str(make_str(" struct varchar_"), mm_strdup($2)), make_str(" { int len; char arr["), mm_strdup(ascii_len), make_str("]; } "), mm_strdup($2), mm_strdup(dim), $4);
Michael Meskes's avatar
Michael Meskes committed
4393

4394 4395 4396 4397 4398 4399 4400 4401
                               break;
                           case ECPGt_char:
                           case ECPGt_unsigned_char:
                               if (dimension == -1)
                                   type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
                               else
                                   type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);

Michael Meskes's avatar
Michael Meskes committed
4402
			       $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4403 4404 4405 4406 4407 4408 4409
                               break;
                           default:
                               if (dimension < 0)
                                   type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1);
                               else
                                   type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, 1), dimension);

Michael Meskes's avatar
Michael Meskes committed
4410
			       $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4411 4412 4413 4414 4415 4416 4417 4418 4419
                               break;
			}

			if (struct_level == 0)
				new_variable($2, type);
			else
				ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));

			free($2);
Michael Meskes's avatar
Michael Meskes committed
4420
		};
4421

Michael Meskes's avatar
Michael Meskes committed
4422
opt_initializer: /* empty */		{ $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
4423 4424 4425 4426
	| '=' c_term			{ 
						initializer = 1;
						$$ = cat2_str(make_str("="), $2);
					}
Michael Meskes's avatar
Michael Meskes committed
4427
	;
4428

Michael Meskes's avatar
Michael Meskes committed
4429
opt_pointer: /* empty */	{ $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
4430
	| '*'			{ $$ = make_str("*"); }
4431
	| '*' '*'		{ $$ = make_str("**"); }
Michael Meskes's avatar
Michael Meskes committed
4432
	;
4433 4434 4435 4436 4437 4438 4439 4440

/*
 * As long as the prepare statement is not supported by the backend, we will
 * try to simulate it here so we get dynamic SQL 
 */
ECPGDeclare: DECLARE STATEMENT ident
	{
		/* this is only supported for compatibility */
Michael Meskes's avatar
Michael Meskes committed
4441
		$$ = cat_str(3, make_str("/* declare statement"), $3, make_str("*/"));
Michael Meskes's avatar
Michael Meskes committed
4442
	};
4443 4444 4445 4446 4447 4448
/*
 * the exec sql disconnect statement: disconnect from the given database 
 */
ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }

dis_name: connection_object	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
4449 4450 4451
	| CURRENT	{ $$ = make_str("\"CURRENT\""); }
	| ALL		{ $$ = make_str("\"ALL\""); }
	| /* empty */	{ $$ = make_str("\"CURRENT\""); }
Michael Meskes's avatar
Michael Meskes committed
4452
	;
4453 4454

connection_object: connection_target { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
4455
	| DEFAULT	{ $$ = make_str("\"DEFAULT\""); }
Michael Meskes's avatar
Michael Meskes committed
4456
	;
4457 4458 4459 4460

/*
 * execute a given string as sql command
 */
Michael Meskes's avatar
Michael Meskes committed
4461
ECPGExecute : EXECUTE IMMEDIATE execstring
4462 4463 4464 4465 4466 4467 4468 4469 4470 4471
	{ 
		struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));

		thisquery->type = &ecpg_query;
		thisquery->brace_level = 0;
		thisquery->next = NULL;
		thisquery->name = $3;

		add_variable(&argsinsert, thisquery, &no_indicator); 

Michael Meskes's avatar
Michael Meskes committed
4472
		$$ = make_str("?");
4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484
	}
	| EXECUTE ident 
	{
		struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));

		thisquery->type = &ecpg_query;
		thisquery->brace_level = 0;
		thisquery->next = NULL;
		thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($2));
		sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2);

		add_variable(&argsinsert, thisquery, &no_indicator); 
4485
	} ecpg_using opt_ecpg_into
4486
	{
Michael Meskes's avatar
Michael Meskes committed
4487
		$$ = make_str("?");
4488
	}
Michael Meskes's avatar
Michael Meskes committed
4489
	;
4490

Michael Meskes's avatar
Michael Meskes committed
4491 4492 4493
execstring:	char_variable	{ $$ = $1; }
	| 	CSTRING		{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
	;
4494 4495 4496 4497 4498

/*
 * the exec sql free command to deallocate a previously
 * prepared statement
 */
Michael Meskes's avatar
Michael Meskes committed
4499
ECPGFree:	SQL_FREE ident	{ $$ = $2; };
4500 4501 4502 4503

/*
 * open is an open cursor, at the moment this has to be removed
 */
Michael Meskes's avatar
Michael Meskes committed
4504
ECPGOpen: SQL_OPEN name ecpg_using { $$ = $2; };
4505

Michael Meskes's avatar
Michael Meskes committed
4506
ecpg_using: /* empty */		{ $$ = EMPTY; }
4507
	| USING variablelist	{
Michael Meskes's avatar
Michael Meskes committed
4508
					/* mmerror ("open cursor with variables not implemented yet"); */
Michael Meskes's avatar
Michael Meskes committed
4509
					$$ = EMPTY;
4510
				}
Michael Meskes's avatar
Michael Meskes committed
4511
	;
4512

4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528
opt_sql: /* empty */ | SQL_SQL;

ecpg_into: INTO into_list	{
					$$ = EMPTY;
				}
	| INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
				{
					add_variable(&argsresult, descriptor_variable($4,0), &no_indicator);
					$$ = EMPTY;
				}
	;

opt_ecpg_into: /* empty */         	{ $$ = EMPTY; } 
		| ecpg_into		{ $$ = $1; }
		;

4529 4530
variable: civarind | civar 
variablelist: variable | variable ',' variablelist;
4531 4532 4533 4534 4535

/*
 * As long as the prepare statement is not supported by the backend, we will
 * try to simulate it here so we get dynamic SQL 
 */
Michael Meskes's avatar
Michael Meskes committed
4536
ECPGPrepare: SQL_PREPARE ident FROM execstring
4537
	{
Michael Meskes's avatar
Michael Meskes committed
4538
		$$ = cat2_str(make3_str(make_str("\""), $2, make_str("\",")), $4);
Michael Meskes's avatar
Michael Meskes committed
4539
	};
4540

Michael Meskes's avatar
Michael Meskes committed
4541 4542 4543 4544 4545 4546 4547 4548
/*
 * dynamic SQL: descriptor based access
 * 	written by Christof Petig <christof.petig@wtal.de>
 */

/*
 * deallocate a descriptor
 */
4549
ECPGDeallocateDescr:	SQL_DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
Michael Meskes's avatar
Michael Meskes committed
4550 4551 4552 4553
		{
			drop_descriptor($3,connection);
			$$ = $3;
		};
Michael Meskes's avatar
Michael Meskes committed
4554 4555 4556 4557

/*
 * allocate a descriptor
 */
4558
ECPGAllocateDescr:	SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
Michael Meskes's avatar
Michael Meskes committed
4559 4560 4561 4562
		{
			add_descriptor($3,connection);
			$$ = $3;
		};
Michael Meskes's avatar
Michael Meskes committed
4563 4564 4565 4566 4567

/*
 * read from descriptor
 */

Michael Meskes's avatar
Michael Meskes committed
4568
ECPGGetDescHeaderItem: cvariable '=' desc_header_item  { push_assignment($1, $3); };
Michael Meskes's avatar
Michael Meskes committed
4569

Michael Meskes's avatar
Michael Meskes committed
4570
desc_header_item:	SQL_COUNT		{ $$ = ECPGd_count; };
Michael Meskes's avatar
Michael Meskes committed
4571

Michael Meskes's avatar
Michael Meskes committed
4572
ECPGGetDescItem: cvariable '=' descriptor_item  { push_assignment($1, $3); };
Michael Meskes's avatar
Michael Meskes committed
4573

4574 4575
descriptor_item:	SQL_CARDINALITY	{ $$ = ECPGd_cardinality; }
		|	SQL_DATA			{ $$ = ECPGd_data; }
Michael Meskes's avatar
Michael Meskes committed
4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590
		|	SQL_DATETIME_INTERVAL_CODE	{ $$ = ECPGd_di_code; }
		| 	SQL_DATETIME_INTERVAL_PRECISION	{ $$ = ECPGd_di_precision; }
		|	SQL_INDICATOR			{ $$ = ECPGd_indicator; }
		|	SQL_KEY_MEMBER			{ $$ = ECPGd_key_member; }
		|	SQL_LENGTH			{ $$ = ECPGd_length; }
		|	SQL_NAME			{ $$ = ECPGd_name; }
		|	SQL_NULLABLE			{ $$ = ECPGd_nullable; }
		|	SQL_OCTET_LENGTH		{ $$ = ECPGd_octet; }
		|	PRECISION			{ $$ = ECPGd_precision; }
		|	SQL_RETURNED_LENGTH		{ $$ = ECPGd_length; }
		|	SQL_RETURNED_OCTET_LENGTH	{ $$ = ECPGd_ret_octet; }
		|	SQL_SCALE			{ $$ = ECPGd_scale; }
		|	TYPE_P				{ $$ = ECPGd_type; }
		;

Michael Meskes's avatar
Michael Meskes committed
4591
ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
Michael Meskes's avatar
Michael Meskes committed
4592 4593
	| ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
	;
Michael Meskes's avatar
Michael Meskes committed
4594 4595
 
ECPGGetDescItems: ECPGGetDescItem
Michael Meskes's avatar
Michael Meskes committed
4596 4597
	| ECPGGetDescItems ',' ECPGGetDescItem
	;
Michael Meskes's avatar
Michael Meskes committed
4598
 
4599
ECPGGetDescriptorHeader:	SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
Michael Meskes's avatar
Michael Meskes committed
4600
		{  $$ = $3; };
Michael Meskes's avatar
Michael Meskes committed
4601

4602
ECPGGetDescriptor:	SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE cvariable ECPGGetDescItems
Michael Meskes's avatar
Michael Meskes committed
4603
		{  $$.str = $5; $$.name = $3; }
4604
	|	SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE Iconst ECPGGetDescItems
Michael Meskes's avatar
Michael Meskes committed
4605
		{  $$.str = $5; $$.name = $3; }
Michael Meskes's avatar
Michael Meskes committed
4606
	;
Michael Meskes's avatar
Michael Meskes committed
4607

4608 4609 4610 4611 4612 4613 4614
/*
 * for compatibility with ORACLE we will also allow the keyword RELEASE
 * after a transaction statement to disconnect from the database.
 */

ECPGRelease: TransactionStmt SQL_RELEASE
	{
Michael Meskes's avatar
Michael Meskes committed
4615 4616
		if (strcmp($1, "begin") == 0)
                        mmerror(ET_ERROR, "RELEASE does not make sense when beginning a transaction");
4617

4618 4619
		fprintf(yyout, "ECPGtrans(__LINE__, %s, \"%s\");",
				connection ? connection : "NULL", $1);
4620
		whenever_action(0);
4621
		fprintf(yyout, "ECPGdisconnect(__LINE__, \"\");"); 
4622 4623
		whenever_action(0);
		free($1);
Michael Meskes's avatar
Michael Meskes committed
4624
	};
4625

Michael Meskes's avatar
Michael Meskes committed
4626 4627 4628 4629 4630 4631 4632
/* 
 * set/reset the automatic transaction mode, this needs a differnet handling
 * as the other set commands
 */
ECPGSetAutocommit:  SET SQL_AUTOCOMMIT to_equal on_off
           		{
				$$ = $4;
Michael Meskes's avatar
Michael Meskes committed
4633
                        };
Michael Meskes's avatar
Michael Meskes committed
4634

Michael Meskes's avatar
Michael Meskes committed
4635
on_off:	ON		{ $$ = make_str("on"); }
Michael Meskes's avatar
Michael Meskes committed
4636
	| OFF		{ $$ = make_str("off"); }
Michael Meskes's avatar
Michael Meskes committed
4637
	;
Michael Meskes's avatar
Michael Meskes committed
4638

Michael Meskes's avatar
Michael Meskes committed
4639
to_equal:	TO | '=';
Michael Meskes's avatar
Michael Meskes committed
4640

4641 4642 4643 4644
/* 
 * set the actual connection, this needs a differnet handling as the other
 * set commands
 */
Michael Meskes's avatar
Michael Meskes committed
4645
ECPGSetConnection:  SET SQL_CONNECTION to_equal connection_object
4646
           		{
Michael Meskes's avatar
Michael Meskes committed
4647
				$$ = $4;
Michael Meskes's avatar
Michael Meskes committed
4648
                        };
4649 4650 4651 4652

/*
 * define a new type for embedded SQL
 */
4653
ECPGTypedef: TYPE_P ColLabel IS type opt_type_array_bounds opt_reference
4654 4655 4656 4657 4658 4659
	{
		/* add entry to list */
		struct typedefs *ptr, *this;
		int dimension = $5.index1;
		int length = $5.index2;

Michael Meskes's avatar
Michael Meskes committed
4660 4661 4662 4663 4664
		if (($4.type_enum == ECPGt_struct ||
		     $4.type_enum == ECPGt_union) &&
		    initializer == 1)
			mmerror(ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");

4665 4666 4667 4668 4669
		for (ptr = types; ptr != NULL; ptr = ptr->next)
		{
			if (strcmp($2, ptr->name) == 0)
			{
			        /* re-definition is a bug */
Michael Meskes's avatar
Michael Meskes committed
4670
				sprintf(errortext, "Type %s already defined", $2);
Michael Meskes's avatar
Michael Meskes committed
4671
				mmerror(ET_ERROR, errortext);
4672 4673 4674
	                }
		}

4675
		adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, *$6?1:0);
4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686

        	this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));

        	/* initial definition */
	        this->next = types;
	        this->name = $2;
		this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
		this->type->type_enum = $4.type_enum;
		this->type->type_str = mm_strdup($2);
		this->type->type_dimension = dimension; /* dimension of array */
		this->type->type_index = length;    /* lenght of string */
Michael Meskes's avatar
Michael Meskes committed
4687 4688
		this->struct_member_list = ($4.type_enum == ECPGt_struct || $4.type_enum == ECPGt_union) ?
			struct_member_list[struct_level] : NULL;
4689 4690 4691 4692 4693

		if ($4.type_enum != ECPGt_varchar &&
		    $4.type_enum != ECPGt_char &&
	            $4.type_enum != ECPGt_unsigned_char &&
		    this->type->type_index >= 0)
Michael Meskes's avatar
Michael Meskes committed
4694
                            mmerror(ET_ERROR, "No multi-dimensional array support for simple data types");
4695 4696 4697

        	types = this;

Michael Meskes's avatar
Michael Meskes committed
4698
		$$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($2), make_str("is"), mm_strdup($4.type_str), mm_strdup($5.str), $6, make_str("*/"));
Michael Meskes's avatar
Michael Meskes committed
4699
	};
4700

Michael Meskes's avatar
Michael Meskes committed
4701
opt_type_array_bounds:  '[' ']' opt_type_array_bounds
4702 4703 4704
			{
                            $$.index1 = 0;
                            $$.index2 = $3.index1;
Michael Meskes's avatar
Michael Meskes committed
4705
                            $$.str = cat2_str(make_str("[]"), $3.str);
4706
                        }
Michael Meskes's avatar
Michael Meskes committed
4707
		| '(' ')' opt_type_array_bounds
4708 4709 4710
			{
                            $$.index1 = 0;
                            $$.index2 = $3.index1;
Michael Meskes's avatar
Michael Meskes committed
4711
                            $$.str = cat2_str(make_str("[]"), $3.str);
4712
                        }
Michael Meskes's avatar
Michael Meskes committed
4713
		| '[' Iresult ']' opt_type_array_bounds
4714
			{
Michael Meskes's avatar
Michael Meskes committed
4715 4716 4717 4718
			    char *txt = mm_alloc(20L);

			    sprintf (txt, "%d", $2);
                            $$.index1 = $2;
4719
                            $$.index2 = $4.index1;
Michael Meskes's avatar
Michael Meskes committed
4720
                            $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
4721
                        }
Michael Meskes's avatar
Michael Meskes committed
4722
		| '(' Iresult ')' opt_type_array_bounds
4723
			{
Michael Meskes's avatar
Michael Meskes committed
4724 4725 4726 4727
			    char *txt = mm_alloc(20L);

			    sprintf (txt, "%d", $2);
                            $$.index1 = $2;
4728
                            $$.index2 = $4.index1;
Michael Meskes's avatar
Michael Meskes committed
4729
                            $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
4730 4731 4732 4733 4734
                        }
		| /* EMPTY */
			{
                            $$.index1 = -1;
                            $$.index2 = -1;
Michael Meskes's avatar
Michael Meskes committed
4735
                            $$.str= EMPTY;
4736 4737 4738
                        }
		;

Michael Meskes's avatar
Michael Meskes committed
4739
opt_reference: SQL_REFERENCE { $$ = make_str("reference"); }
Michael Meskes's avatar
Michael Meskes committed
4740
	| /* empty */ 	     { $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
4741
	;
4742 4743 4744 4745

/*
 * define the type of one variable for embedded SQL
 */
4746
ECPGVar: SQL_VAR ColLabel IS type opt_type_array_bounds opt_reference
4747 4748 4749 4750 4751 4752
	{
		struct variable *p = find_variable($2);
		int dimension = $5.index1;
		int length = $5.index2;
		struct ECPGtype * type;

Michael Meskes's avatar
Michael Meskes committed
4753 4754 4755 4756 4757
		if (($4.type_enum == ECPGt_struct ||
		     $4.type_enum == ECPGt_union) &&
		    initializer == 1)
			mmerror(ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");

4758
		adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, *$6?1:0);
4759 4760 4761 4762

		switch ($4.type_enum)
		{
		   case ECPGt_struct:
4763
		   case ECPGt_union:
4764
                        if (dimension < 0)
4765
                            type = ECPGmake_struct_type(struct_member_list[struct_level], $4.type_enum);
4766
                        else
4767
                            type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $4.type_enum), dimension); 
4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785
                        break;
                   case ECPGt_varchar:
                        if (dimension == -1)
                            type = ECPGmake_simple_type($4.type_enum, length);
                        else
                            type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, length), dimension);

			break;
                   case ECPGt_char:
                   case ECPGt_unsigned_char:
                        if (dimension == -1)
                            type = ECPGmake_simple_type($4.type_enum, length);
                        else
                            type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, length), dimension);

			break;
		   default:
			if (length >= 0)
Michael Meskes's avatar
Michael Meskes committed
4786
                	    mmerror(ET_ERROR, "No multi-dimensional array support for simple data types");
4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798

                        if (dimension < 0)
                            type = ECPGmake_simple_type($4.type_enum, 1);
                        else
                            type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, 1), dimension);

			break;
		}	

		ECPGfree_type(p->type);
		p->type = type;

Michael Meskes's avatar
Michael Meskes committed
4799
		$$ = cat_str(7, make_str("/* exec sql var"), mm_strdup($2), make_str("is"), mm_strdup($4.type_str), mm_strdup($5.str), $6, make_str("*/"));
Michael Meskes's avatar
Michael Meskes committed
4800
	};
4801

Marc G. Fournier's avatar
Marc G. Fournier committed
4802
/*
4803
 * whenever statement: decide what to do in case of error/no data found
4804
 * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
Marc G. Fournier's avatar
Marc G. Fournier committed
4805
 */
Michael Meskes's avatar
Michael Meskes committed
4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824
ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
	{
		when_error.code = $<action>3.code;
		when_error.command = $<action>3.command;
		$$ = cat_str(3, make_str("/* exec sql whenever sqlerror "), $3.str, make_str("; */\n"));
	}
	| SQL_WHENEVER NOT SQL_FOUND action
	{
		when_nf.code = $<action>4.code;
		when_nf.command = $<action>4.command;
		$$ = cat_str(3, make_str("/* exec sql whenever not found "), $4.str, make_str("; */\n"));
	}
	| SQL_WHENEVER SQL_SQLWARNING action
	{
		when_warn.code = $<action>3.code;
		when_warn.command = $<action>3.command;
		$$ = cat_str(3, make_str("/* exec sql whenever sql_warning "), $3.str, make_str("; */\n"));
	}
	;
4825

Michael Meskes's avatar
Michael Meskes committed
4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874
action : SQL_CONTINUE
	{
		$<action>$.code = W_NOTHING;
		$<action>$.command = NULL;
		$<action>$.str = make_str("continue");
	}
       | SQL_SQLPRINT
	{
		$<action>$.code = W_SQLPRINT;
		$<action>$.command = NULL;
		$<action>$.str = make_str("sqlprint");
	}
       | SQL_STOP
	{
		$<action>$.code = W_STOP;
		$<action>$.command = NULL;
		$<action>$.str = make_str("stop");
	}
       | SQL_GOTO name
	{
        	$<action>$.code = W_GOTO;
	        $<action>$.command = strdup($2);
		$<action>$.str = cat2_str(make_str("goto "), $2);
	}
       | SQL_GO TO name
	{
        	$<action>$.code = W_GOTO;
	        $<action>$.command = strdup($3);
		$<action>$.str = cat2_str(make_str("goto "), $3);
	}
       | DO name '(' c_args ')'
	{
		$<action>$.code = W_DO;
		$<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
		$<action>$.str = cat2_str(make_str("do"), mm_strdup($<action>$.command));
	}
       | DO SQL_BREAK
	{
        	$<action>$.code = W_BREAK;
	        $<action>$.command = NULL;
        	$<action>$.str = make_str("break");
	}
       | SQL_CALL name '(' c_args ')'
	{
		$<action>$.code = W_DO;
		$<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
		$<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
	}
	;
4875

4876
/* some other stuff for ecpg */
Michael Meskes's avatar
Michael Meskes committed
4877

4878 4879 4880 4881
/* additional ColId entries */
ECPGKeywords: 	  SQL_BREAK			{ $$ = make_str("break"); }
		| SQL_CALL			{ $$ = make_str("call"); }
		| SQL_CARDINALITY	{ $$ = make_str("cardinality"); }
Michael Meskes's avatar
Michael Meskes committed
4882 4883
		| SQL_CONNECT			{ $$ = make_str("connect"); }
		| SQL_CONTINUE			{ $$ = make_str("continue"); }
4884 4885
		| SQL_COUNT			{ $$ = make_str("count"); }
		| SQL_DATA			{ $$ = make_str("data"); }
Michael Meskes's avatar
Michael Meskes committed
4886 4887 4888 4889
		| SQL_DATETIME_INTERVAL_CODE	{ $$ = make_str("datetime_interval_code"); }
		| SQL_DATETIME_INTERVAL_PRECISION	{ $$ = make_str("datetime_interval_precision"); }
		| SQL_DEALLOCATE		{ $$ = make_str("deallocate"); }
		| SQL_DISCONNECT		{ $$ = make_str("disconnect"); }
4890 4891 4892
		| SQL_FOUND			{ $$ = make_str("found"); }
		| SQL_GO			{ $$ = make_str("go"); }
		| SQL_GOTO			{ $$ = make_str("goto"); }
Michael Meskes's avatar
Michael Meskes committed
4893 4894 4895 4896
		| SQL_IDENTIFIED		{ $$ = make_str("identified"); }
		| SQL_INDICATOR			{ $$ = make_str("indicator"); }
		| SQL_KEY_MEMBER		{ $$ = make_str("key_member"); }
		| SQL_LENGTH			{ $$ = make_str("length"); }
4897
		| SQL_NAME			{ $$ = make_str("name"); }
Michael Meskes's avatar
Michael Meskes committed
4898 4899
		| SQL_NULLABLE			{ $$ = make_str("nullable"); }
		| SQL_OCTET_LENGTH		{ $$ = make_str("octet_length"); }
4900
		| SQL_OPEN			{ $$ = make_str("open"); }
Michael Meskes's avatar
Michael Meskes committed
4901 4902 4903 4904
		| SQL_PREPARE			{ $$ = make_str("prepare"); }
		| SQL_RELEASE			{ $$ = make_str("release"); }
		| SQL_RETURNED_LENGTH		{ $$ = make_str("returned_length"); }
		| SQL_RETURNED_OCTET_LENGTH	{ $$ = make_str("returned_octet_length"); }
4905
		| SQL_SCALE			{ $$ = make_str("scale"); }
Michael Meskes's avatar
Michael Meskes committed
4906 4907 4908 4909
		| SQL_SECTION			{ $$ = make_str("section"); }
		| SQL_SQLERROR			{ $$ = make_str("sqlerror"); }
		| SQL_SQLPRINT			{ $$ = make_str("sqlprint"); }
		| SQL_SQLWARNING		{ $$ = make_str("sqlwarning"); }
4910 4911
		| SQL_STOP			{ $$ = make_str("stop"); }
		| SQL_VAR			{ $$ = make_str("var"); }
Michael Meskes's avatar
Michael Meskes committed
4912
		| SQL_WHENEVER			{ $$ = make_str("whenever"); }
4913
/*		| ECPGTypeName			{ $$ = $1 }*/
Michael Meskes's avatar
Michael Meskes committed
4914 4915
		;

4916 4917 4918 4919
ECPGTypeName:	  SQL_BOOL		{ $$ = make_str("bool"); }
		| SQL_INT		{ $$ = make_str("int"); }
		| SQL_LONG		{ $$ = make_str("long"); }
		| SQL_SHORT		{ $$ = make_str("short"); }
Michael Meskes's avatar
Michael Meskes committed
4920 4921 4922 4923 4924 4925 4926 4927 4928
		| SQL_STRUCT		{ $$ = make_str("struct"); }
		| SQL_SIGNED		{ $$ = make_str("signed"); }
		| SQL_UNSIGNED		{ $$ = make_str("unsigned"); }
		;

opt_symbol:	symbol		{ $$ = $1; }
		| /*EMPTY*/	{ $$ = EMPTY; }
		;

Michael Meskes's avatar
Michael Meskes committed
4929
symbol:		ColLabel	{ $$ = $1; };
Michael Meskes's avatar
Michael Meskes committed
4930

4931
/*
4932 4933 4934 4935 4936 4937 4938 4939
 * Keyword classification lists.  Generally, every keyword present in
 * the Postgres grammar should be in one of these lists.  (Presently,
 * "AS" is the sole exception: it is our only completely-reserved word.)
 *
 * Put a new keyword into the earliest list (of TypeFuncId, ColId, ColLabel)
 * that it can go into without creating shift or reduce conflicts.  The
 * earlier lists define "less reserved" categories of keywords.  Notice that
 * each list includes by reference the ones before it.
Michael Meskes's avatar
Michael Meskes committed
4940
 */
Michael Meskes's avatar
Michael Meskes committed
4941

4942 4943
/* Type/func identifier --- names that can be type and function names
 * (as well as ColIds --- ie, these are completely unreserved keywords).
4944
 */
4945
TypeFuncId:  ECPGTypeFuncId				{ $$ = $1; }
4946 4947 4948
		| ECPGKeywords                  { $$ = $1; }
		;

4949 4950
ECPGTypeFuncId:  ident					{ $$ = $1; }
		| ABORT_TRANS					{ $$ = make_str("abort"); }
4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105
		| ABSOLUTE						{ $$ = make_str("absolute"); }
		| ACCESS						{ $$ = make_str("access"); }
		| ACTION						{ $$ = make_str("action"); }
		| ADD							{ $$ = make_str("add"); }
		| AFTER							{ $$ = make_str("after"); }
		| AGGREGATE						{ $$ = make_str("aggregate"); }
		| ALTER							{ $$ = make_str("alter"); }
		| AT							{ $$ = make_str("at"); }
		| AUTHORIZATION					{ $$ = make_str("authorization"); }
		| BACKWARD						{ $$ = make_str("backward"); }
		| BEFORE						{ $$ = make_str("before"); }
		| BEGIN_TRANS					{ $$ = make_str("begin"); }
		| BY							{ $$ = make_str("by"); }
		| CACHE							{ $$ = make_str("cache"); }
		| CASCADE						{ $$ = make_str("cascade"); }
		| CHAIN							{ $$ = make_str("chain"); }
		| CHARACTERISTICS				{ $$ = make_str("characteristics"); }
		| CHECKPOINT					{ $$ = make_str("checkpoint"); }
		| CLOSE							{ $$ = make_str("close"); }
		| CLUSTER						{ $$ = make_str("cluster"); }
		| COMMENT						{ $$ = make_str("comment"); }
		| COMMIT						{ $$ = make_str("commit"); }
		| COMMITTED						{ $$ = make_str("committed"); }
		| CONSTRAINTS					{ $$ = make_str("constraints"); }
		| COPY							{ $$ = make_str("copy"); }
		| CREATE						{ $$ = make_str("create"); }
		| CREATEDB						{ $$ = make_str("createdb"); }
		| CREATEUSER					{ $$ = make_str("createuser"); }
		| CURSOR						{ $$ = make_str("cursor"); }
		| CYCLE							{ $$ = make_str("cycle"); }
		| DATABASE						{ $$ = make_str("database"); }
		| DAY_P							{ $$ = make_str("day"); }
		| DECLARE						{ $$ = make_str("declare"); }
		| DEFERRED						{ $$ = make_str("deferred"); }
		| DELETE						{ $$ = make_str("delete"); }
		| DELIMITERS					{ $$ = make_str("delimiters"); }
		| DOUBLE						{ $$ = make_str("double"); }
		| DROP							{ $$ = make_str("drop"); }
		| EACH							{ $$ = make_str("each"); }
		| ENCODING						{ $$ = make_str("encoding"); }
		| ENCRYPTED						{ $$ = make_str("encrypted"); }
		| ESCAPE						{ $$ = make_str("escape"); }
		| EXCLUSIVE						{ $$ = make_str("exclusive"); }
		| EXECUTE						{ $$ = make_str("execute"); }
		| EXPLAIN						{ $$ = make_str("explain"); }
		| FETCH							{ $$ = make_str("fetch"); }
		| FORCE							{ $$ = make_str("force"); }
		| FORWARD						{ $$ = make_str("forward"); }
		| FUNCTION						{ $$ = make_str("function"); }
		| GLOBAL						{ $$ = make_str("global"); }
		| GRANT							{ $$ = make_str("grant"); }
		| HANDLER						{ $$ = make_str("handler"); }
		| HOUR_P						{ $$ = make_str("hour"); }
		| IMMEDIATE						{ $$ = make_str("immediate"); }
		| INCREMENT						{ $$ = make_str("increment"); }
		| INDEX							{ $$ = make_str("index"); }
		| INHERITS						{ $$ = make_str("inherits"); }
		| INOUT							{ $$ = make_str("inout"); }
		| INSENSITIVE					{ $$ = make_str("insensitive"); }
		| INSERT						{ $$ = make_str("insert"); }
		| INSTEAD						{ $$ = make_str("instead"); }
		| ISOLATION						{ $$ = make_str("isolation"); }
		| KEY							{ $$ = make_str("key"); }
		| LANGUAGE						{ $$ = make_str("language"); }
		| LANCOMPILER					{ $$ = make_str("lancompiler"); }
		| LEVEL							{ $$ = make_str("level"); }
		| LISTEN						{ $$ = make_str("listen"); }
		| LOAD							{ $$ = make_str("load"); }
		| LOCAL							{ $$ = make_str("local"); }
		| LOCATION						{ $$ = make_str("location"); }
		| LOCK_P						{ $$ = make_str("lock"); }
		| MATCH							{ $$ = make_str("match"); }
		| MAXVALUE						{ $$ = make_str("maxvalue"); }
		| MINUTE_P						{ $$ = make_str("minute"); }
		| MINVALUE						{ $$ = make_str("minvalue"); }
		| MODE							{ $$ = make_str("mode"); }
		| MONTH_P						{ $$ = make_str("month"); }
		| MOVE							{ $$ = make_str("move"); }
		| NAMES							{ $$ = make_str("names"); }
		| NATIONAL						{ $$ = make_str("national"); }
		| NEXT							{ $$ = make_str("next"); }
		| NO							{ $$ = make_str("no"); }
		| NOCREATEDB					{ $$ = make_str("nocreatedb"); }
		| NOCREATEUSER					{ $$ = make_str("nocreateuser"); }
		| NOTHING						{ $$ = make_str("nothing"); }
		| NOTIFY						{ $$ = make_str("notify"); }
		| OF							{ $$ = make_str("of"); }
		| OIDS							{ $$ = make_str("oids"); }
		| OPERATOR						{ $$ = make_str("operator"); }
		| OPTION						{ $$ = make_str("option"); }
		| OUT							{ $$ = make_str("out"); }
		| OWNER							{ $$ = make_str("owner"); }
		| PARTIAL						{ $$ = make_str("partial"); }
		| PASSWORD						{ $$ = make_str("password"); }
		| PATH_P						{ $$ = make_str("path"); }
		| PENDANT						{ $$ = make_str("pendant"); }
		| PRECISION						{ $$ = make_str("precision"); }
		| PRIOR							{ $$ = make_str("prior"); }
		| PRIVILEGES					{ $$ = make_str("privileges"); }
		| PROCEDURAL					{ $$ = make_str("procedural"); }
		| PROCEDURE						{ $$ = make_str("procedure"); }
		| READ							{ $$ = make_str("read"); }
		| REINDEX						{ $$ = make_str("reindex"); }
		| RELATIVE						{ $$ = make_str("relative"); }
		| RENAME						{ $$ = make_str("rename"); }
		| REPLACE						{ $$ = make_str("replace"); }
		| RESET							{ $$ = make_str("reset"); }
		| RESTRICT						{ $$ = make_str("restrict"); }
		| RETURNS						{ $$ = make_str("returns"); }
		| REVOKE						{ $$ = make_str("revoke"); }
		| ROLLBACK						{ $$ = make_str("rollback"); }
		| ROW							{ $$ = make_str("row"); }
		| RULE							{ $$ = make_str("rule"); }
		| SCHEMA						{ $$ = make_str("schema"); }
		| SCROLL						{ $$ = make_str("scroll"); }
		| SECOND_P						{ $$ = make_str("second"); }
		| SESSION						{ $$ = make_str("session"); }
		| SEQUENCE						{ $$ = make_str("sequence"); }
		| SERIALIZABLE					{ $$ = make_str("serializable"); }
		| SET							{ $$ = make_str("set"); }
		| SHARE							{ $$ = make_str("share"); }
		| SHOW							{ $$ = make_str("show"); }
		| START							{ $$ = make_str("start"); }
		| STATEMENT						{ $$ = make_str("statement"); }
		| STATISTICS					{ $$ = make_str("statistics"); }
		| STDIN							{ $$ = make_str("stdin"); }
		| STDOUT						{ $$ = make_str("stdout"); }
		| SYSID							{ $$ = make_str("sysid"); }
		| TEMP							{ $$ = make_str("temp"); }
		| TEMPLATE						{ $$ = make_str("template"); }
		| TEMPORARY						{ $$ = make_str("temporary"); }
		| TOAST							{ $$ = make_str("toast"); }
		| TRANSACTION					{ $$ = make_str("transaction"); }
		| TRIGGER						{ $$ = make_str("trigger"); }
		| TRUNCATE						{ $$ = make_str("truncate"); }
		| TRUSTED						{ $$ = make_str("trusted"); }
		| TYPE_P						{ $$ = make_str("type"); }
		| UNENCRYPTED					{ $$ = make_str("unencrypted"); }
		| UNKNOWN						{ $$ = make_str("unknown"); }
		| UNLISTEN						{ $$ = make_str("unlisten"); }
		| UNTIL							{ $$ = make_str("until"); }
		| UPDATE						{ $$ = make_str("update"); }
		| VACUUM						{ $$ = make_str("vacuum"); }
		| VALID							{ $$ = make_str("valid"); }
		| VALUES						{ $$ = make_str("values"); }
		| VARYING						{ $$ = make_str("varying"); }
		| VERSION						{ $$ = make_str("version"); }
		| VIEW							{ $$ = make_str("view"); }
		| WITH							{ $$ = make_str("with"); }
		| WITHOUT						{ $$ = make_str("without"); }
		| WORK							{ $$ = make_str("work"); }
		| YEAR_P						{ $$ = make_str("year"); }
		| ZONE							{ $$ = make_str("zone"); }
		;

5106
/* Column identifier --- names that can be column, table, etc names.
5107
 *
5108 5109 5110 5111
 * This contains the TypeFuncId list plus those keywords that conflict
 * only with typename productions, not with other uses.  Note that
 * most of these keywords will in fact be recognized as type names too;
 * they just have to have special productions for the purpose.
5112
 *
5113 5114 5115
 * Most of these cannot be in TypeFuncId (ie, are not also usable as function
 * names) because they can be followed by '(' in typename productions, which
 * looks too much like a function call for a LALR(1) parser.
5116
 */
5117 5118 5119 5120 5121 5122
ColId:  ECPGColId						{ $$ = $1; }
		| CHAR							{ $$ = make_str("char"); }
		;

ECPGColId:  TypeFuncId					{ $$ = $1; }
		| BIT							{ $$ = make_str("bit"); }
5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139
/* CHAR must be excluded from ECPGColLabel because of conflict with UNSIGNED
		| CHAR							{ $$ = make_str("char"); }
 */
		| CHARACTER						{ $$ = make_str("character"); }
		| DEC							{ $$ = make_str("dec"); }
		| DECIMAL						{ $$ = make_str("decimal"); }
		| FLOAT							{ $$ = make_str("float"); }
		| INTERVAL						{ $$ = make_str("interval"); }
		| NCHAR							{ $$ = make_str("nchar"); }
		| NONE							{ $$ = make_str("none"); }
		| NUMERIC						{ $$ = make_str("numeric"); }
		| SETOF							{ $$ = make_str("setof"); }
		| TIME							{ $$ = make_str("time"); }
		| TIMESTAMP						{ $$ = make_str("timestamp"); }
		| VARCHAR						{ $$ = make_str("varchar"); }
		;

5140
/* Column label --- allowed labels in "AS" clauses.
5141
 *
5142 5143 5144
 * Keywords appear here if they could not be distinguished from variable,
 * type, or function names in some contexts.
 * When adding a ColLabel, consider whether it can be added to func_name.
5145
 */
5146 5147 5148
ColLabel:  ECPGColLabel					{ $$ = $1; }
		| CHAR							{ $$ = make_str("char"); }
		| UNION							{ $$ = make_str("union"); }
5149 5150
		;

5151 5152
ECPGColLabel:  ECPGColId				{ $$ = $1; }
		| ALL							{ $$ = make_str("all"); }
5153 5154 5155 5156 5157
		| ANALYSE						{ $$ = make_str("analyse"); } /* British */
		| ANALYZE						{ $$ = make_str("analyze"); }
		| AND							{ $$ = make_str("and"); }
		| ANY							{ $$ = make_str("any"); }
		| ASC							{ $$ = make_str("asc"); }
5158 5159
		| BETWEEN						{ $$ = make_str("between"); }
		| BINARY						{ $$ = make_str("binary"); }
5160 5161 5162 5163
		| BOTH							{ $$ = make_str("both"); }
		| CASE							{ $$ = make_str("case"); }
		| CAST							{ $$ = make_str("cast"); }
		| CHECK							{ $$ = make_str("check"); }
5164
		| COALESCE						{ $$ = make_str("coalesce"); }
5165 5166 5167
		| COLLATE						{ $$ = make_str("collate"); }
		| COLUMN						{ $$ = make_str("column"); }
		| CONSTRAINT					{ $$ = make_str("constraint"); }
5168
		| CROSS							{ $$ = make_str("cross"); }
5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180
		| CURRENT_DATE					{ $$ = make_str("current_date"); }
		| CURRENT_TIME					{ $$ = make_str("current_time"); }
		| CURRENT_TIMESTAMP				{ $$ = make_str("current_timestamp"); }
		| CURRENT_USER					{ $$ = make_str("current_user"); }
		| DEFAULT						{ $$ = make_str("default"); }
		| DEFERRABLE					{ $$ = make_str("deferrable"); }
		| DESC							{ $$ = make_str("desc"); }
		| DISTINCT						{ $$ = make_str("distinct"); }
		| DO							{ $$ = make_str("do"); }
		| ELSE							{ $$ = make_str("else"); }
		| END_TRANS						{ $$ = make_str("end"); }
		| EXCEPT						{ $$ = make_str("except"); }
5181 5182
		| EXISTS						{ $$ = make_str("exists"); }
		| EXTRACT						{ $$ = make_str("extract"); }
5183 5184 5185
		| FALSE_P						{ $$ = make_str("false"); }
		| FOR							{ $$ = make_str("for"); }
		| FOREIGN						{ $$ = make_str("foreign"); }
5186
		| FREEZE						{ $$ = make_str("freeze"); }
5187
		| FROM							{ $$ = make_str("from"); }
5188
		| FULL							{ $$ = make_str("full"); }
5189 5190
		| GROUP							{ $$ = make_str("group"); }
		| HAVING						{ $$ = make_str("having"); }
5191 5192
		| ILIKE							{ $$ = make_str("ilike"); }
		| IN							{ $$ = make_str("in"); }
5193
		| INITIALLY						{ $$ = make_str("initially"); }
5194
		| INNER_P						{ $$ = make_str("inner"); }
5195 5196
		| INTERSECT						{ $$ = make_str("intersect"); }
		| INTO							{ $$ = make_str("into"); }
5197 5198 5199
		| IS							{ $$ = make_str("is"); }
		| ISNULL						{ $$ = make_str("isnull"); }
		| JOIN							{ $$ = make_str("join"); }
5200
		| LEADING						{ $$ = make_str("leading"); }
5201 5202
		| LEFT							{ $$ = make_str("left"); }
		| LIKE							{ $$ = make_str("like"); }
5203
		| LIMIT							{ $$ = make_str("limit"); }
5204
		| NATURAL						{ $$ = make_str("natural"); }
5205 5206
		| NEW							{ $$ = make_str("new"); }
		| NOT							{ $$ = make_str("not"); }
5207 5208
		| NOTNULL						{ $$ = make_str("notnull"); }
		| NULLIF						{ $$ = make_str("nullif"); }
5209 5210 5211 5212 5213 5214 5215 5216
		| NULL_P						{ $$ = make_str("null"); }
		| OFF							{ $$ = make_str("off"); }
		| OFFSET						{ $$ = make_str("offset"); }
		| OLD							{ $$ = make_str("old"); }
		| ON							{ $$ = make_str("on"); }
		| ONLY							{ $$ = make_str("only"); }
		| OR							{ $$ = make_str("or"); }
		| ORDER							{ $$ = make_str("order"); }
5217 5218 5219
		| OUTER_P						{ $$ = make_str("outer"); }
		| OVERLAPS						{ $$ = make_str("overlaps"); }
		| POSITION						{ $$ = make_str("position"); }
5220
		| PRIMARY						{ $$ = make_str("primary"); }
5221
		| PUBLIC						{ $$ = make_str("public"); }
5222
		| REFERENCES					{ $$ = make_str("references"); }
5223
		| RIGHT							{ $$ = make_str("right"); }
5224 5225 5226
		| SELECT						{ $$ = make_str("select"); }
		| SESSION_USER					{ $$ = make_str("session_user"); }
		| SOME							{ $$ = make_str("some"); }
5227
		| SUBSTRING						{ $$ = make_str("substring"); }
5228 5229 5230 5231
		| TABLE							{ $$ = make_str("table"); }
		| THEN							{ $$ = make_str("then"); }
		| TO							{ $$ = make_str("to"); }
		| TRAILING						{ $$ = make_str("trailing"); }
5232
		| TRIM							{ $$ = make_str("trim"); }
5233 5234 5235 5236 5237 5238 5239
		| TRUE_P						{ $$ = make_str("true"); }
/* UNION must be excluded from ECPGColLabel because of conflict with s_union
		| UNION							{ $$ = make_str("union"); }
 */
		| UNIQUE						{ $$ = make_str("unique"); }
		| USER							{ $$ = make_str("user"); }
		| USING							{ $$ = make_str("using"); }
5240
		| VERBOSE						{ $$ = make_str("verbose"); }
5241 5242 5243 5244
		| WHEN							{ $$ = make_str("when"); }
		| WHERE							{ $$ = make_str("where"); }
		;

5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277
/* Function identifier --- names that can be function names.
 *
 * This contains the TypeFuncId list plus some ColLabel keywords
 * that are used as operators in expressions; in general such keywords
 * can't be ColId because they would be ambiguous with variable names,
 * 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:  TypeFuncId					{ $$ = $1; }
		| BETWEEN						{ $$ = make_str("between"); }
		| BINARY						{ $$ = make_str("binary"); }
		| CROSS							{ $$ = make_str("cross"); }
		| FREEZE						{ $$ = make_str("freeze"); }
		| FULL							{ $$ = make_str("full"); }
		| ILIKE							{ $$ = make_str("ilike"); }
		| IN							{ $$ = make_str("in"); }
		| INNER_P						{ $$ = make_str("inner"); }
		| IS							{ $$ = make_str("is"); }
		| ISNULL						{ $$ = make_str("isnull"); }
		| JOIN							{ $$ = make_str("join"); }
		| LEFT							{ $$ = make_str("left"); }
		| LIKE							{ $$ = make_str("like"); }
		| NATURAL						{ $$ = make_str("natural"); }
		| NOTNULL						{ $$ = make_str("notnull"); }
		| OUTER_P						{ $$ = make_str("outer"); }
		| OVERLAPS						{ $$ = make_str("overlaps"); }
		| PUBLIC						{ $$ = make_str("public"); }
		| RIGHT							{ $$ = make_str("right"); }
		| VERBOSE						{ $$ = make_str("verbose"); }
		;
Marc G. Fournier's avatar
Marc G. Fournier committed
5278 5279 5280

into_list : coutputvariable | into_list ',' coutputvariable;

Michael Meskes's avatar
Michael Meskes committed
5281
ecpgstart: SQL_START { reset_variables(); };
5282

Michael Meskes's avatar
Michael Meskes committed
5283
c_args: /* empty */		{ $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
5284
	| c_list		{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5285
	;
Marc G. Fournier's avatar
Marc G. Fournier committed
5286

5287
coutputvariable: cvariable indicator
Michael Meskes's avatar
Michael Meskes committed
5288
	{
5289 5290 5291 5292 5293 5294 5295
		add_variable(&argsresult, find_variable($1), find_variable($2)); 
	}
	| cvariable
	{
		add_variable(&argsresult, find_variable($1), &no_indicator); 
	}
	;
Marc G. Fournier's avatar
Marc G. Fournier committed
5296

5297 5298

civarind: cvariable indicator
Michael Meskes's avatar
Michael Meskes committed
5299
	{
Michael Meskes's avatar
Michael Meskes committed
5300 5301 5302
		if ($2 != NULL && (find_variable($2))->type->typ == ECPGt_array)
			mmerror(ET_ERROR, "arrays of indicators are not allowed on input");

5303
		add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2)); 
Michael Meskes's avatar
Michael Meskes committed
5304
	};
Marc G. Fournier's avatar
Marc G. Fournier committed
5305

5306
civar: cvariable
Michael Meskes's avatar
Michael Meskes committed
5307
	{
5308
		add_variable(&argsinsert, find_variable($1), &no_indicator); 
5309
		$$ = $1;
Michael Meskes's avatar
Michael Meskes committed
5310
	};
5311

5312
cvariable: CVARIABLE	{ $$ = $1; }
5313

5314
indicator: CVARIABLE		 	{ check_indicator((find_variable($1))->type); $$ = $1; }
5315
	| SQL_INDICATOR cvariable 	{ check_indicator((find_variable($2))->type); $$ = $2; }
Marc G. Fournier's avatar
Marc G. Fournier committed
5316
	| SQL_INDICATOR name		{ check_indicator((find_variable($2))->type); $$ = $2; }
Michael Meskes's avatar
Michael Meskes committed
5317
	;
Marc G. Fournier's avatar
Marc G. Fournier committed
5318

Michael Meskes's avatar
Michael Meskes committed
5319
ident: IDENT		{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5320 5321
	| CSTRING	{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
	;
Michael Meskes's avatar
Michael Meskes committed
5322

5323 5324 5325 5326 5327 5328 5329
quoted_ident_stringvar: IDENT	{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
	| CSTRING	{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
	| char_variable	
		{	$$ = make3_str(make_str("("), $1, make_str(")"));
		}
	;

Marc G. Fournier's avatar
Marc G. Fournier committed
5330 5331 5332
/*
 * C stuff
 */
5333

Michael Meskes's avatar
Michael Meskes committed
5334
cpp_line: CPP_LINE	{ $$ = $1; };
5335

Michael Meskes's avatar
Michael Meskes committed
5336 5337 5338 5339 5340 5341 5342
c_stuff: c_anything 	{ $$ = $1; }
	| c_stuff c_anything
			{
				$$ = cat2_str($1, $2);
			}
	| c_stuff '(' c_stuff ')'
			{
Michael Meskes's avatar
Michael Meskes committed
5343
				$$ = cat_str(4, $1, make_str("("), $3, make_str(")"));
Michael Meskes's avatar
Michael Meskes committed
5344
			}
5345 5346 5347 5348
	| c_stuff '(' ')'
			{
				$$ = cat_str(3, $1, make_str("("), make_str(")"));
			}
Michael Meskes's avatar
Michael Meskes committed
5349
	;
Michael Meskes's avatar
Michael Meskes committed
5350 5351

c_list: c_term			{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5352
	| c_list ',' c_term	{ $$ = cat_str(3, $1, make_str(","), $3); }
Michael Meskes's avatar
Michael Meskes committed
5353
	;
Michael Meskes's avatar
Michael Meskes committed
5354 5355

c_term:  c_stuff 		{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5356
	| '{' c_list '}'	{ $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
Michael Meskes's avatar
Michael Meskes committed
5357
	;
5358

Michael Meskes's avatar
Michael Meskes committed
5359
c_thing:	c_anything	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5360 5361 5362 5363
	|	'('		{ $$ = make_str("("); }
	|	')'		{ $$ = make_str(")"); }
	|	','		{ $$ = make_str(","); }
	|	';'		{ $$ = make_str(";"); }
Michael Meskes's avatar
Michael Meskes committed
5364
	;
5365

5366
c_anything:  IDENT 	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5367
	| CSTRING	{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5368
	| PosIntConst	{ $$ = $1; }
5369
	| Fconst	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5370
	| Sconst	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5371 5372 5373 5374 5375
	| '*'		{ $$ = make_str("*"); }
	| '+'		{ $$ = make_str("+"); }
	| '-'		{ $$ = make_str("-"); }
	| '/'		{ $$ = make_str("/"); }
	| '%'		{ $$ = make_str("%"); }
5376 5377
	| NULL_P	{ $$ = make_str("NULL"); }
	| S_ADD		{ $$ = make_str("+="); } 
5378
	| S_AND		{ $$ = make_str("&&"); } 
Michael Meskes's avatar
Michael Meskes committed
5379
	| S_ANYTHING	{ $$ = make_name(); }
Michael Meskes's avatar
Michael Meskes committed
5380 5381
	| S_AUTO	{ $$ = make_str("auto"); }
	| S_CONST	{ $$ = make_str("const"); }
5382 5383 5384 5385
	| S_DEC		{ $$ = make_str("--"); } 
	| S_DIV		{ $$ = make_str("/="); } 
	| S_DOTPOINT	{ $$ = make_str(".*"); } 
	| S_EQUAL	{ $$ = make_str("=="); } 
Michael Meskes's avatar
Michael Meskes committed
5386
	| S_EXTERN	{ $$ = make_str("extern"); }
5387
	| S_INC		{ $$ = make_str("++"); } 
5388 5389
	| S_LSHIFT	{ $$ = make_str("<<"); } 
	| S_MEMBER	{ $$ = make_str("->"); } 
5390
	| S_MEMPOINT	{ $$ = make_str("->*"); } 
5391
	| S_MOD		{ $$ = make_str("%="); }
5392 5393
	| S_MUL		{ $$ = make_str("*="); } 
	| S_NEQUAL	{ $$ = make_str("!="); } 
5394
	| S_OR		{ $$ = make_str("||"); } 
Michael Meskes's avatar
Michael Meskes committed
5395
	| S_REGISTER	{ $$ = make_str("register"); }
5396
	| S_RSHIFT	{ $$ = make_str(">>"); } 
Michael Meskes's avatar
Michael Meskes committed
5397
	| S_STATIC	{ $$ = make_str("static"); }
5398
	| S_SUB		{ $$ = make_str("-="); } 
Michael Meskes's avatar
Michael Meskes committed
5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411
	| SQL_BOOL	{ $$ = make_str("bool"); }
	| SQL_ENUM	{ $$ = make_str("enum"); }
        | SQL_INT	{ $$ = make_str("int"); }
	| SQL_LONG	{ $$ = make_str("long"); }
	| SQL_SHORT	{ $$ = make_str("short"); }
	| SQL_SIGNED	{ $$ = make_str("signed"); }
        | SQL_STRUCT	{ $$ = make_str("struct"); }
	| SQL_UNSIGNED	{ $$ = make_str("unsigned"); }
	| CHAR		{ $$ = make_str("char"); }
	| DOUBLE	{ $$ = make_str("double"); }
	| FLOAT		{ $$ = make_str("float"); }
        | UNION		{ $$ = make_str("union"); }
	| VARCHAR	{ $$ = make_str("varchar"); }
Michael Meskes's avatar
Michael Meskes committed
5412 5413 5414
        | '['		{ $$ = make_str("["); }
	| ']'		{ $$ = make_str("]"); }
	| '='		{ $$ = make_str("="); }
Michael Meskes's avatar
Michael Meskes committed
5415
	;
5416

Michael Meskes's avatar
Michael Meskes committed
5417 5418 5419 5420 5421
blockstart : '{'
	{
	    braces_open++;
	    $$ = make_str("{");
	};
5422

Michael Meskes's avatar
Michael Meskes committed
5423 5424 5425 5426 5427
blockend : '}'
	{
	    remove_variables(braces_open--);
	    $$ = make_str("}");
	};
Marc G. Fournier's avatar
Marc G. Fournier committed
5428

5429
%%
5430

5431 5432 5433 5434 5435
void yyerror( char * error)
{	char buf[1024];
        snprintf(buf,sizeof buf,"%s at or near \"%s\"",error,yytext);
        buf[sizeof(buf)-1]=0;
	mmerror(ET_ERROR, buf);
5436
}