preproc.y 162 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 91 92 93 94
make_str(const char *str)
{
        char * res_str = (char *)mm_alloc(strlen(str) + 1);

	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
Michael Meskes's avatar
Michael Meskes committed
282
%type  <str>    ConstraintElem key_actions ColQualList TokenId 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 generic 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 datetime 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 327
%type  <str>    ViewStmt LoadStmt CreatedbStmt createdb_opt_item
%type  <str>	createdb_opt_list opt_encoding OptInherit Geometric
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
Michael Meskes's avatar
Michael Meskes committed
360
%type  <str>	ECPGGetDescriptorHeader ECPGColLabel ECPGTypeName
361
%type  <str>	ECPGLabelTypeName ECPGColId variablelist cvariable
Michael Meskes's avatar
Michael Meskes committed
362

363
%type  <descriptor> ECPGGetDescriptor
364

Michael Meskes's avatar
Michael Meskes committed
365
%type  <type_enum> simple_type signed_type unsigned_type varchar_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 916 917 918 919 920 921
                               }
               | constraints_set_namelist
                               {
                                       $$ = $1;
                               }
               ;


constraints_set_namelist:      IDENT
                               {
                                       $$ = $1;
                               }
               | constraints_set_namelist ',' IDENT
                               {
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 1120
 						sprintf(errortext, "Currently unsupported CREATE TABLE/COLLATE %s will be passed to backend", $4);
 						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)
Michael Meskes's avatar
Michael Meskes committed
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;
				}
		;

Michael Meskes's avatar
Michael Meskes committed
1532 1533
def_arg:  func_return		{  $$ = $1; }
		| TokenId	{  $$ = $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 1967 1968 1969 1970 1971 1972
func_type:	Typename
				{
					$$ = $1;
				}
		| IDENT '.' ColId '%' TYPE_P   
				{
					$$ = 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
		;

2682
select_limit:      LIMIT select_offset_value ',' select_limit_value
Michael Meskes's avatar
Michael Meskes committed
2683
                       { $$ = cat_str(4, make_str("limit"), $2, make_str(","), $4); }
2684
               | LIMIT select_limit_value OFFSET select_offset_value
Michael Meskes's avatar
Michael Meskes committed
2685
                       { $$ = cat_str(4, make_str("limit"), $2, make_str("offset"), $4); }
2686
               | LIMIT select_limit_value
Michael Meskes's avatar
Michael Meskes committed
2687
                       { $$ = cat2_str(make_str("limit"), $2); }
2688
               | OFFSET select_offset_value LIMIT select_limit_value
Michael Meskes's avatar
Michael Meskes committed
2689
                       { $$ = cat_str(4, make_str("offset"), $2, make_str("limit"), $4); }
2690
               | OFFSET select_offset_value
Michael Meskes's avatar
Michael Meskes committed
2691
                       { $$ = cat2_str(make_str("offset"), $2); }
2692 2693
               ;

2694 2695 2696 2697 2698 2699 2700 2701 2702
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
2703
	          	| ALL	{ $$ = make_str("all"); }
2704 2705 2706
			| PARAM { $$ = make_name(); }
               ;

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

Marc G. Fournier's avatar
Marc G. Fournier committed
2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726
/*
 *	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
2727
				{	$$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
2728 2729
		;

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

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

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

opt_for_update_clause: for_update_clause                { $$ = $1; }
		| /* EMPTY */				{ $$ = EMPTY; }
2753
                ;
2754

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

/*****************************************************************************
 *
 *	clauses common to all Optimizable Stmts:
Michael Meskes's avatar
Michael Meskes committed
2768 2769
 *		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
2770 2771 2772
 *
 *****************************************************************************/

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

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

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

2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829
/*
 * 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.
 */       
2830

2831 2832 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
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);
                }  
2859 2860
                ;

Michael Meskes's avatar
Michael Meskes committed
2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875
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
2876

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

2882 2883 2884 2885 2886 2887
/* 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
2888

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

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

2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933
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
2934
opt_array_bounds:  '[' ']' opt_array_bounds
2935 2936 2937
			{
                            $$.index1 = 0;
                            $$.index2 = $3.index1;
Michael Meskes's avatar
Michael Meskes committed
2938
                            $$.str = cat2_str(make_str("[]"), $3.str);
2939
                        }
Michael Meskes's avatar
Michael Meskes committed
2940
		| '[' Iresult ']' opt_array_bounds
2941
			{
Michael Meskes's avatar
Michael Meskes committed
2942 2943 2944 2945
			    char *txt = mm_alloc(20L);

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

2957
Iresult:	PosIntConst		{ $$ = atol($1); }
Michael Meskes's avatar
Michael Meskes committed
2958
	|	'(' Iresult ')'		{ $$ = $2; }
Michael Meskes's avatar
Michael Meskes committed
2959 2960 2961 2962 2963 2964
	|	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
2965

2966 2967 2968
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
2969 2970
               ;  

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

2979 2980 2981 2982 2983 2984 2985 2986
Generic:  generic
				{
					$$ = $1;
				}
		;

generic:  ident					{ $$ = $1; }
		| TYPE_P			{ $$ = make_str("type"); }
Michael Meskes's avatar
Michael Meskes committed
2987 2988
		| ECPGKeywords			{ $$ = $1; }
		| ECPGTypeName			{ $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
2989 2990 2991 2992
		;

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

Michael Meskes's avatar
Michael Meskes committed
3018
Geometric:  PATH_P 	{ $$ = make_str("path"); };
Michael Meskes's avatar
Michael Meskes committed
3019

3020
opt_float:  '(' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3021
				{
Michael Meskes's avatar
Michael Meskes committed
3022
					$$ = cat_str(3, make_str("("), $2, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3023 3024 3025
				}
		| /*EMPTY*/
				{
Michael Meskes's avatar
Michael Meskes committed
3026
					$$ = EMPTY;
Marc G. Fournier's avatar
Marc G. Fournier committed
3027 3028 3029
				}
		;

3030
opt_numeric:  '(' PosIntConst ',' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3031
				{
Michael Meskes's avatar
Michael Meskes committed
3032
					$$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3033
				}
