1 /* Copyright comment */
6 #include "catalog/catname.h"
12 #include "mb/pg_wchar.h"
15 #define STRUCT_DEPTH 128
18 * Variables containing simple states.
20 static int struct_level = 0;
21 static char errortext[128];
22 static int QueryIsRule = 0;
23 static enum ECPGttype 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};
33 * Handle the filename and line numbering.
35 char * input_filename = NULL;
41 fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename);
45 * store the whenever action here
47 static struct when when_error, when_nf;
50 print_action(struct when *w)
54 case W_SQLPRINT: fprintf(yyout, "sqlprint();");
56 case W_GOTO: fprintf(yyout, "goto %s;", w->command);
58 case W_DO: fprintf(yyout, "%s;", w->command);
60 case W_STOP: fprintf(yyout, "exit (1);");
62 case W_BREAK: fprintf(yyout, "break;");
64 default: fprintf(yyout, "{/* %d not implemented yet */}", w->code);
70 whenever_action(int mode)
72 if (mode == 1 && when_nf.code != W_NOTHING)
75 fprintf(yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
76 print_action(&when_nf);
78 if (when_error.code != W_NOTHING)
81 fprintf(yyout, "\nif (sqlca.sqlcode < 0) ");
82 print_action(&when_error);
88 * Handling of variables.
96 static struct variable * allvariables = NULL;
98 static struct variable *
99 new_variable(const char * name, struct ECPGtype * type)
101 struct variable * p = (struct variable*) mm_alloc(sizeof(struct variable));
103 p->name = mm_strdup(name);
105 p->brace_level = braces_open;
107 p->next = allvariables;
113 static struct variable * find_variable(char * name);
115 static struct variable *
116 find_struct_member(char *name, char *str, struct ECPGstruct_member *members)
118 char *next = strchr(++str, '.'), c = '\0';
126 for (; members; members = members->next)
128 if (strcmp(members->name, str) == 0)
133 switch (members->typ->typ)
136 return(new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size)));
138 return(new_variable(name, ECPGmake_struct_type(members->typ->u.members)));
140 return(new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
149 return(find_struct_member(name, next, members->typ->u.element->u.members));
151 else return(find_struct_member(name, next, members->typ->u.members));
159 static struct variable *
160 find_struct(char * name, char *next)
165 /* first get the mother structure entry */
167 p = find_variable(name);
169 /* restore the name, we will need it later on */
174 return find_struct_member(name, next, p->type->u.element->u.members);
176 else return find_struct_member(name, next, p->type->u.members);
179 static struct variable *
180 find_simple(char * name)
184 for (p = allvariables; p; p = p->next)
186 if (strcmp(p->name, name) == 0)
193 /* Note that this function will end the program in case of an unknown */
195 static struct variable *
196 find_variable(char * name)
201 if ((next = strchr(name, '.')) != NULL)
202 p = find_struct(name, next);
203 else if ((next = strstr(name, "->")) != NULL)
204 p = find_struct(name, next);
206 p = find_simple(name);
210 sprintf(errortext, "The variable %s is not declared", name);
218 remove_variables(int brace_level)
220 struct variable * p, *prev;
222 for (p = prev = allvariables; p; p = p ? p->next : NULL)
224 if (p->brace_level >= brace_level)
227 if (p == allvariables)
228 prev = allvariables = p->next;
230 prev->next = p->next;
232 ECPGfree_type(p->type);
244 * Here are the variables that need to be handled on every request.
245 * These are of two kinds: input and output.
246 * I will make two lists for them.
249 struct arguments * argsinsert = NULL;
250 struct arguments * argsresult = NULL;
253 reset_variables(void)
260 /* Add a variable to a request. */
262 add_variable(struct arguments ** list, struct variable * var, struct variable * ind)
264 struct arguments * p = (struct arguments *)mm_alloc(sizeof(struct arguments));
272 /* Dump out a list of all the variable on this list.
273 This is a recursive function that works from the end of the list and
274 deletes the list as we go on.
277 dump_variables(struct arguments * list, int mode)
284 /* The list is build up from the beginning so lets first dump the
288 dump_variables(list->next, mode);
290 /* Then the current element and its indicator */
291 ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
292 (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->name : NULL,
293 (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->type : NULL, NULL, NULL);
295 /* Then release the list element. */
301 check_indicator(struct ECPGtype *var)
303 /* make sure this is a valid indicator variable */
306 struct ECPGstruct_member *p;
311 case ECPGt_unsigned_short:
312 case ECPGt_unsigned_int:
313 case ECPGt_unsigned_long:
317 for (p = var->u.members; p; p = p->next)
318 check_indicator(p->typ);
322 check_indicator(var->u.element);
325 yyerror ("indicator variable must be integer type");
331 make1_str(const char *str)
333 char * res_str = (char *)mm_alloc(strlen(str) + 1);
335 strcpy(res_str, str);
340 make2_str(char *str1, char *str2)
342 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
344 strcpy(res_str, str1);
345 strcat(res_str, str2);
352 cat2_str(char *str1, char *str2)
354 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
356 strcpy(res_str, str1);
357 strcat(res_str, " ");
358 strcat(res_str, str2);
365 make3_str(char *str1, char *str2, char * str3)
367 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 1);
369 strcpy(res_str, str1);
370 strcat(res_str, str2);
371 strcat(res_str, str3);
379 cat3_str(char *str1, char *str2, char * str3)
381 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 3);
383 strcpy(res_str, str1);
384 strcat(res_str, " ");
385 strcat(res_str, str2);
386 strcat(res_str, " ");
387 strcat(res_str, str3);
395 make4_str(char *str1, char *str2, char *str3, char *str4)
397 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 1);
399 strcpy(res_str, str1);
400 strcat(res_str, str2);
401 strcat(res_str, str3);
402 strcat(res_str, str4);
411 cat4_str(char *str1, char *str2, char *str3, char *str4)
413 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 4);
415 strcpy(res_str, str1);
416 strcat(res_str, " ");
417 strcat(res_str, str2);
418 strcat(res_str, " ");
419 strcat(res_str, str3);
420 strcat(res_str, " ");
421 strcat(res_str, str4);
430 make5_str(char *str1, char *str2, char *str3, char *str4, char *str5)
432 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + strlen(str5) + 1);
434 strcpy(res_str, str1);
435 strcat(res_str, str2);
436 strcat(res_str, str3);
437 strcat(res_str, str4);
438 strcat(res_str, str5);
448 cat5_str(char *str1, char *str2, char *str3, char *str4, char *str5)
450 char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + strlen(str5) + 5);
452 strcpy(res_str, str1);
453 strcat(res_str, " ");
454 strcat(res_str, str2);
455 strcat(res_str, " ");
456 strcat(res_str, str3);
457 strcat(res_str, " ");
458 strcat(res_str, str4);
459 strcat(res_str, " ");
460 strcat(res_str, str5);
472 char * name = (char *)mm_alloc(yyleng + 1);
474 strncpy(name, yytext, yyleng);
480 output_statement(char * stmt, int mode)
482 int i, j=strlen(stmt);
484 fputs("ECPGdo(__LINE__, \"", yyout);
486 /* do this char by char as we have to filter '\"' */
487 for (i = 0;i < j; i++)
489 fputc(stmt[i], yyout);
490 fputs("\", ", yyout);
492 /* dump variables to C file*/
493 dump_variables(argsinsert, 1);
494 fputs("ECPGt_EOIT, ", yyout);
495 dump_variables(argsresult, 1);
496 fputs("ECPGt_EORT);", yyout);
497 whenever_action(mode);
510 struct this_type type;
511 enum ECPGttype type_enum;
514 /* special embedded SQL token */
515 %token SQL_BREAK SQL_CALL SQL_CONNECT SQL_CONNECTION SQL_CONTINUE
516 %token SQL_DISCONNECT SQL_FOUND SQL_GO SQL_GOTO
517 %token SQL_IDENTIFIED SQL_IMMEDIATE SQL_INDICATOR SQL_OPEN SQL_RELEASE
518 %token SQL_SECTION SQL_SEMI SQL_SQLERROR SQL_SQLPRINT SQL_START
519 %token SQL_STOP SQL_WHENEVER
522 %token S_ANYTHING S_AUTO S_BOOL S_CHAR S_CONST S_DOUBLE S_ENUM S_EXTERN
523 %token S_FLOAT S_INT S
524 %token S_LONG S_REGISTER S_SHORT S_SIGNED S_STATIC S_STRUCT
525 %token S_UNSIGNED S_VARCHAR
527 /* I need this and don't know where it is defined inside the backend */
530 /* Keywords (in SQL92 reserved words) */
531 %token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
532 BEGIN_TRANS, BETWEEN, BOTH, BY,
533 CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
534 COALESCE, COLLATE, COLUMN, COMMIT,
535 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
536 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
537 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
538 ELSE, END_TRANS, EXECUTE, EXISTS, EXTRACT,
539 FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
540 GRANT, GROUP, HAVING, HOUR_P,
541 IN, INNER_P, INSENSITIVE, INSERT, INTERVAL, INTO, IS, ISOLATION,
542 JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
543 MATCH, MINUTE_P, MONTH_P, NAMES,
544 NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
545 OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
546 PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
547 READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
548 SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
549 TABLE, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE,
550 TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
551 UNION, UNIQUE, UPDATE, USER, USING,
552 VALUES, VARCHAR, VARYING, VIEW,
553 WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
555 /* Keywords (in SQL3 reserved words) */
558 /* Keywords (in SQL92 non-reserved words) */
561 /* Keywords for Postgres support (not in SQL92 reserved words)
563 * The CREATEDB and CREATEUSER tokens should go away
564 * when some sort of pg_privileges relation is introduced.
565 * - Todd A. Brandys 1998-01-01?
567 %token ABORT_TRANS, AFTER, AGGREGATE, ANALYZE, BACKWARD, BEFORE, BINARY,
568 CACHE, CLUSTER, COPY, CREATEDB, CREATEUSER, CYCLE,
569 DATABASE, DELIMITERS, DO, EACH, ENCODING, EXPLAIN, EXTEND,
570 FORWARD, FUNCTION, HANDLER,
571 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
572 LANCOMPILER, LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE, MINVALUE, MOVE,
573 NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
574 OIDS, OPERATOR, PASSWORD, PROCEDURAL,
575 RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
576 SERIAL, SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED,
577 UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
579 /* Special keywords, not in the query language - see the "lex" file */
580 %token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE
581 %token <ival> ICONST PARAM
584 /* these are not real. they are here so that they get generated as #define's*/
596 %nonassoc Op /* multi-character ops and user-defined operators */
602 %left '|' /* this is the relation union op, not logical or */
603 /* Unary Operators */
605 %left ';' /* end of statement or natural log */
612 %type <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId
613 %type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt
614 %type <str> OptInherit key_reference key_action
615 %type <str> key_match constraint_expr ColLabel SpecialRuleRelation
616 %type <str> ColId default_expr ColQualifier columnDef ColQualList
617 %type <str> ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
618 %type <str> OptTableElementList OptTableElement TableConstraint
619 %type <str> ConstraintElem key_actions constraint_list ColPrimaryKey
620 %type <str> res_target_list res_target_el res_target_list2
621 %type <str> res_target_el2 opt_id relation_name database_name
622 %type <str> access_method attr_name class index_name name func_name
623 %type <str> file_name recipe_name AexprConst ParamNo TypeId
624 %type <str> in_expr_nodes not_in_expr_nodes a_expr b_expr
625 %type <str> opt_indirection expr_list extract_list extract_arg
626 %type <str> position_list position_expr substr_list substr_from
627 %type <str> trim_list in_expr substr_for not_in_expr attr attrs
628 %type <str> Typename Array Generic Numeric generic opt_float opt_numeric
629 %type <str> opt_decimal Character character opt_varying opt_charset
630 %type <str> opt_collate Datetime datetime opt_timezone opt_interval
631 %type <str> numeric a_expr_or_null row_expr row_descriptor row_list
632 %type <str> SelectStmt union_clause select_list SubSelect result
633 %type <str> opt_table opt_union opt_unique sort_clause sortby_list
634 %type <str> sortby OptUseOp opt_inh_star relation_name_list name_list
635 %type <str> group_clause having_clause from_clause c_list
636 %type <str> from_list from_val join_expr join_outer join_spec join_list
637 %type <str> join_using where_clause relation_expr row_op sub_type
638 %type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
639 %type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
640 %type <str> NotifyStmt columnElem copy_dirn SubUnion c_expr UnlistenStmt
641 %type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
642 %type <str> opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name
643 %type <str> ClosePortalStmt DestroyStmt VacuumStmt opt_verbose
644 %type <str> opt_analyze opt_va_list va_list ExplainStmt index_params
645 %type <str> index_list func_index index_elem opt_type opt_class access_method_clause
646 %type <str> index_opt_unique IndexStmt set_opt func_return def_rest
647 %type <str> func_args_list func_args opt_with ProcedureStmt def_arg
648 %type <str> def_elem def_list definition def_name def_type DefineStmt
649 %type <str> opt_instead event event_object OptStmtMulti OptStmtBlock
650 %type <str> OptStmtList RuleStmt opt_column opt_name oper_argtypes
651 %type <str> MathOp RemoveFuncStmt aggr_argtype
652 %type <str> RemoveAggrStmt remove_type RemoveStmt ExtendStmt RecipeStmt
653 %type <str> RemoveOperStmt RenameStmt all_Op user_valid_clause
654 %type <str> VariableSetStmt var_value zone_value VariableShowStmt
655 %type <str> VariableResetStmt AddAttrStmt alter_clause DropUserStmt
656 %type <str> user_passwd_clause user_createdb_clause opt_trans
657 %type <str> user_createuser_clause user_group_list user_group_clause
658 %type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
659 %type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
660 %type <str> DropTrigStmt TriggerOneEvent TriggerEvents
661 %type <str> TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
662 %type <str> CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
663 %type <str> ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
664 %type <str> DestroydbStmt ClusterStmt grantee RevokeStmt encoding
665 %type <str> GrantStmt privileges operation_commalist operation
666 %type <str> cursor_clause opt_cursor opt_readonly opt_of opt_lmode
667 %type <str> case_expr when_clause_list case_default case_arg when_clause
669 %type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen open_opts
670 %type <str> indicator ECPGExecute ecpg_expr dotext
671 %type <str> storage_clause opt_initializer vartext c_anything blockstart
672 %type <str> blockend variable_list variable var_anything do_anything
673 %type <str> opt_pointer cvariable ECPGDisconnect dis_name
674 %type <str> stmt symbol opt_symbol ECPGRelease execstring server_name
675 %type <str> connection_object opt_server opt_port c_thing
676 %type <str> user_name opt_user char_variable ora_user ident
677 %type <str> db_prefix server opt_options opt_connection_name
678 %type <str> ECPGSetConnection c_line cpp_line s_enum
679 %type <str> enum_type
681 %type <type_enum> simple_type
685 %type <action> action
687 %type <index> opt_array_bounds nest_array_bounds
692 statements: /* empty */
693 | statements statement
695 statement: ecpgstart stmt SQL_SEMI
697 | c_thing { fprintf(yyout, "%s", $1); free($1); }
698 | cpp_line { fprintf(yyout, "%s", $1); free($1); }
699 | blockstart { fputs($1, yyout); free($1); }
700 | blockend { fputs($1, yyout); free($1); }
702 stmt: AddAttrStmt { output_statement($1, 0); }
703 | AlterUserStmt { output_statement($1, 0); }
704 | ClosePortalStmt { output_statement($1, 0); }
705 | CopyStmt { output_statement($1, 0); }
706 | CreateStmt { output_statement($1, 0); }
707 | CreateAsStmt { output_statement($1, 0); }
708 | CreateSeqStmt { output_statement($1, 0); }
709 | CreatePLangStmt { output_statement($1, 0); }
710 | CreateTrigStmt { output_statement($1, 0); }
711 | CreateUserStmt { output_statement($1, 0); }
712 | ClusterStmt { output_statement($1, 0); }
713 | DefineStmt { output_statement($1, 0); }
714 | DestroyStmt { output_statement($1, 0); }
715 | DropPLangStmt { output_statement($1, 0); }
716 | DropTrigStmt { output_statement($1, 0); }
717 | DropUserStmt { output_statement($1, 0); }
718 | ExtendStmt { output_statement($1, 0); }
719 | ExplainStmt { output_statement($1, 0); }
720 | FetchStmt { output_statement($1, 1); }
721 | GrantStmt { output_statement($1, 0); }
722 | IndexStmt { output_statement($1, 0); }
723 | ListenStmt { output_statement($1, 0); }
724 | UnlistenStmt { output_statement($1, 0); }
725 | LockStmt { output_statement($1, 0); }
726 | ProcedureStmt { output_statement($1, 0); }
727 | RecipeStmt { output_statement($1, 0); }
728 | RemoveAggrStmt { output_statement($1, 0); }
729 | RemoveOperStmt { output_statement($1, 0); }
730 | RemoveFuncStmt { output_statement($1, 0); }
731 | RemoveStmt { output_statement($1, 0); }
732 | RenameStmt { output_statement($1, 0); }
733 | RevokeStmt { output_statement($1, 0); }
735 if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
741 output_statement($1, 1);
743 | RuleStmt { output_statement($1, 0); }
745 fprintf(yyout, "ECPGtrans(__LINE__, \"%s\");", $1);
749 | ViewStmt { output_statement($1, 0); }
750 | LoadStmt { output_statement($1, 0); }
751 | CreatedbStmt { output_statement($1, 0); }
752 | DestroydbStmt { output_statement($1, 0); }
753 | VacuumStmt { output_statement($1, 0); }
754 | VariableSetStmt { output_statement($1, 0); }
755 | VariableShowStmt { output_statement($1, 0); }
756 | VariableResetStmt { output_statement($1, 0); }
758 fprintf(yyout, "no_auto_trans = %d;\n", no_auto_trans);
759 fprintf(yyout, "ECPGconnect(__LINE__, %s);", $1);
764 fprintf(yyout, "ECPGdisconnect(__LINE__, \"%s\");", $1);
769 fprintf(yyout, "ECPGdo(__LINE__, %s, ECPGt_EOIT, ECPGt_EORT);", $1);
776 for (ptr = cur; ptr != NULL; ptr=ptr->next)
778 if (strcmp(ptr->name, $1) == 0)
784 sprintf(errortext, "trying to open undeclared cursor %s\n", $1);
788 fprintf(yyout, "ECPGdo(__LINE__, \"%s\",", ptr->command);
789 /* dump variables to C file*/
790 dump_variables(ptr->argsinsert, 0);
791 fputs("ECPGt_EOIT, ", yyout);
792 dump_variables(ptr->argsresult, 0);
793 fputs("ECPGt_EORT);", yyout);
797 | ECPGRelease { /* output already done */ }
798 | ECPGSetConnection {
799 fprintf(yyout, "ECPGsetconn(__LINE__, %s);", $1);
805 output_line_number();
810 * We start with a lot of stuff that's very similar to the backend's parsing
813 /*****************************************************************************
815 * Create a new Postgres DBMS user
818 *****************************************************************************/
820 CreateUserStmt: CREATE USER UserId user_passwd_clause user_createdb_clause
821 user_createuser_clause user_group_clause user_valid_clause
823 $$ = cat3_str(cat5_str(make1_str("create user"), $3, $4, $5, $6), $7, $8);
827 /*****************************************************************************
829 * Alter a postresql DBMS user
832 *****************************************************************************/
834 AlterUserStmt: ALTER USER UserId user_passwd_clause user_createdb_clause
835 user_createuser_clause user_group_clause user_valid_clause
837 $$ = cat3_str(cat5_str(make1_str("alter user"), $3, $4, $5, $6), $7, $8);
841 /*****************************************************************************
843 * Drop a postresql DBMS user
846 *****************************************************************************/
848 DropUserStmt: DROP USER UserId
850 $$ = cat2_str(make1_str("drop user"), $3);
854 user_passwd_clause: WITH PASSWORD UserId { $$ = cat2_str(make1_str("with password") , $3); }
855 | /*EMPTY*/ { $$ = make1_str(""); }
858 user_createdb_clause: CREATEDB
860 $$ = make1_str("createdb");
864 $$ = make1_str("nocreatedb");
866 | /*EMPTY*/ { $$ = make1_str(""); }
869 user_createuser_clause: CREATEUSER
871 $$ = make1_str("createuser");
875 $$ = make1_str("nocreateuser");
877 | /*EMPTY*/ { $$ = NULL; }
880 user_group_list: user_group_list ',' UserId
882 $$ = cat3_str($1, make1_str(","), $3);
890 user_group_clause: IN GROUP user_group_list { $$ = cat2_str(make1_str("in group"), $3); }
891 | /*EMPTY*/ { $$ = make1_str(""); }
894 user_valid_clause: VALID UNTIL Sconst { $$ = cat2_str(make1_str("valid until"), $3);; }
895 | /*EMPTY*/ { $$ = make1_str(""); }
898 /*****************************************************************************
900 * Set PG internal variable
901 * SET name TO 'var_value'
902 * Include SQL92 syntax (thomas 1997-10-22):
903 * SET TIME ZONE 'var_value'
905 *****************************************************************************/
907 VariableSetStmt: SET ColId TO var_value
909 $$ = cat4_str(make1_str("set"), $2, make1_str("to"), $4);
911 | SET ColId '=' var_value
913 $$ = cat4_str(make1_str("set"), $2, make1_str("="), $4);
915 | SET TIME ZONE zone_value
917 $$ = cat2_str(make1_str("set time zone"), $4);
919 | SET TRANSACTION ISOLATION LEVEL READ ColId
921 if (strcasecmp($6, "COMMITTED"))
923 sprintf(errortext, "syntax error at or near \"%s\"", $6);
927 $$ = cat2_str(make1_str("set transaction isolation level read"), $6);
929 | SET TRANSACTION ISOLATION LEVEL ColId
931 if (strcasecmp($5, "SERIALIZABLE"))
933 sprintf(errortext, "syntax error at or near \"%s\"", $5);
937 $$ = cat2_str(make1_str("set transaction isolation level read"), $5);
942 $$ = cat2_str(make1_str("set names"), $3);
944 yyerror("SET NAMES is not supported");
949 var_value: Sconst { $$ = $1; }
950 | DEFAULT { $$ = make1_str("default"); }
953 zone_value: Sconst { $$ = $1; }
954 | DEFAULT { $$ = make1_str("default"); }
955 | LOCAL { $$ = make1_str("local"); }
958 VariableShowStmt: SHOW ColId
960 $$ = cat2_str(make1_str("show"), $2);
964 $$ = make1_str("show time zone");
966 | SHOW TRANSACTION ISOLATION LEVEL
968 $$ = make1_str("show transaction isolation level");
972 VariableResetStmt: RESET ColId
974 $$ = cat2_str(make1_str("reset"), $2);
978 $$ = make1_str("reset time zone");
980 | RESET TRANSACTION ISOLATION LEVEL
982 $$ = make1_str("reset transaction isolation level");
987 /*****************************************************************************
990 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
992 *****************************************************************************/
994 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
996 $$ = cat4_str(make1_str("alter table"), $3, $4, $5);
1000 alter_clause: ADD opt_column columnDef
1002 $$ = cat3_str(make1_str("add"), $2, $3);
1004 | ADD '(' OptTableElementList ')'
1006 $$ = make3_str(make1_str("add("), $3, make1_str(")"));
1008 | DROP opt_column ColId
1009 { yyerror("ALTER TABLE/DROP COLUMN not yet implemented"); }
1010 | ALTER opt_column ColId SET DEFAULT default_expr
1011 { yyerror("ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
1012 | ALTER opt_column ColId DROP DEFAULT
1013 { yyerror("ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
1014 | ADD ConstraintElem
1015 { yyerror("ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
1018 /*****************************************************************************
1023 *****************************************************************************/
1025 ClosePortalStmt: CLOSE opt_id
1027 $$ = cat2_str(make1_str("close"), $2);
1032 /*****************************************************************************
1035 * COPY [BINARY] <relname> FROM/TO
1036 * [USING DELIMITERS <delimiter>]
1038 *****************************************************************************/
1040 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
1042 $$ = cat3_str(cat5_str(make1_str("copy"), $2, $3, $4, $5), $6, $7);
1047 { $$ = make1_str("to"); }
1049 { $$ = make1_str("from"); }
1053 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
1054 * used depends on the direction. (It really doesn't make sense to copy from
1055 * stdout. We silently correct the "typo". - AY 9/94
1057 copy_file_name: Sconst { $$ = $1; }
1058 | STDIN { $$ = make1_str("stdin"); }
1059 | STDOUT { $$ = make1_str("stdout"); }
1062 opt_binary: BINARY { $$ = make1_str("binary"); }
1063 | /*EMPTY*/ { $$ = make1_str(""); }
1066 opt_with_copy: WITH OIDS { $$ = make1_str("with oids"); }
1067 | /*EMPTY*/ { $$ = make1_str(""); }
1071 * the default copy delimiter is tab but the user can configure it
1073 copy_delimiter: USING DELIMITERS Sconst { $$ = cat2_str(make1_str("using delimiters"), $3); }
1074 | /*EMPTY*/ { $$ = make1_str(""); }
1079 /*****************************************************************************
1084 *****************************************************************************/
1086 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
1089 $$ = cat4_str(make1_str("create table"), $3, make3_str(make1_str("("), $5, make1_str(")")), $7);
1093 OptTableElementList: OptTableElementList ',' OptTableElement
1095 $$ = cat3_str($1, make1_str(","), $3);
1101 | /*EMPTY*/ { $$ = make1_str(""); }
1104 OptTableElement: columnDef { $$ = $1; }
1105 | TableConstraint { $$ = $1; }
1108 columnDef: ColId Typename ColQualifier
1110 $$ = cat3_str($1, $2, $3);
1112 | ColId SERIAL ColPrimaryKey
1114 $$ = make3_str($1, make1_str(" serial "), $3);
1118 ColQualifier: ColQualList { $$ = $1; }
1119 | /*EMPTY*/ { $$ = make1_str(""); }
1122 ColQualList: ColQualList ColConstraint { $$ = cat2_str($1,$2); }
1123 | ColConstraint { $$ = $1; }
1126 ColPrimaryKey: PRIMARY KEY
1128 $$ = make1_str("primary key");
1137 CONSTRAINT name ColConstraintElem
1139 $$ = cat3_str(make1_str("constraint"), $2, $3);
1145 /* The column constraint WITH NULL gives a shift/reduce error
1146 * because it requires yacc to look more than one token ahead to
1147 * resolve WITH TIME ZONE and WITH NULL.
1148 * So, leave it out of the syntax for now.
1153 * - thomas 1998-09-12
1155 * DEFAULT NULL is already the default for Postgres.
1156 * Bue define it here and carry it forward into the system
1157 * to make it explicit.
1158 * - thomas 1998-09-13
1160 ColConstraintElem: CHECK '(' constraint_expr ')'
1162 $$ = make3_str(make1_str("check("), $3, make1_str(")"));
1166 $$ = make1_str("default null");
1168 | DEFAULT default_expr
1170 $$ = cat2_str(make1_str("default"), $2);
1174 $$ = make1_str("not null");
1178 $$ = make1_str("unique");
1182 $$ = make1_str("primary key");
1184 | REFERENCES ColId opt_column_list key_match key_actions
1186 fprintf(stderr, "CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
1191 default_list: default_list ',' default_expr
1193 $$ = cat3_str($1, make1_str(","), $3);
1201 /* The Postgres default column value is NULL.
1202 * Rather than carrying DEFAULT NULL forward as a clause,
1203 * let's just have it be a no-op.
1205 { $$ = make1_str("null"); }
1206 * - thomas 1998-09-13
1209 default_expr: AexprConst
1211 | '-' default_expr %prec UMINUS
1212 { $$ = cat2_str(make1_str("-"), $2); }
1213 | default_expr '+' default_expr
1214 { $$ = cat3_str($1, make1_str("+"), $3); }
1215 | default_expr '-' default_expr
1216 { $$ = cat3_str($1, make1_str("-"), $3); }
1217 | default_expr '/' default_expr
1218 { $$ = cat3_str($1, make1_str("/"), $3); }
1219 | default_expr '*' default_expr
1220 { $$ = cat3_str($1, make1_str("*"), $3); }
1221 | default_expr '=' default_expr
1222 { yyerror("boolean expressions not supported in DEFAULT"); }
1223 | default_expr '<' default_expr
1224 { yyerror("boolean expressions not supported in DEFAULT"); }
1225 | default_expr '>' default_expr
1226 { yyerror("boolean expressions not supported in DEFAULT"); }
1227 /* not possible in embedded sql
1229 { $$ = cat2_str(make1_str(":"), $2); }
1232 { $$ = cat2_str(make1_str(";"), $2); }
1234 { $$ = cat2_str(make1_str("|"), $2); }
1235 | default_expr TYPECAST Typename
1236 { $$ = cat3_str($1, make1_str("::"), $3); }
1237 | CAST '(' default_expr AS Typename ')'
1239 $$ = cat3_str(make2_str(make1_str("cast("), $3) , make1_str("as"), make2_str($5, make1_str(")")));
1241 | '(' default_expr ')'
1242 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
1244 { $$ = cat2_str($1, make1_str("()")); }
1245 | func_name '(' default_list ')'
1246 { $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")"))); }
1247 | default_expr Op default_expr
1249 if (!strcmp("<=", $2) || !strcmp(">=", $2))
1250 yyerror("boolean expressions not supported in DEFAULT");
1251 $$ = cat3_str($1, $2, $3);
1254 { $$ = cat2_str($1, $2); }
1256 { $$ = cat2_str($1, $2); }
1257 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
1259 { $$ = make1_str("current_date"); }
1261 { $$ = make1_str("current_time"); }
1262 | CURRENT_TIME '(' Iconst ')'
1265 fprintf(stderr, "CURRENT_TIME(%s) precision not implemented; zero used instead",$3);
1266 $$ = "current_time";
1269 { $$ = make1_str("current_timestamp"); }
1270 | CURRENT_TIMESTAMP '(' Iconst ')'
1273 fprintf(stderr, "CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
1274 $$ = "current_timestamp";
1277 { $$ = make1_str("current_user"); }
1279 { $$ = make1_str("user"); }
1282 /* ConstraintElem specifies constraint syntax which is not embedded into
1283 * a column definition. ColConstraintElem specifies the embedded form.
1284 * - thomas 1997-12-03
1286 TableConstraint: CONSTRAINT name ConstraintElem
1288 $$ = cat3_str(make1_str("constraint"), $2, $3);
1294 ConstraintElem: CHECK '(' constraint_expr ')'
1296 $$ = make3_str(make1_str("check("), $3, make1_str(")"));
1298 | UNIQUE '(' columnList ')'
1300 $$ = make3_str(make1_str("unique("), $3, make1_str(")"));
1302 | PRIMARY KEY '(' columnList ')'
1304 $$ = make3_str(make1_str("primary key("), $4, make1_str(")"));
1306 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
1308 fprintf(stderr, "CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
1313 constraint_list: constraint_list ',' constraint_expr
1315 $$ = cat3_str($1, make1_str(","), $3);
1323 constraint_expr: AexprConst
1326 { $$ = make1_str("null"); }
1331 | '-' constraint_expr %prec UMINUS
1332 { $$ = cat2_str(make1_str("-"), $2); }
1333 | constraint_expr '+' constraint_expr
1334 { $$ = cat3_str($1, make1_str("+"), $3); }
1335 | constraint_expr '-' constraint_expr
1336 { $$ = cat3_str($1, make1_str("-"), $3); }
1337 | constraint_expr '/' constraint_expr
1338 { $$ = cat3_str($1, make1_str("/"), $3); }
1339 | constraint_expr '*' constraint_expr
1340 { $$ = cat3_str($1, make1_str("*"), $3); }
1341 | constraint_expr '=' constraint_expr
1342 { $$ = cat3_str($1, make1_str("="), $3); }
1343 | constraint_expr '<' constraint_expr
1344 { $$ = cat3_str($1, make1_str("<"), $3); }
1345 | constraint_expr '>' constraint_expr
1346 { $$ = cat3_str($1, make1_str(">"), $3); }
1347 /* this one doesn't work with embedded sql anyway
1348 | ':' constraint_expr
1349 { $$ = cat2_str(make1_str(":"), $2); }
1351 | ';' constraint_expr
1352 { $$ = cat2_str(make1_str(";"), $2); }
1353 | '|' constraint_expr
1354 { $$ = cat2_str(make1_str("|"), $2); }
1355 | constraint_expr TYPECAST Typename
1357 $$ = cat3_str($1, make1_str("::"), $3);
1359 | CAST '(' constraint_expr AS Typename ')'
1361 $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
1363 | '(' constraint_expr ')'
1364 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
1367 { $$ = cat2_str($1, make1_str("()")); }
1369 | func_name '(' constraint_list ')'
1371 $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")")));
1373 | constraint_expr Op constraint_expr
1374 { $$ = cat3_str($1, $2, $3); }
1375 | constraint_expr LIKE constraint_expr
1376 { $$ = cat3_str($1, make1_str("like"), $3); }
1377 | constraint_expr NOT LIKE constraint_expr
1378 { $$ = cat3_str($1, make1_str("not like"), $4); }
1379 | constraint_expr AND constraint_expr
1380 { $$ = cat3_str($1, make1_str("and"), $3); }
1381 | constraint_expr OR constraint_expr
1382 { $$ = cat3_str($1, make1_str("or"), $3); }
1383 | NOT constraint_expr
1384 { $$ = cat2_str(make1_str("not"), $2); }
1385 | Op constraint_expr
1386 { $$ = cat2_str($1, $2); }
1387 | constraint_expr Op
1388 { $$ = cat2_str($1, $2); }
1389 | constraint_expr ISNULL
1390 { $$ = cat2_str($1, make1_str("isnull")); }
1391 | constraint_expr IS NULL_P
1392 { $$ = cat2_str($1, make1_str("is null")); }
1393 | constraint_expr NOTNULL
1394 { $$ = cat2_str($1, make1_str("notnull")); }
1395 | constraint_expr IS NOT NULL_P
1396 { $$ = cat2_str($1, make1_str("is not null")); }
1397 | constraint_expr IS TRUE_P
1398 { $$ = cat2_str($1, make1_str("is true")); }
1399 | constraint_expr IS FALSE_P
1400 { $$ = cat2_str($1, make1_str("is false")); }
1401 | constraint_expr IS NOT TRUE_P
1402 { $$ = cat2_str($1, make1_str("is not true")); }
1403 | constraint_expr IS NOT FALSE_P
1404 { $$ = cat2_str($1, make1_str("is not false")); }
1405 | constraint_expr IN '(' c_list ')'
1406 { $$ = cat4_str($1, make1_str("in ("), $4, make1_str(")")); }
1407 | constraint_expr NOT IN '(' c_list ')'
1408 { $$ = cat4_str($1, make1_str("not in ("), $5, make1_str(")")); }
1409 | constraint_expr BETWEEN c_expr AND c_expr
1410 { $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5); }
1411 | constraint_expr NOT BETWEEN c_expr AND c_expr
1412 { $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6); }
1414 c_list: c_list ',' c_expr
1416 $$ = make3_str($1, make1_str(", "), $3);
1428 key_match: MATCH FULL { $$ = make1_str("match full"); }
1429 | MATCH PARTIAL { $$ = make1_str("match partial"); }
1430 | /*EMPTY*/ { $$ = make1_str(""); }
1433 key_actions: key_action key_action { $$ = cat2_str($1, $2); }
1434 | key_action { $$ = $1; }
1435 | /*EMPTY*/ { $$ = make1_str(""); }
1438 key_action: ON DELETE key_reference { $$ = cat2_str(make1_str("on delete"), $3); }
1439 | ON UPDATE key_reference { $$ = cat2_str(make1_str("on update"), $3); }
1442 key_reference: NO ACTION { $$ = make1_str("no action"); }
1443 | CASCADE { $$ = make1_str("cascade"); }
1444 | SET DEFAULT { $$ = make1_str("set default"); }
1445 | SET NULL_P { $$ = make1_str("set null"); }
1448 OptInherit: INHERITS '(' relation_name_list ')' { $$ = make3_str(make1_str("inherits ("), $3, make1_str(")")); }
1449 | /*EMPTY*/ { $$ = make1_str(""); }
1452 CreateAsStmt: CREATE TABLE relation_name OptCreateAs AS SubSelect
1454 $$ = cat5_str(make1_str("create table"), $3, $4, make1_str("as"), $6);
1458 OptCreateAs: '(' CreateAsList ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
1459 | /*EMPTY*/ { $$ = make1_str(""); }
1462 CreateAsList: CreateAsList ',' CreateAsElement { $$ = cat3_str($1, make1_str(","), $3); }
1463 | CreateAsElement { $$ = $1; }
1466 CreateAsElement: ColId { $$ = $1; }
1469 /*****************************************************************************
1472 * CREATE SEQUENCE seqname
1474 *****************************************************************************/
1476 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1478 $$ = cat3_str(make1_str("create sequence"), $3, $4);
1482 OptSeqList: OptSeqList OptSeqElem
1483 { $$ = cat2_str($1, $2); }
1484 | { $$ = make1_str(""); }
1487 OptSeqElem: CACHE IntegerOnly
1489 $$ = cat2_str(make1_str("cache"), $2);
1493 $$ = make1_str("cycle");
1495 | INCREMENT IntegerOnly
1497 $$ = cat2_str(make1_str("increment"), $2);
1499 | MAXVALUE IntegerOnly
1501 $$ = cat2_str(make1_str("maxvalue"), $2);
1503 | MINVALUE IntegerOnly
1505 $$ = cat2_str(make1_str("minvalue"), $2);
1509 $$ = cat2_str(make1_str("start"), $2);
1513 NumericOnly: FloatOnly { $$ = $1; }
1514 | IntegerOnly { $$ = $1; }
1522 $$ = cat2_str(make1_str("-"), $2);
1533 $$ = cat2_str(make1_str("-"), $2);
1537 /*****************************************************************************
1540 * CREATE PROCEDURAL LANGUAGE ...
1541 * DROP PROCEDURAL LANGUAGE ...
1543 *****************************************************************************/
1545 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1546 HANDLER def_name LANCOMPILER Sconst
1548 $$ = cat4_str(cat5_str(make1_str("create"), $2, make1_str("precedural language"), $5, make1_str("handler")), $7, make1_str("langcompiler"), $9);
1552 PLangTrusted: TRUSTED { $$ = make1_str("trusted"); }
1553 | { $$ = make1_str(""); }
1555 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1557 $$ = cat2_str(make1_str("drop procedural language"), $4);
1561 /*****************************************************************************
1564 * CREATE TRIGGER ...
1567 *****************************************************************************/
1569 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1570 relation_name TriggerForSpec EXECUTE PROCEDURE
1571 name '(' TriggerFuncArgs ')'
1573 $$ = 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(")")));
1577 TriggerActionTime: BEFORE { $$ = make1_str("before"); }
1578 | AFTER { $$ = make1_str("after"); }
1581 TriggerEvents: TriggerOneEvent
1585 | TriggerOneEvent OR TriggerOneEvent
1587 $$ = cat3_str($1, make1_str("or"), $3);
1589 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1591 $$ = cat5_str($1, make1_str("or"), $3, make1_str("or"), $5);
1595 TriggerOneEvent: INSERT { $$ = make1_str("insert"); }
1596 | DELETE { $$ = make1_str("delete"); }
1597 | UPDATE { $$ = make1_str("update"); }
1600 TriggerForSpec: FOR TriggerForOpt TriggerForType
1602 $$ = cat3_str(make1_str("for"), $2, $3);
1606 TriggerForOpt: EACH { $$ = make1_str("each"); }
1607 | /*EMPTY*/ { $$ = make1_str(""); }
1610 TriggerForType: ROW { $$ = make1_str("row"); }
1611 | STATEMENT { $$ = make1_str("statement"); }
1614 TriggerFuncArgs: TriggerFuncArg
1616 | TriggerFuncArgs ',' TriggerFuncArg
1617 { $$ = cat3_str($1, make1_str(","), $3); }
1619 { $$ = make1_str(""); }
1622 TriggerFuncArg: Iconst
1630 | Sconst { $$ = $1; }
1631 | ident { $$ = $1; }
1634 DropTrigStmt: DROP TRIGGER name ON relation_name
1636 $$ = cat4_str(make1_str("drop trigger"), $3, make1_str("on"), $5);
1640 /*****************************************************************************
1643 * define (type,operator,aggregate)
1645 *****************************************************************************/
1647 DefineStmt: CREATE def_type def_rest
1649 $$ = cat3_str(make1_str("create"), $2, $3);
1653 def_rest: def_name definition
1655 $$ = cat2_str($1, $2);
1659 def_type: OPERATOR { $$ = make1_str("operator"); }
1660 | TYPE_P { $$ = make1_str("type"); }
1661 | AGGREGATE { $$ = make1_str("aggregate"); }
1664 def_name: PROCEDURE { $$ = make1_str("procedure"); }
1665 | JOIN { $$ = make1_str("join"); }
1666 | ColId { $$ = $1; }
1667 | MathOp { $$ = $1; }
1671 definition: '(' def_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
1674 def_list: def_elem { $$ = $1; }
1675 | def_list ',' def_elem { $$ = cat3_str($1, make1_str(","), $3); }
1678 def_elem: def_name '=' def_arg {
1679 $$ = cat3_str($1, make1_str("="), $3);
1685 | DEFAULT '=' def_arg
1687 $$ = cat2_str(make1_str("default ="), $3);
1691 def_arg: ColId { $$ = $1; }
1692 | all_Op { $$ = $1; }
1693 | NumericOnly { $$ = $1; }
1694 | Sconst { $$ = $1; }
1697 $$ = cat2_str(make1_str("setof"), $2);
1701 /*****************************************************************************
1704 * destroy <relname1> [, <relname2> .. <relnameN> ]
1706 *****************************************************************************/
1708 DestroyStmt: DROP TABLE relation_name_list
1710 $$ = cat2_str(make1_str("drop table"), $3);
1712 | DROP SEQUENCE relation_name_list
1714 $$ = cat2_str(make1_str("drop sequence"), $3);
1720 /*****************************************************************************
1723 * fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
1724 * fetch [ forward | backward | absolute | relative ]
1725 * [ # | all | next | prior ] [ [ in | from ] <portalname> ]
1727 *****************************************************************************/
1729 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name INTO into_list
1731 if (strncmp($2, "relative", strlen("relative")) == 0 && atol($3) == 0L)
1732 yyerror("FETCH/RELATIVE at current position is not supported");
1734 $$ = cat4_str(make1_str("fetch"), $2, $3, $4);
1736 | MOVE opt_direction fetch_how_many opt_portal_name
1738 $$ = cat4_str(make1_str("fetch"), $2, $3, $4);
1742 opt_direction: FORWARD { $$ = make1_str("forward"); }
1743 | BACKWARD { $$ = make1_str("backward"); }
1744 | RELATIVE { $$ = make1_str("relative"); }
1747 fprintf(stderr, "FETCH/ABSOLUTE not supported, using RELATIVE");
1748 $$ = make1_str("absolute");
1750 | /*EMPTY*/ { $$ = make1_str(""); /* default */ }
1753 fetch_how_many: Iconst { $$ = $1; }
1754 | '-' Iconst { $$ = make2_str(make1_str("-"), $2); }
1755 | ALL { $$ = make1_str("all"); }
1756 | NEXT { $$ = make1_str("next"); }
1757 | PRIOR { $$ = make1_str("prior"); }
1758 | /*EMPTY*/ { $$ = make1_str(""); /*default*/ }
1761 opt_portal_name: IN name { $$ = cat2_str(make1_str("in"), $2); }
1762 | FROM name { $$ = cat2_str(make1_str("from"), $2); }
1763 /* | name { $$ = cat2_str(make1_str("in"), $1); */
1764 | /*EMPTY*/ { $$ = make1_str(""); }
1768 /*****************************************************************************
1771 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1773 *****************************************************************************/
1775 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1777 $$ = cat2_str(cat5_str(make1_str("grant"), $2, make1_str("on"), $4, make1_str("to")), $6);
1781 privileges: ALL PRIVILEGES
1783 $$ = make1_str("all privileges");
1787 $$ = make1_str("all");
1789 | operation_commalist
1795 operation_commalist: operation
1799 | operation_commalist ',' operation
1801 $$ = cat3_str($1, make1_str(","), $3);
1807 $$ = make1_str("select");
1811 $$ = make1_str("insert");
1815 $$ = make1_str("update");
1819 $$ = make1_str("delete");
1823 $$ = make1_str("rule");
1829 $$ = make1_str("public");
1833 $$ = cat2_str(make1_str("group"), $2);
1841 opt_with_grant: WITH GRANT OPTION
1843 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1849 /*****************************************************************************
1852 * REVOKE [privileges] ON [relation_name] FROM [user]
1854 *****************************************************************************/
1856 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1858 $$ = cat2_str(cat5_str(make1_str("revoke"), $2, make1_str("on"), $4, make1_str("from")), $6);
1864 /*****************************************************************************
1867 * create index <indexname> on <relname>
1868 * using <access> "(" (<col> with <op>)+ ")" [with
1871 * [where <qual>] is not supported anymore
1872 *****************************************************************************/
1874 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1875 access_method_clause '(' index_params ')' opt_with
1877 /* should check that access_method is valid,
1878 etc ... but doesn't */
1879 $$ = 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);
1883 index_opt_unique: UNIQUE { $$ = make1_str("unique"); }
1884 | /*EMPTY*/ { $$ = make1_str(""); }
1887 access_method_clause: USING access_method { $$ = cat2_str(make1_str("using"), $2); }
1888 | /*EMPTY*/ { $$ = make1_str(""); }
1891 index_params: index_list { $$ = $1; }
1892 | func_index { $$ = $1; }
1895 index_list: index_list ',' index_elem { $$ = cat3_str($1, make1_str(","), $3); }
1896 | index_elem { $$ = $1; }
1899 func_index: func_name '(' name_list ')' opt_type opt_class
1901 $$ = cat4_str($1, make3_str(make1_str("("), $3, ")"), $5, $6);
1905 index_elem: attr_name opt_type opt_class
1907 $$ = cat3_str($1, $2, $3);
1911 opt_type: ':' Typename { $$ = cat2_str(make1_str(":"), $2); }
1912 | FOR Typename { $$ = cat2_str(make1_str("for"), $2); }
1913 | /*EMPTY*/ { $$ = make1_str(""); }
1916 /* opt_class "WITH class" conflicts with preceeding opt_type
1917 * for Typename of "TIMESTAMP WITH TIME ZONE"
1918 * So, remove "WITH class" from the syntax. OK??
1919 * - thomas 1997-10-12
1920 * | WITH class { $$ = $2; }
1922 opt_class: class { $$ = $1; }
1923 | USING class { $$ = cat2_str(make1_str("using"), $2); }
1924 | /*EMPTY*/ { $$ = make1_str(""); }
1927 /*****************************************************************************
1930 * extend index <indexname> [where <qual>]
1932 *****************************************************************************/
1934 ExtendStmt: EXTEND INDEX index_name where_clause
1936 $$ = cat3_str(make1_str("extend index"), $3, $4);
1941 /*****************************************************************************
1944 * execute recipe <recipeName>
1946 *****************************************************************************/
1948 RecipeStmt: EXECUTE RECIPE recipe_name
1950 $$ = cat2_str(make1_str("execute recipe"), $3);
1954 /*****************************************************************************
1957 * define function <fname>
1958 * (language = <lang>, returntype = <typename>
1959 * [, arch_pct = <percentage | pre-defined>]
1960 * [, disk_pct = <percentage | pre-defined>]
1961 * [, byte_pct = <percentage | pre-defined>]
1962 * [, perbyte_cpu = <int | pre-defined>]
1963 * [, percall_cpu = <int | pre-defined>]
1965 * [arg is (<type-1> { , <type-n>})]
1966 * as <filename or code in language as appropriate>
1968 *****************************************************************************/
1970 ProcedureStmt: CREATE FUNCTION func_name func_args
1971 RETURNS func_return opt_with AS Sconst LANGUAGE Sconst
1973 $$ = 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);
1976 opt_with: WITH definition { $$ = cat2_str(make1_str("with"), $2); }
1977 | /*EMPTY*/ { $$ = make1_str(""); }
1980 func_args: '(' func_args_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
1981 | '(' ')' { $$ = make1_str("()"); }
1984 func_args_list: TypeId { $$ = $1; }
1985 | func_args_list ',' TypeId
1986 { $$ = cat3_str($1, make1_str(","), $3); }
1989 func_return: set_opt TypeId
1991 $$ = cat2_str($1, $2);
1995 set_opt: SETOF { $$ = make1_str("setof"); }
1996 | /*EMPTY*/ { $$ = make1_str(""); }
2000 /*****************************************************************************
2004 * remove function <funcname>
2005 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
2006 * remove aggregate <aggname>
2007 * (REMOVE AGGREGATE "aggname" "aggtype")
2008 * remove operator <opname>
2009 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
2010 * remove type <typename>
2011 * (REMOVE TYPE "typename")
2012 * remove rule <rulename>
2013 * (REMOVE RULE "rulename")
2015 *****************************************************************************/
2017 RemoveStmt: DROP remove_type name
2019 $$ = cat3_str(make1_str("drop"), $2, $3);;
2023 remove_type: TYPE_P { $$ = make1_str("type"); }
2024 | INDEX { $$ = make1_str("index"); }
2025 | RULE { $$ = make1_str("rule"); }
2026 | VIEW { $$ = make1_str("view"); }
2030 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
2032 $$ = cat3_str(make1_str("drop aggregate"), $3, $4);
2036 aggr_argtype: name { $$ = $1; }
2037 | '*' { $$ = make1_str("*"); }
2041 RemoveFuncStmt: DROP FUNCTION func_name func_args
2043 $$ = cat3_str(make1_str("drop function"), $3, $4);
2048 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
2050 $$ = cat3_str(make1_str("drop operator"), $3, make3_str(make1_str("("), $5, make1_str(")")));
2054 all_Op: Op | MathOp;
2056 MathOp: '+' { $$ = make1_str("+"); }
2057 | '-' { $$ = make1_str("-"); }
2058 | '*' { $$ = make1_str("*"); }
2059 | '/' { $$ = make1_str("/"); }
2060 | '<' { $$ = make1_str("<"); }
2061 | '>' { $$ = make1_str(">"); }
2062 | '=' { $$ = make1_str("="); }
2067 yyerror("parser: argument type missing (use NONE for unary operators)");
2070 { $$ = cat3_str($1, make1_str(","), $3); }
2071 | NONE ',' name /* left unary */
2072 { $$ = cat2_str(make1_str("none,"), $3); }
2073 | name ',' NONE /* right unary */
2074 { $$ = cat2_str($1, make1_str(", none")); }
2078 /*****************************************************************************
2081 * rename <attrname1> in <relname> [*] to <attrname2>
2082 * rename <relname1> to <relname2>
2084 *****************************************************************************/
2086 RenameStmt: ALTER TABLE relation_name opt_inh_star
2087 RENAME opt_column opt_name TO name
2089 $$ = cat4_str(cat5_str(make1_str("alter table"), $3, $4, make1_str("rename"), $6), $7, make1_str("to"), $9);
2093 opt_name: name { $$ = $1; }
2094 | /*EMPTY*/ { $$ = make1_str(""); }
2097 opt_column: COLUMN { $$ = make1_str("colmunn"); }
2098 | /*EMPTY*/ { $$ = make1_str(""); }
2102 /*****************************************************************************
2104 * QUERY: Define Rewrite Rule , Define Tuple Rule
2105 * Define Rule <old rules >
2107 * only rewrite rule is supported -- ay 9/94
2109 *****************************************************************************/
2111 RuleStmt: CREATE RULE name AS
2113 ON event TO event_object where_clause
2114 DO opt_instead OptStmtList
2116 $$ = 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);
2120 OptStmtList: NOTHING { $$ = make1_str("nothing"); }
2121 | OptimizableStmt { $$ = $1; }
2122 | '[' OptStmtBlock ']' { $$ = cat3_str(make1_str("["), $2, make1_str("]")); }
2123 | '(' OptStmtBlock ')' { $$ = cat3_str(make1_str("("), $2, make1_str(")")); }
2126 OptStmtBlock: OptStmtMulti
2132 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
2133 { $$ = cat3_str($1, $2, make1_str(";")); }
2134 | OptStmtMulti OptimizableStmt
2135 { $$ = cat2_str($1, $2); }
2136 | OptimizableStmt ';'
2137 { $$ = cat2_str($1, make1_str(";")); }
2140 event_object: relation_name '.' attr_name
2142 $$ = make3_str($1, make1_str("."), $3);
2150 /* change me to select, update, etc. some day */
2151 event: SELECT { $$ = make1_str("select"); }
2152 | UPDATE { $$ = make1_str("update"); }
2153 | DELETE { $$ = make1_str("delete"); }
2154 | INSERT { $$ = make1_str("insert"); }
2157 opt_instead: INSTEAD { $$ = make1_str("instead"); }
2158 | /*EMPTY*/ { $$ = make1_str(""); }
2162 /*****************************************************************************
2165 * NOTIFY <relation_name> can appear both in rule bodies and
2166 * as a query-level command
2168 *****************************************************************************/
2170 NotifyStmt: NOTIFY relation_name
2172 $$ = cat2_str(make1_str("notify"), $2);
2176 ListenStmt: LISTEN relation_name
2178 $$ = cat2_str(make1_str("listen"), $2);
2182 UnlistenStmt: UNLISTEN relation_name
2184 $$ = cat2_str(make1_str("unlisten"), $2);
2188 $$ = make1_str("unlisten *");
2192 /*****************************************************************************
2203 *****************************************************************************/
2204 TransactionStmt: ABORT_TRANS opt_trans { $$ = make1_str("rollback"); }
2205 | BEGIN_TRANS opt_trans { $$ = make1_str("begin transaction"); }
2206 | COMMIT opt_trans { $$ = make1_str("commit"); }
2207 | END_TRANS opt_trans { $$ = make1_str("commit"); }
2208 | ROLLBACK opt_trans { $$ = make1_str("rollback"); }
2210 opt_trans: WORK { $$ = ""; }
2211 | TRANSACTION { $$ = ""; }
2212 | /*EMPTY*/ { $$ = ""; }
2215 /*****************************************************************************
2218 * define view <viewname> '('target-list ')' [where <quals> ]
2220 *****************************************************************************/
2222 ViewStmt: CREATE VIEW name AS SelectStmt
2224 $$ = cat4_str(make1_str("create view"), $3, make1_str("as"), $5);
2229 /*****************************************************************************
2232 * load make1_str("filename")
2234 *****************************************************************************/
2236 LoadStmt: LOAD file_name
2238 $$ = cat2_str(make1_str("load"), $2);
2243 /*****************************************************************************
2248 *****************************************************************************/
2250 CreatedbStmt: CREATE DATABASE database_name WITH opt_database1 opt_database2
2252 if (strlen($5) == 0 || strlen($6) == 0)
2253 yyerror("CREATE DATABASE WITH requires at least an option");
2255 if (strlen($6) != 0)
2256 yyerror("WITH ENCODING is not supported");
2258 $$ = cat5_str(make1_str("create database"), $3, make1_str("with"), $5, $6);
2260 | CREATE DATABASE database_name
2262 $$ = cat2_str(make1_str("create database"), $3);
2266 opt_database1: LOCATION '=' location { $$ = cat2_str(make1_str("location ="), $3); }
2267 | /*EMPTY*/ { $$ = make1_str(""); }
2270 opt_database2: ENCODING '=' encoding { $$ = cat2_str(make1_str("encoding ="), $3); }
2271 | /*EMPTY*/ { $$ = NULL; }
2274 location: Sconst { $$ = $1; }
2275 | DEFAULT { $$ = make1_str("default"); }
2276 | /*EMPTY*/ { $$ = make1_str(""); }
2279 encoding: Sconst { $$ = $1; }
2280 | DEFAULT { $$ = make1_str("default"); }
2281 | /*EMPTY*/ { $$ = make1_str(""); }
2284 /*****************************************************************************
2289 *****************************************************************************/
2291 DestroydbStmt: DROP DATABASE database_name
2293 $$ = cat2_str(make1_str("drop database"), $3);
2298 /*****************************************************************************
2301 * cluster <index_name> on <relation_name>
2303 *****************************************************************************/
2305 ClusterStmt: CLUSTER index_name ON relation_name
2307 $$ = cat4_str(make1_str("cluster"), $2, make1_str("on"), $4);
2312 /*****************************************************************************
2317 *****************************************************************************/
2319 VacuumStmt: VACUUM opt_verbose opt_analyze
2321 $$ = cat3_str(make1_str("vacuum"), $2, $3);
2323 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2325 if ( strlen($5) > 0 && strlen($4) == 0 )
2326 yyerror("parser: syntax error at or near \"(\"");
2327 $$ = cat5_str(make1_str("vacuum"), $2, $3, $4, $5);
2331 opt_verbose: VERBOSE { $$ = make1_str("verbose"); }
2332 | /*EMPTY*/ { $$ = make1_str(""); }
2335 opt_analyze: ANALYZE { $$ = make1_str("analyse"); }
2336 | /*EMPTY*/ { $$ = make1_str(""); }
2339 opt_va_list: '(' va_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
2340 | /*EMPTY*/ { $$ = make1_str(""); }
2346 { $$=cat3_str($1, make1_str(","), $3); }
2350 /*****************************************************************************
2355 *****************************************************************************/
2357 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2359 $$ = cat3_str(make1_str("explain"), $2, $3);
2364 /*****************************************************************************
2366 * Optimizable Stmts: *
2368 * one of the five queries processed by the planner *
2370 * [ultimately] produces query-trees as specified *
2371 * in the query-spec document in ~postgres/ref *
2373 *****************************************************************************/
2375 OptimizableStmt: SelectStmt
2384 /*****************************************************************************
2389 *****************************************************************************/
2391 InsertStmt: INSERT INTO relation_name opt_column_list insert_rest
2393 $$ = cat4_str(make1_str("insert into"), $3, $4, $5);
2397 insert_rest: VALUES '(' res_target_list2 ')'
2399 $$ = make3_str(make1_str("values("), $3, make1_str(")"));
2403 $$ = make1_str("default values");
2405 | SELECT opt_unique res_target_list2
2406 from_clause where_clause
2407 group_clause having_clause
2410 $$ = cat4_str(cat5_str(make1_str("select"), $2, $3, $4, $5), $6, $7, $8);
2414 opt_column_list: '(' columnList ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
2415 | /*EMPTY*/ { $$ = make1_str(""); }
2419 columnList ',' columnElem
2420 { $$ = cat3_str($1, make1_str(","), $3); }
2425 columnElem: ColId opt_indirection
2427 $$ = cat2_str($1, $2);
2432 /*****************************************************************************
2437 *****************************************************************************/
2439 DeleteStmt: DELETE FROM relation_name
2442 $$ = cat3_str(make1_str("delete from"), $3, $4);
2446 LockStmt: LOCK_P opt_table relation_name
2448 $$ = cat3_str(make1_str("lock"), $2, $3);
2450 | LOCK_P opt_table relation_name IN opt_lmode ROW IDENT IDENT
2452 if (strcasecmp($8, "MODE"))
2454 sprintf(errortext, "syntax error at or near \"%s\"", $8);
2459 if (strcasecmp($5, "SHARE"))
2461 sprintf(errortext, "syntax error at or near \"%s\"", $5);
2464 if (strcasecmp($7, "EXCLUSIVE"))
2466 sprintf(errortext, "syntax error at or near \"%s\"", $7);
2472 if (strcasecmp($7, "SHARE") && strcasecmp($7, "EXCLUSIVE"))
2474 sprintf(errortext, "syntax error at or near \"%s\"", $7);
2479 $$=cat4_str(cat5_str(make1_str("lock"), $2, $3, make1_str("in"), $5), make1_str("row"), $7, $8);
2481 | LOCK_P opt_table relation_name IN IDENT IDENT IDENT
2483 if (strcasecmp($7, "MODE"))
2485 sprintf(errortext, "syntax error at or near \"%s\"", $7);
2488 if (strcasecmp($5, "ACCESS"))
2490 sprintf(errortext, "syntax error at or near \"%s\"", $5);
2493 if (strcasecmp($6, "SHARE") && strcasecmp($6, "EXCLUSIVE"))
2495 sprintf(errortext, "syntax error at or near \"%s\"", $6);
2499 $$=cat3_str(cat5_str(make1_str("lock"), $2, $3, make1_str("in"), $5), $6, $7);
2501 | LOCK_P opt_table relation_name IN IDENT IDENT
2503 if (strcasecmp($6, "MODE"))
2505 sprintf(errortext, "syntax error at or near \"%s\"", $6);
2508 if (strcasecmp($5, "SHARE") && strcasecmp($5, "EXCLUSIVE"))
2510 sprintf(errortext, "syntax error at or near \"%s\"", $5);
2514 $$=cat2_str(cat5_str(make1_str("lock"), $2, $3, make1_str("in"), $5), $6);
2518 opt_lmode: IDENT { $$ = $1; }
2519 | /*EMPTY*/ { $$ = make1_str(""); }
2525 /*****************************************************************************
2528 * UpdateStmt (UPDATE)
2530 *****************************************************************************/
2532 UpdateStmt: UPDATE relation_name
2537 $$ = cat2_str(cat5_str(make1_str("update"), $2, make1_str("set"), $4, $5), $6);
2542 /*****************************************************************************
2547 *****************************************************************************/
2548 CursorStmt: DECLARE name opt_cursor CURSOR FOR
2549 SELECT opt_unique res_target_list2
2550 from_clause where_clause
2551 group_clause having_clause
2552 union_clause sort_clause
2555 struct cursor *ptr, *this;
2557 for (ptr = cur; ptr != NULL; ptr = ptr->next)
2559 if (strcmp($2, ptr->name) == 0)
2561 /* re-definition is a bug*/
2562 sprintf(errortext, "cursor %s already defined", $2);
2567 this = (struct cursor *) mm_alloc(sizeof(struct cursor));
2569 /* initial definition */
2572 this->command = cat4_str(cat5_str(cat5_str(make1_str("declare"), mm_strdup($2), $3, make1_str("cursor for select"), $7), $8, $9, $10, $11), $12, $13, $14);
2573 this->argsinsert = argsinsert;
2574 this->argsresult = argsresult;
2575 argsinsert = argsresult = NULL;
2579 $$ = cat3_str(make1_str("/*"), mm_strdup(this->command), make1_str("*/"));
2583 opt_cursor: BINARY { $$ = make1_str("binary"); }
2584 | INSENSITIVE { $$ = make1_str("insensitive"); }
2585 | SCROLL { $$ = make1_str("scroll"); }
2586 | INSENSITIVE SCROLL { $$ = make1_str("insensitive scroll"); }
2587 | /*EMPTY*/ { $$ = make1_str(""); }
2590 cursor_clause: FOR opt_readonly { $$ = cat2_str(make1_str("for"), $2); }
2591 | /*EMPTY*/ { $$ = make1_str(""); }
2595 opt_readonly: READ ONLY { $$ = make1_str("read only"); }
2598 yyerror("DECLARE/UPDATE not supported; Cursors must be READ ONLY.");
2602 opt_of: OF columnList { $$ = make2_str(make1_str("of"), $2); }
2604 /*****************************************************************************
2609 *****************************************************************************/
2611 SelectStmt: SELECT opt_unique res_target_list2
2612 result from_clause where_clause
2613 group_clause having_clause
2614 union_clause sort_clause
2616 $$ = cat2_str(cat5_str(cat5_str(make1_str("select"), $2, $3, $4, $5), $6, $7, $8, $9), $10);
2620 SubSelect: SELECT opt_unique res_target_list2
2621 from_clause where_clause
2622 group_clause having_clause
2625 $$ =cat4_str(cat5_str(make1_str("select"), $2, $3, $4, $5), $6, $7, $8);
2629 union_clause: UNION opt_union select_list
2631 $$ = cat3_str(make1_str("union"), $2, $3);
2634 { $$ = make1_str(""); }
2637 select_list: select_list UNION opt_union SubUnion
2639 $$ = cat4_str($1, make1_str("union"), $3, $4);
2645 SubUnion: SELECT opt_unique res_target_list2
2646 from_clause where_clause
2647 group_clause having_clause
2649 $$ = cat3_str(cat5_str(make1_str("select"), $2, $3, $4, $5), $6, $7);
2653 result: INTO opt_table relation_name { $$= cat3_str(make1_str("into"), $2, $3); }
2654 | INTO into_list { $$ = make1_str(""); }
2655 | /*EMPTY*/ { $$ = make1_str(""); }
2658 opt_table: TABLE { $$ = make1_str("table"); }
2659 | /*EMPTY*/ { $$ = make1_str(""); }
2662 opt_union: ALL { $$ = make1_str("all"); }
2663 | /*EMPTY*/ { $$ = make1_str(""); }
2666 opt_unique: DISTINCT { $$ = make1_str("distinct"); }
2667 | DISTINCT ON ColId { $$ = cat2_str(make1_str("distinct on"), $3); }
2668 | ALL { $$ = make1_str("all"); }
2669 | /*EMPTY*/ { $$ = make1_str(""); }
2672 sort_clause: ORDER BY sortby_list { $$ = cat2_str(make1_str("order by"), $3); }
2673 | /*EMPTY*/ { $$ = make1_str(""); }
2676 sortby_list: sortby { $$ = $1; }
2677 | sortby_list ',' sortby { $$ = cat3_str($1, make1_str(","), $3); }
2680 sortby: a_expr OptUseOp
2682 $$ = cat2_str($1, $2);
2686 OptUseOp: USING Op { $$ = cat2_str(make1_str("using"), $2); }
2687 | USING '<' { $$ = make1_str("using <"); }
2688 | USING '>' { $$ = make1_str("using >"); }
2689 | ASC { $$ = make1_str("asc"); }
2690 | DESC { $$ = make1_str("desc"); }
2691 | /*EMPTY*/ { $$ = make1_str(""); }
2695 * jimmy bell-style recursive queries aren't supported in the
2698 * ...however, recursive addattr and rename supported. make special
2701 opt_inh_star: '*' { $$ = make1_str("*"); }
2702 | /*EMPTY*/ { $$ = make1_str(""); }
2705 relation_name_list: name_list { $$ = $1; };
2709 | name_list ',' name
2710 { $$ = cat3_str($1, make1_str(","), $3); }
2713 group_clause: GROUP BY expr_list { $$ = cat2_str(make1_str("groub by"), $3); }
2714 | /*EMPTY*/ { $$ = make1_str(""); }
2717 having_clause: HAVING a_expr
2719 $$ = cat2_str(make1_str("having"), $2);
2721 | /*EMPTY*/ { $$ = make1_str(""); }
2725 /*****************************************************************************
2727 * clauses common to all Optimizable Stmts:
2731 *****************************************************************************/
2733 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2735 yyerror("JOIN not yet implemented");
2737 | FROM from_list { $$ = cat2_str(make1_str("from"), $2); }
2738 | /*EMPTY*/ { $$ = make1_str(""); }
2741 from_list: from_list ',' from_val
2742 { $$ = cat3_str($1, make1_str(","), $3); }
2743 | from_val CROSS JOIN from_val
2744 { yyerror("CROSS JOIN not yet implemented"); }
2749 from_val: relation_expr AS ColLabel
2751 $$ = cat3_str($1, make1_str("as"), $3);
2753 | relation_expr ColId
2755 $$ = cat2_str($1, $2);
2763 join_expr: NATURAL join_expr { $$ = cat2_str(make1_str("natural"), $2); }
2765 { yyerror("FULL OUTER JOIN not yet implemented"); }
2767 { yyerror("LEFT OUTER JOIN not yet implemented"); }
2769 { yyerror("RIGHT OUTER JOIN not yet implemented"); }
2771 { yyerror("OUTER JOIN not yet implemented"); }
2773 { yyerror("INNER JOIN not yet implemented"); }
2775 { yyerror("UNION JOIN not yet implemented"); }
2777 { yyerror("INNER JOIN not yet implemented"); }
2780 join_outer: OUTER_P { $$ = make1_str("outer"); }
2781 | /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
2784 join_spec: ON '(' a_expr ')' { $$ = make3_str(make1_str("on ("), $3, make1_str(")")); }
2785 | USING '(' join_list ')' { $$ = make3_str(make1_str("using ("), $3, make1_str(")")); }
2786 | /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
2789 join_list: join_using { $$ = $1; }
2790 | join_list ',' join_using { $$ = cat3_str($1, make1_str(","), $3); }
2799 $$ = make3_str($1, make1_str("."), $3);
2807 where_clause: WHERE a_expr { $$ = cat2_str(make1_str("where"), $2); }
2808 | /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
2811 relation_expr: relation_name
2813 /* normal relations */
2816 | relation_name '*' %prec '='
2818 /* inheritance query */
2819 $$ = cat2_str($1, make1_str("*"));
2822 opt_array_bounds: '[' ']' nest_array_bounds
2825 $$.index2 = $3.index1;
2826 $$.str = cat2_str(make1_str("[]"), $3.str);
2828 | '[' Iconst ']' nest_array_bounds
2830 $$.index1 = atol($2);
2831 $$.index2 = $4.index1;
2832 $$.str = cat4_str(make1_str("["), $2, make1_str("]"), $4.str);
2838 $$.str= make1_str("");
2842 nest_array_bounds: '[' ']' nest_array_bounds
2845 $$.index2 = $3.index1;
2846 $$.str = cat2_str(make1_str("[]"), $3.str);
2848 | '[' Iconst ']' nest_array_bounds
2850 $$.index1 = atol($2);
2851 $$.index2 = $4.index1;
2852 $$.str = cat4_str(make1_str("["), $2, make1_str("]"), $4.str);
2858 $$.str= make1_str("");
2862 /*****************************************************************************
2865 * SQL92 introduces a large amount of type-specific syntax.
2866 * Define individual clauses to handle these cases, and use
2867 * the generic case to handle regular type-extensible Postgres syntax.
2868 * - thomas 1997-10-10
2870 *****************************************************************************/
2872 Typename: Array opt_array_bounds
2874 $$ = cat2_str($1, $2.str);
2876 | Character { $$ = $1; }
2879 $$ = cat2_str(make1_str("setof"), $2);
2884 | Datetime { $$ = $1; }
2885 | Numeric { $$ = $1; }
2894 generic: ident { $$ = $1; }
2895 | TYPE_P { $$ = make1_str("type"); }
2898 /* SQL92 numeric data types
2899 * Check FLOAT() precision limits assuming IEEE floating types.
2900 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2901 * by checking parameters and making sure they match what is possible with INTEGER.
2902 * - thomas 1997-09-18
2904 Numeric: FLOAT opt_float
2906 $$ = cat2_str(make1_str("float"), $2);
2910 $$ = make1_str("double precision");
2912 | DECIMAL opt_decimal
2914 $$ = cat2_str(make1_str("decimal"), $2);
2916 | NUMERIC opt_numeric
2918 $$ = cat2_str(make1_str("numeric"), $2);
2923 { $$ = make1_str("float"); }
2925 { $$ = make1_str("double precision"); }
2927 { $$ = make1_str("decimal"); }
2929 { $$ = make1_str("numeric"); }
2932 opt_float: '(' Iconst ')'
2935 yyerror("precision for FLOAT must be at least 1");
2936 else if (atol($2) >= 16)
2937 yyerror("precision for FLOAT must be less than 16");
2938 $$ = make3_str(make1_str("("), $2, make1_str(")"));
2946 opt_numeric: '(' Iconst ',' Iconst ')'
2948 if (atol($2) != 9) {
2949 sprintf(errortext, make1_str("NUMERIC precision %s must be 9"), $2);
2952 if (atol($4) != 0) {
2953 sprintf(errortext, "NUMERIC scale %s must be zero", $4);
2956 $$ = cat3_str(make2_str(make1_str("("), $2), make1_str(","), make2_str($4, make1_str(")")));
2960 if (atol($2) != 9) {
2961 sprintf("NUMERIC precision %s must be 9",$2);
2964 $$ = make3_str(make1_str("("), $2, make1_str(")"));
2972 opt_decimal: '(' Iconst ',' Iconst ')'
2974 if (atol($2) != 9) {
2975 sprintf(errortext, "DECIMAL precision %s exceeds implementation limit of 9", $2);
2978 if (atol($4) != 0) {
2979 sprintf(errortext, "DECIMAL scale %s must be zero",$4);
2982 $$ = cat3_str(make2_str(make1_str("("), $2), make1_str(","), make2_str($4, make1_str(")")));
2986 if (atol($2) != 9) {
2987 sprintf(errortext, "DECIMAL precision %s exceeds implementation limit of 9",$2);
2990 $$ = make3_str(make1_str("("), $2, make1_str(")"));
2998 /* SQL92 character data types
2999 * The following implements CHAR() and VARCHAR().
3000 * We do it here instead of the 'Generic' production
3001 * because we don't want to allow arrays of VARCHAR().
3002 * I haven't thought about whether that will work or not.
3005 Character: character '(' Iconst ')'
3007 if (strncasecmp($1, "char", strlen("char")) && strncasecmp($1, "varchar", strlen("varchar")))
3008 yyerror("internal parsing error; unrecognized character type");
3010 sprintf(errortext, "length for '%s' type must be at least 1",$1);
3013 else if (atol($3) > 4096) {
3014 /* we can store a char() of length up to the size
3015 * of a page (8KB) - page headers and friends but
3016 * just to be safe here... - ay 6/95
3017 * XXX note this hardcoded limit - thomas 1997-07-13
3019 sprintf(errortext, "length for type '%s' cannot exceed 4096",$1);
3023 $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")")));
3031 character: CHARACTER opt_varying opt_charset opt_collate
3034 fprintf(stderr, "COLLATE %s not yet implemented",$4);
3036 $$ = cat4_str(make1_str("character"), $2, $3, $4);
3038 | CHAR opt_varying { $$ = cat2_str(make1_str("char"), $2); }
3039 | VARCHAR { $$ = make1_str("varchar"); }
3040 | NATIONAL CHARACTER opt_varying { $$ = cat2_str(make1_str("national character"), $3); }
3041 | NCHAR opt_varying { $$ = cat2_str(make1_str("nchar"), $2); }
3044 opt_varying: VARYING { $$ = make1_str("varying"); }
3045 | /*EMPTY*/ { $$ = make1_str(""); }
3048 opt_charset: CHARACTER SET ColId { $$ = cat2_str(make1_str("character set"), $3); }
3049 | /*EMPTY*/ { $$ = make1_str(""); }
3052 opt_collate: COLLATE ColId { $$ = cat2_str(make1_str("collate"), $2); }
3053 | /*EMPTY*/ { $$ = make1_str(""); }
3060 | TIMESTAMP opt_timezone
3062 $$ = cat2_str(make1_str("timestamp"), $2);
3066 $$ = make1_str("time");
3068 | INTERVAL opt_interval
3070 $$ = cat2_str(make1_str("interval"), $2);
3074 datetime: YEAR_P { $$ = make1_str("year"); }
3075 | MONTH_P { $$ = make1_str("month"); }
3076 | DAY_P { $$ = make1_str("day"); }
3077 | HOUR_P { $$ = make1_str("hour"); }
3078 | MINUTE_P { $$ = make1_str("minute"); }
3079 | SECOND_P { $$ = make1_str("second"); }
3082 opt_timezone: WITH TIME ZONE { $$ = make1_str("with time zone"); }
3083 | /*EMPTY*/ { $$ = make1_str(""); }
3086 opt_interval: datetime { $$ = $1; }
3087 | YEAR_P TO MONTH_P { $$ = make1_str("year to #month"); }
3088 | DAY_P TO HOUR_P { $$ = make1_str("day to hour"); }
3089 | DAY_P TO MINUTE_P { $$ = make1_str("day to minute"); }
3090 | DAY_P TO SECOND_P { $$ = make1_str("day to second"); }
3091 | HOUR_P TO MINUTE_P { $$ = make1_str("hour to minute"); }
3092 | MINUTE_P TO SECOND_P { $$ = make1_str("minute to second"); }
3093 | HOUR_P TO SECOND_P { $$ = make1_str("hour to second"); }
3094 | /*EMPTY*/ { $$ = make1_str(""); }
3098 /*****************************************************************************
3100 * expression grammar, still needs some cleanup
3102 *****************************************************************************/
3104 a_expr_or_null: a_expr
3108 $$ = make1_str("null");
3112 /* Expressions using row descriptors
3113 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
3114 * with singleton expressions.
3115 * Eliminated lots of code by defining row_op and sub_type clauses.
3116 * However, can not consolidate EXPR_LINK case with others subselects
3117 * due to shift/reduce conflict with the non-subselect clause (the parser
3118 * would have to look ahead more than one token to resolve the conflict).
3119 * - thomas 1998-05-09
3121 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
3123 $$ = make5_str(make1_str("("), $2, make1_str(") in ("), $6, make1_str(")"));
3125 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
3127 $$ = make5_str(make1_str("("), $2, make1_str(") not in ("), $7, make1_str(")"));
3129 | '(' row_descriptor ')' row_op sub_type '(' SubSelect ')'
3131 $$ = make4_str(make5_str(make1_str("("), $2, make1_str(")"), $4, $5), make1_str("("), $7, make1_str(")"));
3133 | '(' row_descriptor ')' row_op '(' SubSelect ')'
3135 $$ = make3_str(make5_str(make1_str("("), $2, make1_str(")"), $4, make1_str("(")), $6, make1_str(")"));
3137 | '(' row_descriptor ')' row_op '(' row_descriptor ')'
3139 $$ = cat3_str(make3_str(make1_str("("), $2, make1_str(")")), $4, make3_str(make1_str("("), $6, make1_str(")")));
3143 row_descriptor: row_list ',' a_expr
3145 $$ = cat3_str($1, make1_str(","), $3);
3149 row_op: Op { $$ = $1; }
3159 sub_type: ANY { $$ = make1_str("ANY"); }
3160 | ALL { $$ = make1_str("ALL"); }
3164 row_list: row_list ',' a_expr
3166 $$ = cat3_str($1, make1_str(","), $3);
3174 /* General expressions
3175 * This is the heart of the expression syntax.
3176 * Note that the BETWEEN clause looks similar to a boolean expression
3177 * and so we must define b_expr which is almost the same as a_expr
3178 * but without the boolean expressions.
3179 * All operations/expressions are allowed in a BETWEEN clause
3180 * if surrounded by parens.
3183 a_expr: attr opt_indirection
3185 $$ = cat2_str($1, $2);
3195 | '-' a_expr %prec UMINUS
3196 { $$ = cat2_str(make1_str("-"), $2); }
3198 { $$ = cat3_str($1, make1_str("+"), $3); }
3200 { $$ = cat3_str($1, make1_str("-"), $3); }
3202 { $$ = cat3_str($1, make1_str("/"), $3); }
3204 { $$ = cat3_str($1, make1_str("*"), $3); }
3206 { $$ = cat3_str($1, make1_str("<"), $3); }
3208 { $$ = cat3_str($1, make1_str(">"), $3); }
3210 { $$ = cat3_str($1, make1_str("="), $3); }
3211 /* not possible in embedded sql | ':' a_expr
3212 { $$ = cat2_str(make1_str(":"), $2); }
3215 { $$ = cat2_str(make1_str(";"), $2); }
3217 { $$ = cat2_str(make1_str("|"), $2); }
3218 | a_expr TYPECAST Typename
3220 $$ = cat3_str($1, make1_str("::"), $3);
3222 | CAST '(' a_expr AS Typename ')'
3224 $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
3226 | '(' a_expr_or_null ')'
3227 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
3229 { $$ = cat3_str($1, $2, $3); }
3230 | a_expr LIKE a_expr
3231 { $$ = cat3_str($1, make1_str("like"), $3); }
3232 | a_expr NOT LIKE a_expr
3233 { $$ = cat3_str($1, make1_str("not like"), $4); }
3235 { $$ = cat2_str($1, $2); }
3237 { $$ = cat2_str($1, $2); }
3238 | func_name '(' '*' ')'
3240 $$ = cat2_str($1, make1_str("(*)"));
3244 $$ = cat2_str($1, make1_str("()"));
3246 | func_name '(' expr_list ')'
3248 $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
3252 $$ = make1_str("current_date");
3256 $$ = make1_str("current_time");
3258 | CURRENT_TIME '(' Iconst ')'
3261 fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
3262 $$ = make1_str("current_time");
3266 $$ = make1_str("current_timestamp");
3268 | CURRENT_TIMESTAMP '(' Iconst ')'
3271 fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
3272 $$ = make1_str("current_timestamp");
3276 $$ = make1_str("current_user");
3280 $$ = make1_str("user");
3283 | EXISTS '(' SubSelect ')'
3285 $$ = make3_str(make1_str("exists("), $3, make1_str(")"));
3287 | EXTRACT '(' extract_list ')'
3289 $$ = make3_str(make1_str("extract("), $3, make1_str(")"));
3291 | POSITION '(' position_list ')'
3293 $$ = make3_str(make1_str("position("), $3, make1_str(")"));
3295 | SUBSTRING '(' substr_list ')'
3297 $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
3299 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3300 | TRIM '(' BOTH trim_list ')'
3302 $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
3304 | TRIM '(' LEADING trim_list ')'
3306 $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
3308 | TRIM '(' TRAILING trim_list ')'
3310 $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
3312 | TRIM '(' trim_list ')'
3314 $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
3317 { $$ = cat2_str($1, make1_str("isnull")); }
3319 { $$ = cat2_str($1, make1_str("is null")); }
3321 { $$ = cat2_str($1, make1_str("notnull")); }
3322 | a_expr IS NOT NULL_P
3323 { $$ = cat2_str($1, make1_str("is not null")); }
3324 /* IS TRUE, IS FALSE, etc used to be function calls
3325 * but let's make them expressions to allow the optimizer
3326 * a chance to eliminate them if a_expr is a constant string.
3327 * - thomas 1997-12-22
3331 { $$ = cat2_str($1, make1_str("is true")); }
3333 | a_expr IS NOT FALSE_P
3335 { $$ = cat2_str($1, make1_str("is not false")); }
3339 { $$ = cat2_str($1, make1_str("is false")); }
3341 | a_expr IS NOT TRUE_P
3343 { $$ = cat2_str($1, make1_str("is not true")); }
3345 | a_expr BETWEEN b_expr AND b_expr
3347 $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5);
3349 | a_expr NOT BETWEEN b_expr AND b_expr
3351 $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6);
3353 | a_expr IN '(' in_expr ')'
3355 $$ = make4_str($1, make1_str("in ("), $4, make1_str(")"));
3357 | a_expr NOT IN '(' not_in_expr ')'
3359 $$ = make4_str($1, make1_str("not in ("), $5, make1_str(")"));
3361 | a_expr Op '(' SubSelect ')'
3363 $$ = cat3_str($1, $2, make3_str(make1_str("("), $4, make1_str(")")));
3365 | a_expr '+' '(' SubSelect ')'
3367 $$ = make4_str($1, make1_str("+("), $4, make1_str(")"));
3369 | a_expr '-' '(' SubSelect ')'
3371 $$ = make4_str($1, make1_str("-("), $4, make1_str(")"));
3373 | a_expr '/' '(' SubSelect ')'
3375 $$ = make4_str($1, make1_str("/("), $4, make1_str(")"));
3377 | a_expr '*' '(' SubSelect ')'
3379 $$ = make4_str($1, make1_str("*("), $4, make1_str(")"));
3381 | a_expr '<' '(' SubSelect ')'
3383 $$ = make4_str($1, make1_str("<("), $4, make1_str(")"));
3385 | a_expr '>' '(' SubSelect ')'
3387 $$ = make4_str($1, make1_str(">("), $4, make1_str(")"));
3389 | a_expr '=' '(' SubSelect ')'
3391 $$ = make4_str($1, make1_str("=("), $4, make1_str(")"));
3393 | a_expr Op ANY '(' SubSelect ')'
3395 $$ = cat3_str($1, $2, make3_str(make1_str("any("), $5, make1_str(")")));
3397 | a_expr '+' ANY '(' SubSelect ')'
3399 $$ = make4_str($1, make1_str("+any("), $5, make1_str(")"));
3401 | a_expr '-' ANY '(' SubSelect ')'
3403 $$ = make4_str($1, make1_str("-any("), $5, make1_str(")"));
3405 | a_expr '/' ANY '(' SubSelect ')'
3407 $$ = make4_str($1, make1_str("/any("), $5, make1_str(")"));
3409 | a_expr '*' ANY '(' SubSelect ')'
3411 $$ = make4_str($1, make1_str("*any("), $5, make1_str(")"));
3413 | a_expr '<' ANY '(' SubSelect ')'
3415 $$ = make4_str($1, make1_str("<any("), $5, make1_str(")"));
3417 | a_expr '>' ANY '(' SubSelect ')'
3419 $$ = make4_str($1, make1_str(">any("), $5, make1_str(")"));
3421 | a_expr '=' ANY '(' SubSelect ')'
3423 $$ = make4_str($1, make1_str("=any("), $5, make1_str(")"));
3425 | a_expr Op ALL '(' SubSelect ')'
3427 $$ = cat3_str($1, $2, make3_str(make1_str("all ("), $5, make1_str(")")));
3429 | a_expr '+' ALL '(' SubSelect ')'
3431 $$ = make4_str($1, make1_str("+all("), $5, make1_str(")"));
3433 | a_expr '-' ALL '(' SubSelect ')'
3435 $$ = make4_str($1, make1_str("-all("), $5, make1_str(")"));
3437 | a_expr '/' ALL '(' SubSelect ')'
3439 $$ = make4_str($1, make1_str("/all("), $5, make1_str(")"));
3441 | a_expr '*' ALL '(' SubSelect ')'
3443 $$ = make4_str($1, make1_str("*all("), $5, make1_str(")"));
3445 | a_expr '<' ALL '(' SubSelect ')'
3447 $$ = make4_str($1, make1_str("<all("), $5, make1_str(")"));
3449 | a_expr '>' ALL '(' SubSelect ')'
3451 $$ = make4_str($1, make1_str(">all("), $5, make1_str(")"));
3453 | a_expr '=' ALL '(' SubSelect ')'
3455 $$ = make4_str($1, make1_str("=all("), $5, make1_str(")"));
3458 { $$ = cat3_str($1, make1_str("and"), $3); }
3460 { $$ = cat3_str($1, make1_str("or"), $3); }
3462 { $$ = cat2_str(make1_str("not"), $2); }
3466 { $$ = make1_str(";;"); }
3469 /* Restricted expressions
3470 * b_expr is a subset of the complete expression syntax
3471 * defined by a_expr. b_expr is used in BETWEEN clauses
3472 * to eliminate parser ambiguities stemming from the AND keyword.
3474 b_expr: attr opt_indirection
3476 $$ = cat2_str($1, $2);
3484 | '-' b_expr %prec UMINUS
3485 { $$ = cat2_str(make1_str("-"), $2); }
3487 { $$ = cat3_str($1, make1_str("+"), $3); }
3489 { $$ = cat3_str($1, make1_str("-"), $3); }
3491 { $$ = cat3_str($1, make1_str("/"), $3); }
3493 { $$ = cat3_str($1, make1_str("*"), $3); }
3494 /* not possible in embedded sql | ':' b_expr
3495 { $$ = cat2_str(make1_str(":"), $2); }
3498 { $$ = cat2_str(make1_str(";"), $2); }
3500 { $$ = cat2_str(make1_str("|"), $2); }
3501 | b_expr TYPECAST Typename
3503 $$ = cat3_str($1, make1_str("::"), $3);
3505 | CAST '(' b_expr AS Typename ')'
3507 $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
3510 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
3512 { $$ = cat3_str($1, $2, $3); }
3514 { $$ = cat2_str($1, $2); }
3516 { $$ = cat2_str($1, $2); }
3519 $$ = cat2_str($1, make1_str("()"));
3521 | func_name '(' expr_list ')'
3523 $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
3527 $$ = make1_str("current_date");
3531 $$ = make1_str("current_time");
3533 | CURRENT_TIME '(' Iconst ')'
3536 fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
3537 $$ = make1_str("current_time");
3541 $$ = make1_str("current_timestamp");
3543 | CURRENT_TIMESTAMP '(' Iconst ')'
3546 fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
3547 $$ = make1_str("current_timestamp");
3551 $$ = make1_str("current_user");
3555 $$ = make1_str("user");
3557 | POSITION '(' position_list ')'
3559 $$ = make3_str(make1_str("position ("), $3, make1_str(")"));
3561 | SUBSTRING '(' substr_list ')'
3563 $$ = make3_str(make1_str("substring ("), $3, make1_str(")"));
3565 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3566 | TRIM '(' BOTH trim_list ')'
3568 $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
3570 | TRIM '(' LEADING trim_list ')'
3572 $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
3574 | TRIM '(' TRAILING trim_list ')'
3576 $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
3578 | TRIM '(' trim_list ')'
3580 $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
3583 { $$ = make1_str(";;"); }
3586 opt_indirection: '[' ecpg_expr ']' opt_indirection
3588 $$ = cat4_str(make1_str("["), $2, make1_str("]"), $4);
3590 | '[' ecpg_expr ':' ecpg_expr ']' opt_indirection
3592 $$ = cat2_str(cat5_str(make1_str("["), $2, make1_str(":"), $4, make1_str("]")), $6);
3595 { $$ = make1_str(""); }
3598 expr_list: a_expr_or_null
3600 | expr_list ',' a_expr_or_null
3601 { $$ = cat3_str($1, make1_str(","), $3); }
3602 | expr_list USING a_expr
3603 { $$ = cat3_str($1, make1_str("using"), $3); }
3606 extract_list: extract_arg FROM a_expr
3608 $$ = cat3_str($1, make1_str("from"), $3);
3611 { $$ = make1_str(""); }
3613 { $$ = make1_str(";;"); }
3616 extract_arg: datetime { $$ = $1; }
3617 | TIMEZONE_HOUR { $$ = make1_str("timezone_hour"); }
3618 | TIMEZONE_MINUTE { $$ = make1_str("timezone_minute"); }
3621 position_list: position_expr IN position_expr
3622 { $$ = cat3_str($1, make1_str("in"), $3); }
3624 { $$ = make1_str(""); }
3627 position_expr: attr opt_indirection
3629 $$ = cat2_str($1, $2);
3633 | '-' position_expr %prec UMINUS
3634 { $$ = cat2_str(make1_str("-"), $2); }
3635 | position_expr '+' position_expr
3636 { $$ = cat3_str($1, make1_str("+"), $3); }
3637 | position_expr '-' position_expr
3638 { $$ = cat3_str($1, make1_str("-"), $3); }
3639 | position_expr '/' position_expr
3640 { $$ = cat3_str($1, make1_str("/"), $3); }
3641 | position_expr '*' position_expr
3642 { $$ = cat3_str($1, make1_str("*"), $3); }
3644 { $$ = cat2_str(make1_str("|"), $2); }
3645 | position_expr TYPECAST Typename
3647 $$ = cat3_str($1, make1_str("::"), $3);
3649 | CAST '(' position_expr AS Typename ')'
3651 $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
3653 | '(' position_expr ')'
3654 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
3655 | position_expr Op position_expr
3656 { $$ = cat3_str($1, $2, $3); }
3658 { $$ = cat2_str($1, $2); }
3660 { $$ = cat2_str($1, $2); }
3667 $$ = cat2_str($1, make1_str("()"));
3669 | func_name '(' expr_list ')'
3671 $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
3673 | POSITION '(' position_list ')'
3675 $$ = make3_str(make1_str("position("), $3, make1_str(")"));
3677 | SUBSTRING '(' substr_list ')'
3679 $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
3681 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3682 | TRIM '(' BOTH trim_list ')'
3684 $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
3686 | TRIM '(' LEADING trim_list ')'
3688 $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
3690 | TRIM '(' TRAILING trim_list ')'
3692 $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
3694 | TRIM '(' trim_list ')'
3696 $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
3700 substr_list: expr_list substr_from substr_for
3702 $$ = cat3_str($1, $2, $3);
3705 { $$ = make1_str(""); }
3708 substr_from: FROM expr_list
3709 { $$ = cat2_str(make1_str("from"), $2); }
3716 substr_for: FOR expr_list
3717 { $$ = cat2_str(make1_str("for"), $2); }
3719 { $$ = make1_str(""); }
3722 trim_list: a_expr FROM expr_list
3723 { $$ = cat3_str($1, make1_str("from"), $3); }
3725 { $$ = cat2_str(make1_str("from"), $2); }
3738 in_expr_nodes: AexprConst
3740 | in_expr_nodes ',' AexprConst
3741 { $$ = cat3_str($1, make1_str(","), $3);}
3744 not_in_expr: SubSelect
3752 not_in_expr_nodes: AexprConst
3754 | not_in_expr_nodes ',' AexprConst
3755 { $$ = cat3_str($1, make1_str(","), $3);}
3759 * Define SQL92-style case clause.
3760 * Allow all four forms described in the standard:
3761 * - Full specification
3762 * CASE WHEN a = b THEN c ... ELSE d END
3763 * - Implicit argument
3764 * CASE a WHEN b THEN c ... ELSE d END
3765 * - Conditional NULL
3767 * same as CASE WHEN x = y THEN NULL ELSE x END
3768 * - Conditional substitution from list, use first non-null argument
3770 * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
3771 * - thomas 1998-11-09
3773 case_expr: CASE case_arg when_clause_list case_default END_TRANS
3774 { $$ = cat5_str(make1_str("case"), $2, $3, $4, make1_str("end")); }
3775 | NULLIF '(' a_expr ',' a_expr ')'
3777 $$ = cat5_str(make1_str("nullif("), $3, make1_str(","), $5, make1_str(")"));
3779 fprintf(stderr, "NULLIF() not yet fully implemented");
3781 | COALESCE '(' expr_list ')'
3783 $$ = cat3_str(make1_str("coalesce("), $3, make1_str(")"));
3785 fprintf(stderr, "COALESCE() not yet fully implemented");
3789 when_clause_list: when_clause_list when_clause
3790 { $$ = cat2_str($1, $2); }
3795 when_clause: WHEN a_expr THEN a_expr_or_null
3797 $$ = cat4_str(make1_str("when"), $2, make1_str("then"), $4);
3801 case_default: ELSE a_expr_or_null { $$ = cat2_str(make1_str("else"), $2); }
3802 | /*EMPTY*/ { $$ = make1_str(""); }
3805 case_arg: attr opt_indirection
3807 $$ = cat2_str($1, $2);
3814 { $$ = make1_str(""); }
3817 attr: relation_name '.' attrs
3819 $$ = make3_str($1, make1_str("."), $3);
3823 $$ = make3_str($1, make1_str("."), $3);
3829 | attrs '.' attr_name
3830 { $$ = make3_str($1, make1_str("."), $3); }
3832 { $$ = make2_str($1, make1_str(".*")); }
3836 /*****************************************************************************
3840 *****************************************************************************/
3842 res_target_list: res_target_list ',' res_target_el
3843 { $$ = cat3_str($1, make1_str(","),$3); }
3846 | '*' { $$ = make1_str("*"); }
3849 res_target_el: ColId opt_indirection '=' a_expr_or_null
3851 $$ = cat4_str($1, $2, make1_str("="), $4);
3853 | attr opt_indirection
3855 $$ = cat2_str($1, $2);
3857 | relation_name '.' '*'
3859 $$ = make2_str($1, make1_str(".*"));
3864 ** target list for select.
3865 ** should get rid of the other but is still needed by the defunct select into
3866 ** and update (uses a subset)
3868 res_target_list2: res_target_list2 ',' res_target_el2
3869 { $$ = cat3_str($1, make1_str(","), $3); }
3874 /* AS is not optional because shift/red conflict with unary ops */
3875 res_target_el2: a_expr_or_null AS ColLabel
3877 $$ = cat3_str($1, make1_str("as"), $3);
3883 | relation_name '.' '*'
3885 $$ = make2_str($1, make1_str(".*"));
3889 $$ = make1_str("*");
3893 opt_id: ColId { $$ = $1; }
3894 | /* EMPTY */ { $$ = make1_str(""); }
3897 relation_name: SpecialRuleRelation
3903 /* disallow refs to variable system tables */
3904 if (strcmp(LogRelationName, $1) == 0
3905 || strcmp(VariableRelationName, $1) == 0) {
3906 sprintf(errortext, make1_str("%s cannot be accessed by users"),$1);
3914 database_name: ColId { $$ = $1; };
3915 access_method: ident { $$ = $1; };
3916 attr_name: ColId { $$ = $1; };
3917 class: ident { $$ = $1; };
3918 index_name: ColId { $$ = $1; };
3921 * Include date/time keywords as SQL92 extension.
3922 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
3924 name: ColId { $$ = $1; };
3925 func_name: ColId { $$ = $1; };
3927 file_name: Sconst { $$ = $1; };
3928 recipe_name: ident { $$ = $1; };
3931 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
3947 $$ = cat2_str($1, $2);
3953 $$ = make1_str("true");
3957 $$ = make1_str("false");
3961 ParamNo: PARAM opt_indirection
3963 $$ = cat2_str(make_name(), $2);
3967 Iconst: ICONST { $$ = make_name();};
3968 Fconst: FCONST { $$ = make_name();};
3970 $$ = (char *)mm_alloc(strlen($1) + 3);
3973 $$[strlen($1)+2]='\0';
3974 $$[strlen($1)+1]='\'';
3977 UserId: ident { $$ = $1;};
3979 /* Column and type identifier
3980 * Does not include explicit datetime types
3981 * since these must be decoupled in Typename syntax.
3982 * Use ColId for most identifiers. - thomas 1997-10-21
3991 /* Column identifier
3992 * Include date/time keywords as SQL92 extension.
3993 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
3994 * Add other keywords. Note that as the syntax expands,
3995 * some of these keywords will have to be removed from this
3996 * list due to shift/reduce conflicts in yacc. If so, move
3997 * down to the ColLabel entity. - thomas 1997-11-06
3999 ColId: ident { $$ = $1; }
4000 | datetime { $$ = $1; }
4001 | ABSOLUTE { $$ = make1_str("absolute"); }
4002 | ACTION { $$ = make1_str("action"); }
4003 | AFTER { $$ = make1_str("after"); }
4004 | AGGREGATE { $$ = make1_str("aggregate"); }
4005 | BACKWARD { $$ = make1_str("backward"); }
4006 | BEFORE { $$ = make1_str("before"); }
4007 | CACHE { $$ = make1_str("cache"); }
4008 | CREATEDB { $$ = make1_str("createdb"); }
4009 | CREATEUSER { $$ = make1_str("createuser"); }
4010 | CYCLE { $$ = make1_str("cycle"); }
4011 | DATABASE { $$ = make1_str("database"); }
4012 | DELIMITERS { $$ = make1_str("delimiters"); }
4013 | DOUBLE { $$ = make1_str("double"); }
4014 | EACH { $$ = make1_str("each"); }
4015 | ENCODING { $$ = make1_str("encoding"); }
4016 | FORWARD { $$ = make1_str("forward"); }
4017 | FUNCTION { $$ = make1_str("function"); }
4018 | HANDLER { $$ = make1_str("handler"); }
4019 | INCREMENT { $$ = make1_str("increment"); }
4020 | INDEX { $$ = make1_str("index"); }
4021 | INHERITS { $$ = make1_str("inherits"); }
4022 | INSENSITIVE { $$ = make1_str("insensitive"); }
4023 | INSTEAD { $$ = make1_str("instead"); }
4024 | ISNULL { $$ = make1_str("isnull"); }
4025 | KEY { $$ = make1_str("key"); }
4026 | LANGUAGE { $$ = make1_str("language"); }
4027 | LANCOMPILER { $$ = make1_str("lancompiler"); }
4028 | LOCATION { $$ = make1_str("location"); }
4029 | MATCH { $$ = make1_str("match"); }
4030 | MAXVALUE { $$ = make1_str("maxvalue"); }
4031 | MINVALUE { $$ = make1_str("minvalue"); }
4032 | NEXT { $$ = make1_str("next"); }
4033 | NOCREATEDB { $$ = make1_str("nocreatedb"); }
4034 | NOCREATEUSER { $$ = make1_str("nocreateuser"); }
4035 | NOTHING { $$ = make1_str("nothing"); }
4036 | NOTNULL { $$ = make1_str("notnull"); }
4037 | OF { $$ = make1_str("of"); }
4038 | OIDS { $$ = make1_str("oids"); }
4039 | ONLY { $$ = make1_str("only"); }
4040 | OPERATOR { $$ = make1_str("operator"); }
4041 | OPTION { $$ = make1_str("option"); }
4042 | PASSWORD { $$ = make1_str("password"); }
4043 | PRIOR { $$ = make1_str("prior"); }
4044 | PRIVILEGES { $$ = make1_str("privileges"); }
4045 | PROCEDURAL { $$ = make1_str("procedural"); }
4046 | READ { $$ = make1_str("read"); }
4047 | RECIPE { $$ = make1_str("recipe"); }
4048 | RELATIVE { $$ = make1_str("relative"); }
4049 | RENAME { $$ = make1_str("rename"); }
4050 | RETURNS { $$ = make1_str("returns"); }
4051 | ROW { $$ = make1_str("row"); }
4052 | RULE { $$ = make1_str("rule"); }
4053 | SCROLL { $$ = make1_str("scroll"); }
4054 | SEQUENCE { $$ = make1_str("sequence"); }
4055 | SERIAL { $$ = make1_str("serial"); }
4056 | START { $$ = make1_str("start"); }
4057 | STATEMENT { $$ = make1_str("statement"); }
4058 | STDIN { $$ = make1_str("stdin"); }
4059 | STDOUT { $$ = make1_str("stdout"); }
4060 | TIME { $$ = make1_str("time"); }
4061 | TIMESTAMP { $$ = make1_str("timestamp"); }
4062 | TIMEZONE_HOUR { $$ = make1_str("timezone_hour"); }
4063 | TIMEZONE_MINUTE { $$ = make1_str("timezone_minute"); }
4064 | TRIGGER { $$ = make1_str("trigger"); }
4065 | TRUSTED { $$ = make1_str("trusted"); }
4066 | TYPE_P { $$ = make1_str("type"); }
4067 | VALID { $$ = make1_str("valid"); }
4068 | VERSION { $$ = make1_str("version"); }
4069 | ZONE { $$ = make1_str("zone"); }
4072 * Allowed labels in "AS" clauses.
4073 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
4074 * compatibility. Cannot allow this for column names since the
4075 * syntax would not distinguish between the constant value and
4076 * a column name. - thomas 1997-10-24
4077 * Add other keywords to this list. Note that they appear here
4078 * rather than in ColId if there was a shift/reduce conflict
4079 * when used as a full identifier. - thomas 1997-11-06
4081 ColLabel: ColId { $$ = $1; }
4082 | ABORT_TRANS { $$ = make1_str("abort"); }
4083 | ANALYZE { $$ = make1_str("analyze"); }
4084 | BINARY { $$ = make1_str("binary"); }
4085 | CASE { $$ = make1_str("case"); }
4086 | CLUSTER { $$ = make1_str("cluster"); }
4087 | COALESCE { $$ = make1_str("coalesce"); }
4088 | CONSTRAINT { $$ = make1_str("constraint"); }
4089 | COPY { $$ = make1_str("copy"); }
4090 | CROSS { $$ = make1_str("cross"); }
4091 | CURRENT { $$ = make1_str("current"); }
4092 | DO { $$ = make1_str("do"); }
4093 | ELSE { $$ = make1_str("else"); }
4094 | END_TRANS { $$ = make1_str("end"); }
4095 | EXPLAIN { $$ = make1_str("explain"); }
4096 | EXTEND { $$ = make1_str("extend"); }
4097 | FALSE_P { $$ = make1_str("false"); }
4098 | FOREIGN { $$ = make1_str("foreign"); }
4099 | GROUP { $$ = make1_str("group"); }
4100 | LISTEN { $$ = make1_str("listen"); }
4101 | LOAD { $$ = make1_str("load"); }
4102 | LOCK_P { $$ = make1_str("lock"); }
4103 | MOVE { $$ = make1_str("move"); }
4104 | NEW { $$ = make1_str("new"); }
4105 | NONE { $$ = make1_str("none"); }
4106 | NULLIF { $$ = make1_str("nullif"); }
4107 | ORDER { $$ = make1_str("order"); }
4108 | POSITION { $$ = make1_str("position"); }
4109 | PRECISION { $$ = make1_str("precision"); }
4110 | RESET { $$ = make1_str("reset"); }
4111 | SETOF { $$ = make1_str("setof"); }
4112 | SHOW { $$ = make1_str("show"); }
4113 | TABLE { $$ = make1_str("table"); }
4114 | THEN { $$ = make1_str("then"); }
4115 | TRANSACTION { $$ = make1_str("transaction"); }
4116 | TRUE_P { $$ = make1_str("true"); }
4117 | VACUUM { $$ = make1_str("vacuum"); }
4118 | VERBOSE { $$ = make1_str("verbose"); }
4119 | WHEN { $$ = make1_str("when"); }
4122 SpecialRuleRelation: CURRENT
4125 $$ = make1_str("current");
4127 yyerror("CURRENT used in non-rule query");
4132 $$ = make1_str("new");
4134 yyerror("NEW used in non-rule query");
4139 * and now special embedded SQL stuff
4143 * variable declaration inside the exec sql declare block
4145 ECPGDeclaration: sql_startdeclare variable_declarations sql_enddeclare {}
4147 sql_startdeclare : ecpgstart BEGIN_TRANS DECLARE SQL_SECTION SQL_SEMI {
4148 fputs("/* exec sql begin declare section */\n", yyout);
4149 output_line_number();
4152 sql_enddeclare: ecpgstart END_TRANS DECLARE SQL_SECTION SQL_SEMI {
4153 fputs("/* exec sql end declare section */\n", yyout);
4154 output_line_number();
4157 variable_declarations: /* empty */
4158 | declaration variable_declarations;
4160 declaration: storage_clause type
4162 actual_storage[struct_level] = $1;
4163 actual_type[struct_level] = $2.type_enum;
4164 if ($2.type_enum != ECPGt_varchar && $2.type_enum != ECPGt_struct)
4165 fprintf(yyout, "%s %s", $1, $2.type_str);
4168 variable_list ';' { fputc(';', yyout); }
4170 storage_clause : S_EXTERN { $$ = "extern"; }
4171 | S_STATIC { $$ = "static"; }
4172 | S_SIGNED { $$ = "signed"; }
4173 | S_CONST { $$ = "const"; }
4174 | S_REGISTER { $$ = "register"; }
4175 | S_AUTO { $$ = "auto"; }
4176 | /* empty */ { $$ = ""; }
4181 $$.type_str = mm_strdup(ECPGtype_name($1));
4185 $$.type_enum = ECPGt_struct;
4186 $$.type_str = make1_str("");
4191 $$.type_enum = ECPGt_int;
4194 enum_type: s_enum '{' c_line '}'
4196 $$ = cat4_str($1, make1_str("{"), $3, make1_str("}"));
4199 s_enum: S_ENUM opt_symbol { $$ = cat2_str(make1_str("enum"), $2); }
4201 struct_type: s_struct '{' variable_declarations '}'
4203 ECPGfree_struct_member(struct_member_list[struct_level]);
4204 free(actual_storage[struct_level--]);
4208 s_struct : S_STRUCT opt_symbol
4210 struct_member_list[struct_level++] = NULL;
4211 if (struct_level >= STRUCT_DEPTH)
4212 yyerror("Too many levels in nested structure definition");
4213 fprintf(yyout, "struct %s {", $2);
4217 opt_symbol: /* empty */ { $$ = make1_str(""); }
4218 | symbol { $$ = $1; }
4220 simple_type: S_SHORT { $$ = ECPGt_short; }
4221 | S_UNSIGNED S_SHORT { $$ = ECPGt_unsigned_short; }
4222 | S_INT { $$ = ECPGt_int; }
4223 | S_UNSIGNED S_INT { $$ = ECPGt_unsigned_int; }
4224 | S_LONG { $$ = ECPGt_long; }
4225 | S_UNSIGNED S_LONG { $$ = ECPGt_unsigned_long; }
4226 | S_FLOAT { $$ = ECPGt_float; }
4227 | S_DOUBLE { $$ = ECPGt_double; }
4228 | S_BOOL { $$ = ECPGt_bool; };
4229 | S_CHAR { $$ = ECPGt_char; }
4230 | S_UNSIGNED S_CHAR { $$ = ECPGt_unsigned_char; }
4231 | S_VARCHAR { $$ = ECPGt_varchar; }
4233 variable_list: variable
4236 if (actual_type[struct_level] != ECPGt_varchar)
4239 fputs(";\n ", yyout);
4242 variable: opt_pointer symbol opt_array_bounds opt_initializer
4244 struct ECPGtype * type;
4245 int dimension = $3.index1; /* dimension of array */
4246 int length = $3.index2; /* lenght of string */
4249 switch (actual_type[struct_level])
4252 /* pointer has to get dimension 0 */
4260 yyerror("No multi-dimensional array support for structures");
4262 if (dimension == 1 || dimension < 0)
4263 type = ECPGmake_struct_type(struct_member_list[struct_level]);
4265 type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level]), dimension);
4267 fprintf(yyout, "%s%s%s%s", $1, $2, $3.str, $4);
4270 /* pointer has to get length 0 */
4274 /* one index is the string length */
4282 type = ECPGmake_simple_type(actual_type[struct_level], length);
4284 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level], length), dimension);
4295 sprintf(dim, "[%d]", dimension);
4299 fprintf(yyout, "%s struct varchar_%s { int len; char arr[%d]; } %s%s", actual_storage[struct_level], $2, length, $2, dim);
4301 fprintf(yyout, "%s struct varchar_%s { int len; char *arr; } %s%s", actual_storage[struct_level], $2, $2, dim);
4304 case ECPGt_unsigned_char:
4305 /* pointer has to get length 0 */
4309 /* one index is the string length */
4312 length = (dimension < 0) ? 1 : dimension;
4317 type = ECPGmake_simple_type(actual_type[struct_level], length);
4319 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level], length), dimension);
4321 fprintf(yyout, "%s%s%s%s", $1, $2, $3.str, $4);
4324 /* a pointer has dimension = 0 */
4325 if (strlen($1) > 0) {
4331 yyerror("No multi-dimensional array support for simple data types");
4333 if (dimension == 1 || dimension < 0)
4334 type = ECPGmake_simple_type(actual_type[struct_level], 1);
4336 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level], 1), dimension);
4338 fprintf(yyout, "%s%s%s%s", $1, $2, $3.str, $4);
4342 if (struct_level == 0)
4343 new_variable($2, type);
4345 ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
4353 opt_initializer: /* empty */ { $$ = make1_str(""); }
4354 | '=' vartext { $$ = make2_str(make1_str("="), $2); }
4356 opt_pointer: /* empty */ { $$ = make1_str(""); }
4357 | '*' { $$ = make1_str("*"); }
4360 * the exec sql connect statement: connect to the given database
4362 ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
4364 $$ = make5_str($3, make1_str(","), $5, make1_str(","), $4);
4366 | SQL_CONNECT TO DEFAULT
4368 $$ = make1_str("NULL,NULL,NULL,\"DEFAULT\"");
4370 /* also allow ORACLE syntax */
4371 | SQL_CONNECT ora_user
4373 $$ = make3_str(make1_str("NULL,"), $2, make1_str(",NULL"));
4376 connection_target: database_name opt_server opt_port
4378 /* old style: dbname[@server][:port] */
4379 if (strlen($2) > 0 && *($2) != '@')
4381 sprintf(errortext, "parse error at or near '%s'", $2);
4385 $$ = make5_str(make1_str("\""), $1, $2, $3, make1_str("\""));
4387 | db_prefix server opt_port '/' database_name opt_options
4389 /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
4390 if (strncmp($2, "://", 3) != 0)
4392 sprintf(errortext, "parse error at or near '%s'", $2);
4396 if (strncmp($1, "unix", 4) == 0 && strncmp($2, "localhost", 9) != 0)
4398 sprintf(errortext, "unix domain sockets only work on 'localhost'");
4402 if (strncmp($1, "unix", 4) != 0 && strncmp($1, "tcp", 3) != 0)
4404 sprintf(errortext, "only protocols 'tcp' and 'unix' are supported");
4408 $$ = make4_str(make5_str(make1_str("\""), $1, $2, $3, make1_str("/")), $5, $6, make1_str("\""));
4418 $$[strlen($$) - 1] = '\"';
4422 db_prefix: ident cvariable
4424 if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
4426 sprintf(errortext, "parse error at or near '%s'", $2);
4430 if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
4432 sprintf(errortext, "Illegal connection type %s", $1);
4436 $$ = make3_str($1, make1_str(":"), $2);
4439 server: Op server_name
4441 if (strcmp($1, "@") != 0 && strcmp($1, "://") != 0)
4443 sprintf(errortext, "parse error at or near '%s'", $1);
4447 $$ = make2_str($1, $2);
4450 opt_server: server { $$ = $1; }
4451 | /* empty */ { $$ = make1_str(""); }
4453 server_name: ColId { $$ = $1; }
4454 | ColId '.' server_name { $$ = make3_str($1, make1_str("."), $3); }
4456 opt_port: ':' Iconst { $$ = make2_str(make1_str(":"), $2); }
4457 | /* empty */ { $$ = make1_str(""); }
4459 opt_connection_name: AS connection_target { $$ = $2; }
4460 | /* empty */ { $$ = make1_str("NULL"); }
4462 opt_user: USER ora_user { $$ = $2; }
4463 | /* empty */ { $$ = make1_str("NULL,NULL"); }
4467 $$ = make2_str($1, make1_str(",NULL"));
4469 | user_name '/' ColId
4471 $$ = make3_str($1, make1_str(","), $3);
4473 | user_name SQL_IDENTIFIED BY user_name
4475 $$ = make3_str($1, make1_str(","), $4);
4477 | user_name USING user_name
4479 $$ = make3_str($1, make1_str(","), $3);
4482 user_name: UserId { if ($1[0] == '\"')
4485 $$ = make3_str(make1_str("\""), $1, make1_str("\""));
4487 | char_variable { $$ = $1; }
4488 | SCONST { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); }
4490 char_variable: cvariable
4491 { /* check if we have a char variable */
4492 struct variable *p = find_variable($1);
4493 enum ECPGttype typ = p->type->typ;
4495 /* if array see what's inside */
4496 if (typ == ECPGt_array)
4497 typ = p->type->u.element->typ;
4502 case ECPGt_unsigned_char:
4506 $$ = make2_str($1, make1_str(".arr"));
4509 yyerror("invalid datatype");
4514 opt_options: Op ColId
4516 if (strlen($1) == 0)
4517 yyerror("parse error");
4519 if (strcmp($1, "?") != 0)
4521 sprintf(errortext, "parse error at or near %s", $1);
4525 $$ = make2_str(make1_str("?"), $2);
4527 | /* empty */ { $$ = make1_str(""); }
4530 * the exec sql disconnect statement: disconnect from the given database
4532 ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
4534 dis_name: connection_object { $$ = $1; }
4535 | CURRENT { $$ = make1_str("CURRENT"); }
4536 | ALL { $$ = make1_str("ALL"); }
4537 | /* empty */ { $$ = make1_str("CURRENT"); }
4539 connection_object: connection_target { $$ = $1; }
4540 | DEFAULT { $$ = make1_str("DEFAULT"); }
4543 * execute a given string as sql command
4545 ECPGExecute : EXECUTE SQL_IMMEDIATE execstring { $$ = $3; };
4547 execstring: cvariable |
4548 CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); };
4551 * open is an open cursor, at the moment this has to be removed
4553 ECPGOpen: SQL_OPEN name open_opts {
4557 open_opts: /* empty */ { $$ = make1_str(""); }
4559 yyerror ("open cursor with variables not implemented yet");
4563 * for compatibility with ORACLE we will also allow the keyword RELEASE
4564 * after a transaction statement to disconnect from the database.
4567 ECPGRelease: TransactionStmt SQL_RELEASE
4569 if (strncmp($1, "begin", 5) == 0)
4570 yyerror("RELEASE does not make sense when beginning a transaction");
4572 fprintf(yyout, "ECPGtrans(__LINE__, \"%s\");", $1);
4574 fprintf(yyout, "ECPGdisconnect(\"\");");
4580 * set the actual connection, this needs a differnet handling as the other
4583 ECPGSetConnection: SET SQL_CONNECTION connection_object
4588 * whenever statement: decide what to do in case of error/no data found
4589 * according to SQL standards we miss: SQLSTATE, CONSTRAINT, SQLEXCEPTION
4593 ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action {
4594 when_error.code = $<action>3.code;
4595 when_error.command = $<action>3.command;
4596 $$ = cat3_str(make1_str("/* exec sql whenever sqlerror "), $3.str, make1_str("; */\n"));
4598 | SQL_WHENEVER NOT SQL_FOUND action {
4599 when_nf.code = $<action>4.code;
4600 when_nf.command = $<action>4.command;
4601 $$ = cat3_str(make1_str("/* exec sql whenever not found "), $4.str, make1_str("; */\n"));
4604 action : SQL_CONTINUE {
4605 $<action>$.code = W_NOTHING;
4606 $<action>$.command = NULL;
4607 $<action>$.str = make1_str("continue");
4610 $<action>$.code = W_SQLPRINT;
4611 $<action>$.command = NULL;
4612 $<action>$.str = make1_str("sqlprint");
4615 $<action>$.code = W_STOP;
4616 $<action>$.command = NULL;
4617 $<action>$.str = make1_str("stop");
4620 $<action>$.code = W_GOTO;
4621 $<action>$.command = $2;
4622 $<action>$.str = cat2_str(make1_str("goto "), $2);
4625 $<action>$.code = W_GOTO;
4626 $<action>$.command = $3;
4627 $<action>$.str = cat2_str(make1_str("goto "), $3);
4629 | DO name '(' dotext ')' {
4630 $<action>$.code = W_DO;
4631 $<action>$.command = make4_str($2, make1_str("("), $4, make1_str(")"));
4632 $<action>$.str = cat2_str(make1_str("do"), mm_strdup($<action>$.command));
4635 $<action>$.code = W_BREAK;
4636 $<action>$.command = NULL;
4637 $<action>$.str = make1_str("break");
4639 | SQL_CALL name '(' dotext ')' {
4640 $<action>$.code = W_DO;
4641 $<action>$.command = make4_str($2, make1_str("("), $4, make1_str(")"));
4642 $<action>$.str = cat2_str(make1_str("call"), mm_strdup($<action>$.command));
4645 /* some other stuff for ecpg */
4647 ecpg_expr: attr opt_indirection
4649 $$ = cat2_str($1, $2);
4659 | '-' ecpg_expr %prec UMINUS
4660 { $$ = cat2_str(make1_str("-"), $2); }
4661 | a_expr '+' ecpg_expr
4662 { $$ = cat3_str($1, make1_str("+"), $3); }
4663 | a_expr '-' ecpg_expr
4664 { $$ = cat3_str($1, make1_str("-"), $3); }
4665 | a_expr '/' ecpg_expr
4666 { $$ = cat3_str($1, make1_str("/"), $3); }
4667 | a_expr '*' ecpg_expr
4668 { $$ = cat3_str($1, make1_str("*"), $3); }
4669 | a_expr '<' ecpg_expr
4670 { $$ = cat3_str($1, make1_str("<"), $3); }
4671 | a_expr '>' ecpg_expr
4672 { $$ = cat3_str($1, make1_str(">"), $3); }
4673 | a_expr '=' ecpg_expr
4674 { $$ = cat3_str($1, make1_str("="), $3); }
4676 { $$ = cat2_str(make1_str(":"), $2); }*/
4678 { $$ = cat2_str(make1_str(";"), $2); }
4680 { $$ = cat2_str(make1_str("|"), $2); }
4681 | a_expr TYPECAST Typename
4683 $$ = cat3_str($1, make1_str("::"), $3);
4685 | CAST '(' a_expr AS Typename ')'
4687 $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
4689 | '(' a_expr_or_null ')'
4690 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
4691 | a_expr Op ecpg_expr
4692 { $$ = cat3_str($1, $2, $3); }
4693 | a_expr LIKE ecpg_expr
4694 { $$ = cat3_str($1, make1_str("like"), $3); }
4695 | a_expr NOT LIKE ecpg_expr
4696 { $$ = cat3_str($1, make1_str("not like"), $4); }
4698 { $$ = cat2_str($1, $2); }
4700 { $$ = cat2_str($1, $2); }
4701 | func_name '(' '*' ')'
4703 $$ = cat2_str($1, make1_str("(*)"));
4707 $$ = cat2_str($1, make1_str("()"));
4709 | func_name '(' expr_list ')'
4711 $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
4715 $$ = make1_str("current_date");
4719 $$ = make1_str("current_time");
4721 | CURRENT_TIME '(' Iconst ')'
4724 fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
4725 $$ = make1_str("current_time");
4729 $$ = make1_str("current_timestamp");
4731 | CURRENT_TIMESTAMP '(' Iconst ')'
4734 fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
4735 $$ = make1_str("current_timestamp");
4739 $$ = make1_str("current_user");
4741 | EXISTS '(' SubSelect ')'
4743 $$ = make3_str(make1_str("exists("), $3, make1_str(")"));
4745 | EXTRACT '(' extract_list ')'
4747 $$ = make3_str(make1_str("extract("), $3, make1_str(")"));
4749 | POSITION '(' position_list ')'
4751 $$ = make3_str(make1_str("position("), $3, make1_str(")"));
4753 | SUBSTRING '(' substr_list ')'
4755 $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
4757 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4758 | TRIM '(' BOTH trim_list ')'
4760 $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
4762 | TRIM '(' LEADING trim_list ')'
4764 $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
4766 | TRIM '(' TRAILING trim_list ')'
4768 $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
4770 | TRIM '(' trim_list ')'
4772 $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
4775 { $$ = cat2_str($1, make1_str("isnull")); }
4777 { $$ = cat2_str($1, make1_str("is null")); }
4779 { $$ = cat2_str($1, make1_str("notnull")); }
4780 | a_expr IS NOT NULL_P
4781 { $$ = cat2_str($1, make1_str("is not null")); }
4782 /* IS TRUE, IS FALSE, etc used to be function calls
4783 * but let's make them expressions to allow the optimizer
4784 * a chance to eliminate them if a_expr is a constant string.
4785 * - thomas 1997-12-22
4789 { $$ = cat2_str($1, make1_str("is true")); }
4791 | a_expr IS NOT FALSE_P
4793 { $$ = cat2_str($1, make1_str("is not false")); }
4797 { $$ = cat2_str($1, make1_str("is false")); }
4799 | a_expr IS NOT TRUE_P
4801 { $$ = cat2_str($1, make1_str("is not true")); }
4803 | a_expr BETWEEN b_expr AND b_expr
4805 $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5);
4807 | a_expr NOT BETWEEN b_expr AND b_expr
4809 $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6);
4811 | a_expr IN '(' in_expr ')'
4813 $$ = make4_str($1, make1_str("in ("), $4, make1_str(")"));
4815 | a_expr NOT IN '(' not_in_expr ')'
4817 $$ = make4_str($1, make1_str("not in ("), $5, make1_str(")"));
4819 | a_expr Op '(' SubSelect ')'
4821 $$ = cat3_str($1, $2, make3_str(make1_str("("), $4, make1_str(")")));
4823 | a_expr '+' '(' SubSelect ')'
4825 $$ = make4_str($1, make1_str("+("), $4, make1_str(")"));
4827 | a_expr '-' '(' SubSelect ')'
4829 $$ = make4_str($1, make1_str("-("), $4, make1_str(")"));
4831 | a_expr '/' '(' SubSelect ')'
4833 $$ = make4_str($1, make1_str("/("), $4, make1_str(")"));
4835 | a_expr '*' '(' SubSelect ')'
4837 $$ = make4_str($1, make1_str("*("), $4, make1_str(")"));
4839 | a_expr '<' '(' SubSelect ')'
4841 $$ = make4_str($1, make1_str("<("), $4, make1_str(")"));
4843 | a_expr '>' '(' SubSelect ')'
4845 $$ = make4_str($1, make1_str(">("), $4, make1_str(")"));
4847 | a_expr '=' '(' SubSelect ')'
4849 $$ = make4_str($1, make1_str("=("), $4, make1_str(")"));
4851 | a_expr Op ANY '(' SubSelect ')'
4853 $$ = cat3_str($1, $2, make3_str(make1_str("any ("), $5, make1_str(")")));
4855 | a_expr '+' ANY '(' SubSelect ')'
4857 $$ = make4_str($1, make1_str("+any("), $5, make1_str(")"));
4859 | a_expr '-' ANY '(' SubSelect ')'
4861 $$ = make4_str($1, make1_str("-any("), $5, make1_str(")"));
4863 | a_expr '/' ANY '(' SubSelect ')'
4865 $$ = make4_str($1, make1_str("/any("), $5, make1_str(")"));
4867 | a_expr '*' ANY '(' SubSelect ')'
4869 $$ = make4_str($1, make1_str("*any("), $5, make1_str(")"));
4871 | a_expr '<' ANY '(' SubSelect ')'
4873 $$ = make4_str($1, make1_str("<any("), $5, make1_str(")"));
4875 | a_expr '>' ANY '(' SubSelect ')'
4877 $$ = make4_str($1, make1_str(">any("), $5, make1_str(")"));
4879 | a_expr '=' ANY '(' SubSelect ')'
4881 $$ = make4_str($1, make1_str("=any("), $5, make1_str(")"));
4883 | a_expr Op ALL '(' SubSelect ')'
4885 $$ = make3_str($1, $2, make3_str(make1_str("all ("), $5, make1_str(")")));
4887 | a_expr '+' ALL '(' SubSelect ')'
4889 $$ = make4_str($1, make1_str("+all("), $5, make1_str(")"));
4891 | a_expr '-' ALL '(' SubSelect ')'
4893 $$ = make4_str($1, make1_str("-all("), $5, make1_str(")"));
4895 | a_expr '/' ALL '(' SubSelect ')'
4897 $$ = make4_str($1, make1_str("/all("), $5, make1_str(")"));
4899 | a_expr '*' ALL '(' SubSelect ')'
4901 $$ = make4_str($1, make1_str("*all("), $5, make1_str(")"));
4903 | a_expr '<' ALL '(' SubSelect ')'
4905 $$ = make4_str($1, make1_str("<all("), $5, make1_str(")"));
4907 | a_expr '>' ALL '(' SubSelect ')'
4909 $$ = make4_str($1, make1_str(">all("), $5, make1_str(")"));
4911 | a_expr '=' ALL '(' SubSelect ')'
4913 $$ = make4_str($1, make1_str("=all("), $5, make1_str(")"));
4915 | a_expr AND ecpg_expr
4916 { $$ = cat3_str($1, make1_str("and"), $3); }
4917 | a_expr OR ecpg_expr
4918 { $$ = cat3_str($1, make1_str("or"), $3); }
4920 { $$ = cat2_str(make1_str("not"), $2); }
4922 { $$ = make1_str(";;"); }
4925 into_list : coutputvariable | into_list ',' coutputvariable;
4927 ecpgstart: SQL_START { reset_variables();}
4929 dotext: /* empty */ { $$ = make1_str(""); }
4930 | dotext do_anything { $$ = make2_str($1, $2); }
4932 vartext: var_anything { $$ = $1; }
4933 | vartext var_anything { $$ = make2_str($1, $2); }
4935 coutputvariable : cvariable indicator {
4936 add_variable(&argsresult, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
4939 cinputvariable : cvariable indicator {
4940 add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
4943 civariableonly : cvariable {
4944 add_variable(&argsinsert, find_variable($1), &no_indicator);
4947 cvariable: CVARIABLE { $$ = $1; }
4949 indicator: /* empty */ { $$ = NULL; }
4950 | cvariable { check_indicator((find_variable($1))->type); $$ = $1; }
4951 | SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; }
4952 | SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
4954 ident: IDENT { $$ = $1; }
4955 | CSTRING { $$ = $1; }
4960 symbol: IDENT { $$ = $1; }
4962 cpp_line: CPP_LINE { $$ = $1; }
4964 c_line: c_anything { $$ = $1; }
4967 $$ = make2_str($1, $2);
4970 c_thing: c_anything | ';' { $$ = make1_str(";"); }
4972 c_anything: IDENT { $$ = $1; }
4973 | CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); }
4974 | Iconst { $$ = $1; }
4975 | Fconst { $$ = $1; }
4976 | '*' { $$ = make1_str("*"); }
4977 | S_AUTO { $$ = make1_str("auto"); }
4978 | S_BOOL { $$ = make1_str("bool"); }
4979 | S_CHAR { $$ = make1_str("char"); }
4980 | S_CONST { $$ = make1_str("const"); }
4981 | S_DOUBLE { $$ = make1_str("double"); }
4982 | S_EXTERN { $$ = make1_str("extern"); }
4983 | S_FLOAT { $$ = make1_str("float"); }
4984 | S_INT { $$ = make1_str("int"); }
4985 | S_LONG { $$ = make1_str("long"); }
4986 | S_REGISTER { $$ = make1_str("register"); }
4987 | S_SHORT { $$ = make1_str("short"); }
4988 | S_SIGNED { $$ = make1_str("signed"); }
4989 | S_STATIC { $$ = make1_str("static"); }
4990 | S_STRUCT { $$ = make1_str("struct"); }
4991 | S_UNSIGNED { $$ = make1_str("unsigned"); }
4992 | S_VARCHAR { $$ = make1_str("varchar"); }
4993 | S_ANYTHING { $$ = make_name(); }
4994 | '[' { $$ = make1_str("["); }
4995 | ']' { $$ = make1_str("]"); }
4996 | '(' { $$ = make1_str("("); }
4997 | ')' { $$ = make1_str(")"); }
4998 | '=' { $$ = make1_str("="); }
4999 | ',' { $$ = make1_str(","); }
5001 do_anything: IDENT { $$ = $1; }
5002 | CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\""));}
5003 | Iconst { $$ = $1; }
5004 | Fconst { $$ = $1; }
5005 | ',' { $$ = make1_str(","); }
5007 var_anything: IDENT { $$ = $1; }
5008 | CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); }
5009 | Iconst { $$ = $1; }
5010 | Fconst { $$ = $1; }
5011 | '{' c_line '}' { $$ = make3_str(make1_str("{"), $2, make1_str("}")); }
5015 $$ = make1_str("{");
5019 remove_variables(braces_open--);
5020 $$ = make1_str("}");
5025 void yyerror(char * error)
5027 fprintf(stderr, "%s:%d: %s\n", input_filename, yylineno, error);