1 /* Copyright comment */
6 #include "access/htup.h"
7 #include "catalog/catname.h"
8 #include "utils/numeric.h"
9 #include "utils/memutils.h"
10 #include "storage/bufpage.h"
15 #include "mb/pg_wchar.h"
18 #define EMPTY make_str("")
21 * Variables containing simple states.
25 static char *connection = NULL;
26 static int QueryIsRule = 0, ForUpdateNotAllowed = 0, FoundInto = 0;
27 static int initializer = 0;
28 static struct this_type actual_type[STRUCT_DEPTH];
29 static char *actual_storage[STRUCT_DEPTH];
30 static char *actual_startline[STRUCT_DEPTH];
32 /* temporarily store struct members while creating the data structure */
33 struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
35 struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}};
36 struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
38 struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}};
41 * Handle parsing errors and warnings
44 mmerror(enum errortype type, char * error)
50 fprintf(stderr, "%s:%d: WARNING: %s\n", input_filename, yylineno, error);
53 fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
54 ret_value = PARSE_ERROR;
57 fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
63 * Handle the filename and line numbering.
65 char * input_filename = NULL;
71 fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename);
75 output_simple_statement(char *cmd)
83 * store the whenever action here
85 struct when when_error, when_nf, when_warn;
88 print_action(struct when *w)
92 case W_SQLPRINT: fprintf(yyout, "sqlprint();");
94 case W_GOTO: fprintf(yyout, "goto %s;", w->command);
96 case W_DO: fprintf(yyout, "%s;", w->command);
98 case W_STOP: fprintf(yyout, "exit (1);");
100 case W_BREAK: fprintf(yyout, "break;");
102 default: fprintf(yyout, "{/* %d not implemented yet */}", w->code);
108 whenever_action(int mode)
110 if ((mode&1) == 1 && when_nf.code != W_NOTHING)
112 output_line_number();
113 fprintf(yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
114 print_action(&when_nf);
116 if (when_warn.code != W_NOTHING)
118 output_line_number();
119 fprintf(yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
120 print_action(&when_warn);
122 if (when_error.code != W_NOTHING)
124 output_line_number();
125 fprintf(yyout, "\nif (sqlca.sqlcode < 0) ");
126 print_action(&when_error);
130 output_line_number();
134 * Handling of variables.
138 * brace level counter
142 static struct variable * allvariables = NULL;
144 static struct variable *
145 new_variable(const char * name, struct ECPGtype * type)
147 struct variable * p = (struct variable*) mm_alloc(sizeof(struct variable));
149 p->name = mm_strdup(name);
151 p->brace_level = braces_open;
153 p->next = allvariables;
159 static struct variable * find_variable(char * name);
161 static struct variable *
162 find_struct_member(char *name, char *str, struct ECPGstruct_member *members)
164 char *next = strchr(++str, '.'), c = '\0';
172 for (; members; members = members->next)
174 if (strcmp(members->name, str) == 0)
179 switch (members->typ->typ)
182 return(new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size)));
185 return(new_variable(name, ECPGmake_struct_type(members->typ->u.members, members->typ->typ)));
187 return(new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
196 return(find_struct_member(name, next, members->typ->u.element->u.members));
198 else return(find_struct_member(name, next, members->typ->u.members));
206 static struct variable *
207 find_struct(char * name, char *next)
212 /* first get the mother structure entry */
214 p = find_variable(name);
218 if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
220 sprintf(errortext, "variable %s is not a pointer", name);
221 mmerror(ET_FATAL, errortext);
224 if (p->type->u.element->typ != ECPGt_struct && p->type->u.element->typ != ECPGt_union)
226 sprintf(errortext, "variable %s is not a pointer to a structure or a union", name);
227 mmerror(ET_FATAL, errortext);
230 /* restore the name, we will need it later on */
234 return find_struct_member(name, next, p->type->u.element->u.members);
238 if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
240 sprintf(errortext, "variable %s is neither a structure nor a union", name);
241 mmerror(ET_FATAL, errortext);
244 /* restore the name, we will need it later on */
247 return find_struct_member(name, next, p->type->u.members);
251 static struct variable *
252 find_simple(char * name)
256 for (p = allvariables; p; p = p->next)
258 if (strcmp(p->name, name) == 0)
265 /* Note that this function will end the program in case of an unknown */
267 static struct variable *
268 find_variable(char * name)
273 if ((next = strchr(name, '.')) != NULL)
274 p = find_struct(name, next);
275 else if ((next = strstr(name, "->")) != NULL)
276 p = find_struct(name, next);
278 p = find_simple(name);
282 sprintf(errortext, "The variable %s is not declared", name);
283 mmerror(ET_FATAL, errortext);
290 remove_variables(int brace_level)
292 struct variable * p, *prev;
294 for (p = prev = allvariables; p; p = p ? p->next : NULL)
296 if (p->brace_level >= brace_level)
299 if (p == allvariables)
300 prev = allvariables = p->next;
302 prev->next = p->next;
304 ECPGfree_type(p->type);
316 * Here are the variables that need to be handled on every request.
317 * These are of two kinds: input and output.
318 * I will make two lists for them.
321 struct arguments * argsinsert = NULL;
322 struct arguments * argsresult = NULL;
325 reset_variables(void)
332 /* Add a variable to a request. */
334 add_variable(struct arguments ** list, struct variable * var, struct variable * ind)
336 struct arguments * p = (struct arguments *)mm_alloc(sizeof(struct arguments));
344 /* Dump out a list of all the variable on this list.
345 This is a recursive function that works from the end of the list and
346 deletes the list as we go on.
349 dump_variables(struct arguments * list, int mode)
356 /* The list is build up from the beginning so lets first dump the
360 dump_variables(list->next, mode);
362 /* Then the current element and its indicator */
363 ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
364 (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->name : NULL,
365 (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->type : NULL, NULL, NULL);
367 /* Then release the list element. */
373 check_indicator(struct ECPGtype *var)
375 /* make sure this is a valid indicator variable */
378 struct ECPGstruct_member *p;
383 case ECPGt_unsigned_short:
384 case ECPGt_unsigned_int:
385 case ECPGt_unsigned_long:
390 for (p = var->u.members; p; p = p->next)
391 check_indicator(p->typ);
395 check_indicator(var->u.element);
398 mmerror(ET_ERROR, "indicator variable must be integer type");
404 cat2_str(char *str1, char *str2)
406 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
408 strcpy(res_str, str1);
409 strcat(res_str, " ");
410 strcat(res_str, str2);
417 cat_str(int count, ...)
423 va_start(args, count);
425 res_str = va_arg(args, char *);
427 /* now add all other strings */
428 for (i = 1; i < count; i++)
429 res_str = cat2_str(res_str, va_arg(args, char *));
437 make_str(const char *str)
439 char * res_str = (char *)mm_alloc(strlen(str) + 1);
441 strcpy(res_str, str);
446 make2_str(char *str1, char *str2)
448 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
450 strcpy(res_str, str1);
451 strcat(res_str, str2);
458 make3_str(char *str1, char *str2, char *str3)
460 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1);
462 strcpy(res_str, str1);
463 strcat(res_str, str2);
464 strcat(res_str, str3);
474 char * name = (char *)mm_alloc(yyleng + 1);
476 strncpy(name, yytext, yyleng);
486 char* line = mm_alloc(strlen("\n#line %d \"%s\"\n") + 21 + strlen(input_filename));
487 sprintf(line, "\n#line %d \"%s\"\n", yylineno, input_filename);
496 output_statement(char * stmt, int mode)
498 int i, j=strlen(stmt);
500 fprintf(yyout, "{ ECPGdo(__LINE__, %s, \"", connection ? connection : "NULL");
502 /* do this char by char as we have to filter '\"' */
503 for (i = 0;i < j; i++) {
505 fputc(stmt[i], yyout);
507 fputs("\\\"", yyout);
510 fputs("\", ", yyout);
512 /* dump variables to C file*/
513 dump_variables(argsinsert, 1);
514 fputs("ECPGt_EOIT, ", yyout);
515 dump_variables(argsresult, 1);
516 fputs("ECPGt_EORT);", yyout);
518 whenever_action(mode);
520 if (connection != NULL)
524 static struct typedefs *
525 get_typedef(char *name)
527 struct typedefs *this;
529 for (this = types; this && strcmp(this->name, name); this = this->next);
532 sprintf(errortext, "invalid datatype '%s'", name);
533 mmerror(ET_FATAL, errortext);
540 adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dimension, int type_index, bool pointer)
545 mmerror(ET_FATAL, "No multi-dimensional array support");
547 *length = type_index;
550 if (type_dimension >= 0)
552 if (*dimension >= 0 && *length >= 0)
553 mmerror(ET_FATAL, "No multi-dimensional array support");
556 *length = *dimension;
558 *dimension = type_dimension;
561 if (*length >= 0 && *dimension >= 0 && pointer)
562 mmerror(ET_FATAL, "No multi-dimensional array support");
568 /* pointer has to get dimension 0 */
571 *length = *dimension;
576 mmerror(ET_FATAL, "No multi-dimensional array support for structures");
580 /* pointer has to get dimension 0 */
584 /* one index is the string length */
587 *length = *dimension;
593 case ECPGt_unsigned_char:
594 /* pointer has to get length 0 */
598 /* one index is the string length */
601 *length = (*dimension < 0) ? 1 : *dimension;
607 /* a pointer has dimension = 0 */
609 *length = *dimension;
614 mmerror(ET_FATAL, "No multi-dimensional array support for simple data types");
629 struct this_type type;
630 enum ECPGttype type_enum;
633 /* special embedded SQL token */
634 %token SQL_AT SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
635 %token SQL_CALL SQL_CONNECT SQL_CONNECTION SQL_CONTINUE
636 %token SQL_DEALLOCATE SQL_DISCONNECT SQL_ENUM
637 %token SQL_FOUND SQL_FREE SQL_GO SQL_GOTO
638 %token SQL_IDENTIFIED SQL_INDICATOR SQL_INT SQL_LONG
639 %token SQL_OFF SQL_OPEN SQL_PREPARE SQL_RELEASE SQL_REFERENCE
640 %token SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQLERROR SQL_SQLPRINT
641 %token SQL_SQLWARNING SQL_START SQL_STOP SQL_STRUCT SQL_UNSIGNED
642 %token SQL_VAR SQL_WHENEVER
645 %token S_ANYTHING S_AUTO S_CONST S_EXTERN
646 %token S_REGISTER S_STATIC S_VOLATILE
648 /* I need this and don't know where it is defined inside the backend */
651 /* Keywords (in SQL92 reserved words) */
652 %token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
653 BEGIN_TRANS, BETWEEN, BOTH, BY,
654 CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
655 COALESCE, COLLATE, COLUMN, COMMIT,
656 CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT, CURRENT_DATE,
657 CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
658 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
659 ELSE, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
660 FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
661 GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
662 IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
663 ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
664 MATCH, MINUTE_P, MONTH_P, NAMES,
665 NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
666 OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
667 PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
668 READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
669 SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
670 TABLE, TEMP, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
671 TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
672 UNION, UNIQUE, UPDATE, USER, USING,
673 VALUES, VARCHAR, VARYING, VIEW,
674 WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
676 /* Keywords (in SQL3 reserved words) */
677 %token DEFERRABLE, DEFERRED,
678 IMMEDIATE, INITIALLY,
683 /* Keywords (in SQL92 non-reserved words) */
684 %token COMMITTED, SERIALIZABLE, TYPE_P
686 /* Keywords for Postgres support (not in SQL92 reserved words)
688 * The CREATEDB and CREATEUSER tokens should go away
689 * when some sort of pg_privileges relation is introduced.
690 * - Todd A. Brandys 1998-01-01?
692 %token ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYZE,
693 BACKWARD, BEFORE, BINARY,
694 CACHE, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE,
695 DATABASE, DELIMITERS, DO,
696 EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
697 FORWARD, FUNCTION, HANDLER,
698 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
699 LANCOMPILER, LIMIT, LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P,
700 MAXVALUE, MINVALUE, MODE, MOVE,
701 NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
702 OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
703 RENAME, RESET, RETURNS, ROW, RULE,
704 SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT, SYSID
706 UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
708 /* Special keywords, not in the query language - see the "lex" file */
709 %token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE
710 %token <ival> ICONST PARAM
713 /* these are not real. they are here so that they get generated as #define's*/
725 %left Op /* multi-character ops and user-defined operators */
733 %left '|' /* this is the relation union op, not logical or */
734 /* Unary Operators */
736 %left ';' /* end of statement or natural log */
741 %left UNION INTERSECT EXCEPT
743 %type <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId
744 %type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt
745 %type <str> OptInherit key_reference key_action comment_text
746 %type <str> key_match ColLabel SpecialRuleRelation ColId columnDef
747 %type <str> ColConstraint ColConstraintElem NumericOnly FloatOnly
748 %type <str> OptTableElementList OptTableElement TableConstraint
749 %type <str> ConstraintElem key_actions ColPrimaryKey
750 %type <str> target_list target_el update_target_list ColConstraintList
751 %type <str> update_target_el opt_id relation_name database_name
752 %type <str> access_method attr_name class index_name name func_name
753 %type <str> file_name AexprConst ParamNo TypeId com_expr
754 %type <str> in_expr_nodes a_expr b_expr TruncateStmt CommentStmt
755 %type <str> opt_indirection expr_list extract_list extract_arg
756 %type <str> position_list substr_list substr_from alter_column_action
757 %type <str> trim_list in_expr substr_for attr attrs drop_behavior
758 %type <str> Typename SimpleTypename Generic Numeric generic opt_float opt_numeric
759 %type <str> opt_decimal Character character opt_varying opt_charset
760 %type <str> opt_collate Datetime datetime opt_timezone opt_interval
761 %type <str> numeric a_expr_or_null row_expr row_descriptor row_list
762 %type <str> SelectStmt SubSelect result OptTemp OptTempType OptTempScope
763 %type <str> opt_table opt_all sort_clause sortby_list
764 %type <str> sortby OptUseOp opt_inh_star relation_name_list name_list
765 %type <str> group_clause having_clause from_clause opt_distinct
766 %type <str> table_list join_outer where_clause relation_expr sub_type
767 %type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
768 %type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
769 %type <str> NotifyStmt columnElem copy_dirn UnlistenStmt copy_null
770 %type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
771 %type <str> opt_with_copy FetchStmt direction fetch_how_many from_in
772 %type <str> ClosePortalStmt DropStmt VacuumStmt opt_verbose
773 %type <str> opt_analyze opt_va_list va_list ExplainStmt index_params
774 %type <str> index_list func_index index_elem opt_type opt_class access_method_clause
775 %type <str> index_opt_unique IndexStmt set_opt func_return def_rest
776 %type <str> func_args_list func_args opt_with ProcedureStmt def_arg
777 %type <str> def_elem def_list definition def_name def_type DefineStmt
778 %type <str> opt_instead event event_object RuleActionList opt_using
779 %type <str> RuleActionStmtOrEmpty RuleActionMulti join_list func_as
780 %type <str> RuleStmt opt_column opt_name oper_argtypes sysid_clause
781 %type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
782 %type <str> RemoveAggrStmt remove_type RemoveStmt ExtendStmt
783 %type <str> RemoveOperStmt RenameStmt all_Op user_valid_clause
784 %type <str> VariableSetStmt var_value zone_value VariableShowStmt
785 %type <str> VariableResetStmt AlterTableStmt DropUserStmt
786 %type <str> user_passwd_clause user_createdb_clause opt_trans
787 %type <str> user_createuser_clause user_list user_group_clause
788 %type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
789 %type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
790 %type <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
791 %type <str> TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
792 %type <str> CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
793 %type <str> ViewStmt LoadStmt CreatedbStmt createdb_opt_encoding
794 %type <str> createdb_opt_location opt_encoding AlterTableStmt
795 %type <str> DropdbStmt ClusterStmt grantee RevokeStmt
796 %type <str> GrantStmt privileges operation_commalist operation
797 %type <str> opt_cursor opt_lmode ConstraintsSetStmt comment_tg
798 %type <str> case_expr when_clause_list case_default case_arg when_clause
799 %type <str> select_clause opt_select_limit select_limit_value
800 %type <str> select_offset_value table_list using_expr join_expr
801 %type <str> using_list from_expr table_expr join_clause join_type
802 %type <str> join_qual update_list join_clause join_clause_with_union
803 %type <str> opt_level opt_lock lock_type users_in_new_group_clause
804 %type <str> OptConstrFromTable comment_op ConstraintAttributeSpec
805 %type <str> constraints_set_list constraints_set_namelist comment_fn
806 %type <str> constraints_set_mode comment_type comment_cl comment_ag
807 %type <str> ConstraintDeferrabilitySpec ConstraintTimeSpec
808 %type <str> CreateGroupStmt, AlterGroupStmt, DropGroupStmt
810 %type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen
811 %type <str> indicator ECPGExecute ECPGPrepare ecpg_using
812 %type <str> storage_clause opt_initializer c_anything blockstart
813 %type <str> blockend variable_list variable c_thing c_term
814 %type <str> opt_pointer cvariable ECPGDisconnect dis_name storage_modifier
815 %type <str> stmt symbol opt_symbol ECPGRelease execstring server_name
816 %type <str> connection_object opt_server opt_port c_stuff opt_reference
817 %type <str> user_name opt_user char_variable ora_user ident
818 %type <str> db_prefix server opt_options opt_connection_name c_list
819 %type <str> ECPGSetConnection cpp_line ECPGTypedef c_args
820 %type <str> enum_type civariableonly ECPGCursorStmt ECPGDeallocate
821 %type <str> ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
822 %type <str> struct_type s_struct declaration declarations variable_declarations
823 %type <str> s_struct s_union union_type ECPGSetAutocommit on_off
825 %type <type_enum> simple_type signed_type unsigned_type varchar_type
829 %type <action> action
831 %type <index> opt_array_bounds opt_type_array_bounds
837 statements: /* empty */
838 | statements statement
840 statement: ecpgstart opt_at stmt ';' { connection = NULL; }
843 | c_thing { fprintf(yyout, "%s", $1); free($1); }
844 | cpp_line { fprintf(yyout, "%s", $1); free($1); }
845 | blockstart { fputs($1, yyout); free($1); }
846 | blockend { fputs($1, yyout); free($1); }
848 opt_at: SQL_AT connection_target { connection = $2; }
850 stmt: AlterTableStmt { output_statement($1, 0); }
851 | AlterGroupStmt { output_statement($1, 0); }
852 | AlterUserStmt { output_statement($1, 0); }
853 | ClosePortalStmt { output_statement($1, 0); }
854 | CommentStmt { output_statement($1, 0); }
855 | CopyStmt { output_statement($1, 0); }
856 | CreateStmt { output_statement($1, 0); }
857 | CreateAsStmt { output_statement($1, 0); }
858 | CreateGroupStmt { output_statement($1, 0); }
859 | CreateSeqStmt { output_statement($1, 0); }
860 | CreatePLangStmt { output_statement($1, 0); }
861 | CreateTrigStmt { output_statement($1, 0); }
862 | CreateUserStmt { output_statement($1, 0); }
863 | ClusterStmt { output_statement($1, 0); }
864 | DefineStmt { output_statement($1, 0); }
865 | DropStmt { output_statement($1, 0); }
866 | TruncateStmt { output_statement($1, 0); }
867 | DropGroupStmt { output_statement($1, 0); }
868 | DropPLangStmt { output_statement($1, 0); }
869 | DropTrigStmt { output_statement($1, 0); }
870 | DropUserStmt { output_statement($1, 0); }
871 | ExtendStmt { output_statement($1, 0); }
872 | ExplainStmt { output_statement($1, 0); }
873 | FetchStmt { output_statement($1, 1); }
874 | GrantStmt { output_statement($1, 0); }
875 | IndexStmt { output_statement($1, 0); }
876 | ListenStmt { output_statement($1, 0); }
877 | UnlistenStmt { output_statement($1, 0); }
878 | LockStmt { output_statement($1, 0); }
879 | ProcedureStmt { output_statement($1, 0); }
880 | RemoveAggrStmt { output_statement($1, 0); }
881 | RemoveOperStmt { output_statement($1, 0); }
882 | RemoveFuncStmt { output_statement($1, 0); }
883 | RemoveStmt { output_statement($1, 0); }
884 | RenameStmt { output_statement($1, 0); }
885 | RevokeStmt { output_statement($1, 0); }
887 if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
888 output_simple_statement($1);
890 output_statement($1, 1);
892 | RuleStmt { output_statement($1, 0); }
894 fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
898 | ViewStmt { output_statement($1, 0); }
899 | LoadStmt { output_statement($1, 0); }
900 | CreatedbStmt { output_statement($1, 0); }
901 | DropdbStmt { output_statement($1, 0); }
902 | VacuumStmt { output_statement($1, 0); }
903 | VariableSetStmt { output_statement($1, 0); }
904 | VariableShowStmt { output_statement($1, 0); }
905 | VariableResetStmt { output_statement($1, 0); }
906 | ConstraintsSetStmt { output_statement($1, 0); }
909 mmerror(ET_ERROR, "no at option for connect statement.\n");
911 fprintf(yyout, "{ ECPGconnect(__LINE__, %s, %d);", $1, autocommit);
916 output_simple_statement($1);
920 mmerror(ET_ERROR, "no at option for connect statement.\n");
928 output_simple_statement($1);
932 mmerror(ET_ERROR, "no at option for disconnect statement.\n");
934 fprintf(yyout, "{ ECPGdisconnect(__LINE__, \"%s\");", $1);
939 output_statement($1, 0);
942 fprintf(yyout, "{ ECPGdeallocate(__LINE__, \"%s\");", $1);
950 for (ptr = cur; ptr != NULL; ptr=ptr->next)
952 if (strcmp(ptr->name, $1) == 0)
958 sprintf(errortext, "trying to open undeclared cursor %s\n", $1);
959 mmerror(ET_ERROR, errortext);
962 fprintf(yyout, "{ ECPGdo(__LINE__, %s, \"%s\",", ptr->connection ? ptr->connection : "NULL", ptr->command);
963 /* dump variables to C file*/
964 dump_variables(ptr->argsinsert, 0);
965 dump_variables(argsinsert, 0);
966 fputs("ECPGt_EOIT, ", yyout);
967 dump_variables(ptr->argsresult, 0);
968 fputs("ECPGt_EORT);", yyout);
974 mmerror(ET_ERROR, "no at option for set connection statement.\n");
976 fprintf(yyout, "{ ECPGprepare(__LINE__, %s);", $1);
980 | ECPGRelease { /* output already done */ }
981 | ECPGSetAutocommit {
982 fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
986 | ECPGSetConnection {
988 mmerror(ET_ERROR, "no at option for set connection statement.\n");
990 fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
996 mmerror(ET_ERROR, "no at option for typedef statement.\n");
998 output_simple_statement($1);
1002 mmerror(ET_ERROR, "no at option for var statement.\n");
1004 output_simple_statement($1);
1008 mmerror(ET_ERROR, "no at option for whenever statement.\n");
1010 output_simple_statement($1);
1016 * We start with a lot of stuff that's very similar to the backend's parsing
1019 /*****************************************************************************
1021 * Create a new Postgres DBMS user
1024 *****************************************************************************/
1026 CreateUserStmt: CREATE USER UserId
1027 user_createdb_clause user_createuser_clause user_group_clause
1030 $$ = cat_str(6, make_str("create user"), $3, $4, $5, $6, $7);
1032 | CREATE USER UserId WITH sysid_clause user_passwd_clause
1033 user_createdb_clause user_createuser_clause user_group_clause
1036 $$ = cat_str(9, make_str("create user"), $3, make_str("with"), $5, $6, $7, $8, $9, $10);
1040 /*****************************************************************************
1042 * Alter a postresql DBMS user
1045 *****************************************************************************/
1047 AlterUserStmt: ALTER USER UserId user_createdb_clause
1048 user_createuser_clause user_valid_clause
1050 $$ = cat_str(5, make_str("alter user"), $3, $4, $5, $6);
1052 |ALTER USER UserId WITH PASSWORD Sconst
1053 user_createdb_clause user_createuser_clause user_valid_clause
1055 $$ = cat_str(7, make_str("alter user"), $3, make_str("with password"), $6, $7, $8, $9);
1059 /*****************************************************************************
1061 * Drop a postresql DBMS user
1064 *****************************************************************************/
1066 DropUserStmt: DROP USER user_list
1068 $$ = cat2_str(make_str("drop user"), $3);
1072 user_passwd_clause: PASSWORD Sconst { $$ = cat2_str(make_str("password") , $2); }
1073 | /*EMPTY*/ { $$ = EMPTY; }
1076 sysid_clause: SYSID Iconst { if (atoi($2) <= 0)
1077 mmerror(ET_ERROR, "sysid must be positive");
1079 $$ = cat2_str(make_str("sysid"), $2); }
1080 | /*EMPTY*/ { $$ = EMPTY; }
1083 user_createdb_clause: CREATEDB
1085 $$ = make_str("createdb");
1089 $$ = make_str("nocreatedb");
1091 | /*EMPTY*/ { $$ = EMPTY; }
1094 user_createuser_clause: CREATEUSER
1096 $$ = make_str("createuser");
1100 $$ = make_str("nocreateuser");
1102 | /*EMPTY*/ { $$ = NULL; }
1105 user_list: user_list ',' UserId
1107 $$ = cat_str(3, $1, make_str(","), $3);
1115 user_group_clause: IN GROUP user_list
1117 $$ = cat2_str(make_str("in group"), $3);
1119 | /*EMPTY*/ { $$ = EMPTY; }
1122 user_valid_clause: VALID UNTIL Sconst { $$ = cat2_str(make_str("valid until"), $3); }
1123 | /*EMPTY*/ { $$ = EMPTY; }
1127 /*****************************************************************************
1129 * Create a postresql group
1132 ****************************************************************************/
1133 CreateGroupStmt: CREATE GROUP UserId
1135 $$ = cat2_str(make_str("create group"), $3);
1137 | CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause
1139 $$ = cat_str(5, make_str("create group"), $3, make_str("with"), $5, $6);
1143 users_in_new_group_clause: USER user_list { $$ = cat2_str(make_str("user"), $2); }
1144 | /* EMPTY */ { $$ = EMPTY; }
1148 /*****************************************************************************
1150 * Alter a postresql group
1153 *****************************************************************************/
1154 AlterGroupStmt: ALTER GROUP UserId ADD USER user_list
1156 $$ = cat_str(4, make_str("alter group"), $3, make_str("add user"), $6);
1159 ALTER GROUP UserId DROP USER user_list
1161 $$ = cat_str(4, make_str("alter group"), $3, make_str("drop user"), $6);
1165 /*****************************************************************************
1167 * Drop a postresql group
1170 *****************************************************************************/
1171 DropGroupStmt: DROP GROUP UserId
1173 $$ = cat2_str(make_str("drop group"), $3);
1178 /*****************************************************************************
1180 * Set PG internal variable
1181 * SET name TO 'var_value'
1182 * Include SQL92 syntax (thomas 1997-10-22):
1183 * SET TIME ZONE 'var_value'
1185 *****************************************************************************/
1187 VariableSetStmt: SET ColId TO var_value
1189 $$ = cat_str(4, make_str("set"), $2, make_str("to"), $4);
1191 | SET ColId '=' var_value
1193 $$ = cat_str(4, make_str("set"), $2, make_str("="), $4);
1195 | SET TIME ZONE zone_value
1197 $$ = cat2_str(make_str("set time zone"), $4);
1199 | SET TRANSACTION ISOLATION LEVEL opt_level
1201 $$ = cat2_str(make_str("set transaction isolation level"), $5);
1203 | SET NAMES opt_encoding
1206 $$ = cat2_str(make_str("set names"), $3);
1208 mmerror(ET_ERROR, "SET NAMES is not supported.");
1213 opt_level: READ COMMITTED { $$ = make_str("read committed"); }
1214 | SERIALIZABLE { $$ = make_str("serializable"); }
1218 var_value: Sconst { $$ = $1; }
1219 | DEFAULT { $$ = make_str("default"); }
1222 zone_value: Sconst { $$ = $1; }
1223 | DEFAULT { $$ = make_str("default"); }
1224 | LOCAL { $$ = make_str("local"); }
1227 opt_encoding: Sconst { $$ = $1; }
1228 | DEFAULT { $$ = make_str("default"); }
1229 | /*EMPTY*/ { $$ = EMPTY; }
1232 VariableShowStmt: SHOW ColId
1234 $$ = cat2_str(make_str("show"), $2);
1238 $$ = make_str("show time zone");
1240 | SHOW TRANSACTION ISOLATION LEVEL
1242 $$ = make_str("show transaction isolation level");
1246 VariableResetStmt: RESET ColId
1248 $$ = cat2_str(make_str("reset"), $2);
1252 $$ = make_str("reset time zone");
1254 | RESET TRANSACTION ISOLATION LEVEL
1256 $$ = make_str("reset transaction isolation level");
1260 ConstraintsSetStmt: SET CONSTRAINTS constraints_set_list constraints_set_mode
1262 $$ = cat_str(3, make_str("set constraints"), $3, $4);
1266 constraints_set_list: ALL
1268 $$ = make_str("all");
1270 | constraints_set_namelist
1277 constraints_set_namelist: IDENT
1281 | constraints_set_namelist ',' IDENT
1283 $$ = cat_str(3, $1, make_str(","), $3);
1287 constraints_set_mode: DEFERRED
1289 $$ = make_str("deferred");
1293 $$ = make_str("immediate");
1297 /*****************************************************************************
1301 * ALTER TABLE variations
1303 *****************************************************************************/
1306 /* ALTER TABLE <name> ADD [COLUMN] <coldef> */
1307 ALTER TABLE relation_name opt_inh_star ADD opt_column columnDef
1309 $$ = cat_str(6, make_str("alter table"), $3, $4, make_str("add"), $6, $7);
1311 /* ALTER TABLE <name> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP
1313 | ALTER TABLE relation_name opt_inh_star ALTER opt_column ColId
1316 $$ = cat_str(7, make_str("alter table"), $3, $4, make_str("alter"), $6, $7, $8);
1318 /* ALTER TABLE <name> DROP [COLUMN] <name> {RESTRICT|CASCADE} */
1319 | ALTER TABLE relation_name opt_inh_star DROP opt_column ColId drop_behavior
1321 $$ = cat_str(7, make_str("alter table"), $3, $4, make_str("drop"), $6, $7, $8);
1323 /* ALTER TABLE <name> ADD CONSTRAINT ... */
1324 | ALTER TABLE relation_name opt_inh_star ADD TableConstraint
1326 $$ = cat_str(5, make_str("alter table"), $3, $4, make_str("add"), $6);
1328 /* ALTER TABLE <name> DROP CONSTRAINT ... */
1329 | ALTER TABLE relation_name opt_inh_star DROP CONSTRAINT name drop_behavior
1331 $$ = cat_str(6, make_str("alter table"), $3, $4, make_str("drop constraint"), $7, $8);
1335 alter_column_action:
1336 SET DEFAULT a_expr { $$ = cat2_str(make_str("set default"), $3); }
1337 | SET DEFAULT NULL_P { $$ = make_str("set default null"); }
1338 | DROP DEFAULT { $$ = make_str("drop default"); }
1341 drop_behavior: CASCADE { $$ = make_str("cascade"); }
1342 | RESTRICT { $$ = make_str("restrict"); }
1345 /*****************************************************************************
1350 *****************************************************************************/
1352 ClosePortalStmt: CLOSE opt_id
1354 $$ = cat2_str(make_str("close"), $2);
1358 opt_id: ColId { $$ = $1; }
1359 | /*EMPTY*/ { $$ = NULL; }
1362 /*****************************************************************************
1365 * COPY [BINARY] <relname> FROM/TO
1366 * [USING DELIMITERS <delimiter>]
1368 *****************************************************************************/
1370 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
1372 $$ = cat_str(8, make_str("copy"), $2, $3, $4, $5, $6, $7, $8);
1377 { $$ = make_str("to"); }
1379 { $$ = make_str("from"); }
1383 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
1384 * used depends on the direction. (It really doesn't make sense to copy from
1385 * stdout. We silently correct the "typo". - AY 9/94
1387 copy_file_name: Sconst { $$ = $1; }
1388 | STDIN { $$ = make_str("stdin"); }
1389 | STDOUT { $$ = make_str("stdout"); }
1392 opt_binary: BINARY { $$ = make_str("binary"); }
1393 | /*EMPTY*/ { $$ = EMPTY; }
1396 opt_with_copy: WITH OIDS { $$ = make_str("with oids"); }
1397 | /*EMPTY*/ { $$ = EMPTY; }
1401 * the default copy delimiter is tab but the user can configure it
1403 copy_delimiter: opt_using DELIMITERS Sconst { $$ = cat_str(3, $1, make_str("delimiters"), $3); }
1404 | /*EMPTY*/ { $$ = EMPTY; }
1407 opt_using: USING { $$ = make_str("using"); }
1408 | /* EMPTY */ { $$ = EMPTY; }
1411 copy_null: WITH NULL_P AS Sconst { $$ = cat2_str(make_str("with null as"), $4); }
1412 | /* EMPTY */ { $$ = EMPTY; }
1415 /*****************************************************************************
1420 *****************************************************************************/
1422 CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
1425 $$ = cat_str(8, make_str("create"), $2, make_str("table"), $4, make_str("("), $6, make_str(")"), $8);
1429 OptTemp: OptTempType { $$ = $1; }
1430 | OptTempScope OptTempType { $$ = cat2_str($1,$2); }
1433 OptTempType: TEMP { $$ = make_str("temp"); }
1434 | TEMPORARY { $$ = make_str("temporary"); }
1435 | /* EMPTY */ { $$ = EMPTY; }
1438 OptTempScope: GLOBAL
1440 mmerror(ET_ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
1441 $$ = make_str("global");
1443 | LOCAL { $$ = make_str("local"); }
1447 OptTableElementList: OptTableElementList ',' OptTableElement
1449 $$ = cat_str(3, $1, make_str(","), $3);
1455 | /*EMPTY*/ { $$ = EMPTY; }
1458 OptTableElement: columnDef { $$ = $1; }
1459 | TableConstraint { $$ = $1; }
1462 columnDef: ColId Typename ColConstraintList
1464 $$ = cat_str(3, $1, $2, $3);
1466 | ColId SERIAL ColPrimaryKey
1468 $$ = cat_str(3, $1, make_str(" serial "), $3);
1472 ColConstraintList: ColConstraintList ColConstraint { $$ = cat2_str($1,$2); }
1473 | /* EMPTY */ { $$ = EMPTY; }
1476 ColPrimaryKey: PRIMARY KEY
1478 $$ = make_str("primary key");
1487 CONSTRAINT name ColConstraintElem
1489 $$ = cat_str(3, make_str("constraint"), $2, $3);
1496 * DEFAULT NULL is already the default for Postgres.
1497 * Bue define it here and carry it forward into the system
1498 * to make it explicit.
1499 * - thomas 1998-09-13
1501 * WITH NULL and NULL are not SQL92-standard syntax elements,
1502 * so leave them out. Use DEFAULT NULL to explicitly indicate
1503 * that a column may have that value. WITH NULL leads to
1504 * shift/reduce conflicts with WITH TIME ZONE anyway.
1505 * - thomas 1999-01-08
1507 * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce
1508 * conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
1509 * or be part of a_expr NOT LIKE or similar constructs).
1511 ColConstraintElem: CHECK '(' a_expr ')'
1513 $$ = cat_str(3, make_str("check("), $3, make_str(")"));
1517 $$ = make_str("default null");
1521 $$ = cat2_str(make_str("default"), $2);
1525 $$ = make_str("not null");
1529 $$ = make_str("unique");
1533 $$ = make_str("primary key");
1535 | REFERENCES ColId opt_column_list key_match key_actions
1537 $$ = cat_str(5, make_str("references"), $2, $3, $4, $5);
1541 /* ConstraintElem specifies constraint syntax which is not embedded into
1542 * a column definition. ColConstraintElem specifies the embedded form.
1543 * - thomas 1997-12-03
1545 TableConstraint: CONSTRAINT name ConstraintElem
1547 $$ = cat_str(3, make_str("constraint"), $2, $3);
1553 ConstraintElem: CHECK '(' a_expr ')'
1555 $$ = cat_str(3, make_str("check("), $3, make_str(")"));
1557 | UNIQUE '(' columnList ')'
1559 $$ = cat_str(3, make_str("unique("), $3, make_str(")"));
1561 | PRIMARY KEY '(' columnList ')'
1563 $$ = cat_str(3, make_str("primary key("), $4, make_str(")"));
1565 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
1567 $$ = cat_str(7, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10);
1571 key_match: MATCH FULL
1573 $$ = make_str("match full");
1577 mmerror(ET_WARN, "FOREIGN KEY match type PARTIAL not implemented yet");
1578 $$ = make_str("match partial");
1586 key_actions: key_action key_action { $$ = cat2_str($1, $2); }
1587 | key_action { $$ = $1; }
1588 | /*EMPTY*/ { $$ = EMPTY; }
1591 key_action: ON DELETE key_reference { $$ = cat2_str(make_str("on delete"), $3); }
1592 | ON UPDATE key_reference { $$ = cat2_str(make_str("on update"), $3); }
1595 key_reference: NO ACTION { $$ = make_str("no action"); }
1596 | RESTRICT { $$ = make_str("restrict"); }
1597 | CASCADE { $$ = make_str("cascade"); }
1598 | SET DEFAULT { $$ = make_str("set default"); }
1599 | SET NULL_P { $$ = make_str("set null"); }
1602 OptInherit: INHERITS '(' relation_name_list ')' { $$ = cat_str(3, make_str("inherits ("), $3, make_str(")")); }
1603 | /*EMPTY*/ { $$ = EMPTY; }
1607 * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
1611 CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS SelectStmt
1614 mmerror(ET_ERROR, "CREATE TABLE/AS SELECT may not specify INTO");
1616 $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4, $5, make_str("as"), $7);
1620 OptCreateAs: '(' CreateAsList ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1621 | /*EMPTY*/ { $$ = EMPTY; }
1624 CreateAsList: CreateAsList ',' CreateAsElement { $$ = cat_str(3, $1, make_str(","), $3); }
1625 | CreateAsElement { $$ = $1; }
1628 CreateAsElement: ColId { $$ = $1; }
1631 /*****************************************************************************
1634 * CREATE SEQUENCE seqname
1636 *****************************************************************************/
1638 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1640 $$ = cat_str(3, make_str("create sequence"), $3, $4);
1644 OptSeqList: OptSeqList OptSeqElem
1645 { $$ = cat2_str($1, $2); }
1649 OptSeqElem: CACHE IntegerOnly
1651 $$ = cat2_str(make_str("cache"), $2);
1655 $$ = make_str("cycle");
1657 | INCREMENT IntegerOnly
1659 $$ = cat2_str(make_str("increment"), $2);
1661 | MAXVALUE IntegerOnly
1663 $$ = cat2_str(make_str("maxvalue"), $2);
1665 | MINVALUE IntegerOnly
1667 $$ = cat2_str(make_str("minvalue"), $2);
1671 $$ = cat2_str(make_str("start"), $2);
1675 NumericOnly: FloatOnly { $$ = $1; }
1676 | IntegerOnly { $$ = $1; }
1684 $$ = cat2_str(make_str("-"), $2);
1695 $$ = cat2_str(make_str("-"), $2);
1699 /*****************************************************************************
1702 * CREATE PROCEDURAL LANGUAGE ...
1703 * DROP PROCEDURAL LANGUAGE ...
1705 *****************************************************************************/
1707 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1708 HANDLER def_name LANCOMPILER Sconst
1710 $$ = cat_str(8, make_str("create"), $2, make_str("precedural language"), $5, make_str("handler"), $7, make_str("langcompiler"), $9);
1714 PLangTrusted: TRUSTED { $$ = make_str("trusted"); }
1717 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1719 $$ = cat2_str(make_str("drop procedural language"), $4);
1723 /*****************************************************************************
1726 * CREATE TRIGGER ...
1729 *****************************************************************************/
1731 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1732 relation_name TriggerForSpec EXECUTE PROCEDURE
1733 name '(' TriggerFuncArgs ')'
1735 $$ = 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(")"));
1737 | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
1738 relation_name OptConstrFromTable
1739 ConstraintAttributeSpec
1740 FOR EACH ROW EXECUTE PROCEDURE
1741 name '(' TriggerFuncArgs ')'
1743 $$ = 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(")"));
1747 TriggerActionTime: BEFORE { $$ = make_str("before"); }
1748 | AFTER { $$ = make_str("after"); }
1751 TriggerEvents: TriggerOneEvent
1755 | TriggerOneEvent OR TriggerOneEvent
1757 $$ = cat_str(3, $1, make_str("or"), $3);
1759 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1761 $$ = cat_str(5, $1, make_str("or"), $3, make_str("or"), $5);
1765 TriggerOneEvent: INSERT { $$ = make_str("insert"); }
1766 | DELETE { $$ = make_str("delete"); }
1767 | UPDATE { $$ = make_str("update"); }
1770 TriggerForSpec: FOR TriggerForOpt TriggerForType
1772 $$ = cat_str(3, make_str("for"), $2, $3);
1776 TriggerForOpt: EACH { $$ = make_str("each"); }
1777 | /*EMPTY*/ { $$ = EMPTY; }
1780 TriggerForType: ROW { $$ = make_str("row"); }
1781 | STATEMENT { $$ = make_str("statement"); }
1784 TriggerFuncArgs: TriggerFuncArg
1786 | TriggerFuncArgs ',' TriggerFuncArg
1787 { $$ = cat_str(3, $1, make_str(","), $3); }
1792 TriggerFuncArg: Iconst
1800 | Sconst { $$ = $1; }
1801 | ident { $$ = $1; }
1804 OptConstrFromTable: /* Empty */
1808 | FROM relation_name
1810 $$ = cat2_str(make_str("from"), $2);
1814 ConstraintAttributeSpec: /* Empty */
1816 | ConstraintDeferrabilitySpec
1818 | ConstraintDeferrabilitySpec ConstraintTimeSpec
1820 if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 )
1821 mmerror(ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
1823 $$ = cat2_str($1, $2);
1825 | ConstraintTimeSpec
1827 | ConstraintTimeSpec ConstraintDeferrabilitySpec
1829 if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
1830 mmerror(ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
1832 $$ = cat2_str($1, $2);
1836 ConstraintDeferrabilitySpec: NOT DEFERRABLE
1838 $$ = make_str("not deferrable");
1842 $$ = make_str("deferrable");
1846 ConstraintTimeSpec: INITIALLY IMMEDIATE
1848 $$ = make_str("initially immediate");
1850 | INITIALLY DEFERRED
1852 $$ = make_str("initially deferrable");
1856 DropTrigStmt: DROP TRIGGER name ON relation_name
1858 $$ = cat_str(4, make_str("drop trigger"), $3, make_str("on"), $5);
1862 /*****************************************************************************
1865 * define (type,operator,aggregate)
1867 *****************************************************************************/
1869 DefineStmt: CREATE def_type def_rest
1871 $$ = cat_str(3, make_str("create"), $2, $3);
1875 def_rest: def_name definition
1877 $$ = cat2_str($1, $2);
1881 def_type: OPERATOR { $$ = make_str("operator"); }
1882 | TYPE_P { $$ = make_str("type"); }
1883 | AGGREGATE { $$ = make_str("aggregate"); }
1886 def_name: PROCEDURE { $$ = make_str("procedure"); }
1887 | JOIN { $$ = make_str("join"); }
1888 | ColId { $$ = $1; }
1889 | all_Op { $$ = $1; }
1892 definition: '(' def_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1895 def_list: def_elem { $$ = $1; }
1896 | def_list ',' def_elem { $$ = cat_str(3, $1, make_str(","), $3); }
1899 def_elem: def_name '=' def_arg {
1900 $$ = cat_str(3, $1, make_str("="), $3);
1906 | DEFAULT '=' def_arg
1908 $$ = cat2_str(make_str("default ="), $3);
1912 def_arg: ColId { $$ = $1; }
1913 | all_Op { $$ = $1; }
1914 | NumericOnly { $$ = $1; }
1915 | Sconst { $$ = $1; }
1918 $$ = cat2_str(make_str("setof"), $2);
1922 /*****************************************************************************
1925 * drop <relname1> [, <relname2> .. <relnameN> ]
1927 *****************************************************************************/
1929 DropStmt: DROP TABLE relation_name_list
1931 $$ = cat2_str(make_str("drop table"), $3);
1933 | DROP SEQUENCE relation_name_list
1935 $$ = cat2_str(make_str("drop sequence"), $3);
1939 /*****************************************************************************
1942 * truncate table relname
1944 *****************************************************************************/
1945 TruncateStmt: TRUNCATE TABLE relation_name
1947 $$ = cat2_str(make_str("drop table"), $3);
1951 /*****************************************************************************
1954 * fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
1955 * fetch [ forward | backward | absolute | relative ]
1956 * [ # | all | next | prior ] [ [ in | from ] <portalname> ]
1958 *****************************************************************************/
1960 FetchStmt: FETCH direction fetch_how_many from_in name INTO into_list
1962 if (strcmp($2, "relative") == 0 && atol($3) == 0L)
1963 mmerror(ET_ERROR, "FETCH/RELATIVE at current position is not supported");
1965 $$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5);
1967 | FETCH fetch_how_many from_in name INTO into_list
1969 $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
1971 | FETCH direction from_in name INTO into_list
1973 $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
1975 | FETCH from_in name INTO into_list
1977 $$ = cat_str(3, make_str("fetch"), $2, $3);
1979 | FETCH name INTO into_list
1981 $$ = cat2_str(make_str("fetch"), $2);
1983 | MOVE direction fetch_how_many from_in name
1985 $$ = cat_str(5, make_str("move"), $2, $3, $4, $5);
1987 | MOVE fetch_how_many from_in name
1989 $$ = cat_str(4, make_str("move"), $2, $3, $4);
1991 | MOVE direction from_in name
1993 $$ = cat_str(4, make_str("move"), $2, $3, $4);
1997 $$ = cat_str(3, make_str("move"), $2, $3);
2001 $$ = cat2_str(make_str("move"), $2);
2005 direction: FORWARD { $$ = make_str("forward"); }
2006 | BACKWARD { $$ = make_str("backward"); }
2007 | RELATIVE { $$ = make_str("relative"); }
2009 mmerror(ET_WARN, "FETCH/ABSOLUTE not supported, backend will use RELATIVE");
2010 $$ = make_str("absolute");
2014 fetch_how_many: Iconst { $$ = $1; }
2015 | '-' Iconst { $$ = cat2_str(make_str("-"), $2); }
2016 | ALL { $$ = make_str("all"); }
2017 | NEXT { $$ = make_str("next"); }
2018 | PRIOR { $$ = make_str("prior"); }
2021 from_in: IN { $$ = make_str("in"); }
2022 | FROM { $$ = make_str("from"); }
2025 /*****************************************************************************
2027 * The COMMENT ON statement can take different forms based upon the type of
2028 * the object associated with the comment. The form of the statement is:
2030 * COMMENT ON [ [ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ]
2031 * <objname> | AGGREGATE <aggname> <aggtype> | FUNCTION
2032 * <funcname> (arg1, arg2, ...) | OPERATOR <op>
2033 * (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
2034 * <relname> ] IS 'text'
2036 *****************************************************************************/
2037 CommentStmt: COMMENT ON comment_type name IS comment_text
2039 $$ = cat_str(5, make_str("comment on"), $3, $4, make_str("is"), $6);
2041 | COMMENT ON comment_cl relation_name '.' attr_name IS comment_text
2043 $$ = cat_str(7, make_str("comment on"), $3, $4, make_str("."), $6, make_str("is"), $8);
2045 | COMMENT ON comment_ag name aggr_argtype IS comment_text
2047 $$ = cat_str(6, make_str("comment on"), $3, $4, $5, make_str("is"), $7);
2049 | COMMENT ON comment_fn func_name func_args IS comment_text
2051 $$ = cat_str(6, make_str("comment on"), $3, $4, $5, make_str("is"), $7);
2053 | COMMENT ON comment_op all_Op '(' oper_argtypes ')' IS comment_text
2055 $$ = cat_str(7, make_str("comment on"), $3, $4, make_str("("), $6, make_str(") is"), $9);
2057 | COMMENT ON comment_tg name ON relation_name IS comment_text
2059 $$ = cat_str(7, make_str("comment on"), $3, $4, make_str("on"), $6, make_str("is"), $8);
2063 comment_type: DATABASE { $$ = make_str("database"); }
2064 | INDEX { $$ = make_str("idnex"); }
2065 | RULE { $$ = make_str("rule"); }
2066 | SEQUENCE { $$ = make_str("sequence"); }
2067 | TABLE { $$ = make_str("table"); }
2068 | TYPE_P { $$ = make_str("type"); }
2069 | VIEW { $$ = make_str("view"); }
2072 comment_cl: COLUMN { $$ = make_str("column"); }
2074 comment_ag: AGGREGATE { $$ = make_str("aggregate"); }
2076 comment_fn: FUNCTION { $$ = make_str("function"); }
2078 comment_op: OPERATOR { $$ = make_str("operator"); }
2080 comment_tg: TRIGGER { $$ = make_str("trigger"); }
2082 comment_text: Sconst { $$ = $1; }
2083 | NULL_P { $$ = make_str("null"); }
2086 /*****************************************************************************
2089 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
2091 *****************************************************************************/
2093 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
2095 $$ = cat_str(7, make_str("grant"), $2, make_str("on"), $4, make_str("to"), $6);
2099 privileges: ALL PRIVILEGES
2101 $$ = make_str("all privileges");
2105 $$ = make_str("all");
2107 | operation_commalist
2113 operation_commalist: operation
2117 | operation_commalist ',' operation
2119 $$ = cat_str(3, $1, make_str(","), $3);
2125 $$ = make_str("select");
2129 $$ = make_str("insert");
2133 $$ = make_str("update");
2137 $$ = make_str("delete");
2141 $$ = make_str("rule");
2147 $$ = make_str("public");
2151 $$ = cat2_str(make_str("group"), $2);
2159 opt_with_grant: WITH GRANT OPTION
2161 mmerror(ET_ERROR, "WITH GRANT OPTION is not supported. Only relation owners can set privileges");
2167 /*****************************************************************************
2170 * REVOKE [privileges] ON [relation_name] FROM [user]
2172 *****************************************************************************/
2174 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
2176 $$ = cat_str(7, make_str("revoke"), $2, make_str("on"), $4, make_str("from"), $6);
2182 /*****************************************************************************
2185 * create index <indexname> on <relname>
2186 * using <access> "(" (<col> with <op>)+ ")" [with
2189 * [where <qual>] is not supported anymore
2190 *****************************************************************************/
2192 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
2193 access_method_clause '(' index_params ')' opt_with
2195 /* should check that access_method is valid,
2196 etc ... but doesn't */
2197 $$ = cat_str(11, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11);
2201 index_opt_unique: UNIQUE { $$ = make_str("unique"); }
2202 | /*EMPTY*/ { $$ = EMPTY; }
2205 access_method_clause: USING access_method { $$ = cat2_str(make_str("using"), $2); }
2206 | /*EMPTY*/ { $$ = EMPTY; }
2209 index_params: index_list { $$ = $1; }
2210 | func_index { $$ = $1; }
2213 index_list: index_list ',' index_elem { $$ = cat_str(3, $1, make_str(","), $3); }
2214 | index_elem { $$ = $1; }
2217 func_index: func_name '(' name_list ')' opt_type opt_class
2219 $$ = cat_str(6, $1, make_str("("), $3, ")", $5, $6);
2223 index_elem: attr_name opt_type opt_class
2225 $$ = cat_str(3, $1, $2, $3);
2229 opt_type: ':' Typename { $$ = cat2_str(make_str(":"), $2); }
2230 | FOR Typename { $$ = cat2_str(make_str("for"), $2); }
2231 | /*EMPTY*/ { $$ = EMPTY; }
2234 /* opt_class "WITH class" conflicts with preceeding opt_type
2235 * for Typename of "TIMESTAMP WITH TIME ZONE"
2236 * So, remove "WITH class" from the syntax. OK??
2237 * - thomas 1997-10-12
2238 * | WITH class { $$ = $2; }
2240 opt_class: class { $$ = $1; }
2241 | USING class { $$ = cat2_str(make_str("using"), $2); }
2242 | /*EMPTY*/ { $$ = EMPTY; }
2245 /*****************************************************************************
2248 * extend index <indexname> [where <qual>]
2250 *****************************************************************************/
2252 ExtendStmt: EXTEND INDEX index_name where_clause
2254 $$ = cat_str(3, make_str("extend index"), $3, $4);
2259 /*****************************************************************************
2262 * execute recipe <recipeName>
2264 *****************************************************************************/
2266 RecipeStmt: EXECUTE RECIPE recipe_name
2268 $$ = cat2_str(make_str("execute recipe"), $3);
2272 /*****************************************************************************
2275 * define function <fname>
2276 * (language = <lang>, returntype = <typename>
2277 * [, arch_pct = <percentage | pre-defined>]
2278 * [, disk_pct = <percentage | pre-defined>]
2279 * [, byte_pct = <percentage | pre-defined>]
2280 * [, perbyte_cpu = <int | pre-defined>]
2281 * [, percall_cpu = <int | pre-defined>]
2283 * [arg is (<type-1> { , <type-n>})]
2284 * as <filename or code in language as appropriate>
2286 *****************************************************************************/
2288 ProcedureStmt: CREATE FUNCTION func_name func_args
2289 RETURNS func_return opt_with AS func_as LANGUAGE Sconst
2291 $$ = cat_str(10, make_str("create function"), $3, $4, make_str("returns"), $6, $7, make_str("as"), $9, make_str("language"), $11);
2294 opt_with: WITH definition { $$ = cat2_str(make_str("with"), $2); }
2295 | /*EMPTY*/ { $$ = EMPTY; }
2298 func_args: '(' func_args_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2299 | '(' ')' { $$ = make_str("()"); }
2302 func_args_list: TypeId { $$ = $1; }
2303 | func_args_list ',' TypeId
2304 { $$ = cat_str(3, $1, make_str(","), $3); }
2307 func_as: Sconst { $$ = $1; }
2308 | Sconst ',' Sconst { $$ = cat_str(3, $1, make_str(","), $3); }
2310 func_return: set_opt TypeId
2312 $$ = cat2_str($1, $2);
2316 set_opt: SETOF { $$ = make_str("setof"); }
2317 | /*EMPTY*/ { $$ = EMPTY; }
2321 /*****************************************************************************
2325 * remove function <funcname>
2326 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
2327 * remove aggregate <aggname>
2328 * (REMOVE AGGREGATE "aggname" "aggtype")
2329 * remove operator <opname>
2330 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
2331 * remove type <typename>
2332 * (REMOVE TYPE "typename")
2333 * remove rule <rulename>
2334 * (REMOVE RULE "rulename")
2336 *****************************************************************************/
2338 RemoveStmt: DROP remove_type name
2340 $$ = cat_str(3, make_str("drop"), $2, $3);
2344 remove_type: TYPE_P { $$ = make_str("type"); }
2345 | INDEX { $$ = make_str("index"); }
2346 | RULE { $$ = make_str("rule"); }
2347 | VIEW { $$ = make_str("view"); }
2351 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
2353 $$ = cat_str(3, make_str("drop aggregate"), $3, $4);
2357 aggr_argtype: name { $$ = $1; }
2358 | '*' { $$ = make_str("*"); }
2362 RemoveFuncStmt: DROP FUNCTION func_name func_args
2364 $$ = cat_str(3, make_str("drop function"), $3, $4);
2369 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
2371 $$ = cat_str(5, make_str("drop operator"), $3, make_str("("), $5, make_str(")"));
2377 mmerror(ET_ERROR, "parser: argument type missing (use NONE for unary operators)");
2380 { $$ = cat_str(3, $1, make_str(","), $3); }
2381 | NONE ',' name /* left unary */
2382 { $$ = cat2_str(make_str("none,"), $3); }
2383 | name ',' NONE /* right unary */
2384 { $$ = cat2_str($1, make_str(", none")); }
2388 /*****************************************************************************
2391 * rename <attrname1> in <relname> [*] to <attrname2>
2392 * rename <relname1> to <relname2>
2394 *****************************************************************************/
2396 RenameStmt: ALTER TABLE relation_name opt_inh_star
2397 RENAME opt_column opt_name TO name
2399 $$ = cat_str(8, make_str("alter table"), $3, $4, make_str("rename"), $6, $7, make_str("to"), $9);
2403 opt_name: name { $$ = $1; }
2404 | /*EMPTY*/ { $$ = EMPTY; }
2407 opt_column: COLUMN { $$ = make_str("colmunn"); }
2408 | /*EMPTY*/ { $$ = EMPTY; }
2412 /*****************************************************************************
2414 * QUERY: Define Rewrite Rule , Define Tuple Rule
2415 * Define Rule <old rules >
2417 * only rewrite rule is supported -- ay 9/94
2419 *****************************************************************************/
2421 RuleStmt: CREATE RULE name AS
2423 ON event TO event_object where_clause
2424 DO opt_instead RuleActionList
2426 $$ = cat_str(10, make_str("create rule"), $3, make_str("as on"), $7, make_str("to"), $9, $10, make_str("do"), $12, $13);
2430 RuleActionList: NOTHING { $$ = make_str("nothing"); }
2431 | SelectStmt { $$ = $1; }
2432 | RuleActionStmt { $$ = $1; }
2433 | '[' RuleActionMulti ']' { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
2434 | '(' RuleActionMulti ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2437 /* the thrashing around here is to discard "empty" statements... */
2438 RuleActionMulti: RuleActionMulti ';' RuleActionStmtOrEmpty
2439 { $$ = cat_str(3, $1, make_str(";"), $3); }
2440 | RuleActionStmtOrEmpty
2441 { $$ = cat2_str($1, make_str(";")); }
2444 RuleActionStmt: InsertStmt
2449 RuleActionStmtOrEmpty: RuleActionStmt { $$ = $1; }
2450 | /*EMPTY*/ { $$ = EMPTY; }
2453 event_object: relation_name '.' attr_name
2455 $$ = make3_str($1, make_str("."), $3);
2463 /* change me to select, update, etc. some day */
2464 event: SELECT { $$ = make_str("select"); }
2465 | UPDATE { $$ = make_str("update"); }
2466 | DELETE { $$ = make_str("delete"); }
2467 | INSERT { $$ = make_str("insert"); }
2470 opt_instead: INSTEAD { $$ = make_str("instead"); }
2471 | /*EMPTY*/ { $$ = EMPTY; }
2475 /*****************************************************************************
2478 * NOTIFY <relation_name> can appear both in rule bodies and
2479 * as a query-level command
2481 *****************************************************************************/
2483 NotifyStmt: NOTIFY relation_name
2485 $$ = cat2_str(make_str("notify"), $2);
2489 ListenStmt: LISTEN relation_name
2491 $$ = cat2_str(make_str("listen"), $2);
2495 UnlistenStmt: UNLISTEN relation_name
2497 $$ = cat2_str(make_str("unlisten"), $2);
2501 $$ = make_str("unlisten *");
2505 /*****************************************************************************
2509 * BEGIN / COMMIT / ROLLBACK
2510 * (also older versions END / ABORT)
2512 *****************************************************************************/
2513 TransactionStmt: ABORT_TRANS opt_trans { $$ = make_str("rollback"); }
2514 | BEGIN_TRANS opt_trans { $$ = make_str("begin transaction"); }
2515 | COMMIT opt_trans { $$ = make_str("commit"); }
2516 | END_TRANS opt_trans { $$ = make_str("commit"); }
2517 | ROLLBACK opt_trans { $$ = make_str("rollback"); }
2519 opt_trans: WORK { $$ = ""; }
2520 | TRANSACTION { $$ = ""; }
2521 | /*EMPTY*/ { $$ = ""; }
2524 /*****************************************************************************
2527 * define view <viewname> '('target-list ')' [where <quals> ]
2529 *****************************************************************************/
2531 ViewStmt: CREATE VIEW name AS SelectStmt
2533 $$ = cat_str(4, make_str("create view"), $3, make_str("as"), $5);
2538 /*****************************************************************************
2541 * load make_str("filename")
2543 *****************************************************************************/
2545 LoadStmt: LOAD file_name
2547 $$ = cat2_str(make_str("load"), $2);
2552 /*****************************************************************************
2557 *****************************************************************************/
2559 CreatedbStmt: CREATE DATABASE database_name WITH createdb_opt_location createdb_opt_encoding
2561 if (strlen($5) == 0 || strlen($6) == 0)
2562 mmerror(ET_ERROR, "CREATE DATABASE WITH requires at least an option");
2563 $$ = cat_str(5, make_str("create database"), $3, make_str("with"), $5, $6);
2565 | CREATE DATABASE database_name
2567 $$ = cat2_str(make_str("create database"), $3);
2571 createdb_opt_location: LOCATION '=' Sconst { $$ = cat2_str(make_str("location ="), $3); }
2572 | LOCATION '=' DEFAULT { $$ = make_str("location = default"); }
2573 | /*EMPTY*/ { $$ = EMPTY; }
2576 createdb_opt_encoding: ENCODING '=' Sconst
2579 mmerror(ET_ERROR, "Multi-byte support is not enabled.");
2581 $$ = cat2_str(make_str("encoding ="), $3);
2583 | ENCODING '=' Iconst
2586 mmerror(ET_ERROR, "Multi-byte support is not enabled.");
2588 $$ = cat2_str(make_str("encoding ="), $3);
2590 | ENCODING '=' DEFAULT
2593 mmerror(ET_ERROR, "Multi-byte support is not enabled.");
2595 $$ = make_str("encoding = default");
2597 | /*EMPTY*/ { $$ = NULL; }
2600 /*****************************************************************************
2605 *****************************************************************************/
2607 DropdbStmt: DROP DATABASE database_name
2609 $$ = cat2_str(make_str("drop database"), $3);
2614 /*****************************************************************************
2617 * cluster <index_name> on <relation_name>
2619 *****************************************************************************/
2621 ClusterStmt: CLUSTER index_name ON relation_name
2623 $$ = cat_str(4, make_str("cluster"), $2, make_str("on"), $4);
2628 /*****************************************************************************
2633 *****************************************************************************/
2635 VacuumStmt: VACUUM opt_verbose opt_analyze
2637 $$ = cat_str(3, make_str("vacuum"), $2, $3);
2639 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2641 if ( strlen($5) > 0 && strlen($4) == 0 )
2642 mmerror(ET_ERROR, "parser: syntax error at or near \"(\"");
2643 $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5);
2647 opt_verbose: VERBOSE { $$ = make_str("verbose"); }
2648 | /*EMPTY*/ { $$ = EMPTY; }
2651 opt_analyze: ANALYZE { $$ = make_str("analyse"); }
2652 | /*EMPTY*/ { $$ = EMPTY; }
2655 opt_va_list: '(' va_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2656 | /*EMPTY*/ { $$ = EMPTY; }
2662 { $$=cat_str(3, $1, make_str(","), $3); }
2666 /*****************************************************************************
2671 *****************************************************************************/
2673 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2675 $$ = cat_str(3, make_str("explain"), $2, $3);
2680 /*****************************************************************************
2682 * Optimizable Stmts: *
2684 * one of the five queries processed by the planner *
2686 * [ultimately] produces query-trees as specified *
2687 * in the query-spec document in ~postgres/ref *
2689 *****************************************************************************/
2691 OptimizableStmt: SelectStmt
2700 /*****************************************************************************
2705 *****************************************************************************/
2707 /* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
2708 * originally. When the second rule of 'insert_rest' was changed to use
2709 * the new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/red uce
2710 * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to accept
2711 * the same statements without any shift/reduce conflicts */
2712 InsertStmt: INSERT INTO relation_name insert_rest
2714 $$ = cat_str(3, make_str("insert into"), $3, $4);
2718 insert_rest: VALUES '(' target_list ')'
2720 $$ = cat_str(3, make_str("values("), $3, make_str(")"));
2724 $$ = make_str("default values");
2730 | '(' columnList ')' VALUES '(' target_list ')'
2732 $$ = cat_str(5, make_str("("), $2, make_str(") values ("), $6, make_str(")"));
2734 | '(' columnList ')' SelectStmt
2736 $$ = cat_str(4, make_str("("), $2, make_str(")"), $4);
2740 opt_column_list: '(' columnList ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2741 | /*EMPTY*/ { $$ = EMPTY; }
2745 columnList ',' columnElem
2746 { $$ = cat_str(3, $1, make_str(","), $3); }
2751 columnElem: ColId opt_indirection
2753 $$ = cat2_str($1, $2);
2758 /*****************************************************************************
2763 *****************************************************************************/
2765 DeleteStmt: DELETE FROM relation_name
2768 $$ = cat_str(3, make_str("delete from"), $3, $4);
2772 LockStmt: LOCK_P opt_table relation_name opt_lock
2774 $$ = cat_str(4, make_str("lock"), $2, $3, $4);
2778 opt_lock: IN lock_type MODE { $$ = cat_str(3, make_str("in"), $2, make_str("mode")); }
2779 | /*EMPTY*/ { $$ = EMPTY;}
2782 lock_type: SHARE ROW EXCLUSIVE { $$ = make_str("share row exclusive"); }
2783 | ROW opt_lmode { $$ = cat2_str(make_str("row"), $2);}
2784 | ACCESS opt_lmode { $$ = cat2_str(make_str("access"), $2);}
2785 | opt_lmode { $$ = $1; }
2788 opt_lmode: SHARE { $$ = make_str("share"); }
2789 | EXCLUSIVE { $$ = make_str("exclusive"); }
2792 /*****************************************************************************
2795 * UpdateStmt (UPDATE)
2797 *****************************************************************************/
2799 UpdateStmt: UPDATE relation_name
2800 SET update_target_list
2804 $$ = cat_str(6, make_str("update"), $2, make_str("set"), $4, $5, $6);
2809 /*****************************************************************************
2814 *****************************************************************************/
2815 CursorStmt: DECLARE name opt_cursor CURSOR FOR
2816 { ForUpdateNotAllowed = 1; }
2819 struct cursor *ptr, *this;
2821 for (ptr = cur; ptr != NULL; ptr = ptr->next)
2823 if (strcmp($2, ptr->name) == 0)
2825 /* re-definition is a bug */
2826 sprintf(errortext, "cursor %s already defined", $2);
2827 mmerror(ET_ERROR, errortext);
2831 this = (struct cursor *) mm_alloc(sizeof(struct cursor));
2833 /* initial definition */
2836 this->connection = connection;
2837 this->command = cat_str(5, make_str("declare"), mm_strdup($2), $3, make_str("cursor for"), $7);
2838 this->argsinsert = argsinsert;
2839 this->argsresult = argsresult;
2840 argsinsert = argsresult = NULL;
2844 $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
2848 opt_cursor: BINARY { $$ = make_str("binary"); }
2849 | INSENSITIVE { $$ = make_str("insensitive"); }
2850 | SCROLL { $$ = make_str("scroll"); }
2851 | INSENSITIVE SCROLL { $$ = make_str("insensitive scroll"); }
2852 | /*EMPTY*/ { $$ = EMPTY; }
2855 /*****************************************************************************
2860 *****************************************************************************/
2862 /* The new 'SelectStmt' rule adapted for the optional use of INTERSECT EXCEPT a nd UNION
2863 * accepts the use of '(' and ')' to select an order of set operations.
2864 * The rule returns a SelectStmt Node having the set operations attached to
2865 * unionClause and intersectClause (NIL if no set operations were present)
2868 SelectStmt: select_clause sort_clause for_update_clause opt_select_limit
2870 if (strlen($3) > 0 && ForUpdateNotAllowed != 0)
2871 mmerror(ET_ERROR, "FOR UPDATE is not allowed in this context");
2873 ForUpdateNotAllowed = 0;
2874 $$ = cat_str(4, $1, $2, $3, $4);
2877 /* This rule parses Select statements including UNION INTERSECT and EXCEPT.
2878 * '(' and ')' can be used to specify the order of the operations
2879 * (UNION EXCEPT INTERSECT). Without the use of '(' and ')' we want the
2880 * operations to be left associative.
2882 * The sort_clause is not handled here!
2884 select_clause: '(' select_clause ')'
2886 $$ = cat_str(3, make_str("("), $2, make_str(")"));
2893 | select_clause EXCEPT select_clause
2895 $$ = cat_str(3, $1, make_str("except"), $3);
2896 ForUpdateNotAllowed = 1;
2898 | select_clause UNION opt_all select_clause
2900 $$ = cat_str(4, $1, make_str("union"), $3, $4);
2901 ForUpdateNotAllowed = 1;
2903 | select_clause INTERSECT opt_all select_clause
2905 $$ = cat_str(3, $1, make_str("intersect"), $3);
2906 ForUpdateNotAllowed = 1;
2910 SubSelect: SELECT opt_distinct target_list
2911 result from_clause where_clause
2912 group_clause having_clause
2914 if (strlen($7) > 0 || strlen($8) > 0)
2915 ForUpdateNotAllowed = 1;
2916 $$ = cat_str(8, make_str("select"), $2, $3, $4, $5, $6, $7, $8);
2920 result: INTO OptTemp opt_table relation_name { FoundInto = 1;
2921 $$= cat_str(4, make_str("into"), $2, $3, $4);
2923 | INTO into_list { $$ = EMPTY; }
2924 | /*EMPTY*/ { $$ = EMPTY; }
2927 opt_table: TABLE { $$ = make_str("table"); }
2928 | /*EMPTY*/ { $$ = EMPTY; }
2931 opt_all: ALL { $$ = make_str("all"); }
2932 | /*EMPTY*/ { $$ = EMPTY; }
2935 opt_distinct: DISTINCT { $$ = make_str("distinct"); }
2936 | DISTINCT ON '(' expr_list ')' { $$ = cat_str(3, make_str("distinct on ("), $4, make_str(")")); }
2937 | ALL { $$ = make_str("all"); }
2938 | /*EMPTY*/ { $$ = EMPTY; }
2941 sort_clause: ORDER BY sortby_list { $$ = cat2_str(make_str("order by"), $3); }
2942 | /*EMPTY*/ { $$ = EMPTY; }
2945 sortby_list: sortby { $$ = $1; }
2946 | sortby_list ',' sortby { $$ = cat_str(3, $1, make_str(","), $3); }
2949 sortby: a_expr OptUseOp
2951 $$ = cat2_str($1, $2);
2955 OptUseOp: USING all_Op { $$ = cat2_str(make_str("using"), $2); }
2956 | ASC { $$ = make_str("asc"); }
2957 | DESC { $$ = make_str("desc"); }
2958 | /*EMPTY*/ { $$ = EMPTY; }
2961 opt_select_limit: LIMIT select_limit_value ',' select_offset_value
2962 { $$ = cat_str(4, make_str("limit"), $2, make_str(","), $4); }
2963 | LIMIT select_limit_value OFFSET select_offset_value
2964 { $$ = cat_str(4, make_str("limit"), $2, make_str("offset"), $4); }
2965 | LIMIT select_limit_value
2966 { $$ = cat2_str(make_str("limit"), $2); }
2967 | OFFSET select_offset_value LIMIT select_limit_value
2968 { $$ = cat_str(4, make_str("offset"), $2, make_str("limit"), $4); }
2969 | OFFSET select_offset_value
2970 { $$ = cat2_str(make_str("offset"), $2); }
2975 select_limit_value: Iconst { $$ = $1; }
2976 | ALL { $$ = make_str("all"); }
2977 | PARAM { $$ = make_name(); }
2980 select_offset_value: Iconst { $$ = $1; }
2981 | PARAM { $$ = make_name(); }
2985 * jimmy bell-style recursive queries aren't supported in the
2988 * ...however, recursive addattr and rename supported. make special
2991 opt_inh_star: '*' { $$ = make_str("*"); }
2992 | /*EMPTY*/ { $$ = EMPTY; }
2995 relation_name_list: name_list { $$ = $1; };
2999 | name_list ',' name
3000 { $$ = cat_str(3, $1, make_str(","), $3); }
3003 group_clause: GROUP BY expr_list { $$ = cat2_str(make_str("group by"), $3); }
3004 | /*EMPTY*/ { $$ = EMPTY; }
3007 having_clause: HAVING a_expr
3009 $$ = cat2_str(make_str("having"), $2);
3011 | /*EMPTY*/ { $$ = EMPTY; }
3014 for_update_clause: FOR UPDATE update_list
3016 $$ = make_str("for update");
3020 $$ = make_str("for read only");
3027 update_list: OF va_list
3029 $$ = cat2_str(make_str("of"), $2);
3037 /*****************************************************************************
3039 * clauses common to all Optimizable Stmts:
3043 *****************************************************************************/
3045 from_clause: FROM from_expr
3047 $$ = cat2_str(make_str("from"), $2);
3055 from_expr: '(' join_clause_with_union ')'
3056 { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3063 table_list: table_list ',' table_expr
3064 { $$ = cat_str(3, $1, make_str(","), $3); }
3069 table_expr: relation_expr AS ColLabel
3071 $$ = cat_str(3, $1, make_str("as"), $3);
3073 | relation_expr ColId
3075 $$ = cat2_str($1, $2);
3083 /* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
3084 * all result rows which would have matched on an INNER JOIN.
3085 * Let's reject this for now. - thomas 1999-01-08
3087 join_clause_with_union: join_clause
3089 | table_expr UNION JOIN table_expr
3090 { mmerror(ET_ERROR, "UNION JOIN not yet implemented"); }
3093 join_clause: table_expr join_list
3095 $$ = cat2_str($1, $2);
3099 join_list: join_list join_expr
3101 $$ = cat2_str($1, $2);
3109 /* This is everything but the left side of a join.
3110 * Note that a CROSS JOIN is the same as an unqualified
3111 * inner join, so just pass back the right-side table.
3112 * A NATURAL JOIN implicitly matches column names between
3113 * tables, so we'll collect those during the later transformation.
3116 join_expr: join_type JOIN table_expr join_qual
3118 $$ = cat_str(4, $1, make_str("join"), $3, $4);
3120 | NATURAL join_type JOIN table_expr
3122 $$ = cat_str(4, make_str("natural"), $2, make_str("join"), $4);
3124 | CROSS JOIN table_expr
3125 { $$ = cat2_str(make_str("cross join"), $3); }
3128 /* OUTER is just noise... */
3129 join_type: FULL join_outer
3131 $$ = cat2_str(make_str("full"), $2);
3132 mmerror(ET_WARN, "FULL OUTER JOIN not yet implemented");
3136 $$ = cat2_str(make_str("left"), $2);
3137 mmerror(ET_WARN, "LEFT OUTER JOIN not yet implemented");
3141 $$ = cat2_str(make_str("right"), $2);
3142 mmerror(ET_WARN, "RIGHT OUTER JOIN not yet implemented");
3146 $$ = make_str("outer");
3147 mmerror(ET_WARN, "OUTER JOIN not yet implemented");
3151 $$ = make_str("inner");
3159 join_outer: OUTER_P { $$ = make_str("outer"); }
3160 | /*EMPTY*/ { $$ = EMPTY; /* no qualifiers */ }
3163 /* JOIN qualification clauses
3164 * Possibilities are:
3165 * USING ( column list ) allows only unqualified column names,
3166 * which must match between tables.
3167 * ON expr allows more general qualifications.
3168 * - thomas 1999-01-07
3171 join_qual: USING '(' using_list ')' { $$ = cat_str(3, make_str("using ("), $3, make_str(")")); }
3172 | ON a_expr { $$ = cat2_str(make_str("on"), $2); }
3175 using_list: using_list ',' using_expr { $$ = cat_str(3, $1, make_str(","), $3); }
3176 | using_expr { $$ = $1; }
3185 where_clause: WHERE a_expr { $$ = cat2_str(make_str("where"), $2); }
3186 | /*EMPTY*/ { $$ = EMPTY; /* no qualifiers */ }
3189 relation_expr: relation_name
3191 /* normal relations */
3194 | relation_name '*' %prec '='
3196 /* inheritance query */
3197 $$ = cat2_str($1, make_str("*"));
3200 opt_array_bounds: '[' ']' opt_array_bounds
3203 $$.index2 = $3.index1;
3204 $$.str = cat2_str(make_str("[]"), $3.str);
3206 | '[' Iresult ']' opt_array_bounds
3208 char *txt = mm_alloc(20L);
3210 sprintf (txt, "%d", $2);
3212 $$.index2 = $4.index1;
3213 $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
3223 Iresult: Iconst { $$ = atol($1); }
3224 | '(' Iresult ')' { $$ = $2; }
3225 | Iresult '+' Iresult { $$ = $1 + $3; }
3226 | Iresult '-' Iresult { $$ = $1 - $3; }
3227 | Iresult '*' Iresult { $$ = $1 * $3; }
3228 | Iresult '/' Iresult { $$ = $1 / $3; }
3229 | Iresult '%' Iresult { $$ = $1 % $3; }
3233 /*****************************************************************************
3236 * SQL92 introduces a large amount of type-specific syntax.
3237 * Define individual clauses to handle these cases, and use
3238 * the generic case to handle regular type-extensible Postgres syntax.
3239 * - thomas 1997-10-10
3241 *****************************************************************************/
3243 Typename: SimpleTypename opt_array_bounds
3245 $$ = cat2_str($1, $2.str);
3247 | SETOF SimpleTypename
3249 $$ = cat2_str(make_str("setof"), $2);
3253 SimpleTypename: Generic { $$ = $1; }
3254 | Datetime { $$ = $1; }
3255 | Numeric { $$ = $1; }
3256 | Character { $$ = $1; }
3265 generic: ident { $$ = $1; }
3266 | TYPE_P { $$ = make_str("type"); }
3267 | SQL_AT { $$ = make_str("at"); }
3268 | SQL_AUTOCOMMIT { $$ = make_str("autocommit"); }
3269 | SQL_BOOL { $$ = make_str("bool"); }
3270 | SQL_BREAK { $$ = make_str("break"); }
3271 | SQL_CALL { $$ = make_str("call"); }
3272 | SQL_CONNECT { $$ = make_str("connect"); }
3273 | SQL_CONNECTION { $$ = make_str("connection"); }
3274 | SQL_CONTINUE { $$ = make_str("continue"); }
3275 | SQL_DEALLOCATE { $$ = make_str("deallocate"); }
3276 | SQL_DISCONNECT { $$ = make_str("disconnect"); }
3277 | SQL_FOUND { $$ = make_str("found"); }
3278 | SQL_GO { $$ = make_str("go"); }
3279 | SQL_GOTO { $$ = make_str("goto"); }
3280 | SQL_IDENTIFIED { $$ = make_str("identified"); }
3281 | SQL_INDICATOR { $$ = make_str("indicator"); }
3282 | SQL_INT { $$ = make_str("int"); }
3283 | SQL_LONG { $$ = make_str("long"); }
3284 | SQL_OFF { $$ = make_str("off"); }
3285 | SQL_OPEN { $$ = make_str("open"); }
3286 | SQL_PREPARE { $$ = make_str("prepare"); }
3287 | SQL_RELEASE { $$ = make_str("release"); }
3288 | SQL_SECTION { $$ = make_str("section"); }
3289 | SQL_SHORT { $$ = make_str("short"); }
3290 | SQL_SIGNED { $$ = make_str("signed"); }
3291 | SQL_SQLERROR { $$ = make_str("sqlerror"); }
3292 | SQL_SQLPRINT { $$ = make_str("sqlprint"); }
3293 | SQL_SQLWARNING { $$ = make_str("sqlwarning"); }
3294 | SQL_STOP { $$ = make_str("stop"); }
3295 | SQL_STRUCT { $$ = make_str("struct"); }
3296 | SQL_UNSIGNED { $$ = make_str("unsigned"); }
3297 | SQL_VAR { $$ = make_str("var"); }
3298 | SQL_WHENEVER { $$ = make_str("whenever"); }
3301 /* SQL92 numeric data types
3302 * Check FLOAT() precision limits assuming IEEE floating types.
3303 * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
3304 * - thomas 1997-09-18
3306 Numeric: FLOAT opt_float
3308 $$ = cat2_str(make_str("float"), $2);
3312 $$ = make_str("double precision");
3314 | DECIMAL opt_decimal
3316 $$ = cat2_str(make_str("decimal"), $2);
3318 | NUMERIC opt_numeric
3320 $$ = cat2_str(make_str("numeric"), $2);
3325 { $$ = make_str("float"); }
3327 { $$ = make_str("double precision"); }
3329 { $$ = make_str("decimal"); }
3331 { $$ = make_str("numeric"); }
3334 opt_float: '(' Iconst ')'
3337 mmerror(ET_ERROR, "precision for FLOAT must be at least 1");
3338 else if (atol($2) >= 16)
3339 mmerror(ET_ERROR, "precision for FLOAT must be less than 16");
3340 $$ = cat_str(3, make_str("("), $2, make_str(")"));
3348 opt_numeric: '(' Iconst ',' Iconst ')'
3350 if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
3351 sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
3352 mmerror(ET_ERROR, errortext);
3354 if (atol($4) < 0 || atol($4) > atol($2)) {
3355 sprintf(errortext, "NUMERIC scale %s must be between 0 and precision %s", $4, $2);
3356 mmerror(ET_ERROR, errortext);
3358 $$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")"));
3362 if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
3363 sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
3364 mmerror(ET_ERROR, errortext);
3366 $$ = cat_str(3, make_str("("), $2, make_str(")"));
3374 opt_decimal: '(' Iconst ',' Iconst ')'
3376 if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
3377 sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
3378 mmerror(ET_ERROR, errortext);
3380 if (atol($4) < 0 || atol($4) > atol($2)) {
3381 sprintf(errortext, "NUMERIC scale %s must be between 0 and precision %s", $4, $2);
3382 mmerror(ET_ERROR, errortext);
3384 $$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")"));
3388 if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
3389 sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
3390 mmerror(ET_ERROR, errortext);
3392 $$ = cat_str(3, make_str("("), $2, make_str(")"));
3401 * SQL92 character data types
3402 * The following implements CHAR() and VARCHAR().
3405 Character: character '(' Iconst ')'
3409 sprintf(errortext, "length for type '%s' type must be at least 1",$1);
3410 mmerror(ET_ERROR, errortext);
3412 else if (atol($3) > MaxAttrSize)
3414 sprintf(errortext, "length for type '%s' cannot exceed %ld", $1, MaxAttrSize);
3415 mmerror(ET_ERROR, errortext);
3418 $$ = cat_str(4, $1, make_str("("), $3, make_str(")"));
3426 character: CHARACTER opt_varying opt_charset opt_collate
3430 sprintf(errortext, "COLLATE %s not yet implemented", $4);
3431 mmerror(ET_WARN, errortext);
3434 $$ = cat_str(4, make_str("character"), $2, $3, $4);
3436 | CHAR opt_varying { $$ = cat2_str(make_str("char"), $2); }
3437 | VARCHAR { $$ = make_str("varchar"); }
3438 | NATIONAL CHARACTER opt_varying { $$ = cat2_str(make_str("national character"), $3); }
3439 | NCHAR opt_varying { $$ = cat2_str(make_str("nchar"), $2); }
3442 opt_varying: VARYING { $$ = make_str("varying"); }
3443 | /*EMPTY*/ { $$ = EMPTY; }
3446 opt_charset: CHARACTER SET ColId { $$ = cat2_str(make_str("character set"), $3); }
3447 | /*EMPTY*/ { $$ = EMPTY; }
3450 opt_collate: COLLATE ColId { $$ = cat2_str(make_str("collate"), $2); }
3451 | /*EMPTY*/ { $$ = EMPTY; }
3458 | TIMESTAMP opt_timezone
3460 $$ = cat2_str(make_str("timestamp"), $2);
3464 $$ = make_str("time");
3466 | INTERVAL opt_interval
3468 $$ = cat2_str(make_str("interval"), $2);
3472 datetime: YEAR_P { $$ = make_str("year"); }
3473 | MONTH_P { $$ = make_str("month"); }
3474 | DAY_P { $$ = make_str("day"); }
3475 | HOUR_P { $$ = make_str("hour"); }
3476 | MINUTE_P { $$ = make_str("minute"); }
3477 | SECOND_P { $$ = make_str("second"); }
3480 opt_timezone: WITH TIME ZONE { $$ = make_str("with time zone"); }
3481 | /*EMPTY*/ { $$ = EMPTY; }
3484 opt_interval: datetime { $$ = $1; }
3485 | YEAR_P TO MONTH_P { $$ = make_str("year to #month"); }
3486 | DAY_P TO HOUR_P { $$ = make_str("day to hour"); }
3487 | DAY_P TO MINUTE_P { $$ = make_str("day to minute"); }
3488 | DAY_P TO SECOND_P { $$ = make_str("day to second"); }
3489 | HOUR_P TO MINUTE_P { $$ = make_str("hour to minute"); }
3490 | MINUTE_P TO SECOND_P { $$ = make_str("minute to second"); }
3491 | HOUR_P TO SECOND_P { $$ = make_str("hour to second"); }
3492 | /*EMPTY*/ { $$ = EMPTY; }
3496 /*****************************************************************************
3498 * expression grammar
3500 *****************************************************************************/
3502 a_expr_or_null: a_expr
3506 $$ = make_str("null");
3510 /* Expressions using row descriptors
3511 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
3512 * with singleton expressions.
3514 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
3516 $$ = cat_str(5, make_str("("), $2, make_str(") in ("), $6, make_str(")"));
3518 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
3520 $$ = cat_str(5, make_str("("), $2, make_str(") not in ("), $7, make_str(")"));
3522 | '(' row_descriptor ')' all_Op sub_type '(' SubSelect ')'
3524 $$ = cat_str(8, make_str("("), $2, make_str(")"), $4, $5, make_str("("), $7, make_str(")"));
3526 | '(' row_descriptor ')' all_Op '(' SubSelect ')'
3528 $$ = cat_str(7, make_str("("), $2, make_str(")"), $4, make_str("("), $6, make_str(")"));
3530 | '(' row_descriptor ')' all_Op '(' row_descriptor ')'
3532 $$ = cat_str(7, make_str("("), $2, make_str(")"), $4, make_str("("), $6, make_str(")"));
3536 row_descriptor: row_list ',' a_expr
3538 $$ = cat_str(3, $1, make_str(","), $3);
3542 sub_type: ANY { $$ = make_str("ANY"); }
3543 | ALL { $$ = make_str("ALL"); }
3547 row_list: row_list ',' a_expr
3549 $$ = cat_str(3, $1, make_str(","), $3);
3557 all_Op: Op | MathOp;
3559 MathOp: '+' { $$ = make_str("+"); }
3560 | '-' { $$ = make_str("-"); }
3561 | '*' { $$ = make_str("*"); }
3562 | '%' { $$ = make_str("%"); }
3563 | '^' { $$ = make_str("^"); }
3564 | '|' { $$ = make_str("|"); }
3565 | '/' { $$ = make_str("/"); }
3566 | '<' { $$ = make_str("<"); }
3567 | '>' { $$ = make_str(">"); }
3568 | '=' { $$ = make_str("="); }
3571 /* General expressions
3572 * This is the heart of the expression syntax.
3574 * We have two expression types: a_expr is the unrestricted kind, and
3575 * b_expr is a subset that must be used in some places to avoid shift/reduce
3576 * conflicts. For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
3577 * because that use of AND conflicts with AND as a boolean operator. So,
3578 * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
3580 * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
3581 * always be used by surrounding it with parens.
3583 * com_expr is all the productions that are common to a_expr and b_expr;
3584 * it's factored out just to eliminate redundant coding.
3589 | a_expr TYPECAST Typename
3590 { $$ = cat_str(3, $1, make_str("::"), $3); }
3592 * Can't collapse this into prior rule by using a_expr_or_null;
3593 * that creates reduce/reduce conflicts. Grumble.
3595 | NULL_P TYPECAST Typename
3597 $$ = cat2_str(make_str("null::"), $3);
3600 * These operators must be called out explicitly in order to make use
3601 * of yacc/bison's automatic operator-precedence handling. All other
3602 * operator names are handled by the generic productions using "Op",
3603 * below; and all those operators will have the same precedence.
3605 * If you add more explicitly-known operators, be sure to add them
3606 * also to b_expr and to the MathOp list above.
3608 | '-' a_expr %prec UMINUS
3609 { $$ = cat2_str(make_str("-"), $2); }
3611 { $$ = cat2_str(make_str("%"), $2); }
3613 { $$ = cat2_str(make_str("^"), $2); }
3615 { $$ = cat2_str(make_str("|"), $2); }
3616 /* not possible in embedded sql | ':' a_expr
3617 { $$ = cat2_str(make_str(":"), $2); }
3620 { $$ = cat2_str(make_str(";"), $2); }
3622 { $$ = cat2_str($1, make_str("%")); }
3624 { $$ = cat2_str($1, make_str("^")); }
3626 { $$ = cat2_str($1, make_str("|")); }
3628 { $$ = cat_str(3, $1, make_str("+"), $3); }
3630 { $$ = cat_str(3, $1, make_str("-"), $3); }
3632 { $$ = cat_str(3, $1, make_str("*"), $3); }
3634 { $$ = cat_str(3, $1, make_str("/"), $3); }
3636 { $$ = cat_str(3, $1, make_str("%"), $3); }
3638 { $$ = cat_str(3, $1, make_str("^"), $3); }
3640 { $$ = cat_str(3, $1, make_str("|"), $3); }
3642 { $$ = cat_str(3, $1, make_str("<"), $3); }
3644 { $$ = cat_str(3, $1, make_str(">"), $3); }
3646 { $$ = cat2_str($1, make_str("= NULL")); }
3647 /* We allow this for standards-broken SQL products, like MS stuff */
3649 { $$ = cat2_str(make_str("= NULL"), $3); }
3651 { $$ = cat_str(3, $1, make_str("="), $3); }
3653 { $$ = cat_str(3, $1, $2, $3); }
3655 { $$ = cat2_str($1, $2); }
3657 { $$ = cat2_str($1, $2); }
3659 { $$ = cat_str(3, $1, make_str("and"), $3); }
3661 { $$ = cat_str(3, $1, make_str("or"), $3); }
3663 { $$ = cat2_str(make_str("not"), $2); }
3664 | a_expr LIKE a_expr
3665 { $$ = cat_str(3, $1, make_str("like"), $3); }
3666 | a_expr NOT LIKE a_expr
3667 { $$ = cat_str(3, $1, make_str("not like"), $4); }
3669 { $$ = cat2_str($1, make_str("isnull")); }
3671 { $$ = cat2_str($1, make_str("is null")); }
3673 { $$ = cat2_str($1, make_str("notnull")); }
3674 | a_expr IS NOT NULL_P
3675 { $$ = cat2_str($1, make_str("is not null")); }
3676 /* IS TRUE, IS FALSE, etc used to be function calls
3677 * but let's make them expressions to allow the optimizer
3678 * a chance to eliminate them if a_expr is a constant string.
3679 * - thomas 1997-12-22
3682 { $$ = cat2_str($1, make_str("is true")); }
3683 | a_expr IS NOT FALSE_P
3684 { $$ = cat2_str($1, make_str("is not false")); }
3686 { $$ = cat2_str($1, make_str("is false")); }
3687 | a_expr IS NOT TRUE_P
3688 { $$ = cat2_str($1, make_str("is not true")); }
3689 | a_expr BETWEEN b_expr AND b_expr
3691 $$ = cat_str(5, $1, make_str("between"), $3, make_str("and"), $5);
3693 | a_expr NOT BETWEEN b_expr AND b_expr
3695 $$ = cat_str(5, $1, make_str("not between"), $4, make_str("and"), $6);
3697 | a_expr IN '(' in_expr ')'
3699 $$ = cat_str(4, $1, make_str(" in ("), $4, make_str(")"));
3701 | a_expr NOT IN '(' in_expr ')'
3703 $$ = cat_str(4, $1, make_str(" not in ("), $5, make_str(")"));
3705 | a_expr all_Op sub_type '(' SubSelect ')'
3707 $$ = cat_str(6, $1, $2, $3, make_str("("), $5, make_str(")"));
3712 { $$ = make_str("?"); }
3715 /* Restricted expressions
3717 * b_expr is a subset of the complete expression syntax
3719 * Presently, AND, NOT, IS, IN, and NULL are the a_expr keywords that would
3720 * cause trouble in the places where b_expr is used. For simplicity, we
3721 * just eliminate all the boolean-keyword-operator productions from b_expr.
3727 | b_expr TYPECAST Typename
3729 $$ = cat_str(3, $1, make_str("::"), $3);
3731 | NULL_P TYPECAST Typename
3733 $$ = cat2_str(make_str("null::"), $3);
3735 | '-' b_expr %prec UMINUS
3736 { $$ = cat2_str(make_str("-"), $2); }
3738 { $$ = cat2_str(make_str("%"), $2); }
3740 { $$ = cat2_str(make_str("^"), $2); }
3742 { $$ = cat2_str(make_str("|"), $2); }
3743 /* not possible in embedded sql | ':' b_expr
3744 { $$ = cat2_str(make_str(":"), $2); }
3747 { $$ = cat2_str(make_str(";"), $2); }
3749 { $$ = cat2_str($1, make_str("%")); }
3751 { $$ = cat2_str($1, make_str("^")); }
3753 { $$ = cat2_str($1, make_str("|")); }
3755 { $$ = cat_str(3, $1, make_str("+"), $3); }
3757 { $$ = cat_str(3, $1, make_str("-"), $3); }
3759 { $$ = cat_str(3, $1, make_str("*"), $3); }
3761 { $$ = cat_str(3, $1, make_str("/"), $3); }
3763 { $$ = cat_str(3, $1, make_str("%"), $3); }
3765 { $$ = cat_str(3, $1, make_str("^"), $3); }
3767 { $$ = cat_str(3, $1, make_str("|"), $3); }
3769 { $$ = cat_str(3, $1, make_str("<"), $3); }
3771 { $$ = cat_str(3, $1, make_str(">"), $3); }
3773 { $$ = cat_str(3, $1, make_str("="), $3); }
3775 { $$ = cat_str(3, $1, $2, $3); }
3777 { $$ = cat2_str($1, $2); }
3779 { $$ = cat2_str($1, $2); }
3785 * Productions that can be used in both a_expr and b_expr.
3787 * Note: productions that refer recursively to a_expr or b_expr mostly
3788 * cannot appear here. However, it's OK to refer to a_exprs that occur
3789 * inside parentheses, such as function arguments; that cannot introduce
3790 * ambiguity to the b_expr syntax.
3794 | ColId opt_indirection
3795 { $$ = cat2_str($1, $2); }
3798 | '(' a_expr_or_null ')'
3799 { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3800 | CAST '(' a_expr_or_null AS Typename ')'
3801 { $$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); }
3805 { $$ = cat2_str($1, make_str("()")); }
3806 | func_name '(' expr_list ')'
3807 { $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
3808 | func_name '(' DISTINCT expr_list ')'
3809 { $$ = cat_str(4, $1, make_str("( distinct"), $4, make_str(")")); }
3810 | func_name '(' '*' ')'
3811 { $$ = cat2_str($1, make_str("(*)")); }
3813 { $$ = make_str("current_date"); }
3815 { $$ = make_str("current_time"); }
3816 | CURRENT_TIME '(' Iconst ')'
3820 sprintf(errortext, "CURRENT_TIME(%s) precision not implemented; backend will use zero instead", $3);
3821 mmerror(ET_WARN, errortext);
3824 $$ = make_str("current_time");
3827 { $$ = make_str("current_timestamp"); }
3828 | CURRENT_TIMESTAMP '(' Iconst ')'
3832 sprintf(errortext, "CURRENT_TIMESTAMP(%s) precision not implemented; backend will use zero instead", $3);
3833 mmerror(ET_WARN, errortext);
3836 $$ = make_str("current_timestamp");
3839 { $$ = make_str("current_user"); }
3841 { $$ = make_str("user"); }
3842 | EXTRACT '(' extract_list ')'
3843 { $$ = cat_str(3, make_str("extract("), $3, make_str(")")); }
3844 | POSITION '(' position_list ')'
3845 { $$ = cat_str(3, make_str("position("), $3, make_str(")")); }
3846 | SUBSTRING '(' substr_list ')'
3847 { $$ = cat_str(3, make_str("substring("), $3, make_str(")")); }
3848 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3849 | TRIM '(' BOTH trim_list ')'
3850 { $$ = cat_str(3, make_str("trim(both"), $4, make_str(")")); }
3851 | TRIM '(' LEADING trim_list ')'
3852 { $$ = cat_str(3, make_str("trim(leading"), $4, make_str(")")); }
3853 | TRIM '(' TRAILING trim_list ')'
3854 { $$ = cat_str(3, make_str("trim(trailing"), $4, make_str(")")); }
3855 | TRIM '(' trim_list ')'
3856 { $$ = cat_str(3, make_str("trim("), $3, make_str(")")); }
3858 { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3859 | EXISTS '(' SubSelect ')'
3860 { $$ = cat_str(3, make_str("exists("), $3, make_str(")")); }
3863 * This used to use ecpg_expr, but since there is no shift/reduce conflict
3864 * anymore, we can remove ecpg_expr. - MM
3866 opt_indirection: '[' a_expr ']' opt_indirection
3868 $$ = cat_str(4, make_str("["), $2, make_str("]"), $4);
3870 | '[' a_expr ':' a_expr ']' opt_indirection
3872 $$ = cat_str(6, make_str("["), $2, make_str(":"), $4, make_str("]"), $6);
3878 expr_list: a_expr_or_null
3880 | expr_list ',' a_expr_or_null
3881 { $$ = cat_str(3, $1, make_str(","), $3); }
3882 | expr_list USING a_expr
3883 { $$ = cat_str(3, $1, make_str("using"), $3); }
3886 extract_list: extract_arg FROM a_expr
3888 $$ = cat_str(3, $1, make_str("from"), $3);
3893 { $$ = make_str("?"); }
3896 extract_arg: datetime { $$ = $1; }
3897 | TIMEZONE_HOUR { $$ = make_str("timezone_hour"); }
3898 | TIMEZONE_MINUTE { $$ = make_str("timezone_minute"); }
3901 /* position_list uses b_expr not a_expr to avoid conflict with general IN */
3902 position_list: b_expr IN b_expr
3903 { $$ = cat_str(3, $1, make_str("in"), $3); }
3908 substr_list: expr_list substr_from substr_for
3910 $$ = cat_str(3, $1, $2, $3);
3916 substr_from: FROM expr_list
3917 { $$ = cat2_str(make_str("from"), $2); }
3924 substr_for: FOR expr_list
3925 { $$ = cat2_str(make_str("for"), $2); }
3930 trim_list: a_expr FROM expr_list
3931 { $$ = cat_str(3, $1, make_str("from"), $3); }
3933 { $$ = cat2_str(make_str("from"), $2); }
3946 in_expr_nodes: a_expr
3948 | in_expr_nodes ',' a_expr
3949 { $$ = cat_str(3, $1, make_str(","), $3);}
3953 * Define SQL92-style case clause.
3954 * Allow all four forms described in the standard:
3955 * - Full specification
3956 * CASE WHEN a = b THEN c ... ELSE d END
3957 * - Implicit argument
3958 * CASE a WHEN b THEN c ... ELSE d END
3959 * - Conditional NULL
3961 * same as CASE WHEN x = y THEN NULL ELSE x END
3962 * - Conditional substitution from list, use first non-null argument
3964 * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
3965 * - thomas 1998-11-09
3967 case_expr: CASE case_arg when_clause_list case_default END_TRANS
3968 { $$ = cat_str(5, make_str("case"), $2, $3, $4, make_str("end")); }
3969 | NULLIF '(' a_expr ',' a_expr ')'
3971 $$ = cat_str(5, make_str("nullif("), $3, make_str(","), $5, make_str(")"));
3973 mmerror(ET_WARN, "NULLIF() not yet fully implemented");
3975 | COALESCE '(' expr_list ')'
3977 $$ = cat_str(3, make_str("coalesce("), $3, make_str(")"));
3981 when_clause_list: when_clause_list when_clause
3982 { $$ = cat2_str($1, $2); }
3987 when_clause: WHEN a_expr THEN a_expr_or_null
3989 $$ = cat_str(4, make_str("when"), $2, make_str("then"), $4);
3993 case_default: ELSE a_expr_or_null { $$ = cat2_str(make_str("else"), $2); }
3994 | /*EMPTY*/ { $$ = EMPTY; }
4004 attr: relation_name '.' attrs opt_indirection
4006 $$ = cat_str(4, $1, make_str("."), $3, $4);
4008 | ParamNo '.' attrs opt_indirection
4010 $$ = cat_str(4, $1, make_str("."), $3, $4);
4016 | attrs '.' attr_name
4017 { $$ = cat_str(3, $1, make_str("."), $3); }
4019 { $$ = make2_str($1, make_str(".*")); }
4023 /*****************************************************************************
4027 *****************************************************************************/
4029 /* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
4030 target_list: target_list ',' target_el
4031 { $$ = cat_str(3, $1, make_str(","), $3); }
4036 /* AS is not optional because shift/red conflict with unary ops */
4037 target_el: a_expr_or_null AS ColLabel
4039 $$ = cat_str(3, $1, make_str("as"), $3);
4045 | relation_name '.' '*'
4047 $$ = make2_str($1, make_str(".*"));
4055 /* Target list as found in UPDATE table SET ... */
4056 update_target_list: update_target_list ',' update_target_el
4057 { $$ = cat_str(3, $1, make_str(","),$3); }
4060 | '*' { $$ = make_str("*"); }
4063 update_target_el: ColId opt_indirection '=' a_expr_or_null
4065 $$ = cat_str(4, $1, $2, make_str("="), $4);
4069 /*****************************************************************************
4071 * Names and constants
4073 *****************************************************************************/
4075 relation_name: SpecialRuleRelation
4081 /* disallow refs to variable system tables */
4082 if (strcmp(LogRelationName, $1) == 0
4083 || strcmp(VariableRelationName, $1) == 0) {
4084 sprintf(errortext, make_str("%s cannot be accessed by users"),$1);
4085 mmerror(ET_ERROR, errortext);
4092 database_name: ColId { $$ = $1; };
4093 access_method: ident { $$ = $1; };
4094 attr_name: ColId { $$ = $1; };
4095 class: ident { $$ = $1; };
4096 index_name: ColId { $$ = $1; };
4099 * Include date/time keywords as SQL92 extension.
4100 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4102 name: ColId { $$ = $1; };
4103 func_name: ColId { $$ = $1; };
4105 file_name: Sconst { $$ = $1; };
4106 /* NOT USED recipe_name: ident { $$ = $1; };*/
4109 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4123 /* this rule formerly used Typename, but that causes reduce conf licts
4124 * with subscripted column names ...
4126 | SimpleTypename Sconst
4128 $$ = cat2_str($1, $2);
4134 $$ = make_str("true");
4138 $$ = make_str("false");
4142 ParamNo: PARAM opt_indirection
4144 $$ = cat2_str(make_name(), $2);
4148 Iconst: ICONST { $$ = make_name();};
4149 Fconst: FCONST { $$ = make_name();};
4151 $$ = (char *)mm_alloc(strlen($1) + 3);
4154 $$[strlen($1)+2]='\0';
4155 $$[strlen($1)+1]='\'';
4158 UserId: ident { $$ = $1;};
4160 /* Column and type identifier
4161 * Does not include explicit datetime types
4162 * since these must be decoupled in Typename syntax.
4163 * Use ColId for most identifiers. - thomas 1997-10-21
4172 /* Column identifier
4173 * Include date/time keywords as SQL92 extension.
4174 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4175 * Add other keywords. Note that as the syntax expands,
4176 * some of these keywords will have to be removed from this
4177 * list due to shift/reduce conflicts in yacc. If so, move
4178 * down to the ColLabel entity. - thomas 1997-11-06
4180 ColId: ident { $$ = $1; }
4181 | datetime { $$ = $1; }
4182 | ABSOLUTE { $$ = make_str("absolute"); }
4183 | ACCESS { $$ = make_str("access"); }
4184 | ACTION { $$ = make_str("action"); }
4185 | AFTER { $$ = make_str("after"); }
4186 | AGGREGATE { $$ = make_str("aggregate"); }
4187 | BACKWARD { $$ = make_str("backward"); }
4188 | BEFORE { $$ = make_str("before"); }
4189 | CACHE { $$ = make_str("cache"); }
4190 | COMMENT { $$ = make_str("comment"); }
4191 | COMMITTED { $$ = make_str("committed"); }
4192 | CONSTRAINTS { $$ = make_str("constraints"); }
4193 | CREATEDB { $$ = make_str("createdb"); }
4194 | CREATEUSER { $$ = make_str("createuser"); }
4195 | CYCLE { $$ = make_str("cycle"); }
4196 | DATABASE { $$ = make_str("database"); }
4197 | DEFERRABLE { $$ = make_str("deferrable"); }
4198 | DEFERRED { $$ = make_str("deferred"); }
4199 | DELIMITERS { $$ = make_str("delimiters"); }
4200 | DOUBLE { $$ = make_str("double"); }
4201 | EACH { $$ = make_str("each"); }
4202 | ENCODING { $$ = make_str("encoding"); }
4203 | EXCLUSIVE { $$ = make_str("exclusive"); }
4204 | FORWARD { $$ = make_str("forward"); }
4205 | FUNCTION { $$ = make_str("function"); }
4206 | HANDLER { $$ = make_str("handler"); }
4207 | IMMEDIATE { $$ = make_str("immediate"); }
4208 | INCREMENT { $$ = make_str("increment"); }
4209 | INDEX { $$ = make_str("index"); }
4210 | INHERITS { $$ = make_str("inherits"); }
4211 | INITIALLY { $$ = make_str("initially"); }
4212 | INSENSITIVE { $$ = make_str("insensitive"); }
4213 | INSTEAD { $$ = make_str("instead"); }
4214 | ISNULL { $$ = make_str("isnull"); }
4215 | ISOLATION { $$ = make_str("isolation"); }
4216 | KEY { $$ = make_str("key"); }
4217 | LANGUAGE { $$ = make_str("language"); }
4218 | LANCOMPILER { $$ = make_str("lancompiler"); }
4219 | LEVEL { $$ = make_str("level"); }
4220 | LOCATION { $$ = make_str("location"); }
4221 | MATCH { $$ = make_str("match"); }
4222 | MAXVALUE { $$ = make_str("maxvalue"); }
4223 | MINVALUE { $$ = make_str("minvalue"); }
4224 | MODE { $$ = make_str("mode"); }
4225 | NEXT { $$ = make_str("next"); }
4226 | NOCREATEDB { $$ = make_str("nocreatedb"); }
4227 | NOCREATEUSER { $$ = make_str("nocreateuser"); }
4228 | NOTHING { $$ = make_str("nothing"); }
4229 | NOTNULL { $$ = make_str("notnull"); }
4230 | OF { $$ = make_str("of"); }
4231 | OIDS { $$ = make_str("oids"); }
4232 | ONLY { $$ = make_str("only"); }
4233 | OPERATOR { $$ = make_str("operator"); }
4234 | OPTION { $$ = make_str("option"); }
4235 | PASSWORD { $$ = make_str("password"); }
4236 | PENDANT { $$ = make_str("pendant"); }
4237 | PRIOR { $$ = make_str("prior"); }
4238 | PRIVILEGES { $$ = make_str("privileges"); }
4239 | PROCEDURAL { $$ = make_str("procedural"); }
4240 | READ { $$ = make_str("read"); }
4241 | RELATIVE { $$ = make_str("relative"); }
4242 | RENAME { $$ = make_str("rename"); }
4243 | RESTRICT { $$ = make_str("restrict"); }
4244 | RETURNS { $$ = make_str("returns"); }
4245 | ROW { $$ = make_str("row"); }
4246 | RULE { $$ = make_str("rule"); }
4247 | SCROLL { $$ = make_str("scroll"); }
4248 | SEQUENCE { $$ = make_str("sequence"); }
4249 | SERIAL { $$ = make_str("serial"); }
4250 | SERIALIZABLE { $$ = make_str("serializable"); }
4251 | SHARE { $$ = make_str("share"); }
4252 | START { $$ = make_str("start"); }
4253 | STATEMENT { $$ = make_str("statement"); }
4254 | STDIN { $$ = make_str("stdin"); }
4255 | STDOUT { $$ = make_str("stdout"); }
4256 | SYSID { $$ = make_str("sysid"); }
4257 | TIME { $$ = make_str("time"); }
4258 | TIMESTAMP { $$ = make_str("timestamp"); }
4259 | TIMEZONE_HOUR { $$ = make_str("timezone_hour"); }
4260 | TIMEZONE_MINUTE { $$ = make_str("timezone_minute"); }
4261 | TRIGGER { $$ = make_str("trigger"); }
4262 | TRUNCATE { $$ = make_str("truncate"); }
4263 | TRUSTED { $$ = make_str("trusted"); }
4264 | TYPE_P { $$ = make_str("type"); }
4265 | VALID { $$ = make_str("valid"); }
4266 | VERSION { $$ = make_str("version"); }
4267 | ZONE { $$ = make_str("zone"); }
4268 | SQL_AT { $$ = make_str("at"); }
4269 | SQL_BOOL { $$ = make_str("bool"); }
4270 | SQL_BREAK { $$ = make_str("break"); }
4271 | SQL_CALL { $$ = make_str("call"); }
4272 | SQL_CONNECT { $$ = make_str("connect"); }
4273 | SQL_CONTINUE { $$ = make_str("continue"); }
4274 | SQL_DEALLOCATE { $$ = make_str("deallocate"); }
4275 | SQL_DISCONNECT { $$ = make_str("disconnect"); }
4276 | SQL_FOUND { $$ = make_str("found"); }
4277 | SQL_GO { $$ = make_str("go"); }
4278 | SQL_GOTO { $$ = make_str("goto"); }
4279 | SQL_IDENTIFIED { $$ = make_str("identified"); }
4280 | SQL_INDICATOR { $$ = make_str("indicator"); }
4281 | SQL_INT { $$ = make_str("int"); }
4282 | SQL_LONG { $$ = make_str("long"); }
4283 | SQL_OFF { $$ = make_str("off"); }
4284 | SQL_OPEN { $$ = make_str("open"); }
4285 | SQL_PREPARE { $$ = make_str("prepare"); }
4286 | SQL_RELEASE { $$ = make_str("release"); }
4287 | SQL_SECTION { $$ = make_str("section"); }
4288 | SQL_SHORT { $$ = make_str("short"); }
4289 | SQL_SIGNED { $$ = make_str("signed"); }
4290 | SQL_SQLERROR { $$ = make_str("sqlerror"); }
4291 | SQL_SQLPRINT { $$ = make_str("sqlprint"); }
4292 | SQL_SQLWARNING { $$ = make_str("sqlwarning"); }
4293 | SQL_STOP { $$ = make_str("stop"); }
4294 | SQL_STRUCT { $$ = make_str("struct"); }
4295 | SQL_UNSIGNED { $$ = make_str("unsigned"); }
4296 | SQL_VAR { $$ = make_str("var"); }
4297 | SQL_WHENEVER { $$ = make_str("whenever"); }
4300 * Allowed labels in "AS" clauses.
4301 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
4302 * compatibility. Cannot allow this for column names since the
4303 * syntax would not distinguish between the constant value and
4304 * a column name. - thomas 1997-10-24
4305 * Add other keywords to this list. Note that they appear here
4306 * rather than in ColId if there was a shift/reduce conflict
4307 * when used as a full identifier. - thomas 1997-11-06
4309 ColLabel: ColId { $$ = $1; }
4310 | ABORT_TRANS { $$ = make_str("abort"); }
4311 | ANALYZE { $$ = make_str("analyze"); }
4312 | BINARY { $$ = make_str("binary"); }
4313 | CASE { $$ = make_str("case"); }
4314 | CLUSTER { $$ = make_str("cluster"); }
4315 | COALESCE { $$ = make_str("coalesce"); }
4316 | CONSTRAINT { $$ = make_str("constraint"); }
4317 | COPY { $$ = make_str("copy"); }
4318 | CURRENT { $$ = make_str("current"); }
4319 | DECIMAL { $$ = make_str("decimal"); }
4320 | DO { $$ = make_str("do"); }
4321 | ELSE { $$ = make_str("else"); }
4322 | END_TRANS { $$ = make_str("end"); }
4323 | EXPLAIN { $$ = make_str("explain"); }
4324 | EXTEND { $$ = make_str("extend"); }
4325 | FALSE_P { $$ = make_str("false"); }
4326 | FLOAT { $$ = make_str("float"); }
4327 | FOREIGN { $$ = make_str("foreign"); }
4328 | GLOBAL { $$ = make_str("global"); }
4329 | GROUP { $$ = make_str("group"); }
4330 | LISTEN { $$ = make_str("listen"); }
4331 | LOAD { $$ = make_str("load"); }
4332 | LOCK_P { $$ = make_str("lock"); }
4333 | MOVE { $$ = make_str("move"); }
4334 | NEW { $$ = make_str("new"); }
4335 | NONE { $$ = make_str("none"); }
4336 | NULLIF { $$ = make_str("nullif"); }
4337 | NUMERIC { $$ = make_str("numeric"); }
4338 | ORDER { $$ = make_str("order"); }
4339 | POSITION { $$ = make_str("position"); }
4340 | PRECISION { $$ = make_str("precision"); }
4341 | RESET { $$ = make_str("reset"); }
4342 | SETOF { $$ = make_str("setof"); }
4343 | SHOW { $$ = make_str("show"); }
4344 | TABLE { $$ = make_str("table"); }
4345 | THEN { $$ = make_str("then"); }
4346 | TRANSACTION { $$ = make_str("transaction"); }
4347 | TRUE_P { $$ = make_str("true"); }
4348 | VACUUM { $$ = make_str("vacuum"); }
4349 | VERBOSE { $$ = make_str("verbose"); }
4350 | WHEN { $$ = make_str("when"); }
4353 SpecialRuleRelation: CURRENT
4356 $$ = make_str("current");
4358 mmerror(ET_ERROR, "CURRENT used in non-rule query");
4363 $$ = make_str("new");
4365 mmerror(ET_ERROR, "NEW used in non-rule query");
4370 * and now special embedded SQL stuff
4374 * the exec sql connect statement: connect to the given database
4376 ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
4378 $$ = cat_str(5, $3, make_str(","), $5, make_str(","), $4);
4380 | SQL_CONNECT TO DEFAULT
4382 $$ = make_str("NULL,NULL,NULL,\"DEFAULT\"");
4384 /* also allow ORACLE syntax */
4385 | SQL_CONNECT ora_user
4387 $$ = cat_str(3, make_str("NULL,"), $2, make_str(",NULL"));
4390 connection_target: database_name opt_server opt_port
4392 /* old style: dbname[@server][:port] */
4393 if (strlen($2) > 0 && *($2) != '@')
4395 sprintf(errortext, "parse error at or near '%s'", $2);
4396 mmerror(ET_ERROR, errortext);
4399 $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
4401 | db_prefix server opt_port '/' database_name opt_options
4403 /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
4404 if (strncmp($2, "://", strlen("://")) != 0)
4406 sprintf(errortext, "parse error at or near '%s'", $2);
4407 mmerror(ET_ERROR, errortext);
4410 if (strncmp($1, "unix", strlen("unix")) == 0 && strncmp($2 + strlen("://"), "localhost", strlen("localhost")) != 0)
4412 sprintf(errortext, "unix domain sockets only work on 'localhost' but not on '%9.9s'", $2);
4413 mmerror(ET_ERROR, errortext);
4416 if (strncmp($1, "unix", strlen("unix")) != 0 && strncmp($1, "tcp", strlen("tcp")) != 0)
4418 sprintf(errortext, "only protocols 'tcp' and 'unix' are supported");
4419 mmerror(ET_ERROR, errortext);
4422 $$ = make2_str(make3_str(make_str("\""), $1, $2), make3_str(make3_str($3, make_str("/"), $5), $6, make_str("\"")));
4432 $$[strlen($$) - 1] = '\"';
4436 db_prefix: ident cvariable
4438 if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
4440 sprintf(errortext, "parse error at or near '%s'", $2);
4441 mmerror(ET_ERROR, errortext);
4444 if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
4446 sprintf(errortext, "Illegal connection type %s", $1);
4447 mmerror(ET_ERROR, errortext);
4450 $$ = make3_str( $1, make_str(":"), $2);
4453 server: Op server_name
4455 if (strcmp($1, "@") != 0 && strcmp($1, "://") != 0)
4457 sprintf(errortext, "parse error at or near '%s'", $1);
4458 mmerror(ET_ERROR, errortext);
4461 $$ = make2_str($1, $2);
4464 opt_server: server { $$ = $1; }
4465 | /* empty */ { $$ = EMPTY; }
4467 server_name: ColId { $$ = $1; }
4468 | ColId '.' server_name { $$ = make3_str($1, make_str("."), $3); }
4470 opt_port: ':' Iconst { $$ = make2_str(make_str(":"), $2); }
4471 | /* empty */ { $$ = EMPTY; }
4473 opt_connection_name: AS connection_target { $$ = $2; }
4474 | /* empty */ { $$ = make_str("NULL"); }
4476 opt_user: USER ora_user { $$ = $2; }
4477 | /* empty */ { $$ = make_str("NULL,NULL"); }
4481 $$ = cat2_str($1, make_str(", NULL"));
4483 | user_name '/' user_name
4485 $$ = cat_str(3, $1, make_str(","), $3);
4487 | user_name SQL_IDENTIFIED BY user_name
4489 $$ = cat_str(3, $1, make_str(","), $4);
4491 | user_name USING user_name
4493 $$ = cat_str(3, $1, make_str(","), $3);
4496 user_name: UserId { if ($1[0] == '\"')
4499 $$ = make3_str(make_str("\""), $1, make_str("\""));
4501 | char_variable { $$ = $1; }
4502 | SCONST { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
4504 char_variable: cvariable
4505 { /* check if we have a char variable */
4506 struct variable *p = find_variable($1);
4507 enum ECPGttype typ = p->type->typ;
4509 /* if array see what's inside */
4510 if (typ == ECPGt_array)
4511 typ = p->type->u.element->typ;
4516 case ECPGt_unsigned_char:
4520 $$ = make2_str($1, make_str(".arr"));
4523 mmerror(ET_ERROR, "invalid datatype");
4528 opt_options: Op ColId
4530 if (strlen($1) == 0)
4531 mmerror(ET_ERROR, "parse error");
4533 if (strcmp($1, "?") != 0)
4535 sprintf(errortext, "parse error at or near %s", $1);
4536 mmerror(ET_ERROR, errortext);
4539 $$ = make2_str(make_str("?"), $2);
4541 | /* empty */ { $$ = EMPTY; }
4544 * Declare a prepared cursor. The syntax is different from the standard
4545 * declare statement, so we create a new rule.
4547 ECPGCursorStmt: DECLARE name opt_cursor CURSOR FOR ident
4549 struct cursor *ptr, *this;
4550 struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4552 for (ptr = cur; ptr != NULL; ptr = ptr->next)
4554 if (strcmp($2, ptr->name) == 0)
4556 /* re-definition is a bug */
4557 sprintf(errortext, "cursor %s already defined", $2);
4558 mmerror(ET_ERROR, errortext);
4562 this = (struct cursor *) mm_alloc(sizeof(struct cursor));
4564 /* initial definition */
4567 this->connection = connection;
4568 this->command = cat_str(4, make_str("declare"), mm_strdup($2), $3, make_str("cursor for ?"));
4569 this->argsresult = NULL;
4571 thisquery->type = &ecpg_query;
4572 thisquery->brace_level = 0;
4573 thisquery->next = NULL;
4574 thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($6));
4575 sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $6);
4577 this->argsinsert = NULL;
4578 add_variable(&(this->argsinsert), thisquery, &no_indicator);
4582 $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
4587 * the exec sql deallocate prepare command to deallocate a previously
4588 * prepared statement
4590 ECPGDeallocate: SQL_DEALLOCATE SQL_PREPARE ident { $$ = cat_str(3, make_str("ECPGdeallocate(__LINE__, \""), $3, make_str("\");")); }
4593 * variable declaration inside the exec sql declare block
4595 ECPGDeclaration: sql_startdeclare
4597 fputs("/* exec sql begin declare section */", yyout);
4599 variable_declarations sql_enddeclare
4601 fprintf(yyout, "%s/* exec sql end declare section */", $3);
4603 output_line_number();
4606 sql_startdeclare : ecpgstart BEGIN_TRANS DECLARE SQL_SECTION ';' {}
4608 sql_enddeclare: ecpgstart END_TRANS DECLARE SQL_SECTION ';' {}
4610 variable_declarations: /* empty */ { $$ = EMPTY; }
4611 | declarations { $$ = $1; }
4613 declarations: declaration { $$ = $1; }
4614 | declarations declaration { $$ = cat2_str($1, $2); }
4616 declaration: storage_clause storage_modifier
4618 actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2));
4619 actual_startline[struct_level] = hashline_number();
4623 actual_type[struct_level].type_enum = $4.type_enum;
4624 actual_type[struct_level].type_dimension = $4.type_dimension;
4625 actual_type[struct_level].type_index = $4.type_index;
4627 /* we do not need the string "varchar" for output */
4628 /* so replace it with an empty string */
4629 if ($4.type_enum == ECPGt_varchar)
4637 $$ = cat_str(6, actual_startline[struct_level], $1, $2, $4.type_str, $6, make_str(";\n"));
4640 storage_clause : S_EXTERN { $$ = make_str("extern"); }
4641 | S_STATIC { $$ = make_str("static"); }
4642 | S_REGISTER { $$ = make_str("register"); }
4643 | S_AUTO { $$ = make_str("auto"); }
4644 | /* empty */ { $$ = EMPTY; }
4646 storage_modifier : S_CONST { $$ = make_str("const"); }
4647 | S_VOLATILE { $$ = make_str("volatile"); }
4648 | /* empty */ { $$ = EMPTY; }
4653 $$.type_str = mm_strdup(ECPGtype_name($1));
4654 $$.type_dimension = -1;
4659 $$.type_enum = ECPGt_varchar;
4660 $$.type_str = make_str("varchar");;
4661 $$.type_dimension = -1;
4666 $$.type_enum = ECPGt_struct;
4668 $$.type_dimension = -1;
4673 $$.type_enum = ECPGt_union;
4675 $$.type_dimension = -1;
4681 $$.type_enum = ECPGt_int;
4682 $$.type_dimension = -1;
4687 /* this is for typedef'ed types */
4688 struct typedefs *this = get_typedef($1);
4690 $$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
4691 $$.type_enum = this->type->type_enum;
4692 $$.type_dimension = this->type->type_dimension;
4693 $$.type_index = this->type->type_index;
4694 struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
4697 enum_type: SQL_ENUM opt_symbol enum_definition
4699 $$ = cat_str(3, make_str("enum"), $2, $3);
4703 $$ = cat2_str(make_str("enum"), $2);
4706 enum_definition: '{' c_list '}' { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
4708 struct_type: s_struct '{' variable_declarations '}'
4710 ECPGfree_struct_member(struct_member_list[struct_level]);
4711 free(actual_storage[struct_level--]);
4712 $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
4715 union_type: s_union '{' variable_declarations '}'
4717 ECPGfree_struct_member(struct_member_list[struct_level]);
4718 free(actual_storage[struct_level--]);
4719 $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
4722 s_struct: SQL_STRUCT opt_symbol
4724 struct_member_list[struct_level++] = NULL;
4725 if (struct_level >= STRUCT_DEPTH)
4726 mmerror(ET_ERROR, "Too many levels in nested structure definition");
4728 /* reset this variable so we see if there was */
4729 /* an initializer specified */
4732 $$ = cat2_str(make_str("struct"), $2);
4735 s_union: UNION opt_symbol
4737 struct_member_list[struct_level++] = NULL;
4738 if (struct_level >= STRUCT_DEPTH)
4739 mmerror(ET_ERROR, "Too many levels in nested structure definition");
4741 /* reset this variable so we see if there was */
4742 /* an initializer specified */
4745 $$ = cat2_str(make_str("union"), $2);
4748 opt_symbol: /* empty */ { $$ = EMPTY; }
4749 | symbol { $$ = $1; }
4751 simple_type: unsigned_type { $$=$1; }
4752 | opt_signed signed_type { $$=$2; }
4755 unsigned_type: SQL_UNSIGNED SQL_SHORT { $$ = ECPGt_unsigned_short; }
4756 | SQL_UNSIGNED SQL_SHORT SQL_INT { $$ = ECPGt_unsigned_short; }
4757 | SQL_UNSIGNED { $$ = ECPGt_unsigned_int; }
4758 | SQL_UNSIGNED SQL_INT { $$ = ECPGt_unsigned_int; }
4759 | SQL_UNSIGNED SQL_LONG { $$ = ECPGt_unsigned_long; }
4760 | SQL_UNSIGNED SQL_LONG SQL_INT { $$ = ECPGt_unsigned_long; }
4761 | SQL_UNSIGNED CHAR { $$ = ECPGt_unsigned_char; }
4764 signed_type: SQL_SHORT { $$ = ECPGt_short; }
4765 | SQL_SHORT SQL_INT { $$ = ECPGt_short; }
4766 | SQL_INT { $$ = ECPGt_int; }
4767 | SQL_LONG { $$ = ECPGt_long; }
4768 | SQL_LONG SQL_INT { $$ = ECPGt_long; }
4769 | SQL_BOOL { $$ = ECPGt_bool; };
4770 | FLOAT { $$ = ECPGt_float; }
4771 | DOUBLE { $$ = ECPGt_double; }
4772 | CHAR { $$ = ECPGt_char; }
4775 opt_signed: SQL_SIGNED
4779 varchar_type: VARCHAR { $$ = ECPGt_varchar; }
4781 variable_list: variable
4785 | variable_list ',' variable
4787 $$ = cat_str(3, $1, make_str(","), $3);
4790 variable: opt_pointer symbol opt_array_bounds opt_initializer
4792 struct ECPGtype * type;
4793 int dimension = $3.index1; /* dimension of array */
4794 int length = $3.index2; /* lenght of string */
4795 char dim[14L], ascii_len[12];
4797 adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
4799 switch (actual_type[struct_level].type_enum)
4804 type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum);
4806 type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum), dimension);
4808 $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4811 if (dimension == -1)
4812 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
4814 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
4824 sprintf(dim, "[%d]", dimension);
4827 sprintf(ascii_len, "%d", length);
4830 mmerror(ET_ERROR, "pointer to varchar are not implemented");
4833 $$ = 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);
4835 $$ = 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);
4839 case ECPGt_unsigned_char:
4840 if (dimension == -1)
4841 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
4843 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
4845 $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4849 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1);
4851 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, 1), dimension);
4853 $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
4857 if (struct_level == 0)
4858 new_variable($2, type);
4860 ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
4865 opt_initializer: /* empty */ { $$ = EMPTY; }
4868 $$ = cat2_str(make_str("="), $2);
4871 opt_pointer: /* empty */ { $$ = EMPTY; }
4872 | '*' { $$ = make_str("*"); }
4875 * As long as the prepare statement is not supported by the backend, we will
4876 * try to simulate it here so we get dynamic SQL
4878 ECPGDeclare: DECLARE STATEMENT ident
4880 /* this is only supported for compatibility */
4881 $$ = cat_str(3, make_str("/* declare statement"), $3, make_str("*/"));
4884 * the exec sql disconnect statement: disconnect from the given database
4886 ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
4888 dis_name: connection_object { $$ = $1; }
4889 | CURRENT { $$ = make_str("CURRENT"); }
4890 | ALL { $$ = make_str("ALL"); }
4891 | /* empty */ { $$ = make_str("CURRENT"); }
4893 connection_object: connection_target { $$ = $1; }
4894 | DEFAULT { $$ = make_str("DEFAULT"); }
4897 * execute a given string as sql command
4899 ECPGExecute : EXECUTE IMMEDIATE execstring
4901 struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4903 thisquery->type = &ecpg_query;
4904 thisquery->brace_level = 0;
4905 thisquery->next = NULL;
4906 thisquery->name = $3;
4908 add_variable(&argsinsert, thisquery, &no_indicator);
4914 struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4916 thisquery->type = &ecpg_query;
4917 thisquery->brace_level = 0;
4918 thisquery->next = NULL;
4919 thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($2));
4920 sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2);
4922 add_variable(&argsinsert, thisquery, &no_indicator);
4928 execstring: char_variable |
4929 CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); };
4932 * the exec sql free command to deallocate a previously
4933 * prepared statement
4935 ECPGFree: SQL_FREE ident { $$ = $2; }
4938 * open is an open cursor, at the moment this has to be removed
4940 ECPGOpen: SQL_OPEN name ecpg_using {
4944 ecpg_using: /* empty */ { $$ = EMPTY; }
4945 | USING variablelist {
4946 /* mmerror ("open cursor with variables not implemented yet"); */
4950 variablelist: cinputvariable | cinputvariable ',' variablelist
4953 * As long as the prepare statement is not supported by the backend, we will
4954 * try to simulate it here so we get dynamic SQL
4956 ECPGPrepare: SQL_PREPARE ident FROM execstring
4958 $$ = cat2_str(make3_str(make_str("\""), $2, make_str("\",")), $4);
4962 * for compatibility with ORACLE we will also allow the keyword RELEASE
4963 * after a transaction statement to disconnect from the database.
4966 ECPGRelease: TransactionStmt SQL_RELEASE
4968 if (strcmp($1, "begin") == 0)
4969 mmerror(ET_ERROR, "RELEASE does not make sense when beginning a transaction");
4971 fprintf(yyout, "ECPGtrans(__LINE__, %s, \"%s\");",
4972 connection ? connection : "NULL", $1);
4974 fprintf(yyout, "ECPGdisconnect(__LINE__, \"\");");
4980 * set/reset the automatic transaction mode, this needs a differnet handling
4981 * as the other set commands
4983 ECPGSetAutocommit: SET SQL_AUTOCOMMIT to_equal on_off
4988 on_off: ON { $$ = make_str("on"); }
4989 | SQL_OFF { $$ = make_str("off"); }
4994 * set the actual connection, this needs a differnet handling as the other
4997 ECPGSetConnection: SET SQL_CONNECTION to_equal connection_object
5003 * define a new type for embedded SQL
5005 ECPGTypedef: TYPE_P symbol IS type opt_type_array_bounds opt_reference
5007 /* add entry to list */
5008 struct typedefs *ptr, *this;
5009 int dimension = $5.index1;
5010 int length = $5.index2;
5012 if (($4.type_enum == ECPGt_struct ||
5013 $4.type_enum == ECPGt_union) &&
5015 mmerror(ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
5017 for (ptr = types; ptr != NULL; ptr = ptr->next)
5019 if (strcmp($2, ptr->name) == 0)
5021 /* re-definition is a bug */
5022 sprintf(errortext, "Type %s already defined", $2);
5023 mmerror(ET_ERROR, errortext);
5027 adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, strlen($6));
5029 this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
5031 /* initial definition */
5034 this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
5035 this->type->type_enum = $4.type_enum;
5036 this->type->type_str = mm_strdup($2);
5037 this->type->type_dimension = dimension; /* dimension of array */
5038 this->type->type_index = length; /* lenght of string */
5039 this->struct_member_list = ($4.type_enum == ECPGt_struct || $4.type_enum == ECPGt_union) ?
5040 struct_member_list[struct_level] : NULL;
5042 if ($4.type_enum != ECPGt_varchar &&
5043 $4.type_enum != ECPGt_char &&
5044 $4.type_enum != ECPGt_unsigned_char &&
5045 this->type->type_index >= 0)
5046 mmerror(ET_ERROR, "No multi-dimensional array support for simple data types");
5050 $$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($2), make_str("is"), mm_strdup($4.type_str), mm_strdup($5.str), $6, make_str("*/"));
5053 opt_type_array_bounds: '[' ']' opt_type_array_bounds
5056 $$.index2 = $3.index1;
5057 $$.str = cat2_str(make_str("[]"), $3.str);
5059 | '(' ')' opt_type_array_bounds
5062 $$.index2 = $3.index1;
5063 $$.str = cat2_str(make_str("[]"), $3.str);
5065 | '[' Iresult ']' opt_type_array_bounds
5067 char *txt = mm_alloc(20L);
5069 sprintf (txt, "%d", $2);
5071 $$.index2 = $4.index1;
5072 $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
5074 | '(' Iresult ')' opt_type_array_bounds
5076 char *txt = mm_alloc(20L);
5078 sprintf (txt, "%d", $2);
5080 $$.index2 = $4.index1;
5081 $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
5091 opt_reference: SQL_REFERENCE { $$ = make_str("reference"); }
5092 | /* empty */ { $$ = EMPTY; }
5095 * define the type of one variable for embedded SQL
5097 ECPGVar: SQL_VAR symbol IS type opt_type_array_bounds opt_reference
5099 struct variable *p = find_variable($2);
5100 int dimension = $5.index1;
5101 int length = $5.index2;
5102 struct ECPGtype * type;
5104 if (($4.type_enum == ECPGt_struct ||
5105 $4.type_enum == ECPGt_union) &&
5107 mmerror(ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
5109 adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, strlen($6));
5111 switch ($4.type_enum)
5116 type = ECPGmake_struct_type(struct_member_list[struct_level], $4.type_enum);
5118 type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $4.type_enum), dimension);
5121 if (dimension == -1)
5122 type = ECPGmake_simple_type($4.type_enum, length);
5124 type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, length), dimension);
5128 case ECPGt_unsigned_char:
5129 if (dimension == -1)
5130 type = ECPGmake_simple_type($4.type_enum, length);
5132 type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, length), dimension);
5137 mmerror(ET_ERROR, "No multi-dimensional array support for simple data types");
5140 type = ECPGmake_simple_type($4.type_enum, 1);
5142 type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, 1), dimension);
5147 ECPGfree_type(p->type);
5150 $$ = cat_str(7, make_str("/* exec sql var"), mm_strdup($2), make_str("is"), mm_strdup($4.type_str), mm_strdup($5.str), $6, make_str("*/"));
5154 * whenever statement: decide what to do in case of error/no data found
5155 * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
5157 ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action {
5158 when_error.code = $<action>3.code;
5159 when_error.command = $<action>3.command;
5160 $$ = cat_str(3, make_str("/* exec sql whenever sqlerror "), $3.str, make_str("; */\n"));
5162 | SQL_WHENEVER NOT SQL_FOUND action {
5163 when_nf.code = $<action>4.code;
5164 when_nf.command = $<action>4.command;
5165 $$ = cat_str(3, make_str("/* exec sql whenever not found "), $4.str, make_str("; */\n"));
5167 | SQL_WHENEVER SQL_SQLWARNING action {
5168 when_warn.code = $<action>3.code;
5169 when_warn.command = $<action>3.command;
5170 $$ = cat_str(3, make_str("/* exec sql whenever sql_warning "), $3.str, make_str("; */\n"));
5173 action : SQL_CONTINUE {
5174 $<action>$.code = W_NOTHING;
5175 $<action>$.command = NULL;
5176 $<action>$.str = make_str("continue");
5179 $<action>$.code = W_SQLPRINT;
5180 $<action>$.command = NULL;
5181 $<action>$.str = make_str("sqlprint");
5184 $<action>$.code = W_STOP;
5185 $<action>$.command = NULL;
5186 $<action>$.str = make_str("stop");
5189 $<action>$.code = W_GOTO;
5190 $<action>$.command = strdup($2);
5191 $<action>$.str = cat2_str(make_str("goto "), $2);
5194 $<action>$.code = W_GOTO;
5195 $<action>$.command = strdup($3);
5196 $<action>$.str = cat2_str(make_str("goto "), $3);
5198 | DO name '(' c_args ')' {
5199 $<action>$.code = W_DO;
5200 $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
5201 $<action>$.str = cat2_str(make_str("do"), mm_strdup($<action>$.command));
5204 $<action>$.code = W_BREAK;
5205 $<action>$.command = NULL;
5206 $<action>$.str = make_str("break");
5208 | SQL_CALL name '(' c_args ')' {
5209 $<action>$.code = W_DO;
5210 $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
5211 $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
5214 /* some other stuff for ecpg */
5219 | a_expr TYPECAST Typename
5220 { $$ = cat_str(3, $1, make_str("::"), $3); }
5221 | '-' ecpg_expr %prec UMINUS
5222 { $$ = cat2_str(make_str("-"), $2); }
5224 { $$ = cat2_str(make_str("%"), $2); }
5226 { $$ = cat2_str(make_str("^"), $2); }
5228 { $$ = cat2_str(make_str("|"), $2); }
5230 { $$ = cat2_str(make_str(";"), $2); }
5232 { $$ = cat2_str($1, make_str("%")); }
5234 { $$ = cat2_str($1, make_str("^")); }
5236 { $$ = cat2_str($1, make_str("|")); }
5237 | a_expr '+' ecpg_expr
5238 { $$ = cat_str(3, $1, make_str("+"), $3); }
5239 | a_expr '-' ecpg_expr
5240 { $$ = cat_str(3, $1, make_str("-"), $3); }
5241 | a_expr '*' ecpg_expr
5242 { $$ = cat_str(3, $1, make_str("*"), $3); }
5243 | a_expr '/' ecpg_expr
5244 { $$ = cat_str(3, $1, make_str("/"), $3); }
5245 | a_expr '%' ecpg_expr
5246 { $$ = cat_str(3, $1, make_str("%"), $3); }
5247 | a_expr '^' ecpg_expr
5248 { $$ = cat_str(3, $1, make_str("^"), $3); }
5249 | a_expr '|' ecpg_expr
5250 { $$ = cat_str(3, $1, make_str("|"), $3); }
5251 | a_expr '<' ecpg_expr
5252 { $$ = cat_str(3, $1, make_str("<"), $3); }
5253 | a_expr '>' ecpg_expr
5254 { $$ = cat_str(3, $1, make_str(">"), $3); }
5256 { $$ = cat2_str($1, make_str("= NULL")); }
5257 | NULL_P '=' ecpg_expr
5258 { $$ = cat2_str(make_str("= NULL"), $3); }
5259 | a_expr '=' ecpg_expr
5260 { $$ = cat_str(3, $1, make_str("="), $3); }
5261 | a_expr Op ecpg_expr
5262 { $$ = cat_str(3, $1, make_str("="), $3); }
5264 { $$ = cat2_str($1, $2); }
5266 { $$ = cat2_str($1, $2); }
5267 | a_expr AND ecpg_expr
5268 { $$ = cat_str(3, $1, make_str("and"), $3); }
5269 | a_expr OR ecpg_expr
5270 { $$ = cat_str(3, $1, make_str("or"), $3); }
5272 { $$ = cat2_str(make_str("not"), $2); }
5273 | a_expr LIKE ecpg_expr
5274 { $$ = cat_str(3, $1, make_str("like"), $3); }
5275 | a_expr NOT LIKE ecpg_expr
5276 { $$ = cat_str(3, $1, make_str("not like"), $4); }
5278 { $$ = cat2_str($1, make_str("isnull")); }
5280 { $$ = cat2_str($1, make_str("is null")); }
5282 { $$ = cat2_str($1, make_str("notnull")); }
5283 | a_expr IS NOT NULL_P
5284 { $$ = cat2_str($1, make_str("is not null")); }
5286 { $$ = cat2_str($1, make_str("is true")); }
5287 | a_expr IS NOT FALSE_P
5288 { $$ = cat2_str($1, make_str("is not false")); }
5290 { $$ = cat2_str($1, make_str("is false")); }
5291 | a_expr IS NOT TRUE_P
5292 { $$ = cat2_str($1, make_str("is not true")); }
5293 | a_expr BETWEEN b_expr AND b_expr
5295 $$ = cat_str(5, $1, make_str("between"), $3, make_str("and"), $5);
5297 | a_expr NOT BETWEEN b_expr AND b_expr
5299 $$ = cat_str(5, $1, make_str("not between"), $4, make_str("and"), $6);
5301 | a_expr IN '(' in_expr ')'
5303 $$ = cat_str(4, $1, make_str(" in ("), $4, make_str(")"));
5305 | a_expr NOT IN '(' in_expr ')'
5307 $$ = cat_str(4, $1, make_str(" not in ("), $5, make_str(")"));
5309 | a_expr all_Op sub_type '(' SubSelect ')'
5311 $$ = cat_str(4, $1, $2, $3, cat_str(3, make_str("("), $5, make_str(")")));
5320 into_list : coutputvariable | into_list ',' coutputvariable;
5322 ecpgstart: SQL_START { reset_variables();}
5324 c_args: /* empty */ { $$ = EMPTY; }
5325 | c_list { $$ = $1; }
5327 coutputvariable : cvariable indicator {
5328 add_variable(&argsresult, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
5331 cinputvariable : cvariable indicator {
5332 add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
5335 civariableonly : cvariable {
5336 add_variable(&argsinsert, find_variable($1), &no_indicator);
5340 cvariable: CVARIABLE { $$ = $1; }
5342 indicator: /* empty */ { $$ = NULL; }
5343 | cvariable { check_indicator((find_variable($1))->type); $$ = $1; }
5344 | SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; }
5345 | SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
5347 ident: IDENT { $$ = $1; }
5348 | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); };
5354 symbol: IDENT { $$ = $1; }
5356 cpp_line: CPP_LINE { $$ = $1; }
5358 c_stuff: c_anything { $$ = $1; }
5359 | c_stuff c_anything
5361 $$ = cat2_str($1, $2);
5363 | c_stuff '(' c_stuff ')'
5365 $$ = cat_str(4, $1, make_str("("), $3, make_str(")"));
5368 c_list: c_term { $$ = $1; }
5369 | c_list ',' c_term { $$ = cat_str(3, $1, make_str(","), $3); }
5371 c_term: c_stuff { $$ = $1; }
5372 | '{' c_list '}' { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
5374 c_thing: c_anything { $$ = $1; }
5375 | '(' { $$ = make_str("("); }
5376 | ')' { $$ = make_str(")"); }
5377 | ',' { $$ = make_str(","); }
5378 | ';' { $$ = make_str(";"); }
5380 c_anything: IDENT { $$ = $1; }
5381 | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5382 | Iconst { $$ = $1; }
5383 | Fconst { $$ = $1; }
5384 | '*' { $$ = make_str("*"); }
5385 | '+' { $$ = make_str("+"); }
5386 | '-' { $$ = make_str("-"); }
5387 | '/' { $$ = make_str("/"); }
5388 | '%' { $$ = make_str("%"); }
5389 | S_ANYTHING { $$ = make_name(); }
5390 | S_AUTO { $$ = make_str("auto"); }
5391 | S_CONST { $$ = make_str("const"); }
5392 | S_EXTERN { $$ = make_str("extern"); }
5393 | S_REGISTER { $$ = make_str("register"); }
5394 | S_STATIC { $$ = make_str("static"); }
5395 | SQL_BOOL { $$ = make_str("bool"); }
5396 | SQL_ENUM { $$ = make_str("enum"); }
5397 | SQL_INT { $$ = make_str("int"); }
5398 | SQL_LONG { $$ = make_str("long"); }
5399 | SQL_SHORT { $$ = make_str("short"); }
5400 | SQL_SIGNED { $$ = make_str("signed"); }
5401 | SQL_STRUCT { $$ = make_str("struct"); }
5402 | SQL_UNSIGNED { $$ = make_str("unsigned"); }
5403 | CHAR { $$ = make_str("char"); }
5404 | DOUBLE { $$ = make_str("double"); }
5405 | FLOAT { $$ = make_str("float"); }
5406 | UNION { $$ = make_str("union"); }
5407 | VARCHAR { $$ = make_str("varchar"); }
5408 | '[' { $$ = make_str("["); }
5409 | ']' { $$ = make_str("]"); }
5410 /* | '(' { $$ = make_str("("); }
5411 | ')' { $$ = make_str(")"); }*/
5412 | '=' { $$ = make_str("="); }
5420 remove_variables(braces_open--);
5426 void yyerror(char * error)
5428 mmerror(ET_ERROR, error);