1 /* Copyright comment */
6 #include "catalog/catname.h"
7 #include "utils/numeric.h"
12 #include "mb/pg_wchar.h"
15 #define STRUCT_DEPTH 128
18 * Variables containing simple states.
21 static char errortext[128];
22 static int QueryIsRule = 0, ForUpdateNotAllowed = 0;
23 static struct this_type actual_type[STRUCT_DEPTH];
24 static char *actual_storage[STRUCT_DEPTH];
26 /* temporarily store struct members while creating the data structure */
27 struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
29 struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}};
30 struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
32 struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}};
35 * Handle the filename and line numbering.
37 char * input_filename = NULL;
43 fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename);
47 * store the whenever action here
49 static struct when when_error, when_nf, when_warn;
52 print_action(struct when *w)
56 case W_SQLPRINT: fprintf(yyout, "sqlprint();");
58 case W_GOTO: fprintf(yyout, "goto %s;", w->command);
60 case W_DO: fprintf(yyout, "%s;", w->command);
62 case W_STOP: fprintf(yyout, "exit (1);");
64 case W_BREAK: fprintf(yyout, "break;");
66 default: fprintf(yyout, "{/* %d not implemented yet */}", w->code);
72 whenever_action(int mode)
74 if (mode == 1 && when_nf.code != W_NOTHING)
77 fprintf(yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
78 print_action(&when_nf);
80 if (when_warn.code != W_NOTHING)
83 fprintf(yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
84 print_action(&when_warn);
86 if (when_error.code != W_NOTHING)
89 fprintf(yyout, "\nif (sqlca.sqlcode < 0) ");
90 print_action(&when_error);
96 * Handling of variables.
100 * brace level counter
104 static struct variable * allvariables = NULL;
106 static struct variable *
107 new_variable(const char * name, struct ECPGtype * type)
109 struct variable * p = (struct variable*) mm_alloc(sizeof(struct variable));
111 p->name = mm_strdup(name);
113 p->brace_level = braces_open;
115 p->next = allvariables;
121 static struct variable * find_variable(char * name);
123 static struct variable *
124 find_struct_member(char *name, char *str, struct ECPGstruct_member *members)
126 char *next = strchr(++str, '.'), c = '\0';
134 for (; members; members = members->next)
136 if (strcmp(members->name, str) == 0)
141 switch (members->typ->typ)
144 return(new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size)));
146 return(new_variable(name, ECPGmake_struct_type(members->typ->u.members)));
148 return(new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
157 return(find_struct_member(name, next, members->typ->u.element->u.members));
159 else return(find_struct_member(name, next, members->typ->u.members));
167 static struct variable *
168 find_struct(char * name, char *next)
173 /* first get the mother structure entry */
175 p = find_variable(name);
177 /* restore the name, we will need it later on */
182 return find_struct_member(name, next, p->type->u.element->u.members);
184 else return find_struct_member(name, next, p->type->u.members);
187 static struct variable *
188 find_simple(char * name)
192 for (p = allvariables; p; p = p->next)
194 if (strcmp(p->name, name) == 0)
201 /* Note that this function will end the program in case of an unknown */
203 static struct variable *
204 find_variable(char * name)
209 if ((next = strchr(name, '.')) != NULL)
210 p = find_struct(name, next);
211 else if ((next = strstr(name, "->")) != NULL)
212 p = find_struct(name, next);
214 p = find_simple(name);
218 sprintf(errortext, "The variable %s is not declared", name);
226 remove_variables(int brace_level)
228 struct variable * p, *prev;
230 for (p = prev = allvariables; p; p = p ? p->next : NULL)
232 if (p->brace_level >= brace_level)
235 if (p == allvariables)
236 prev = allvariables = p->next;
238 prev->next = p->next;
240 ECPGfree_type(p->type);
252 * Here are the variables that need to be handled on every request.
253 * These are of two kinds: input and output.
254 * I will make two lists for them.
257 struct arguments * argsinsert = NULL;
258 struct arguments * argsresult = NULL;
261 reset_variables(void)
268 /* Add a variable to a request. */
270 add_variable(struct arguments ** list, struct variable * var, struct variable * ind)
272 struct arguments * p = (struct arguments *)mm_alloc(sizeof(struct arguments));
280 /* Dump out a list of all the variable on this list.
281 This is a recursive function that works from the end of the list and
282 deletes the list as we go on.
285 dump_variables(struct arguments * list, int mode)
292 /* The list is build up from the beginning so lets first dump the
296 dump_variables(list->next, mode);
298 /* Then the current element and its indicator */
299 ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
300 (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->name : NULL,
301 (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->type : NULL, NULL, NULL);
303 /* Then release the list element. */
309 check_indicator(struct ECPGtype *var)
311 /* make sure this is a valid indicator variable */
314 struct ECPGstruct_member *p;
319 case ECPGt_unsigned_short:
320 case ECPGt_unsigned_int:
321 case ECPGt_unsigned_long:
325 for (p = var->u.members; p; p = p->next)
326 check_indicator(p->typ);
330 check_indicator(var->u.element);
333 yyerror ("indicator variable must be integer type");
339 make1_str(const char *str)
341 char * res_str = (char *)mm_alloc(strlen(str) + 1);
343 strcpy(res_str, str);
348 make2_str(char *str1, char *str2)
350 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
352 strcpy(res_str, str1);
353 strcat(res_str, str2);
360 cat2_str(char *str1, char *str2)
362 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
364 strcpy(res_str, str1);
365 strcat(res_str, " ");
366 strcat(res_str, str2);
373 make3_str(char *str1, char *str2, char * str3)
375 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 1);
377 strcpy(res_str, str1);
378 strcat(res_str, str2);
379 strcat(res_str, str3);
387 cat3_str(char *str1, char *str2, char * str3)
389 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 3);
391 strcpy(res_str, str1);
392 strcat(res_str, " ");
393 strcat(res_str, str2);
394 strcat(res_str, " ");
395 strcat(res_str, str3);
403 make4_str(char *str1, char *str2, char *str3, char *str4)
405 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 1);
407 strcpy(res_str, str1);
408 strcat(res_str, str2);
409 strcat(res_str, str3);
410 strcat(res_str, str4);
419 cat4_str(char *str1, char *str2, char *str3, char *str4)
421 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 4);
423 strcpy(res_str, str1);
424 strcat(res_str, " ");
425 strcat(res_str, str2);
426 strcat(res_str, " ");
427 strcat(res_str, str3);
428 strcat(res_str, " ");
429 strcat(res_str, str4);
438 make5_str(char *str1, char *str2, char *str3, char *str4, char *str5)
440 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + strlen(str5) + 1);
442 strcpy(res_str, str1);
443 strcat(res_str, str2);
444 strcat(res_str, str3);
445 strcat(res_str, str4);
446 strcat(res_str, str5);
456 cat5_str(char *str1, char *str2, char *str3, char *str4, char *str5)
458 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + strlen(str5) + 5);
460 strcpy(res_str, str1);
461 strcat(res_str, " ");
462 strcat(res_str, str2);
463 strcat(res_str, " ");
464 strcat(res_str, str3);
465 strcat(res_str, " ");
466 strcat(res_str, str4);
467 strcat(res_str, " ");
468 strcat(res_str, str5);
480 char * name = (char *)mm_alloc(yyleng + 1);
482 strncpy(name, yytext, yyleng);
488 output_statement(char * stmt, int mode)
490 int i, j=strlen(stmt);
492 fputs("ECPGdo(__LINE__, \"", yyout);
494 /* do this char by char as we have to filter '\"' */
495 for (i = 0;i < j; i++)
497 fputc(stmt[i], yyout);
498 fputs("\", ", yyout);
500 /* dump variables to C file*/
501 dump_variables(argsinsert, 1);
502 fputs("ECPGt_EOIT, ", yyout);
503 dump_variables(argsresult, 1);
504 fputs("ECPGt_EORT);", yyout);
505 whenever_action(mode);
509 static struct typedefs *
510 get_typedef(char *name)
512 struct typedefs *this;
514 for (this = types; this && strcmp(this->name, name); this = this->next);
517 sprintf(errortext, "invalid datatype '%s'", name);
525 adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dimension, int type_index, bool pointer)
530 yyerror("No multi-dimensional array support");
532 *length = type_index;
535 if (type_dimension >= 0)
537 if (*dimension >= 0 && *length >= 0)
538 yyerror("No multi-dimensional array support");
541 *length = *dimension;
543 *dimension = type_dimension;
549 /* pointer has to get dimension 0 */
552 *length = *dimension;
557 yyerror("No multi-dimensional array support for structures");
561 /* pointer has to get length 0 */
565 /* one index is the string length */
568 *length = *dimension;
574 case ECPGt_unsigned_char:
575 /* pointer has to get length 0 */
579 /* one index is the string length */
582 *length = (*dimension < 0) ? 1 : *dimension;
588 /* a pointer has dimension = 0 */
590 *length = *dimension;
595 yyerror("No multi-dimensional array support for simple data types");
610 struct this_type type;
611 enum ECPGttype type_enum;
614 /* special embedded SQL token */
615 %token SQL_BOOL SQL_BREAK
616 %token SQL_CALL SQL_CONNECT SQL_CONNECTION SQL_CONTINUE
617 %token SQL_DEALLOCATE SQL_DISCONNECT SQL_ENUM
618 %token SQL_FOUND SQL_FREE SQL_GO SQL_GOTO
619 %token SQL_IDENTIFIED SQL_IMMEDIATE SQL_INDICATOR SQL_INT SQL_LONG
620 %token SQL_OPEN SQL_PREPARE SQL_RELEASE SQL_REFERENCE
621 %token SQL_SECTION SQL_SEMI SQL_SHORT SQL_SIGNED SQL_SQLERROR SQL_SQLPRINT
622 %token SQL_SQLWARNING SQL_START SQL_STOP SQL_STRUCT SQL_UNSIGNED
623 %token SQL_VAR SQL_WHENEVER
626 %token S_ANYTHING S_AUTO S_BOOL S_CHAR S_CONST S_DOUBLE S_ENUM S_EXTERN
627 %token S_FLOAT S_INT S
628 %token S_LONG S_REGISTER S_SHORT S_SIGNED S_STATIC S_STRUCT
629 %token S_UNSIGNED S_VARCHAR
631 /* I need this and don't know where it is defined inside the backend */
634 /* Keywords (in SQL92 reserved words) */
635 %token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
636 BEGIN_TRANS, BETWEEN, BOTH, BY,
637 CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
638 COALESCE, COLLATE, COLUMN, COMMIT,
639 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
640 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
641 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
642 ELSE, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
643 FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
644 GRANT, GROUP, HAVING, HOUR_P,
645 IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
646 ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
647 MATCH, MINUTE_P, MONTH_P, NAMES,
648 NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
649 OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
650 PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
651 READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
652 SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
653 TABLE, TEMP, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE,
654 TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
655 UNION, UNIQUE, UPDATE, USER, USING,
656 VALUES, VARCHAR, VARYING, VIEW,
657 WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
659 /* Keywords (in SQL3 reserved words) */
662 /* Keywords (in SQL92 non-reserved words) */
665 /* Keywords for Postgres support (not in SQL92 reserved words)
667 * The CREATEDB and CREATEUSER tokens should go away
668 * when some sort of pg_privileges relation is introduced.
669 * - Todd A. Brandys 1998-01-01?
671 %token ABORT_TRANS, AFTER, AGGREGATE, ANALYZE, BACKWARD, BEFORE, BINARY,
672 CACHE, CLUSTER, COPY, CREATEDB, CREATEUSER, CYCLE,
673 DATABASE, DELIMITERS, DO, EACH, ENCODING, EXPLAIN, EXTEND,
674 FORWARD, FUNCTION, HANDLER,
675 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
676 LANCOMPILER, LIMIT, LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE, MINVALUE, MOVE,
677 NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
678 OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
679 RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
680 SERIAL, SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED,
681 UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
683 /* Special keywords, not in the query language - see the "lex" file */
684 %token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE
685 %token <ival> ICONST PARAM
688 /* these are not real. they are here so that they get generated as #define's*/
700 %nonassoc Op /* multi-character ops and user-defined operators */
706 %left '|' /* this is the relation union op, not logical or */
707 /* Unary Operators */
709 %left ';' /* end of statement or natural log */
714 %left UNION INTERSECT EXCEPT
716 %type <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId
717 %type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt
718 %type <str> OptInherit key_reference key_action
719 %type <str> key_match constraint_expr ColLabel SpecialRuleRelation
720 %type <str> ColId default_expr ColQualifier columnDef ColQualList
721 %type <str> ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
722 %type <str> OptTableElementList OptTableElement TableConstraint
723 %type <str> ConstraintElem key_actions constraint_list ColPrimaryKey
724 %type <str> res_target_list res_target_el res_target_list2
725 %type <str> res_target_el2 opt_id relation_name database_name
726 %type <str> access_method attr_name class index_name name func_name
727 %type <str> file_name recipe_name AexprConst ParamNo TypeId
728 %type <str> in_expr_nodes not_in_expr_nodes a_expr b_expr
729 %type <str> opt_indirection expr_list extract_list extract_arg
730 %type <str> position_list position_expr substr_list substr_from
731 %type <str> trim_list in_expr substr_for not_in_expr attr attrs
732 %type <str> Typename Array Generic Numeric generic opt_float opt_numeric
733 %type <str> opt_decimal Character character opt_varying opt_charset
734 %type <str> opt_collate Datetime datetime opt_timezone opt_interval
735 %type <str> numeric a_expr_or_null row_expr row_descriptor row_list
736 %type <str> SelectStmt SubSelect result OptTemp
737 %type <str> opt_table opt_union opt_unique sort_clause sortby_list
738 %type <str> sortby OptUseOp opt_inh_star relation_name_list name_list
739 %type <str> group_clause having_clause from_clause c_list
740 %type <str> from_list from_val join_expr join_outer join_spec join_list
741 %type <str> join_using where_clause relation_expr row_op sub_type
742 %type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
743 %type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
744 %type <str> NotifyStmt columnElem copy_dirn c_expr UnlistenStmt
745 %type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
746 %type <str> opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name
747 %type <str> ClosePortalStmt DestroyStmt VacuumStmt opt_verbose
748 %type <str> opt_analyze opt_va_list va_list ExplainStmt index_params
749 %type <str> index_list func_index index_elem opt_type opt_class access_method_clause
750 %type <str> index_opt_unique IndexStmt set_opt func_return def_rest
751 %type <str> func_args_list func_args opt_with ProcedureStmt def_arg
752 %type <str> def_elem def_list definition def_name def_type DefineStmt
753 %type <str> opt_instead event event_object RuleActionList,
754 %type <str> RuleActionBlock RuleActionMulti
755 %type <str> RuleStmt opt_column opt_name oper_argtypes
756 %type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
757 %type <str> RemoveAggrStmt remove_type RemoveStmt ExtendStmt RecipeStmt
758 %type <str> RemoveOperStmt RenameStmt all_Op user_valid_clause
759 %type <str> VariableSetStmt var_value zone_value VariableShowStmt
760 %type <str> VariableResetStmt AddAttrStmt alter_clause DropUserStmt
761 %type <str> user_passwd_clause user_createdb_clause opt_trans
762 %type <str> user_createuser_clause user_group_list user_group_clause
763 %type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
764 %type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
765 %type <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
766 %type <str> TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
767 %type <str> CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
768 %type <str> ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
769 %type <str> DestroydbStmt ClusterStmt grantee RevokeStmt encoding
770 %type <str> GrantStmt privileges operation_commalist operation
771 %type <str> cursor_clause opt_cursor opt_readonly opt_of opt_lmode
772 %type <str> case_expr when_clause_list case_default case_arg when_clause
773 %type <str> select_w_o_sort opt_select_limit select_limit_value,
774 %type <str> select_offset_value
776 %type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen opt_using
777 %type <str> indicator ECPGExecute ecpg_expr dotext ECPGPrepare
778 %type <str> storage_clause opt_initializer vartext c_anything blockstart
779 %type <str> blockend variable_list variable var_anything do_anything
780 %type <str> opt_pointer cvariable ECPGDisconnect dis_name
781 %type <str> stmt symbol opt_symbol ECPGRelease execstring server_name
782 %type <str> connection_object opt_server opt_port c_thing opt_reference
783 %type <str> user_name opt_user char_variable ora_user ident
784 %type <str> db_prefix server opt_options opt_connection_name
785 %type <str> ECPGSetConnection c_line cpp_line s_enum ECPGTypedef
786 %type <str> enum_type civariableonly ECPGCursorStmt ECPGDeallocate
787 %type <str> ECPGFree ECPGDeclare ECPGVar sql_variable_declarations
788 %type <str> sql_declaration sql_variable_list sql_variable
789 %type <str> struct_type s_struct declaration variable_declarations
791 %type <type_enum> simple_type varchar_type
793 %type <type> type ctype
795 %type <action> action
797 %type <index> opt_array_bounds nest_array_bounds opt_type_array_bounds
798 %type <index> nest_type_array_bounds
803 statements: /* empty */
804 | statements statement
806 statement: ecpgstart stmt SQL_SEMI
808 | c_thing { fprintf(yyout, "%s", $1); free($1); }
809 | cpp_line { fprintf(yyout, "%s", $1); free($1); }
810 | blockstart { fputs($1, yyout); free($1); }
811 | blockend { fputs($1, yyout); free($1); }
813 stmt: AddAttrStmt { output_statement($1, 0); }
814 | AlterUserStmt { output_statement($1, 0); }
815 | ClosePortalStmt { output_statement($1, 0); }
816 | CopyStmt { output_statement($1, 0); }
817 | CreateStmt { output_statement($1, 0); }
818 | CreateAsStmt { output_statement($1, 0); }
819 | CreateSeqStmt { output_statement($1, 0); }
820 | CreatePLangStmt { output_statement($1, 0); }
821 | CreateTrigStmt { output_statement($1, 0); }
822 | CreateUserStmt { output_statement($1, 0); }
823 | ClusterStmt { output_statement($1, 0); }
824 | DefineStmt { output_statement($1, 0); }
825 | DestroyStmt { output_statement($1, 0); }
826 | DropPLangStmt { output_statement($1, 0); }
827 | DropTrigStmt { output_statement($1, 0); }
828 | DropUserStmt { output_statement($1, 0); }
829 | ExtendStmt { output_statement($1, 0); }
830 | ExplainStmt { output_statement($1, 0); }
831 | FetchStmt { output_statement($1, 1); }
832 | GrantStmt { output_statement($1, 0); }
833 | IndexStmt { output_statement($1, 0); }
834 | ListenStmt { output_statement($1, 0); }
835 | UnlistenStmt { output_statement($1, 0); }
836 | LockStmt { output_statement($1, 0); }
837 | ProcedureStmt { output_statement($1, 0); }
838 | RecipeStmt { output_statement($1, 0); }
839 | RemoveAggrStmt { output_statement($1, 0); }
840 | RemoveOperStmt { output_statement($1, 0); }
841 | RemoveFuncStmt { output_statement($1, 0); }
842 | RemoveStmt { output_statement($1, 0); }
843 | RenameStmt { output_statement($1, 0); }
844 | RevokeStmt { output_statement($1, 0); }
846 if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
852 output_statement($1, 1);
854 | RuleStmt { output_statement($1, 0); }
856 fprintf(yyout, "ECPGtrans(__LINE__, \"%s\");", $1);
860 | ViewStmt { output_statement($1, 0); }
861 | LoadStmt { output_statement($1, 0); }
862 | CreatedbStmt { output_statement($1, 0); }
863 | DestroydbStmt { output_statement($1, 0); }
864 | VacuumStmt { output_statement($1, 0); }
865 | VariableSetStmt { output_statement($1, 0); }
866 | VariableShowStmt { output_statement($1, 0); }
867 | VariableResetStmt { output_statement($1, 0); }
869 fprintf(yyout, "no_auto_trans = %d;\n", no_auto_trans);
870 fprintf(yyout, "ECPGconnect(__LINE__, %s);", $1);
888 fprintf(yyout, "ECPGdisconnect(__LINE__, \"%s\");", $1);
893 output_statement($1, 0);
896 fprintf(yyout, "ECPGdeallocate(__LINE__, \"%s\");", $1);
903 for (ptr = cur; ptr != NULL; ptr=ptr->next)
905 if (strcmp(ptr->name, $1) == 0)
911 sprintf(errortext, "trying to open undeclared cursor %s\n", $1);
915 fprintf(yyout, "ECPGdo(__LINE__, \"%s\",", ptr->command);
916 /* dump variables to C file*/
917 dump_variables(ptr->argsinsert, 0);
918 dump_variables(argsinsert, 0);
919 fputs("ECPGt_EOIT, ", yyout);
920 dump_variables(ptr->argsresult, 0);
921 fputs("ECPGt_EORT);", yyout);
926 fprintf(yyout, "ECPGprepare(__LINE__, %s);", $1);
930 | ECPGRelease { /* output already done */ }
931 | ECPGSetConnection {
932 fprintf(yyout, "ECPGsetconn(__LINE__, %s);", $1);
946 output_line_number();
953 * We start with a lot of stuff that's very similar to the backend's parsing
956 /*****************************************************************************
958 * Create a new Postgres DBMS user
961 *****************************************************************************/
963 CreateUserStmt: CREATE USER UserId user_passwd_clause user_createdb_clause
964 user_createuser_clause user_group_clause user_valid_clause
966 $$ = cat3_str(cat5_str(make1_str("create user"), $3, $4, $5, $6), $7, $8);
970 /*****************************************************************************
972 * Alter a postresql DBMS user
975 *****************************************************************************/
977 AlterUserStmt: ALTER USER UserId user_passwd_clause user_createdb_clause
978 user_createuser_clause user_group_clause user_valid_clause
980 $$ = cat3_str(cat5_str(make1_str("alter user"), $3, $4, $5, $6), $7, $8);
984 /*****************************************************************************
986 * Drop a postresql DBMS user
989 *****************************************************************************/
991 DropUserStmt: DROP USER UserId
993 $$ = cat2_str(make1_str("drop user"), $3);
997 user_passwd_clause: WITH PASSWORD UserId { $$ = cat2_str(make1_str("with password") , $3); }
998 | /*EMPTY*/ { $$ = make1_str(""); }
1001 user_createdb_clause: CREATEDB
1003 $$ = make1_str("createdb");
1007 $$ = make1_str("nocreatedb");
1009 | /*EMPTY*/ { $$ = make1_str(""); }
1012 user_createuser_clause: CREATEUSER
1014 $$ = make1_str("createuser");
1018 $$ = make1_str("nocreateuser");
1020 | /*EMPTY*/ { $$ = NULL; }
1023 user_group_list: user_group_list ',' UserId
1025 $$ = cat3_str($1, make1_str(","), $3);
1033 user_group_clause: IN GROUP user_group_list { $$ = cat2_str(make1_str("in group"), $3); }
1034 | /*EMPTY*/ { $$ = make1_str(""); }
1037 user_valid_clause: VALID UNTIL Sconst { $$ = cat2_str(make1_str("valid until"), $3);; }
1038 | /*EMPTY*/ { $$ = make1_str(""); }
1041 /*****************************************************************************
1043 * Set PG internal variable
1044 * SET name TO 'var_value'
1045 * Include SQL92 syntax (thomas 1997-10-22):
1046 * SET TIME ZONE 'var_value'
1048 *****************************************************************************/
1050 VariableSetStmt: SET ColId TO var_value
1052 $$ = cat4_str(make1_str("set"), $2, make1_str("to"), $4);
1054 | SET ColId '=' var_value
1056 $$ = cat4_str(make1_str("set"), $2, make1_str("="), $4);
1058 | SET TIME ZONE zone_value
1060 $$ = cat2_str(make1_str("set time zone"), $4);
1062 | SET TRANSACTION ISOLATION LEVEL READ ColId
1064 if (strcasecmp($6, "COMMITTED"))
1066 sprintf(errortext, "syntax error at or near \"%s\"", $6);
1070 $$ = cat2_str(make1_str("set transaction isolation level read"), $6);
1072 | SET TRANSACTION ISOLATION LEVEL ColId
1074 if (strcasecmp($5, "SERIALIZABLE"))
1076 sprintf(errortext, "syntax error at or near \"%s\"", $5);
1080 $$ = cat2_str(make1_str("set transaction isolation level read"), $5);
1082 | SET NAMES encoding
1085 $$ = cat2_str(make1_str("set names"), $3);
1087 yyerror("SET NAMES is not supported");
1092 var_value: Sconst { $$ = $1; }
1093 | DEFAULT { $$ = make1_str("default"); }
1096 zone_value: Sconst { $$ = $1; }
1097 | DEFAULT { $$ = make1_str("default"); }
1098 | LOCAL { $$ = make1_str("local"); }
1101 VariableShowStmt: SHOW ColId
1103 $$ = cat2_str(make1_str("show"), $2);
1107 $$ = make1_str("show time zone");
1109 | SHOW TRANSACTION ISOLATION LEVEL
1111 $$ = make1_str("show transaction isolation level");
1115 VariableResetStmt: RESET ColId
1117 $$ = cat2_str(make1_str("reset"), $2);
1121 $$ = make1_str("reset time zone");
1123 | RESET TRANSACTION ISOLATION LEVEL
1125 $$ = make1_str("reset transaction isolation level");
1130 /*****************************************************************************
1133 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
1135 *****************************************************************************/
1137 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
1139 $$ = cat4_str(make1_str("alter table"), $3, $4, $5);
1143 alter_clause: ADD opt_column columnDef
1145 $$ = cat3_str(make1_str("add"), $2, $3);
1147 | ADD '(' OptTableElementList ')'
1149 $$ = make3_str(make1_str("add("), $3, make1_str(")"));
1151 | DROP opt_column ColId
1152 { yyerror("ALTER TABLE/DROP COLUMN not yet implemented"); }
1153 | ALTER opt_column ColId SET DEFAULT default_expr
1154 { yyerror("ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
1155 | ALTER opt_column ColId DROP DEFAULT
1156 { yyerror("ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
1157 | ADD ConstraintElem
1158 { yyerror("ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
1161 /*****************************************************************************
1166 *****************************************************************************/
1168 ClosePortalStmt: CLOSE opt_id
1170 $$ = cat2_str(make1_str("close"), $2);
1175 /*****************************************************************************
1178 * COPY [BINARY] <relname> FROM/TO
1179 * [USING DELIMITERS <delimiter>]
1181 *****************************************************************************/
1183 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
1185 $$ = cat3_str(cat5_str(make1_str("copy"), $2, $3, $4, $5), $6, $7);
1190 { $$ = make1_str("to"); }
1192 { $$ = make1_str("from"); }
1196 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
1197 * used depends on the direction. (It really doesn't make sense to copy from
1198 * stdout. We silently correct the "typo". - AY 9/94
1200 copy_file_name: Sconst { $$ = $1; }
1201 | STDIN { $$ = make1_str("stdin"); }
1202 | STDOUT { $$ = make1_str("stdout"); }
1205 opt_binary: BINARY { $$ = make1_str("binary"); }
1206 | /*EMPTY*/ { $$ = make1_str(""); }
1209 opt_with_copy: WITH OIDS { $$ = make1_str("with oids"); }
1210 | /*EMPTY*/ { $$ = make1_str(""); }
1214 * the default copy delimiter is tab but the user can configure it
1216 copy_delimiter: USING DELIMITERS Sconst { $$ = cat2_str(make1_str("using delimiters"), $3); }
1217 | /*EMPTY*/ { $$ = make1_str(""); }
1222 /*****************************************************************************
1227 *****************************************************************************/
1229 CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
1232 $$ = cat3_str(cat4_str(make1_str("create"), $2, make1_str("table"), $4), make3_str(make1_str("("), $6, make1_str(")")), $8);
1236 OptTemp: TEMP { $$ = make1_str("temp"); }
1237 | /* EMPTY */ { $$ = make1_str(""); }
1240 OptTableElementList: OptTableElementList ',' OptTableElement
1242 $$ = cat3_str($1, make1_str(","), $3);
1248 | /*EMPTY*/ { $$ = make1_str(""); }
1251 OptTableElement: columnDef { $$ = $1; }
1252 | TableConstraint { $$ = $1; }
1255 columnDef: ColId Typename ColQualifier
1257 $$ = cat3_str($1, $2, $3);
1259 | ColId SERIAL ColPrimaryKey
1261 $$ = make3_str($1, make1_str(" serial "), $3);
1265 ColQualifier: ColQualList { $$ = $1; }
1266 | /*EMPTY*/ { $$ = make1_str(""); }
1269 ColQualList: ColQualList ColConstraint { $$ = cat2_str($1,$2); }
1270 | ColConstraint { $$ = $1; }
1273 ColPrimaryKey: PRIMARY KEY
1275 $$ = make1_str("primary key");
1284 CONSTRAINT name ColConstraintElem
1286 $$ = cat3_str(make1_str("constraint"), $2, $3);
1292 /* The column constraint WITH NULL gives a shift/reduce error
1293 * because it requires yacc to look more than one token ahead to
1294 * resolve WITH TIME ZONE and WITH NULL.
1295 * So, leave it out of the syntax for now.
1300 * - thomas 1998-09-12
1302 * DEFAULT NULL is already the default for Postgres.
1303 * Bue define it here and carry it forward into the system
1304 * to make it explicit.
1305 * - thomas 1998-09-13
1307 ColConstraintElem: CHECK '(' constraint_expr ')'
1309 $$ = make3_str(make1_str("check("), $3, make1_str(")"));
1313 $$ = make1_str("default null");
1315 | DEFAULT default_expr
1317 $$ = cat2_str(make1_str("default"), $2);
1321 $$ = make1_str("not null");
1325 $$ = make1_str("unique");
1329 $$ = make1_str("primary key");
1331 | REFERENCES ColId opt_column_list key_match key_actions
1333 fprintf(stderr, "CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
1338 default_list: default_list ',' default_expr
1340 $$ = cat3_str($1, make1_str(","), $3);
1348 /* The Postgres default column value is NULL.
1349 * Rather than carrying DEFAULT NULL forward as a clause,
1350 * let's just have it be a no-op.
1352 { $$ = make1_str("null"); }
1353 * - thomas 1998-09-13
1356 default_expr: AexprConst
1358 | '-' default_expr %prec UMINUS
1359 { $$ = cat2_str(make1_str("-"), $2); }
1360 | default_expr '+' default_expr
1361 { $$ = cat3_str($1, make1_str("+"), $3); }
1362 | default_expr '-' default_expr
1363 { $$ = cat3_str($1, make1_str("-"), $3); }
1364 | default_expr '/' default_expr
1365 { $$ = cat3_str($1, make1_str("/"), $3); }
1366 | default_expr '*' default_expr
1367 { $$ = cat3_str($1, make1_str("*"), $3); }
1368 | default_expr '=' default_expr
1369 { yyerror("boolean expressions not supported in DEFAULT"); }
1370 | default_expr '<' default_expr
1371 { yyerror("boolean expressions not supported in DEFAULT"); }
1372 | default_expr '>' default_expr
1373 { yyerror("boolean expressions not supported in DEFAULT"); }
1374 /* not possible in embedded sql
1376 { $$ = cat2_str(make1_str(":"), $2); }
1379 { $$ = cat2_str(make1_str(";"), $2); }
1381 { $$ = cat2_str(make1_str("|"), $2); }
1382 | default_expr TYPECAST Typename
1383 { $$ = cat3_str($1, make1_str("::"), $3); }
1384 | CAST '(' default_expr AS Typename ')'
1386 $$ = cat3_str(make2_str(make1_str("cast("), $3) , make1_str("as"), make2_str($5, make1_str(")")));
1388 | '(' default_expr ')'
1389 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
1391 { $$ = cat2_str($1, make1_str("()")); }
1392 | func_name '(' default_list ')'
1393 { $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")"))); }
1394 | default_expr Op default_expr
1396 if (!strcmp("<=", $2) || !strcmp(">=", $2))
1397 yyerror("boolean expressions not supported in DEFAULT");
1398 $$ = cat3_str($1, $2, $3);
1401 { $$ = cat2_str($1, $2); }
1403 { $$ = cat2_str($1, $2); }
1404 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
1406 { $$ = make1_str("current_date"); }
1408 { $$ = make1_str("current_time"); }
1409 | CURRENT_TIME '(' Iconst ')'
1412 fprintf(stderr, "CURRENT_TIME(%s) precision not implemented; zero used instead",$3);
1413 $$ = "current_time";
1416 { $$ = make1_str("current_timestamp"); }
1417 | CURRENT_TIMESTAMP '(' Iconst ')'
1420 fprintf(stderr, "CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
1421 $$ = "current_timestamp";
1424 { $$ = make1_str("current_user"); }
1426 { $$ = make1_str("user"); }
1429 /* ConstraintElem specifies constraint syntax which is not embedded into
1430 * a column definition. ColConstraintElem specifies the embedded form.
1431 * - thomas 1997-12-03
1433 TableConstraint: CONSTRAINT name ConstraintElem
1435 $$ = cat3_str(make1_str("constraint"), $2, $3);
1441 ConstraintElem: CHECK '(' constraint_expr ')'
1443 $$ = make3_str(make1_str("check("), $3, make1_str(")"));
1445 | UNIQUE '(' columnList ')'
1447 $$ = make3_str(make1_str("unique("), $3, make1_str(")"));
1449 | PRIMARY KEY '(' columnList ')'
1451 $$ = make3_str(make1_str("primary key("), $4, make1_str(")"));
1453 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
1455 fprintf(stderr, "CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
1460 constraint_list: constraint_list ',' constraint_expr
1462 $$ = cat3_str($1, make1_str(","), $3);
1470 constraint_expr: AexprConst
1473 { $$ = make1_str("null"); }
1478 | '-' constraint_expr %prec UMINUS
1479 { $$ = cat2_str(make1_str("-"), $2); }
1480 | constraint_expr '+' constraint_expr
1481 { $$ = cat3_str($1, make1_str("+"), $3); }
1482 | constraint_expr '-' constraint_expr
1483 { $$ = cat3_str($1, make1_str("-"), $3); }
1484 | constraint_expr '/' constraint_expr
1485 { $$ = cat3_str($1, make1_str("/"), $3); }
1486 | constraint_expr '*' constraint_expr
1487 { $$ = cat3_str($1, make1_str("*"), $3); }
1488 | constraint_expr '=' constraint_expr
1489 { $$ = cat3_str($1, make1_str("="), $3); }
1490 | constraint_expr '<' constraint_expr
1491 { $$ = cat3_str($1, make1_str("<"), $3); }
1492 | constraint_expr '>' constraint_expr
1493 { $$ = cat3_str($1, make1_str(">"), $3); }
1494 /* this one doesn't work with embedded sql anyway
1495 | ':' constraint_expr
1496 { $$ = cat2_str(make1_str(":"), $2); }
1498 | ';' constraint_expr
1499 { $$ = cat2_str(make1_str(";"), $2); }
1500 | '|' constraint_expr
1501 { $$ = cat2_str(make1_str("|"), $2); }
1502 | constraint_expr TYPECAST Typename
1504 $$ = cat3_str($1, make1_str("::"), $3);
1506 | CAST '(' constraint_expr AS Typename ')'
1508 $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
1510 | '(' constraint_expr ')'
1511 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
1514 { $$ = cat2_str($1, make1_str("()")); }
1516 | func_name '(' constraint_list ')'
1518 $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")")));
1520 | constraint_expr Op constraint_expr
1521 { $$ = cat3_str($1, $2, $3); }
1522 | constraint_expr LIKE constraint_expr
1523 { $$ = cat3_str($1, make1_str("like"), $3); }
1524 | constraint_expr NOT LIKE constraint_expr
1525 { $$ = cat3_str($1, make1_str("not like"), $4); }
1526 | constraint_expr AND constraint_expr
1527 { $$ = cat3_str($1, make1_str("and"), $3); }
1528 | constraint_expr OR constraint_expr
1529 { $$ = cat3_str($1, make1_str("or"), $3); }
1530 | NOT constraint_expr
1531 { $$ = cat2_str(make1_str("not"), $2); }
1532 | Op constraint_expr
1533 { $$ = cat2_str($1, $2); }
1534 | constraint_expr Op
1535 { $$ = cat2_str($1, $2); }
1536 | constraint_expr ISNULL
1537 { $$ = cat2_str($1, make1_str("isnull")); }
1538 | constraint_expr IS NULL_P
1539 { $$ = cat2_str($1, make1_str("is null")); }
1540 | constraint_expr NOTNULL
1541 { $$ = cat2_str($1, make1_str("notnull")); }
1542 | constraint_expr IS NOT NULL_P
1543 { $$ = cat2_str($1, make1_str("is not null")); }
1544 | constraint_expr IS TRUE_P
1545 { $$ = cat2_str($1, make1_str("is true")); }
1546 | constraint_expr IS FALSE_P
1547 { $$ = cat2_str($1, make1_str("is false")); }
1548 | constraint_expr IS NOT TRUE_P
1549 { $$ = cat2_str($1, make1_str("is not true")); }
1550 | constraint_expr IS NOT FALSE_P
1551 { $$ = cat2_str($1, make1_str("is not false")); }
1552 | constraint_expr IN '(' c_list ')'
1553 { $$ = cat4_str($1, make1_str("in ("), $4, make1_str(")")); }
1554 | constraint_expr NOT IN '(' c_list ')'
1555 { $$ = cat4_str($1, make1_str("not in ("), $5, make1_str(")")); }
1556 | constraint_expr BETWEEN c_expr AND c_expr
1557 { $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5); }
1558 | constraint_expr NOT BETWEEN c_expr AND c_expr
1559 { $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6); }
1561 c_list: c_list ',' c_expr
1563 $$ = make3_str($1, make1_str(", "), $3);
1575 key_match: MATCH FULL { $$ = make1_str("match full"); }
1576 | MATCH PARTIAL { $$ = make1_str("match partial"); }
1577 | /*EMPTY*/ { $$ = make1_str(""); }
1580 key_actions: key_action key_action { $$ = cat2_str($1, $2); }
1581 | key_action { $$ = $1; }
1582 | /*EMPTY*/ { $$ = make1_str(""); }
1585 key_action: ON DELETE key_reference { $$ = cat2_str(make1_str("on delete"), $3); }
1586 | ON UPDATE key_reference { $$ = cat2_str(make1_str("on update"), $3); }
1589 key_reference: NO ACTION { $$ = make1_str("no action"); }
1590 | CASCADE { $$ = make1_str("cascade"); }
1591 | SET DEFAULT { $$ = make1_str("set default"); }
1592 | SET NULL_P { $$ = make1_str("set null"); }
1595 OptInherit: INHERITS '(' relation_name_list ')' { $$ = make3_str(make1_str("inherits ("), $3, make1_str(")")); }
1596 | /*EMPTY*/ { $$ = make1_str(""); }
1599 CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS SubSelect
1601 $$ = cat5_str(cat3_str(make1_str("create"), $2, make1_str("table")), $4, $5, make1_str("as"), $7);
1605 OptCreateAs: '(' CreateAsList ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
1606 | /*EMPTY*/ { $$ = make1_str(""); }
1609 CreateAsList: CreateAsList ',' CreateAsElement { $$ = cat3_str($1, make1_str(","), $3); }
1610 | CreateAsElement { $$ = $1; }
1613 CreateAsElement: ColId { $$ = $1; }
1616 /*****************************************************************************
1619 * CREATE SEQUENCE seqname
1621 *****************************************************************************/
1623 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1625 $$ = cat3_str(make1_str("create sequence"), $3, $4);
1629 OptSeqList: OptSeqList OptSeqElem
1630 { $$ = cat2_str($1, $2); }
1631 | { $$ = make1_str(""); }
1634 OptSeqElem: CACHE IntegerOnly
1636 $$ = cat2_str(make1_str("cache"), $2);
1640 $$ = make1_str("cycle");
1642 | INCREMENT IntegerOnly
1644 $$ = cat2_str(make1_str("increment"), $2);
1646 | MAXVALUE IntegerOnly
1648 $$ = cat2_str(make1_str("maxvalue"), $2);
1650 | MINVALUE IntegerOnly
1652 $$ = cat2_str(make1_str("minvalue"), $2);
1656 $$ = cat2_str(make1_str("start"), $2);
1660 NumericOnly: FloatOnly { $$ = $1; }
1661 | IntegerOnly { $$ = $1; }
1669 $$ = cat2_str(make1_str("-"), $2);
1680 $$ = cat2_str(make1_str("-"), $2);
1684 /*****************************************************************************
1687 * CREATE PROCEDURAL LANGUAGE ...
1688 * DROP PROCEDURAL LANGUAGE ...
1690 *****************************************************************************/
1692 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1693 HANDLER def_name LANCOMPILER Sconst
1695 $$ = cat4_str(cat5_str(make1_str("create"), $2, make1_str("precedural language"), $5, make1_str("handler")), $7, make1_str("langcompiler"), $9);
1699 PLangTrusted: TRUSTED { $$ = make1_str("trusted"); }
1700 | { $$ = make1_str(""); }
1702 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1704 $$ = cat2_str(make1_str("drop procedural language"), $4);
1708 /*****************************************************************************
1711 * CREATE TRIGGER ...
1714 *****************************************************************************/
1716 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1717 relation_name TriggerForSpec EXECUTE PROCEDURE
1718 name '(' TriggerFuncArgs ')'
1720 $$ = cat2_str(cat5_str(cat5_str(make1_str("create trigger"), $3, $4, $5, make1_str("on")), $7, $8, make1_str("execute procedure"), $11), make3_str(make1_str("("), $13, make1_str(")")));
1724 TriggerActionTime: BEFORE { $$ = make1_str("before"); }
1725 | AFTER { $$ = make1_str("after"); }
1728 TriggerEvents: TriggerOneEvent
1732 | TriggerOneEvent OR TriggerOneEvent
1734 $$ = cat3_str($1, make1_str("or"), $3);
1736 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1738 $$ = cat5_str($1, make1_str("or"), $3, make1_str("or"), $5);
1742 TriggerOneEvent: INSERT { $$ = make1_str("insert"); }
1743 | DELETE { $$ = make1_str("delete"); }
1744 | UPDATE { $$ = make1_str("update"); }
1747 TriggerForSpec: FOR TriggerForOpt TriggerForType
1749 $$ = cat3_str(make1_str("for"), $2, $3);
1753 TriggerForOpt: EACH { $$ = make1_str("each"); }
1754 | /*EMPTY*/ { $$ = make1_str(""); }
1757 TriggerForType: ROW { $$ = make1_str("row"); }
1758 | STATEMENT { $$ = make1_str("statement"); }
1761 TriggerFuncArgs: TriggerFuncArg
1763 | TriggerFuncArgs ',' TriggerFuncArg
1764 { $$ = cat3_str($1, make1_str(","), $3); }
1766 { $$ = make1_str(""); }
1769 TriggerFuncArg: Iconst
1777 | Sconst { $$ = $1; }
1778 | ident { $$ = $1; }
1781 DropTrigStmt: DROP TRIGGER name ON relation_name
1783 $$ = cat4_str(make1_str("drop trigger"), $3, make1_str("on"), $5);
1787 /*****************************************************************************
1790 * define (type,operator,aggregate)
1792 *****************************************************************************/
1794 DefineStmt: CREATE def_type def_rest
1796 $$ = cat3_str(make1_str("create"), $2, $3);
1800 def_rest: def_name definition
1802 $$ = cat2_str($1, $2);
1806 def_type: OPERATOR { $$ = make1_str("operator"); }
1807 | TYPE_P { $$ = make1_str("type"); }
1808 | AGGREGATE { $$ = make1_str("aggregate"); }
1811 def_name: PROCEDURE { $$ = make1_str("procedure"); }
1812 | JOIN { $$ = make1_str("join"); }
1813 | ColId { $$ = $1; }
1814 | MathOp { $$ = $1; }
1818 definition: '(' def_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
1821 def_list: def_elem { $$ = $1; }
1822 | def_list ',' def_elem { $$ = cat3_str($1, make1_str(","), $3); }
1825 def_elem: def_name '=' def_arg {
1826 $$ = cat3_str($1, make1_str("="), $3);
1832 | DEFAULT '=' def_arg
1834 $$ = cat2_str(make1_str("default ="), $3);
1838 def_arg: ColId { $$ = $1; }
1839 | all_Op { $$ = $1; }
1840 | NumericOnly { $$ = $1; }
1841 | Sconst { $$ = $1; }
1844 $$ = cat2_str(make1_str("setof"), $2);
1848 /*****************************************************************************
1851 * destroy <relname1> [, <relname2> .. <relnameN> ]
1853 *****************************************************************************/
1855 DestroyStmt: DROP TABLE relation_name_list
1857 $$ = cat2_str(make1_str("drop table"), $3);
1859 | DROP SEQUENCE relation_name_list
1861 $$ = cat2_str(make1_str("drop sequence"), $3);
1867 /*****************************************************************************
1870 * fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
1871 * fetch [ forward | backward | absolute | relative ]
1872 * [ # | all | next | prior ] [ [ in | from ] <portalname> ]
1874 *****************************************************************************/
1876 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name INTO into_list
1878 if (strncmp($2, "relative", strlen("relative")) == 0 && atol($3) == 0L)
1879 yyerror("FETCH/RELATIVE at current position is not supported");
1881 $$ = cat4_str(make1_str("fetch"), $2, $3, $4);
1883 | MOVE opt_direction fetch_how_many opt_portal_name
1885 $$ = cat4_str(make1_str("fetch"), $2, $3, $4);
1889 opt_direction: FORWARD { $$ = make1_str("forward"); }
1890 | BACKWARD { $$ = make1_str("backward"); }
1891 | RELATIVE { $$ = make1_str("relative"); }
1894 fprintf(stderr, "FETCH/ABSOLUTE not supported, using RELATIVE");
1895 $$ = make1_str("absolute");
1897 | /*EMPTY*/ { $$ = make1_str(""); /* default */ }
1900 fetch_how_many: Iconst { $$ = $1; }
1901 | '-' Iconst { $$ = make2_str(make1_str("-"), $2); }
1902 | ALL { $$ = make1_str("all"); }
1903 | NEXT { $$ = make1_str("next"); }
1904 | PRIOR { $$ = make1_str("prior"); }
1905 | /*EMPTY*/ { $$ = make1_str(""); /*default*/ }
1908 opt_portal_name: IN name { $$ = cat2_str(make1_str("in"), $2); }
1909 | FROM name { $$ = cat2_str(make1_str("from"), $2); }
1910 /* | name { $$ = cat2_str(make1_str("in"), $1); */
1911 | /*EMPTY*/ { $$ = make1_str(""); }
1915 /*****************************************************************************
1918 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1920 *****************************************************************************/
1922 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1924 $$ = cat2_str(cat5_str(make1_str("grant"), $2, make1_str("on"), $4, make1_str("to")), $6);
1928 privileges: ALL PRIVILEGES
1930 $$ = make1_str("all privileges");
1934 $$ = make1_str("all");
1936 | operation_commalist
1942 operation_commalist: operation
1946 | operation_commalist ',' operation
1948 $$ = cat3_str($1, make1_str(","), $3);
1954 $$ = make1_str("select");
1958 $$ = make1_str("insert");
1962 $$ = make1_str("update");
1966 $$ = make1_str("delete");
1970 $$ = make1_str("rule");
1976 $$ = make1_str("public");
1980 $$ = cat2_str(make1_str("group"), $2);
1988 opt_with_grant: WITH GRANT OPTION
1990 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1996 /*****************************************************************************
1999 * REVOKE [privileges] ON [relation_name] FROM [user]
2001 *****************************************************************************/
2003 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
2005 $$ = cat2_str(cat5_str(make1_str("revoke"), $2, make1_str("on"), $4, make1_str("from")), $6);
2011 /*****************************************************************************
2014 * create index <indexname> on <relname>
2015 * using <access> "(" (<col> with <op>)+ ")" [with
2018 * [where <qual>] is not supported anymore
2019 *****************************************************************************/
2021 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
2022 access_method_clause '(' index_params ')' opt_with
2024 /* should check that access_method is valid,
2025 etc ... but doesn't */
2026 $$ = cat5_str(cat5_str(make1_str("create"), $2, make1_str("index"), $4, make1_str("on")), $6, $7, make3_str(make1_str("("), $9, make1_str(")")), $11);
2030 index_opt_unique: UNIQUE { $$ = make1_str("unique"); }
2031 | /*EMPTY*/ { $$ = make1_str(""); }
2034 access_method_clause: USING access_method { $$ = cat2_str(make1_str("using"), $2); }
2035 | /*EMPTY*/ { $$ = make1_str(""); }
2038 index_params: index_list { $$ = $1; }
2039 | func_index { $$ = $1; }
2042 index_list: index_list ',' index_elem { $$ = cat3_str($1, make1_str(","), $3); }
2043 | index_elem { $$ = $1; }
2046 func_index: func_name '(' name_list ')' opt_type opt_class
2048 $$ = cat4_str($1, make3_str(make1_str("("), $3, ")"), $5, $6);
2052 index_elem: attr_name opt_type opt_class
2054 $$ = cat3_str($1, $2, $3);
2058 opt_type: ':' Typename { $$ = cat2_str(make1_str(":"), $2); }
2059 | FOR Typename { $$ = cat2_str(make1_str("for"), $2); }
2060 | /*EMPTY*/ { $$ = make1_str(""); }
2063 /* opt_class "WITH class" conflicts with preceeding opt_type
2064 * for Typename of "TIMESTAMP WITH TIME ZONE"
2065 * So, remove "WITH class" from the syntax. OK??
2066 * - thomas 1997-10-12
2067 * | WITH class { $$ = $2; }
2069 opt_class: class { $$ = $1; }
2070 | USING class { $$ = cat2_str(make1_str("using"), $2); }
2071 | /*EMPTY*/ { $$ = make1_str(""); }
2074 /*****************************************************************************
2077 * extend index <indexname> [where <qual>]
2079 *****************************************************************************/
2081 ExtendStmt: EXTEND INDEX index_name where_clause
2083 $$ = cat3_str(make1_str("extend index"), $3, $4);
2088 /*****************************************************************************
2091 * execute recipe <recipeName>
2093 *****************************************************************************/
2095 RecipeStmt: EXECUTE RECIPE recipe_name
2097 $$ = cat2_str(make1_str("execute recipe"), $3);
2101 /*****************************************************************************
2104 * define function <fname>
2105 * (language = <lang>, returntype = <typename>
2106 * [, arch_pct = <percentage | pre-defined>]
2107 * [, disk_pct = <percentage | pre-defined>]
2108 * [, byte_pct = <percentage | pre-defined>]
2109 * [, perbyte_cpu = <int | pre-defined>]
2110 * [, percall_cpu = <int | pre-defined>]
2112 * [arg is (<type-1> { , <type-n>})]
2113 * as <filename or code in language as appropriate>
2115 *****************************************************************************/
2117 ProcedureStmt: CREATE FUNCTION func_name func_args
2118 RETURNS func_return opt_with AS Sconst LANGUAGE Sconst
2120 $$ = cat2_str(cat5_str(cat5_str(make1_str("create function"), $3, $4, make1_str("returns"), $6), $7, make1_str("as"), $9, make1_str("language")), $11);
2123 opt_with: WITH definition { $$ = cat2_str(make1_str("with"), $2); }
2124 | /*EMPTY*/ { $$ = make1_str(""); }
2127 func_args: '(' func_args_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
2128 | '(' ')' { $$ = make1_str("()"); }
2131 func_args_list: TypeId { $$ = $1; }
2132 | func_args_list ',' TypeId
2133 { $$ = cat3_str($1, make1_str(","), $3); }
2136 func_return: set_opt TypeId
2138 $$ = cat2_str($1, $2);
2142 set_opt: SETOF { $$ = make1_str("setof"); }
2143 | /*EMPTY*/ { $$ = make1_str(""); }
2147 /*****************************************************************************
2151 * remove function <funcname>
2152 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
2153 * remove aggregate <aggname>
2154 * (REMOVE AGGREGATE "aggname" "aggtype")
2155 * remove operator <opname>
2156 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
2157 * remove type <typename>
2158 * (REMOVE TYPE "typename")
2159 * remove rule <rulename>
2160 * (REMOVE RULE "rulename")
2162 *****************************************************************************/
2164 RemoveStmt: DROP remove_type name
2166 $$ = cat3_str(make1_str("drop"), $2, $3);;
2170 remove_type: TYPE_P { $$ = make1_str("type"); }
2171 | INDEX { $$ = make1_str("index"); }
2172 | RULE { $$ = make1_str("rule"); }
2173 | VIEW { $$ = make1_str("view"); }
2177 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
2179 $$ = cat3_str(make1_str("drop aggregate"), $3, $4);
2183 aggr_argtype: name { $$ = $1; }
2184 | '*' { $$ = make1_str("*"); }
2188 RemoveFuncStmt: DROP FUNCTION func_name func_args
2190 $$ = cat3_str(make1_str("drop function"), $3, $4);
2195 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
2197 $$ = cat3_str(make1_str("drop operator"), $3, make3_str(make1_str("("), $5, make1_str(")")));
2201 all_Op: Op | MathOp;
2203 MathOp: '+' { $$ = make1_str("+"); }
2204 | '-' { $$ = make1_str("-"); }
2205 | '*' { $$ = make1_str("*"); }
2206 | '/' { $$ = make1_str("/"); }
2207 | '<' { $$ = make1_str("<"); }
2208 | '>' { $$ = make1_str(">"); }
2209 | '=' { $$ = make1_str("="); }
2214 yyerror("parser: argument type missing (use NONE for unary operators)");
2217 { $$ = cat3_str($1, make1_str(","), $3); }
2218 | NONE ',' name /* left unary */
2219 { $$ = cat2_str(make1_str("none,"), $3); }
2220 | name ',' NONE /* right unary */
2221 { $$ = cat2_str($1, make1_str(", none")); }
2225 /*****************************************************************************
2228 * rename <attrname1> in <relname> [*] to <attrname2>
2229 * rename <relname1> to <relname2>
2231 *****************************************************************************/
2233 RenameStmt: ALTER TABLE relation_name opt_inh_star
2234 RENAME opt_column opt_name TO name
2236 $$ = cat4_str(cat5_str(make1_str("alter table"), $3, $4, make1_str("rename"), $6), $7, make1_str("to"), $9);
2240 opt_name: name { $$ = $1; }
2241 | /*EMPTY*/ { $$ = make1_str(""); }
2244 opt_column: COLUMN { $$ = make1_str("colmunn"); }
2245 | /*EMPTY*/ { $$ = make1_str(""); }
2249 /*****************************************************************************
2251 * QUERY: Define Rewrite Rule , Define Tuple Rule
2252 * Define Rule <old rules >
2254 * only rewrite rule is supported -- ay 9/94
2256 *****************************************************************************/
2258 RuleStmt: CREATE RULE name AS
2260 ON event TO event_object where_clause
2261 DO opt_instead RuleActionList
2263 $$ = cat2_str(cat5_str(cat5_str(make1_str("create rule"), $3, make1_str("as on"), $7, make1_str("to")), $9, $10, make1_str("do"), $12), $13);
2267 RuleActionList: NOTHING { $$ = make1_str("nothing"); }
2268 | SelectStmt { $$ = $1; }
2269 | RuleActionStmt { $$ = $1; }
2270 | '[' RuleActionBlock ']' { $$ = cat3_str(make1_str("["), $2, make1_str("]")); }
2271 | '(' RuleActionBlock ')' { $$ = cat3_str(make1_str("("), $2, make1_str(")")); }
2274 RuleActionBlock: RuleActionMulti { $$ = $1; }
2275 | RuleActionStmt { $$ = $1; }
2278 RuleActionMulti: RuleActionMulti RuleActionStmt
2279 { $$ = cat2_str($1, $2); }
2280 | RuleActionMulti RuleActionStmt ';'
2281 { $$ = cat3_str($1, $2, make1_str(";")); }
2282 | RuleActionStmt ';'
2283 { $$ = cat2_str($1, make1_str(";")); }
2286 RuleActionStmt: InsertStmt
2292 event_object: relation_name '.' attr_name
2294 $$ = make3_str($1, make1_str("."), $3);
2302 /* change me to select, update, etc. some day */
2303 event: SELECT { $$ = make1_str("select"); }
2304 | UPDATE { $$ = make1_str("update"); }
2305 | DELETE { $$ = make1_str("delete"); }
2306 | INSERT { $$ = make1_str("insert"); }
2309 opt_instead: INSTEAD { $$ = make1_str("instead"); }
2310 | /*EMPTY*/ { $$ = make1_str(""); }
2314 /*****************************************************************************
2317 * NOTIFY <relation_name> can appear both in rule bodies and
2318 * as a query-level command
2320 *****************************************************************************/
2322 NotifyStmt: NOTIFY relation_name
2324 $$ = cat2_str(make1_str("notify"), $2);
2328 ListenStmt: LISTEN relation_name
2330 $$ = cat2_str(make1_str("listen"), $2);
2334 UnlistenStmt: UNLISTEN relation_name
2336 $$ = cat2_str(make1_str("unlisten"), $2);
2340 $$ = make1_str("unlisten *");
2344 /*****************************************************************************
2355 *****************************************************************************/
2356 TransactionStmt: ABORT_TRANS opt_trans { $$ = make1_str("rollback"); }
2357 | BEGIN_TRANS opt_trans { $$ = make1_str("begin transaction"); }
2358 | COMMIT opt_trans { $$ = make1_str("commit"); }
2359 | END_TRANS opt_trans { $$ = make1_str("commit"); }
2360 | ROLLBACK opt_trans { $$ = make1_str("rollback"); }
2362 opt_trans: WORK { $$ = ""; }
2363 | TRANSACTION { $$ = ""; }
2364 | /*EMPTY*/ { $$ = ""; }
2367 /*****************************************************************************
2370 * define view <viewname> '('target-list ')' [where <quals> ]
2372 *****************************************************************************/
2374 ViewStmt: CREATE VIEW name AS SelectStmt
2376 $$ = cat4_str(make1_str("create view"), $3, make1_str("as"), $5);
2381 /*****************************************************************************
2384 * load make1_str("filename")
2386 *****************************************************************************/
2388 LoadStmt: LOAD file_name
2390 $$ = cat2_str(make1_str("load"), $2);
2395 /*****************************************************************************
2400 *****************************************************************************/
2402 CreatedbStmt: CREATE DATABASE database_name WITH opt_database1 opt_database2
2404 if (strlen($5) == 0 || strlen($6) == 0)
2405 yyerror("CREATE DATABASE WITH requires at least an option");
2407 if (strlen($6) != 0)
2408 yyerror("WITH ENCODING is not supported");
2410 $$ = cat5_str(make1_str("create database"), $3, make1_str("with"), $5, $6);
2412 | CREATE DATABASE database_name
2414 $$ = cat2_str(make1_str("create database"), $3);
2418 opt_database1: LOCATION '=' location { $$ = cat2_str(make1_str("location ="), $3); }
2419 | /*EMPTY*/ { $$ = make1_str(""); }
2422 opt_database2: ENCODING '=' encoding { $$ = cat2_str(make1_str("encoding ="), $3); }
2423 | /*EMPTY*/ { $$ = NULL; }
2426 location: Sconst { $$ = $1; }
2427 | DEFAULT { $$ = make1_str("default"); }
2428 | /*EMPTY*/ { $$ = make1_str(""); }
2431 encoding: Sconst { $$ = $1; }
2432 | DEFAULT { $$ = make1_str("default"); }
2433 | /*EMPTY*/ { $$ = make1_str(""); }
2436 /*****************************************************************************
2441 *****************************************************************************/
2443 DestroydbStmt: DROP DATABASE database_name
2445 $$ = cat2_str(make1_str("drop database"), $3);
2450 /*****************************************************************************
2453 * cluster <index_name> on <relation_name>
2455 *****************************************************************************/
2457 ClusterStmt: CLUSTER index_name ON relation_name
2459 $$ = cat4_str(make1_str("cluster"), $2, make1_str("on"), $4);
2464 /*****************************************************************************
2469 *****************************************************************************/
2471 VacuumStmt: VACUUM opt_verbose opt_analyze
2473 $$ = cat3_str(make1_str("vacuum"), $2, $3);
2475 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2477 if ( strlen($5) > 0 && strlen($4) == 0 )
2478 yyerror("parser: syntax error at or near \"(\"");
2479 $$ = cat5_str(make1_str("vacuum"), $2, $3, $4, $5);
2483 opt_verbose: VERBOSE { $$ = make1_str("verbose"); }
2484 | /*EMPTY*/ { $$ = make1_str(""); }
2487 opt_analyze: ANALYZE { $$ = make1_str("analyse"); }
2488 | /*EMPTY*/ { $$ = make1_str(""); }
2491 opt_va_list: '(' va_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
2492 | /*EMPTY*/ { $$ = make1_str(""); }
2498 { $$=cat3_str($1, make1_str(","), $3); }
2502 /*****************************************************************************
2507 *****************************************************************************/
2509 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2511 $$ = cat3_str(make1_str("explain"), $2, $3);
2516 /*****************************************************************************
2518 * Optimizable Stmts: *
2520 * one of the five queries processed by the planner *
2522 * [ultimately] produces query-trees as specified *
2523 * in the query-spec document in ~postgres/ref *
2525 *****************************************************************************/
2527 OptimizableStmt: SelectStmt
2536 /*****************************************************************************
2541 *****************************************************************************/
2544 /* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
2545 * originally. When the second rule of 'insert_rest' was changed to use
2546 * the new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/red uce
2547 * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to accept
2548 * the same statements without any shift/reduce conflicts */
2549 InsertStmt: INSERT INTO relation_name insert_rest
2551 $$ = cat3_str(make1_str("insert into"), $3, $4);
2555 insert_rest: VALUES '(' res_target_list2 ')'
2557 $$ = make3_str(make1_str("values("), $3, make1_str(")"));
2561 $$ = make1_str("default values");
2567 | '(' columnList ')' VALUES '(' res_target_list2 ')'
2569 $$ = make5_str(make1_str("("), $2, make1_str(") values ("), $6, make1_str(")"));
2571 | '(' columnList ')' SelectStmt
2573 $$ = make4_str(make1_str("("), $2, make1_str(")"), $4);
2577 opt_column_list: '(' columnList ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
2578 | /*EMPTY*/ { $$ = make1_str(""); }
2582 columnList ',' columnElem
2583 { $$ = cat3_str($1, make1_str(","), $3); }
2588 columnElem: ColId opt_indirection
2590 $$ = cat2_str($1, $2);
2595 /*****************************************************************************
2600 *****************************************************************************/
2602 DeleteStmt: DELETE FROM relation_name
2605 $$ = cat3_str(make1_str("delete from"), $3, $4);
2609 LockStmt: LOCK_P opt_table relation_name
2611 $$ = cat3_str(make1_str("lock"), $2, $3);
2613 | LOCK_P opt_table relation_name IN opt_lmode ROW IDENT IDENT
2615 if (strcasecmp($8, "MODE"))
2617 sprintf(errortext, "syntax error at or near \"%s\"", $8);
2622 if (strcasecmp($5, "SHARE"))
2624 sprintf(errortext, "syntax error at or near \"%s\"", $5);
2627 if (strcasecmp($7, "EXCLUSIVE"))
2629 sprintf(errortext, "syntax error at or near \"%s\"", $7);
2635 if (strcasecmp($7, "SHARE") && strcasecmp($7, "EXCLUSIVE"))
2637 sprintf(errortext, "syntax error at or near \"%s\"", $7);
2642 $$=cat4_str(cat5_str(make1_str("lock"), $2, $3, make1_str("in"), $5), make1_str("row"), $7, $8);
2644 | LOCK_P opt_table relation_name IN IDENT IDENT IDENT
2646 if (strcasecmp($7, "MODE"))
2648 sprintf(errortext, "syntax error at or near \"%s\"", $7);
2651 if (strcasecmp($5, "ACCESS"))
2653 sprintf(errortext, "syntax error at or near \"%s\"", $5);
2656 if (strcasecmp($6, "SHARE") && strcasecmp($6, "EXCLUSIVE"))
2658 sprintf(errortext, "syntax error at or near \"%s\"", $6);
2662 $$=cat3_str(cat5_str(make1_str("lock"), $2, $3, make1_str("in"), $5), $6, $7);
2664 | LOCK_P opt_table relation_name IN IDENT IDENT
2666 if (strcasecmp($6, "MODE"))
2668 sprintf(errortext, "syntax error at or near \"%s\"", $6);
2671 if (strcasecmp($5, "SHARE") && strcasecmp($5, "EXCLUSIVE"))
2673 sprintf(errortext, "syntax error at or near \"%s\"", $5);
2677 $$=cat2_str(cat5_str(make1_str("lock"), $2, $3, make1_str("in"), $5), $6);
2681 opt_lmode: IDENT { $$ = $1; }
2682 | /*EMPTY*/ { $$ = make1_str(""); }
2688 /*****************************************************************************
2691 * UpdateStmt (UPDATE)
2693 *****************************************************************************/
2695 UpdateStmt: UPDATE relation_name
2700 $$ = cat2_str(cat5_str(make1_str("update"), $2, make1_str("set"), $4, $5), $6);
2705 /*****************************************************************************
2710 *****************************************************************************/
2711 CursorStmt: DECLARE name opt_cursor CURSOR FOR SelectStmt cursor_clause
2713 struct cursor *ptr, *this;
2715 for (ptr = cur; ptr != NULL; ptr = ptr->next)
2717 if (strcmp($2, ptr->name) == 0)
2719 /* re-definition is a bug */
2720 sprintf(errortext, "cursor %s already defined", $2);
2725 this = (struct cursor *) mm_alloc(sizeof(struct cursor));
2727 /* initial definition */
2730 this->command = cat2_str(cat5_str(make1_str("declare"), mm_strdup($2), $3, make1_str("cursor for"), $6), $7);
2731 this->argsinsert = argsinsert;
2732 this->argsresult = argsresult;
2733 argsinsert = argsresult = NULL;
2737 $$ = cat3_str(make1_str("/*"), mm_strdup(this->command), make1_str("*/"));
2741 opt_cursor: BINARY { $$ = make1_str("binary"); }
2742 | INSENSITIVE { $$ = make1_str("insensitive"); }
2743 | SCROLL { $$ = make1_str("scroll"); }
2744 | INSENSITIVE SCROLL { $$ = make1_str("insensitive scroll"); }
2745 | /*EMPTY*/ { $$ = make1_str(""); }
2748 cursor_clause: FOR opt_readonly { $$ = cat2_str(make1_str("for"), $2); }
2749 | /*EMPTY*/ { $$ = make1_str(""); }
2753 opt_readonly: READ ONLY { $$ = make1_str("read only"); }
2756 yyerror("DECLARE/UPDATE not supported; Cursors must be READ ONLY.");
2760 opt_of: OF columnList { $$ = make2_str(make1_str("of"), $2); }
2762 /*****************************************************************************
2767 *****************************************************************************/
2770 /* The new 'SelectStmt' rule adapted for the optional use of INTERSECT EXCEPT a nd UNION
2771 * accepts the use of '(' and ')' to select an order of set operations.
2773 SelectStmt: select_w_o_sort sort_clause for_update_clause opt_select_limit
2775 if (strlen($3) > 0 && ForUpdateNotAllowed != 0)
2776 yyerror("SELECT FOR UPDATE is not allowed in this context");
2778 ForUpdateNotAllowed = 0;
2779 $$ = cat4_str($1, $2, $3, $4);
2783 /* This rule parses Select statements including UNION INTERSECT and EXCEPT.
2784 * '(' and ')' can be used to specify the order of the operations
2785 * (UNION EXCEPT INTERSECT). Without the use of '(' and ')' we want the
2786 * operations to be left associative.
2788 * The sort_clause is not handled here!
2790 select_w_o_sort: '(' select_w_o_sort ')'
2792 $$ = make3_str(make1_str("("), $2, make1_str(")"));
2798 | select_w_o_sort EXCEPT select_w_o_sort
2800 $$ = cat3_str($1, make1_str("except"), $3);
2801 ForUpdateNotAllowed = 1;
2803 | select_w_o_sort UNION opt_union select_w_o_sort
2805 $$ = cat3_str($1, make1_str("union"), $3);
2806 ForUpdateNotAllowed = 1;
2808 | select_w_o_sort INTERSECT opt_union select_w_o_sort
2810 $$ = cat3_str($1, make1_str("intersect"), $3);
2811 ForUpdateNotAllowed = 1;
2816 SubSelect: SELECT opt_unique res_target_list2
2817 result from_clause where_clause
2818 group_clause having_clause
2820 $$ = cat4_str(cat5_str(make1_str("select"), $2, $3, $4, $5), $6, $7, $8);
2821 if (strlen($7) > 0 || strlen($8) > 0)
2822 ForUpdateNotAllowed = 1;
2826 result: INTO OptTemp opt_table relation_name { $$= cat4_str(make1_str("into"), $2, $3, $4); }
2827 | INTO into_list { $$ = make1_str(""); }
2828 | /*EMPTY*/ { $$ = make1_str(""); }
2831 opt_table: TABLE { $$ = make1_str("table"); }
2832 | /*EMPTY*/ { $$ = make1_str(""); }
2835 opt_union: ALL { $$ = make1_str("all"); }
2836 | /*EMPTY*/ { $$ = make1_str(""); }
2839 opt_unique: DISTINCT { $$ = make1_str("distinct"); }
2840 | DISTINCT ON ColId { $$ = cat2_str(make1_str("distinct on"), $3); }
2841 | ALL { $$ = make1_str("all"); }
2842 | /*EMPTY*/ { $$ = make1_str(""); }
2845 sort_clause: ORDER BY sortby_list { $$ = cat2_str(make1_str("order by"), $3); }
2846 | /*EMPTY*/ { $$ = make1_str(""); }
2849 sortby_list: sortby { $$ = $1; }
2850 | sortby_list ',' sortby { $$ = cat3_str($1, make1_str(","), $3); }
2853 sortby: a_expr OptUseOp
2855 $$ = cat2_str($1, $2);
2859 OptUseOp: USING Op { $$ = cat2_str(make1_str("using"), $2); }
2860 | USING '<' { $$ = make1_str("using <"); }
2861 | USING '>' { $$ = make1_str("using >"); }
2862 | ASC { $$ = make1_str("asc"); }
2863 | DESC { $$ = make1_str("desc"); }
2864 | /*EMPTY*/ { $$ = make1_str(""); }
2867 opt_select_limit: LIMIT select_limit_value ',' select_offset_value
2868 { $$ = cat4_str(make1_str("limit"), $2, make1_str(","), $4); }
2869 | LIMIT select_limit_value OFFSET select_offset_value
2870 { $$ = cat4_str(make1_str("limit"), $2, make1_str("offset"), $4); }
2871 | LIMIT select_limit_value
2872 { $$ = cat2_str(make1_str("limit"), $2);; }
2873 | OFFSET select_offset_value LIMIT select_limit_value
2874 { $$ = cat4_str(make1_str("offset"), $2, make1_str("limit"), $4); }
2875 | OFFSET select_offset_value
2876 { $$ = cat2_str(make1_str("offset"), $2); }
2878 { $$ = make1_str(""); }
2881 select_limit_value: Iconst { $$ = $1; }
2882 | ALL { $$ = make1_str("all"); }
2883 | PARAM { $$ = make_name(); }
2886 select_offset_value: Iconst { $$ = $1; }
2887 | PARAM { $$ = make_name(); }
2891 * jimmy bell-style recursive queries aren't supported in the
2894 * ...however, recursive addattr and rename supported. make special
2897 opt_inh_star: '*' { $$ = make1_str("*"); }
2898 | /*EMPTY*/ { $$ = make1_str(""); }
2901 relation_name_list: name_list { $$ = $1; };
2905 | name_list ',' name
2906 { $$ = cat3_str($1, make1_str(","), $3); }
2909 group_clause: GROUP BY expr_list { $$ = cat2_str(make1_str("groub by"), $3); }
2910 | /*EMPTY*/ { $$ = make1_str(""); }
2913 having_clause: HAVING a_expr
2915 $$ = cat2_str(make1_str("having"), $2);
2917 | /*EMPTY*/ { $$ = make1_str(""); }
2923 $$ = make1_str("for update");
2925 | FOR UPDATE OF va_list
2927 $$ = cat2_str(make1_str("for update of"), $4);
2935 /*****************************************************************************
2937 * clauses common to all Optimizable Stmts:
2941 *****************************************************************************/
2943 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2945 yyerror("JOIN not yet implemented");
2947 | FROM from_list { $$ = cat2_str(make1_str("from"), $2); }
2948 | /*EMPTY*/ { $$ = make1_str(""); }
2951 from_list: from_list ',' from_val
2952 { $$ = cat3_str($1, make1_str(","), $3); }
2953 | from_val CROSS JOIN from_val
2954 { yyerror("CROSS JOIN not yet implemented"); }
2959 from_val: relation_expr AS ColLabel
2961 $$ = cat3_str($1, make1_str("as"), $3);
2963 | relation_expr ColId
2965 $$ = cat2_str($1, $2);
2973 join_expr: NATURAL join_expr { $$ = cat2_str(make1_str("natural"), $2); }
2975 { yyerror("FULL OUTER JOIN not yet implemented"); }
2977 { yyerror("LEFT OUTER JOIN not yet implemented"); }
2979 { yyerror("RIGHT OUTER JOIN not yet implemented"); }
2981 { yyerror("OUTER JOIN not yet implemented"); }
2983 { yyerror("INNER JOIN not yet implemented"); }
2985 { yyerror("UNION JOIN not yet implemented"); }
2987 { yyerror("INNER JOIN not yet implemented"); }
2990 join_outer: OUTER_P { $$ = make1_str("outer"); }
2991 | /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
2994 join_spec: ON '(' a_expr ')' { $$ = make3_str(make1_str("on ("), $3, make1_str(")")); }
2995 | USING '(' join_list ')' { $$ = make3_str(make1_str("using ("), $3, make1_str(")")); }
2996 | /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
2999 join_list: join_using { $$ = $1; }
3000 | join_list ',' join_using { $$ = cat3_str($1, make1_str(","), $3); }
3009 $$ = make3_str($1, make1_str("."), $3);
3017 where_clause: WHERE a_expr { $$ = cat2_str(make1_str("where"), $2); }
3018 | /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
3021 relation_expr: relation_name
3023 /* normal relations */
3026 | relation_name '*' %prec '='
3028 /* inheritance query */
3029 $$ = cat2_str($1, make1_str("*"));
3032 opt_array_bounds: '[' ']' nest_array_bounds
3035 $$.index2 = $3.index1;
3036 $$.str = cat2_str(make1_str("[]"), $3.str);
3038 | '[' Iconst ']' nest_array_bounds
3040 $$.index1 = atol($2);
3041 $$.index2 = $4.index1;
3042 $$.str = cat4_str(make1_str("["), $2, make1_str("]"), $4.str);
3048 $$.str= make1_str("");
3052 nest_array_bounds: '[' ']' nest_array_bounds
3055 $$.index2 = $3.index1;
3056 $$.str = cat2_str(make1_str("[]"), $3.str);
3058 | '[' Iconst ']' nest_array_bounds
3060 $$.index1 = atol($2);
3061 $$.index2 = $4.index1;
3062 $$.str = cat4_str(make1_str("["), $2, make1_str("]"), $4.str);
3068 $$.str= make1_str("");
3072 /*****************************************************************************
3075 * SQL92 introduces a large amount of type-specific syntax.
3076 * Define individual clauses to handle these cases, and use
3077 * the generic case to handle regular type-extensible Postgres syntax.
3078 * - thomas 1997-10-10
3080 *****************************************************************************/
3082 Typename: Array opt_array_bounds
3084 $$ = cat2_str($1, $2.str);
3086 | Character { $$ = $1; }
3089 $$ = cat2_str(make1_str("setof"), $2);
3094 | Datetime { $$ = $1; }
3095 | Numeric { $$ = $1; }
3104 generic: ident { $$ = $1; }
3105 | TYPE_P { $$ = make1_str("type"); }
3106 | SQL_BOOL { $$ = make1_str("bool"); }
3107 | SQL_BREAK { $$ = make1_str("break"); }
3108 | SQL_CALL { $$ = make1_str("call"); }
3109 | SQL_CONNECT { $$ = make1_str("connect"); }
3110 | SQL_CONNECTION { $$ = make1_str("connection"); }
3111 | SQL_CONTINUE { $$ = make1_str("continue"); }
3112 | SQL_DEALLOCATE { $$ = make1_str("deallocate"); }
3113 | SQL_DISCONNECT { $$ = make1_str("disconnect"); }
3114 | SQL_FOUND { $$ = make1_str("found"); }
3115 | SQL_GO { $$ = make1_str("go"); }
3116 | SQL_GOTO { $$ = make1_str("goto"); }
3117 | SQL_IDENTIFIED { $$ = make1_str("identified"); }
3118 | SQL_IMMEDIATE { $$ = make1_str("immediate"); }
3119 | SQL_INDICATOR { $$ = make1_str("indicator"); }
3120 | SQL_INT { $$ = make1_str("int"); }
3121 | SQL_LONG { $$ = make1_str("long"); }
3122 | SQL_OPEN { $$ = make1_str("open"); }
3123 | SQL_PREPARE { $$ = make1_str("prepare"); }
3124 | SQL_RELEASE { $$ = make1_str("release"); }
3125 | SQL_SECTION { $$ = make1_str("section"); }
3126 | SQL_SHORT { $$ = make1_str("short"); }
3127 | SQL_SIGNED { $$ = make1_str("signed"); }
3128 | SQL_SQLERROR { $$ = make1_str("sqlerror"); }
3129 | SQL_SQLPRINT { $$ = make1_str("sqlprint"); }
3130 | SQL_SQLWARNING { $$ = make1_str("sqlwarning"); }
3131 | SQL_STOP { $$ = make1_str("stop"); }
3132 | SQL_STRUCT { $$ = make1_str("struct"); }
3133 | SQL_UNSIGNED { $$ = make1_str("unsigned"); }
3134 | SQL_VAR { $$ = make1_str("var"); }
3135 | SQL_WHENEVER { $$ = make1_str("whenever"); }
3138 /* SQL92 numeric data types
3139 * Check FLOAT() precision limits assuming IEEE floating types.
3140 * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
3141 * - thomas 1997-09-18
3143 Numeric: FLOAT opt_float
3145 $$ = cat2_str(make1_str("float"), $2);
3149 $$ = make1_str("double precision");
3151 | DECIMAL opt_decimal
3153 $$ = cat2_str(make1_str("decimal"), $2);
3155 | NUMERIC opt_numeric
3157 $$ = cat2_str(make1_str("numeric"), $2);
3162 { $$ = make1_str("float"); }
3164 { $$ = make1_str("double precision"); }
3166 { $$ = make1_str("decimal"); }
3168 { $$ = make1_str("numeric"); }
3171 opt_float: '(' Iconst ')'
3174 yyerror("precision for FLOAT must be at least 1");
3175 else if (atol($2) >= 16)
3176 yyerror("precision for FLOAT must be less than 16");
3177 $$ = make3_str(make1_str("("), $2, make1_str(")"));
3185 opt_numeric: '(' Iconst ',' Iconst ')'
3187 if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
3188 sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
3191 if (atol($4) < 0 || atol($4) > atol($2)) {
3192 sprintf(errortext, "NUMERIC scale %s must be between 0 and precision %s", $4, $2);
3195 $$ = cat3_str(make2_str(make1_str("("), $2), make1_str(","), make2_str($4, make1_str(")")));
3199 if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
3200 sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
3203 $$ = make3_str(make1_str("("), $2, make1_str(")"));
3211 opt_decimal: '(' Iconst ',' Iconst ')'
3213 if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
3214 sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
3217 if (atol($4) < 0 || atol($4) > atol($2)) {
3218 sprintf(errortext, "NUMERIC scale %s must be between 0 and precision %s", $4, $2);
3221 $$ = cat3_str(make2_str(make1_str("("), $2), make1_str(","), make2_str($4, make1_str(")")));
3225 if (atol($2) < 1 || atol($2) > NUMERIC_MAX_PRECISION) {
3226 sprintf(errortext, "NUMERIC precision %s must be between 1 and %d", $2, NUMERIC_MAX_PRECISION);
3229 $$ = make3_str(make1_str("("), $2, make1_str(")"));
3237 /* SQL92 character data types
3238 * The following implements CHAR() and VARCHAR().
3239 * We do it here instead of the 'Generic' production
3240 * because we don't want to allow arrays of VARCHAR().
3241 * I haven't thought about whether that will work or not.
3244 Character: character '(' Iconst ')'
3246 if (strncasecmp($1, "char", strlen("char")) && strncasecmp($1, "varchar", strlen("varchar")))
3247 yyerror("internal parsing error; unrecognized character type");
3249 sprintf(errortext, "length for '%s' type must be at least 1",$1);
3252 else if (atol($3) > 4096) {
3253 /* we can store a char() of length up to the size
3254 * of a page (8KB) - page headers and friends but
3255 * just to be safe here... - ay 6/95
3256 * XXX note this hardcoded limit - thomas 1997-07-13
3258 sprintf(errortext, "length for type '%s' cannot exceed 4096",$1);
3262 $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")")));
3270 character: CHARACTER opt_varying opt_charset opt_collate
3273 fprintf(stderr, "COLLATE %s not yet implemented",$4);
3275 $$ = cat4_str(make1_str("character"), $2, $3, $4);
3277 | CHAR opt_varying { $$ = cat2_str(make1_str("char"), $2); }
3278 | VARCHAR { $$ = make1_str("varchar"); }
3279 | NATIONAL CHARACTER opt_varying { $$ = cat2_str(make1_str("national character"), $3); }
3280 | NCHAR opt_varying { $$ = cat2_str(make1_str("nchar"), $2); }
3283 opt_varying: VARYING { $$ = make1_str("varying"); }
3284 | /*EMPTY*/ { $$ = make1_str(""); }
3287 opt_charset: CHARACTER SET ColId { $$ = cat2_str(make1_str("character set"), $3); }
3288 | /*EMPTY*/ { $$ = make1_str(""); }
3291 opt_collate: COLLATE ColId { $$ = cat2_str(make1_str("collate"), $2); }
3292 | /*EMPTY*/ { $$ = make1_str(""); }
3299 | TIMESTAMP opt_timezone
3301 $$ = cat2_str(make1_str("timestamp"), $2);
3305 $$ = make1_str("time");
3307 | INTERVAL opt_interval
3309 $$ = cat2_str(make1_str("interval"), $2);
3313 datetime: YEAR_P { $$ = make1_str("year"); }
3314 | MONTH_P { $$ = make1_str("month"); }
3315 | DAY_P { $$ = make1_str("day"); }
3316 | HOUR_P { $$ = make1_str("hour"); }
3317 | MINUTE_P { $$ = make1_str("minute"); }
3318 | SECOND_P { $$ = make1_str("second"); }
3321 opt_timezone: WITH TIME ZONE { $$ = make1_str("with time zone"); }
3322 | /*EMPTY*/ { $$ = make1_str(""); }
3325 opt_interval: datetime { $$ = $1; }
3326 | YEAR_P TO MONTH_P { $$ = make1_str("year to #month"); }
3327 | DAY_P TO HOUR_P { $$ = make1_str("day to hour"); }
3328 | DAY_P TO MINUTE_P { $$ = make1_str("day to minute"); }
3329 | DAY_P TO SECOND_P { $$ = make1_str("day to second"); }
3330 | HOUR_P TO MINUTE_P { $$ = make1_str("hour to minute"); }
3331 | MINUTE_P TO SECOND_P { $$ = make1_str("minute to second"); }
3332 | HOUR_P TO SECOND_P { $$ = make1_str("hour to second"); }
3333 | /*EMPTY*/ { $$ = make1_str(""); }
3337 /*****************************************************************************
3339 * expression grammar, still needs some cleanup
3341 *****************************************************************************/
3343 a_expr_or_null: a_expr
3347 $$ = make1_str("null");
3351 /* Expressions using row descriptors
3352 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
3353 * with singleton expressions.
3354 * Eliminated lots of code by defining row_op and sub_type clauses.
3355 * However, can not consolidate EXPR_LINK case with others subselects
3356 * due to shift/reduce conflict with the non-subselect clause (the parser
3357 * would have to look ahead more than one token to resolve the conflict).
3358 * - thomas 1998-05-09
3360 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
3362 $$ = make5_str(make1_str("("), $2, make1_str(") in ("), $6, make1_str(")"));
3364 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
3366 $$ = make5_str(make1_str("("), $2, make1_str(") not in ("), $7, make1_str(")"));
3368 | '(' row_descriptor ')' row_op sub_type '(' SubSelect ')'
3370 $$ = make4_str(make5_str(make1_str("("), $2, make1_str(")"), $4, $5), make1_str("("), $7, make1_str(")"));
3372 | '(' row_descriptor ')' row_op '(' SubSelect ')'
3374 $$ = make3_str(make5_str(make1_str("("), $2, make1_str(")"), $4, make1_str("(")), $6, make1_str(")"));
3376 | '(' row_descriptor ')' row_op '(' row_descriptor ')'
3378 $$ = cat3_str(make3_str(make1_str("("), $2, make1_str(")")), $4, make3_str(make1_str("("), $6, make1_str(")")));
3382 row_descriptor: row_list ',' a_expr
3384 $$ = cat3_str($1, make1_str(","), $3);
3388 row_op: Op { $$ = $1; }
3398 sub_type: ANY { $$ = make1_str("ANY"); }
3399 | ALL { $$ = make1_str("ALL"); }
3403 row_list: row_list ',' a_expr
3405 $$ = cat3_str($1, make1_str(","), $3);
3413 /* General expressions
3414 * This is the heart of the expression syntax.
3415 * Note that the BETWEEN clause looks similar to a boolean expression
3416 * and so we must define b_expr which is almost the same as a_expr
3417 * but without the boolean expressions.
3418 * All operations/expressions are allowed in a BETWEEN clause
3419 * if surrounded by parens.
3422 a_expr: attr opt_indirection
3424 $$ = cat2_str($1, $2);
3434 | '-' a_expr %prec UMINUS
3435 { $$ = cat2_str(make1_str("-"), $2); }
3437 { $$ = cat3_str($1, make1_str("+"), $3); }
3439 { $$ = cat3_str($1, make1_str("-"), $3); }
3441 { $$ = cat3_str($1, make1_str("/"), $3); }
3443 { $$ = cat3_str($1, make1_str("*"), $3); }
3445 { $$ = cat3_str($1, make1_str("<"), $3); }
3447 { $$ = cat3_str($1, make1_str(">"), $3); }
3449 { $$ = cat3_str($1, make1_str("="), $3); }
3450 /* not possible in embedded sql | ':' a_expr
3451 { $$ = cat2_str(make1_str(":"), $2); }
3454 { $$ = cat2_str(make1_str(";"), $2); }
3456 { $$ = cat2_str(make1_str("|"), $2); }
3457 | a_expr TYPECAST Typename
3459 $$ = cat3_str($1, make1_str("::"), $3);
3461 | CAST '(' a_expr AS Typename ')'
3463 $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
3465 | '(' a_expr_or_null ')'
3466 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
3468 { $$ = cat3_str($1, $2, $3); }
3469 | a_expr LIKE a_expr
3470 { $$ = cat3_str($1, make1_str("like"), $3); }
3471 | a_expr NOT LIKE a_expr
3472 { $$ = cat3_str($1, make1_str("not like"), $4); }
3474 { $$ = cat2_str($1, $2); }
3476 { $$ = cat2_str($1, $2); }
3477 | func_name '(' '*' ')'
3479 $$ = cat2_str($1, make1_str("(*)"));
3483 $$ = cat2_str($1, make1_str("()"));
3485 | func_name '(' expr_list ')'
3487 $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
3491 $$ = make1_str("current_date");
3495 $$ = make1_str("current_time");
3497 | CURRENT_TIME '(' Iconst ')'
3500 fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
3501 $$ = make1_str("current_time");
3505 $$ = make1_str("current_timestamp");
3507 | CURRENT_TIMESTAMP '(' Iconst ')'
3510 fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
3511 $$ = make1_str("current_timestamp");
3515 $$ = make1_str("current_user");
3519 $$ = make1_str("user");
3522 | EXISTS '(' SubSelect ')'
3524 $$ = make3_str(make1_str("exists("), $3, make1_str(")"));
3526 | EXTRACT '(' extract_list ')'
3528 $$ = make3_str(make1_str("extract("), $3, make1_str(")"));
3530 | POSITION '(' position_list ')'
3532 $$ = make3_str(make1_str("position("), $3, make1_str(")"));
3534 | SUBSTRING '(' substr_list ')'
3536 $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
3538 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3539 | TRIM '(' BOTH trim_list ')'
3541 $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
3543 | TRIM '(' LEADING trim_list ')'
3545 $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
3547 | TRIM '(' TRAILING trim_list ')'
3549 $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
3551 | TRIM '(' trim_list ')'
3553 $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
3556 { $$ = cat2_str($1, make1_str("isnull")); }
3558 { $$ = cat2_str($1, make1_str("is null")); }
3560 { $$ = cat2_str($1, make1_str("notnull")); }
3561 | a_expr IS NOT NULL_P
3562 { $$ = cat2_str($1, make1_str("is not null")); }
3563 /* IS TRUE, IS FALSE, etc used to be function calls
3564 * but let's make them expressions to allow the optimizer
3565 * a chance to eliminate them if a_expr is a constant string.
3566 * - thomas 1997-12-22
3570 { $$ = cat2_str($1, make1_str("is true")); }
3572 | a_expr IS NOT FALSE_P
3574 { $$ = cat2_str($1, make1_str("is not false")); }
3578 { $$ = cat2_str($1, make1_str("is false")); }
3580 | a_expr IS NOT TRUE_P
3582 { $$ = cat2_str($1, make1_str("is not true")); }
3584 | a_expr BETWEEN b_expr AND b_expr
3586 $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5);
3588 | a_expr NOT BETWEEN b_expr AND b_expr
3590 $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6);
3592 | a_expr IN '(' in_expr ')'
3594 $$ = make4_str($1, make1_str("in ("), $4, make1_str(")"));
3596 | a_expr NOT IN '(' not_in_expr ')'
3598 $$ = make4_str($1, make1_str("not in ("), $5, make1_str(")"));
3600 | a_expr Op '(' SubSelect ')'
3602 $$ = cat3_str($1, $2, make3_str(make1_str("("), $4, make1_str(")")));
3604 | a_expr '+' '(' SubSelect ')'
3606 $$ = make4_str($1, make1_str("+("), $4, make1_str(")"));
3608 | a_expr '-' '(' SubSelect ')'
3610 $$ = make4_str($1, make1_str("-("), $4, make1_str(")"));
3612 | a_expr '/' '(' SubSelect ')'
3614 $$ = make4_str($1, make1_str("/("), $4, make1_str(")"));
3616 | a_expr '*' '(' SubSelect ')'
3618 $$ = make4_str($1, make1_str("*("), $4, make1_str(")"));
3620 | a_expr '<' '(' SubSelect ')'
3622 $$ = make4_str($1, make1_str("<("), $4, make1_str(")"));
3624 | a_expr '>' '(' SubSelect ')'
3626 $$ = make4_str($1, make1_str(">("), $4, make1_str(")"));
3628 | a_expr '=' '(' SubSelect ')'
3630 $$ = make4_str($1, make1_str("=("), $4, make1_str(")"));
3632 | a_expr Op ANY '(' SubSelect ')'
3634 $$ = cat3_str($1, $2, make3_str(make1_str("any("), $5, make1_str(")")));
3636 | a_expr '+' ANY '(' SubSelect ')'
3638 $$ = make4_str($1, make1_str("+any("), $5, make1_str(")"));
3640 | a_expr '-' ANY '(' SubSelect ')'
3642 $$ = make4_str($1, make1_str("-any("), $5, make1_str(")"));
3644 | a_expr '/' ANY '(' SubSelect ')'
3646 $$ = make4_str($1, make1_str("/any("), $5, make1_str(")"));
3648 | a_expr '*' ANY '(' SubSelect ')'
3650 $$ = make4_str($1, make1_str("*any("), $5, make1_str(")"));
3652 | a_expr '<' ANY '(' SubSelect ')'
3654 $$ = make4_str($1, make1_str("<any("), $5, make1_str(")"));
3656 | a_expr '>' ANY '(' SubSelect ')'
3658 $$ = make4_str($1, make1_str(">any("), $5, make1_str(")"));
3660 | a_expr '=' ANY '(' SubSelect ')'
3662 $$ = make4_str($1, make1_str("=any("), $5, make1_str(")"));
3664 | a_expr Op ALL '(' SubSelect ')'
3666 $$ = cat3_str($1, $2, make3_str(make1_str("all ("), $5, make1_str(")")));
3668 | a_expr '+' ALL '(' SubSelect ')'
3670 $$ = make4_str($1, make1_str("+all("), $5, make1_str(")"));
3672 | a_expr '-' ALL '(' SubSelect ')'
3674 $$ = make4_str($1, make1_str("-all("), $5, make1_str(")"));
3676 | a_expr '/' ALL '(' SubSelect ')'
3678 $$ = make4_str($1, make1_str("/all("), $5, make1_str(")"));
3680 | a_expr '*' ALL '(' SubSelect ')'
3682 $$ = make4_str($1, make1_str("*all("), $5, make1_str(")"));
3684 | a_expr '<' ALL '(' SubSelect ')'
3686 $$ = make4_str($1, make1_str("<all("), $5, make1_str(")"));
3688 | a_expr '>' ALL '(' SubSelect ')'
3690 $$ = make4_str($1, make1_str(">all("), $5, make1_str(")"));
3692 | a_expr '=' ALL '(' SubSelect ')'
3694 $$ = make4_str($1, make1_str("=all("), $5, make1_str(")"));
3697 { $$ = cat3_str($1, make1_str("and"), $3); }
3699 { $$ = cat3_str($1, make1_str("or"), $3); }
3701 { $$ = cat2_str(make1_str("not"), $2); }
3705 { $$ = make1_str(";;"); }
3708 /* Restricted expressions
3709 * b_expr is a subset of the complete expression syntax
3710 * defined by a_expr. b_expr is used in BETWEEN clauses
3711 * to eliminate parser ambiguities stemming from the AND keyword.
3713 b_expr: attr opt_indirection
3715 $$ = cat2_str($1, $2);
3723 | '-' b_expr %prec UMINUS
3724 { $$ = cat2_str(make1_str("-"), $2); }
3726 { $$ = cat3_str($1, make1_str("+"), $3); }
3728 { $$ = cat3_str($1, make1_str("-"), $3); }
3730 { $$ = cat3_str($1, make1_str("/"), $3); }
3732 { $$ = cat3_str($1, make1_str("*"), $3); }
3733 /* not possible in embedded sql | ':' b_expr
3734 { $$ = cat2_str(make1_str(":"), $2); }
3737 { $$ = cat2_str(make1_str(";"), $2); }
3739 { $$ = cat2_str(make1_str("|"), $2); }
3740 | b_expr TYPECAST Typename
3742 $$ = cat3_str($1, make1_str("::"), $3);
3744 | CAST '(' b_expr AS Typename ')'
3746 $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
3749 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
3751 { $$ = cat3_str($1, $2, $3); }
3753 { $$ = cat2_str($1, $2); }
3755 { $$ = cat2_str($1, $2); }
3758 $$ = cat2_str($1, make1_str("()"));
3760 | func_name '(' expr_list ')'
3762 $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
3766 $$ = make1_str("current_date");
3770 $$ = make1_str("current_time");
3772 | CURRENT_TIME '(' Iconst ')'
3775 fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
3776 $$ = make1_str("current_time");
3780 $$ = make1_str("current_timestamp");
3782 | CURRENT_TIMESTAMP '(' Iconst ')'
3785 fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
3786 $$ = make1_str("current_timestamp");
3790 $$ = make1_str("current_user");
3794 $$ = make1_str("user");
3796 | POSITION '(' position_list ')'
3798 $$ = make3_str(make1_str("position ("), $3, make1_str(")"));
3800 | SUBSTRING '(' substr_list ')'
3802 $$ = make3_str(make1_str("substring ("), $3, make1_str(")"));
3804 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3805 | TRIM '(' BOTH trim_list ')'
3807 $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
3809 | TRIM '(' LEADING trim_list ')'
3811 $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
3813 | TRIM '(' TRAILING trim_list ')'
3815 $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
3817 | TRIM '(' trim_list ')'
3819 $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
3825 opt_indirection: '[' ecpg_expr ']' opt_indirection
3827 $$ = cat4_str(make1_str("["), $2, make1_str("]"), $4);
3829 | '[' ecpg_expr ':' ecpg_expr ']' opt_indirection
3831 $$ = cat2_str(cat5_str(make1_str("["), $2, make1_str(":"), $4, make1_str("]")), $6);
3834 { $$ = make1_str(""); }
3837 expr_list: a_expr_or_null
3839 | expr_list ',' a_expr_or_null
3840 { $$ = cat3_str($1, make1_str(","), $3); }
3841 | expr_list USING a_expr
3842 { $$ = cat3_str($1, make1_str("using"), $3); }
3845 extract_list: extract_arg FROM a_expr
3847 $$ = cat3_str($1, make1_str("from"), $3);
3850 { $$ = make1_str(""); }
3852 { $$ = make1_str(";;"); }
3855 extract_arg: datetime { $$ = $1; }
3856 | TIMEZONE_HOUR { $$ = make1_str("timezone_hour"); }
3857 | TIMEZONE_MINUTE { $$ = make1_str("timezone_minute"); }
3860 position_list: position_expr IN position_expr
3861 { $$ = cat3_str($1, make1_str("in"), $3); }
3863 { $$ = make1_str(""); }
3866 position_expr: attr opt_indirection
3868 $$ = cat2_str($1, $2);
3872 | '-' position_expr %prec UMINUS
3873 { $$ = cat2_str(make1_str("-"), $2); }
3874 | position_expr '+' position_expr
3875 { $$ = cat3_str($1, make1_str("+"), $3); }
3876 | position_expr '-' position_expr
3877 { $$ = cat3_str($1, make1_str("-"), $3); }
3878 | position_expr '/' position_expr
3879 { $$ = cat3_str($1, make1_str("/"), $3); }
3880 | position_expr '*' position_expr
3881 { $$ = cat3_str($1, make1_str("*"), $3); }
3883 { $$ = cat2_str(make1_str("|"), $2); }
3884 | position_expr TYPECAST Typename
3886 $$ = cat3_str($1, make1_str("::"), $3);
3888 | CAST '(' position_expr AS Typename ')'
3890 $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
3892 | '(' position_expr ')'
3893 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
3894 | position_expr Op position_expr
3895 { $$ = cat3_str($1, $2, $3); }
3897 { $$ = cat2_str($1, $2); }
3899 { $$ = cat2_str($1, $2); }
3906 $$ = cat2_str($1, make1_str("()"));
3908 | func_name '(' expr_list ')'
3910 $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
3912 | POSITION '(' position_list ')'
3914 $$ = make3_str(make1_str("position("), $3, make1_str(")"));
3916 | SUBSTRING '(' substr_list ')'
3918 $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
3920 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3921 | TRIM '(' BOTH trim_list ')'
3923 $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
3925 | TRIM '(' LEADING trim_list ')'
3927 $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
3929 | TRIM '(' TRAILING trim_list ')'
3931 $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
3933 | TRIM '(' trim_list ')'
3935 $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
3939 substr_list: expr_list substr_from substr_for
3941 $$ = cat3_str($1, $2, $3);
3944 { $$ = make1_str(""); }
3947 substr_from: FROM expr_list
3948 { $$ = cat2_str(make1_str("from"), $2); }
3955 substr_for: FOR expr_list
3956 { $$ = cat2_str(make1_str("for"), $2); }
3958 { $$ = make1_str(""); }
3961 trim_list: a_expr FROM expr_list
3962 { $$ = cat3_str($1, make1_str("from"), $3); }
3964 { $$ = cat2_str(make1_str("from"), $2); }
3977 in_expr_nodes: AexprConst
3979 | in_expr_nodes ',' AexprConst
3980 { $$ = cat3_str($1, make1_str(","), $3);}
3983 not_in_expr: SubSelect
3991 not_in_expr_nodes: AexprConst
3993 | not_in_expr_nodes ',' AexprConst
3994 { $$ = cat3_str($1, make1_str(","), $3);}
3998 * Define SQL92-style case clause.
3999 * Allow all four forms described in the standard:
4000 * - Full specification
4001 * CASE WHEN a = b THEN c ... ELSE d END
4002 * - Implicit argument
4003 * CASE a WHEN b THEN c ... ELSE d END
4004 * - Conditional NULL
4006 * same as CASE WHEN x = y THEN NULL ELSE x END
4007 * - Conditional substitution from list, use first non-null argument
4009 * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
4010 * - thomas 1998-11-09
4012 case_expr: CASE case_arg when_clause_list case_default END_TRANS
4013 { $$ = cat5_str(make1_str("case"), $2, $3, $4, make1_str("end")); }
4014 | NULLIF '(' a_expr ',' a_expr ')'
4016 $$ = cat5_str(make1_str("nullif("), $3, make1_str(","), $5, make1_str(")"));
4018 fprintf(stderr, "NULLIF() not yet fully implemented");
4020 | COALESCE '(' expr_list ')'
4022 $$ = cat3_str(make1_str("coalesce("), $3, make1_str(")"));
4024 fprintf(stderr, "COALESCE() not yet fully implemented");
4028 when_clause_list: when_clause_list when_clause
4029 { $$ = cat2_str($1, $2); }
4034 when_clause: WHEN a_expr THEN a_expr_or_null
4036 $$ = cat4_str(make1_str("when"), $2, make1_str("then"), $4);
4040 case_default: ELSE a_expr_or_null { $$ = cat2_str(make1_str("else"), $2); }
4041 | /*EMPTY*/ { $$ = make1_str(""); }
4044 case_arg: attr opt_indirection
4046 $$ = cat2_str($1, $2);
4053 { $$ = make1_str(""); }
4056 attr: relation_name '.' attrs
4058 $$ = make3_str($1, make1_str("."), $3);
4062 $$ = make3_str($1, make1_str("."), $3);
4068 | attrs '.' attr_name
4069 { $$ = make3_str($1, make1_str("."), $3); }
4071 { $$ = make2_str($1, make1_str(".*")); }
4075 /*****************************************************************************
4079 *****************************************************************************/
4081 res_target_list: res_target_list ',' res_target_el
4082 { $$ = cat3_str($1, make1_str(","),$3); }
4085 | '*' { $$ = make1_str("*"); }
4088 res_target_el: ColId opt_indirection '=' a_expr_or_null
4090 $$ = cat4_str($1, $2, make1_str("="), $4);
4092 | attr opt_indirection
4094 $$ = cat2_str($1, $2);
4096 | relation_name '.' '*'
4098 $$ = make2_str($1, make1_str(".*"));
4103 ** target list for select.
4104 ** should get rid of the other but is still needed by the defunct select into
4105 ** and update (uses a subset)
4107 res_target_list2: res_target_list2 ',' res_target_el2
4108 { $$ = cat3_str($1, make1_str(","), $3); }
4113 /* AS is not optional because shift/red conflict with unary ops */
4114 res_target_el2: a_expr_or_null AS ColLabel
4116 $$ = cat3_str($1, make1_str("as"), $3);
4122 | relation_name '.' '*'
4124 $$ = make2_str($1, make1_str(".*"));
4128 $$ = make1_str("*");
4132 opt_id: ColId { $$ = $1; }
4133 | /* EMPTY */ { $$ = make1_str(""); }
4136 relation_name: SpecialRuleRelation
4142 /* disallow refs to variable system tables */
4143 if (strcmp(LogRelationName, $1) == 0
4144 || strcmp(VariableRelationName, $1) == 0) {
4145 sprintf(errortext, make1_str("%s cannot be accessed by users"),$1);
4153 database_name: ColId { $$ = $1; };
4154 access_method: ident { $$ = $1; };
4155 attr_name: ColId { $$ = $1; };
4156 class: ident { $$ = $1; };
4157 index_name: ColId { $$ = $1; };
4160 * Include date/time keywords as SQL92 extension.
4161 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4163 name: ColId { $$ = $1; };
4164 func_name: ColId { $$ = $1; };
4166 file_name: Sconst { $$ = $1; };
4167 recipe_name: ident { $$ = $1; };
4170 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4186 $$ = cat2_str($1, $2);
4192 $$ = make1_str("true");
4196 $$ = make1_str("false");
4200 ParamNo: PARAM opt_indirection
4202 $$ = cat2_str(make_name(), $2);
4206 Iconst: ICONST { $$ = make_name();};
4207 Fconst: FCONST { $$ = make_name();};
4209 $$ = (char *)mm_alloc(strlen($1) + 3);
4212 $$[strlen($1)+2]='\0';
4213 $$[strlen($1)+1]='\'';
4216 UserId: ident { $$ = $1;};
4218 /* Column and type identifier
4219 * Does not include explicit datetime types
4220 * since these must be decoupled in Typename syntax.
4221 * Use ColId for most identifiers. - thomas 1997-10-21
4230 /* Column identifier
4231 * Include date/time keywords as SQL92 extension.
4232 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4233 * Add other keywords. Note that as the syntax expands,
4234 * some of these keywords will have to be removed from this
4235 * list due to shift/reduce conflicts in yacc. If so, move
4236 * down to the ColLabel entity. - thomas 1997-11-06
4238 ColId: ident { $$ = $1; }
4239 | datetime { $$ = $1; }
4240 | ABSOLUTE { $$ = make1_str("absolute"); }
4241 | ACTION { $$ = make1_str("action"); }
4242 | AFTER { $$ = make1_str("after"); }
4243 | AGGREGATE { $$ = make1_str("aggregate"); }
4244 | BACKWARD { $$ = make1_str("backward"); }
4245 | BEFORE { $$ = make1_str("before"); }
4246 | CACHE { $$ = make1_str("cache"); }
4247 | CREATEDB { $$ = make1_str("createdb"); }
4248 | CREATEUSER { $$ = make1_str("createuser"); }
4249 | CYCLE { $$ = make1_str("cycle"); }
4250 | DATABASE { $$ = make1_str("database"); }
4251 | DELIMITERS { $$ = make1_str("delimiters"); }
4252 | DOUBLE { $$ = make1_str("double"); }
4253 | EACH { $$ = make1_str("each"); }
4254 | ENCODING { $$ = make1_str("encoding"); }
4255 | FORWARD { $$ = make1_str("forward"); }
4256 | FUNCTION { $$ = make1_str("function"); }
4257 | HANDLER { $$ = make1_str("handler"); }
4258 | INCREMENT { $$ = make1_str("increment"); }
4259 | INDEX { $$ = make1_str("index"); }
4260 | INHERITS { $$ = make1_str("inherits"); }
4261 | INSENSITIVE { $$ = make1_str("insensitive"); }
4262 | INSTEAD { $$ = make1_str("instead"); }
4263 | ISNULL { $$ = make1_str("isnull"); }
4264 | KEY { $$ = make1_str("key"); }
4265 | LANGUAGE { $$ = make1_str("language"); }
4266 | LANCOMPILER { $$ = make1_str("lancompiler"); }
4267 | LOCATION { $$ = make1_str("location"); }
4268 | MATCH { $$ = make1_str("match"); }
4269 | MAXVALUE { $$ = make1_str("maxvalue"); }
4270 | MINVALUE { $$ = make1_str("minvalue"); }
4271 | NEXT { $$ = make1_str("next"); }
4272 | NOCREATEDB { $$ = make1_str("nocreatedb"); }
4273 | NOCREATEUSER { $$ = make1_str("nocreateuser"); }
4274 | NOTHING { $$ = make1_str("nothing"); }
4275 | NOTNULL { $$ = make1_str("notnull"); }
4276 | OF { $$ = make1_str("of"); }
4277 | OIDS { $$ = make1_str("oids"); }
4278 | ONLY { $$ = make1_str("only"); }
4279 | OPERATOR { $$ = make1_str("operator"); }
4280 | OPTION { $$ = make1_str("option"); }
4281 | PASSWORD { $$ = make1_str("password"); }
4282 | PRIOR { $$ = make1_str("prior"); }
4283 | PRIVILEGES { $$ = make1_str("privileges"); }
4284 | PROCEDURAL { $$ = make1_str("procedural"); }
4285 | READ { $$ = make1_str("read"); }
4286 | RECIPE { $$ = make1_str("recipe"); }
4287 | RELATIVE { $$ = make1_str("relative"); }
4288 | RENAME { $$ = make1_str("rename"); }
4289 | RETURNS { $$ = make1_str("returns"); }
4290 | ROW { $$ = make1_str("row"); }
4291 | RULE { $$ = make1_str("rule"); }
4292 | SCROLL { $$ = make1_str("scroll"); }
4293 | SEQUENCE { $$ = make1_str("sequence"); }
4294 | SERIAL { $$ = make1_str("serial"); }
4295 | START { $$ = make1_str("start"); }
4296 | STATEMENT { $$ = make1_str("statement"); }
4297 | STDIN { $$ = make1_str("stdin"); }
4298 | STDOUT { $$ = make1_str("stdout"); }
4299 | TIME { $$ = make1_str("time"); }
4300 | TIMESTAMP { $$ = make1_str("timestamp"); }
4301 | TIMEZONE_HOUR { $$ = make1_str("timezone_hour"); }
4302 | TIMEZONE_MINUTE { $$ = make1_str("timezone_minute"); }
4303 | TRIGGER { $$ = make1_str("trigger"); }
4304 | TRUSTED { $$ = make1_str("trusted"); }
4305 | TYPE_P { $$ = make1_str("type"); }
4306 | VALID { $$ = make1_str("valid"); }
4307 | VERSION { $$ = make1_str("version"); }
4308 | ZONE { $$ = make1_str("zone"); }
4309 | SQL_BOOL { $$ = make1_str("bool"); }
4310 | SQL_BREAK { $$ = make1_str("break"); }
4311 | SQL_CALL { $$ = make1_str("call"); }
4312 | SQL_CONNECT { $$ = make1_str("connect"); }
4313 | SQL_CONNECTION { $$ = make1_str("connection"); }
4314 | SQL_CONTINUE { $$ = make1_str("continue"); }
4315 | SQL_DEALLOCATE { $$ = make1_str("deallocate"); }
4316 | SQL_DISCONNECT { $$ = make1_str("disconnect"); }
4317 | SQL_FOUND { $$ = make1_str("found"); }
4318 | SQL_GO { $$ = make1_str("go"); }
4319 | SQL_GOTO { $$ = make1_str("goto"); }
4320 | SQL_IDENTIFIED { $$ = make1_str("identified"); }
4321 | SQL_IMMEDIATE { $$ = make1_str("immediate"); }
4322 | SQL_INDICATOR { $$ = make1_str("indicator"); }
4323 | SQL_INT { $$ = make1_str("int"); }
4324 | SQL_LONG { $$ = make1_str("long"); }
4325 | SQL_OPEN { $$ = make1_str("open"); }
4326 | SQL_PREPARE { $$ = make1_str("prepare"); }
4327 | SQL_RELEASE { $$ = make1_str("release"); }
4328 | SQL_SECTION { $$ = make1_str("section"); }
4329 | SQL_SHORT { $$ = make1_str("short"); }
4330 | SQL_SIGNED { $$ = make1_str("signed"); }
4331 | SQL_SQLERROR { $$ = make1_str("sqlerror"); }
4332 | SQL_SQLPRINT { $$ = make1_str("sqlprint"); }
4333 | SQL_SQLWARNING { $$ = make1_str("sqlwarning"); }
4334 | SQL_STOP { $$ = make1_str("stop"); }
4335 | SQL_STRUCT { $$ = make1_str("struct"); }
4336 | SQL_UNSIGNED { $$ = make1_str("unsigned"); }
4337 | SQL_VAR { $$ = make1_str("var"); }
4338 | SQL_WHENEVER { $$ = make1_str("whenever"); }
4341 * Allowed labels in "AS" clauses.
4342 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
4343 * compatibility. Cannot allow this for column names since the
4344 * syntax would not distinguish between the constant value and
4345 * a column name. - thomas 1997-10-24
4346 * Add other keywords to this list. Note that they appear here
4347 * rather than in ColId if there was a shift/reduce conflict
4348 * when used as a full identifier. - thomas 1997-11-06
4350 ColLabel: ColId { $$ = $1; }
4351 | ABORT_TRANS { $$ = make1_str("abort"); }
4352 | ANALYZE { $$ = make1_str("analyze"); }
4353 | BINARY { $$ = make1_str("binary"); }
4354 | CASE { $$ = make1_str("case"); }
4355 | CLUSTER { $$ = make1_str("cluster"); }
4356 | COALESCE { $$ = make1_str("coalesce"); }
4357 | CONSTRAINT { $$ = make1_str("constraint"); }
4358 | COPY { $$ = make1_str("copy"); }
4359 | CROSS { $$ = make1_str("cross"); }
4360 | CURRENT { $$ = make1_str("current"); }
4361 | DO { $$ = make1_str("do"); }
4362 | ELSE { $$ = make1_str("else"); }
4363 | END_TRANS { $$ = make1_str("end"); }
4364 | EXPLAIN { $$ = make1_str("explain"); }
4365 | EXTEND { $$ = make1_str("extend"); }
4366 | FALSE_P { $$ = make1_str("false"); }
4367 | FOREIGN { $$ = make1_str("foreign"); }
4368 | GROUP { $$ = make1_str("group"); }
4369 | LISTEN { $$ = make1_str("listen"); }
4370 | LOAD { $$ = make1_str("load"); }
4371 | LOCK_P { $$ = make1_str("lock"); }
4372 | MOVE { $$ = make1_str("move"); }
4373 | NEW { $$ = make1_str("new"); }
4374 | NONE { $$ = make1_str("none"); }
4375 | NULLIF { $$ = make1_str("nullif"); }
4376 | ORDER { $$ = make1_str("order"); }
4377 | POSITION { $$ = make1_str("position"); }
4378 | PRECISION { $$ = make1_str("precision"); }
4379 | RESET { $$ = make1_str("reset"); }
4380 | SETOF { $$ = make1_str("setof"); }
4381 | SHOW { $$ = make1_str("show"); }
4382 | TABLE { $$ = make1_str("table"); }
4383 | THEN { $$ = make1_str("then"); }
4384 | TRANSACTION { $$ = make1_str("transaction"); }
4385 | TRUE_P { $$ = make1_str("true"); }
4386 | VACUUM { $$ = make1_str("vacuum"); }
4387 | VERBOSE { $$ = make1_str("verbose"); }
4388 | WHEN { $$ = make1_str("when"); }
4391 SpecialRuleRelation: CURRENT
4394 $$ = make1_str("current");
4396 yyerror("CURRENT used in non-rule query");
4401 $$ = make1_str("new");
4403 yyerror("NEW used in non-rule query");
4408 * and now special embedded SQL stuff
4412 * the exec sql connect statement: connect to the given database
4414 ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
4416 $$ = make5_str($3, make1_str(","), $5, make1_str(","), $4);
4418 | SQL_CONNECT TO DEFAULT
4420 $$ = make1_str("NULL,NULL,NULL,\"DEFAULT\"");
4422 /* also allow ORACLE syntax */
4423 | SQL_CONNECT ora_user
4425 $$ = make3_str(make1_str("NULL,"), $2, make1_str(",NULL"));
4428 connection_target: database_name opt_server opt_port
4430 /* old style: dbname[@server][:port] */
4431 if (strlen($2) > 0 && *($2) != '@')
4433 sprintf(errortext, "parse error at or near '%s'", $2);
4437 $$ = make5_str(make1_str("\""), $1, $2, $3, make1_str("\""));
4439 | db_prefix server opt_port '/' database_name opt_options
4441 /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
4442 if (strncmp($2, "://", 3) != 0)
4444 sprintf(errortext, "parse error at or near '%s'", $2);
4448 if (strncmp($1, "unix", 4) == 0 && strncmp($2 + 3, "localhost", 9) != 0)
4450 sprintf(errortext, "unix domain sockets only work on 'localhost' but not on '%9.9s'", $2);
4454 if (strncmp($1, "unix", 4) != 0 && strncmp($1, "tcp", 3) != 0)
4456 sprintf(errortext, "only protocols 'tcp' and 'unix' are supported");
4460 $$ = make4_str(make5_str(make1_str("\""), $1, $2, $3, make1_str("/")), $5, $6, make1_str("\""));
4470 $$[strlen($$) - 1] = '\"';
4474 db_prefix: ident cvariable
4476 if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
4478 sprintf(errortext, "parse error at or near '%s'", $2);
4482 if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
4484 sprintf(errortext, "Illegal connection type %s", $1);
4488 $$ = make3_str($1, make1_str(":"), $2);
4491 server: Op server_name
4493 if (strcmp($1, "@") != 0 && strcmp($1, "://") != 0)
4495 sprintf(errortext, "parse error at or near '%s'", $1);
4499 $$ = make2_str($1, $2);
4502 opt_server: server { $$ = $1; }
4503 | /* empty */ { $$ = make1_str(""); }
4505 server_name: ColId { $$ = $1; }
4506 | ColId '.' server_name { $$ = make3_str($1, make1_str("."), $3); }
4508 opt_port: ':' Iconst { $$ = make2_str(make1_str(":"), $2); }
4509 | /* empty */ { $$ = make1_str(""); }
4511 opt_connection_name: AS connection_target { $$ = $2; }
4512 | /* empty */ { $$ = make1_str("NULL"); }
4514 opt_user: USER ora_user { $$ = $2; }
4515 | /* empty */ { $$ = make1_str("NULL,NULL"); }
4519 $$ = make2_str($1, make1_str(",NULL"));
4521 | user_name '/' ColId
4523 $$ = make3_str($1, make1_str(","), $3);
4525 | user_name SQL_IDENTIFIED BY user_name
4527 $$ = make3_str($1, make1_str(","), $4);
4529 | user_name USING user_name
4531 $$ = make3_str($1, make1_str(","), $3);
4534 user_name: UserId { if ($1[0] == '\"')
4537 $$ = make3_str(make1_str("\""), $1, make1_str("\""));
4539 | char_variable { $$ = $1; }
4540 | SCONST { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); }
4542 char_variable: cvariable
4543 { /* check if we have a char variable */
4544 struct variable *p = find_variable($1);
4545 enum ECPGttype typ = p->type->typ;
4547 /* if array see what's inside */
4548 if (typ == ECPGt_array)
4549 typ = p->type->u.element->typ;
4554 case ECPGt_unsigned_char:
4558 $$ = make2_str($1, make1_str(".arr"));
4561 yyerror("invalid datatype");
4566 opt_options: Op ColId
4568 if (strlen($1) == 0)
4569 yyerror("parse error");
4571 if (strcmp($1, "?") != 0)
4573 sprintf(errortext, "parse error at or near %s", $1);
4577 $$ = make2_str(make1_str("?"), $2);
4579 | /* empty */ { $$ = make1_str(""); }
4582 * Declare a prepared cursor. The syntax is different from the standard
4583 * declare statement, so we create a new rule.
4585 ECPGCursorStmt: DECLARE name opt_cursor CURSOR FOR ident cursor_clause
4587 struct cursor *ptr, *this;
4588 struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4590 for (ptr = cur; ptr != NULL; ptr = ptr->next)
4592 if (strcmp($2, ptr->name) == 0)
4594 /* re-definition is a bug */
4595 sprintf(errortext, "cursor %s already defined", $2);
4600 this = (struct cursor *) mm_alloc(sizeof(struct cursor));
4602 /* initial definition */
4605 this->command = cat5_str(make1_str("declare"), mm_strdup($2), $3, make1_str("cursor for ;;"), $7);
4606 this->argsresult = NULL;
4608 thisquery->type = &ecpg_query;
4609 thisquery->brace_level = 0;
4610 thisquery->next = NULL;
4611 thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($6));
4612 sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $6);
4614 this->argsinsert = NULL;
4615 add_variable(&(this->argsinsert), thisquery, &no_indicator);
4619 $$ = cat3_str(make1_str("/*"), mm_strdup(this->command), make1_str("*/"));
4624 * the exec sql deallocate prepare command to deallocate a previously
4625 * prepared statement
4627 ECPGDeallocate: SQL_DEALLOCATE SQL_PREPARE ident { $$ = make3_str(make1_str("ECPGdeallocate(__LINE__, \""), $3, make1_str("\");")); }
4630 * variable declaration inside the exec sql declare block
4632 ECPGDeclaration: sql_startdeclare
4634 fputs("/* exec sql begin declare section */", yyout);
4635 output_line_number();
4637 variable_declarations sql_enddeclare
4639 fprintf(yyout, "%s/* exec sql end declare section */", $3);
4641 output_line_number();
4644 sql_startdeclare : ecpgstart BEGIN_TRANS DECLARE SQL_SECTION SQL_SEMI {}
4646 sql_enddeclare: ecpgstart END_TRANS DECLARE SQL_SECTION SQL_SEMI {}
4648 variable_declarations: /* empty */
4652 | declaration variable_declarations
4654 $$ = cat2_str($1, $2);
4657 declaration: storage_clause
4659 actual_storage[struct_level] = mm_strdup($1);
4663 actual_type[struct_level].type_enum = $3.type_enum;
4664 actual_type[struct_level].type_dimension = $3.type_dimension;
4665 actual_type[struct_level].type_index = $3.type_index;
4669 $$ = cat4_str($1, $3.type_str, $5, make1_str(";\n"));
4672 storage_clause : S_EXTERN { $$ = make1_str("extern"); }
4673 | S_STATIC { $$ = make1_str("static"); }
4674 | S_SIGNED { $$ = make1_str("signed"); }
4675 | S_CONST { $$ = make1_str("const"); }
4676 | S_REGISTER { $$ = make1_str("register"); }
4677 | S_AUTO { $$ = make1_str("auto"); }
4678 | /* empty */ { $$ = make1_str(""); }
4683 $$.type_str = mm_strdup(ECPGtype_name($1));
4684 $$.type_dimension = -1;
4689 $$.type_enum = ECPGt_varchar;
4690 $$.type_str = make1_str("");
4691 $$.type_dimension = -1;
4696 $$.type_enum = ECPGt_struct;
4698 $$.type_dimension = -1;
4704 $$.type_enum = ECPGt_int;
4705 $$.type_dimension = -1;
4710 /* this is for typedef'ed types */
4711 struct typedefs *this = get_typedef($1);
4713 $$.type_str = mm_strdup(this->name);
4714 $$.type_enum = this->type->type_enum;
4715 $$.type_dimension = this->type->type_dimension;
4716 $$.type_index = this->type->type_index;
4717 struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
4720 enum_type: s_enum '{' c_line '}'
4722 $$ = cat4_str($1, make1_str("{"), $3, make1_str("}"));
4725 s_enum: S_ENUM opt_symbol { $$ = cat2_str(make1_str("enum"), $2); }
4727 struct_type: s_struct '{' variable_declarations '}'
4729 ECPGfree_struct_member(struct_member_list[struct_level]);
4730 free(actual_storage[struct_level--]);
4731 $$ = cat4_str($1, make1_str("{"), $3, make1_str("}"));
4734 s_struct : S_STRUCT opt_symbol
4736 struct_member_list[struct_level++] = NULL;
4737 if (struct_level >= STRUCT_DEPTH)
4738 yyerror("Too many levels in nested structure definition");
4739 $$ = cat2_str(make1_str("struct"), $2);
4742 opt_symbol: /* empty */ { $$ = make1_str(""); }
4743 | symbol { $$ = $1; }
4745 simple_type: S_SHORT { $$ = ECPGt_short; }
4746 | S_UNSIGNED S_SHORT { $$ = ECPGt_unsigned_short; }
4747 | S_INT { $$ = ECPGt_int; }
4748 | S_UNSIGNED S_INT { $$ = ECPGt_unsigned_int; }
4749 | S_LONG { $$ = ECPGt_long; }
4750 | S_UNSIGNED S_LONG { $$ = ECPGt_unsigned_long; }
4751 | S_FLOAT { $$ = ECPGt_float; }
4752 | S_DOUBLE { $$ = ECPGt_double; }
4753 | S_BOOL { $$ = ECPGt_bool; };
4754 | S_CHAR { $$ = ECPGt_char; }
4755 | S_UNSIGNED S_CHAR { $$ = ECPGt_unsigned_char; }
4757 varchar_type: S_VARCHAR { $$ = ECPGt_varchar; }
4759 variable_list: variable
4763 | variable_list ',' variable
4765 $$ = cat3_str($1, make1_str(","), $3);
4768 variable: opt_pointer symbol opt_array_bounds opt_initializer
4770 struct ECPGtype * type;
4771 int dimension = $3.index1; /* dimension of array */
4772 int length = $3.index2; /* lenght of string */
4773 char dim[14L], ascii_len[12];
4775 adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
4777 switch (actual_type[struct_level].type_enum)
4781 type = ECPGmake_struct_type(struct_member_list[struct_level]);
4783 type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level]), dimension);
4785 $$ = make4_str($1, mm_strdup($2), $3.str, $4);
4788 if (dimension == -1)
4789 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
4791 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
4803 sprintf(dim, "[%d]", dimension);
4806 sprintf(ascii_len, "%d", length);
4809 $$ = make4_str(make5_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2), make1_str(" { int len; char arr["), mm_strdup(ascii_len)), make1_str("]; } "), mm_strdup($2), mm_strdup(dim));
4811 $$ = make4_str(make3_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2)), make1_str(" { int len; char *arr; } "), mm_strdup($2), mm_strdup(dim));
4814 case ECPGt_unsigned_char:
4815 if (dimension == -1)
4816 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
4818 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
4820 $$ = make4_str($1, mm_strdup($2), $3.str, $4);
4824 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1);
4826 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, 1), dimension);
4828 $$ = make4_str($1, mm_strdup($2), $3.str, $4);
4832 if (struct_level == 0)
4833 new_variable($2, type);
4835 ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
4840 opt_initializer: /* empty */ { $$ = make1_str(""); }
4841 | '=' vartext { $$ = make2_str(make1_str("="), $2); }
4843 opt_pointer: /* empty */ { $$ = make1_str(""); }
4844 | '*' { $$ = make1_str("*"); }
4847 * As long as the prepare statement is not supported by the backend, we will
4848 * try to simulate it here so we get dynamic SQL
4850 ECPGDeclare: DECLARE STATEMENT ident
4852 /* this is only supported for compatibility */
4853 $$ = cat3_str(make1_str("/* declare statement"), $3, make1_str("*/"));
4856 * the exec sql disconnect statement: disconnect from the given database
4858 ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
4860 dis_name: connection_object { $$ = $1; }
4861 | CURRENT { $$ = make1_str("CURRENT"); }
4862 | ALL { $$ = make1_str("ALL"); }
4863 | /* empty */ { $$ = make1_str("CURRENT"); }
4865 connection_object: connection_target { $$ = $1; }
4866 | DEFAULT { $$ = make1_str("DEFAULT"); }
4869 * execute a given string as sql command
4871 ECPGExecute : EXECUTE SQL_IMMEDIATE execstring
4873 struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4875 thisquery->type = &ecpg_query;
4876 thisquery->brace_level = 0;
4877 thisquery->next = NULL;
4878 thisquery->name = $3;
4880 add_variable(&argsinsert, thisquery, &no_indicator);
4882 $$ = make1_str(";;");
4886 struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
4888 thisquery->type = &ecpg_query;
4889 thisquery->brace_level = 0;
4890 thisquery->next = NULL;
4891 thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($2));
4892 sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2);
4894 add_variable(&argsinsert, thisquery, &no_indicator);
4897 $$ = make1_str(";;");
4900 execstring: char_variable |
4901 CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); };
4904 * the exec sql free command to deallocate a previously
4905 * prepared statement
4907 ECPGFree: SQL_FREE ident { $$ = $2; }
4910 * open is an open cursor, at the moment this has to be removed
4912 ECPGOpen: SQL_OPEN name opt_using {
4916 opt_using: /* empty */ { $$ = make1_str(""); }
4917 | USING variablelist {
4918 /* yyerror ("open cursor with variables not implemented yet"); */
4922 variablelist: cinputvariable | cinputvariable ',' variablelist
4925 * As long as the prepare statement is not supported by the backend, we will
4926 * try to simulate it here so we get dynamic SQL
4928 ECPGPrepare: SQL_PREPARE ident FROM char_variable
4930 $$ = make4_str(make1_str("\""), $2, make1_str("\", "), $4);
4934 * for compatibility with ORACLE we will also allow the keyword RELEASE
4935 * after a transaction statement to disconnect from the database.
4938 ECPGRelease: TransactionStmt SQL_RELEASE
4940 if (strncmp($1, "begin", 5) == 0)
4941 yyerror("RELEASE does not make sense when beginning a transaction");
4943 fprintf(yyout, "ECPGtrans(__LINE__, \"%s\");", $1);
4945 fprintf(yyout, "ECPGdisconnect(\"\");");
4951 * set the actual connection, this needs a differnet handling as the other
4954 ECPGSetConnection: SET SQL_CONNECTION connection_object
4960 * define a new type for embedded SQL
4962 ECPGTypedef: TYPE_P symbol IS ctype opt_type_array_bounds opt_reference
4964 /* add entry to list */
4965 struct typedefs *ptr, *this;
4966 int dimension = $5.index1;
4967 int length = $5.index2;
4969 for (ptr = types; ptr != NULL; ptr = ptr->next)
4971 if (strcmp($2, ptr->name) == 0)
4973 /* re-definition is a bug */
4974 sprintf(errortext, "type %s already defined", $2);
4979 adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, strlen($6));
4981 this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
4983 /* initial definition */
4986 this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
4987 this->type->type_enum = $4.type_enum;
4988 this->type->type_str = mm_strdup($2);
4989 this->type->type_dimension = dimension; /* dimension of array */
4990 this->type->type_index = length; /* lenght of string */
4991 this->struct_member_list = struct_member_list[struct_level];
4993 if ($4.type_enum != ECPGt_varchar &&
4994 $4.type_enum != ECPGt_char &&
4995 $4.type_enum != ECPGt_unsigned_char &&
4996 this->type->type_index >= 0)
4997 yyerror("No multi-dimensional array support for simple data types");
5001 $$ = cat5_str(cat3_str(make1_str("/* exec sql type"), mm_strdup($2), make1_str("is")), mm_strdup($4.type_str), mm_strdup($5.str), $6, make1_str("*/"));
5004 opt_type_array_bounds: '[' ']' nest_type_array_bounds
5007 $$.index2 = $3.index1;
5008 $$.str = cat2_str(make1_str("[]"), $3.str);
5010 | '(' ')' nest_type_array_bounds
5013 $$.index2 = $3.index1;
5014 $$.str = cat2_str(make1_str("[]"), $3.str);
5016 | '[' Iconst ']' nest_type_array_bounds
5018 $$.index1 = atol($2);
5019 $$.index2 = $4.index1;
5020 $$.str = cat4_str(make1_str("["), $2, make1_str("]"), $4.str);
5022 | '(' Iconst ')' nest_type_array_bounds
5024 $$.index1 = atol($2);
5025 $$.index2 = $4.index1;
5026 $$.str = cat4_str(make1_str("["), $2, make1_str("]"), $4.str);
5032 $$.str= make1_str("");
5036 nest_type_array_bounds: '[' ']' nest_type_array_bounds
5039 $$.index2 = $3.index1;
5040 $$.str = cat2_str(make1_str("[]"), $3.str);
5042 | '(' ')' nest_type_array_bounds
5045 $$.index2 = $3.index1;
5046 $$.str = cat2_str(make1_str("[]"), $3.str);
5048 | '[' Iconst ']' nest_type_array_bounds
5050 $$.index1 = atol($2);
5051 $$.index2 = $4.index1;
5052 $$.str = cat4_str(make1_str("["), $2, make1_str("]"), $4.str);
5054 | '(' Iconst ')' nest_type_array_bounds
5056 $$.index1 = atol($2);
5057 $$.index2 = $4.index1;
5058 $$.str = cat4_str(make1_str("["), $2, make1_str("]"), $4.str);
5064 $$.str= make1_str("");
5067 opt_reference: SQL_REFERENCE { $$ = make1_str("reference"); }
5068 | /* empty */ { $$ = make1_str(""); }
5072 $$.type_str = make1_str("char");
5073 $$.type_enum = ECPGt_char;
5075 $$.type_dimension = -1;
5079 $$.type_str = make1_str("varchar");
5080 $$.type_enum = ECPGt_varchar;
5082 $$.type_dimension = -1;
5086 $$.type_str = make1_str("float");
5087 $$.type_enum = ECPGt_float;
5089 $$.type_dimension = -1;
5093 $$.type_str = make1_str("double");
5094 $$.type_enum = ECPGt_double;
5096 $$.type_dimension = -1;
5098 | opt_signed SQL_INT
5100 $$.type_str = make1_str("int");
5101 $$.type_enum = ECPGt_int;
5103 $$.type_dimension = -1;
5107 $$.type_str = make1_str("int");
5108 $$.type_enum = ECPGt_int;
5110 $$.type_dimension = -1;
5112 | opt_signed SQL_SHORT
5114 $$.type_str = make1_str("short");
5115 $$.type_enum = ECPGt_short;
5117 $$.type_dimension = -1;
5119 | opt_signed SQL_LONG
5121 $$.type_str = make1_str("long");
5122 $$.type_enum = ECPGt_long;
5124 $$.type_dimension = -1;
5128 $$.type_str = make1_str("bool");
5129 $$.type_enum = ECPGt_bool;
5131 $$.type_dimension = -1;
5133 | SQL_UNSIGNED SQL_INT
5135 $$.type_str = make1_str("unsigned int");
5136 $$.type_enum = ECPGt_unsigned_int;
5138 $$.type_dimension = -1;
5140 | SQL_UNSIGNED SQL_SHORT
5142 $$.type_str = make1_str("unsigned short");
5143 $$.type_enum = ECPGt_unsigned_short;
5145 $$.type_dimension = -1;
5147 | SQL_UNSIGNED SQL_LONG
5149 $$.type_str = make1_str("unsigned long");
5150 $$.type_enum = ECPGt_unsigned_long;
5152 $$.type_dimension = -1;
5156 struct_member_list[struct_level++] = NULL;
5157 if (struct_level >= STRUCT_DEPTH)
5158 yyerror("Too many levels in nested structure definition");
5159 } '{' sql_variable_declarations '}'
5161 ECPGfree_struct_member(struct_member_list[struct_level--]);
5162 $$.type_str = cat3_str(make1_str("struct {"), $4, make1_str("}"));
5163 $$.type_enum = ECPGt_struct;
5165 $$.type_dimension = -1;
5169 struct typedefs *this = get_typedef($1);
5171 $$.type_str = mm_strdup($1);
5172 $$.type_enum = this->type->type_enum;
5173 $$.type_dimension = this->type->type_dimension;
5174 $$.type_index = this->type->type_index;
5175 struct_member_list[struct_level] = this->struct_member_list;
5178 opt_signed: SQL_SIGNED | /* empty */
5180 sql_variable_declarations: /* empty */
5184 | sql_declaration sql_variable_declarations
5186 $$ = cat2_str($1, $2);
5190 sql_declaration: ctype
5192 actual_type[struct_level].type_enum = $1.type_enum;
5193 actual_type[struct_level].type_dimension = $1.type_dimension;
5194 actual_type[struct_level].type_index = $1.type_index;
5196 sql_variable_list SQL_SEMI
5198 $$ = cat3_str($1.type_str, $3, make1_str(";"));
5201 sql_variable_list: sql_variable
5205 | sql_variable_list ',' sql_variable
5207 $$ = make3_str($1, make1_str(","), $3);
5210 sql_variable: opt_pointer symbol opt_array_bounds
5212 int dimension = $3.index1;
5213 int length = $3.index2;
5214 struct ECPGtype * type;
5217 adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
5219 switch (actual_type[struct_level].type_enum)
5223 type = ECPGmake_struct_type(struct_member_list[struct_level]);
5225 type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level]), dimension);
5229 if (dimension == -1)
5230 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
5232 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
5244 sprintf(dim, "[%d]", dimension);
5250 case ECPGt_unsigned_char:
5251 if (dimension == -1)
5252 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
5254 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
5259 yyerror("No multi-dimensional array support for simple data types");
5262 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1);
5264 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, 1), dimension);
5269 if (struct_level == 0)
5270 new_variable($2, type);
5272 ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
5274 $$ = cat3_str($1, $2, $3.str);
5278 * define the type of one variable for embedded SQL
5280 ECPGVar: SQL_VAR symbol IS ctype opt_type_array_bounds opt_reference
5282 struct variable *p = find_variable($2);
5283 int dimension = $5.index1;
5284 int length = $5.index2;
5285 struct ECPGtype * type;
5287 adjust_array($4.type_enum, &dimension, &length, $4.type_dimension, $4.type_index, strlen($6));
5289 switch ($4.type_enum)
5293 type = ECPGmake_struct_type(struct_member_list[struct_level]);
5295 type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level]), dimension);
5298 if (dimension == -1)
5299 type = ECPGmake_simple_type($4.type_enum, length);
5301 type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, length), dimension);
5305 case ECPGt_unsigned_char:
5306 if (dimension == -1)
5307 type = ECPGmake_simple_type($4.type_enum, length);
5309 type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, length), dimension);
5314 yyerror("No multi-dimensional array support for simple data types");
5317 type = ECPGmake_simple_type($4.type_enum, 1);
5319 type = ECPGmake_array_type(ECPGmake_simple_type($4.type_enum, 1), dimension);
5324 ECPGfree_type(p->type);
5327 $$ = cat5_str(cat3_str(make1_str("/* exec sql var"), mm_strdup($2), make1_str("is")), mm_strdup($4.type_str), mm_strdup($5.str), $6, make1_str("*/"));
5331 * whenever statement: decide what to do in case of error/no data found
5332 * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
5334 ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action {
5335 when_error.code = $<action>3.code;
5336 when_error.command = $<action>3.command;
5337 $$ = cat3_str(make1_str("/* exec sql whenever sqlerror "), $3.str, make1_str("; */\n"));
5339 | SQL_WHENEVER NOT SQL_FOUND action {
5340 when_nf.code = $<action>4.code;
5341 when_nf.command = $<action>4.command;
5342 $$ = cat3_str(make1_str("/* exec sql whenever not found "), $4.str, make1_str("; */\n"));
5344 | SQL_WHENEVER SQL_SQLWARNING action {
5345 when_warn.code = $<action>3.code;
5346 when_warn.command = $<action>3.command;
5347 $$ = cat3_str(make1_str("/* exec sql whenever sql_warning "), $3.str, make1_str("; */\n"));
5350 action : SQL_CONTINUE {
5351 $<action>$.code = W_NOTHING;
5352 $<action>$.command = NULL;
5353 $<action>$.str = make1_str("continue");
5356 $<action>$.code = W_SQLPRINT;
5357 $<action>$.command = NULL;
5358 $<action>$.str = make1_str("sqlprint");
5361 $<action>$.code = W_STOP;
5362 $<action>$.command = NULL;
5363 $<action>$.str = make1_str("stop");
5366 $<action>$.code = W_GOTO;
5367 $<action>$.command = strdup($2);
5368 $<action>$.str = cat2_str(make1_str("goto "), $2);
5371 $<action>$.code = W_GOTO;
5372 $<action>$.command = strdup($3);
5373 $<action>$.str = cat2_str(make1_str("goto "), $3);
5375 | DO name '(' dotext ')' {
5376 $<action>$.code = W_DO;
5377 $<action>$.command = make4_str($2, make1_str("("), $4, make1_str(")"));
5378 $<action>$.str = cat2_str(make1_str("do"), mm_strdup($<action>$.command));
5381 $<action>$.code = W_BREAK;
5382 $<action>$.command = NULL;
5383 $<action>$.str = make1_str("break");
5385 | SQL_CALL name '(' dotext ')' {
5386 $<action>$.code = W_DO;
5387 $<action>$.command = make4_str($2, make1_str("("), $4, make1_str(")"));
5388 $<action>$.str = cat2_str(make1_str("call"), mm_strdup($<action>$.command));
5391 /* some other stuff for ecpg */
5392 ecpg_expr: attr opt_indirection
5394 $$ = cat2_str($1, $2);
5404 | '-' ecpg_expr %prec UMINUS
5405 { $$ = cat2_str(make1_str("-"), $2); }
5406 | a_expr '+' ecpg_expr
5407 { $$ = cat3_str($1, make1_str("+"), $3); }
5408 | a_expr '-' ecpg_expr
5409 { $$ = cat3_str($1, make1_str("-"), $3); }
5410 | a_expr '/' ecpg_expr
5411 { $$ = cat3_str($1, make1_str("/"), $3); }
5412 | a_expr '*' ecpg_expr
5413 { $$ = cat3_str($1, make1_str("*"), $3); }
5414 | a_expr '<' ecpg_expr
5415 { $$ = cat3_str($1, make1_str("<"), $3); }
5416 | a_expr '>' ecpg_expr
5417 { $$ = cat3_str($1, make1_str(">"), $3); }
5418 | a_expr '=' ecpg_expr
5419 { $$ = cat3_str($1, make1_str("="), $3); }
5421 { $$ = cat2_str(make1_str(":"), $2); }*/
5423 { $$ = cat2_str(make1_str(";"), $2); }
5425 { $$ = cat2_str(make1_str("|"), $2); }
5426 | a_expr TYPECAST Typename
5428 $$ = cat3_str($1, make1_str("::"), $3);
5430 | CAST '(' a_expr AS Typename ')'
5432 $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
5434 | '(' a_expr_or_null ')'
5435 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
5436 | a_expr Op ecpg_expr
5437 { $$ = cat3_str($1, $2, $3); }
5438 | a_expr LIKE ecpg_expr
5439 { $$ = cat3_str($1, make1_str("like"), $3); }
5440 | a_expr NOT LIKE ecpg_expr
5441 { $$ = cat3_str($1, make1_str("not like"), $4); }
5443 { $$ = cat2_str($1, $2); }
5445 { $$ = cat2_str($1, $2); }
5446 | func_name '(' '*' ')'
5448 $$ = cat2_str($1, make1_str("(*)"));
5452 $$ = cat2_str($1, make1_str("()"));
5454 | func_name '(' expr_list ')'
5456 $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
5460 $$ = make1_str("current_date");
5464 $$ = make1_str("current_time");
5466 | CURRENT_TIME '(' Iconst ')'
5469 fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
5470 $$ = make1_str("current_time");
5474 $$ = make1_str("current_timestamp");
5476 | CURRENT_TIMESTAMP '(' Iconst ')'
5479 fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
5480 $$ = make1_str("current_timestamp");
5484 $$ = make1_str("current_user");
5486 | EXISTS '(' SubSelect ')'
5488 $$ = make3_str(make1_str("exists("), $3, make1_str(")"));
5490 | EXTRACT '(' extract_list ')'
5492 $$ = make3_str(make1_str("extract("), $3, make1_str(")"));
5494 | POSITION '(' position_list ')'
5496 $$ = make3_str(make1_str("position("), $3, make1_str(")"));
5498 | SUBSTRING '(' substr_list ')'
5500 $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
5502 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
5503 | TRIM '(' BOTH trim_list ')'
5505 $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
5507 | TRIM '(' LEADING trim_list ')'
5509 $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
5511 | TRIM '(' TRAILING trim_list ')'
5513 $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
5515 | TRIM '(' trim_list ')'
5517 $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
5520 { $$ = cat2_str($1, make1_str("isnull")); }
5522 { $$ = cat2_str($1, make1_str("is null")); }
5524 { $$ = cat2_str($1, make1_str("notnull")); }
5525 | a_expr IS NOT NULL_P
5526 { $$ = cat2_str($1, make1_str("is not null")); }
5527 /* IS TRUE, IS FALSE, etc used to be function calls
5528 * but let's make them expressions to allow the optimizer
5529 * a chance to eliminate them if a_expr is a constant string.
5530 * - thomas 1997-12-22
5534 { $$ = cat2_str($1, make1_str("is true")); }
5536 | a_expr IS NOT FALSE_P
5538 { $$ = cat2_str($1, make1_str("is not false")); }
5542 { $$ = cat2_str($1, make1_str("is false")); }
5544 | a_expr IS NOT TRUE_P
5546 { $$ = cat2_str($1, make1_str("is not true")); }
5548 | a_expr BETWEEN b_expr AND b_expr
5550 $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5);
5552 | a_expr NOT BETWEEN b_expr AND b_expr
5554 $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6);
5556 | a_expr IN '(' in_expr ')'
5558 $$ = make4_str($1, make1_str("in ("), $4, make1_str(")"));
5560 | a_expr NOT IN '(' not_in_expr ')'
5562 $$ = make4_str($1, make1_str("not in ("), $5, make1_str(")"));
5564 | a_expr Op '(' SubSelect ')'
5566 $$ = cat3_str($1, $2, make3_str(make1_str("("), $4, make1_str(")")));
5568 | a_expr '+' '(' SubSelect ')'
5570 $$ = make4_str($1, make1_str("+("), $4, make1_str(")"));
5572 | a_expr '-' '(' SubSelect ')'
5574 $$ = make4_str($1, make1_str("-("), $4, make1_str(")"));
5576 | a_expr '/' '(' SubSelect ')'
5578 $$ = make4_str($1, make1_str("/("), $4, make1_str(")"));
5580 | a_expr '*' '(' SubSelect ')'
5582 $$ = make4_str($1, make1_str("*("), $4, make1_str(")"));
5584 | a_expr '<' '(' SubSelect ')'
5586 $$ = make4_str($1, make1_str("<("), $4, make1_str(")"));
5588 | a_expr '>' '(' SubSelect ')'
5590 $$ = make4_str($1, make1_str(">("), $4, make1_str(")"));
5592 | a_expr '=' '(' SubSelect ')'
5594 $$ = make4_str($1, make1_str("=("), $4, make1_str(")"));
5596 | a_expr Op ANY '(' SubSelect ')'
5598 $$ = cat3_str($1, $2, make3_str(make1_str("any ("), $5, make1_str(")")));
5600 | a_expr '+' ANY '(' SubSelect ')'
5602 $$ = make4_str($1, make1_str("+any("), $5, make1_str(")"));
5604 | a_expr '-' ANY '(' SubSelect ')'
5606 $$ = make4_str($1, make1_str("-any("), $5, make1_str(")"));
5608 | a_expr '/' ANY '(' SubSelect ')'
5610 $$ = make4_str($1, make1_str("/any("), $5, make1_str(")"));
5612 | a_expr '*' ANY '(' SubSelect ')'
5614 $$ = make4_str($1, make1_str("*any("), $5, make1_str(")"));
5616 | a_expr '<' ANY '(' SubSelect ')'
5618 $$ = make4_str($1, make1_str("<any("), $5, make1_str(")"));
5620 | a_expr '>' ANY '(' SubSelect ')'
5622 $$ = make4_str($1, make1_str(">any("), $5, make1_str(")"));
5624 | a_expr '=' ANY '(' SubSelect ')'
5626 $$ = make4_str($1, make1_str("=any("), $5, make1_str(")"));
5628 | a_expr Op ALL '(' SubSelect ')'
5630 $$ = make3_str($1, $2, make3_str(make1_str("all ("), $5, make1_str(")")));
5632 | a_expr '+' ALL '(' SubSelect ')'
5634 $$ = make4_str($1, make1_str("+all("), $5, make1_str(")"));
5636 | a_expr '-' ALL '(' SubSelect ')'
5638 $$ = make4_str($1, make1_str("-all("), $5, make1_str(")"));
5640 | a_expr '/' ALL '(' SubSelect ')'
5642 $$ = make4_str($1, make1_str("/all("), $5, make1_str(")"));
5644 | a_expr '*' ALL '(' SubSelect ')'
5646 $$ = make4_str($1, make1_str("*all("), $5, make1_str(")"));
5648 | a_expr '<' ALL '(' SubSelect ')'
5650 $$ = make4_str($1, make1_str("<all("), $5, make1_str(")"));
5652 | a_expr '>' ALL '(' SubSelect ')'
5654 $$ = make4_str($1, make1_str(">all("), $5, make1_str(")"));
5656 | a_expr '=' ALL '(' SubSelect ')'
5658 $$ = make4_str($1, make1_str("=all("), $5, make1_str(")"));
5660 | a_expr AND ecpg_expr
5661 { $$ = cat3_str($1, make1_str("and"), $3); }
5662 | a_expr OR ecpg_expr
5663 { $$ = cat3_str($1, make1_str("or"), $3); }
5665 { $$ = cat2_str(make1_str("not"), $2); }
5670 into_list : coutputvariable | into_list ',' coutputvariable;
5672 ecpgstart: SQL_START { reset_variables();}
5674 dotext: /* empty */ { $$ = make1_str(""); }
5675 | dotext do_anything { $$ = make2_str($1, $2); }
5677 vartext: var_anything { $$ = $1; }
5678 | vartext var_anything { $$ = make2_str($1, $2); }
5680 coutputvariable : cvariable indicator {
5681 add_variable(&argsresult, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
5684 cinputvariable : cvariable indicator {
5685 add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
5688 civariableonly : cvariable {
5689 add_variable(&argsinsert, find_variable($1), &no_indicator);
5690 $$ = make1_str(";;");
5693 cvariable: CVARIABLE { $$ = $1; }
5695 indicator: /* empty */ { $$ = NULL; }
5696 | cvariable { check_indicator((find_variable($1))->type); $$ = $1; }
5697 | SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; }
5698 | SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
5700 ident: IDENT { $$ = $1; }
5701 | CSTRING { $$ = $1; }
5706 symbol: IDENT { $$ = $1; }
5708 cpp_line: CPP_LINE { $$ = $1; }
5710 c_line: c_anything { $$ = $1; }
5713 $$ = make2_str($1, $2);
5716 c_thing: c_anything | ';' { $$ = make1_str(";"); }
5718 c_anything: IDENT { $$ = $1; }
5719 | CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); }
5720 | Iconst { $$ = $1; }
5721 | Fconst { $$ = $1; }
5722 | '*' { $$ = make1_str("*"); }
5723 | S_AUTO { $$ = make1_str("auto"); }
5724 | S_BOOL { $$ = make1_str("bool"); }
5725 | S_CHAR { $$ = make1_str("char"); }
5726 | S_CONST { $$ = make1_str("const"); }
5727 | S_DOUBLE { $$ = make1_str("double"); }
5728 | S_ENUM { $$ = make1_str("enum"); }
5729 | S_EXTERN { $$ = make1_str("extern"); }
5730 | S_FLOAT { $$ = make1_str("float"); }
5731 | S_INT { $$ = make1_str("int"); }
5732 | S_LONG { $$ = make1_str("long"); }
5733 | S_REGISTER { $$ = make1_str("register"); }
5734 | S_SHORT { $$ = make1_str("short"); }
5735 | S_SIGNED { $$ = make1_str("signed"); }
5736 | S_STATIC { $$ = make1_str("static"); }
5737 | S_STRUCT { $$ = make1_str("struct"); }
5738 | S_UNSIGNED { $$ = make1_str("unsigned"); }
5739 | S_VARCHAR { $$ = make1_str("varchar"); }
5740 | S_ANYTHING { $$ = make_name(); }
5741 | '[' { $$ = make1_str("["); }
5742 | ']' { $$ = make1_str("]"); }
5743 | '(' { $$ = make1_str("("); }
5744 | ')' { $$ = make1_str(")"); }
5745 | '=' { $$ = make1_str("="); }
5746 | ',' { $$ = make1_str(","); }
5748 do_anything: IDENT { $$ = $1; }
5749 | CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\""));}
5750 | Iconst { $$ = $1; }
5751 | Fconst { $$ = $1; }
5752 | ',' { $$ = make1_str(","); }
5754 var_anything: IDENT { $$ = $1; }
5755 | CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); }
5756 | Iconst { $$ = $1; }
5757 | Fconst { $$ = $1; }
5758 | '{' c_line '}' { $$ = make3_str(make1_str("{"), $2, make1_str("}")); }
5762 $$ = make1_str("{");
5766 remove_variables(braces_open--);
5767 $$ = make1_str("}");
5772 void yyerror(char * error)
5774 fprintf(stderr, "%s:%d: %s\n", input_filename, yylineno, error);