1 /* Copyright comment */
3 #include "postgres_fe.h"
8 * Variables containing simple states.
11 int braces_open; /* brace level counter */
13 char *connection = NULL;
14 char *input_filename = NULL;
16 static int QueryIsRule = 0, FoundInto = 0;
17 static int initializer = 0;
18 static struct this_type actual_type[STRUCT_DEPTH];
19 static char *actual_storage[STRUCT_DEPTH];
20 static char *actual_startline[STRUCT_DEPTH];
22 /* temporarily store struct members while creating the data structure */
23 struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
25 /* also store struct type so we can do a sizeof() later */
26 static char *ECPGstruct_sizeof = NULL;
28 struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, NULL, {NULL}};
29 struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
31 struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, NULL, {NULL}};
34 * Handle parsing errors and warnings
37 mmerror(int error_code, enum errortype type, char * error)
42 fprintf(stderr, "%s:%d: WARNING: %s\n", input_filename, yylineno, error);
45 fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
46 ret_value = error_code;
49 fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
55 * string concatenation
59 cat2_str(char *str1, char *str2)
61 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
63 strcpy(res_str, str1);
65 strcat(res_str, str2);
72 cat_str(int count, ...)
78 va_start(args, count);
80 res_str = va_arg(args, char *);
82 /* now add all other strings */
83 for (i = 1; i < count; i++)
84 res_str = cat2_str(res_str, va_arg(args, char *));
92 make_str(const char *str)
94 char * res_str = (char *)mm_alloc(strlen(str) + 1);
101 make2_str(char *str1, char *str2)
103 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
105 strcpy(res_str, str1);
106 strcat(res_str, str2);
113 make3_str(char *str1, char *str2, char *str3)
115 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1);
117 strcpy(res_str, str1);
118 strcat(res_str, str2);
119 strcat(res_str, str3);
129 char * name = (char *)mm_alloc(yyleng + 1);
131 strncpy(name, yytext, yyleng);
145 struct this_type type;
146 enum ECPGttype type_enum;
147 enum ECPGdtype dtype_enum;
148 struct fetch_desc descriptor;
151 /* special embedded SQL token */
152 %token SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
153 %token SQL_CALL SQL_CARDINALITY SQL_CONNECT SQL_CONNECTION
154 %token SQL_CONTINUE SQL_COUNT
155 %token SQL_DATA SQL_DATETIME_INTERVAL_CODE SQL_DATETIME_INTERVAL_PRECISION
156 %token SQL_DEALLOCATE SQL_DESCRIPTOR SQL_DISCONNECT SQL_ENUM
157 %token SQL_FOUND SQL_FREE SQL_GET SQL_GO SQL_GOTO
158 %token SQL_IDENTIFIED SQL_INDICATOR SQL_INT SQL_KEY_MEMBER
159 %token SQL_LENGTH SQL_LONG
160 %token SQL_NAME SQL_NULLABLE
161 %token SQL_OCTET_LENGTH SQL_OPEN SQL_PREPARE
162 %token SQL_RELEASE SQL_REFERENCE SQL_RETURNED_LENGTH
163 %token SQL_RETURNED_OCTET_LENGTH
164 %token SQL_SCALE SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL
165 %token SQL_SQLERROR SQL_SQLPRINT
166 %token SQL_SQLWARNING SQL_START SQL_STOP SQL_STRUCT SQL_UNSIGNED
167 %token SQL_VALUE SQL_VAR SQL_WHENEVER
170 %token S_ADD S_AND S_ANYTHING S_AUTO S_CONST S_DEC S_DIV S_DOTPOINT
171 %token S_EQUAL S_EXTERN S_INC S_LSHIFT
172 %token S_MEMPOINT S_MEMBER S_MOD S_MUL S_NEQUAL S_OR
173 %token S_REGISTER S_RSHIFT S_STATIC S_SUB S_VOLATILE
175 /* I need this and don't know where it is defined inside the backend */
178 /* Keywords (in SQL92 reserved words) */
179 %token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC, AT, AUTHORIZATION,
180 BEGIN_TRANS, BETWEEN, BOTH, BY,
181 CASCADE, CASE, CAST, CHAIN, CHAR, CHARACTER,
182 CHARACTERISTICS, CHECK, CLOSE,
183 COALESCE, COLLATE, COLUMN, COMMIT,
184 CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT, CURRENT_DATE,
185 CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
186 DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
187 ELSE, ENCRYPTED, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
188 FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
189 GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
190 IN, INNER_P, INOUT, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
191 ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
192 MATCH, MINUTE_P, MONTH_P, NAMES,
193 NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
194 OF, OFF, OLD, ON, ONLY, OPTION, OR, ORDER, OUT, OUTER_P, OVERLAPS,
195 PARTIAL, PATH_P, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
196 READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
197 SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING,
198 TABLE, TEMPORARY, THEN, TIME, TIMESTAMP
199 TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
200 UNENCRYPTED, UNION, UNIQUE, UNKNOWN, UPDATE, USER, USING,
201 VALUES, VARCHAR, VARYING, VIEW,
202 WHEN, WHERE, WITH, WITHOUT, WORK, YEAR_P, ZONE
204 /* Keywords (in SQL3 reserved words) */
205 %token DEFERRABLE, DEFERRED,
206 IMMEDIATE, INITIALLY,
211 /* Keywords (in SQL92 non-reserved words) */
212 %token COMMITTED, SERIALIZABLE, TYPE_P
214 /* Keywords for Postgres support (not in SQL92 reserved words)
216 * The CREATEDB and CREATEUSER tokens should go away
217 * when some sort of pg_privileges relation is introduced.
218 * - Todd A. Brandys 1998-01-01?
220 %token ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYSE, ANALYZE,
221 BACKWARD, BEFORE, BINARY, BIT, CACHE, CHECKPOINT, CLUSTER,
222 COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE, DATABASE,
223 DELIMITERS, DO, EACH, ENCODING, EXCLUSIVE, EXPLAIN,
224 FORCE, FORWARD, FREEZE, FUNCTION, HANDLER, INCREMENT,
225 INDEX, INHERITS, INSTEAD, ISNULL, LANCOMPILER, LIMIT,
226 LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE,
227 MINVALUE, MODE, MOVE, NEW, NOCREATEDB, NOCREATEUSER,
228 NONE, NOTHING, NOTIFY, NOTNULL, OFFSET, OIDS,
229 OPERATOR, OWNER, PASSWORD, PROCEDURAL, REINDEX, RENAME, RESET,
230 RETURNS, ROW, RULE, SEQUENCE, SETOF, SHARE,
231 SHOW, START, STATEMENT, STATISTICS, STDIN, STDOUT, SYSID TEMP,
232 TEMPLATE, TOAST, TRUNCATE, TRUSTED, UNLISTEN, UNTIL, VACUUM,
233 VALID, VERBOSE, VERSION
235 /* The grammar thinks these are keywords, but they are not in the keywords.c
236 * list and so can never be entered directly. The filter in parser.c
237 * creates these tokens when required.
241 /* Special keywords, not in the query language - see the "lex" file */
242 %token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE IP BITCONST
243 %token <ival> ICONST PARAM
246 /* these are not real. they are here so that they get generated as #define's*/
249 /* precedence: lowest to highest */
252 %left JOIN UNIONJOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
263 %left POSTFIXOP /* dummy for postfix Op rules */
264 %left Op /* multi-character ops and user-defined operators */
267 %nonassoc IS NULL_P TRUE_P FALSE_P UNKNOWN
271 /* Unary Operators */
279 %type <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId
280 %type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt
281 %type <str> key_reference comment_text ConstraintDeferrabilitySpec
282 %type <str> key_match ColLabel SpecialRuleRelation ColId columnDef
283 %type <str> ColConstraint ColConstraintElem drop_type Bitconst
284 %type <str> OptTableElementList OptTableElement TableConstraint
285 %type <str> ConstraintElem key_actions ColQualList type_name DropSchemaStmt
286 %type <str> target_list target_el update_target_list alias_clause
287 %type <str> update_target_el opt_id relation_name database_name
288 %type <str> access_method attr_name class index_name name func_name
289 %type <str> file_name AexprConst ParamNo c_expr ConstTypename
290 %type <str> in_expr_nodes a_expr b_expr TruncateStmt CommentStmt
291 %type <str> opt_indirection expr_list extract_list extract_arg
292 %type <str> position_list substr_list substr_from alter_column_default
293 %type <str> trim_list in_expr substr_for attr attrs drop_behavior
294 %type <str> Typename SimpleTypename Generic Numeric opt_float opt_numeric
295 %type <str> opt_decimal Character character opt_varying opt_charset
296 %type <str> opt_collate opt_timezone opt_interval table_ref
297 %type <str> row_expr row_descriptor row_list ConstDatetime opt_chain
298 %type <str> SelectStmt into_clause OptTemp ConstraintAttributeSpec
299 %type <str> opt_table opt_all sort_clause sortby_list ConstraintAttr
300 %type <str> sortby OptUseOp relation_name_list name_list ColId_or_Sconst
301 %type <str> group_clause having_clause from_clause opt_distinct
302 %type <str> join_outer where_clause relation_expr sub_type opt_arg
303 %type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
304 %type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
305 %type <str> NotifyStmt columnElem copy_dirn UnlistenStmt copy_null
306 %type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
307 %type <str> opt_with_copy FetchStmt direction fetch_how_many from_in
308 %type <str> ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
309 %type <str> opt_full func_arg OptWithOids opt_freeze opt_ecpg_into
310 %type <str> analyze_keyword opt_name_list ExplainStmt index_params
311 %type <str> index_list func_index index_elem opt_class access_method_clause
312 %type <str> index_opt_unique IndexStmt func_return ConstInterval
313 %type <str> func_args_list func_args opt_with ProcedureStmt def_arg
314 %type <str> def_elem def_list definition DefineStmt select_with_parens
315 %type <str> opt_instead event event_object RuleActionList opt_using
316 %type <str> RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type
317 %type <str> RuleStmt opt_column opt_name oper_argtypes NumConst
318 %type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
319 %type <str> RemoveAggrStmt opt_procedural select_no_parens
320 %type <str> RemoveOperStmt RenameStmt all_Op opt_Trusted opt_lancompiler
321 %type <str> VariableSetStmt var_value zone_value VariableShowStmt
322 %type <str> VariableResetStmt AlterTableStmt DropUserStmt from_list
323 %type <str> opt_trans user_list OptUserList OptUserElem
324 %type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
325 %type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
326 %type <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
327 %type <str> TriggerActionTime CreateTrigStmt DropPLangStmt
328 %type <str> CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
329 %type <str> ViewStmt LoadStmt CreatedbStmt createdb_opt_item
330 %type <str> createdb_opt_list opt_encoding OptInherit
331 %type <str> DropdbStmt ClusterStmt grantee RevokeStmt Bit bit
332 %type <str> GrantStmt privileges operation_commalist operation PosAllConst
333 %type <str> opt_with_grant opt_cursor ConstraintsSetStmt AllConst
334 %type <str> case_expr when_clause_list case_default case_arg when_clause
335 %type <str> select_clause opt_select_limit select_limit_value ConstraintTimeSpec
336 %type <str> select_offset_value ReindexStmt join_type opt_boolean
337 %type <str> join_qual update_list AlterSchemaStmt joined_table
338 %type <str> opt_level opt_lock lock_type OptGroupList OptGroupElem
339 %type <str> OptConstrFromTable OptTempTableName StringConst
340 %type <str> constraints_set_list constraints_set_namelist
341 %type <str> constraints_set_mode comment_type opt_empty_parentheses
342 %type <str> CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
343 %type <str> opt_force key_update CreateSchemaStmt PosIntStringConst
344 %type <str> IntConst PosIntConst grantee_list func_type opt_or_replace
345 %type <str> select_limit opt_for_update_clause CheckPointStmt
347 %type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen
348 %type <str> indicator ECPGExecute ECPGPrepare ecpg_using ecpg_into
349 %type <str> storage_clause opt_initializer c_anything blockstart
350 %type <str> blockend variable_list variable c_thing c_term
351 %type <str> opt_pointer ECPGDisconnect dis_name storage_modifier
352 %type <str> stmt ECPGRelease execstring server_name
353 %type <str> connection_object opt_server opt_port c_stuff opt_reference
354 %type <str> user_name opt_user char_variable ora_user ident
355 %type <str> quoted_ident_stringvar
356 %type <str> db_prefix server opt_options opt_connection_name c_list
357 %type <str> ECPGSetConnection cpp_line ECPGTypedef c_args ECPGKeywords
358 %type <str> enum_type civar civarind ECPGCursorStmt ECPGDeallocate
359 %type <str> ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
360 %type <str> struct_type s_struct declaration declarations variable_declarations
361 %type <str> s_union union_type ECPGSetAutocommit on_off
362 %type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol
363 %type <str> ECPGGetDescriptorHeader ECPGColLabel
364 %type <str> reserved_keyword unreserved_keyword
365 %type <str> col_name_keyword func_name_keyword
366 %type <str> ECPGTypeName variablelist cvariable
368 %type <descriptor> ECPGGetDescriptor
370 %type <type_enum> simple_type signed_type unsigned_type
372 %type <dtype_enum> descriptor_item desc_header_item
376 %type <action> action
378 %type <index> opt_array_bounds opt_type_array_bounds
382 %token YYERROR_VERBOSE
386 statements: /* empty */
387 | statements statement
389 statement: ecpgstart opt_at stmt ';' { connection = NULL; }
392 | c_thing { fprintf(yyout, "%s", $1); free($1); }
393 | cpp_line { fprintf(yyout, "%s", $1); free($1); }
394 | blockstart { fputs($1, yyout); free($1); }
395 | blockend { fputs($1, yyout); free($1); }
398 opt_at: AT connection_target {
401 if we have a variable as connection
402 target, remove it from the variable
403 list or else it will be used twice
405 if (argsinsert != NULL)
409 stmt: AlterSchemaStmt { output_statement($1, 0, connection); }
410 | AlterTableStmt { output_statement($1, 0, connection); }
411 | AlterGroupStmt { output_statement($1, 0, connection); }
412 | AlterUserStmt { output_statement($1, 0, connection); }
413 | ClosePortalStmt { output_statement($1, 0, connection); }
414 | CommentStmt { output_statement($1, 0, connection); }
415 | CopyStmt { output_statement($1, 0, connection); }
416 | CreateStmt { output_statement($1, 0, connection); }
417 | CreateAsStmt { output_statement($1, 0, connection); }
418 | CreateSchemaStmt { output_statement($1, 0, connection); }
419 | CreateGroupStmt { output_statement($1, 0, connection); }
420 | CreateSeqStmt { output_statement($1, 0, connection); }
421 | CreatePLangStmt { output_statement($1, 0, connection); }
422 | CreateTrigStmt { output_statement($1, 0, connection); }
423 | CreateUserStmt { output_statement($1, 0, connection); }
424 | ClusterStmt { output_statement($1, 0, connection); }
425 | DefineStmt { output_statement($1, 0, connection); }
426 | DropStmt { output_statement($1, 0, connection); }
427 | DropSchemaStmt { output_statement($1, 0, connection); }
428 | TruncateStmt { output_statement($1, 0, connection); }
429 | DropGroupStmt { output_statement($1, 0, connection); }
430 | DropPLangStmt { output_statement($1, 0, connection); }
431 | DropTrigStmt { output_statement($1, 0, connection); }
432 | DropUserStmt { output_statement($1, 0, connection); }
433 | ExplainStmt { output_statement($1, 0, connection); }
434 | FetchStmt { output_statement($1, 1, connection); }
435 | GrantStmt { output_statement($1, 0, connection); }
436 | IndexStmt { output_statement($1, 0, connection); }
437 | ListenStmt { output_statement($1, 0, connection); }
438 | UnlistenStmt { output_statement($1, 0, connection); }
439 | LockStmt { output_statement($1, 0, connection); }
440 | NotifyStmt { output_statement($1, 0, connection); }
441 | ProcedureStmt { output_statement($1, 0, connection); }
442 | ReindexStmt { output_statement($1, 0, connection); }
443 | RemoveAggrStmt { output_statement($1, 0, connection); }
444 | RemoveOperStmt { output_statement($1, 0, connection); }
445 | RemoveFuncStmt { output_statement($1, 0, connection); }
446 | RenameStmt { output_statement($1, 0, connection); }
447 | RevokeStmt { output_statement($1, 0, connection); }
449 if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
450 output_simple_statement($1);
452 output_statement($1, 1, connection);
454 | RuleStmt { output_statement($1, 0, connection); }
456 fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
460 | ViewStmt { output_statement($1, 0, connection); }
461 | LoadStmt { output_statement($1, 0, connection); }
462 | CreatedbStmt { output_statement($1, 0, connection); }
463 | DropdbStmt { output_statement($1, 0, connection); }
464 | VacuumStmt { output_statement($1, 0, connection); }
465 | AnalyzeStmt { output_statement($1, 0, connection); }
466 | VariableSetStmt { output_statement($1, 0, connection); }
467 | VariableShowStmt { output_statement($1, 0, connection); }
468 | VariableResetStmt { output_statement($1, 0, connection); }
469 | ConstraintsSetStmt { output_statement($1, 0, connection); }
470 | CheckPointStmt { output_statement($1, 0, connection); }
471 | ECPGAllocateDescr { fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
477 mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement.\n");
479 fprintf(yyout, "{ ECPGconnect(__LINE__, %s, %d); ", $1, autocommit);
487 output_simple_statement($1);
491 mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement.\n");
498 | ECPGDeallocateDescr { fprintf(yyout,"ECPGdeallocate_desc(__LINE__, %s);",$1);
503 output_simple_statement($1);
507 mmerror(PARSE_ERROR, ET_ERROR, "no at option for disconnect statement.\n");
509 fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);", $1);
513 | ECPGExecute { output_statement($1, 0, connection); }
515 fprintf(yyout, "{ ECPGdeallocate(__LINE__, \"%s\");", $1);
520 | ECPGGetDescriptor {
521 lookup_descriptor($1.name, connection);
522 output_get_descr($1.name, $1.str);
526 | ECPGGetDescriptorHeader {
527 lookup_descriptor($1, connection);
528 output_get_descr_header($1);
535 for (ptr = cur; ptr != NULL; ptr=ptr->next)
537 if (strcmp(ptr->name, $1) == 0)
543 sprintf(errortext, "trying to open undeclared cursor %s\n", $1);
544 mmerror(PARSE_ERROR, ET_ERROR, errortext);
547 /* merge variables given in prepare statement with those given here */
548 for (p = ptr->argsinsert; p; p = p->next)
549 append_variable(&argsinsert, p->variable, p->indicator);
551 for (p = ptr->argsresult; p; p = p->next)
552 add_variable(&argsresult, p->variable, p->indicator);
554 output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL);
558 mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement.\n");
560 fprintf(yyout, "{ ECPGprepare(__LINE__, %s);", $1);
564 | ECPGRelease { /* output already done */ }
565 | ECPGSetAutocommit {
566 fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
570 | ECPGSetConnection {
572 mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement.\n");
574 fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
580 mmerror(PARSE_ERROR, ET_ERROR, "no at option for typedef statement.\n");
582 output_simple_statement($1);
586 mmerror(PARSE_ERROR, ET_ERROR, "no at option for var statement.\n");
588 output_simple_statement($1);
592 mmerror(PARSE_ERROR, ET_ERROR, "no at option for whenever statement.\n");
594 output_simple_statement($1);
600 * We start with a lot of stuff that's very similar to the backend's parsing
603 /*****************************************************************************
605 * Create a new Postgres DBMS user
608 *****************************************************************************/
610 CreateUserStmt: CREATE USER UserId OptUserList
612 $$ = cat_str(3, make_str("create user"), $3, $4);
614 | CREATE USER UserId WITH OptUserList
616 $$ = cat_str(4, make_str("create user"), $3, make_str("with"), $5);
620 /*****************************************************************************
622 * Alter a postgresql DBMS user
625 *****************************************************************************/
627 AlterUserStmt: ALTER USER UserId OptUserList
629 $$ = cat_str(3, make_str("alter user"), $3, $4);
631 | ALTER USER UserId WITH OptUserList
633 $$ = cat_str(4, make_str("alter user"), $3, make_str("with"), $5);
637 /*****************************************************************************
639 * Drop a postgresql DBMS user
642 *****************************************************************************/
644 DropUserStmt: DROP USER user_list
646 $$ = cat2_str(make_str("drop user"), $3);
651 * Options for CREATE USER and ALTER USER
653 OptUserList: OptUserList OptUserElem { $$ = cat2_str($1, $2); }
654 | /* EMPTY */ { $$ = EMPTY; }
657 OptUserElem: PASSWORD Sconst
659 $$ = cat2_str(make_str("password"), $2);
663 $$ = cat2_str(make_str("sysid"), $2);
667 $$ = make_str("createdb");
671 $$ = make_str("nocreatedb");
675 $$ = make_str("createuser");
679 $$ = make_str("nocreateuser");
683 $$ = cat2_str(make_str("in group"), $3);
687 $$ = cat2_str(make_str("valid until"), $3);
691 user_list: user_list ',' UserId
693 $$ = cat_str(3, $1, make_str(","), $3);
702 /*****************************************************************************
704 * Create a postgresql group
707 ****************************************************************************/
708 CreateGroupStmt: CREATE GROUP UserId OptGroupList
710 $$ = cat_str(3, make_str("create group"), $3, $4);
712 | CREATE GROUP UserId WITH OptGroupList
714 $$ = cat_str(4, make_str("create group"), $3, make_str("with"), $5);
719 * Options for CREATE GROUP
721 OptGroupList: OptGroupList OptGroupElem { $$ = cat2_str($1, $2); }
722 | /* EMPTY */ { $$ = EMPTY; }
725 OptGroupElem: USER user_list
727 $$ = cat2_str(make_str("user"), $2);
731 $$ = cat2_str(make_str("sysid"), $2);
736 /*****************************************************************************
738 * Alter a postgresql group
741 *****************************************************************************/
742 AlterGroupStmt: ALTER GROUP UserId ADD USER user_list
744 $$ = cat_str(4, make_str("alter group"), $3, make_str("add user"), $6);
746 | ALTER GROUP UserId DROP USER user_list
748 $$ = cat_str(4, make_str("alter group"), $3, make_str("drop user"), $6);
752 /*****************************************************************************
754 * Drop a postgresql group
757 *****************************************************************************/
758 DropGroupStmt: DROP GROUP UserId
760 $$ = cat2_str(make_str("drop group"), $3);
764 /*****************************************************************************
766 * Manipulate a schema
769 *****************************************************************************/
771 CreateSchemaStmt: CREATE SCHEMA UserId
773 $$ = cat2_str(make_str("create scheme"), $3);
777 AlterSchemaStmt: ALTER SCHEMA UserId
779 $$ = cat2_str(make_str("alter scheme"), $3);
783 DropSchemaStmt: DROP SCHEMA UserId
785 $$ = cat2_str(make_str("drop scheme"), $3);
789 /*****************************************************************************
791 * Set PG internal variable
792 * SET name TO 'var_value'
793 * Include SQL92 syntax (thomas 1997-10-22):
794 * SET TIME ZONE 'var_value'
796 *****************************************************************************/
798 VariableSetStmt: SET ColId TO var_value
800 $$ = cat_str(4, make_str("set"), $2, make_str("to"), $4);
802 | SET ColId '=' var_value
804 $$ = cat_str(4, make_str("set"), $2, make_str("="), $4);
806 | SET TIME ZONE zone_value
808 $$ = cat2_str(make_str("set time zone"), $4);
810 | SET TRANSACTION ISOLATION LEVEL opt_level
812 $$ = cat2_str(make_str("set transaction isolation level"), $5);
814 | SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL opt_level
816 $$ = cat2_str(make_str("set session characteristics as transaction isolation level"), $8);
818 | SET NAMES opt_encoding
820 $$ = cat2_str(make_str("set names"), $3);
822 | SET SESSION AUTHORIZATION ColId_or_Sconst
824 $$ = cat2_str(make_str("set session authorization"), $4);
828 opt_level: READ COMMITTED { $$ = make_str("read committed"); }
829 | SERIALIZABLE { $$ = make_str("serializable"); }
833 var_value: opt_boolean { $$ = $1; }
834 | AllConst { $$ = $1; }
837 mmerror(PARSE_ERROR, ET_ERROR, "SET must have at least one argument.");
841 | DEFAULT { $$ = make_str("default"); }
844 opt_boolean: TRUE_P { $$ = make_str("true"); }
845 | FALSE_P { $$ = make_str("false"); }
846 | ON { $$ = make_str("on"); }
847 | OFF { $$ = make_str("off"); }
850 /* Timezone values can be:
851 * - a string such as 'pst8pdt'
852 * - an integer or floating point number
853 * - a time interval per SQL99
855 zone_value: AllConst { $$ = $1; }
856 | ConstInterval StringConst opt_interval
858 $$ = cat_str(3, $1, $2, $3);
860 | ConstInterval '(' PosIntConst ')' StringConst opt_interval
862 $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6);
864 | DEFAULT { $$ = make_str("default"); }
865 | LOCAL { $$ = make_str("local"); }
868 opt_encoding: StringConst { $$ = $1; }
869 | DEFAULT { $$ = make_str("default"); }
870 | /*EMPTY*/ { $$ = EMPTY; }
873 ColId_or_Sconst: ColId { $$ = $1; }
874 | StringConst { $$ = $1; }
877 VariableShowStmt: SHOW ColId
879 $$ = cat2_str(make_str("show"), $2);
883 $$ = make_str("show time zone");
887 $$ = make_str("show all");
889 | SHOW TRANSACTION ISOLATION LEVEL
891 $$ = make_str("show transaction isolation level");
895 VariableResetStmt: RESET ColId
897 $$ = cat2_str(make_str("reset"), $2);
901 $$ = make_str("reset time zone");
903 | RESET TRANSACTION ISOLATION LEVEL
905 $$ = make_str("reset transaction isolation level");
909 $$ = make_str("reset all");
913 ConstraintsSetStmt: SET CONSTRAINTS constraints_set_list constraints_set_mode
915 $$ = cat_str(3, make_str("set constraints"), $3, $4);
919 constraints_set_list: ALL
921 $$ = make_str("all");
923 | constraints_set_namelist
930 constraints_set_namelist: ColId
934 | constraints_set_namelist ',' ColId
936 $$ = cat_str(3, $1, make_str(","), $3);
940 constraints_set_mode: DEFERRED
942 $$ = make_str("deferred");
946 $$ = make_str("immediate");
951 * Checkpoint statement
953 CheckPointStmt: CHECKPOINT { $$= make_str("checkpoint"); }
957 /*****************************************************************************
959 * ALTER TABLE variations
961 *****************************************************************************/
964 /* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
965 ALTER TABLE relation_expr ADD opt_column columnDef
967 $$ = cat_str(5, make_str("alter table"), $3, make_str("add"), $5, $6);
969 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
970 | ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default
972 $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, $7);
974 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <Iconst> */
975 | ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS Iconst
977 $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set statistics"), $9);
979 /* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
980 | ALTER TABLE relation_expr DROP opt_column ColId drop_behavior
982 $$ = cat_str(6, make_str("alter table"), $3, make_str("drop"), $5, $6, $7);
984 /* ALTER TABLE <relation> ADD CONSTRAINT ... */
985 | ALTER TABLE relation_expr ADD TableConstraint
987 $$ = cat_str(4, make_str("alter table"), $3, make_str("add"), $5);
989 /* ALTER TABLE <relation> DROP CONSTRAINT ... */
990 | ALTER TABLE relation_expr DROP CONSTRAINT name drop_behavior
992 $$ = cat_str(5, make_str("alter table"), $3, make_str("drop constraint"), $6, $7);
994 /* ALTER TABLE <name> OWNER TO UserId */
995 | ALTER TABLE relation_name OWNER TO UserId
997 $$ = cat_str(4, make_str("alter table"), $3, make_str("owner to"), $6);
1001 alter_column_default:
1002 SET DEFAULT a_expr { $$ = cat2_str(make_str("set default"), $3); }
1003 | DROP DEFAULT { $$ = make_str("drop default"); }
1006 drop_behavior: CASCADE { $$ = make_str("cascade"); }
1007 | RESTRICT { $$ = make_str("restrict"); }
1010 /*****************************************************************************
1015 *****************************************************************************/
1017 ClosePortalStmt: CLOSE opt_id
1019 $$ = cat2_str(make_str("close"), $2);
1023 opt_id: ColId { $$ = $1; }
1024 | /*EMPTY*/ { $$ = NULL; }
1027 /*****************************************************************************
1030 * COPY [BINARY] <relname> FROM/TO
1031 * [USING DELIMITERS <delimiter>]
1033 *****************************************************************************/
1035 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
1037 $$ = cat_str(8, make_str("copy"), $2, $3, $4, $5, $6, $7, $8);
1042 { $$ = make_str("to"); }
1044 { $$ = make_str("from"); }
1048 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
1049 * used depends on the direction. (It really doesn't make sense to copy from
1050 * stdout. We silently correct the "typo". - AY 9/94
1052 copy_file_name: StringConst { $$ = $1; }
1053 | STDIN { $$ = make_str("stdin"); }
1054 | STDOUT { $$ = make_str("stdout"); }
1057 opt_binary: BINARY { $$ = make_str("binary"); }
1058 | /*EMPTY*/ { $$ = EMPTY; }
1061 opt_with_copy: WITH OIDS { $$ = make_str("with oids"); }
1062 | /*EMPTY*/ { $$ = EMPTY; }
1066 * the default copy delimiter is tab but the user can configure it
1068 copy_delimiter: opt_using DELIMITERS StringConst { $$ = cat_str(3, $1, make_str("delimiters"), $3); }
1069 | /*EMPTY*/ { $$ = EMPTY; }
1072 opt_using: USING { $$ = make_str("using"); }
1073 | /* EMPTY */ { $$ = EMPTY; }
1076 copy_null: WITH NULL_P AS StringConst { $$ = cat2_str(make_str("with null as"), $4); }
1077 | /* EMPTY */ { $$ = EMPTY; }
1080 /*****************************************************************************
1085 *****************************************************************************/
1087 CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
1088 OptInherit OptWithOids
1090 $$ = cat_str(9, make_str("create"), $2, make_str("table"), $4, make_str("("), $6, make_str(")"), $8, $9);
1095 * Redundancy here is needed to avoid shift/reduce conflicts,
1096 * since TEMP is not a reserved word. See also OptTempTableName.
1099 OptTemp: TEMPORARY { $$ = make_str("temporary"); }
1100 | TEMP { $$ = make_str("temp"); }
1101 | LOCAL TEMPORARY { $$ = make_str("local temporary"); }
1102 | LOCAL TEMP { $$ = make_str("local temp"); }
1103 | GLOBAL TEMPORARY {
1104 mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
1105 $$ = make_str("global temporary");
1108 mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
1109 $$ = make_str("global temp");
1111 | /*EMPTY*/ { $$ = EMPTY; }
1114 OptTableElementList: OptTableElementList ',' OptTableElement
1116 $$ = cat_str(3, $1, make_str(","), $3);
1122 | /*EMPTY*/ { $$ = EMPTY; }
1125 OptTableElement: columnDef { $$ = $1; }
1126 | TableConstraint { $$ = $1; }
1129 columnDef: ColId Typename ColQualList opt_collate
1133 sprintf(errortext, "Currently unsupported CREATE TABLE / COLLATE %s will be passed to backend", $4);
1134 mmerror(PARSE_ERROR, ET_NOTICE, errortext);
1136 $$ = cat_str(4, $1, $2, $3, $4);
1140 ColQualList: ColQualList ColConstraint { $$ = cat2_str($1,$2); }
1141 | /*EMPTY*/ { $$ = EMPTY; }
1144 ColConstraint: CONSTRAINT name ColConstraintElem
1146 $$ = cat_str(3, make_str("constraint"), $2, $3);
1154 /* DEFAULT NULL is already the default for Postgres.
1155 * But define it here and carry it forward into the system
1156 * to make it explicit.
1157 * - thomas 1998-09-13
1159 * WITH NULL and NULL are not SQL92-standard syntax elements,
1160 * so leave them out. Use DEFAULT NULL to explicitly indicate
1161 * that a column may have that value. WITH NULL leads to
1162 * shift/reduce conflicts with WITH TIME ZONE anyway.
1163 * - thomas 1999-01-08
1165 ColConstraintElem: NOT NULL_P
1167 $$ = make_str("not null");
1171 $$ = make_str("null");
1175 $$ = make_str("unique");
1179 $$ = make_str("primary key");
1181 | CHECK '(' a_expr ')'
1183 $$ = cat_str(3, make_str("check ("), $3, make_str(")"));
1187 $$ = cat2_str(make_str("default"), $2);
1189 | REFERENCES ColId opt_column_list key_match key_actions
1191 $$ = cat_str(5, make_str("references"), $2, $3, $4, $5);
1196 * ConstraintAttr represents constraint attributes, which we parse as if
1197 * they were independent constraint clauses, in order to avoid shift/reduce
1198 * conflicts (since NOT might start either an independent NOT NULL clause
1199 * or an attribute). analyze.c is responsible for attaching the attribute
1200 * information to the preceding "real" constraint node, and for complaining
1201 * if attribute clauses appear in the wrong place or wrong combinations.
1203 * See also ConstraintAttributeSpec, which can be used in places where
1204 * there is no parsing conflict.
1206 ConstraintAttr: DEFERRABLE { $$ = make_str("deferrable"); }
1207 | NOT DEFERRABLE { $$ = make_str("not deferrable"); }
1208 | INITIALLY DEFERRED { $$ = make_str("initially deferred"); }
1209 | INITIALLY IMMEDIATE { $$ = make_str("initially immediate"); }
1212 /* ConstraintElem specifies constraint syntax which is not embedded into
1213 * a column definition. ColConstraintElem specifies the embedded form.
1214 * - thomas 1997-12-03
1216 TableConstraint: CONSTRAINT name ConstraintElem
1218 $$ = cat_str(3, make_str("constraint"), $2, $3);
1224 ConstraintElem: CHECK '(' a_expr ')'
1226 $$ = cat_str(3, make_str("check("), $3, make_str(")"));
1228 | UNIQUE '(' columnList ')'
1230 $$ = cat_str(3, make_str("unique("), $3, make_str(")"));
1232 | PRIMARY KEY '(' columnList ')'
1234 $$ = cat_str(3, make_str("primary key("), $4, make_str(")"));
1236 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list
1237 key_match key_actions ConstraintAttributeSpec
1239 $$ = cat_str(8, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10, $11);
1243 key_match: MATCH FULL
1245 $$ = make_str("match full");
1249 mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported FOREIGN KEY/MATCH PARTIAL will be passed to backend");
1250 $$ = make_str("match partial");
1258 key_actions: key_delete { $$ = $1; }
1259 | key_update { $$ = $1; }
1260 | key_delete key_update { $$ = cat2_str($1, $2); }
1261 | key_update key_delete { $$ = cat2_str($1, $2); }
1262 | /*EMPTY*/ { $$ = EMPTY; }
1265 key_delete: ON DELETE key_reference { $$ = cat2_str(make_str("on delete"), $3); }
1267 key_update: ON UPDATE key_reference { $$ = cat2_str(make_str("on update"), $3); }
1269 key_reference: NO ACTION { $$ = make_str("no action"); }
1270 | RESTRICT { $$ = make_str("restrict"); }
1271 | CASCADE { $$ = make_str("cascade"); }
1272 | SET DEFAULT { $$ = make_str("set default"); }
1273 | SET NULL_P { $$ = make_str("set null"); }
1276 OptInherit: INHERITS '(' relation_name_list ')' { $$ = cat_str(3, make_str("inherits ("), $3, make_str(")")); }
1277 | /*EMPTY*/ { $$ = EMPTY; }
1280 OptWithOids: WITH OIDS { $$ = make_str("with oids"); }
1281 | WITHOUT OIDS { $$ = make_str("without oids"); }
1282 | /*EMPTY*/ { $$ = EMPTY; }
1287 * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
1291 CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS
1292 { FoundInto = 0; } SelectStmt
1295 mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE / AS SELECT may not specify INTO");
1297 $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4, $5, make_str("as"), $8);
1301 OptCreateAs: '(' CreateAsList ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1302 | /*EMPTY*/ { $$ = EMPTY; }
1305 CreateAsList: CreateAsList ',' CreateAsElement { $$ = cat_str(3, $1, make_str(","), $3); }
1306 | CreateAsElement { $$ = $1; }
1309 CreateAsElement: ColId { $$ = $1; }
1312 /*****************************************************************************
1315 * CREATE SEQUENCE seqname
1317 *****************************************************************************/
1319 CreateSeqStmt: CREATE OptTemp SEQUENCE relation_name OptSeqList
1321 $$ = cat_str(4, make_str("create sequence"), $2, $4, $5);
1325 OptSeqList: OptSeqList OptSeqElem
1326 { $$ = cat2_str($1, $2); }
1330 OptSeqElem: CACHE NumConst
1332 $$ = cat2_str(make_str("cache"), $2);
1336 $$ = make_str("cycle");
1338 | INCREMENT NumConst
1340 $$ = cat2_str(make_str("increment"), $2);
1344 $$ = cat2_str(make_str("maxvalue"), $2);
1348 $$ = cat2_str(make_str("minvalue"), $2);
1352 $$ = cat2_str(make_str("start"), $2);
1356 /*****************************************************************************
1359 * CREATE PROCEDURAL LANGUAGE ...
1360 * DROP PROCEDURAL LANGUAGE ...
1362 *****************************************************************************/
1364 CreatePLangStmt: CREATE opt_Trusted opt_procedural LANGUAGE ColId_or_Sconst
1365 HANDLER func_name opt_lancompiler
1367 $$ = cat_str(8, make_str("create"), $2, $3, make_str("language"), $5, make_str("handler"), $7, $8);
1371 opt_Trusted: TRUSTED { $$ = make_str("trusted"); }
1375 opt_lancompiler: LANCOMPILER StringConst { $$ = cat2_str(make_str("lancompiler"), $2); }
1376 | /*EMPTY*/ { $$ = ""; }
1379 DropPLangStmt: DROP opt_procedural LANGUAGE StringConst
1381 $$ = cat_str(4, make_str("drop"), $2, make_str("language"), $4);
1385 opt_procedural: PROCEDURAL { $$ = make_str("prcedural"); }
1386 | /*EMPTY*/ { $$ = EMPTY; }
1389 /*****************************************************************************
1392 * CREATE TRIGGER ...
1395 *****************************************************************************/
1397 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1398 relation_name TriggerForSpec EXECUTE PROCEDURE
1399 name '(' TriggerFuncArgs ')'
1401 $$ = 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(")"));
1403 | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
1404 relation_name OptConstrFromTable
1405 ConstraintAttributeSpec
1406 FOR EACH ROW EXECUTE PROCEDURE
1407 name '(' TriggerFuncArgs ')'
1409 $$ = 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(")"));
1413 TriggerActionTime: BEFORE { $$ = make_str("before"); }
1414 | AFTER { $$ = make_str("after"); }
1417 TriggerEvents: TriggerOneEvent
1421 | TriggerOneEvent OR TriggerOneEvent
1423 $$ = cat_str(3, $1, make_str("or"), $3);
1425 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1427 $$ = cat_str(5, $1, make_str("or"), $3, make_str("or"), $5);
1431 TriggerOneEvent: INSERT { $$ = make_str("insert"); }
1432 | DELETE { $$ = make_str("delete"); }
1433 | UPDATE { $$ = make_str("update"); }
1436 TriggerForSpec: FOR TriggerForOpt TriggerForType
1438 $$ = cat_str(3, make_str("for"), $2, $3);
1442 TriggerForOpt: EACH { $$ = make_str("each"); }
1443 | /*EMPTY*/ { $$ = EMPTY; }
1446 TriggerForType: ROW { $$ = make_str("row"); }
1447 | STATEMENT { $$ = make_str("statement"); }
1450 TriggerFuncArgs: TriggerFuncArg
1452 | TriggerFuncArgs ',' TriggerFuncArg
1453 { $$ = cat_str(3, $1, make_str(","), $3); }
1458 TriggerFuncArg: PosAllConst
1462 | ColId { $$ = $1; }
1465 OptConstrFromTable: /* Empty */
1469 | FROM relation_name
1471 $$ = cat2_str(make_str("from"), $2);
1475 ConstraintAttributeSpec: ConstraintDeferrabilitySpec
1477 | ConstraintDeferrabilitySpec ConstraintTimeSpec
1479 if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 )
1480 mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
1482 $$ = cat2_str($1, $2);
1484 | ConstraintTimeSpec
1486 | ConstraintTimeSpec ConstraintDeferrabilitySpec
1488 if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
1489 mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
1491 $$ = cat2_str($1, $2);
1495 ConstraintDeferrabilitySpec: NOT DEFERRABLE { $$ = make_str("not deferrable"); }
1496 | DEFERRABLE { $$ = make_str("deferrable"); }
1499 ConstraintTimeSpec: INITIALLY IMMEDIATE { $$ = make_str("initially immediate"); }
1500 | INITIALLY DEFERRED { $$ = make_str("initially deferred"); }
1503 DropTrigStmt: DROP TRIGGER name ON relation_name
1505 $$ = cat_str(4, make_str("drop trigger"), $3, make_str("on"), $5);
1509 /*****************************************************************************
1512 * define (type,operator,aggregate)
1514 *****************************************************************************/
1516 DefineStmt: CREATE AGGREGATE func_name definition
1518 $$ = cat_str(3, make_str("create aggregate"), $3, $4);
1520 | CREATE OPERATOR all_Op definition
1522 $$ = cat_str(3, make_str("create operator"), $3, $4);
1524 | CREATE TYPE_P name definition
1526 $$ = cat_str(3, make_str("create type"), $3, $4);
1530 definition: '(' def_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1533 def_list: def_elem { $$ = $1; }
1534 | def_list ',' def_elem { $$ = cat_str(3, $1, make_str(","), $3); }
1537 def_elem: ColLabel '=' def_arg {
1538 $$ = cat_str(3, $1, make_str("="), $3);
1546 /* Note: any simple identifier will be returned as a type name! */
1547 def_arg: func_return { $$ = $1; }
1548 | all_Op { $$ = $1; }
1549 | AllConst { $$ = $1; }
1552 /*****************************************************************************
1556 * DROP itemtype itemname [, itemname ...]
1558 *****************************************************************************/
1560 DropStmt: DROP drop_type relation_name_list
1562 $$ = cat_str(3, make_str("drop"), $2, $3);
1566 drop_type: TABLE { $$ = make_str("table"); }
1567 | SEQUENCE { $$ = make_str("sequence"); }
1568 | VIEW { $$ = make_str("view"); }
1569 | INDEX { $$ = make_str("index"); }
1570 | RULE { $$ = make_str("rule"); }
1571 | TYPE_P { $$ = make_str("type"); }
1574 /*****************************************************************************
1577 * truncate table relname
1579 *****************************************************************************/
1580 TruncateStmt: TRUNCATE opt_table relation_name
1582 $$ = cat2_str(make_str("truncate table"), $3);
1586 /*****************************************************************************
1589 * fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
1590 * fetch [ forward | backward | absolute | relative ]
1591 * [ # | all | next | prior ] [ [ in | from ] <portalname> ]
1593 *****************************************************************************/
1595 FetchStmt: FETCH direction fetch_how_many from_in name ecpg_into
1597 if (strcmp($2, "relative") == 0 && atol($3) == 0L)
1598 mmerror(PARSE_ERROR, ET_ERROR, "FETCH/RELATIVE at current position is not supported");
1600 $$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5);
1602 | FETCH fetch_how_many from_in name ecpg_into
1604 $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
1606 | FETCH direction from_in name ecpg_into
1608 $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
1610 | FETCH from_in name ecpg_into
1612 $$ = cat_str(3, make_str("fetch"), $2, $3);
1614 | FETCH name ecpg_into
1616 $$ = cat2_str(make_str("fetch"), $2);
1618 | MOVE direction fetch_how_many from_in name
1620 $$ = cat_str(5, make_str("move"), $2, $3, $4, $5);
1622 | MOVE fetch_how_many from_in name
1624 $$ = cat_str(4, make_str("move"), $2, $3, $4);
1626 | MOVE direction from_in name
1628 $$ = cat_str(4, make_str("move"), $2, $3, $4);
1632 $$ = cat_str(3, make_str("move"), $2, $3);
1636 $$ = cat2_str(make_str("move"), $2);
1640 direction: FORWARD { $$ = make_str("forward"); }
1641 | BACKWARD { $$ = make_str("backward"); }
1642 | RELATIVE { $$ = make_str("relative"); }
1644 mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported FETCH/ABSOLUTE will be passed to backend, backend will use RELATIVE");
1645 $$ = make_str("absolute");
1649 fetch_how_many: IntConst { $$ = $1; }
1650 | ALL { $$ = make_str("all"); }
1651 | NEXT { $$ = make_str("next"); }
1652 | PRIOR { $$ = make_str("prior"); }
1655 from_in: IN { $$ = make_str("in"); }
1656 | FROM { $$ = make_str("from"); }
1659 /*****************************************************************************
1661 * The COMMENT ON statement can take different forms based upon the type of
1662 * the object associated with the comment. The form of the statement is:
1664 * COMMENT ON [ [ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ]
1665 * <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION
1666 * <funcname> (arg1, arg2, ...) | OPERATOR <op>
1667 * (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
1668 * <relname> ] IS 'text'
1670 *****************************************************************************/
1671 CommentStmt: COMMENT ON comment_type name IS comment_text
1673 $$ = cat_str(5, make_str("comment on"), $3, $4, make_str("is"), $6);
1675 | COMMENT ON COLUMN relation_name '.' attr_name IS comment_text
1677 $$ = cat_str(6, make_str("comment on column"), $4, make_str("."), $6, make_str("is"), $8);
1679 | COMMENT ON AGGREGATE name '(' aggr_argtype ')' IS comment_text
1681 $$ = cat_str(6, make_str("comment on aggregate"), $4, make_str("("), $6, make_str(") is"), $9);
1683 | COMMENT ON AGGREGATE name aggr_argtype IS comment_text
1685 $$ = cat_str(5, make_str("comment on aggregate"), $4, $5, make_str("is"), $7);
1687 | COMMENT ON FUNCTION func_name func_args IS comment_text
1689 $$ = cat_str(5, make_str("comment on function"), $4, $5, make_str("is"), $7);
1691 | COMMENT ON OPERATOR all_Op '(' oper_argtypes ')' IS comment_text
1693 $$ = cat_str(6, make_str("comment on operator"), $4, make_str("("), $6, make_str(") is"), $9);
1695 | COMMENT ON TRIGGER name ON relation_name IS comment_text
1697 $$ = cat_str(6, make_str("comment on trigger"), $4, make_str("on"), $6, make_str("is"), $8);
1701 comment_type: DATABASE { $$ = make_str("database"); }
1702 | INDEX { $$ = make_str("idnex"); }
1703 | RULE { $$ = make_str("rule"); }
1704 | SEQUENCE { $$ = make_str("sequence"); }
1705 | TABLE { $$ = make_str("table"); }
1706 | TYPE_P { $$ = make_str("type"); }
1707 | VIEW { $$ = make_str("view"); }
1710 comment_text: StringConst { $$ = $1; }
1711 | NULL_P { $$ = make_str("null"); }
1714 /*****************************************************************************
1717 * GRANT [privileges] ON [TABLE] relation_name_list TO [GROUP] grantee, ...
1719 *****************************************************************************/
1721 GrantStmt: GRANT privileges ON opt_table relation_name_list TO grantee_list opt_with_grant
1723 $$ = cat_str(8, make_str("grant"), $2, make_str("on"), $4, $5, make_str("to"), $7, $8);
1727 privileges: ALL PRIVILEGES
1729 $$ = make_str("all privileges");
1733 $$ = make_str("all");
1735 | operation_commalist
1741 operation_commalist: operation
1745 | operation_commalist ',' operation
1747 $$ = cat_str(3, $1, make_str(","), $3);
1753 $$ = make_str("select");
1757 $$ = make_str("insert");
1761 $$ = make_str("update");
1765 $$ = make_str("delete");
1769 $$ = make_str("rule");
1773 $$ = make_str("references");
1777 $$ = make_str("trigger");
1783 $$ = make_str("public");
1787 $$ = cat2_str(make_str("group"), $2);
1795 grantee_list: grantee { $$ = $1; }
1796 | grantee_list ',' grantee { $$ = cat_str(3, $1, make_str(","), $3); }
1799 opt_with_grant: WITH GRANT OPTION
1801 mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported GRANT/WITH GRANT OPTION will be passed to backend");
1802 $$ = make_str("with grant option");
1804 | /*EMPTY*/ { $$ = EMPTY; }
1808 /*****************************************************************************
1811 * REVOKE privileges ON [TABLE relation_name_list FROM [user], ...
1813 *****************************************************************************/
1815 RevokeStmt: REVOKE privileges ON opt_table relation_name_list FROM grantee_list
1817 $$ = cat_str(8, make_str("revoke"), $2, make_str("on"), $4, $5, make_str("from"), $7);
1823 /*****************************************************************************
1826 * create index <indexname> on <relname>
1827 * [ using <access> ] "(" (<col> with <op>)+ ")"
1828 * [ where <predicate> ]
1830 *****************************************************************************/
1832 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1833 access_method_clause '(' index_params ')' where_clause
1835 $$ = cat_str(11, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11);
1839 index_opt_unique: UNIQUE { $$ = make_str("unique"); }
1840 | /*EMPTY*/ { $$ = EMPTY; }
1843 access_method_clause: USING access_method { $$ = cat2_str(make_str("using"), $2); }
1844 | /*EMPTY*/ { $$ = EMPTY; }
1847 index_params: index_list { $$ = $1; }
1848 | func_index { $$ = $1; }
1851 index_list: index_list ',' index_elem { $$ = cat_str(3, $1, make_str(","), $3); }
1852 | index_elem { $$ = $1; }
1855 func_index: func_name '(' name_list ')' opt_class
1857 $$ = cat_str(5, $1, make_str("("), $3, ")", $5);
1861 index_elem: attr_name opt_class
1863 $$ = cat2_str($1, $2);
1869 * Release 7.0 removed network_ops, timespan_ops, and
1870 * datetime_ops, so we suppress it from being passed to
1871 * the parser so the default *_ops is used. This can be
1872 * removed in some later release. bjm 2000/02/07
1874 * Release 7.1 removes lztext_ops, so suppress that too
1875 * for a while. tgl 2000/07/30
1877 if (strcmp($1, "network_ops") != 0 &&
1878 strcmp($1, "timespan_ops") != 0 &&
1879 strcmp($1, "datetime_ops") != 0 &&
1880 strcmp($1, "lztext_ops") != 0)
1885 | USING class { $$ = cat2_str(make_str("using"), $2); }
1886 | /*EMPTY*/ { $$ = EMPTY; }
1890 /*****************************************************************************
1893 * execute recipe <recipeName>
1895 *****************************************************************************/
1897 RecipeStmt: EXECUTE RECIPE recipe_name
1899 $$ = cat2_str(make_str("execute recipe"), $3);
1903 /*****************************************************************************
1906 * create [or replace] function <fname>
1907 * [(<type-1> { , <type-n>})]
1909 * as <filename or code in language as appropriate>
1910 * language <lang> [with parameters]
1912 *****************************************************************************/
1914 ProcedureStmt: CREATE opt_or_replace FUNCTION func_name func_args
1915 RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with
1917 $$ = 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);
1920 opt_or_replace: OR REPLACE { $$ = make_str("or replace"); }
1921 | /*EMPTY*/ { $$ = EMPTY; }
1924 opt_with: WITH definition { $$ = cat2_str(make_str("with"), $2); }
1925 | /*EMPTY*/ { $$ = EMPTY; }
1928 func_args: '(' func_args_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1929 | '(' ')' { $$ = make_str("()"); }
1932 func_args_list: func_arg { $$ = $1; }
1933 | func_args_list ',' func_arg
1934 { $$ = cat_str(3, $1, make_str(","), $3); }
1937 func_arg: opt_arg func_type
1939 /* We can catch over-specified arguments here if we want to,
1940 * but for now better to silently swallow typmod, etc.
1941 * - thomas 2000-03-22
1943 $$ = cat2_str($1, $2);
1951 opt_arg: IN { $$ = make_str("in"); }
1953 mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE FUNCTION/OUT will be passed to backend");
1955 $$ = make_str("out");
1958 mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE FUNCTION/INOUT will be passed to backend");
1960 $$ = make_str("inout");
1964 func_as: StringConst { $$ = $1; }
1965 | StringConst ',' StringConst { $$ = cat_str(3, $1, make_str(","), $3); }
1967 func_return: func_type
1969 /* We can catch over-specified arguments here if we want to,
1970 * but for now better to silently swallow typmod, etc.
1971 * - thomas 2000-03-22
1981 | type_name '.' ColId '%' TYPE_P
1983 $$ = cat_str(4, $1, make_str("."), $3, make_str("% type"));
1987 /*****************************************************************************
1991 * DROP FUNCTION funcname (arg1, arg2, ...)
1992 * DROP AGGREGATE aggname (aggtype)
1993 * DROP OPERATOR opname (leftoperand_typ rightoperand_typ)
1995 *****************************************************************************/
1997 RemoveFuncStmt: DROP FUNCTION func_name func_args
1999 $$ = cat_str(3, make_str("drop function"), $3, $4);
2003 RemoveAggrStmt: DROP AGGREGATE func_name '(' aggr_argtype ')'
2005 $$ = cat_str(5, make_str("drop aggregate"), $3, make_str("("), $5, make_str(")"));
2007 | DROP AGGREGATE func_name aggr_argtype
2009 /* Obsolete syntax, but must support for awhile */
2010 $$ = cat_str(3, make_str("drop aggregate"), $3, $4);
2014 aggr_argtype: Typename { $$ = $1; }
2015 | '*' { $$ = make_str("*"); }
2019 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
2021 $$ = cat_str(5, make_str("drop operator"), $3, make_str("("), $5, make_str(")"));
2025 oper_argtypes: Typename
2027 mmerror(PARSE_ERROR, ET_ERROR, "parser: argument type missing (use NONE for unary operators)");
2029 | Typename ',' Typename
2030 { $$ = cat_str(3, $1, make_str(","), $3); }
2031 | NONE ',' Typename /* left unary */
2032 { $$ = cat2_str(make_str("none,"), $3); }
2033 | Typename ',' NONE /* right unary */
2034 { $$ = cat2_str($1, make_str(", none")); }
2037 /*****************************************************************************
2041 * REINDEX type <typename> [FORCE] [ALL]
2043 *****************************************************************************/
2044 ReindexStmt: REINDEX reindex_type name opt_force
2046 $$ = cat_str(4, make_str("reindex"), $2, $3, $4);
2049 reindex_type: INDEX { $$ = make_str("index"); }
2050 | TABLE { $$ = make_str("table"); }
2051 | DATABASE { $$ = make_str("database"); }
2053 opt_force: FORCE { $$ = make_str("force"); }
2054 | /* EMPTY */ { $$ = EMPTY; }
2057 /*****************************************************************************
2060 * rename <attrname1> in <relname> [*] to <attrname2>
2061 * rename <relname1> to <relname2>
2063 *****************************************************************************/
2065 RenameStmt: ALTER TABLE relation_expr RENAME opt_column opt_name TO name
2067 $$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8);
2071 opt_name: name { $$ = $1; }
2072 | /*EMPTY*/ { $$ = EMPTY; }
2075 opt_column: COLUMN { $$ = make_str("column"); }
2076 | /*EMPTY*/ { $$ = EMPTY; }
2080 /*****************************************************************************
2082 * QUERY: Define Rewrite Rule , Define Tuple Rule
2083 * Define Rule <old rules >
2085 * only rewrite rule is supported -- ay 9/94
2087 *****************************************************************************/
2089 RuleStmt: CREATE RULE name AS
2091 ON event TO event_object where_clause
2092 DO opt_instead RuleActionList
2095 $$ = cat_str(10, make_str("create rule"), $3, make_str("as on"), $7, make_str("to"), $9, $10, make_str("do"), $12, $13);
2099 RuleActionList: NOTHING { $$ = make_str("nothing"); }
2100 | RuleActionStmt { $$ = $1; }
2101 | '[' RuleActionMulti ']' { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
2102 | '(' RuleActionMulti ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2105 /* the thrashing around here is to discard "empty" statements... */
2106 RuleActionMulti: RuleActionMulti ';' RuleActionStmtOrEmpty
2107 { $$ = cat_str(3, $1, make_str(";"), $3); }
2108 | RuleActionStmtOrEmpty
2109 { $$ = cat2_str($1, make_str(";")); }
2112 RuleActionStmt: SelectStmt
2118 RuleActionStmtOrEmpty: RuleActionStmt { $$ = $1; }
2119 | /*EMPTY*/ { $$ = EMPTY; }
2122 event_object: relation_name '.' attr_name
2124 $$ = make3_str($1, make_str("."), $3);
2132 /* change me to select, update, etc. some day */
2133 event: SELECT { $$ = make_str("select"); }
2134 | UPDATE { $$ = make_str("update"); }
2135 | DELETE { $$ = make_str("delete"); }
2136 | INSERT { $$ = make_str("insert"); }
2139 opt_instead: INSTEAD { $$ = make_str("instead"); }
2140 | /*EMPTY*/ { $$ = EMPTY; }
2144 /*****************************************************************************
2147 * NOTIFY <relation_name> can appear both in rule bodies and
2148 * as a query-level command
2150 *****************************************************************************/
2152 NotifyStmt: NOTIFY relation_name
2154 $$ = cat2_str(make_str("notify"), $2);
2158 ListenStmt: LISTEN relation_name
2160 $$ = cat2_str(make_str("listen"), $2);
2164 UnlistenStmt: UNLISTEN relation_name
2166 $$ = cat2_str(make_str("unlisten"), $2);
2170 $$ = make_str("unlisten *");
2174 /*****************************************************************************
2178 * BEGIN / COMMIT / ROLLBACK
2179 * (also older versions END / ABORT)
2181 *****************************************************************************/
2182 TransactionStmt: ABORT_TRANS opt_trans { $$ = make_str("rollback"); }
2183 | BEGIN_TRANS opt_trans { $$ = make_str("begin transaction"); }
2184 | COMMIT opt_trans { $$ = make_str("commit"); }
2185 | COMMIT opt_trans opt_chain { $$ = cat2_str(make_str("commit"), $3); }
2186 | END_TRANS opt_trans { $$ = make_str("commit"); }
2187 | ROLLBACK opt_trans { $$ = make_str("rollback"); }
2188 | ROLLBACK opt_trans opt_chain { $$ = cat2_str(make_str("rollback"), $3); }
2191 opt_trans: WORK { $$ = ""; }
2192 | TRANSACTION { $$ = ""; }
2193 | /*EMPTY*/ { $$ = ""; }
2196 opt_chain: AND NO CHAIN { $$ = make_str("and no chain"); }
2198 mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported COMMIT/CHAIN will be passed to backend");
2200 $$ = make_str("and chain");
2204 /*****************************************************************************
2207 * define view <viewname> '('target-list ')' [where <quals> ]
2209 *****************************************************************************/
2211 ViewStmt: CREATE VIEW name opt_column_list AS SelectStmt
2213 $$ = cat_str(5, make_str("create view"), $3, $4, make_str("as"), $6);
2218 /*****************************************************************************
2221 * load make_str("filename")
2223 *****************************************************************************/
2225 LoadStmt: LOAD file_name
2227 $$ = cat2_str(make_str("load"), $2);
2232 /*****************************************************************************
2237 *****************************************************************************/
2239 CreatedbStmt: CREATE DATABASE database_name WITH createdb_opt_list
2241 $$ = cat_str(4, make_str("create database"), $3, make_str("with"), $5);
2243 | CREATE DATABASE database_name
2245 $$ = cat2_str(make_str("create database"), $3);
2249 createdb_opt_list: createdb_opt_item
2251 | createdb_opt_list createdb_opt_item
2252 { $$ = cat2_str($1, $2); }
2255 createdb_opt_item: LOCATION '=' StringConst { $$ = cat2_str(make_str("location ="), $3); }
2256 | LOCATION '=' DEFAULT { $$ = make_str("location = default"); }
2257 | TEMPLATE '=' name { $$ = cat2_str(make_str("template ="), $3); }
2258 | TEMPLATE '=' DEFAULT { $$ = make_str("template = default"); }
2259 | ENCODING '=' PosIntStringConst
2261 $$ = cat2_str(make_str("encoding ="), $3);
2263 | ENCODING '=' DEFAULT
2265 $$ = make_str("encoding = default");
2269 /*****************************************************************************
2274 *****************************************************************************/
2276 DropdbStmt: DROP DATABASE database_name
2278 $$ = cat2_str(make_str("drop database"), $3);
2283 /*****************************************************************************
2286 * cluster <index_name> on <relation_name>
2288 *****************************************************************************/
2290 ClusterStmt: CLUSTER index_name ON relation_name
2292 $$ = cat_str(4, make_str("cluster"), $2, make_str("on"), $4);
2297 /*****************************************************************************
2303 *****************************************************************************/
2305 VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
2307 $$ = cat_str(4, make_str("vacuum"), $2, $3, $4);
2309 | VACUUM opt_full opt_freeze opt_verbose relation_name
2311 $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5);
2313 | VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
2315 $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5);
2319 AnalyzeStmt: analyze_keyword opt_verbose
2321 $$ = cat_str(2, $1, $2);
2323 | analyze_keyword opt_verbose relation_name opt_name_list
2325 $$ = cat_str(4, $1, $2, $3, $4);
2329 analyze_keyword: ANALYZE { $$ = make_str("analyze"); }
2330 | ANALYSE { $$ = make_str("analyse"); }
2333 opt_verbose: VERBOSE { $$ = make_str("verbose"); }
2334 | /*EMPTY*/ { $$ = EMPTY; }
2337 opt_full: FULL { $$ = make_str("full"); }
2338 | /*EMPTY*/ { $$ = EMPTY; }
2341 opt_freeze: FREEZE { $$ = make_str("freeze"); }
2342 | /*EMPTY*/ { $$ = EMPTY; }
2345 opt_name_list: '(' name_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2346 | /*EMPTY*/ { $$ = EMPTY; }
2350 /*****************************************************************************
2355 *****************************************************************************/
2357 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2359 $$ = cat_str(3, make_str("explain"), $2, $3);
2361 | EXPLAIN analyze_keyword opt_verbose OptimizableStmt
2363 $$ = cat_str(4, make_str("explain"), $2, $3, $4);
2368 /*****************************************************************************
2370 * Optimizable Stmts: *
2372 * one of the five queries processed by the planner *
2374 * [ultimately] produces query-trees as specified *
2375 * in the query-spec document in ~postgres/ref *
2377 *****************************************************************************/
2379 OptimizableStmt: SelectStmt
2387 /*****************************************************************************
2392 *****************************************************************************/
2394 /* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
2395 * originally. When the second rule of 'insert_rest' was changed to use
2396 * the new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/reduce
2397 * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to accept
2398 * the same statements without any shift/reduce conflicts */
2399 InsertStmt: INSERT INTO relation_name insert_rest
2401 $$ = cat_str(3, make_str("insert into"), $3, $4);
2405 insert_rest: VALUES '(' target_list ')'
2407 $$ = cat_str(3, make_str("values("), $3, make_str(")"));
2411 $$ = make_str("default values");
2417 | '(' columnList ')' VALUES '(' target_list ')'
2419 $$ = cat_str(5, make_str("("), $2, make_str(") values ("), $6, make_str(")"));
2421 | '(' columnList ')' SelectStmt
2423 $$ = cat_str(4, make_str("("), $2, make_str(")"), $4);
2427 opt_column_list: '(' columnList ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2428 | /*EMPTY*/ { $$ = EMPTY; }
2432 columnList ',' columnElem
2433 { $$ = cat_str(3, $1, make_str(","), $3); }
2438 columnElem: ColId opt_indirection
2440 $$ = cat2_str($1, $2);
2445 /*****************************************************************************
2450 *****************************************************************************/
2452 DeleteStmt: DELETE FROM relation_expr where_clause
2454 $$ = cat_str(3, make_str("delete from"), $3, $4);
2458 LockStmt: LOCK_P opt_table relation_name_list opt_lock
2460 $$ = cat_str(4, make_str("lock"), $2, $3, $4);
2464 opt_lock: IN lock_type MODE { $$ = cat_str(3, make_str("in"), $2, make_str("mode")); }
2465 | /*EMPTY*/ { $$ = EMPTY;}
2468 lock_type: ACCESS SHARE { $$ = make_str("access share"); }
2469 | ROW SHARE { $$ = make_str("access share"); }
2470 | ROW EXCLUSIVE { $$ = make_str("row exclusive"); }
2471 | SHARE UPDATE EXCLUSIVE { $$ = make_str("share update exclusive"); }
2472 | SHARE { $$ = make_str("share"); }
2473 | SHARE ROW EXCLUSIVE { $$ = make_str("share row exclusive"); }
2474 | EXCLUSIVE { $$ = make_str("exclusive"); }
2475 | ACCESS EXCLUSIVE { $$ = make_str("access exclusive"); }
2478 /*****************************************************************************
2481 * UpdateStmt (UPDATE)
2483 *****************************************************************************/
2485 UpdateStmt: UPDATE relation_expr
2486 SET update_target_list
2490 $$ = cat_str(6, make_str("update"), $2, make_str("set"), $4, $5, $6);
2495 /*****************************************************************************
2500 *****************************************************************************/
2501 CursorStmt: DECLARE name opt_cursor CURSOR FOR SelectStmt
2503 struct cursor *ptr, *this;
2505 for (ptr = cur; ptr != NULL; ptr = ptr->next)
2507 if (strcmp($2, ptr->name) == 0)
2509 /* re-definition is a bug */
2510 sprintf(errortext, "cursor %s already defined", $2);
2511 mmerror(PARSE_ERROR, ET_ERROR, errortext);
2515 this = (struct cursor *) mm_alloc(sizeof(struct cursor));
2517 /* initial definition */
2520 this->connection = connection;
2521 this->command = cat_str(5, make_str("declare"), mm_strdup($2), $3, make_str("cursor for"), $6);
2522 this->argsinsert = argsinsert;
2523 this->argsresult = argsresult;
2524 argsinsert = argsresult = NULL;
2528 $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
2532 opt_cursor: BINARY { $$ = make_str("binary"); }
2533 | INSENSITIVE { $$ = make_str("insensitive"); }
2534 | SCROLL { $$ = make_str("scroll"); }
2535 | INSENSITIVE SCROLL { $$ = make_str("insensitive scroll"); }
2536 | /*EMPTY*/ { $$ = EMPTY; }
2539 /*****************************************************************************
2544 *****************************************************************************/
2546 SelectStmt: select_no_parens %prec UMINUS
2548 | select_with_parens %prec UMINUS
2552 select_with_parens: '(' select_no_parens ')'
2554 $$ = cat_str(3, make_str("("), $2, make_str(")"));
2556 | '(' select_with_parens ')'
2558 $$ = cat_str(3, make_str("("), $2, make_str(")"));
2562 select_no_parens: simple_select
2566 | select_clause sort_clause opt_for_update_clause opt_select_limit
2568 $$ = cat_str(4, $1, $2, $3, $4);
2570 | select_clause for_update_clause opt_select_limit
2572 $$ = cat_str(3, $1, $2, $3);
2574 | select_clause select_limit
2576 $$ = cat2_str($1, $2);
2579 select_clause: simple_select
2584 | select_with_parens
2590 simple_select: SELECT opt_distinct target_list
2591 into_clause from_clause where_clause
2592 group_clause having_clause
2594 $$ = cat_str(8, make_str("select"), $2, $3, $4, $5, $6, $7, $8);
2596 | select_clause UNION opt_all select_clause
2598 $$ = cat_str(4, $1, make_str("union"), $3, $4);
2600 | select_clause INTERSECT opt_all select_clause
2602 $$ = cat_str(4, $1, make_str("intersect"), $3, $4);
2604 | select_clause EXCEPT opt_all select_clause
2606 $$ = cat_str(4, $1, make_str("except"), $3, $4);
2610 into_clause: INTO OptTempTableName {
2612 $$= cat2_str(make_str("into"), $2);
2614 | ecpg_into { $$ = EMPTY; }
2615 | /*EMPTY*/ { $$ = EMPTY; }
2619 * Redundancy here is needed to avoid shift/reduce conflicts,
2620 * since TEMP is not a reserved word. See also OptTemp.
2622 * The result is a cons cell (not a true list!) containing
2623 * a boolean and a table name.
2625 OptTempTableName: TEMPORARY opt_table relation_name
2627 $$ = cat_str(3, make_str("temporary"), $2, $3);
2629 | TEMP opt_table relation_name
2631 $$ = cat_str(3, make_str("temp"), $2, $3);
2633 | LOCAL TEMPORARY opt_table relation_name
2635 $$ = cat_str(3, make_str("local temporary"), $3, $4);
2637 | LOCAL TEMP opt_table relation_name
2639 $$ = cat_str(3, make_str("local temp"), $3, $4);
2641 | GLOBAL TEMPORARY opt_table relation_name
2643 mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
2644 $$ = cat_str(3, make_str("global temporary"), $3, $4);
2646 | GLOBAL TEMP opt_table relation_name
2648 mmerror(PARSE_ERROR, ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
2649 $$ = cat_str(3, make_str("global temp"), $3, $4);
2651 | TABLE relation_name
2653 $$ = cat2_str(make_str("table"), $2);
2661 opt_table: TABLE { $$ = make_str("table"); }
2662 | /*EMPTY*/ { $$ = EMPTY; }
2665 opt_all: ALL { $$ = make_str("all"); }
2666 | /*EMPTY*/ { $$ = EMPTY; }
2669 opt_distinct: DISTINCT { $$ = make_str("distinct"); }
2670 | DISTINCT ON '(' expr_list ')' { $$ = cat_str(3, make_str("distinct on ("), $4, make_str(")")); }
2671 | ALL { $$ = make_str("all"); }
2672 | /*EMPTY*/ { $$ = EMPTY; }
2675 sort_clause: ORDER BY sortby_list {
2676 $$ = cat2_str(make_str("order by"), $3);
2680 sortby_list: sortby { $$ = $1; }
2681 | sortby_list ',' sortby { $$ = cat_str(3, $1, make_str(","), $3); }
2684 sortby: a_expr OptUseOp
2686 $$ = cat2_str($1, $2);
2690 OptUseOp: USING all_Op { $$ = cat2_str(make_str("using"), $2); }
2691 | ASC { $$ = make_str("asc"); }
2692 | DESC { $$ = make_str("desc"); }
2693 | /*EMPTY*/ { $$ = EMPTY; }
2696 select_limit: LIMIT select_limit_value OFFSET select_offset_value
2697 { $$ = cat_str(4, make_str("limit"), $2, make_str("offset"), $4); }
2698 | OFFSET select_offset_value LIMIT select_limit_value
2699 { $$ = cat_str(4, make_str("offset"), $2, make_str("limit"), $4); }
2700 | LIMIT select_limit_value
2701 { $$ = cat2_str(make_str("limit"), $2); }
2702 | OFFSET select_offset_value
2703 { $$ = cat2_str(make_str("offset"), $2); }
2704 | LIMIT select_limit_value ',' select_offset_value
2705 { $$ = cat_str(4, make_str("limit"), $2, make_str(","), $4); }
2706 /* enable this in 7.3, bjm 2001-10-22
2707 { mmerror(PARSE_ERROR, ET_NOTICE, "No longer supported LIMIT #,# syntax passed to backend."); }
2711 opt_select_limit: select_limit { $$ = $1; }
2712 | /*EMPTY*/ { $$ = EMPTY; }
2715 select_limit_value: PosIntConst {
2717 mmerror(PARSE_ERROR, ET_ERROR, "LIMIT must not be negative");
2720 | ALL { $$ = make_str("all"); }
2721 | PARAM { $$ = make_name(); }
2724 select_offset_value: PosIntConst {
2726 mmerror(PARSE_ERROR, ET_ERROR, "OFFSET must not be negative");
2729 | PARAM { $$ = make_name(); }
2733 * jimmy bell-style recursive queries aren't supported in the
2736 * ...however, recursive addattr and rename supported. make special
2739 relation_name_list: name_list { $$ = $1; };
2743 | name_list ',' name
2744 { $$ = cat_str(3, $1, make_str(","), $3); }
2747 group_clause: GROUP BY expr_list { $$ = cat2_str(make_str("group by"), $3); }
2748 | /*EMPTY*/ { $$ = EMPTY; }
2751 having_clause: HAVING a_expr
2753 $$ = cat2_str(make_str("having"), $2);
2755 | /*EMPTY*/ { $$ = EMPTY; }
2758 for_update_clause: FOR UPDATE update_list
2760 $$ = make_str("for update");
2764 $$ = make_str("for read only");
2768 opt_for_update_clause: for_update_clause { $$ = $1; }
2769 | /* EMPTY */ { $$ = EMPTY; }
2772 update_list: OF name_list
2774 $$ = cat2_str(make_str("of"), $2);
2782 /*****************************************************************************
2784 * clauses common to all Optimizable Stmts:
2785 * from_clause - allow list of both JOIN expressions and table names
2786 * where_clause - qualifications for joins or restrictions
2788 *****************************************************************************/
2790 from_clause: FROM from_list { $$ = cat2_str(make_str("from"), $2); }
2791 | /* EMPTY */ { $$ = EMPTY; }
2794 from_list: from_list ',' table_ref { $$ = cat_str(3, $1, make_str(","), $3); }
2795 | table_ref { $$ = $1; }
2799 * table_ref is where an alias clause can be attached. Note we cannot make
2800 * alias_clause have an empty production because that causes parse conflicts
2801 * between table_ref := '(' joined_table ')' alias_clause
2802 * and joined_table := '(' joined_table ')'. So, we must have the
2803 * redundant-looking productions here instead.
2805 table_ref: relation_expr
2809 | relation_expr alias_clause
2811 $$= cat2_str($1, $2);
2813 | select_with_parens
2815 mmerror(PARSE_ERROR, ET_ERROR, "sub-SELECT in FROM must have an alias");
2817 | select_with_parens alias_clause
2819 $$=cat2_str($1, $2);
2825 | '(' joined_table ')' alias_clause
2827 $$=cat_str(4, make_str("("), $2, make_str(")"), $4);
2832 * It may seem silly to separate joined_table from table_ref, but there is
2833 * method in SQL92's madness: if you don't do it this way you get reduce-
2834 * reduce conflicts, because it's not clear to the parser generator whether
2835 * to expect alias_clause after ')' or not. For the same reason we must
2836 * treat 'JOIN' and 'join_type JOIN' separately, rather than allowing
2837 * join_type to expand to empty; if we try it, the parser generator can't
2838 * figure out when to reduce an empty join_type right after table_ref.
2840 * Note that a CROSS JOIN is the same as an unqualified
2841 * INNER JOIN, and an INNER JOIN/ON has the same shape
2842 * but a qualification expression to limit membership.
2843 * A NATURAL JOIN implicitly matches column names between
2844 * tables and the shape is determined by which columns are
2845 * in common. We'll collect columns during the later transformations.
2848 joined_table: '(' joined_table ')'
2850 $$ = cat_str(3, make_str("("), $2, make_str(")"));
2852 | table_ref CROSS JOIN table_ref
2854 $$ = cat_str(3, $1, make_str("cross join"), $4);
2856 | table_ref UNIONJOIN table_ref
2858 $$ = cat_str(3, $1, make_str("unionjoin"), $3);
2860 | table_ref join_type JOIN table_ref join_qual
2862 $$ = cat_str(5, $1, $2, make_str("join"), $4, $5);
2864 | table_ref JOIN table_ref join_qual
2866 $$ = cat_str(4, $1, make_str("join"), $3, $4);
2868 | table_ref NATURAL join_type JOIN table_ref
2870 $$ = cat_str(5, $1, make_str("natural"), $3, make_str("join"), $5);
2872 | table_ref NATURAL JOIN table_ref
2874 $$ = cat_str(3, $1, make_str("natural join"), $4);
2878 alias_clause: AS ColId '(' name_list ')'
2879 { $$ = cat_str(5, make_str("as"), $2, make_str("("), $4, make_str(")")); }
2881 { $$ = cat2_str(make_str("as"), $2); }
2882 | ColId '(' name_list ')'
2883 { $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
2888 join_type: FULL join_outer { $$ = cat2_str(make_str("full"), $2); }
2889 | LEFT join_outer { $$ = cat2_str(make_str("left"), $2); }
2890 | RIGHT join_outer { $$ = cat2_str(make_str("right"), $2); }
2891 | INNER_P { $$ = make_str("inner"); }
2894 /* OUTER is just noise... */
2895 join_outer: OUTER_P { $$ = make_str("outer"); }
2896 | /*EMPTY*/ { $$ = EMPTY; /* no qualifiers */ }
2899 /* JOIN qualification clauses
2900 * Possibilities are:
2901 * USING ( column list ) allows only unqualified column names,
2902 * which must match between tables.
2903 * ON expr allows more general qualifications.
2906 join_qual: USING '(' name_list ')' { $$ = cat_str(3, make_str("using ("), $3, make_str(")")); }
2907 | ON a_expr { $$ = cat2_str(make_str("on"), $2); }
2910 relation_expr: relation_name
2912 /* normal relations */
2917 /* inheritance query */
2918 $$ = cat2_str($1, make_str("*"));
2920 | ONLY relation_name
2922 /* inheritance query */
2923 $$ = cat2_str(make_str("ONLY "), $2);
2926 where_clause: WHERE a_expr { $$ = cat2_str(make_str("where"), $2); }
2927 | /*EMPTY*/ { $$ = EMPTY; /* no qualifiers */ }
2930 /*****************************************************************************
2933 * SQL92 introduces a large amount of type-specific syntax.
2934 * Define individual clauses to handle these cases, and use
2935 * the generic case to handle regular type-extensible Postgres syntax.
2936 * - thomas 1997-10-10
2938 *****************************************************************************/
2940 Typename: SimpleTypename opt_array_bounds
2942 $$ = cat2_str($1, $2.str);
2944 | SETOF SimpleTypename
2946 $$ = cat2_str(make_str("setof"), $2);
2951 opt_array_bounds: '[' ']' opt_array_bounds
2954 $$.index2 = $3.index1;
2955 $$.str = cat2_str(make_str("[]"), $3.str);
2957 | '[' Iresult ']' opt_array_bounds
2959 char *txt = mm_alloc(20L);
2961 sprintf (txt, "%d", $2);
2963 $$.index2 = $4.index1;
2964 $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
2974 Iresult: PosIntConst { $$ = atol($1); }
2975 | '(' Iresult ')' { $$ = $2; }
2976 | Iresult '+' Iresult { $$ = $1 + $3; }
2977 | Iresult '-' Iresult { $$ = $1 - $3; }
2978 | Iresult '*' Iresult { $$ = $1 * $3; }
2979 | Iresult '/' Iresult { $$ = $1 / $3; }
2980 | Iresult '%' Iresult { $$ = $1 % $3; }
2983 SimpleTypename: ConstTypename { $$ = $1; }
2984 | ConstInterval opt_interval { $$ = cat2_str($1, $2); }
2985 | ConstInterval '(' PosIntConst ')' opt_interval { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
2988 ConstTypename: Generic { $$ = $1; }
2989 | ConstDatetime { $$ = $1; }
2990 | Numeric { $$ = $1; }
2992 | Character { $$ = $1; }
2995 Generic: type_name { $$ = $1; }
2998 /* SQL92 numeric data types
2999 * Check FLOAT() precision limits assuming IEEE floating types.
3000 * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
3001 * - thomas 1997-09-18
3003 Numeric: FLOAT opt_float
3005 $$ = cat2_str(make_str("float"), $2);
3009 $$ = make_str("double precision");
3011 | DECIMAL opt_decimal
3013 $$ = cat2_str(make_str("decimal"), $2);
3017 $$ = cat2_str(make_str("dec"), $2);
3019 | NUMERIC opt_numeric
3021 $$ = cat2_str(make_str("numeric"), $2);
3025 opt_float: '(' PosIntConst ')'
3027 $$ = cat_str(3, make_str("("), $2, make_str(")"));
3035 opt_numeric: '(' PosIntConst ',' PosIntConst ')'
3037 $$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")"));
3039 | '(' PosIntConst ')'
3041 $$ = cat_str(3, make_str("("), $2, make_str(")"));
3049 opt_decimal: '(' PosIntConst ',' PosIntConst ')'
3051 $$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")"));
3053 | '(' PosIntConst ')'
3055 $$ = cat_str(3, make_str("("), $2, make_str(")"));
3064 * SQL92 bit-field data types
3065 * The following implements BIT() and BIT VARYING().
3067 Bit: bit '(' PosIntConst ')'
3069 $$ = cat_str(4, $1, make_str("("), $3, make_str(")"));
3077 bit: BIT opt_varying
3079 $$ = cat2_str(make_str("bit"), $2);
3083 * SQL92 character data types
3084 * The following implements CHAR() and VARCHAR().
3087 Character: character '(' PosIntConst ')' opt_charset
3089 $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5);
3091 | character opt_charset
3093 $$ = cat2_str($1, $2);
3097 character: CHARACTER opt_varying
3099 $$ = cat2_str(make_str("character"), $2);
3101 | CHAR opt_varying { $$ = cat2_str(make_str("char"), $2); }
3102 | VARCHAR { $$ = make_str("varchar"); }
3103 | NATIONAL CHARACTER opt_varying { $$ = cat2_str(make_str("national character"), $3); }
3104 | NATIONAL CHAR opt_varying { $$ = cat2_str(make_str("national char"), $3); }
3105 | NCHAR opt_varying { $$ = cat2_str(make_str("nchar"), $2); }
3108 opt_varying: VARYING { $$ = make_str("varying"); }
3109 | /*EMPTY*/ { $$ = EMPTY; }
3112 opt_charset: CHARACTER SET ColId { $$ = cat2_str(make_str("character set"), $3); }
3113 | /*EMPTY*/ { $$ = EMPTY; }
3116 opt_collate: COLLATE ColId { $$ = cat2_str(make_str("collate"), $2); }
3117 | /*EMPTY*/ { $$ = EMPTY; }
3120 ConstDatetime: TIMESTAMP '(' PosIntConst ')' opt_timezone
3122 $$ = cat_str(4, make_str("timestamp("), $3, make_str(")"), $5);
3124 | TIMESTAMP opt_timezone
3126 $$ = cat2_str(make_str("timestamp"), $2);
3128 | TIME '(' PosIntConst ')' opt_timezone
3130 $$ = cat_str(4, make_str("time("), $3, make_str(")"), $5);
3134 $$ = cat2_str(make_str("time"), $2);
3138 ConstInterval: INTERVAL
3140 $$ = make_str("interval");
3144 opt_timezone: WITH TIME ZONE { $$ = make_str("with time zone"); }
3145 | WITHOUT TIME ZONE { $$ = make_str("without time zone"); }
3146 | /*EMPTY*/ { $$ = EMPTY; }
3149 opt_interval: YEAR_P { $$ = make_str("year"); }
3150 | MONTH_P { $$ = make_str("month"); }
3151 | DAY_P { $$ = make_str("day"); }
3152 | HOUR_P { $$ = make_str("hour"); }
3153 | MINUTE_P { $$ = make_str("minute"); }
3154 | SECOND_P { $$ = make_str("second"); }
3155 | YEAR_P TO MONTH_P { $$ = make_str("year to month"); }
3156 | DAY_P TO HOUR_P { $$ = make_str("day to hour"); }
3157 | DAY_P TO MINUTE_P { $$ = make_str("day to minute"); }
3158 | DAY_P TO SECOND_P { $$ = make_str("day to second"); }
3159 | HOUR_P TO MINUTE_P { $$ = make_str("hour to minute"); }
3160 | MINUTE_P TO SECOND_P { $$ = make_str("minute to second"); }
3161 | HOUR_P TO SECOND_P { $$ = make_str("hour to second"); }
3162 | /*EMPTY*/ { $$ = EMPTY; }
3166 /*****************************************************************************
3168 * expression grammar
3170 *****************************************************************************/
3172 /* Expressions using row descriptors
3173 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
3174 * with singleton expressions.
3176 row_expr: '(' row_descriptor ')' IN select_with_parens
3178 $$ = cat_str(4, make_str("("), $2, make_str(") in "), $5);
3180 | '(' row_descriptor ')' NOT IN select_with_parens
3182 $$ = cat_str(4, make_str("("), $2, make_str(") not in "), $6);
3184 | '(' row_descriptor ')' all_Op sub_type select_with_parens
3186 $$ = cat_str(6, make_str("("), $2, make_str(")"), $4, $5, $6);
3188 | '(' row_descriptor ')' all_Op select_with_parens
3190 $$ = cat_str(5, make_str("("), $2, make_str(")"), $4, $5);
3192 | '(' row_descriptor ')' all_Op '(' row_descriptor ')'
3194 $$ = cat_str(7, make_str("("), $2, make_str(")"), $4, make_str("("), $6, make_str(")"));
3196 | '(' row_descriptor ')' OVERLAPS '(' row_descriptor ')'
3198 $$ = cat_str(5, make_str("("), $2, make_str(") overlaps ("), $6, make_str(")"));
3202 row_descriptor: row_list ',' a_expr
3204 $$ = cat_str(3, $1, make_str(","), $3);
3208 sub_type: ANY { $$ = make_str("ANY"); }
3209 | SOME { $$ = make_str("SOME"); }
3210 | ALL { $$ = make_str("ALL"); }
3214 row_list: row_list ',' a_expr
3216 $$ = cat_str(3, $1, make_str(","), $3);
3224 all_Op: Op | MathOp;
3226 MathOp: '+' { $$ = make_str("+"); }
3227 | '-' { $$ = make_str("-"); }
3228 | '*' { $$ = make_str("*"); }
3229 | '%' { $$ = make_str("%"); }
3230 | '^' { $$ = make_str("^"); }
3231 | '/' { $$ = make_str("/"); }
3232 | '<' { $$ = make_str("<"); }
3233 | '>' { $$ = make_str(">"); }
3234 | '=' { $$ = make_str("="); }
3237 /* General expressions
3238 * This is the heart of the expression syntax.
3240 * We have two expression types: a_expr is the unrestricted kind, and
3241 * b_expr is a subset that must be used in some places to avoid shift/reduce
3242 * conflicts. For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
3243 * because that use of AND conflicts with AND as a boolean operator. So,
3244 * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
3246 * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
3247 * always be used by surrounding it with parens.
3249 * c_expr is all the productions that are common to a_expr and b_expr;
3250 * it's factored out just to eliminate redundant coding.
3255 | a_expr TYPECAST Typename
3256 { $$ = cat_str(3, $1, make_str("::"), $3); }
3257 | a_expr AT TIME ZONE c_expr
3258 { $$ = cat_str(3, $1, make_str("at time zone"), $5); }
3260 * These operators must be called out explicitly in order to make use
3261 * of yacc/bison's automatic operator-precedence handling. All other
3262 * operator names are handled by the generic productions using "Op",
3263 * below; and all those operators will have the same precedence.
3265 * If you add more explicitly-known operators, be sure to add them
3266 * also to b_expr and to the MathOp list above.
3268 | '+' a_expr %prec UMINUS
3269 { $$ = cat2_str(make_str("+"), $2); }
3270 | '-' a_expr %prec UMINUS
3271 { $$ = cat2_str(make_str("-"), $2); }
3273 { $$ = cat2_str(make_str("%"), $2); }
3275 { $$ = cat2_str(make_str("^"), $2); }
3277 { $$ = cat2_str($1, make_str("%")); }
3279 { $$ = cat2_str($1, make_str("^")); }
3281 { $$ = cat_str(3, $1, make_str("+"), $3); }
3283 { $$ = cat_str(3, $1, make_str("-"), $3); }
3285 { $$ = cat_str(3, $1, make_str("*"), $3); }
3287 { $$ = cat_str(3, $1, make_str("/"), $3); }
3289 { $$ = cat_str(3, $1, make_str("%"), $3); }
3291 { $$ = cat_str(3, $1, make_str("^"), $3); }
3293 { $$ = cat_str(3, $1, make_str("<"), $3); }
3295 { $$ = cat_str(3, $1, make_str(">"), $3); }
3297 { $$ = cat_str(3, $1, make_str("="), $3); }
3299 { $$ = cat_str(3, $1, $2, $3); }
3301 { $$ = cat2_str($1, $2); }
3302 | a_expr Op %prec POSTFIXOP
3303 { $$ = cat2_str($1, $2); }
3305 { $$ = cat_str(3, $1, make_str("and"), $3); }
3307 { $$ = cat_str(3, $1, make_str("or"), $3); }
3309 { $$ = cat2_str(make_str("not"), $2); }
3310 | a_expr LIKE a_expr
3311 { $$ = cat_str(3, $1, make_str("like"), $3); }
3312 | a_expr LIKE a_expr ESCAPE a_expr
3313 { $$ = cat_str(5, $1, make_str("like"), $3, make_str("escape"), $5); }
3314 | a_expr NOT LIKE a_expr
3315 { $$ = cat_str(3, $1, make_str("not like"), $4); }
3316 | a_expr NOT LIKE a_expr ESCAPE a_expr
3317 { $$ = cat_str(5, $1, make_str("not like"), $4, make_str("escape"), $6); }
3318 | a_expr ILIKE a_expr
3319 { $$ = cat_str(3, $1, make_str("ilike"), $3); }
3320 | a_expr ILIKE a_expr ESCAPE a_expr
3321 { $$ = cat_str(5, $1, make_str("ilike"), $3, make_str("escape"), $5); }
3322 | a_expr NOT ILIKE a_expr
3323 { $$ = cat_str(3, $1, make_str("not ilike"), $4); }
3324 | a_expr NOT ILIKE a_expr ESCAPE a_expr
3325 { $$ = cat_str(5, $1, make_str("not ilike"), $4, make_str("escape"), $6); }
3327 { $$ = cat2_str($1, make_str("isnull")); }
3329 { $$ = cat2_str($1, make_str("is null")); }
3331 { $$ = cat2_str($1, make_str("notnull")); }
3332 | a_expr IS NOT NULL_P
3333 { $$ = cat2_str($1, make_str("is not null")); }
3334 /* IS TRUE, IS FALSE, etc used to be function calls
3335 * but let's make them expressions to allow the optimizer
3336 * a chance to eliminate them if a_expr is a constant string.
3337 * - thomas 1997-12-22
3339 * Created BooleanTest Node type, and changed handling
3344 { $$ = cat2_str($1, make_str("is true")); }
3345 | a_expr IS NOT TRUE_P
3346 { $$ = cat2_str($1, make_str("is not true")); }
3348 { $$ = cat2_str($1, make_str("is false")); }
3349 | a_expr IS NOT FALSE_P
3350 { $$ = cat2_str($1, make_str("is not false")); }
3352 { $$ = cat2_str($1, make_str("is unknown")); }
3353 | a_expr IS NOT UNKNOWN
3354 { $$ = cat2_str($1, make_str("is not unknown")); }
3355 | a_expr BETWEEN b_expr AND b_expr %prec BETWEEN
3357 $$ = cat_str(5, $1, make_str("between"), $3, make_str("and"), $5);
3359 | a_expr NOT BETWEEN b_expr AND b_expr %prec BETWEEN
3361 $$ = cat_str(5, $1, make_str("not between"), $4, make_str("and"), $6);
3365 $$ = cat_str(3, $1, make_str(" in"), $3);
3367 | a_expr NOT IN in_expr
3369 $$ = cat_str(3, $1, make_str(" not in "), $4);
3371 | a_expr all_Op sub_type select_with_parens %prec Op
3373 $$ = cat_str(4, $1, $2, $3, $4);
3379 /* Restricted expressions
3381 * b_expr is a subset of the complete expression syntax
3383 * Presently, AND, NOT, IS and IN are the a_expr keywords that would
3384 * cause trouble in the places where b_expr is used. For simplicity, we
3385 * just eliminate all the boolean-keyword-operator productions from b_expr.
3391 | b_expr TYPECAST Typename
3393 $$ = cat_str(3, $1, make_str("::"), $3);
3395 | '-' b_expr %prec UMINUS
3396 { $$ = cat2_str(make_str("-"), $2); }
3398 { $$ = cat2_str(make_str("%"), $2); }
3400 { $$ = cat2_str(make_str("^"), $2); }
3402 { $$ = cat2_str($1, make_str("%")); }
3404 { $$ = cat2_str($1, make_str("^")); }
3406 { $$ = cat_str(3, $1, make_str("+"), $3); }
3408 { $$ = cat_str(3, $1, make_str("-"), $3); }
3410 { $$ = cat_str(3, $1, make_str("*"), $3); }
3412 { $$ = cat_str(3, $1, make_str("/"), $3); }
3414 { $$ = cat_str(3, $1, make_str("%"), $3); }
3416 { $$ = cat_str(3, $1, make_str("^"), $3); }
3418 { $$ = cat_str(3, $1, make_str("<"), $3); }
3420 { $$ = cat_str(3, $1, make_str(">"), $3); }
3422 { $$ = cat_str(3, $1, make_str("="), $3); }
3424 { $$ = cat_str(3, $1, $2, $3); }
3426 { $$ = cat2_str($1, $2); }
3427 | b_expr Op %prec POSTFIXOP
3428 { $$ = cat2_str($1, $2); }
3432 * Productions that can be used in both a_expr and b_expr.
3434 * Note: productions that refer recursively to a_expr or b_expr mostly
3435 * cannot appear here. However, it's OK to refer to a_exprs that occur
3436 * inside parentheses, such as function arguments; that cannot introduce
3437 * ambiguity to the b_expr syntax.
3441 | ColId opt_indirection
3442 { $$ = cat2_str($1, $2); }
3446 { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3447 | CAST '(' a_expr AS Typename ')'
3448 { $$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); }
3452 { $$ = cat2_str($1, make_str("()")); }
3453 | func_name '(' expr_list ')'
3454 { $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
3455 | func_name '(' ALL expr_list ')'
3456 { $$ = cat_str(4, $1, make_str("( all"), $4, make_str(")")); }
3457 | func_name '(' DISTINCT expr_list ')'
3458 { $$ = cat_str(4, $1, make_str("( distinct"), $4, make_str(")")); }
3459 | func_name '(' '*' ')'
3460 { $$ = cat2_str($1, make_str("(*)")); }
3462 { $$ = make_str("current_date"); }
3463 | CURRENT_TIME opt_empty_parentheses
3464 { $$ = cat2_str(make_str("current_time"), $2); }
3465 | CURRENT_TIME '(' PosIntConst ')'
3467 $$ = make_str("current_time");
3469 | CURRENT_TIMESTAMP opt_empty_parentheses
3470 { $$ = cat2_str(make_str("current_timestamp"), $2); }
3471 | CURRENT_TIMESTAMP '(' PosIntConst ')'
3473 $$ = make_str("current_timestamp");
3475 | CURRENT_USER opt_empty_parentheses
3476 { $$ = cat2_str(make_str("current_user"), $2); }
3477 | SESSION_USER opt_empty_parentheses
3478 { $$ = cat2_str(make_str("session_user"), $2); }
3479 | USER opt_empty_parentheses
3480 { $$ = cat2_str(make_str("user"), $2); }
3481 | EXTRACT '(' extract_list ')'
3482 { $$ = cat_str(3, make_str("extract("), $3, make_str(")")); }
3483 | POSITION '(' position_list ')'
3484 { $$ = cat_str(3, make_str("position("), $3, make_str(")")); }
3485 | SUBSTRING '(' substr_list ')'
3486 { $$ = cat_str(3, make_str("substring("), $3, make_str(")")); }
3487 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3488 | TRIM '(' BOTH trim_list ')'
3489 { $$ = cat_str(3, make_str("trim(both"), $4, make_str(")")); }
3490 | TRIM '(' LEADING trim_list ')'
3491 { $$ = cat_str(3, make_str("trim(leading"), $4, make_str(")")); }
3492 | TRIM '(' TRAILING trim_list ')'
3493 { $$ = cat_str(3, make_str("trim(trailing"), $4, make_str(")")); }
3494 | TRIM '(' trim_list ')'
3495 { $$ = cat_str(3, make_str("trim("), $3, make_str(")")); }
3496 | select_with_parens %prec UMINUS
3498 | EXISTS select_with_parens
3499 { $$ = cat2_str(make_str("exists"), $2); }
3502 * This used to use ecpg_expr, but since there is no shift/reduce conflict
3503 * anymore, we can remove ecpg_expr. - MM
3505 opt_indirection: '[' a_expr ']' opt_indirection
3507 $$ = cat_str(4, make_str("["), $2, make_str("]"), $4);
3509 | '[' a_expr ':' a_expr ']' opt_indirection
3511 $$ = cat_str(6, make_str("["), $2, make_str(":"), $4, make_str("]"), $6);
3519 | expr_list ',' a_expr
3520 { $$ = cat_str(3, $1, make_str(","), $3); }
3521 | expr_list USING a_expr
3522 { $$ = cat_str(3, $1, make_str("using"), $3); }
3525 extract_list: extract_arg FROM a_expr
3527 $$ = cat_str(3, $1, make_str("from"), $3);
3533 /* Allow delimited string SCONST in extract_arg as an SQL extension.
3534 * - thomas 2001-04-12
3537 extract_arg: IDENT { $$ = $1; }
3538 | YEAR_P { $$ = make_str("year"); }
3539 | MONTH_P { $$ = make_str("month"); }
3540 | DAY_P { $$ = make_str("day"); }
3541 | HOUR_P { $$ = make_str("hour"); }
3542 | MINUTE_P { $$ = make_str("minute"); }
3543 | SECOND_P { $$ = make_str("second"); }
3544 | StringConst { $$ = $1; }
3547 /* position_list uses b_expr not a_expr to avoid conflict with general IN */
3548 position_list: b_expr IN b_expr
3549 { $$ = cat_str(3, $1, make_str("in"), $3); }
3554 substr_list: a_expr substr_from substr_for
3556 $$ = cat_str(3, $1, $2, $3);
3558 | a_expr substr_for substr_from
3560 $$ = cat_str(3, $1, $2, $3);
3562 | a_expr substr_from
3564 $$ = cat2_str($1, $2);
3568 $$ = cat2_str($1, $2);
3578 substr_from: FROM a_expr
3579 { $$ = cat2_str(make_str("from"), $2); }
3582 substr_for: FOR a_expr
3583 { $$ = cat2_str(make_str("for"), $2); }
3586 trim_list: a_expr FROM expr_list
3587 { $$ = cat_str(3, $1, make_str("from"), $3); }
3589 { $$ = cat2_str(make_str("from"), $2); }
3594 in_expr: select_with_parens
3598 | '(' in_expr_nodes ')'
3599 { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3602 in_expr_nodes: a_expr
3604 | in_expr_nodes ',' a_expr
3605 { $$ = cat_str(3, $1, make_str(","), $3);}
3609 * Define SQL92-style case clause.
3610 * Allow all four forms described in the standard:
3611 * - Full specification
3612 * CASE WHEN a = b THEN c ... ELSE d END
3613 * - Implicit argument
3614 * CASE a WHEN b THEN c ... ELSE d END
3615 * - Conditional NULL
3617 * same as CASE WHEN x = y THEN NULL ELSE x END
3618 * - Conditional substitution from list, use first non-null argument
3620 * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
3621 * - thomas 1998-11-09
3623 case_expr: CASE case_arg when_clause_list case_default END_TRANS
3624 { $$ = cat_str(5, make_str("case"), $2, $3, $4, make_str("end")); }
3625 | NULLIF '(' a_expr ',' a_expr ')'
3627 $$ = cat_str(5, make_str("nullif("), $3, make_str(","), $5, make_str(")"));
3629 | COALESCE '(' expr_list ')'
3631 $$ = cat_str(3, make_str("coalesce("), $3, make_str(")"));
3635 when_clause_list: when_clause_list when_clause
3636 { $$ = cat2_str($1, $2); }
3641 when_clause: WHEN a_expr THEN a_expr
3643 $$ = cat_str(4, make_str("when"), $2, make_str("then"), $4);
3647 case_default: ELSE a_expr { $$ = cat2_str(make_str("else"), $2); }
3648 | /*EMPTY*/ { $$ = EMPTY; }
3658 attr: relation_name '.' attrs opt_indirection
3660 $$ = cat_str(4, $1, make_str("."), $3, $4);
3662 | ParamNo '.' attrs opt_indirection
3664 $$ = cat_str(4, $1, make_str("."), $3, $4);
3670 | attrs '.' attr_name
3671 { $$ = cat_str(3, $1, make_str("."), $3); }
3673 { $$ = make2_str($1, make_str(".*")); }
3676 opt_empty_parentheses: '(' ')' { $$ = make_str("()"); }
3677 | /*EMPTY*/ { $$ = EMPTY; }
3679 /*****************************************************************************
3683 *****************************************************************************/
3685 /* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
3686 target_list: target_list ',' target_el
3687 { $$ = cat_str(3, $1, make_str(","), $3); }
3692 /* AS is not optional because shift/red conflict with unary ops */
3693 target_el: a_expr AS ColLabel
3695 $$ = cat_str(3, $1, make_str("as"), $3);
3701 | relation_name '.' '*'
3703 $$ = make2_str($1, make_str(".*"));
3711 /* Target list as found in UPDATE table SET ... */
3712 update_target_list: update_target_list ',' update_target_el
3713 { $$ = cat_str(3, $1, make_str(","),$3); }
3716 | '*' { $$ = make_str("*"); }
3719 update_target_el: ColId opt_indirection '=' a_expr
3721 $$ = cat_str(4, $1, $2, make_str("="), $4);
3725 /*****************************************************************************
3727 * Names and constants
3729 *****************************************************************************/
3731 relation_name: SpecialRuleRelation
3741 name: ColId { $$ = $1; };
3742 database_name: ColId { $$ = $1; };
3743 access_method: ColId { $$ = $1; };
3744 attr_name: ColId { $$ = $1; };
3745 class: ColId { $$ = $1; };
3746 index_name: ColId { $$ = $1; };
3748 file_name: StringConst { $$ = $1; };
3751 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
3753 AexprConst: PosAllConst
3757 | ConstTypename StringConst
3759 $$ = cat2_str($1, $2);
3761 | ConstInterval StringConst opt_interval
3763 $$ = cat_str(3, $1, $2, $3);
3765 | ConstInterval '(' PosIntConst ')' StringConst opt_interval
3767 $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6);
3773 $$ = make_str("true");
3777 $$ = make_str("false");
3781 $$ = make_str("null");
3784 { $$ = make_str("?"); }
3787 ParamNo: PARAM opt_indirection
3789 $$ = cat2_str(make_name(), $2);
3793 Iconst: ICONST { $$ = make_name();};
3794 Fconst: FCONST { $$ = make_name();};
3795 Bitconst: BITCONST { $$ = make_name();};
3797 $$ = (char *)mm_alloc(strlen($1) + 3);
3800 $$[strlen($1)+2]='\0';
3801 $$[strlen($1)+1]='\'';
3804 PosIntConst: Iconst { $$ = $1; }
3805 | civar { $$ = make_str("?"); }
3808 IntConst: PosIntConst { $$ = $1; }
3809 | '-' PosIntConst { $$ = cat2_str(make_str("-"), $2); }
3812 StringConst: Sconst { $$ = $1; }
3813 | civar { $$ = make_str("?"); }
3816 PosIntStringConst: Iconst { $$ = $1; }
3817 | Sconst { $$ = $1; }
3818 | civar { $$ = make_str("?"); }
3821 NumConst: Fconst { $$ = $1; }
3822 | Iconst { $$ = $1; }
3823 | '-' Fconst { $$ = cat2_str(make_str("-"), $2); }
3824 | '-' Iconst { $$ = cat2_str(make_str("-"), $2); }
3825 | civar { $$ = make_str("?"); }
3828 AllConst: Sconst { $$ = $1; }
3829 | NumConst { $$ = $1; }
3832 PosAllConst: Sconst { $$ = $1; }
3833 | Fconst { $$ = $1; }
3834 | Iconst { $$ = $1; }
3835 | Bitconst { $$ = $1; }
3836 | civar { $$ = make_str("?"); }
3839 UserId: ColId { $$ = $1;};
3841 SpecialRuleRelation: OLD
3844 mmerror(PARSE_ERROR, ET_ERROR, "OLD used in non-rule query");
3846 $$ = make_str("old");
3851 mmerror(PARSE_ERROR, ET_ERROR, "NEW used in non-rule query");
3853 $$ = make_str("new");
3858 * and now special embedded SQL stuff
3862 * the exec sql connect statement: connect to the given database
3864 ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
3866 $$ = cat_str(5, $3, make_str(","), $5, make_str(","), $4);
3868 | SQL_CONNECT TO DEFAULT
3870 $$ = make_str("NULL,NULL,NULL,\"DEFAULT\"");
3872 /* also allow ORACLE syntax */
3873 | SQL_CONNECT ora_user
3875 $$ = cat_str(3, make_str("NULL,"), $2, make_str(",NULL"));
3878 connection_target: database_name opt_server opt_port
3880 /* old style: dbname[@server][:port] */
3881 if (strlen($2) > 0 && *($2) != '@')
3883 sprintf(errortext, "Expected '@', found '%s'", $2);
3884 mmerror(PARSE_ERROR, ET_ERROR, errortext);
3887 $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
3889 | db_prefix ':' server opt_port '/' database_name opt_options
3891 /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
3892 if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0)
3894 sprintf(errortext, "only protocols 'tcp' and 'unix' and database type 'postgresql' are supported");
3895 mmerror(PARSE_ERROR, ET_ERROR, errortext);
3898 if (strncmp($3, "//", strlen("//")) != 0)
3900 sprintf(errortext, "Expected '://', found '%s'", $3);
3901 mmerror(PARSE_ERROR, ET_ERROR, errortext);
3904 if (strncmp($1, "unix", strlen("unix")) == 0 &&
3905 strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 &&
3906 strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0)
3908 sprintf(errortext, "unix domain sockets only work on 'localhost' but not on '%9.9s'", $3 + strlen("//"));
3909 mmerror(PARSE_ERROR, ET_ERROR, errortext);
3912 $$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6), $7, make_str("\"")));
3918 else if (strcmp($1, "?") == 0) /* variable */
3920 enum ECPGttype type = argsinsert->variable->type->type;
3922 /* if array see what's inside */
3923 if (type == ECPGt_array)
3924 type = argsinsert->variable->type->u.element->type;
3926 /* handle varchars */
3927 if (type == ECPGt_varchar)
3928 $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
3930 $$ = mm_strdup(argsinsert->variable->name);
3933 $$ = make3_str(make_str("\""), $1, make_str("\""));
3936 db_prefix: ident cvariable
3938 if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
3940 sprintf(errortext, "Expected 'postgresql', found '%s'", $2);
3941 mmerror(PARSE_ERROR, ET_ERROR, errortext);
3944 if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
3946 sprintf(errortext, "Illegal connection type %s", $1);
3947 mmerror(PARSE_ERROR, ET_ERROR, errortext);
3950 $$ = make3_str($1, make_str(":"), $2);
3953 server: Op server_name
3955 if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
3957 sprintf(errortext, "Expected '@' or '://', found '%s'", $1);
3958 mmerror(PARSE_ERROR, ET_ERROR, errortext);
3961 $$ = make2_str($1, $2);
3964 opt_server: server { $$ = $1; }
3965 | /* empty */ { $$ = EMPTY; }
3967 server_name: ColId { $$ = $1; }
3968 | ColId '.' server_name { $$ = make3_str($1, make_str("."), $3); }
3969 | IP { $$ = make_name(); }
3971 opt_port: ':' PosIntConst { $$ = make2_str(make_str(":"), $2); }
3972 | /* empty */ { $$ = EMPTY; }
3974 opt_connection_name: AS connection_target { $$ = $2; }
3975 | /* empty */ { $$ = make_str("NULL"); }
3977 opt_user: USER ora_user { $$ = $2; }
3978 | /* empty */ { $$ = make_str("NULL,NULL"); }
3982 $$ = cat2_str($1, make_str(", NULL"));
3984 | user_name '/' user_name
3986 $$ = cat_str(3, $1, make_str(","), $3);
3988 | user_name SQL_IDENTIFIED BY user_name
3990 $$ = cat_str(3, $1, make_str(","), $4);
3992 | user_name USING user_name
3994 $$ = cat_str(3, $1, make_str(","), $3);
4001 $$ = make3_str(make_str("\""), $1, make_str("\""));
4006 else if (strcmp($1, "?") == 0) /* variable */
4008 enum ECPGttype type = argsinsert->variable->type->type;
4010 /* if array see what's inside */
4011 if (type == ECPGt_array)
4012 type = argsinsert->variable->type->u.element->type;
4014 /* handle varchars */
4015 if (type == ECPGt_varchar)
4016 $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
4018 $$ = mm_strdup(argsinsert->variable->name);
4021 $$ = make3_str(make_str("\""), $1, make_str("\""));
4024 char_variable: cvariable
4025 { /* check if we have a char variable */
4026 struct variable *p = find_variable($1);
4027 enum ECPGttype type = p->type->type;
4029 /* if array see what's inside */
4030 if (type == ECPGt_array)
4031 type = p->type->u.element->type;
4036 case ECPGt_unsigned_char:
4040 $$ = make2_str($1, make_str(".arr"));
4043 mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
4048 opt_options: Op ColId
4050 if (strlen($1) == 0)
4051 mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
4053 if (strcmp($1, "?") != 0)
4055 sprintf(errortext, "unrecognised token '%s'", $1);
4056 mmerror(PARSE_ERROR, ET_ERROR, errortext);
4059 $$ = make2_str(make_str("?"), $2);
4061 | /* empty */ { $$ = EMPTY; }
4065 * Declare a prepared cursor. The syntax is different from the standard
4066 * declare statement, so we create a new rule.
4068 ECPGCursorStmt: DECLARE name opt_cursor CURSOR FOR ident
4070 struct cursor *ptr, *this;
4071 struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4073 for (ptr = cur; ptr != NULL; ptr = ptr->next)
4075 if (strcmp($2, ptr->name) == 0)
4077 /* re-definition is a bug */
4078 sprintf(errortext, "cursor %s already defined", $2);
4079 mmerror(PARSE_ERROR, ET_ERROR, errortext);
4083 this = (struct cursor *) mm_alloc(sizeof(struct cursor));
4085 /* initial definition */
4088 this->connection = connection;
4089 this->command = cat_str(4, make_str("declare"), mm_strdup($2), $3, make_str("cursor for ?"));
4090 this->argsresult = NULL;
4092 thisquery->type = &ecpg_query;
4093 thisquery->brace_level = 0;
4094 thisquery->next = NULL;
4095 thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($6));
4096 sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $6);
4098 this->argsinsert = NULL;
4099 add_variable(&(this->argsinsert), thisquery, &no_indicator);
4103 $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
4108 * the exec sql deallocate prepare command to deallocate a previously
4109 * prepared statement
4111 ECPGDeallocate: SQL_DEALLOCATE SQL_PREPARE ident { $$ = cat_str(3, make_str("ECPGdeallocate(__LINE__, \""), $3, make_str("\");")); };
4114 * variable declaration inside the exec sql declare block
4116 ECPGDeclaration: sql_startdeclare
4118 fputs("/* exec sql begin declare section */", yyout);
4120 variable_declarations sql_enddeclare
4122 fprintf(yyout, "%s/* exec sql end declare section */", $3);
4124 output_line_number();
4127 sql_startdeclare: ecpgstart BEGIN_TRANS DECLARE SQL_SECTION ';' {};
4129 sql_enddeclare: ecpgstart END_TRANS DECLARE SQL_SECTION ';' {};
4131 variable_declarations: /* empty */ { $$ = EMPTY; }
4132 | declarations { $$ = $1; }
4135 declarations: declaration { $$ = $1; }
4136 | declarations declaration { $$ = cat2_str($1, $2); }
4139 declaration: storage_clause storage_modifier
4141 actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2));
4142 actual_startline[struct_level] = hashline_number();
4146 actual_type[struct_level].type_enum = $4.type_enum;
4147 actual_type[struct_level].type_dimension = $4.type_dimension;
4148 actual_type[struct_level].type_index = $4.type_index;
4150 /* we do not need the string "varchar" for output */
4151 /* so replace it with an empty string */
4152 if ($4.type_enum == ECPGt_varchar)
4160 $$ = cat_str(6, actual_startline[struct_level], $1, $2, $4.type_str, $6, make_str(";\n"));
4163 storage_clause : S_EXTERN { $$ = make_str("extern"); }
4164 | S_STATIC { $$ = make_str("static"); }
4165 | S_REGISTER { $$ = make_str("register"); }
4166 | S_AUTO { $$ = make_str("auto"); }
4167 | /* empty */ { $$ = EMPTY; }
4170 storage_modifier : S_CONST { $$ = make_str("const"); }
4171 | S_VOLATILE { $$ = make_str("volatile"); }
4172 | /* empty */ { $$ = EMPTY; }
4178 $$.type_str = mm_strdup(ECPGtype_name($1));
4179 $$.type_dimension = -1;
4184 $$.type_enum = ECPGt_struct;
4186 $$.type_dimension = -1;
4191 $$.type_enum = ECPGt_union;
4193 $$.type_dimension = -1;
4199 $$.type_enum = ECPGt_int;
4200 $$.type_dimension = -1;
4206 * Check for type names that the SQL grammar treats as
4207 * unreserved keywords
4209 if (strcmp($1, "varchar") == 0)
4211 $$.type_enum = ECPGt_varchar;
4212 $$.type_str = make_str("varchar");
4213 $$.type_dimension = -1;
4216 else if (strcmp($1, "float") == 0)
4218 $$.type_enum = ECPGt_float;
4219 $$.type_str = make_str("float");
4220 $$.type_dimension = -1;
4223 else if (strcmp($1, "double") == 0)
4225 $$.type_enum = ECPGt_double;
4226 $$.type_str = make_str("double");
4227 $$.type_dimension = -1;
4232 /* this is for typedef'ed types */
4233 struct typedefs *this = get_typedef($1);
4235 $$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
4236 $$.type_enum = this->type->type_enum;
4237 $$.type_dimension = this->type->type_dimension;
4238 $$.type_index = this->type->type_index;
4239 struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
4244 enum_type: SQL_ENUM opt_symbol enum_definition
4246 $$ = cat_str(3, make_str("enum"), $2, $3);
4250 $$ = cat2_str(make_str("enum"), $2);
4254 enum_definition: '{' c_list '}' { $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
4256 struct_type: s_struct '{' variable_declarations '}'
4258 ECPGfree_struct_member(struct_member_list[struct_level]);
4259 free(actual_storage[struct_level--]);
4260 $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
4263 union_type: s_union '{' variable_declarations '}'
4265 ECPGfree_struct_member(struct_member_list[struct_level]);
4266 free(actual_storage[struct_level--]);
4267 $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
4270 s_struct: SQL_STRUCT opt_symbol
4272 struct_member_list[struct_level++] = NULL;
4273 $$ = cat2_str(make_str("struct"), $2);
4274 ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), strdup($$), make_str(")"));
4275 if (struct_level >= STRUCT_DEPTH)
4276 mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition");
4279 s_union: UNION opt_symbol
4281 struct_member_list[struct_level++] = NULL;
4282 if (struct_level >= STRUCT_DEPTH)
4283 mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition");
4285 $$ = cat2_str(make_str("union"), $2);
4288 simple_type: unsigned_type { $$=$1; }
4289 | opt_signed signed_type { $$=$2; }
4292 unsigned_type: SQL_UNSIGNED SQL_SHORT { $$ = ECPGt_unsigned_short; }
4293 | SQL_UNSIGNED SQL_SHORT SQL_INT { $$ = ECPGt_unsigned_short; }
4294 | SQL_UNSIGNED { $$ = ECPGt_unsigned_int; }
4295 | SQL_UNSIGNED SQL_INT { $$ = ECPGt_unsigned_int; }
4296 | SQL_UNSIGNED SQL_LONG { $$ = ECPGt_unsigned_long; }
4297 | SQL_UNSIGNED SQL_LONG SQL_INT { $$ = ECPGt_unsigned_long; }
4298 | SQL_UNSIGNED SQL_LONG SQL_LONG {
4299 #ifdef HAVE_LONG_LONG_INT_64
4300 $$ = ECPGt_unsigned_long_long;
4302 $$ = ECPGt_unsigned_long;
4305 | SQL_UNSIGNED SQL_LONG SQL_LONG SQL_INT {
4306 #ifdef HAVE_LONG_LONG_INT_64
4307 $$ = ECPGt_unsigned_long_long;
4309 $$ = ECPGt_unsigned_long;
4312 | SQL_UNSIGNED CHAR { $$ = ECPGt_unsigned_char; }
4315 signed_type: SQL_SHORT { $$ = ECPGt_short; }
4316 | SQL_SHORT SQL_INT { $$ = ECPGt_short; }
4317 | SQL_INT { $$ = ECPGt_int; }
4318 | SQL_LONG { $$ = ECPGt_long; }
4319 | SQL_LONG SQL_INT { $$ = ECPGt_long; }
4320 | SQL_LONG SQL_LONG {
4321 #ifdef HAVE_LONG_LONG_INT_64
4322 $$ = ECPGt_long_long;
4327 | SQL_LONG SQL_LONG SQL_INT {
4328 #ifdef HAVE_LONG_LONG_INT_64
4329 $$ = ECPGt_long_long;
4334 | SQL_BOOL { $$ = ECPGt_bool; }
4335 | CHAR { $$ = ECPGt_char; }
4338 opt_signed: SQL_SIGNED
4342 variable_list: variable
4346 | variable_list ',' variable
4348 $$ = cat_str(3, $1, make_str(","), $3);
4352 variable: opt_pointer ECPGColLabel opt_array_bounds opt_initializer
4354 struct ECPGtype * type;
4355 int dimension = $3.index1; /* dimension of array */
4356 int length = $3.index2; /* lenght of string */
4357 char dim[14L], ascii_len[12];
4359 adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
4361 switch (actual_type[struct_level].type_enum)
4366 type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, ECPGstruct_sizeof);
4368 type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, ECPGstruct_sizeof), dimension);
4370 $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4374 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
4376 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
4386 sprintf(dim, "[%d]", dimension);
4389 sprintf(ascii_len, "%d", length);
4392 mmerror(PARSE_ERROR, ET_ERROR, "pointer to varchar are not implemented");
4395 $$ = 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);
4397 $$ = 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);
4401 case ECPGt_unsigned_char:
4402 if (dimension == -1)
4403 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
4405 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
4407 $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4411 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1);
4413 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, 1), dimension);
4415 $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4419 if (struct_level == 0)
4420 new_variable($2, type);
4422 ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
4427 opt_initializer: /* empty */ { $$ = EMPTY; }
4430 $$ = cat2_str(make_str("="), $2);
4434 opt_pointer: /* empty */ { $$ = EMPTY; }
4435 | '*' { $$ = make_str("*"); }
4436 | '*' '*' { $$ = make_str("**"); }
4440 * As long as the prepare statement is not supported by the backend, we will
4441 * try to simulate it here so we get dynamic SQL
4443 ECPGDeclare: DECLARE STATEMENT ident
4445 /* this is only supported for compatibility */
4446 $$ = cat_str(3, make_str("/* declare statement"), $3, make_str("*/"));
4449 * the exec sql disconnect statement: disconnect from the given database
4451 ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
4453 dis_name: connection_object { $$ = $1; }
4454 | CURRENT { $$ = make_str("\"CURRENT\""); }
4455 | ALL { $$ = make_str("\"ALL\""); }
4456 | /* empty */ { $$ = make_str("\"CURRENT\""); }
4459 connection_object: connection_target { $$ = $1; }
4460 | DEFAULT { $$ = make_str("\"DEFAULT\""); }
4464 * execute a given string as sql command
4466 ECPGExecute : EXECUTE IMMEDIATE execstring
4468 struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4470 thisquery->type = &ecpg_query;
4471 thisquery->brace_level = 0;
4472 thisquery->next = NULL;
4473 thisquery->name = $3;
4475 add_variable(&argsinsert, thisquery, &no_indicator);
4481 struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4483 thisquery->type = &ecpg_query;
4484 thisquery->brace_level = 0;
4485 thisquery->next = NULL;
4486 thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($2));
4487 sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2);
4489 add_variable(&argsinsert, thisquery, &no_indicator);
4490 } ecpg_using opt_ecpg_into
4496 execstring: char_variable { $$ = $1; }
4497 | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
4501 * the exec sql free command to deallocate a previously
4502 * prepared statement
4504 ECPGFree: SQL_FREE ident { $$ = $2; };
4507 * open is an open cursor, at the moment this has to be removed
4509 ECPGOpen: SQL_OPEN name ecpg_using { $$ = $2; };
4511 ecpg_using: /* empty */ { $$ = EMPTY; }
4512 | USING variablelist {
4513 /* mmerror ("open cursor with variables not implemented yet"); */
4518 opt_sql: /* empty */ | SQL_SQL;
4520 ecpg_into: INTO into_list {
4523 | INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
4525 add_variable(&argsresult, descriptor_variable($4,0), &no_indicator);
4530 opt_ecpg_into: /* empty */ { $$ = EMPTY; }
4531 | ecpg_into { $$ = $1; }
4534 variable: civarind | civar
4535 variablelist: variable | variable ',' variablelist;
4538 * As long as the prepare statement is not supported by the backend, we will
4539 * try to simulate it here so we get dynamic SQL
4541 ECPGPrepare: SQL_PREPARE ident FROM execstring
4543 $$ = cat2_str(make3_str(make_str("\""), $2, make_str("\",")), $4);
4547 * dynamic SQL: descriptor based access
4548 * written by Christof Petig <christof.petig@wtal.de>
4552 * deallocate a descriptor
4554 ECPGDeallocateDescr: SQL_DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
4556 drop_descriptor($3,connection);
4561 * allocate a descriptor
4563 ECPGAllocateDescr: SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
4565 add_descriptor($3,connection);
4570 * read from descriptor
4573 ECPGGetDescHeaderItem: cvariable '=' desc_header_item { push_assignment($1, $3); };
4575 desc_header_item: SQL_COUNT { $$ = ECPGd_count; };
4577 ECPGGetDescItem: cvariable '=' descriptor_item { push_assignment($1, $3); };
4579 descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; }
4580 | SQL_DATA { $$ = ECPGd_data; }
4581 | SQL_DATETIME_INTERVAL_CODE { $$ = ECPGd_di_code; }
4582 | SQL_DATETIME_INTERVAL_PRECISION { $$ = ECPGd_di_precision; }
4583 | SQL_INDICATOR { $$ = ECPGd_indicator; }
4584 | SQL_KEY_MEMBER { $$ = ECPGd_key_member; }
4585 | SQL_LENGTH { $$ = ECPGd_length; }
4586 | SQL_NAME { $$ = ECPGd_name; }
4587 | SQL_NULLABLE { $$ = ECPGd_nullable; }
4588 | SQL_OCTET_LENGTH { $$ = ECPGd_octet; }
4589 | PRECISION { $$ = ECPGd_precision; }
4590 | SQL_RETURNED_LENGTH { $$ = ECPGd_length; }
4591 | SQL_RETURNED_OCTET_LENGTH { $$ = ECPGd_ret_octet; }
4592 | SQL_SCALE { $$ = ECPGd_scale; }
4593 | TYPE_P { $$ = ECPGd_type; }
4596 ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
4597 | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
4600 ECPGGetDescItems: ECPGGetDescItem
4601 | ECPGGetDescItems ',' ECPGGetDescItem
4604 ECPGGetDescriptorHeader: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
4607 ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE cvariable ECPGGetDescItems
4608 { $$.str = $5; $$.name = $3; }
4609 | SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE Iconst ECPGGetDescItems
4610 { $$.str = $5; $$.name = $3; }
4614 * for compatibility with ORACLE we will also allow the keyword RELEASE
4615 * after a transaction statement to disconnect from the database.
4618 ECPGRelease: TransactionStmt SQL_RELEASE
4620 if (strcmp($1, "begin") == 0)
4621 mmerror(PARSE_ERROR, ET_ERROR, "RELEASE does not make sense when beginning a transaction");
4623 fprintf(yyout, "ECPGtrans(__LINE__, %s, \"%s\");",
4624 connection ? connection : "NULL", $1);
4626 fprintf(yyout, "ECPGdisconnect(__LINE__, \"\");");
4632 * set/reset the automatic transaction mode, this needs a differnet handling
4633 * as the other set commands
4635 ECPGSetAutocommit: SET SQL_AUTOCOMMIT to_equal on_off
4640 on_off: ON { $$ = make_str("on"); }
4641 | OFF { $$ = make_str("off"); }
4647 * set the actual connection, this needs a differnet handling as the other
4650 ECPGSetConnection: SET SQL_CONNECTION to_equal connection_object
4656 * define a new type for embedded SQL
4660 /* reset this variable so we see if there was */
4661 /* an initializer specified */
4664 ColLabel IS type opt_type_array_bounds opt_reference
4666 /* add entry to list */
4667 struct typedefs *ptr, *this;
4668 int dimension = $6.index1;
4669 int length = $6.index2;
4671 if (($5.type_enum == ECPGt_struct ||
4672 $5.type_enum == ECPGt_union) &&
4675 mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
4679 for (ptr = types; ptr != NULL; ptr = ptr->next)
4681 if (strcmp($3, ptr->name) == 0)
4683 /* re-definition is a bug */
4684 sprintf(errortext, "Type %s already defined", $3);
4685 mmerror(PARSE_ERROR, ET_ERROR, errortext);
4689 adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0);
4691 this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
4693 /* initial definition */
4696 this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
4697 this->type->type_enum = $5.type_enum;
4698 this->type->type_str = mm_strdup($3);
4699 this->type->type_dimension = dimension; /* dimension of array */
4700 this->type->type_index = length; /* lenght of string */
4701 this->struct_member_list = ($5.type_enum == ECPGt_struct || $5.type_enum == ECPGt_union) ?
4702 struct_member_list[struct_level] : NULL;
4704 if ($5.type_enum != ECPGt_varchar &&
4705 $5.type_enum != ECPGt_char &&
4706 $5.type_enum != ECPGt_unsigned_char &&
4707 this->type->type_index >= 0)
4708 mmerror(PARSE_ERROR, ET_ERROR, "No multi-dimensional array support for simple data types");
4713 $$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
4716 opt_type_array_bounds: '[' ']' opt_type_array_bounds
4719 $$.index2 = $3.index1;
4720 $$.str = cat2_str(make_str("[]"), $3.str);
4722 | '(' ')' opt_type_array_bounds
4725 $$.index2 = $3.index1;
4726 $$.str = cat2_str(make_str("[]"), $3.str);
4728 | '[' Iresult ']' opt_type_array_bounds
4730 char *txt = mm_alloc(20L);
4732 sprintf (txt, "%d", $2);
4734 $$.index2 = $4.index1;
4735 $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
4737 | '(' Iresult ')' opt_type_array_bounds
4739 char *txt = mm_alloc(20L);
4741 sprintf (txt, "%d", $2);
4743 $$.index2 = $4.index1;
4744 $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
4754 opt_reference: SQL_REFERENCE { $$ = make_str("reference"); }
4755 | /* empty */ { $$ = EMPTY; }
4759 * define the type of one variable for embedded SQL
4763 /* reset this variable so we see if there was */
4764 /* an initializer specified */
4767 ColLabel IS type opt_type_array_bounds opt_reference
4769 struct variable *p = find_variable($3);
4770 int dimension = $6.index1;
4771 int length = $6.index2;
4772 struct ECPGtype * type;
4774 if (($5.type_enum == ECPGt_struct ||
4775 $5.type_enum == ECPGt_union) &&
4778 mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
4782 adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0);
4784 switch ($5.type_enum)
4789 type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, ECPGstruct_sizeof);
4791 type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, ECPGstruct_sizeof), dimension);
4794 if (dimension == -1)
4795 type = ECPGmake_simple_type($5.type_enum, length);
4797 type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length), dimension);
4801 case ECPGt_unsigned_char:
4802 if (dimension == -1)
4803 type = ECPGmake_simple_type($5.type_enum, length);
4805 type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length), dimension);
4810 mmerror(PARSE_ERROR, ET_ERROR, "No multi-dimensional array support for simple data types");
4813 type = ECPGmake_simple_type($5.type_enum, 1);
4815 type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, 1), dimension);
4820 ECPGfree_type(p->type);
4824 $$ = cat_str(7, make_str("/* exec sql var"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
4828 * whenever statement: decide what to do in case of error/no data found
4829 * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
4831 ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
4833 when_error.code = $<action>3.code;
4834 when_error.command = $<action>3.command;
4835 $$ = cat_str(3, make_str("/* exec sql whenever sqlerror "), $3.str, make_str("; */\n"));
4837 | SQL_WHENEVER NOT SQL_FOUND action
4839 when_nf.code = $<action>4.code;
4840 when_nf.command = $<action>4.command;
4841 $$ = cat_str(3, make_str("/* exec sql whenever not found "), $4.str, make_str("; */\n"));
4843 | SQL_WHENEVER SQL_SQLWARNING action
4845 when_warn.code = $<action>3.code;
4846 when_warn.command = $<action>3.command;
4847 $$ = cat_str(3, make_str("/* exec sql whenever sql_warning "), $3.str, make_str("; */\n"));
4851 action : SQL_CONTINUE
4853 $<action>$.code = W_NOTHING;
4854 $<action>$.command = NULL;
4855 $<action>$.str = make_str("continue");
4859 $<action>$.code = W_SQLPRINT;
4860 $<action>$.command = NULL;
4861 $<action>$.str = make_str("sqlprint");
4865 $<action>$.code = W_STOP;
4866 $<action>$.command = NULL;
4867 $<action>$.str = make_str("stop");
4871 $<action>$.code = W_GOTO;
4872 $<action>$.command = strdup($2);
4873 $<action>$.str = cat2_str(make_str("goto "), $2);
4877 $<action>$.code = W_GOTO;
4878 $<action>$.command = strdup($3);
4879 $<action>$.str = cat2_str(make_str("goto "), $3);
4881 | DO name '(' c_args ')'
4883 $<action>$.code = W_DO;
4884 $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
4885 $<action>$.str = cat2_str(make_str("do"), mm_strdup($<action>$.command));
4889 $<action>$.code = W_BREAK;
4890 $<action>$.command = NULL;
4891 $<action>$.str = make_str("break");
4893 | SQL_CALL name '(' c_args ')'
4895 $<action>$.code = W_DO;
4896 $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
4897 $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
4901 /* some other stuff for ecpg */
4903 /* additional unreserved keywords */
4904 ECPGKeywords: SQL_BREAK { $$ = make_str("break"); }
4905 | SQL_CALL { $$ = make_str("call"); }
4906 | SQL_CARDINALITY { $$ = make_str("cardinality"); }
4907 | SQL_CONNECT { $$ = make_str("connect"); }
4908 | SQL_CONTINUE { $$ = make_str("continue"); }
4909 | SQL_COUNT { $$ = make_str("count"); }
4910 | SQL_DATA { $$ = make_str("data"); }
4911 | SQL_DATETIME_INTERVAL_CODE { $$ = make_str("datetime_interval_code"); }
4912 | SQL_DATETIME_INTERVAL_PRECISION { $$ = make_str("datetime_interval_precision"); }
4913 | SQL_DEALLOCATE { $$ = make_str("deallocate"); }
4914 | SQL_DISCONNECT { $$ = make_str("disconnect"); }
4915 | SQL_FOUND { $$ = make_str("found"); }
4916 | SQL_GO { $$ = make_str("go"); }
4917 | SQL_GOTO { $$ = make_str("goto"); }
4918 | SQL_IDENTIFIED { $$ = make_str("identified"); }
4919 | SQL_INDICATOR { $$ = make_str("indicator"); }
4920 | SQL_KEY_MEMBER { $$ = make_str("key_member"); }
4921 | SQL_LENGTH { $$ = make_str("length"); }
4922 | SQL_NAME { $$ = make_str("name"); }
4923 | SQL_NULLABLE { $$ = make_str("nullable"); }
4924 | SQL_OCTET_LENGTH { $$ = make_str("octet_length"); }
4925 | SQL_OPEN { $$ = make_str("open"); }
4926 | SQL_PREPARE { $$ = make_str("prepare"); }
4927 | SQL_RELEASE { $$ = make_str("release"); }
4928 | SQL_RETURNED_LENGTH { $$ = make_str("returned_length"); }
4929 | SQL_RETURNED_OCTET_LENGTH { $$ = make_str("returned_octet_length"); }
4930 | SQL_SCALE { $$ = make_str("scale"); }
4931 | SQL_SECTION { $$ = make_str("section"); }
4932 | SQL_SQLERROR { $$ = make_str("sqlerror"); }
4933 | SQL_SQLPRINT { $$ = make_str("sqlprint"); }
4934 | SQL_SQLWARNING { $$ = make_str("sqlwarning"); }
4935 | SQL_STOP { $$ = make_str("stop"); }
4936 | SQL_VAR { $$ = make_str("var"); }
4937 | SQL_WHENEVER { $$ = make_str("whenever"); }
4940 /* additional keywords that can be SQL type names (but not ECPGColLabels) */
4941 ECPGTypeName: SQL_BOOL { $$ = make_str("bool"); }
4942 | SQL_INT { $$ = make_str("int"); }
4943 | SQL_LONG { $$ = make_str("long"); }
4944 | SQL_SHORT { $$ = make_str("short"); }
4945 | SQL_STRUCT { $$ = make_str("struct"); }
4946 | SQL_SIGNED { $$ = make_str("signed"); }
4947 | SQL_UNSIGNED { $$ = make_str("unsigned"); }
4950 opt_symbol: symbol { $$ = $1; }
4951 | /*EMPTY*/ { $$ = EMPTY; }
4954 symbol: ColLabel { $$ = $1; };
4957 * Name classification hierarchy.
4959 * IDENT is the lexeme returned by the lexer for identifiers that match
4960 * no known keyword. In most cases, we can accept certain keywords as
4961 * names, not only IDENTs. We prefer to accept as many such keywords
4962 * as possible to minimize the impact of "reserved words" on programmers.
4963 * So, we divide names into several possible classes. The classification
4964 * is chosen in part to make keywords acceptable as names wherever possible.
4967 /* Column identifier --- names that can be column, table, etc names.
4969 ColId: ident { $$ = $1; }
4970 | unreserved_keyword { $$ = $1; }
4971 | col_name_keyword { $$ = $1; }
4972 | ECPGKeywords { $$ = $1; }
4973 | CHAR { $$ = make_str("char"); }
4976 /* Type identifier --- names that can be type names.
4978 type_name: ident { $$ = $1; }
4979 | unreserved_keyword { $$ = $1; }
4980 | ECPGKeywords { $$ = $1; }
4981 | ECPGTypeName { $$ = $1; }
4984 /* Function identifier --- names that can be function names.
4986 func_name: ident { $$ = $1; }
4987 | unreserved_keyword { $$ = $1; }
4988 | func_name_keyword { $$ = $1; }
4989 | ECPGKeywords { $$ = $1; }
4992 /* Column label --- allowed labels in "AS" clauses.
4993 * This presently includes *all* Postgres keywords.
4995 ColLabel: ECPGColLabel { $$ = $1; }
4996 | ECPGTypeName { $$ = $1; }
4997 | CHAR { $$ = make_str("char"); }
4998 | UNION { $$ = make_str("union"); }
5001 ECPGColLabel: ident { $$ = $1; }
5002 | unreserved_keyword { $$ = $1; }
5003 | col_name_keyword { $$ = $1; }
5004 | func_name_keyword { $$ = $1; }
5005 | reserved_keyword { $$ = $1; }
5006 | ECPGKeywords { $$ = $1; }
5011 * Keyword classification lists. Generally, every keyword present in
5012 * the Postgres grammar should appear in exactly one of these lists.
5014 * Put a new keyword into the first list that it can go into without causing
5015 * shift or reduce conflicts. The earlier lists define "less reserved"
5016 * categories of keywords.
5019 /* "Unreserved" keywords --- available for use as any kind of name.
5022 ABORT_TRANS { $$ = make_str("abort"); }
5023 | ABSOLUTE { $$ = make_str("absolute"); }
5024 | ACCESS { $$ = make_str("access"); }
5025 | ACTION { $$ = make_str("action"); }
5026 | ADD { $$ = make_str("add"); }
5027 | AFTER { $$ = make_str("after"); }
5028 | AGGREGATE { $$ = make_str("aggregate"); }
5029 | ALTER { $$ = make_str("alter"); }
5030 | AT { $$ = make_str("at"); }
5031 | AUTHORIZATION { $$ = make_str("authorization"); }
5032 | BACKWARD { $$ = make_str("backward"); }
5033 | BEFORE { $$ = make_str("before"); }
5034 | BEGIN_TRANS { $$ = make_str("begin"); }
5035 | BY { $$ = make_str("by"); }
5036 | CACHE { $$ = make_str("cache"); }
5037 | CASCADE { $$ = make_str("cascade"); }
5038 | CHAIN { $$ = make_str("chain"); }
5039 | CHARACTERISTICS { $$ = make_str("characteristics"); }
5040 | CHECKPOINT { $$ = make_str("checkpoint"); }
5041 | CLOSE { $$ = make_str("close"); }
5042 | CLUSTER { $$ = make_str("cluster"); }
5043 | COMMENT { $$ = make_str("comment"); }
5044 | COMMIT { $$ = make_str("commit"); }
5045 | COMMITTED { $$ = make_str("committed"); }
5046 | CONSTRAINTS { $$ = make_str("constraints"); }
5047 | COPY { $$ = make_str("copy"); }
5048 | CREATE { $$ = make_str("create"); }
5049 | CREATEDB { $$ = make_str("createdb"); }
5050 | CREATEUSER { $$ = make_str("createuser"); }
5051 | CURSOR { $$ = make_str("cursor"); }
5052 | CYCLE { $$ = make_str("cycle"); }
5053 | DATABASE { $$ = make_str("database"); }
5054 | DAY_P { $$ = make_str("day"); }
5055 | DECLARE { $$ = make_str("declare"); }
5056 | DEFERRED { $$ = make_str("deferred"); }
5057 | DELETE { $$ = make_str("delete"); }
5058 | DELIMITERS { $$ = make_str("delimiters"); }
5059 | DOUBLE { $$ = make_str("double"); }
5060 | DROP { $$ = make_str("drop"); }
5061 | EACH { $$ = make_str("each"); }
5062 | ENCODING { $$ = make_str("encoding"); }
5063 | ENCRYPTED { $$ = make_str("encrypted"); }
5064 | ESCAPE { $$ = make_str("escape"); }
5065 | EXCLUSIVE { $$ = make_str("exclusive"); }
5066 | EXECUTE { $$ = make_str("execute"); }
5067 | EXPLAIN { $$ = make_str("explain"); }
5068 | FETCH { $$ = make_str("fetch"); }
5069 | FORCE { $$ = make_str("force"); }
5070 | FORWARD { $$ = make_str("forward"); }
5071 | FUNCTION { $$ = make_str("function"); }
5072 | GLOBAL { $$ = make_str("global"); }
5073 | GRANT { $$ = make_str("grant"); }
5074 | HANDLER { $$ = make_str("handler"); }
5075 | HOUR_P { $$ = make_str("hour"); }
5076 | IMMEDIATE { $$ = make_str("immediate"); }
5077 | INCREMENT { $$ = make_str("increment"); }
5078 | INDEX { $$ = make_str("index"); }
5079 | INHERITS { $$ = make_str("inherits"); }
5080 | INOUT { $$ = make_str("inout"); }
5081 | INSENSITIVE { $$ = make_str("insensitive"); }
5082 | INSERT { $$ = make_str("insert"); }
5083 | INSTEAD { $$ = make_str("instead"); }
5084 | ISOLATION { $$ = make_str("isolation"); }
5085 | KEY { $$ = make_str("key"); }
5086 | LANGUAGE { $$ = make_str("language"); }
5087 | LANCOMPILER { $$ = make_str("lancompiler"); }
5088 | LEVEL { $$ = make_str("level"); }
5089 | LISTEN { $$ = make_str("listen"); }
5090 | LOAD { $$ = make_str("load"); }
5091 | LOCAL { $$ = make_str("local"); }
5092 | LOCATION { $$ = make_str("location"); }
5093 | LOCK_P { $$ = make_str("lock"); }
5094 | MATCH { $$ = make_str("match"); }
5095 | MAXVALUE { $$ = make_str("maxvalue"); }
5096 | MINUTE_P { $$ = make_str("minute"); }
5097 | MINVALUE { $$ = make_str("minvalue"); }
5098 | MODE { $$ = make_str("mode"); }
5099 | MONTH_P { $$ = make_str("month"); }
5100 | MOVE { $$ = make_str("move"); }
5101 | NAMES { $$ = make_str("names"); }
5102 | NATIONAL { $$ = make_str("national"); }
5103 | NEXT { $$ = make_str("next"); }
5104 | NO { $$ = make_str("no"); }
5105 | NOCREATEDB { $$ = make_str("nocreatedb"); }
5106 | NOCREATEUSER { $$ = make_str("nocreateuser"); }
5107 | NOTHING { $$ = make_str("nothing"); }
5108 | NOTIFY { $$ = make_str("notify"); }
5109 | OF { $$ = make_str("of"); }
5110 | OIDS { $$ = make_str("oids"); }
5111 | OPERATOR { $$ = make_str("operator"); }
5112 | OPTION { $$ = make_str("option"); }
5113 | OUT { $$ = make_str("out"); }
5114 | OWNER { $$ = make_str("owner"); }
5115 | PARTIAL { $$ = make_str("partial"); }
5116 | PASSWORD { $$ = make_str("password"); }
5117 | PATH_P { $$ = make_str("path"); }
5118 | PENDANT { $$ = make_str("pendant"); }
5119 | PRECISION { $$ = make_str("precision"); }
5120 | PRIOR { $$ = make_str("prior"); }
5121 | PRIVILEGES { $$ = make_str("privileges"); }
5122 | PROCEDURAL { $$ = make_str("procedural"); }
5123 | PROCEDURE { $$ = make_str("procedure"); }
5124 | READ { $$ = make_str("read"); }
5125 | REINDEX { $$ = make_str("reindex"); }
5126 | RELATIVE { $$ = make_str("relative"); }
5127 | RENAME { $$ = make_str("rename"); }
5128 | REPLACE { $$ = make_str("replace"); }
5129 | RESET { $$ = make_str("reset"); }
5130 | RESTRICT { $$ = make_str("restrict"); }
5131 | RETURNS { $$ = make_str("returns"); }
5132 | REVOKE { $$ = make_str("revoke"); }
5133 | ROLLBACK { $$ = make_str("rollback"); }
5134 | ROW { $$ = make_str("row"); }
5135 | RULE { $$ = make_str("rule"); }
5136 | SCHEMA { $$ = make_str("schema"); }
5137 | SCROLL { $$ = make_str("scroll"); }
5138 | SECOND_P { $$ = make_str("second"); }
5139 | SESSION { $$ = make_str("session"); }
5140 | SEQUENCE { $$ = make_str("sequence"); }
5141 | SERIALIZABLE { $$ = make_str("serializable"); }
5142 | SET { $$ = make_str("set"); }
5143 | SHARE { $$ = make_str("share"); }
5144 | SHOW { $$ = make_str("show"); }
5145 | START { $$ = make_str("start"); }
5146 | STATEMENT { $$ = make_str("statement"); }
5147 | STATISTICS { $$ = make_str("statistics"); }
5148 | STDIN { $$ = make_str("stdin"); }
5149 | STDOUT { $$ = make_str("stdout"); }
5150 | SYSID { $$ = make_str("sysid"); }
5151 | TEMP { $$ = make_str("temp"); }
5152 | TEMPLATE { $$ = make_str("template"); }
5153 | TEMPORARY { $$ = make_str("temporary"); }
5154 | TOAST { $$ = make_str("toast"); }
5155 | TRANSACTION { $$ = make_str("transaction"); }
5156 | TRIGGER { $$ = make_str("trigger"); }
5157 | TRUNCATE { $$ = make_str("truncate"); }
5158 | TRUSTED { $$ = make_str("trusted"); }
5159 | TYPE_P { $$ = make_str("type"); }
5160 | UNENCRYPTED { $$ = make_str("unencrypted"); }
5161 | UNKNOWN { $$ = make_str("unknown"); }
5162 | UNLISTEN { $$ = make_str("unlisten"); }
5163 | UNTIL { $$ = make_str("until"); }
5164 | UPDATE { $$ = make_str("update"); }
5165 | VACUUM { $$ = make_str("vacuum"); }
5166 | VALID { $$ = make_str("valid"); }
5167 | VALUES { $$ = make_str("values"); }
5168 | VARYING { $$ = make_str("varying"); }
5169 | VERSION { $$ = make_str("version"); }
5170 | VIEW { $$ = make_str("view"); }
5171 | WITH { $$ = make_str("with"); }
5172 | WITHOUT { $$ = make_str("without"); }
5173 | WORK { $$ = make_str("work"); }
5174 | YEAR_P { $$ = make_str("year"); }
5175 | ZONE { $$ = make_str("zone"); }
5178 /* Column identifier --- keywords that can be column, table, etc names.
5180 * Many of these keywords will in fact be recognized as type or function
5181 * names too; but they have special productions for the purpose, and so
5182 * can't be treated as "generic" type or function names.
5184 * The type names appearing here are not usable as function names
5185 * because they can be followed by '(' in typename productions, which
5186 * looks too much like a function call for an LR(1) parser.
5189 BIT { $$ = make_str("bit"); }
5190 /* CHAR must be excluded from ECPGColLabel because of conflict with UNSIGNED
5191 | CHAR { $$ = make_str("char"); }
5193 | CHARACTER { $$ = make_str("character"); }
5194 | COALESCE { $$ = make_str("coalesce"); }
5195 | DEC { $$ = make_str("dec"); }
5196 | DECIMAL { $$ = make_str("decimal"); }
5197 | EXISTS { $$ = make_str("exists"); }
5198 | EXTRACT { $$ = make_str("extract"); }
5199 | FLOAT { $$ = make_str("float"); }
5200 | INTERVAL { $$ = make_str("interval"); }
5201 | NCHAR { $$ = make_str("nchar"); }
5202 | NONE { $$ = make_str("none"); }
5203 | NULLIF { $$ = make_str("nullif"); }
5204 | NUMERIC { $$ = make_str("numeric"); }
5205 | POSITION { $$ = make_str("position"); }
5206 | SETOF { $$ = make_str("setof"); }
5207 | SUBSTRING { $$ = make_str("substring"); }
5208 | TIME { $$ = make_str("time"); }
5209 | TIMESTAMP { $$ = make_str("timestamp"); }
5210 | TRIM { $$ = make_str("trim"); }
5211 | VARCHAR { $$ = make_str("varchar"); }
5214 /* Function identifier --- keywords that can be function names.
5216 * Most of these are keywords that are used as operators in expressions;
5217 * in general such keywords can't be column names because they would be
5218 * ambiguous with variables, but they are unambiguous as function identifiers.
5220 * Do not include POSITION, SUBSTRING, etc here since they have explicit
5221 * productions in a_expr to support the goofy SQL9x argument syntax.
5222 * - thomas 2000-11-28
5225 BETWEEN { $$ = make_str("between"); }
5226 | BINARY { $$ = make_str("binary"); }
5227 | CROSS { $$ = make_str("cross"); }
5228 | FREEZE { $$ = make_str("freeze"); }
5229 | FULL { $$ = make_str("full"); }
5230 | ILIKE { $$ = make_str("ilike"); }
5231 | IN { $$ = make_str("in"); }
5232 | INNER_P { $$ = make_str("inner"); }
5233 | IS { $$ = make_str("is"); }
5234 | ISNULL { $$ = make_str("isnull"); }
5235 | JOIN { $$ = make_str("join"); }
5236 | LEFT { $$ = make_str("left"); }
5237 | LIKE { $$ = make_str("like"); }
5238 | NATURAL { $$ = make_str("natural"); }
5239 | NOTNULL { $$ = make_str("notnull"); }
5240 | OUTER_P { $$ = make_str("outer"); }
5241 | OVERLAPS { $$ = make_str("overlaps"); }
5242 | PUBLIC { $$ = make_str("public"); }
5243 | RIGHT { $$ = make_str("right"); }
5244 | VERBOSE { $$ = make_str("verbose"); }
5247 /* Reserved keyword --- these keywords are usable only as a ColLabel.
5249 * Keywords appear here if they could not be distinguished from variable,
5250 * type, or function names in some contexts. Don't put things here unless
5254 ALL { $$ = make_str("all"); }
5255 | ANALYSE { $$ = make_str("analyse"); } /* British */
5256 | ANALYZE { $$ = make_str("analyze"); }
5257 | AND { $$ = make_str("and"); }
5258 | ANY { $$ = make_str("any"); }
5259 | AS { $$ = make_str("as"); }
5260 | ASC { $$ = make_str("asc"); }
5261 | BOTH { $$ = make_str("both"); }
5262 | CASE { $$ = make_str("case"); }
5263 | CAST { $$ = make_str("cast"); }
5264 | CHECK { $$ = make_str("check"); }
5265 | COLLATE { $$ = make_str("collate"); }
5266 | COLUMN { $$ = make_str("column"); }
5267 | CONSTRAINT { $$ = make_str("constraint"); }
5268 | CURRENT_DATE { $$ = make_str("current_date"); }
5269 | CURRENT_TIME { $$ = make_str("current_time"); }
5270 | CURRENT_TIMESTAMP { $$ = make_str("current_timestamp"); }
5271 | CURRENT_USER { $$ = make_str("current_user"); }
5272 | DEFAULT { $$ = make_str("default"); }
5273 | DEFERRABLE { $$ = make_str("deferrable"); }
5274 | DESC { $$ = make_str("desc"); }
5275 | DISTINCT { $$ = make_str("distinct"); }
5276 | DO { $$ = make_str("do"); }
5277 | ELSE { $$ = make_str("else"); }
5278 | END_TRANS { $$ = make_str("end"); }
5279 | EXCEPT { $$ = make_str("except"); }
5280 | FALSE_P { $$ = make_str("false"); }
5281 | FOR { $$ = make_str("for"); }
5282 | FOREIGN { $$ = make_str("foreign"); }
5283 | FROM { $$ = make_str("from"); }
5284 | GROUP { $$ = make_str("group"); }
5285 | HAVING { $$ = make_str("having"); }
5286 | INITIALLY { $$ = make_str("initially"); }
5287 | INTERSECT { $$ = make_str("intersect"); }
5288 | INTO { $$ = make_str("into"); }
5289 | LEADING { $$ = make_str("leading"); }
5290 | LIMIT { $$ = make_str("limit"); }
5291 | NEW { $$ = make_str("new"); }
5292 | NOT { $$ = make_str("not"); }
5293 | NULL_P { $$ = make_str("null"); }
5294 | OFF { $$ = make_str("off"); }
5295 | OFFSET { $$ = make_str("offset"); }
5296 | OLD { $$ = make_str("old"); }
5297 | ON { $$ = make_str("on"); }
5298 | ONLY { $$ = make_str("only"); }
5299 | OR { $$ = make_str("or"); }
5300 | ORDER { $$ = make_str("order"); }
5301 | PRIMARY { $$ = make_str("primary"); }
5302 | REFERENCES { $$ = make_str("references"); }
5303 | SELECT { $$ = make_str("select"); }
5304 | SESSION_USER { $$ = make_str("session_user"); }
5305 | SOME { $$ = make_str("some"); }
5306 | TABLE { $$ = make_str("table"); }
5307 | THEN { $$ = make_str("then"); }
5308 | TO { $$ = make_str("to"); }
5309 | TRAILING { $$ = make_str("trailing"); }
5310 | TRUE_P { $$ = make_str("true"); }
5311 /* UNION must be excluded from ECPGColLabel because of conflict with s_union
5312 | UNION { $$ = make_str("union"); }
5314 | UNIQUE { $$ = make_str("unique"); }
5315 | USER { $$ = make_str("user"); }
5316 | USING { $$ = make_str("using"); }
5317 | WHEN { $$ = make_str("when"); }
5318 | WHERE { $$ = make_str("where"); }
5322 into_list : coutputvariable | into_list ',' coutputvariable;
5324 ecpgstart: SQL_START { reset_variables(); };
5326 c_args: /* empty */ { $$ = EMPTY; }
5327 | c_list { $$ = $1; }
5330 coutputvariable: cvariable indicator
5332 add_variable(&argsresult, find_variable($1), find_variable($2));
5336 add_variable(&argsresult, find_variable($1), &no_indicator);
5341 civarind: cvariable indicator
5343 if ($2 != NULL && (find_variable($2))->type->type == ECPGt_array)
5344 mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
5346 add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
5351 add_variable(&argsinsert, find_variable($1), &no_indicator);
5355 cvariable: CVARIABLE { $$ = $1; }
5357 indicator: CVARIABLE { check_indicator((find_variable($1))->type); $$ = $1; }
5358 | SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; }
5359 | SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
5362 ident: IDENT { $$ = $1; }
5363 | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5366 quoted_ident_stringvar: IDENT { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5367 | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5369 { $$ = make3_str(make_str("("), $1, make_str(")"));
5377 cpp_line: CPP_LINE { $$ = $1; };
5379 c_stuff: c_anything { $$ = $1; }
5380 | c_stuff c_anything
5382 $$ = cat2_str($1, $2);
5384 | c_stuff '(' c_stuff ')'
5386 $$ = cat_str(4, $1, make_str("("), $3, make_str(")"));
5390 $$ = cat_str(3, $1, make_str("("), make_str(")"));
5394 $$ = cat_str(3, make_str("("), $2, make_str(")"));
5396 | '(' c_stuff ')' c_stuff
5398 $$ = cat_str(4, make_str("("), $2, make_str(")"), $4);
5402 c_list: c_term { $$ = $1; }
5403 | c_list ',' c_term { $$ = cat_str(3, $1, make_str(","), $3); }
5406 c_term: c_stuff { $$ = $1; }
5407 | '{' c_list '}' { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
5410 c_thing: c_anything { $$ = $1; }
5411 | '(' { $$ = make_str("("); }
5412 | ')' { $$ = make_str(")"); }
5413 | ',' { $$ = make_str(","); }
5414 | ';' { $$ = make_str(";"); }
5417 c_anything: IDENT { $$ = $1; }
5418 | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5419 | PosIntConst { $$ = $1; }
5420 | Fconst { $$ = $1; }
5421 | Sconst { $$ = $1; }
5422 | '*' { $$ = make_str("*"); }
5423 | '+' { $$ = make_str("+"); }
5424 | '-' { $$ = make_str("-"); }
5425 | '/' { $$ = make_str("/"); }
5426 | '%' { $$ = make_str("%"); }
5427 | NULL_P { $$ = make_str("NULL"); }
5428 | S_ADD { $$ = make_str("+="); }
5429 | S_AND { $$ = make_str("&&"); }
5430 | S_ANYTHING { $$ = make_name(); }
5431 | S_AUTO { $$ = make_str("auto"); }
5432 | S_CONST { $$ = make_str("const"); }
5433 | S_DEC { $$ = make_str("--"); }
5434 | S_DIV { $$ = make_str("/="); }
5435 | S_DOTPOINT { $$ = make_str(".*"); }
5436 | S_EQUAL { $$ = make_str("=="); }
5437 | S_EXTERN { $$ = make_str("extern"); }
5438 | S_INC { $$ = make_str("++"); }
5439 | S_LSHIFT { $$ = make_str("<<"); }
5440 | S_MEMBER { $$ = make_str("->"); }
5441 | S_MEMPOINT { $$ = make_str("->*"); }
5442 | S_MOD { $$ = make_str("%="); }
5443 | S_MUL { $$ = make_str("*="); }
5444 | S_NEQUAL { $$ = make_str("!="); }
5445 | S_OR { $$ = make_str("||"); }
5446 | S_REGISTER { $$ = make_str("register"); }
5447 | S_RSHIFT { $$ = make_str(">>"); }
5448 | S_STATIC { $$ = make_str("static"); }
5449 | S_SUB { $$ = make_str("-="); }
5450 | SQL_BOOL { $$ = make_str("bool"); }
5451 | SQL_ENUM { $$ = make_str("enum"); }
5452 | SQL_INT { $$ = make_str("int"); }
5453 | SQL_LONG { $$ = make_str("long"); }
5454 | SQL_SHORT { $$ = make_str("short"); }
5455 | SQL_SIGNED { $$ = make_str("signed"); }
5456 | SQL_STRUCT { $$ = make_str("struct"); }
5457 | SQL_UNSIGNED { $$ = make_str("unsigned"); }
5458 | CHAR { $$ = make_str("char"); }
5459 | DOUBLE { $$ = make_str("double"); }
5460 | FLOAT { $$ = make_str("float"); }
5461 | UNION { $$ = make_str("union"); }
5462 | VARCHAR { $$ = make_str("varchar"); }
5463 | '[' { $$ = make_str("["); }
5464 | ']' { $$ = make_str("]"); }
5465 | '=' { $$ = make_str("="); }
5476 remove_variables(braces_open--);
5482 void yyerror( char * error)
5484 snprintf(buf,sizeof buf,"%s at or near \"%s\"",error,yytext);
5485 buf[sizeof(buf)-1]=0;
5486 mmerror(PARSE_ERROR, ET_ERROR, buf);