3034
		| '(' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3035
				{
Michael Meskes's avatar
Michael Meskes committed
3036
					$$ = cat_str(3, make_str("("), $2, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3037 3038 3039
				}
		| /*EMPTY*/
				{
Michael Meskes's avatar
Michael Meskes committed
3040
					$$ = EMPTY;
Marc G. Fournier's avatar
Marc G. Fournier committed
3041 3042 3043
				}
		;

3044
opt_decimal:  '(' PosIntConst ',' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3045
				{
Michael Meskes's avatar
Michael Meskes committed
3046
					$$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3047
				}
3048
		| '(' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3049
				{
Michael Meskes's avatar
Michael Meskes committed
3050
					$$ = cat_str(3, make_str("("), $2, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3051 3052 3053
				}
		| /*EMPTY*/
				{
Michael Meskes's avatar
Michael Meskes committed
3054
					$$ = EMPTY;
Marc G. Fournier's avatar
Marc G. Fournier committed
3055 3056 3057
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3058 3059 3060 3061
/*
 * SQL92 bit-field data types
 * The following implements BIT() and BIT VARYING().
 */
3062
Bit:  bit '(' PosIntConst ')'
3063 3064 3065
				{
					$$ = cat_str(4, $1, make_str("("), $3, make_str(")"));
				}
Michael Meskes's avatar
Michael Meskes committed
3066
                | bit
3067 3068
				{
					$$ = $1;
Michael Meskes's avatar
Michael Meskes committed
3069 3070 3071 3072 3073 3074 3075 3076
				}
		;

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

Michael Meskes's avatar
Michael Meskes committed
3077 3078
/* 
 * SQL92 character data types
Marc G. Fournier's avatar
Marc G. Fournier committed
3079 3080 3081
 * The following implements CHAR() and VARCHAR().
 *								- ay 6/95
 */
Michael Meskes's avatar
Michael Meskes committed
3082
Character:  character '(' PosIntConst ')' opt_charset
Marc G. Fournier's avatar
Marc G. Fournier committed
3083
				{
Michael Meskes's avatar
Michael Meskes committed
3084
					$$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
3085
				}
Michael Meskes's avatar
Michael Meskes committed
3086
		| character opt_charset
Marc G. Fournier's avatar
Marc G. Fournier committed
3087
				{
Michael Meskes's avatar
Michael Meskes committed
3088
					$$ = cat2_str($1, $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3089 3090 3091
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3092
character:  CHARACTER opt_varying 
Marc G. Fournier's avatar
Marc G. Fournier committed
3093
				{
Michael Meskes's avatar
Michael Meskes committed
3094
					$$ = cat2_str(make_str("character"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3095
				}
Michael Meskes's avatar
Michael Meskes committed
3096 3097 3098 3099 3100
		| 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
3101 3102
		;

Michael Meskes's avatar
Michael Meskes committed
3103
opt_varying:  VARYING			{ $$ = make_str("varying"); }
Michael Meskes's avatar
Michael Meskes committed
3104
		| /*EMPTY*/			{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3105 3106
		;

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

Michael Meskes's avatar
Michael Meskes committed
3111
opt_collate:  COLLATE ColId		{ $$ = cat2_str(make_str("collate"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3112
		| /*EMPTY*/					{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3113 3114
		;

Michael Meskes's avatar
Michael Meskes committed
3115
ConstDatetime:  datetime
Marc G. Fournier's avatar
Marc G. Fournier committed
3116 3117 3118
				{
					$$ = $1;
				}
Michael Meskes's avatar
Michael Meskes committed
3119 3120 3121 3122
		| TIMESTAMP '(' PosIntConst ')' opt_timezone
				{
					$$ = cat_str(4, make_str("timestamp("), $3, make_str(")"), $5);
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
3123 3124
		| TIMESTAMP opt_timezone
				{
Michael Meskes's avatar
Michael Meskes committed
3125
					$$ = cat2_str(make_str("timestamp"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3126
				}
Michael Meskes's avatar
Michael Meskes committed
3127 3128 3129 3130
		| TIME '(' PosIntConst ')' opt_timezone
				{
					$$ = cat_str(4, make_str("time("), $3, make_str(")"), $5);
				}
Michael Meskes's avatar
Michael Meskes committed
3131
		| TIME opt_timezone
Marc G. Fournier's avatar
Marc G. Fournier committed
3132
				{
Michael Meskes's avatar
Michael Meskes committed
3133
					$$ = cat2_str(make_str("time"), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3134
				}
Michael Meskes's avatar
Michael Meskes committed
3135 3136
		;

3137
ConstInterval:	INTERVAL
Marc G. Fournier's avatar
Marc G. Fournier committed
3138
				{
3139
					$$ = make_str("interval");
Marc G. Fournier's avatar
Marc G. Fournier committed
3140 3141 3142
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3143 3144 3145 3146 3147 3148
datetime:  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"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3149 3150
		;

Michael Meskes's avatar
Michael Meskes committed
3151
opt_timezone:  WITH TIME ZONE				{ $$ = make_str("with time zone"); }
Michael Meskes's avatar
Michael Meskes committed
3152
		| WITHOUT TIME ZONE				{ $$ = make_str("without time zone"); }
Michael Meskes's avatar
Michael Meskes committed
3153
		| /*EMPTY*/					{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3154 3155
		;

3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169
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
3170 3171 3172 3173 3174
		;


/*****************************************************************************
 *
Michael Meskes's avatar
Michael Meskes committed
3175
 *	expression grammar
Marc G. Fournier's avatar
Marc G. Fournier committed
3176 3177 3178 3179 3180 3181 3182
 *
 *****************************************************************************/

/* Expressions using row descriptors
 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
 *  with singleton expressions.
 */
3183
row_expr: '(' row_descriptor ')' IN select_with_parens
Marc G. Fournier's avatar
Marc G. Fournier committed
3184
				{
3185
					$$ = cat_str(4, make_str("("), $2, make_str(") in "), $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
3186
				}
3187
		| '(' row_descriptor ')' NOT IN select_with_parens
Marc G. Fournier's avatar
Marc G. Fournier committed
3188
				{
3189
					$$ = cat_str(4, make_str("("), $2, make_str(") not in "), $6);
Marc G. Fournier's avatar
Marc G. Fournier committed
3190
				}
3191
		| '(' row_descriptor ')' all_Op sub_type select_with_parens
Marc G. Fournier's avatar
Marc G. Fournier committed
3192
				{
3193
					$$ = cat_str(6, make_str("("), $2, make_str(")"), $4, $5, $6);
Marc G. Fournier's avatar
Marc G. Fournier committed
3194
				}
3195
		| '(' row_descriptor ')' all_Op select_with_parens
Marc G. Fournier's avatar
Marc G. Fournier committed
3196
				{
3197
					$$ = cat_str(5, make_str("("), $2, make_str(")"), $4, $5);
Marc G. Fournier's avatar
Marc G. Fournier committed
3198
				}
Michael Meskes's avatar
Michael Meskes committed
3199
		| '(' row_descriptor ')' all_Op '(' row_descriptor ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3200
				{
Michael Meskes's avatar
Michael Meskes committed
3201
					$$ = cat_str(7, make_str("("), $2, make_str(")"), $4, make_str("("), $6, make_str(")"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3202
				}
Michael Meskes's avatar
Michael Meskes committed
3203 3204 3205 3206
		| '(' 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
3207 3208 3209 3210
		;

row_descriptor:  row_list ',' a_expr
				{
Michael Meskes's avatar
Michael Meskes committed
3211
					$$ = cat_str(3, $1, make_str(","), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3212 3213 3214
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3215
sub_type:  ANY                  { $$ = make_str("ANY"); }
Michael Meskes's avatar
Michael Meskes committed
3216
         | SOME                 { $$ = make_str("SOME"); }
Michael Meskes's avatar
Michael Meskes committed
3217
         | ALL                  { $$ = make_str("ALL"); }
3218 3219 3220
              ;


Marc G. Fournier's avatar
Marc G. Fournier committed
3221 3222
row_list:  row_list ',' a_expr
				{
Michael Meskes's avatar
Michael Meskes committed
3223
					$$ = cat_str(3, $1, make_str(","), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3224 3225 3226 3227 3228 3229 3230
				}
		| a_expr
				{
					$$ = $1;
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3231 3232
all_Op:  Op | MathOp;

Michael Meskes's avatar
Michael Meskes committed
3233 3234 3235 3236 3237 3238 3239 3240 3241
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
3242 3243
		;

3244
/* General expressions
Marc G. Fournier's avatar
Marc G. Fournier committed
3245
 * This is the heart of the expression syntax.
Michael Meskes's avatar
Michael Meskes committed
3246 3247 3248 3249 3250 3251 3252 3253 3254 3255
 *
 * 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
3256
 * c_expr is all the productions that are common to a_expr and b_expr;
Michael Meskes's avatar
Michael Meskes committed
3257
 * it's factored out just to eliminate redundant coding.
Marc G. Fournier's avatar
Marc G. Fournier committed
3258 3259
 */

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

3386
/* Restricted expressions
Michael Meskes's avatar
Michael Meskes committed
3387
 *
Marc G. Fournier's avatar
Marc G. Fournier committed
3388
 * b_expr is a subset of the complete expression syntax
Michael Meskes's avatar
Michael Meskes committed
3389
 *
Michael Meskes's avatar
Michael Meskes committed
3390
 * Presently, AND, NOT, IS and IN are the a_expr keywords that would
Michael Meskes's avatar
Michael Meskes committed
3391 3392
 * 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
3393
 */
Michael Meskes's avatar
Michael Meskes committed
3394
b_expr:  c_expr
Marc G. Fournier's avatar
Marc G. Fournier committed
3395
				{
Michael Meskes's avatar
Michael Meskes committed
3396
					$$ = $1;
Marc G. Fournier's avatar
Marc G. Fournier committed
3397
				}
Michael Meskes's avatar
Michael Meskes committed
3398
		| b_expr TYPECAST Typename
Marc G. Fournier's avatar
Marc G. Fournier committed
3399
				{
Michael Meskes's avatar
Michael Meskes committed
3400
					$$ = cat_str(3, $1, make_str("::"), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3401 3402
				}
		| '-' b_expr %prec UMINUS
Michael Meskes's avatar
Michael Meskes committed
3403
				{	$$ = cat2_str(make_str("-"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3404
		| '%' b_expr
Michael Meskes's avatar
Michael Meskes committed
3405
				{       $$ = cat2_str(make_str("%"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3406
		| '^' b_expr
Michael Meskes's avatar
Michael Meskes committed
3407
				{       $$ = cat2_str(make_str("^"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3408
		| b_expr '%'
Michael Meskes's avatar
Michael Meskes committed
3409
				{       $$ = cat2_str($1, make_str("%")); }
Michael Meskes's avatar
Michael Meskes committed
3410
		| b_expr '^'
Michael Meskes's avatar
Michael Meskes committed
3411
				{       $$ = cat2_str($1, make_str("^")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3412
		| b_expr '+' b_expr
Michael Meskes's avatar
Michael Meskes committed
3413
				{	$$ = cat_str(3, $1, make_str("+"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3414
		| b_expr '-' b_expr
Michael Meskes's avatar
Michael Meskes committed
3415
				{	$$ = cat_str(3, $1, make_str("-"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3416
		| b_expr '*' b_expr
Michael Meskes's avatar
Michael Meskes committed
3417
				{	$$ = cat_str(3, $1, make_str("*"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3418
		| b_expr '/' b_expr
Michael Meskes's avatar
Michael Meskes committed
3419
				{	$$ = cat_str(3, $1, make_str("/"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3420
		| b_expr '%' b_expr
Michael Meskes's avatar
Michael Meskes committed
3421
				{	$$ = cat_str(3, $1, make_str("%"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3422
		| b_expr '^' b_expr
Michael Meskes's avatar
Michael Meskes committed
3423
				{	$$ = cat_str(3, $1, make_str("^"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3424
		| b_expr '<' b_expr
Michael Meskes's avatar
Michael Meskes committed
3425
				{	$$ = cat_str(3, $1, make_str("<"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3426
		| b_expr '>' b_expr
Michael Meskes's avatar
Michael Meskes committed
3427
				{	$$ = cat_str(3, $1, make_str(">"), $3); }
Michael Meskes's avatar
Michael Meskes committed
3428
		| b_expr '=' b_expr
Michael Meskes's avatar
Michael Meskes committed
3429
				{	$$ = cat_str(3, $1, make_str("="), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3430
		| b_expr Op b_expr
Michael Meskes's avatar
Michael Meskes committed
3431
				{	$$ = cat_str(3, $1, $2, $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3432
		| Op b_expr
3433
				{	$$ = cat2_str($1, $2); }
3434
		| b_expr Op		%prec POSTFIXOP
3435
				{	$$ = cat2_str($1, $2); }
Michael Meskes's avatar
Michael Meskes committed
3436 3437 3438 3439 3440 3441 3442 3443 3444 3445
		;

/*
 * 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
3446
c_expr:  attr
Michael Meskes's avatar
Michael Meskes committed
3447 3448 3449 3450 3451
				{	$$ = $1;  }
		| ColId opt_indirection
				{	$$ = cat2_str($1, $2);	}
		| AexprConst
				{	$$ = $1;  }
Michael Meskes's avatar
Michael Meskes committed
3452
		| '(' a_expr ')'
Michael Meskes's avatar
Michael Meskes committed
3453
				{	$$ = cat_str(3, make_str("("), $2, make_str(")")); }
Michael Meskes's avatar
Michael Meskes committed
3454
		| CAST '(' a_expr AS Typename ')'
Michael Meskes's avatar
Michael Meskes committed
3455
				{ 	$$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); }
Michael Meskes's avatar
Michael Meskes committed
3456 3457
		| case_expr
				{       $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3458
		| func_name '(' ')'
Michael Meskes's avatar
Michael Meskes committed
3459
				{	$$ = cat2_str($1, make_str("()"));  }
Marc G. Fournier's avatar
Marc G. Fournier committed
3460
		| func_name '(' expr_list ')'
Michael Meskes's avatar
Michael Meskes committed
3461
				{	$$ = cat_str(4, $1, make_str("("), $3, make_str(")"));  }
Michael Meskes's avatar
Michael Meskes committed
3462 3463
		| func_name '(' ALL expr_list ')'
				{	$$ = cat_str(4, $1, make_str("( all"), $4, make_str(")"));  }
Michael Meskes's avatar
Michael Meskes committed
3464 3465
		| func_name '(' DISTINCT expr_list ')'
				{	$$ = cat_str(4, $1, make_str("( distinct"), $4, make_str(")"));  }
Michael Meskes's avatar
Michael Meskes committed
3466
		| func_name '(' '*' ')'
Michael Meskes's avatar
Michael Meskes committed
3467
				{	$$ = cat2_str($1, make_str("(*)")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3468
		| CURRENT_DATE
Michael Meskes's avatar
Michael Meskes committed
3469
				{	$$ = make_str("current_date"); }
Michael Meskes's avatar
Michael Meskes committed
3470 3471
		| CURRENT_TIME opt_empty_parentheses
				{	$$ = cat2_str(make_str("current_time"), $2); }
3472
		| CURRENT_TIME '(' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3473
				{
Michael Meskes's avatar
Michael Meskes committed
3474
					$$ = make_str("current_time");
Marc G. Fournier's avatar
Marc G. Fournier committed
3475
				}
Michael Meskes's avatar
Michael Meskes committed
3476 3477
		| CURRENT_TIMESTAMP opt_empty_parentheses
				{	$$ = cat2_str(make_str("current_timestamp"), $2); }
3478
		| CURRENT_TIMESTAMP '(' PosIntConst ')'
Marc G. Fournier's avatar
Marc G. Fournier committed
3479
				{
Michael Meskes's avatar
Michael Meskes committed
3480
					$$ = make_str("current_timestamp");
Marc G. Fournier's avatar
Marc G. Fournier committed
3481
				}
Michael Meskes's avatar
Michael Meskes committed
3482 3483 3484 3485 3486 3487
		| 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
3488
		| EXTRACT '(' extract_list ')'
Michael Meskes's avatar
Michael Meskes committed
3489
				{	$$ = cat_str(3, make_str("extract("), $3, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3490
		| POSITION '(' position_list ')'
Michael Meskes's avatar
Michael Meskes committed
3491
				{	$$ = cat_str(3, make_str("position("), $3, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3492
		| SUBSTRING '(' substr_list ')'
Michael Meskes's avatar
Michael Meskes committed
3493
				{	$$ = cat_str(3, make_str("substring("), $3, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3494 3495
		/* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
		| TRIM '(' BOTH trim_list ')'
Michael Meskes's avatar
Michael Meskes committed
3496
				{	$$ = cat_str(3, make_str("trim(both"), $4, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3497
		| TRIM '(' LEADING trim_list ')'
Michael Meskes's avatar
Michael Meskes committed
3498
				{	$$ = cat_str(3, make_str("trim(leading"), $4, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3499
		| TRIM '(' TRAILING trim_list ')'
Michael Meskes's avatar
Michael Meskes committed
3500
				{	$$ = cat_str(3, make_str("trim(trailing"), $4, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3501
		| TRIM '(' trim_list ')'
Michael Meskes's avatar
Michael Meskes committed
3502
				{	$$ = cat_str(3, make_str("trim("), $3, make_str(")")); }
3503 3504 3505 3506
		| 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
3507
		;
Michael Meskes's avatar
Michael Meskes committed
3508 3509 3510 3511 3512
/* 
 * 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
3513
				{
Michael Meskes's avatar
Michael Meskes committed
3514
					$$ = cat_str(4, make_str("["), $2, make_str("]"), $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
3515
				}
Michael Meskes's avatar
Michael Meskes committed
3516
		| '[' a_expr ':' a_expr ']' opt_indirection
Marc G. Fournier's avatar
Marc G. Fournier committed
3517
				{
Michael Meskes's avatar
Michael Meskes committed
3518
					$$ = cat_str(6, make_str("["), $2, make_str(":"), $4, make_str("]"), $6);
Marc G. Fournier's avatar
Marc G. Fournier committed
3519 3520
				}
		| /* EMPTY */
Michael Meskes's avatar
Michael Meskes committed
3521
				{	$$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3522 3523
		;

Michael Meskes's avatar
Michael Meskes committed
3524
expr_list:  a_expr
Marc G. Fournier's avatar
Marc G. Fournier committed
3525
				{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
3526
		| expr_list ',' a_expr
Michael Meskes's avatar
Michael Meskes committed
3527
				{ $$ = cat_str(3, $1, make_str(","), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3528
		| expr_list USING a_expr
Michael Meskes's avatar
Michael Meskes committed
3529
				{ $$ = cat_str(3, $1, make_str("using"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3530 3531 3532 3533
		;

extract_list:  extract_arg FROM a_expr
				{
Michael Meskes's avatar
Michael Meskes committed
3534
					$$ = cat_str(3, $1, make_str("from"), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3535 3536
				}
		| /* EMPTY */
Michael Meskes's avatar
Michael Meskes committed
3537
				{	$$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3538 3539
		;

Tom Lane's avatar
Tom Lane committed
3540 3541 3542 3543
/* Allow delimited string SCONST in extract_arg as an SQL extension.
 * - thomas 2001-04-12
 */

3544
extract_arg:  datetime		{ $$ = $1; }
3545
	| StringConst				{ $$ = $1; }
Tom Lane's avatar
Tom Lane committed
3546
	| IDENT					{ $$ = $1; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3547 3548
		;

Michael Meskes's avatar
Michael Meskes committed
3549 3550
/* 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
3551
				{	$$ = cat_str(3, $1, make_str("in"), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3552
		| /* EMPTY */
Michael Meskes's avatar
Michael Meskes committed
3553
				{	$$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3554 3555
		;

3556
substr_list:  a_expr substr_from substr_for
Marc G. Fournier's avatar
Marc G. Fournier committed
3557
				{
Michael Meskes's avatar
Michael Meskes committed
3558
					$$ = cat_str(3, $1, $2, $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3559
				}
3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575
		| 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
3576
		| /* EMPTY */
Michael Meskes's avatar
Michael Meskes committed
3577
				{	$$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3578 3579
		;

3580
substr_from:  FROM a_expr
Michael Meskes's avatar
Michael Meskes committed
3581
				{	$$ = cat2_str(make_str("from"), $2); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3582 3583
		;

3584
substr_for:  FOR a_expr
Michael Meskes's avatar
Michael Meskes committed
3585
				{	$$ = cat2_str(make_str("for"), $2); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3586 3587 3588
		;

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

3596
in_expr:  select_with_parens
Marc G. Fournier's avatar
Marc G. Fournier committed
3597 3598 3599
				{
					$$ = $1;
				}
3600 3601
		| '(' in_expr_nodes ')'
				{	$$ = cat_str(3, make_str("("), $2, make_str(")")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3602 3603
		;

Michael Meskes's avatar
Michael Meskes committed
3604
in_expr_nodes:  a_expr
Marc G. Fournier's avatar
Marc G. Fournier committed
3605
				{	$$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
3606
		| in_expr_nodes ',' a_expr
Michael Meskes's avatar
Michael Meskes committed
3607
				{	$$ = cat_str(3, $1, make_str(","), $3);}
Marc G. Fournier's avatar
Marc G. Fournier committed
3608 3609
		;

3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625
/* 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
3626
                                { $$ = cat_str(5, make_str("case"), $2, $3, $4, make_str("end")); }
3627 3628
                | NULLIF '(' a_expr ',' a_expr ')'
                                {
Michael Meskes's avatar
Michael Meskes committed
3629
					$$ = cat_str(5, make_str("nullif("), $3, make_str(","), $5, make_str(")"));
3630 3631 3632
                                }
                | COALESCE '(' expr_list ')'
                                {
Michael Meskes's avatar
Michael Meskes committed
3633
					$$ = cat_str(3, make_str("coalesce("), $3, make_str(")"));
3634 3635 3636 3637 3638 3639 3640 3641 3642
				}
		;

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

Michael Meskes's avatar
Michael Meskes committed
3643
when_clause:  WHEN a_expr THEN a_expr
3644
                               {
Michael Meskes's avatar
Michael Meskes committed
3645
					$$ = cat_str(4, make_str("when"), $2, make_str("then"), $4);
3646 3647 3648
                               }
               ;

Michael Meskes's avatar
Michael Meskes committed
3649
case_default:  ELSE a_expr		{ $$ = cat2_str(make_str("else"), $2); }
Michael Meskes's avatar
Michael Meskes committed
3650
               | /*EMPTY*/        	{ $$ = EMPTY; }
3651 3652
               ;

Michael Meskes's avatar
Michael Meskes committed
3653
case_arg:  a_expr              {
3654 3655 3656
                                       $$ = $1;
                               }
               | /*EMPTY*/
Michael Meskes's avatar
Michael Meskes committed
3657
                               {       $$ = EMPTY; }
3658 3659
               ;

Michael Meskes's avatar
Michael Meskes committed
3660
attr:  relation_name '.' attrs opt_indirection
Marc G. Fournier's avatar
Marc G. Fournier committed
3661
				{
Michael Meskes's avatar
Michael Meskes committed
3662
					$$ = cat_str(4, $1, make_str("."), $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
3663
				}
Michael Meskes's avatar
Michael Meskes committed
3664
		| ParamNo '.' attrs opt_indirection
Marc G. Fournier's avatar
Marc G. Fournier committed
3665
				{
Michael Meskes's avatar
Michael Meskes committed
3666
					$$ = cat_str(4, $1, make_str("."), $3, $4);
Marc G. Fournier's avatar
Marc G. Fournier committed
3667 3668 3669 3670 3671 3672
				}
		;

attrs:	  attr_name
				{ $$ = $1; }
		| attrs '.' attr_name
Michael Meskes's avatar
Michael Meskes committed
3673
				{ $$ = cat_str(3, $1, make_str("."), $3); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3674
		| attrs '.' '*'
Michael Meskes's avatar
Michael Meskes committed
3675
				{ $$ = make2_str($1, make_str(".*")); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3676 3677
		;

Michael Meskes's avatar
Michael Meskes committed
3678 3679
opt_empty_parentheses: '(' ')' 	{ $$ = make_str("()"); }
                | /*EMPTY*/ 	{ $$ = EMPTY; }
Marc G. Fournier's avatar
Marc G. Fournier committed
3680 3681 3682 3683 3684 3685 3686

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

Michael Meskes's avatar
Michael Meskes committed
3687 3688
/* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
target_list:  target_list ',' target_el
Michael Meskes's avatar
Michael Meskes committed
3689
				{	$$ = cat_str(3, $1, make_str(","), $3);  }
Michael Meskes's avatar
Michael Meskes committed
3690
		| target_el
Marc G. Fournier's avatar
Marc G. Fournier committed
3691 3692 3693 3694
				{	$$ = $1;  }
		;

/* AS is not optional because shift/red conflict with unary ops */
Michael Meskes's avatar
Michael Meskes committed
3695
target_el:  a_expr AS ColLabel
Marc G. Fournier's avatar
Marc G. Fournier committed
3696
				{
Michael Meskes's avatar
Michael Meskes committed
3697
					$$ = cat_str(3, $1, make_str("as"), $3);
Marc G. Fournier's avatar
Marc G. Fournier committed
3698
				}
Michael Meskes's avatar
Michael Meskes committed
3699
		| a_expr
Marc G. Fournier's avatar
Marc G. Fournier committed
3700 3701 3702 3703 3704
				{
					$$ = $1;
				}
		| relation_name '.' '*'
				{
Michael Meskes's avatar
Michael Meskes committed
3705
					$$ = make2_str($1, make_str(".*"));
Marc G. Fournier's avatar
Marc G. Fournier committed
3706 3707 3708
				}
		| '*'
				{
Michael Meskes's avatar
Michael Meskes committed
3709
					$$ = make_str("*");
Marc G. Fournier's avatar
Marc G. Fournier committed
3710 3711 3712
				}
		;

Michael Meskes's avatar
Michael Meskes committed
3713 3714
/* Target list as found in UPDATE table SET ... */
update_target_list:  update_target_list ',' update_target_el
Michael Meskes's avatar
Michael Meskes committed
3715
				{	$$ = cat_str(3, $1, make_str(","),$3);  }
Michael Meskes's avatar
Michael Meskes committed
3716 3717
		| update_target_el
				{	$$ = $1;  }
Michael Meskes's avatar
Michael Meskes committed
3718
		| '*'		{ $$ = make_str("*"); }
Michael Meskes's avatar
Michael Meskes committed
3719 3720
		;

Michael Meskes's avatar
Michael Meskes committed
3721
update_target_el:  ColId opt_indirection '=' a_expr
Michael Meskes's avatar
Michael Meskes committed
3722
				{
Michael Meskes's avatar
Michael Meskes committed
3723
					$$ = cat_str(4, $1, $2, make_str("="), $4);
Michael Meskes's avatar
Michael Meskes committed
3724
				}
Marc G. Fournier's avatar
Marc G. Fournier committed
3725 3726
		;

Michael Meskes's avatar
Michael Meskes committed
3727 3728 3729 3730 3731 3732
/*****************************************************************************
 *
 *     Names and constants
 *
 *****************************************************************************/

Marc G. Fournier's avatar
Marc G. Fournier committed
3733 3734 3735 3736 3737 3738
relation_name:	SpecialRuleRelation
				{
					$$ = $1;
				}
		| ColId
				{
3739
					$$ = $1;
Marc G. Fournier's avatar
Marc G. Fournier committed
3740 3741 3742
				}
		;

3743
name:				ColId			{ $$ = $1; };
Marc G. Fournier's avatar
Marc G. Fournier committed
3744
database_name:			ColId			{ $$ = $1; };
Michael Meskes's avatar
Michael Meskes committed
3745
access_method:			ColId			{ $$ = $1; };
Marc G. Fournier's avatar
Marc G. Fournier committed
3746
attr_name:				ColId			{ $$ = $1; };
Michael Meskes's avatar
Michael Meskes committed
3747
class:					ColId			{ $$ = $1; };
Marc G. Fournier's avatar
Marc G. Fournier committed
3748 3749 3750 3751 3752 3753
index_name:				ColId			{ $$ = $1; };

/* Functions
 * Include date/time keywords as SQL92 extension.
 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
 */
3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764
func_name:	ColId			{ $$ = $1; };
		| BETWEEN 		{ $$ = make_str("between");}
		| ILIKE			{ $$ = make_str("ilike");}
		| IN			{ $$ = make_str("in");}
		| IS			{ $$ = make_str("is");}
		| ISNULL		{ $$ = make_str("isnull");}
		| LIKE			{ $$ = make_str("like");}
		| NOTNULL		{ $$ = make_str("notnull");}
		| OVERLAPS		{ $$ = make_str("overlaps");}
		;

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

3766
file_name:				StringConst			{ $$ = $1; };
Marc G. Fournier's avatar
Marc G. Fournier committed
3767 3768 3769 3770

/* Constants
 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
 */
3771
AexprConst:  PosAllConst
Marc G. Fournier's avatar
Marc G. Fournier committed
3772 3773 3774
				{
					$$ = $1;
				}
3775
		| ConstTypename StringConst
Marc G. Fournier's avatar
Marc G. Fournier committed
3776
				{
3777
					$$ = cat2_str($1, $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3778
				}
3779
		| ConstInterval StringConst opt_interval 
Michael Meskes's avatar
Michael Meskes committed
3780 3781 3782
				{
					$$ = cat_str(3, $1, $2, $3);
				}
3783 3784 3785 3786
		| 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
3787 3788 3789 3790
		| ParamNo
				{	$$ = $1;  }
		| TRUE_P
				{
Michael Meskes's avatar
Michael Meskes committed
3791
					$$ = make_str("true");
Marc G. Fournier's avatar
Marc G. Fournier committed
3792 3793 3794
				}
		| FALSE_P
				{
Michael Meskes's avatar
Michael Meskes committed
3795
					$$ = make_str("false");
Marc G. Fournier's avatar
Marc G. Fournier committed
3796
				}
Michael Meskes's avatar
Michael Meskes committed
3797 3798 3799 3800
		| NULL_P
				{
					$$ = make_str("null");
				}
3801 3802
		| civarind
			        { $$ = make_str("?"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
3803 3804
		;

3805
ParamNo:  PARAM opt_indirection
Marc G. Fournier's avatar
Marc G. Fournier committed
3806
				{
3807
					$$ = cat2_str(make_name(), $2);
Marc G. Fournier's avatar
Marc G. Fournier committed
3808 3809 3810 3811
				}
		;

Iconst:  ICONST                                 { $$ = make_name();};
3812
Fconst:  FCONST                                 { $$ = make_name();};
Michael Meskes's avatar
Michael Meskes committed
3813
Bitconst:  BITCONST                             { $$ = make_name();};
Marc G. Fournier's avatar
Marc G. Fournier committed
3814 3815 3816 3817 3818 3819
Sconst:  SCONST                                 {
							$$ = (char *)mm_alloc(strlen($1) + 3);
							$$[0]='\'';
				     		        strcpy($$+1, $1);
							$$[strlen($1)+2]='\0';
							$$[strlen($1)+1]='\'';
3820
							free($1);
Marc G. Fournier's avatar
Marc G. Fournier committed
3821
						}
3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837
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("?"); }
			;
3838 3839 3840 3841 3842

NumConst:	Fconst        { $$ = $1; }
                | Iconst        { $$ = $1; }
                | '-' Fconst    { $$ = cat2_str(make_str("-"), $2); }
                | '-' Iconst    { $$ = cat2_str(make_str("-"), $2); }
3843 3844 3845
		| civar		{ $$ = make_str("?"); }
		;

3846 3847 3848 3849
AllConst:	Sconst		{ $$ = $1; }
		| NumConst	{ $$ = $1; }
		;

3850 3851 3852
PosAllConst:	Sconst  	{ $$ = $1; }
		| Fconst	{ $$ = $1; }
		| Iconst        { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
3853
		| Bitconst	{ $$ = $1; }
3854 3855 3856
		| civar 	{ $$ = make_str("?"); }
		;

Michael Meskes's avatar
Michael Meskes committed
3857
UserId:  ColId                                  { $$ = $1;};
Marc G. Fournier's avatar
Marc G. Fournier committed
3858 3859 3860

/* Column identifier
 */
Michael Meskes's avatar
Michael Meskes committed
3861 3862
ColId:	ECPGColId			{ $$ = $1; }
/*	| ECPGTypeName                  { $$ = $1; }*/
Michael Meskes's avatar
Michael Meskes committed
3863 3864
	;

Marc G. Fournier's avatar
Marc G. Fournier committed
3865 3866 3867 3868 3869 3870 3871 3872 3873 3874
/* Column label
 * Allowed labels in "AS" clauses.
 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
 *  compatibility. Cannot allow this for column names since the
 *  syntax would not distinguish between the constant value and
 *  a column name. - thomas 1997-10-24
 * Add other keywords to this list. Note that they appear here
 *  rather than in ColId if there was a shift/reduce conflict
 *  when used as a full identifier. - thomas 1997-11-06
 */
Michael Meskes's avatar
Michael Meskes committed
3875 3876 3877
ColLabel:  ECPGLabelTypeName			{ $$ = $1; }
	| ECPGColLabel                  { $$ = $1; }
	;
Marc G. Fournier's avatar
Marc G. Fournier committed
3878

3879
SpecialRuleRelation:  OLD
Marc G. Fournier's avatar
Marc G. Fournier committed
3880
				{
3881
					if (!QueryIsRule)
3882
						mmerror(ET_ERROR, "OLD used in non-rule query");
3883 3884

					$$ = make_str("old");
Marc G. Fournier's avatar
Marc G. Fournier committed
3885 3886 3887
				}
		| NEW
				{
3888
					if (!QueryIsRule)
Michael Meskes's avatar
Michael Meskes committed
3889
						mmerror(ET_ERROR, "NEW used in non-rule query");
3890 3891

					$$ = make_str("new");
Marc G. Fournier's avatar
Marc G. Fournier committed
3892 3893 3894 3895 3896 3897 3898 3899 3900 3901
				}
		;

/*
 * and now special embedded SQL stuff
 */

/*
 * the exec sql connect statement: connect to the given database 
 */
3902 3903
ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
		{
Michael Meskes's avatar
Michael Meskes committed
3904
			$$ = cat_str(5, $3, make_str(","), $5, make_str(","), $4);
3905 3906 3907
                }
	| SQL_CONNECT TO DEFAULT
        	{
Michael Meskes's avatar
Michael Meskes committed
3908
                	$$ = make_str("NULL,NULL,NULL,\"DEFAULT\"");
3909 3910 3911 3912
                }
      /* also allow ORACLE syntax */
        | SQL_CONNECT ora_user
                {
Michael Meskes's avatar
Michael Meskes committed
3913
		       $$ = cat_str(3, make_str("NULL,"), $2, make_str(",NULL"));
3914 3915 3916 3917 3918 3919 3920
		}

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

Michael Meskes's avatar
Michael Meskes committed
3925
		  $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
3926
		}
Michael Meskes's avatar
Michael Meskes committed
3927
        |  db_prefix ':' server opt_port '/' database_name opt_options
3928
                {
3929
		  /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
Michael Meskes's avatar
Michael Meskes committed
3930
                  if (strncmp($3, "//", strlen("//")) != 0)
3931
		  {
3932
		    sprintf(errortext, "Expected '://', found '%s'", $3);
Michael Meskes's avatar
Michael Meskes committed
3933
		    mmerror(ET_ERROR, errortext);
3934
		  }
3935

Michael Meskes's avatar
Michael Meskes committed
3936 3937 3938
		  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)
3939
		  {
Michael Meskes's avatar
Michael Meskes committed
3940
		    sprintf(errortext, "unix domain sockets only work on 'localhost' but not on '%9.9s'", $3 + strlen("//"));
Michael Meskes's avatar
Michael Meskes committed
3941
                    mmerror(ET_ERROR, errortext);
3942 3943
		  }

Michael Meskes's avatar
Michael Meskes committed
3944
		  if (strncmp($1, "unix", strlen("unix")) != 0 && strncmp($1, "tcp", strlen("tcp")) != 0)
3945 3946
		  {
		    sprintf(errortext, "only protocols 'tcp' and 'unix' are supported");
Michael Meskes's avatar
Michael Meskes committed
3947
                    mmerror(ET_ERROR, errortext);
3948
		  }
3949
	
Michael Meskes's avatar
Michael Meskes committed
3950
		  $$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6),  $7, make_str("\"")));
3951
		}
3952
	| StringConst
3953
		{
3954 3955
		  if ($1[0] == '\"')
			$$ = $1;
3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969
		  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);
                  }
3970 3971
		  else
			$$ = make3_str(make_str("\""), $1, make_str("\""));
3972
		}
3973 3974 3975 3976 3977

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

3982
		  if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
3983 3984
		  {
		    sprintf(errortext, "Illegal connection type %s", $1);
Michael Meskes's avatar
Michael Meskes committed
3985
		    mmerror(ET_ERROR, errortext);
3986 3987
		  }

Michael Meskes's avatar
Michael Meskes committed
3988
		  $$ = make3_str($1, make_str(":"), $2);
3989 3990 3991 3992
		}
        
server: Op server_name
                {
Michael Meskes's avatar
Michael Meskes committed
3993
		  if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
3994
		  {
3995
		    sprintf(errortext, "Expected '@' or '://', found '%s'", $1);
Michael Meskes's avatar
Michael Meskes committed
3996
		    mmerror(ET_ERROR, errortext);
3997 3998 3999 4000 4001 4002
		  }

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

opt_server: server { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
4003
        | /* empty */ { $$ = EMPTY; }
4004 4005

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

4009
opt_port: ':' PosIntConst { $$ = make2_str(make_str(":"), $2); }
Michael Meskes's avatar
Michael Meskes committed
4010
        | /* empty */ { $$ = EMPTY; }
4011 4012

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

opt_user: USER ora_user { $$ = $2; }
Michael Meskes's avatar
Michael Meskes committed
4016
          | /* empty */ { $$ = make_str("NULL,NULL"); }
4017 4018 4019

ora_user: user_name
		{
Michael Meskes's avatar
Michael Meskes committed
4020
                        $$ = cat2_str($1, make_str(", NULL"));
4021
	        }
Michael Meskes's avatar
Michael Meskes committed
4022
	| user_name '/' user_name
4023
		{
Michael Meskes's avatar
Michael Meskes committed
4024
        		$$ = cat_str(3, $1, make_str(","), $3);
4025 4026 4027
                }
        | user_name SQL_IDENTIFIED BY user_name
                {
Michael Meskes's avatar
Michael Meskes committed
4028
        		$$ = cat_str(3, $1, make_str(","), $4);
4029 4030 4031
                }
        | user_name USING user_name
                {
Michael Meskes's avatar
Michael Meskes committed
4032
        		$$ = cat_str(3, $1, make_str(","), $3);
4033 4034
                }

4035 4036 4037 4038 4039 4040 4041 4042
user_name: UserId       {
			 if ($1[0] == '\"')
				$$ = $1;
			  else
				$$ = make3_str(make_str("\""), $1, make_str("\""));
			}
        | StringConst   { 
			  if ($1[0] == '\"')
4043
				$$ = $1;
4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057
			  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);
                	  }
4058
			  else
Michael Meskes's avatar
Michael Meskes committed
4059
				$$ = make3_str(make_str("\""), $1, make_str("\""));
4060
			}
4061 4062 4063

char_variable: cvariable
		{ /* check if we have a char variable */
4064
			struct variable *p = find_variable($1);
4065 4066 4067 4068 4069 4070
			enum ECPGttype typ = p->type->typ;

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

4071 4072 4073 4074 4075 4076 4077
                        switch (typ)
                        {
                            case ECPGt_char:
                            case ECPGt_unsigned_char:
                                $$ = $1;
                                break;
                            case ECPGt_varchar:
Michael Meskes's avatar
Michael Meskes committed
4078
                                $$ = make2_str($1, make_str(".arr"));
4079 4080
                                break;
                            default:
Michael Meskes's avatar
Michael Meskes committed
4081
                                mmerror(ET_ERROR, "invalid datatype");
4082 4083 4084 4085 4086 4087 4088
                                break;
                        }
		}

opt_options: Op ColId
		{
			if (strlen($1) == 0)
4089
				mmerror(ET_ERROR, "incomplete statement");
4090 4091 4092
				
			if (strcmp($1, "?") != 0)
			{
4093
				sprintf(errortext, "unrecognised token '%s'", $1);
Michael Meskes's avatar
Michael Meskes committed
4094
				mmerror(ET_ERROR, errortext);
4095 4096
			}
			
Michael Meskes's avatar
Michael Meskes committed
4097
			$$ = make2_str(make_str("?"), $2);
4098
		}
Michael Meskes's avatar
Michael Meskes committed
4099
	| /* empty */ { $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
4100
	;
4101

4102
/*
4103 4104
 * Declare a prepared cursor. The syntax is different from the standard
 * declare statement, so we create a new rule.
4105
 */
Michael Meskes's avatar
Michael Meskes committed
4106
ECPGCursorStmt:  DECLARE name opt_cursor CURSOR FOR ident
4107 4108 4109
				{
					struct cursor *ptr, *this;
					struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4110

4111 4112 4113 4114 4115 4116
					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
4117
							mmerror(ET_ERROR, errortext);
4118 4119
				                }
        				}
4120

4121
        				this = (struct cursor *) mm_alloc(sizeof(struct cursor));
4122

4123 4124 4125
			        	/* initial definition */
				        this->next = cur;
				        this->name = $2;
4126
					this->connection = connection;
Michael Meskes's avatar
Michael Meskes committed
4127
				        this->command =  cat_str(4, make_str("declare"), mm_strdup($2), $3, make_str("cursor for ?"));
4128
					this->argsresult = NULL;
4129

4130 4131 4132 4133 4134
					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);
4135

4136 4137
					this->argsinsert = NULL;
					add_variable(&(this->argsinsert), thisquery, &no_indicator); 
4138

4139 4140
			        	cur = this;
					
Michael Meskes's avatar
Michael Meskes committed
4141
					$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
Marc G. Fournier's avatar
Marc G. Fournier committed
4142
				}
4143
		;
Marc G. Fournier's avatar
Marc G. Fournier committed
4144

4145
/*
4146 4147
 * the exec sql deallocate prepare command to deallocate a previously
 * prepared statement
4148
 */
Michael Meskes's avatar
Michael Meskes committed
4149
ECPGDeallocate:	SQL_DEALLOCATE SQL_PREPARE ident	{ $$ = cat_str(3, make_str("ECPGdeallocate(__LINE__, \""), $3, make_str("\");")); };
4150

4151 4152 4153 4154
/*
 * variable declaration inside the exec sql declare block
 */
ECPGDeclaration: sql_startdeclare
4155
	{
4156 4157 4158 4159 4160 4161 4162
		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
4163
	};
4164

Michael Meskes's avatar
Michael Meskes committed
4165
sql_startdeclare: ecpgstart BEGIN_TRANS DECLARE SQL_SECTION ';' {};
4166

Michael Meskes's avatar
Michael Meskes committed
4167
sql_enddeclare: ecpgstart END_TRANS DECLARE SQL_SECTION ';' {};
4168

Michael Meskes's avatar
Michael Meskes committed
4169 4170
variable_declarations:  /* empty */ { $$ = EMPTY; }
			| declarations { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
4171
			;
Michael Meskes's avatar
Michael Meskes committed
4172 4173 4174

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

Michael Meskes's avatar
Michael Meskes committed
4177
declaration: storage_clause storage_modifier
4178
	{
Michael Meskes's avatar
Michael Meskes committed
4179
		actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2));
Michael Meskes's avatar
Michael Meskes committed
4180
		actual_startline[struct_level] = hashline_number();
4181 4182 4183
	}
	type
	{
Michael Meskes's avatar
Michael Meskes committed
4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194
		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;
		}
4195 4196 4197
	}
	variable_list ';'
	{
Michael Meskes's avatar
Michael Meskes committed
4198
 		$$ = cat_str(6, actual_startline[struct_level], $1, $2, $4.type_str, $6, make_str(";\n"));
Michael Meskes's avatar
Michael Meskes committed
4199
	};
4200

Michael Meskes's avatar
Michael Meskes committed
4201
storage_clause : S_EXTERN	{ $$ = make_str("extern"); }
Michael Meskes's avatar
Michael Meskes committed
4202 4203 4204 4205 4206
        | S_STATIC		{ $$ = make_str("static"); }
        | S_REGISTER		{ $$ = make_str("register"); }
        | S_AUTO		{ $$ = make_str("auto"); }
        | /* empty */		{ $$ = EMPTY; }
	;
4207

Michael Meskes's avatar
Michael Meskes committed
4208 4209 4210 4211
storage_modifier : S_CONST       { $$ = make_str("const"); }
        | S_VOLATILE             { $$ = make_str("volatile"); }
        | /* empty */            { $$ = EMPTY; }
	;
Michael Meskes's avatar
Michael Meskes committed
4212

4213 4214 4215 4216 4217 4218 4219 4220 4221 4222
type: simple_type
		{
			$$.type_enum = $1;
			$$.type_str = mm_strdup(ECPGtype_name($1));
			$$.type_dimension = -1;
  			$$.type_index = -1;
		}
	| varchar_type
		{
			$$.type_enum = ECPGt_varchar;
Michael Meskes's avatar
Michael Meskes committed
4223
			$$.type_str = make_str("varchar");;
4224 4225 4226 4227 4228 4229 4230 4231 4232 4233
			$$.type_dimension = -1;
  			$$.type_index = -1;
		}
	| struct_type
		{
			$$.type_enum = ECPGt_struct;
			$$.type_str = $1;
			$$.type_dimension = -1;
  			$$.type_index = -1;
		}
4234 4235 4236 4237 4238 4239 4240
	| union_type
		{
			$$.type_enum = ECPGt_union;
			$$.type_str = $1;
			$$.type_dimension = -1;
  			$$.type_index = -1;
		}
4241 4242 4243 4244
	| enum_type
		{
			$$.type_str = $1;
			$$.type_enum = ECPGt_int;
Michael Meskes's avatar
Michael Meskes committed
4245
			$$.type_dimension = -1;
4246 4247
  			$$.type_index = -1;
		}
Michael Meskes's avatar
Michael Meskes committed
4248
	| ECPGColLabel
4249 4250 4251 4252
		{
			/* this is for typedef'ed types */
			struct typedefs *this = get_typedef($1);

Michael Meskes's avatar
Michael Meskes committed
4253
			$$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
4254 4255 4256 4257 4258
                        $$.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);
		}
Michael Meskes's avatar
Michael Meskes committed
4259
	;
4260

Michael Meskes's avatar
Michael Meskes committed
4261
enum_type: SQL_ENUM opt_symbol enum_definition
4262
	{
Michael Meskes's avatar
Michael Meskes committed
4263 4264 4265 4266 4267
		$$ = cat_str(3, make_str("enum"), $2, $3);
	}
	|  SQL_ENUM symbol
	{
		$$ = cat2_str(make_str("enum"), $2);
4268
	}
Michael Meskes's avatar
Michael Meskes committed
4269
	;
Michael Meskes's avatar
Michael Meskes committed
4270

Michael Meskes's avatar
Michael Meskes committed
4271
enum_definition: '{' c_list '}'	{ $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
4272 4273 4274 4275 4276

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
4277
	    $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
Michael Meskes's avatar
Michael Meskes committed
4278
	};
4279

4280 4281 4282 4283
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
4284
	    $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
Michael Meskes's avatar
Michael Meskes committed
4285
	};
4286

Michael Meskes's avatar
Michael Meskes committed
4287
s_struct: SQL_STRUCT opt_symbol
4288 4289 4290
        {
            struct_member_list[struct_level++] = NULL;
            if (struct_level >= STRUCT_DEPTH)
Michael Meskes's avatar
Michael Meskes committed
4291
                 mmerror(ET_ERROR, "Too many levels in nested structure definition");
Michael Meskes's avatar
Michael Meskes committed
4292 4293 4294 4295 4296

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

Michael Meskes's avatar
Michael Meskes committed
4297
	    $$ = cat2_str(make_str("struct"), $2);
Michael Meskes's avatar
Michael Meskes committed
4298
	};
4299

Michael Meskes's avatar
Michael Meskes committed
4300
s_union: UNION opt_symbol
4301 4302 4303
        {
            struct_member_list[struct_level++] = NULL;
            if (struct_level >= STRUCT_DEPTH)
Michael Meskes's avatar
Michael Meskes committed
4304
                 mmerror(ET_ERROR, "Too many levels in nested structure definition");
Michael Meskes's avatar
Michael Meskes committed
4305 4306 4307 4308 4309

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

Michael Meskes's avatar
Michael Meskes committed
4310
	    $$ = cat2_str(make_str("union"), $2);
Michael Meskes's avatar
Michael Meskes committed
4311
	};
4312

Michael Meskes's avatar
Michael Meskes committed
4313 4314 4315
simple_type: unsigned_type		{ $$=$1; }
	|	opt_signed signed_type	{ $$=$2; }
	;
4316

Michael Meskes's avatar
Michael Meskes committed
4317 4318 4319 4320 4321 4322
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; }
4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336
		| 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
4337 4338 4339 4340 4341 4342 4343 4344
	        | 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; }
4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358
           | 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
								}
Michael Meskes's avatar
Michael Meskes committed
4359 4360 4361 4362
           | SQL_BOOL   		{ $$ = ECPGt_bool; };
           | FLOAT 	        	{ $$ = ECPGt_float; }
           | DOUBLE 		        { $$ = ECPGt_double; }
           | CHAR            		{ $$ = ECPGt_char; }
Michael Meskes's avatar
Michael Meskes committed
4363 4364 4365 4366 4367 4368
	   ;

opt_signed:	SQL_SIGNED
	|	/* EMPTY */
	;

Michael Meskes's avatar
Michael Meskes committed
4369
varchar_type:  VARCHAR		{ $$ = ECPGt_varchar; };
4370 4371 4372 4373 4374 4375 4376

variable_list: variable 
	{
		$$ = $1;
	}
	| variable_list ',' variable
	{
Michael Meskes's avatar
Michael Meskes committed
4377
		$$ = cat_str(3, $1, make_str(","), $3);
4378
	}
Michael Meskes's avatar
Michael Meskes committed
4379
	;
4380

Michael Meskes's avatar
Michael Meskes committed
4381
variable: opt_pointer ECPGColLabel opt_array_bounds opt_initializer
4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392
		{
			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:
4393
			   case ECPGt_union:
4394
                               if (dimension < 0)
4395
                                   type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum);
4396
                               else
4397
                                   type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum), dimension); 
4398

Michael Meskes's avatar
Michael Meskes committed
4399
                               $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4400 4401
                               break;
                           case ECPGt_varchar:
Michael Meskes's avatar
Michael Meskes committed
4402
                               if (dimension < 0)
4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419
                                   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
4420
                               if (length == 0)
Michael Meskes's avatar
Michael Meskes committed
4421
				   mmerror(ET_ERROR, "pointer to varchar are not implemented");
Michael Meskes's avatar
Michael Meskes committed
4422 4423

			       if (dimension == 0)
Michael Meskes's avatar
Michael Meskes committed
4424
				   $$ = 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
4425
			       else
Michael Meskes's avatar
Michael Meskes committed
4426
                                   $$ = 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
4427

4428 4429 4430 4431 4432 4433 4434 4435
                               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
4436
			       $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4437 4438 4439 4440 4441 4442 4443
                               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
4444
			       $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4445 4446 4447 4448 4449 4450 4451 4452 4453
                               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
4454
		};
4455

Michael Meskes's avatar
Michael Meskes committed
4456
opt_initializer: /* empty */		{ $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
4457 4458 4459 4460
	| '=' c_term			{ 
						initializer = 1;
						$$ = cat2_str(make_str("="), $2);
					}
Michael Meskes's avatar
Michael Meskes committed
4461
	;
4462

Michael Meskes's avatar
Michael Meskes committed
4463
opt_pointer: /* empty */	{ $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
4464
	| '*'			{ $$ = make_str("*"); }
Michael Meskes's avatar
Michael Meskes committed
4465
	;
4466 4467 4468 4469 4470 4471 4472 4473

/*
 * 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
4474
		$$ = cat_str(3, make_str("/* declare statement"), $3, make_str("*/"));
Michael Meskes's avatar
Michael Meskes committed
4475
	};
4476 4477 4478 4479 4480 4481
/*
 * 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
4482 4483 4484
	| CURRENT	{ $$ = make_str("\"CURRENT\""); }
	| ALL		{ $$ = make_str("\"ALL\""); }
	| /* empty */	{ $$ = make_str("\"CURRENT\""); }
Michael Meskes's avatar
Michael Meskes committed
4485
	;
4486 4487

connection_object: connection_target { $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
4488
	| DEFAULT	{ $$ = make_str("\"DEFAULT\""); }
Michael Meskes's avatar
Michael Meskes committed
4489
	;
4490 4491 4492 4493

/*
 * execute a given string as sql command
 */
Michael Meskes's avatar
Michael Meskes committed
4494
ECPGExecute : EXECUTE IMMEDIATE execstring
4495 4496 4497 4498 4499 4500 4501 4502 4503 4504
	{ 
		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
4505
		$$ = make_str("?");
4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517
	}
	| 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); 
4518
	} ecpg_using opt_ecpg_into
4519
	{
Michael Meskes's avatar
Michael Meskes committed
4520
		$$ = make_str("?");
4521
	}
Michael Meskes's avatar
Michael Meskes committed
4522
	;
4523

Michael Meskes's avatar
Michael Meskes committed
4524 4525 4526
execstring:	char_variable	{ $$ = $1; }
	| 	CSTRING		{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
	;
4527 4528 4529 4530 4531

/*
 * the exec sql free command to deallocate a previously
 * prepared statement
 */
Michael Meskes's avatar
Michael Meskes committed
4532
ECPGFree:	SQL_FREE ident	{ $$ = $2; };
4533 4534 4535 4536

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

Michael Meskes's avatar
Michael Meskes committed
4539
ecpg_using: /* empty */		{ $$ = EMPTY; }
4540
	| USING variablelist	{
Michael Meskes's avatar
Michael Meskes committed
4541
					/* mmerror ("open cursor with variables not implemented yet"); */
Michael Meskes's avatar
Michael Meskes committed
4542
					$$ = EMPTY;
4543
				}
Michael Meskes's avatar
Michael Meskes committed
4544
	;
4545

4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561
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; }
		;

4562 4563
variable: civarind | civar 
variablelist: variable | variable ',' variablelist;
4564 4565 4566 4567 4568

/*
 * 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
4569
ECPGPrepare: SQL_PREPARE ident FROM execstring
4570
	{
Michael Meskes's avatar
Michael Meskes committed
4571
		$$ = cat2_str(make3_str(make_str("\""), $2, make_str("\",")), $4);
Michael Meskes's avatar
Michael Meskes committed
4572
	};
4573

Michael Meskes's avatar
Michael Meskes committed
4574 4575 4576 4577 4578 4579 4580 4581
/*
 * dynamic SQL: descriptor based access
 * 	written by Christof Petig <christof.petig@wtal.de>
 */

/*
 * deallocate a descriptor
 */
4582
ECPGDeallocateDescr:	SQL_DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
Michael Meskes's avatar
Michael Meskes committed
4583 4584 4585 4586
		{
			drop_descriptor($3,connection);
			$$ = $3;
		};
Michael Meskes's avatar
Michael Meskes committed
4587 4588 4589 4590

/*
 * allocate a descriptor
 */
4591
ECPGAllocateDescr:	SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
Michael Meskes's avatar
Michael Meskes committed
4592 4593 4594 4595
		{
			add_descriptor($3,connection);
			$$ = $3;
		};
Michael Meskes's avatar
Michael Meskes committed
4596 4597 4598 4599 4600

/*
 * read from descriptor
 */

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

Michael Meskes's avatar
Michael Meskes committed
4603
desc_header_item:	SQL_COUNT		{ $$ = ECPGd_count; };
Michael Meskes's avatar
Michael Meskes committed
4604

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

4607 4608
descriptor_item:	SQL_CARDINALITY	{ $$ = ECPGd_cardinality; }
		|	SQL_DATA			{ $$ = ECPGd_data; }
Michael Meskes's avatar
Michael Meskes committed
4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623
		|	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
4624
ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
Michael Meskes's avatar
Michael Meskes committed
4625 4626
	| ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
	;
Michael Meskes's avatar
Michael Meskes committed
4627 4628
 
ECPGGetDescItems: ECPGGetDescItem
Michael Meskes's avatar
Michael Meskes committed
4629 4630
	| ECPGGetDescItems ',' ECPGGetDescItem
	;
Michael Meskes's avatar
Michael Meskes committed
4631
 
4632
ECPGGetDescriptorHeader:	SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
Michael Meskes's avatar
Michael Meskes committed
4633
		{  $$ = $3; };
Michael Meskes's avatar
Michael Meskes committed
4634

4635
ECPGGetDescriptor:	SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE cvariable ECPGGetDescItems
Michael Meskes's avatar
Michael Meskes committed
4636
		{  $$.str = $5; $$.name = $3; }
4637
	|	SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE Iconst ECPGGetDescItems
Michael Meskes's avatar
Michael Meskes committed
4638
		{  $$.str = $5; $$.name = $3; }
Michael Meskes's avatar
Michael Meskes committed
4639
	;
Michael Meskes's avatar
Michael Meskes committed
4640

4641 4642 4643 4644 4645 4646 4647
/*
 * 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
4648 4649
		if (strcmp($1, "begin") == 0)
                        mmerror(ET_ERROR, "RELEASE does not make sense when beginning a transaction");
4650

4651 4652
		fprintf(yyout, "ECPGtrans(__LINE__, %s, \"%s\");",
				connection ? connection : "NULL", $1);
4653
		whenever_action(0);
4654
		fprintf(yyout, "ECPGdisconnect(__LINE__, \"\");"); 
4655 4656
		whenever_action(0);
		free($1);
Michael Meskes's avatar
Michael Meskes committed
4657
	};
4658

Michael Meskes's avatar
Michael Meskes committed
4659 4660 4661 4662 4663 4664 4665
/* 
 * 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
4666
                        };
Michael Meskes's avatar
Michael Meskes committed
4667

Michael Meskes's avatar
Michael Meskes committed
4668
on_off:	ON		{ $$ = make_str("on"); }
Michael Meskes's avatar
Michael Meskes committed
4669
	| OFF		{ $$ = make_str("off"); }
Michael Meskes's avatar
Michael Meskes committed
4670
	;
Michael Meskes's avatar
Michael Meskes committed
4671

Michael Meskes's avatar
Michael Meskes committed
4672
to_equal:	TO | '=';
Michael Meskes's avatar
Michael Meskes committed
4673

4674 4675 4676 4677
/* 
 * set the actual connection, this needs a differnet handling as the other
 * set commands
 */
Michael Meskes's avatar
Michael Meskes committed
4678
ECPGSetConnection:  SET SQL_CONNECTION to_equal connection_object
4679
           		{
Michael Meskes's avatar
Michael Meskes committed
4680
				$$ = $4;
Michael Meskes's avatar
Michael Meskes committed
4681
                        };
4682 4683 4684 4685

/*
 * define a new type for embedded SQL
 */
Michael Meskes's avatar
Michael Meskes committed
4686
ECPGTypedef: TYPE_P ECPGColLabel IS type opt_type_array_bounds opt_reference
4687 4688 4689 4690 4691 4692
	{
		/* add entry to list */
		struct typedefs *ptr, *this;
		int dimension = $5.index1;
		int length = $5.index2;

Michael Meskes's avatar
Michael Meskes committed
4693 4694 4695 4696 4697
		if (($4.type_enum == ECPGt_struct ||
		     $4.type_enum == ECPGt_union) &&
		    initializer == 1)
			mmerror(ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");

4698 4699 4700 4701 4702
		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
4703
				sprintf(errortext, "Type %s already defined", $2);
Michael Meskes's avatar
Michael Meskes committed
4704
				mmerror(ET_ERROR, errortext);
4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719
	                }
		}

		adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, strlen($6));

        	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
4720 4721
		this->struct_member_list = ($4.type_enum == ECPGt_struct || $4.type_enum == ECPGt_union) ?
			struct_member_list[struct_level] : NULL;
4722 4723 4724 4725 4726

		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
4727
                            mmerror(ET_ERROR, "No multi-dimensional array support for simple data types");
4728 4729 4730

        	types = this;

Michael Meskes's avatar
Michael Meskes committed
4731
		$$ = 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
4732
	};
4733

Michael Meskes's avatar
Michael Meskes committed
4734
opt_type_array_bounds:  '[' ']' opt_type_array_bounds
4735 4736 4737
			{
                            $$.index1 = 0;
                            $$.index2 = $3.index1;
Michael Meskes's avatar
Michael Meskes committed
4738
                            $$.str = cat2_str(make_str("[]"), $3.str);
4739
                        }
Michael Meskes's avatar
Michael Meskes committed
4740
		| '(' ')' opt_type_array_bounds
4741 4742 4743
			{
                            $$.index1 = 0;
                            $$.index2 = $3.index1;
Michael Meskes's avatar
Michael Meskes committed
4744
                            $$.str = cat2_str(make_str("[]"), $3.str);
4745
                        }
Michael Meskes's avatar
Michael Meskes committed
4746
		| '[' Iresult ']' opt_type_array_bounds
4747
			{
Michael Meskes's avatar
Michael Meskes committed
4748 4749 4750 4751
			    char *txt = mm_alloc(20L);

			    sprintf (txt, "%d", $2);
                            $$.index1 = $2;
4752
                            $$.index2 = $4.index1;
Michael Meskes's avatar
Michael Meskes committed
4753
                            $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
4754
                        }
Michael Meskes's avatar
Michael Meskes committed
4755
		| '(' Iresult ')' opt_type_array_bounds
4756
			{
Michael Meskes's avatar
Michael Meskes committed
4757 4758 4759 4760
			    char *txt = mm_alloc(20L);

			    sprintf (txt, "%d", $2);
                            $$.index1 = $2;
4761
                            $$.index2 = $4.index1;
Michael Meskes's avatar
Michael Meskes committed
4762
                            $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
4763 4764 4765 4766 4767
                        }
		| /* EMPTY */
			{
                            $$.index1 = -1;
                            $$.index2 = -1;
Michael Meskes's avatar
Michael Meskes committed
4768
                            $$.str= EMPTY;
4769 4770 4771
                        }
		;

Michael Meskes's avatar
Michael Meskes committed
4772
opt_reference: SQL_REFERENCE { $$ = make_str("reference"); }
Michael Meskes's avatar
Michael Meskes committed
4773
	| /* empty */ 	     { $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
4774
	;
4775 4776 4777 4778

/*
 * define the type of one variable for embedded SQL
 */
Michael Meskes's avatar
Michael Meskes committed
4779
ECPGVar: SQL_VAR ECPGColLabel IS type opt_type_array_bounds opt_reference
4780 4781 4782 4783 4784 4785
	{
		struct variable *p = find_variable($2);
		int dimension = $5.index1;
		int length = $5.index2;
		struct ECPGtype * type;

Michael Meskes's avatar
Michael Meskes committed
4786 4787 4788 4789 4790
		if (($4.type_enum == ECPGt_struct ||
		     $4.type_enum == ECPGt_union) &&
		    initializer == 1)
			mmerror(ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");

4791 4792 4793 4794 4795
		adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, strlen($6));

		switch ($4.type_enum)
		{
		   case ECPGt_struct:
4796
		   case ECPGt_union:
4797
                        if (dimension < 0)
4798
                            type = ECPGmake_struct_type(struct_member_list[struct_level], $4.type_enum);
4799
                        else
4800
                            type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $4.type_enum), dimension); 
4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818
                        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
4819
                	    mmerror(ET_ERROR, "No multi-dimensional array support for simple data types");
4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831

                        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
4832
		$$ = 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
4833
	};
4834

Marc G. Fournier's avatar
Marc G. Fournier committed
4835
/*
4836
 * whenever statement: decide what to do in case of error/no data found
4837
 * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
Marc G. Fournier's avatar
Marc G. Fournier committed
4838
 */
Michael Meskes's avatar
Michael Meskes committed
4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857
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"));
	}
	;
4858

Michael Meskes's avatar
Michael Meskes committed
4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907
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));
	}
	;
4908

4909
/* some other stuff for ecpg */
Michael Meskes's avatar
Michael Meskes committed
4910 4911

/* additional ColId entries */
4912
ECPGKeywords: 	  SQL_BREAK			{ $$ = make_str("break"); }
Michael Meskes's avatar
Michael Meskes committed
4913
		| SQL_CALL			{ $$ = make_str("call"); }
4914
		| SQL_CARDINALITY	{ $$ = make_str("cardinality"); }
Michael Meskes's avatar
Michael Meskes committed
4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945
		| SQL_CONNECT			{ $$ = make_str("connect"); }
		| SQL_CONTINUE			{ $$ = make_str("continue"); }
		| SQL_COUNT			{ $$ = make_str("count"); }
		| SQL_DATA			{ $$ = make_str("data"); }
		| 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"); }
		| SQL_FOUND			{ $$ = make_str("found"); }
		| SQL_GO			{ $$ = make_str("go"); }
		| SQL_GOTO			{ $$ = make_str("goto"); }
		| SQL_IDENTIFIED		{ $$ = make_str("identified"); }
		| SQL_INDICATOR			{ $$ = make_str("indicator"); }
		| SQL_KEY_MEMBER		{ $$ = make_str("key_member"); }
		| SQL_LENGTH			{ $$ = make_str("length"); }
		| SQL_NAME			{ $$ = make_str("name"); }
		| SQL_NULLABLE			{ $$ = make_str("nullable"); }
		| SQL_OCTET_LENGTH		{ $$ = make_str("octet_length"); }
		| SQL_OPEN			{ $$ = make_str("open"); }
		| 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"); }
		| SQL_SCALE			{ $$ = make_str("scale"); }
		| SQL_SECTION			{ $$ = make_str("section"); }
		| SQL_SQLERROR			{ $$ = make_str("sqlerror"); }
		| SQL_SQLPRINT			{ $$ = make_str("sqlprint"); }
		| SQL_SQLWARNING		{ $$ = make_str("sqlwarning"); }
		| SQL_STOP			{ $$ = make_str("stop"); }
		| SQL_VAR			{ $$ = make_str("var"); }
		| SQL_WHENEVER			{ $$ = make_str("whenever"); }
Michael Meskes's avatar
Michael Meskes committed
4946
/*		| ECPGTypeName			{ $$ = $1 }*/
Michael Meskes's avatar
Michael Meskes committed
4947 4948 4949 4950 4951 4952 4953 4954 4955 4956
		;

ECPGTypeName:	  SQL_BOOL		{ $$ = make_str("bool"); }
		| SQL_INT		{ $$ = make_str("int"); }
		| SQL_LONG		{ $$ = make_str("long"); }
		| SQL_SHORT		{ $$ = make_str("short"); }
		| SQL_STRUCT		{ $$ = make_str("struct"); }
		| SQL_SIGNED		{ $$ = make_str("signed"); }
		| SQL_UNSIGNED		{ $$ = make_str("unsigned"); }
		| DOUBLE		{ $$ = make_str("double"); }
Michael Meskes's avatar
Michael Meskes committed
4957
		;
Michael Meskes's avatar
Michael Meskes committed
4958

Michael Meskes's avatar
Michael Meskes committed
4959 4960 4961
/* not needed at the moment
 * 			| UNION		{ $$ = make_str("union"); }
 */
Michael Meskes's avatar
Michael Meskes committed
4962 4963 4964
ECPGLabelTypeName:	  CHAR			{ $$ = make_str("char"); }
			| FLOAT		{ $$ = make_str("float"); }
			| VARCHAR	{ $$ = make_str("varchar"); }
Michael Meskes's avatar
Michael Meskes committed
4965
/*			| ECPGTypeName	{ $$ = $1; }*/
Michael Meskes's avatar
Michael Meskes committed
4966 4967 4968 4969 4970 4971
		;

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

Michael Meskes's avatar
Michael Meskes committed
4972
symbol:		ColLabel	{ $$ = $1; };
Michael Meskes's avatar
Michael Meskes committed
4973

Michael Meskes's avatar
Michael Meskes committed
4974 4975 4976 4977 4978
/* Parser tokens to be used as identifiers.
 * Tokens involving data types should appear in ColId only,
 * since they will conflict with real TypeName productions.
 */
TokenId:  ABSOLUTE			{ $$ = make_str("absolute"); }
Michael Meskes's avatar
Michael Meskes committed
4979 4980
	| ACCESS			{ $$ = make_str("access"); }
	| ACTION			{ $$ = make_str("action"); }
Michael Meskes's avatar
Michael Meskes committed
4981
	| ADD				{ $$ = make_str("add"); }
Michael Meskes's avatar
Michael Meskes committed
4982 4983
	| AFTER				{ $$ = make_str("after"); }
	| AGGREGATE			{ $$ = make_str("aggregate"); }
Michael Meskes's avatar
Michael Meskes committed
4984
	| ALTER				{ $$ = make_str("alter"); }
4985
	| AT				{ $$ = make_str("at"); }
4986
	| AUTHORIZATION			{ $$ = make_str("authorization"); }
Michael Meskes's avatar
Michael Meskes committed
4987 4988
	| BACKWARD			{ $$ = make_str("backward"); }
	| BEFORE			{ $$ = make_str("before"); }
Michael Meskes's avatar
Michael Meskes committed
4989
	| BEGIN_TRANS			{ $$ = make_str("begin"); }
Michael Meskes's avatar
Michael Meskes committed
4990
	| CACHE				{ $$ = make_str("cache"); }
Michael Meskes's avatar
Michael Meskes committed
4991
	| CASCADE			{ $$ = make_str("cascade"); }
Michael Meskes's avatar
Michael Meskes committed
4992
	| CHAIN				{ $$ = make_str("chain"); }
4993
	| CHARACTERISTICS		{ $$ = make_str("characteristics"); }
4994
	| CHECKPOINT			{ $$ = make_str("checkpoint"); }
Michael Meskes's avatar
Michael Meskes committed
4995
	| CLOSE				{ $$ = make_str("close"); }
Michael Meskes's avatar
Michael Meskes committed
4996
	| COMMENT			{ $$ = make_str("comment"); } 
Michael Meskes's avatar
Michael Meskes committed
4997
	| COMMIT			{ $$ = make_str("commit"); }
Michael Meskes's avatar
Michael Meskes committed
4998 4999 5000 5001 5002 5003
	| COMMITTED			{ $$ = make_str("committed"); }
	| CONSTRAINTS			{ $$ = make_str("constraints"); }
	| CREATEDB			{ $$ = make_str("createdb"); }
	| CREATEUSER			{ $$ = make_str("createuser"); }
	| CYCLE				{ $$ = make_str("cycle"); }
	| DATABASE			{ $$ = make_str("database"); }
Michael Meskes's avatar
Michael Meskes committed
5004
	| DECLARE			{ $$ = make_str("declare"); }
Michael Meskes's avatar
Michael Meskes committed
5005
	| DEFERRED			{ $$ = make_str("deferred"); }	
Michael Meskes's avatar
Michael Meskes committed
5006
	| DELETE			{ $$ = make_str("delete"); }
Michael Meskes's avatar
Michael Meskes committed
5007
	| DELIMITERS			{ $$ = make_str("delimiters"); }
Michael Meskes's avatar
Michael Meskes committed
5008
	| DROP				{ $$ = make_str("drop"); }
Michael Meskes's avatar
Michael Meskes committed
5009 5010
	| EACH				{ $$ = make_str("each"); }
	| ENCODING			{ $$ = make_str("encoding"); }
5011
	| ENCRYPTED			{ $$ = make_str("encrypted"); }
Michael Meskes's avatar
Michael Meskes committed
5012
	| ESCAPE			{ $$ = make_str("escape"); }
Michael Meskes's avatar
Michael Meskes committed
5013
	| EXCLUSIVE			{ $$ = make_str("exclusive"); }
Michael Meskes's avatar
Michael Meskes committed
5014 5015
	| EXECUTE			{ $$ = make_str("execute"); }
	| FETCH				{ $$ = make_str("fetch"); }
Michael Meskes's avatar
Michael Meskes committed
5016
	| FORCE				{ $$ = make_str("force"); }
Michael Meskes's avatar
Michael Meskes committed
5017 5018
	| FORWARD			{ $$ = make_str("forward"); }
	| FUNCTION			{ $$ = make_str("function"); }
Michael Meskes's avatar
Michael Meskes committed
5019
	| GRANT				{ $$ = make_str("grant"); }
Michael Meskes's avatar
Michael Meskes committed
5020
	| HANDLER			{ $$ = make_str("handler"); }
Michael Meskes's avatar
Michael Meskes committed
5021
	| IMMEDIATE			{ $$ = make_str("immediate"); } 
Michael Meskes's avatar
Michael Meskes committed
5022 5023 5024 5025
	| INCREMENT			{ $$ = make_str("increment"); }
	| INDEX				{ $$ = make_str("index"); }
	| INHERITS			{ $$ = make_str("inherits"); }
	| INSENSITIVE			{ $$ = make_str("insensitive"); }
Michael Meskes's avatar
Michael Meskes committed
5026
	| INSERT			{ $$ = make_str("insert"); }
Michael Meskes's avatar
Michael Meskes committed
5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037
	| INSTEAD			{ $$ = make_str("instead"); }
	| ISOLATION			{ $$ = make_str("isolation"); }
	| KEY				{ $$ = make_str("key"); }
	| LANGUAGE			{ $$ = make_str("language"); }
	| LANCOMPILER			{ $$ = make_str("lancompiler"); }
	| LEVEL				{ $$ = make_str("level"); }
	| LOCATION			{ $$ = make_str("location"); }
	| MATCH				{ $$ = make_str("match"); }
	| MAXVALUE			{ $$ = make_str("maxvalue"); }
	| MINVALUE			{ $$ = make_str("minvalue"); }
	| MODE				{ $$ = make_str("mode"); }
Michael Meskes's avatar
Michael Meskes committed
5038
	| NAMES				{ $$ = make_str("names"); }
Michael Meskes's avatar
Michael Meskes committed
5039
	| NEXT				{ $$ = make_str("next"); }
Michael Meskes's avatar
Michael Meskes committed
5040
	| NO				{ $$ = make_str("no"); }
Michael Meskes's avatar
Michael Meskes committed
5041 5042 5043
	| NOCREATEDB			{ $$ = make_str("nocreatedb"); }
	| NOCREATEUSER			{ $$ = make_str("nocreateuser"); }
	| NOTHING			{ $$ = make_str("nothing"); }
Michael Meskes's avatar
Michael Meskes committed
5044
	| NOTIFY			{ $$ = make_str("notify"); }
Michael Meskes's avatar
Michael Meskes committed
5045 5046 5047 5048
	| OF				{ $$ = make_str("of"); }
	| OIDS				{ $$ = make_str("oids"); }
	| OPERATOR			{ $$ = make_str("operator"); }
	| OPTION			{ $$ = make_str("option"); }
5049
	| OWNER				{ $$ = make_str("owner"); }
Michael Meskes's avatar
Michael Meskes committed
5050
	| PARTIAL			{ $$ = make_str("partial"); }
Michael Meskes's avatar
Michael Meskes committed
5051 5052 5053 5054 5055
	| PASSWORD			{ $$ = make_str("password"); }
	| PENDANT			{ $$ = make_str("pendant"); }
	| PRIOR				{ $$ = make_str("prior"); }
	| PRIVILEGES			{ $$ = make_str("privileges"); }
	| PROCEDURAL			{ $$ = make_str("procedural"); }
5056
	| PROCEDURE			{ $$ = make_str("procedure"); }
Michael Meskes's avatar
Michael Meskes committed
5057
	| READ				{ $$ = make_str("read"); }
Michael Meskes's avatar
Michael Meskes committed
5058
	| REINDEX			{ $$ = make_str("reindex"); }
Michael Meskes's avatar
Michael Meskes committed
5059 5060
	| RELATIVE			{ $$ = make_str("relative"); }
	| RENAME			{ $$ = make_str("rename"); }
5061
	| REPLACE			{ $$ = make_str("replace"); }
Michael Meskes's avatar
Michael Meskes committed
5062 5063
	| RESTRICT			{ $$ = make_str("restrict"); }
	| RETURNS			{ $$ = make_str("returns"); }
Michael Meskes's avatar
Michael Meskes committed
5064 5065
	| REVOKE			{ $$ = make_str("revoke"); }
	| ROLLBACK			{ $$ = make_str("rollback"); }
Michael Meskes's avatar
Michael Meskes committed
5066 5067
	| ROW				{ $$ = make_str("row"); }
	| RULE				{ $$ = make_str("rule"); }
Michael Meskes's avatar
Michael Meskes committed
5068
	| SCHEMA			{ $$ = make_str("schema"); }
Michael Meskes's avatar
Michael Meskes committed
5069
	| SCROLL			{ $$ = make_str("scroll"); }
Michael Meskes's avatar
Michael Meskes committed
5070
	| SESSION			{ $$ = make_str("session"); }
Michael Meskes's avatar
Michael Meskes committed
5071 5072
	| SEQUENCE                      { $$ = make_str("sequence"); }
	| SERIALIZABLE			{ $$ = make_str("serializable"); }
Michael Meskes's avatar
Michael Meskes committed
5073
	| SET				{ $$ = make_str("set"); }
Michael Meskes's avatar
Michael Meskes committed
5074 5075 5076
	| SHARE				{ $$ = make_str("share"); }
	| START				{ $$ = make_str("start"); }
	| STATEMENT			{ $$ = make_str("statement"); }
5077
	| STATISTICS			{ $$ = make_str("statistics"); }
Michael Meskes's avatar
Michael Meskes committed
5078 5079 5080 5081
	| STDIN                         { $$ = make_str("stdin"); }
	| STDOUT                        { $$ = make_str("stdout"); }
	| SYSID                         { $$ = make_str("sysid"); }
	| TEMP				{ $$ = make_str("temp"); }
Michael Meskes's avatar
Michael Meskes committed
5082
	| TEMPLATE			{ $$ = make_str("template"); }
Michael Meskes's avatar
Michael Meskes committed
5083
	| TEMPORARY			{ $$ = make_str("temporary"); }
Michael Meskes's avatar
Michael Meskes committed
5084
        | TOAST		                { $$ = make_str("toast"); }
Michael Meskes's avatar
Michael Meskes committed
5085 5086 5087
	| TRIGGER			{ $$ = make_str("trigger"); }
	| TRUNCATE			{ $$ = make_str("truncate"); }
	| TRUSTED			{ $$ = make_str("trusted"); }
5088
	| UNENCRYPTED			{ $$ = make_str("unencrypted"); }
Michael Meskes's avatar
Michael Meskes committed
5089 5090 5091
	| UNLISTEN			{ $$ = make_str("unlisten"); }
	| UNTIL				{ $$ = make_str("until"); }
	| UPDATE			{ $$ = make_str("update"); }
Michael Meskes's avatar
Michael Meskes committed
5092
	| VALID				{ $$ = make_str("valid"); }
Michael Meskes's avatar
Michael Meskes committed
5093 5094
	| VALUES			{ $$ = make_str("values"); }
	| VARYING			{ $$ = make_str("varying"); }
Michael Meskes's avatar
Michael Meskes committed
5095
	| VERSION			{ $$ = make_str("version"); }
Michael Meskes's avatar
Michael Meskes committed
5096 5097
	| VIEW				{ $$ = make_str("view"); }
	| WITH				{ $$ = make_str("with"); }
Michael Meskes's avatar
Michael Meskes committed
5098
	| WITHOUT			{ $$ = make_str("without"); }
Michael Meskes's avatar
Michael Meskes committed
5099
	| WORK				{ $$ = make_str("work"); }
Michael Meskes's avatar
Michael Meskes committed
5100 5101 5102
	| ZONE				{ $$ = make_str("zone"); }
	;

Michael Meskes's avatar
Michael Meskes committed
5103 5104 5105 5106 5107
ECPGColId: ident			{ $$ = $1; }
	| TYPE_P			{ $$ = make_str("type"); }
	| datetime			{ $$ = $1; }
	| TokenId			{ $$ = $1; }
	| NATIONAL			{ $$ = make_str("national"); }
5108
	| NONE				{ $$ = make_str("none"); }
Michael Meskes's avatar
Michael Meskes committed
5109 5110 5111 5112 5113
	| PATH_P			{ $$ = make_str("path_p"); }
	| ECPGKeywords                  { $$ = $1; }
	;

ECPGColLabel:  ECPGColId	{ $$ = $1; }
5114
		| ABORT_TRANS   { $$ = make_str("abort"); }
Michael Meskes's avatar
Michael Meskes committed
5115
		| ALL		{ $$ = make_str("all"); }
5116
		| ANALYSE       { $$ = make_str("analyse"); }
5117
		| ANALYZE       { $$ = make_str("analyze"); }
Michael Meskes's avatar
Michael Meskes committed
5118 5119
		| ANY		{ $$ = make_str("any"); }
		| ASC		{ $$ = make_str("asc"); }
5120
	    	| BETWEEN       { $$ = make_str("between"); }
5121 5122
		| BINARY        { $$ = make_str("binary"); }
		| BIT	        { $$ = make_str("bit"); }
Michael Meskes's avatar
Michael Meskes committed
5123
		| BOTH		{ $$ = make_str("both"); }
5124
		| CASE          { $$ = make_str("case"); }
Michael Meskes's avatar
Michael Meskes committed
5125
		| CAST		{ $$ = make_str("cast"); }
5126
		| CHARACTER     { $$ = make_str("character"); }
Michael Meskes's avatar
Michael Meskes committed
5127 5128
		| CHECK		{ $$ = make_str("check"); }
		| CLUSTER	{ $$ = make_str("cluster"); }
5129
		| COALESCE      { $$ = make_str("coalesce"); }
Michael Meskes's avatar
Michael Meskes committed
5130 5131
		| COLLATE	{ $$ = make_str("collate"); }
		| COLUMN	{ $$ = make_str("column"); }
5132
		| CONSTRAINT	{ $$ = make_str("constraint"); }
Michael Meskes's avatar
Michael Meskes committed
5133 5134
		| COPY		{ $$ = make_str("copy"); }
		| CROSS		{ $$ = make_str("cross"); }
5135 5136
		| CURRENT_DATE	{ $$ = make_str("current_date"); }
		| CURRENT_TIME	{ $$ = make_str("current_time"); }
Michael Meskes's avatar
Michael Meskes committed
5137
		| CURRENT_TIMESTAMP	{ $$ = make_str("current_timestamp"); }
Michael Meskes's avatar
Michael Meskes committed
5138
		| CURRENT_USER		{ $$ = make_str("current_user"); }
Michael Meskes's avatar
Michael Meskes committed
5139 5140 5141
		| DEC		{ $$ = make_str("dec"); }
		| DECIMAL	{ $$ = make_str("decimal"); }
		| DEFAULT	{ $$ = make_str("default"); }
5142
		| DEFERRABLE	{ $$ = make_str("deferrable"); }
Michael Meskes's avatar
Michael Meskes committed
5143 5144 5145
		| DESC		{ $$ = make_str("desc"); }
		| DISTINCT	{ $$ = make_str("distinct"); }
		| DO		{ $$ = make_str("do"); }
5146 5147
		| ELSE          { $$ = make_str("else"); }
		| END_TRANS     { $$ = make_str("end"); }
Michael Meskes's avatar
Michael Meskes committed
5148 5149 5150 5151 5152 5153 5154
		| EXCEPT	{ $$ = make_str("except"); }
		| EXISTS	{ $$ = make_str("exists"); }
		| EXPLAIN	{ $$ = make_str("explain"); }
		| EXTRACT	{ $$ = make_str("extract"); }
		| FALSE_P	{ $$ = make_str("false"); }
		| FOR		{ $$ = make_str("for"); }
		| FOREIGN	{ $$ = make_str("foreign"); }
5155
		| FREEZE	{ $$ = make_str("freeze"); }
Michael Meskes's avatar
Michael Meskes committed
5156 5157 5158 5159 5160
		| FROM		{ $$ = make_str("from"); }
		| FULL		{ $$ = make_str("full"); }
		| GLOBAL	{ $$ = make_str("global"); }
		| GROUP		{ $$ = make_str("group"); }
		| HAVING	{ $$ = make_str("having"); }
5161
		| ILIKE		{ $$ = make_str("ilike"); }
5162
		| IN		{ $$ = make_str("in"); }
Michael Meskes's avatar
Michael Meskes committed
5163 5164
		| INITIALLY	{ $$ = make_str("initially"); }
		| INNER_P	{ $$ = make_str("inner"); }
5165
		| INOUT         { $$ = make_str("inout"); }
Michael Meskes's avatar
Michael Meskes committed
5166
		| INTERSECT	{ $$ = make_str("intersect"); }
5167
		| INTERVAL	{ $$ = make_str("interval"); }
Michael Meskes's avatar
Michael Meskes committed
5168
		| INTO		{ $$ = make_str("into"); }
5169 5170
		| IS		{ $$ = make_str("is"); }
		| ISNULL	{ $$ = make_str("isnull"); }
Michael Meskes's avatar
Michael Meskes committed
5171 5172 5173
		| JOIN		{ $$ = make_str("join"); }
		| LEADING	{ $$ = make_str("leading"); }
		| LEFT		{ $$ = make_str("left"); }
5174 5175
		| LIKE		{ $$ = make_str("like"); }
		| LIMIT		{ $$ = make_str("limit"); }
Michael Meskes's avatar
Michael Meskes committed
5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201
		| LISTEN	{ $$ = make_str("listen"); }
		| LOAD		{ $$ = make_str("load"); }
		| LOCK_P	{ $$ = make_str("lock"); }
		| MOVE		{ $$ = make_str("move"); }
		| NATURAL	{ $$ = make_str("natural"); }
		| NCHAR		{ $$ = make_str("nchar"); }
		| NEW		{ $$ = make_str("new"); }
		| NOT		{ $$ = make_str("not"); }
		| NOTNULL   	{ $$ = make_str("notnull"); }
		| NULLIF	{ $$ = make_str("nullif"); }
		| NULL_P	{ $$ = make_str("null"); }
		| NUMERIC	{ $$ = make_str("numeric"); }
		| 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"); }
		| OUT		{ $$ = make_str("out"); }
		| OUTER_P	{ $$ = make_str("outer"); }
	        | OVERLAPS      { $$ = make_str("overlaps"); }
		| POSITION	{ $$ = make_str("position"); }
		| PRECISION	{ $$ = make_str("precision"); }
		| PRIMARY	{ $$ = make_str("primary"); }
		| PUBLIC	{ $$ = make_str("public"); }
5202
		| REFERENCES	{ $$ = make_str("references"); }
Michael Meskes's avatar
Michael Meskes committed
5203 5204 5205
		| RESET		{ $$ = make_str("reset"); }
		| RIGHT		{ $$ = make_str("right"); }
		| SELECT	{ $$ = make_str("select"); }
5206
		| SESSION_USER	{ $$ = make_str("session_user"); }
Michael Meskes's avatar
Michael Meskes committed
5207 5208 5209 5210
		| SETOF		{ $$ = make_str("setof"); }
		| SHOW		{ $$ = make_str("show"); }
		| SUBSTRING	{ $$ = make_str("substring"); }
		| TABLE		{ $$ = make_str("table"); }
5211
		| THEN          { $$ = make_str("then"); }
Michael Meskes's avatar
Michael Meskes committed
5212 5213
		| TIME		{ $$ = make_str("time"); }
		| TIMESTAMP	{ $$ = make_str("timestamp"); }
Michael Meskes's avatar
Michael Meskes committed
5214
		| TO		{ $$ = make_str("to"); }
5215
		| TRANSACTION	{ $$ = make_str("transaction"); }
Michael Meskes's avatar
Michael Meskes committed
5216 5217 5218
		| TRIM		{ $$ = make_str("trim"); }
		| TRUE_P	{ $$ = make_str("true"); }
		| UNIQUE	{ $$ = make_str("unique"); }
5219
		| UNKNOWN	{ $$ = make_str("unknown"); }
Michael Meskes's avatar
Michael Meskes committed
5220 5221 5222 5223
		| USER		{ $$ = make_str("user"); }
		| USING		{ $$ = make_str("using"); }
		| VACUUM	{ $$ = make_str("vacuum"); }
		| VERBOSE	{ $$ = make_str("verbose"); }
5224
		| WHEN          { $$ = make_str("when"); }
Michael Meskes's avatar
Michael Meskes committed
5225
		| WHERE		{ $$ = make_str("where"); }
Marc G. Fournier's avatar
Marc G. Fournier committed
5226 5227 5228 5229
		;

into_list : coutputvariable | into_list ',' coutputvariable;

Michael Meskes's avatar
Michael Meskes committed
5230
ecpgstart: SQL_START { reset_variables(); };
5231

Michael Meskes's avatar
Michael Meskes committed
5232
c_args: /* empty */		{ $$ = EMPTY; }
Michael Meskes's avatar
Michael Meskes committed
5233
	| c_list		{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5234
	;
Marc G. Fournier's avatar
Marc G. Fournier committed
5235

5236
coutputvariable: cvariable indicator
Michael Meskes's avatar
Michael Meskes committed
5237
	{
5238 5239 5240 5241 5242 5243 5244
		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
5245

5246 5247

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

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

5255
civar: cvariable
Michael Meskes's avatar
Michael Meskes committed
5256
	{
5257
		add_variable(&argsinsert, find_variable($1), &no_indicator); 
5258
		$$ = $1;
Michael Meskes's avatar
Michael Meskes committed
5259
	};
5260

5261
cvariable: CVARIABLE	{ $$ = $1; }
5262

5263
indicator: CVARIABLE		 	{ check_indicator((find_variable($1))->type); $$ = $1; }
5264
	| SQL_INDICATOR cvariable 	{ check_indicator((find_variable($2))->type); $$ = $2; }
Marc G. Fournier's avatar
Marc G. Fournier committed
5265
	| SQL_INDICATOR name		{ check_indicator((find_variable($2))->type); $$ = $2; }
Michael Meskes's avatar
Michael Meskes committed
5266
	;
Marc G. Fournier's avatar
Marc G. Fournier committed
5267

Michael Meskes's avatar
Michael Meskes committed
5268
ident: IDENT		{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5269 5270
	| CSTRING	{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
	;
Michael Meskes's avatar
Michael Meskes committed
5271

5272 5273 5274 5275 5276 5277 5278
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
5279 5280 5281
/*
 * C stuff
 */
5282

Michael Meskes's avatar
Michael Meskes committed
5283
cpp_line: CPP_LINE	{ $$ = $1; };
5284

Michael Meskes's avatar
Michael Meskes committed
5285 5286 5287 5288 5289 5290 5291
c_stuff: c_anything 	{ $$ = $1; }
	| c_stuff c_anything
			{
				$$ = cat2_str($1, $2);
			}
	| c_stuff '(' c_stuff ')'
			{
Michael Meskes's avatar
Michael Meskes committed
5292
				$$ = cat_str(4, $1, make_str("("), $3, make_str(")"));
Michael Meskes's avatar
Michael Meskes committed
5293
			}
5294 5295 5296 5297
	| c_stuff '(' ')'
			{
				$$ = cat_str(3, $1, make_str("("), make_str(")"));
			}
Michael Meskes's avatar
Michael Meskes committed
5298
	;
Michael Meskes's avatar
Michael Meskes committed
5299 5300

c_list: c_term			{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5301
	| c_list ',' c_term	{ $$ = cat_str(3, $1, make_str(","), $3); }
Michael Meskes's avatar
Michael Meskes committed
5302
	;
Michael Meskes's avatar
Michael Meskes committed
5303 5304

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

Michael Meskes's avatar
Michael Meskes committed
5308
c_thing:	c_anything	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5309 5310 5311 5312
	|	'('		{ $$ = make_str("("); }
	|	')'		{ $$ = make_str(")"); }
	|	','		{ $$ = make_str(","); }
	|	';'		{ $$ = make_str(";"); }
Michael Meskes's avatar
Michael Meskes committed
5313
	;
5314

5315
c_anything:  IDENT 	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5316
	| CSTRING	{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5317
	| PosIntConst	{ $$ = $1; }
5318
	| Fconst	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5319
	| Sconst	{ $$ = $1; }
Michael Meskes's avatar
Michael Meskes committed
5320 5321 5322 5323 5324
	| '*'		{ $$ = make_str("*"); }
	| '+'		{ $$ = make_str("+"); }
	| '-'		{ $$ = make_str("-"); }
	| '/'		{ $$ = make_str("/"); }
	| '%'		{ $$ = make_str("%"); }
5325 5326
	| NULL_P	{ $$ = make_str("NULL"); }
	| S_ADD		{ $$ = make_str("+="); } 
5327
	| S_AND		{ $$ = make_str("&&"); } 
Michael Meskes's avatar
Michael Meskes committed
5328
	| S_ANYTHING	{ $$ = make_name(); }
Michael Meskes's avatar
Michael Meskes committed
5329 5330
	| S_AUTO	{ $$ = make_str("auto"); }
	| S_CONST	{ $$ = make_str("const"); }
5331 5332 5333 5334
	| S_DEC		{ $$ = make_str("--"); } 
	| S_DIV		{ $$ = make_str("/="); } 
	| S_DOTPOINT	{ $$ = make_str(".*"); } 
	| S_EQUAL	{ $$ = make_str("=="); } 
Michael Meskes's avatar
Michael Meskes committed
5335
	| S_EXTERN	{ $$ = make_str("extern"); }
5336
	| S_INC		{ $$ = make_str("++"); } 
5337 5338
	| S_LSHIFT	{ $$ = make_str("<<"); } 
	| S_MEMBER	{ $$ = make_str("->"); } 
5339
	| S_MEMPOINT	{ $$ = make_str("->*"); } 
5340
	| S_MOD		{ $$ = make_str("%="); }
5341 5342
	| S_MUL		{ $$ = make_str("*="); } 
	| S_NEQUAL	{ $$ = make_str("!="); } 
5343
	| S_OR		{ $$ = make_str("||"); } 
Michael Meskes's avatar
Michael Meskes committed
5344
	| S_REGISTER	{ $$ = make_str("register"); }
5345
	| S_RSHIFT	{ $$ = make_str(">>"); } 
Michael Meskes's avatar
Michael Meskes committed
5346
	| S_STATIC	{ $$ = make_str("static"); }
5347
	| S_SUB		{ $$ = make_str("-="); } 
Michael Meskes's avatar
Michael Meskes committed
5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360
	| 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
5361 5362 5363
        | '['		{ $$ = make_str("["); }
	| ']'		{ $$ = make_str("]"); }
	| '='		{ $$ = make_str("="); }
Michael Meskes's avatar
Michael Meskes committed
5364
	;
5365

Michael Meskes's avatar
Michael Meskes committed
5366 5367 5368 5369 5370
blockstart : '{'
	{
	    braces_open++;
	    $$ = make_str("{");
	};
5371

Michael Meskes's avatar
Michael Meskes committed
5372 5373 5374 5375 5376
blockend : '}'
	{
	    remove_variables(braces_open--);
	    $$ = make_str("}");
	};
Marc G. Fournier's avatar
Marc G. Fournier committed
5377

5378
%%
5379

5380 5381 5382 5383 5384
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);
5385
}