preproc.y
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:172k
- /* Copyright comment */
- %{
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "postgres.h"
- #include "access/htup.h"
- #include "catalog/catname.h"
- #include "utils/numeric.h"
- #include "extern.h"
- #ifdef MULTIBYTE
- #include "mb/pg_wchar.h"
- #endif
- #define STRUCT_DEPTH 128
- /*
- * Variables containing simple states.
- */
- int struct_level = 0;
- char errortext[128];
- static char *connection = NULL;
- static int QueryIsRule = 0, ForUpdateNotAllowed = 0;
- static struct this_type actual_type[STRUCT_DEPTH];
- static char *actual_storage[STRUCT_DEPTH];
- /* temporarily store struct members while creating the data structure */
- struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
- struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}};
- struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
- struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}};
- /*
- * Handle the filename and line numbering.
- */
- char * input_filename = NULL;
- void
- output_line_number()
- {
- if (input_filename)
- fprintf(yyout, "n#line %d "%s"n", yylineno + 1, input_filename);
- }
- static void
- output_simple_statement(char *cmd)
- {
- fputs(cmd, yyout);
- output_line_number();
- free(cmd);
- }
- /*
- * store the whenever action here
- */
- static struct when when_error, when_nf, when_warn;
- static void
- print_action(struct when *w)
- {
- switch (w->code)
- {
- case W_SQLPRINT: fprintf(yyout, "sqlprint();");
- break;
- case W_GOTO: fprintf(yyout, "goto %s;", w->command);
- break;
- case W_DO: fprintf(yyout, "%s;", w->command);
- break;
- case W_STOP: fprintf(yyout, "exit (1);");
- break;
- case W_BREAK: fprintf(yyout, "break;");
- break;
- default: fprintf(yyout, "{/* %d not implemented yet */}", w->code);
- break;
- }
- }
- static void
- whenever_action(int mode)
- {
- if ((mode&1) == 1 && when_nf.code != W_NOTHING)
- {
- output_line_number();
- fprintf(yyout, "nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
- print_action(&when_nf);
- }
- if (when_warn.code != W_NOTHING)
- {
- output_line_number();
- fprintf(yyout, "nif (sqlca.sqlwarn[0] == 'W') ");
- print_action(&when_warn);
- }
- if (when_error.code != W_NOTHING)
- {
- output_line_number();
- fprintf(yyout, "nif (sqlca.sqlcode < 0) ");
- print_action(&when_error);
- }
- if ((mode&2) == 2)
- fputc('}', yyout);
- output_line_number();
- }
- /*
- * Handling of variables.
- */
- /*
- * brace level counter
- */
- int braces_open;
- static struct variable * allvariables = NULL;
- static struct variable *
- new_variable(const char * name, struct ECPGtype * type)
- {
- struct variable * p = (struct variable*) mm_alloc(sizeof(struct variable));
- p->name = mm_strdup(name);
- p->type = type;
- p->brace_level = braces_open;
- p->next = allvariables;
- allvariables = p;
- return(p);
- }
- static struct variable * find_variable(char * name);
- static struct variable *
- find_struct_member(char *name, char *str, struct ECPGstruct_member *members)
- {
- char *next = strchr(++str, '.'), c = ' ';
- if (next != NULL)
- {
- c = *next;
- *next = ' ';
- }
- for (; members; members = members->next)
- {
- if (strcmp(members->name, str) == 0)
- {
- if (c == ' ')
- {
- /* found the end */
- switch (members->typ->typ)
- {
- case ECPGt_array:
- return(new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size)));
- case ECPGt_struct:
- case ECPGt_union:
- return(new_variable(name, ECPGmake_struct_type(members->typ->u.members, members->typ->typ)));
- default:
- return(new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
- }
- }
- else
- {
- *next = c;
- if (c == '-')
- {
- next++;
- return(find_struct_member(name, next, members->typ->u.element->u.members));
- }
- else return(find_struct_member(name, next, members->typ->u.members));
- }
- }
- }
- return(NULL);
- }
- static struct variable *
- find_struct(char * name, char *next)
- {
- struct variable * p;
- char c = *next;
- /* first get the mother structure entry */
- *next = ' ';
- p = find_variable(name);
- if (c == '-')
- {
- if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
- {
- sprintf(errortext, "variable %s is not a pointer", name);
- yyerror (errortext);
- }
- if (p->type->u.element->typ != ECPGt_struct && p->type->u.element->typ != ECPGt_union)
- {
- sprintf(errortext, "variable %s is not a pointer to a structure or a union", name);
- yyerror (errortext);
- }
- /* restore the name, we will need it later on */
- *next = c;
- next++;
- return find_struct_member(name, next, p->type->u.element->u.members);
- }
- else
- {
- if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
- {
- sprintf(errortext, "variable %s is neither a structure nor a union", name);
- yyerror (errortext);
- }
- /* restore the name, we will need it later on */
- *next = c;
- return find_struct_member(name, next, p->type->u.members);
- }
- }
- static struct variable *
- find_simple(char * name)
- {
- struct variable * p;
- for (p = allvariables; p; p = p->next)
- {
- if (strcmp(p->name, name) == 0)
- return p;
- }
- return(NULL);
- }
- /* Note that this function will end the program in case of an unknown */
- /* variable */
- static struct variable *
- find_variable(char * name)
- {
- char * next;
- struct variable * p;
- if ((next = strchr(name, '.')) != NULL)
- p = find_struct(name, next);
- else if ((next = strstr(name, "->")) != NULL)
- p = find_struct(name, next);
- else
- p = find_simple(name);
- if (p == NULL)
- {
- sprintf(errortext, "The variable %s is not declared", name);
- yyerror(errortext);
- }
- return(p);
- }
- static void
- remove_variables(int brace_level)
- {
- struct variable * p, *prev;
- for (p = prev = allvariables; p; p = p ? p->next : NULL)
- {
- if (p->brace_level >= brace_level)
- {
- /* remove it */
- if (p == allvariables)
- prev = allvariables = p->next;
- else
- prev->next = p->next;
- ECPGfree_type(p->type);
- free(p->name);
- free(p);
- p = prev;
- }
- else
- prev = p;
- }
- }
- /*
- * Here are the variables that need to be handled on every request.
- * These are of two kinds: input and output.
- * I will make two lists for them.
- */
- struct arguments * argsinsert = NULL;
- struct arguments * argsresult = NULL;
- static void
- reset_variables(void)
- {
- argsinsert = NULL;
- argsresult = NULL;
- }
- /* Add a variable to a request. */
- static void
- add_variable(struct arguments ** list, struct variable * var, struct variable * ind)
- {
- struct arguments * p = (struct arguments *)mm_alloc(sizeof(struct arguments));
- p->variable = var;
- p->indicator = ind;
- p->next = *list;
- *list = p;
- }
- /* Dump out a list of all the variable on this list.
- This is a recursive function that works from the end of the list and
- deletes the list as we go on.
- */
- static void
- dump_variables(struct arguments * list, int mode)
- {
- if (list == NULL)
- {
- return;
- }
- /* The list is build up from the beginning so lets first dump the
- end of the list:
- */
- dump_variables(list->next, mode);
- /* Then the current element and its indicator */
- ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
- (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->name : NULL,
- (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->type : NULL, NULL, NULL);
- /* Then release the list element. */
- if (mode != 0)
- free(list);
- }
- static void
- check_indicator(struct ECPGtype *var)
- {
- /* make sure this is a valid indicator variable */
- switch (var->typ)
- {
- struct ECPGstruct_member *p;
- case ECPGt_short:
- case ECPGt_int:
- case ECPGt_long:
- case ECPGt_unsigned_short:
- case ECPGt_unsigned_int:
- case ECPGt_unsigned_long:
- break;
- case ECPGt_struct:
- case ECPGt_union:
- for (p = var->u.members; p; p = p->next)
- check_indicator(p->typ);
- break;
- case ECPGt_array:
- check_indicator(var->u.element);
- break;
- default:
- yyerror ("indicator variable must be integer type");
- break;
- }
- }
- static char *
- make1_str(const char *str)
- {
- char * res_str = (char *)mm_alloc(strlen(str) + 1);
- strcpy(res_str, str);
- return res_str;
- }
- static char *
- make2_str(char *str1, char *str2)
- {
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
- strcpy(res_str, str1);
- strcat(res_str, str2);
- free(str1);
- free(str2);
- return(res_str);
- }
- static char *
- cat2_str(char *str1, char *str2)
- {
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
- strcpy(res_str, str1);
- strcat(res_str, " ");
- strcat(res_str, str2);
- free(str1);
- free(str2);
- return(res_str);
- }
- static char *
- make3_str(char *str1, char *str2, char * str3)
- {
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 1);
-
- strcpy(res_str, str1);
- strcat(res_str, str2);
- strcat(res_str, str3);
- free(str1);
- free(str2);
- free(str3);
- return(res_str);
- }
- static char *
- cat3_str(char *str1, char *str2, char * str3)
- {
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 3);
-
- strcpy(res_str, str1);
- strcat(res_str, " ");
- strcat(res_str, str2);
- strcat(res_str, " ");
- strcat(res_str, str3);
- free(str1);
- free(str2);
- free(str3);
- return(res_str);
- }
- static char *
- make4_str(char *str1, char *str2, char *str3, char *str4)
- {
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 1);
-
- strcpy(res_str, str1);
- strcat(res_str, str2);
- strcat(res_str, str3);
- strcat(res_str, str4);
- free(str1);
- free(str2);
- free(str3);
- free(str4);
- return(res_str);
- }
- static char *
- cat4_str(char *str1, char *str2, char *str3, char *str4)
- {
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 4);
-
- strcpy(res_str, str1);
- strcat(res_str, " ");
- strcat(res_str, str2);
- strcat(res_str, " ");
- strcat(res_str, str3);
- strcat(res_str, " ");
- strcat(res_str, str4);
- free(str1);
- free(str2);
- free(str3);
- free(str4);
- return(res_str);
- }
- static char *
- make5_str(char *str1, char *str2, char *str3, char *str4, char *str5)
- {
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + strlen(str5) + 1);
-
- strcpy(res_str, str1);
- strcat(res_str, str2);
- strcat(res_str, str3);
- strcat(res_str, str4);
- strcat(res_str, str5);
- free(str1);
- free(str2);
- free(str3);
- free(str4);
- free(str5);
- return(res_str);
- }
- static char *
- cat5_str(char *str1, char *str2, char *str3, char *str4, char *str5)
- {
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + strlen(str5) + 5);
-
- strcpy(res_str, str1);
- strcat(res_str, " ");
- strcat(res_str, str2);
- strcat(res_str, " ");
- strcat(res_str, str3);
- strcat(res_str, " ");
- strcat(res_str, str4);
- strcat(res_str, " ");
- strcat(res_str, str5);
- free(str1);
- free(str2);
- free(str3);
- free(str4);
- free(str5);
- return(res_str);
- }
- static char *
- make_name(void)
- {
- char * name = (char *)mm_alloc(yyleng + 1);
- strncpy(name, yytext, yyleng);
- name[yyleng] = ' ';
- return(name);
- }
- static void
- output_statement(char * stmt, int mode)
- {
- int i, j=strlen(stmt);
- fprintf(yyout, "{ ECPGdo(__LINE__, %s, "", connection ? connection : "NULL");
- /* do this char by char as we have to filter '"' */
- for (i = 0;i < j; i++)
- if (stmt[i] != '"')
- fputc(stmt[i], yyout);
- fputs("", ", yyout);
- /* dump variables to C file*/
- dump_variables(argsinsert, 1);
- fputs("ECPGt_EOIT, ", yyout);
- dump_variables(argsresult, 1);
- fputs("ECPGt_EORT);", yyout);
- mode |= 2;
- whenever_action(mode);
- free(stmt);
- if (connection != NULL)
- free(connection);
- }
- static struct typedefs *
- get_typedef(char *name)
- {
- struct typedefs *this;
- for (this = types; this && strcmp(this->name, name); this = this->next);
- if (!this)
- {
- sprintf(errortext, "invalid datatype '%s'", name);
- yyerror(errortext);
- }
- return(this);
- }
- static void
- adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dimension, int type_index, bool pointer)
- {
- if (type_index >= 0)
- {
- if (*length >= 0)
- yyerror("No multi-dimensional array support");
- *length = type_index;
- }
-
- if (type_dimension >= 0)
- {
- if (*dimension >= 0 && *length >= 0)
- yyerror("No multi-dimensional array support");
- if (*dimension >= 0)
- *length = *dimension;
- *dimension = type_dimension;
- }
- if (*length >= 0 && *dimension >= 0 && pointer)
- yyerror("No multi-dimensional array support");
- switch (type_enum)
- {
- case ECPGt_struct:
- case ECPGt_union:
- /* pointer has to get dimension 0 */
- if (pointer)
- {
- *length = *dimension;
- *dimension = 0;
- }
- if (*length >= 0)
- yyerror("No multi-dimensional array support for structures");
- break;
- case ECPGt_varchar:
- /* pointer has to get dimension 0 */
- if (pointer)
- *dimension = 0;
- /* one index is the string length */
- if (*length < 0)
- {
- *length = *dimension;
- *dimension = -1;
- }
- break;
- case ECPGt_char:
- case ECPGt_unsigned_char:
- /* pointer has to get length 0 */
- if (pointer)
- *length=0;
- /* one index is the string length */
- if (*length < 0)
- {
- *length = (*dimension < 0) ? 1 : *dimension;
- *dimension = -1;
- }
- break;
- default:
- /* a pointer has dimension = 0 */
- if (pointer) {
- *length = *dimension;
- *dimension = 0;
- }
- if (*length >= 0)
- yyerror("No multi-dimensional array support for simple data types");
- break;
- }
- }
- %}
- %union {
- double dval;
- int ival;
- char * str;
- struct when action;
- struct index index;
- int tagname;
- struct this_type type;
- enum ECPGttype type_enum;
- }
- /* special embedded SQL token */
- %token SQL_AT SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
- %token SQL_CALL SQL_CONNECT SQL_CONNECTION SQL_CONTINUE
- %token SQL_DEALLOCATE SQL_DISCONNECT SQL_ENUM
- %token SQL_FOUND SQL_FREE SQL_GO SQL_GOTO
- %token SQL_IDENTIFIED SQL_IMMEDIATE SQL_INDICATOR SQL_INT SQL_LONG
- %token SQL_OFF SQL_OPEN SQL_PREPARE SQL_RELEASE SQL_REFERENCE
- %token SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQLERROR SQL_SQLPRINT
- %token SQL_SQLWARNING SQL_START SQL_STOP SQL_STRUCT SQL_UNSIGNED
- %token SQL_VAR SQL_WHENEVER
- /* C token */
- %token S_ANYTHING S_AUTO S_BOOL S_CHAR S_CONST S_DOUBLE S_ENUM S_EXTERN
- %token S_FLOAT S_INT S
- %token S_LONG S_REGISTER S_SHORT S_SIGNED S_STATIC S_STRUCT
- %token S_UNION S_UNSIGNED S_VARCHAR
- /* I need this and don't know where it is defined inside the backend */
- %token TYPECAST
- /* Keywords (in SQL92 reserved words) */
- %token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
- BEGIN_TRANS, BETWEEN, BOTH, BY,
- CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
- COALESCE, COLLATE, COLUMN, COMMIT,
- CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
- CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
- DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
- ELSE, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
- FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
- GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
- IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
- ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
- MATCH, MINUTE_P, MONTH_P, NAMES,
- NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
- OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
- PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
- READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
- SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
- TABLE, TEMP, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
- TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
- UNION, UNIQUE, UPDATE, USER, USING,
- VALUES, VARCHAR, VARYING, VIEW,
- WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
- /* Keywords (in SQL3 reserved words) */
- %token TRIGGER
- /* Keywords (in SQL92 non-reserved words) */
- %token COMMITTED, SERIALIZABLE, TYPE_P
- /* Keywords for Postgres support (not in SQL92 reserved words)
- *
- * The CREATEDB and CREATEUSER tokens should go away
- * when some sort of pg_privileges relation is introduced.
- * - Todd A. Brandys 1998-01-01?
- */
- %token ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYZE,
- BACKWARD, BEFORE, BINARY,
- CACHE, CLUSTER, COPY, CREATEDB, CREATEUSER, CYCLE,
- DATABASE, DELIMITERS, DO,
- EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
- FORWARD, FUNCTION, HANDLER,
- INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
- LANCOMPILER, LIMIT, LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P,
- MAXVALUE, MINVALUE, MODE, MOVE,
- NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
- OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
- RENAME, RESET, RETURNS, ROW, RULE,
- SERIAL, SEQUENCE, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT,
- TRUSTED,
- UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
- /* Special keywords, not in the query language - see the "lex" file */
- %token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE
- %token <ival> ICONST PARAM
- %token <dval> FCONST
- /* these are not real. they are here so that they get generated as #define's*/
- %token OP
- /* precedence */
- %left OR
- %left AND
- %right NOT
- %right '='
- %nonassoc '<' '>'
- %nonassoc LIKE
- %nonassoc BETWEEN
- %nonassoc IN
- %left Op /* multi-character ops and user-defined operators */
- %nonassoc NOTNULL
- %nonassoc ISNULL
- %nonassoc NULL_P
- %nonassoc IS
- %left '+' '-'
- %left '*' '/' '%'
- %left '|' /* this is the relation union op, not logical or */
- /* Unary Operators */
- %right ':'
- %left ';' /* end of statement or natural log */
- %right UMINUS
- %left '.'
- %left '[' ']'
- %nonassoc TYPECAST
- %left UNION INTERSECT EXCEPT
- %type <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId
- %type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt
- %type <str> OptInherit key_reference key_action
- %type <str> key_match constraint_expr ColLabel SpecialRuleRelation
- %type <str> ColId default_expr ColQualifier columnDef ColQualList
- %type <str> ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
- %type <str> OptTableElementList OptTableElement TableConstraint
- %type <str> ConstraintElem key_actions constraint_list ColPrimaryKey
- %type <str> res_target_list res_target_el res_target_list2
- %type <str> res_target_el2 opt_id relation_name database_name
- %type <str> access_method attr_name class index_name name func_name
- %type <str> file_name AexprConst ParamNo TypeId
- %type <str> in_expr_nodes not_in_expr_nodes a_expr b_expr
- %type <str> opt_indirection expr_list extract_list extract_arg
- %type <str> position_list position_expr substr_list substr_from
- %type <str> trim_list in_expr substr_for not_in_expr attr attrs
- %type <str> Typename Array Generic Numeric generic opt_float opt_numeric
- %type <str> opt_decimal Character character opt_varying opt_charset
- %type <str> opt_collate Datetime datetime opt_timezone opt_interval
- %type <str> numeric a_expr_or_null row_expr row_descriptor row_list
- %type <str> SelectStmt SubSelect result OptTemp OptTempType OptTempScope
- %type <str> opt_table opt_union opt_unique sort_clause sortby_list
- %type <str> sortby OptUseOp opt_inh_star relation_name_list name_list
- %type <str> group_clause having_clause from_clause c_list
- %type <str> table_list join_outer where_clause relation_expr row_op sub_type
- %type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
- %type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
- %type <str> NotifyStmt columnElem copy_dirn c_expr UnlistenStmt
- %type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
- %type <str> opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name
- %type <str> ClosePortalStmt DestroyStmt VacuumStmt opt_verbose
- %type <str> opt_analyze opt_va_list va_list ExplainStmt index_params
- %type <str> index_list func_index index_elem opt_type opt_class access_method_clause
- %type <str> index_opt_unique IndexStmt set_opt func_return def_rest
- %type <str> func_args_list func_args opt_with ProcedureStmt def_arg
- %type <str> def_elem def_list definition def_name def_type DefineStmt
- %type <str> opt_instead event event_object RuleActionList,
- %type <str> RuleActionBlock RuleActionMulti join_list
- %type <str> RuleStmt opt_column opt_name oper_argtypes
- %type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
- %type <str> RemoveAggrStmt remove_type RemoveStmt ExtendStmt
- %type <str> RemoveOperStmt RenameStmt all_Op user_valid_clause
- %type <str> VariableSetStmt var_value zone_value VariableShowStmt
- %type <str> VariableResetStmt AddAttrStmt alter_clause DropUserStmt
- %type <str> user_passwd_clause user_createdb_clause opt_trans
- %type <str> user_createuser_clause user_group_list user_group_clause
- %type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
- %type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
- %type <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
- %type <str> TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
- %type <str> CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
- %type <str> ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
- %type <str> DestroydbStmt ClusterStmt grantee RevokeStmt encoding
- %type <str> GrantStmt privileges operation_commalist operation
- %type <str> opt_cursor opt_lmode
- %type <str> case_expr when_clause_list case_default case_arg when_clause
- %type <str> select_clause opt_select_limit select_limit_value
- %type <str> select_offset_value table_list using_expr join_expr
- %type <str> using_list from_expr table_expr join_clause join_type
- %type <str> join_qual update_list join_clause join_clause_with_union
- %type <str> opt_level opt_lock lock_type
- %type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen opt_using
- %type <str> indicator ECPGExecute ecpg_expr dotext ECPGPrepare
- %type <str> storage_clause opt_initializer vartext c_anything blockstart
- %type <str> blockend variable_list variable var_anything do_anything
- %type <str> opt_pointer cvariable ECPGDisconnect dis_name
- %type <str> stmt symbol opt_symbol ECPGRelease execstring server_name
- %type <str> connection_object opt_server opt_port c_thing opt_reference
- %type <str> user_name opt_user char_variable ora_user ident
- %type <str> db_prefix server opt_options opt_connection_name
- %type <str> ECPGSetConnection c_line cpp_line s_enum ECPGTypedef
- %type <str> enum_type civariableonly ECPGCursorStmt ECPGDeallocate
- %type <str> ECPGFree ECPGDeclare ECPGVar sql_variable_declarations
- %type <str> sql_declaration sql_variable_list sql_variable opt_at
- %type <str> struct_type s_struct declaration variable_declarations
- %type <str> s_struct s_union union_type ECPGSetAutocommit on_off
- %type <type_enum> simple_type varchar_type
- %type <type> type ctype
- %type <action> action
- %type <index> opt_array_bounds nest_array_bounds opt_type_array_bounds
- %type <index> nest_type_array_bounds
- %type <ival> Iresult
- %%
- prog: statements;
- statements: /* empty */
- | statements statement
- statement: ecpgstart opt_at stmt ';' { connection = NULL; }
- | ecpgstart stmt ';'
- | ECPGDeclaration
- | c_thing { fprintf(yyout, "%s", $1); free($1); }
- | cpp_line { fprintf(yyout, "%s", $1); free($1); }
- | blockstart { fputs($1, yyout); free($1); }
- | blockend { fputs($1, yyout); free($1); }
- opt_at: SQL_AT connection_target { connection = $2; }
- stmt: AddAttrStmt { output_statement($1, 0); }
- | AlterUserStmt { output_statement($1, 0); }
- | ClosePortalStmt { output_statement($1, 0); }
- | CopyStmt { output_statement($1, 0); }
- | CreateStmt { output_statement($1, 0); }
- | CreateAsStmt { output_statement($1, 0); }
- | CreateSeqStmt { output_statement($1, 0); }
- | CreatePLangStmt { output_statement($1, 0); }
- | CreateTrigStmt { output_statement($1, 0); }
- | CreateUserStmt { output_statement($1, 0); }
- | ClusterStmt { output_statement($1, 0); }
- | DefineStmt { output_statement($1, 0); }
- | DestroyStmt { output_statement($1, 0); }
- | DropPLangStmt { output_statement($1, 0); }
- | DropTrigStmt { output_statement($1, 0); }
- | DropUserStmt { output_statement($1, 0); }
- | ExtendStmt { output_statement($1, 0); }
- | ExplainStmt { output_statement($1, 0); }
- | FetchStmt { output_statement($1, 1); }
- | GrantStmt { output_statement($1, 0); }
- | IndexStmt { output_statement($1, 0); }
- | ListenStmt { output_statement($1, 0); }
- | UnlistenStmt { output_statement($1, 0); }
- | LockStmt { output_statement($1, 0); }
- | ProcedureStmt { output_statement($1, 0); }
- | RemoveAggrStmt { output_statement($1, 0); }
- | RemoveOperStmt { output_statement($1, 0); }
- | RemoveFuncStmt { output_statement($1, 0); }
- | RemoveStmt { output_statement($1, 0); }
- | RenameStmt { output_statement($1, 0); }
- | RevokeStmt { output_statement($1, 0); }
- | OptimizableStmt {
- if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
- output_simple_statement($1);
- else
- output_statement($1, 1);
- }
- | RuleStmt { output_statement($1, 0); }
- | TransactionStmt {
- fprintf(yyout, "{ ECPGtrans(__LINE__, %s, "%s");", connection ? connection : "NULL", $1);
- whenever_action(2);
- free($1);
- }
- | ViewStmt { output_statement($1, 0); }
- | LoadStmt { output_statement($1, 0); }
- | CreatedbStmt { output_statement($1, 0); }
- | DestroydbStmt { output_statement($1, 0); }
- | VacuumStmt { output_statement($1, 0); }
- | VariableSetStmt { output_statement($1, 0); }
- | VariableShowStmt { output_statement($1, 0); }
- | VariableResetStmt { output_statement($1, 0); }
- | ECPGConnect {
- if (connection)
- yyerror("no at option for connect statement.n");
- fprintf(yyout, "{ ECPGconnect(__LINE__, %s, %d);", $1, autocommit);
- whenever_action(2);
- free($1);
- }
- | ECPGCursorStmt {
- output_simple_statement($1);
- }
- | ECPGDeallocate {
- if (connection)
- yyerror("no at option for connect statement.n");
- fputc('{', yyout);
- fputs($1, yyout);
- whenever_action(2);
- free($1);
- }
- | ECPGDeclare {
- output_simple_statement($1);
- }
- | ECPGDisconnect {
- if (connection)
- yyerror("no at option for disconnect statement.n");
- fprintf(yyout, "{ ECPGdisconnect(__LINE__, "%s");", $1);
- whenever_action(2);
- free($1);
- }
- | ECPGExecute {
- output_statement($1, 0);
- }
- | ECPGFree {
- fprintf(yyout, "{ ECPGdeallocate(__LINE__, %s, "%s");", connection ? connection : "NULL", $1);
- whenever_action(2);
- free($1);
- }
- | ECPGOpen {
- struct cursor *ptr;
-
- for (ptr = cur; ptr != NULL; ptr=ptr->next)
- {
- if (strcmp(ptr->name, $1) == 0)
- break;
- }
-
- if (ptr == NULL)
- {
- sprintf(errortext, "trying to open undeclared cursor %sn", $1);
- yyerror(errortext);
- }
-
- fprintf(yyout, "{ ECPGdo(__LINE__, %s, "%s",", ptr->connection ? ptr->connection : "NULL", ptr->command);
- /* dump variables to C file*/
- dump_variables(ptr->argsinsert, 0);
- dump_variables(argsinsert, 0);
- fputs("ECPGt_EOIT, ", yyout);
- dump_variables(ptr->argsresult, 0);
- fputs("ECPGt_EORT);", yyout);
- whenever_action(2);
- free($1);
- }
- | ECPGPrepare {
- if (connection)
- yyerror("no at option for set connection statement.n");
- fprintf(yyout, "{ ECPGprepare(__LINE__, %s);", $1);
- whenever_action(2);
- free($1);
- }
- | ECPGRelease { /* output already done */ }
- | ECPGSetAutocommit {
- fprintf(yyout, "{ ECPGsetcommit(__LINE__, "%s", %s);", $1, connection ? connection : "NULL");
- whenever_action(2);
- free($1);
- }
- | ECPGSetConnection {
- if (connection)
- yyerror("no at option for set connection statement.n");
- fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
- whenever_action(2);
- free($1);
- }
- | ECPGTypedef {
- if (connection)
- yyerror("no at option for typedef statement.n");
- output_simple_statement($1);
- }
- | ECPGVar {
- if (connection)
- yyerror("no at option for var statement.n");
- output_simple_statement($1);
- }
- | ECPGWhenever {
- if (connection)
- yyerror("no at option for whenever statement.n");
- output_simple_statement($1);
- }
- ;
- /*
- * We start with a lot of stuff that's very similar to the backend's parsing
- */
- /*****************************************************************************
- *
- * Create a new Postgres DBMS user
- *
- *
- *****************************************************************************/
- CreateUserStmt: CREATE USER UserId user_passwd_clause user_createdb_clause
- user_createuser_clause user_group_clause user_valid_clause
- {
- $$ = cat3_str(cat5_str(make1_str("create user"), $3, $4, $5, $6), $7, $8);
- }
- ;
- /*****************************************************************************
- *
- * Alter a postresql DBMS user
- *
- *
- *****************************************************************************/
- AlterUserStmt: ALTER USER UserId user_passwd_clause user_createdb_clause
- user_createuser_clause user_group_clause user_valid_clause
- {
- $$ = cat3_str(cat5_str(make1_str("alter user"), $3, $4, $5, $6), $7, $8);
- }
- ;
- /*****************************************************************************
- *
- * Drop a postresql DBMS user
- *
- *
- *****************************************************************************/
- DropUserStmt: DROP USER UserId
- {
- $$ = cat2_str(make1_str("drop user"), $3);
- }
- ;
- user_passwd_clause: WITH PASSWORD UserId { $$ = cat2_str(make1_str("with password") , $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- user_createdb_clause: CREATEDB
- {
- $$ = make1_str("createdb");
- }
- | NOCREATEDB
- {
- $$ = make1_str("nocreatedb");
- }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- user_createuser_clause: CREATEUSER
- {
- $$ = make1_str("createuser");
- }
- | NOCREATEUSER
- {
- $$ = make1_str("nocreateuser");
- }
- | /*EMPTY*/ { $$ = NULL; }
- ;
- user_group_list: user_group_list ',' UserId
- {
- $$ = cat3_str($1, make1_str(","), $3);
- }
- | UserId
- {
- $$ = $1;
- }
- ;
- user_group_clause: IN GROUP user_group_list { $$ = cat2_str(make1_str("in group"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- user_valid_clause: VALID UNTIL Sconst { $$ = cat2_str(make1_str("valid until"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /*****************************************************************************
- *
- * Set PG internal variable
- * SET name TO 'var_value'
- * Include SQL92 syntax (thomas 1997-10-22):
- * SET TIME ZONE 'var_value'
- *
- *****************************************************************************/
- VariableSetStmt: SET ColId TO var_value
- {
- $$ = cat4_str(make1_str("set"), $2, make1_str("to"), $4);
- }
- | SET ColId '=' var_value
- {
- $$ = cat4_str(make1_str("set"), $2, make1_str("="), $4);
- }
- | SET TIME ZONE zone_value
- {
- $$ = cat2_str(make1_str("set time zone"), $4);
- }
- | SET TRANSACTION ISOLATION LEVEL opt_level
- {
- $$ = cat2_str(make1_str("set transaction isolation level"), $5);
- }
- | SET NAMES encoding
- {
- #ifdef MB
- $$ = cat2_str(make1_str("set names"), $3);
- #else
- yyerror("SET NAMES is not supported");
- #endif
- }
- ;
- opt_level: READ COMMITTED { $$ = make1_str("read committed"); }
- | SERIALIZABLE { $$ = make1_str("serializable"); }
- ;
- var_value: Sconst { $$ = $1; }
- | DEFAULT { $$ = make1_str("default"); }
- ;
- zone_value: Sconst { $$ = $1; }
- | DEFAULT { $$ = make1_str("default"); }
- | LOCAL { $$ = make1_str("local"); }
- ;
- VariableShowStmt: SHOW ColId
- {
- $$ = cat2_str(make1_str("show"), $2);
- }
- | SHOW TIME ZONE
- {
- $$ = make1_str("show time zone");
- }
- | SHOW TRANSACTION ISOLATION LEVEL
- {
- $$ = make1_str("show transaction isolation level");
- }
- ;
- VariableResetStmt: RESET ColId
- {
- $$ = cat2_str(make1_str("reset"), $2);
- }
- | RESET TIME ZONE
- {
- $$ = make1_str("reset time zone");
- }
- | RESET TRANSACTION ISOLATION LEVEL
- {
- $$ = make1_str("reset transaction isolation level");
- }
- ;
- /*****************************************************************************
- *
- * QUERY :
- * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
- *
- *****************************************************************************/
- AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
- {
- $$ = cat4_str(make1_str("alter table"), $3, $4, $5);
- }
- ;
- alter_clause: ADD opt_column columnDef
- {
- $$ = cat3_str(make1_str("add"), $2, $3);
- }
- | ADD '(' OptTableElementList ')'
- {
- $$ = make3_str(make1_str("add("), $3, make1_str(")"));
- }
- | DROP opt_column ColId
- { yyerror("ALTER TABLE/DROP COLUMN not yet implemented"); }
- | ALTER opt_column ColId SET DEFAULT default_expr
- { yyerror("ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
- | ALTER opt_column ColId DROP DEFAULT
- { yyerror("ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
- | ADD ConstraintElem
- { yyerror("ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
- ;
- /*****************************************************************************
- *
- * QUERY :
- * close <optname>
- *
- *****************************************************************************/
- ClosePortalStmt: CLOSE opt_id
- {
- $$ = cat2_str(make1_str("close"), $2);
- }
- ;
- /*****************************************************************************
- *
- * QUERY :
- * COPY [BINARY] <relname> FROM/TO
- * [USING DELIMITERS <delimiter>]
- *
- *****************************************************************************/
- CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
- {
- $$ = cat3_str(cat5_str(make1_str("copy"), $2, $3, $4, $5), $6, $7);
- }
- ;
- copy_dirn: TO
- { $$ = make1_str("to"); }
- | FROM
- { $$ = make1_str("from"); }
- ;
- /*
- * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
- * used depends on the direction. (It really doesn't make sense to copy from
- * stdout. We silently correct the "typo". - AY 9/94
- */
- copy_file_name: Sconst { $$ = $1; }
- | STDIN { $$ = make1_str("stdin"); }
- | STDOUT { $$ = make1_str("stdout"); }
- ;
- opt_binary: BINARY { $$ = make1_str("binary"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- opt_with_copy: WITH OIDS { $$ = make1_str("with oids"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /*
- * the default copy delimiter is tab but the user can configure it
- */
- copy_delimiter: USING DELIMITERS Sconst { $$ = cat2_str(make1_str("using delimiters"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /*****************************************************************************
- *
- * QUERY :
- * CREATE relname
- *
- *****************************************************************************/
- CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
- OptInherit
- {
- $$ = cat3_str(cat4_str(make1_str("create"), $2, make1_str("table"), $4), make3_str(make1_str("("), $6, make1_str(")")), $8);
- }
- ;
- OptTemp: OptTempType { $$ = $1; }
- | OptTempScope OptTempType { $$ = cat2_str($1,$2); }
- ;
- OptTempType: TEMP { $$ = make1_str("temp"); }
- | TEMPORARY { $$ = make1_str("temporary"); }
- | /* EMPTY */ { $$ = make1_str(""); }
- ;
- OptTempScope: GLOBAL
- {
- yyerror("GLOBAL TEMPORARY TABLE is not currently supported");
- $$ = make1_str("global");
- }
- | LOCAL { $$ = make1_str("local"); }
- ;
- OptTableElementList: OptTableElementList ',' OptTableElement
- {
- $$ = cat3_str($1, make1_str(","), $3);
- }
- | OptTableElement
- {
- $$ = $1;
- }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- OptTableElement: columnDef { $$ = $1; }
- | TableConstraint { $$ = $1; }
- ;
- columnDef: ColId Typename ColQualifier
- {
- $$ = cat3_str($1, $2, $3);
- }
- | ColId SERIAL ColPrimaryKey
- {
- $$ = make3_str($1, make1_str(" serial "), $3);
- }
- ;
- ColQualifier: ColQualList { $$ = $1; }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- ColQualList: ColQualList ColConstraint { $$ = cat2_str($1,$2); }
- | ColConstraint { $$ = $1; }
- ;
- ColPrimaryKey: PRIMARY KEY
- {
- $$ = make1_str("primary key");
- }
- | /*EMPTY*/
- {
- $$ = make1_str("");
- }
- ;
- ColConstraint:
- CONSTRAINT name ColConstraintElem
- {
- $$ = cat3_str(make1_str("constraint"), $2, $3);
- }
- | ColConstraintElem
- { $$ = $1; }
- ;
- /* DEFAULT NULL is already the default for Postgres.
- * Bue define it here and carry it forward into the system
- * to make it explicit.
- * - thomas 1998-09-13
- * WITH NULL and NULL are not SQL92-standard syntax elements,
- * so leave them out. Use DEFAULT NULL to explicitly indicate
- * that a column may have that value. WITH NULL leads to
- * shift/reduce conflicts with WITH TIME ZONE anyway.
- * - thomas 1999-01-08
- */
- ColConstraintElem: CHECK '(' constraint_expr ')'
- {
- $$ = make3_str(make1_str("check("), $3, make1_str(")"));
- }
- | DEFAULT NULL_P
- {
- $$ = make1_str("default null");
- }
- | DEFAULT default_expr
- {
- $$ = cat2_str(make1_str("default"), $2);
- }
- | NOT NULL_P
- {
- $$ = make1_str("not null");
- }
- | UNIQUE
- {
- $$ = make1_str("unique");
- }
- | PRIMARY KEY
- {
- $$ = make1_str("primary key");
- }
- | REFERENCES ColId opt_column_list key_match key_actions
- {
- fprintf(stderr, "CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
- $$ = make1_str("");
- }
- ;
- default_list: default_list ',' default_expr
- {
- $$ = cat3_str($1, make1_str(","), $3);
- }
- | default_expr
- {
- $$ = $1;
- }
- ;
- /* The Postgres default column value is NULL.
- * Rather than carrying DEFAULT NULL forward as a clause,
- * let's just have it be a no-op.
- | NULL_P
- { $$ = make1_str("null"); }
- * - thomas 1998-09-13
- */
- default_expr: AexprConst
- { $$ = $1; }
- | '-' default_expr %prec UMINUS
- { $$ = cat2_str(make1_str("-"), $2); }
- | default_expr '+' default_expr
- { $$ = cat3_str($1, make1_str("+"), $3); }
- | default_expr '-' default_expr
- { $$ = cat3_str($1, make1_str("-"), $3); }
- | default_expr '/' default_expr
- { $$ = cat3_str($1, make1_str("/"), $3); }
- | default_expr '%' default_expr
- { $$ = cat3_str($1, make1_str("%"), $3); }
- | default_expr '*' default_expr
- { $$ = cat3_str($1, make1_str("*"), $3); }
- | default_expr '=' default_expr
- { yyerror("boolean expressions not supported in DEFAULT"); }
- | default_expr '<' default_expr
- { yyerror("boolean expressions not supported in DEFAULT"); }
- | default_expr '>' default_expr
- { yyerror("boolean expressions not supported in DEFAULT"); }
- /* not possible in embedded sql
- | ':' default_expr
- { $$ = cat2_str(make1_str(":"), $2); }
- */
- | ';' default_expr
- { $$ = cat2_str(make1_str(";"), $2); }
- | '|' default_expr
- { $$ = cat2_str(make1_str("|"), $2); }
- | default_expr TYPECAST Typename
- { $$ = cat3_str($1, make1_str("::"), $3); }
- | CAST '(' default_expr AS Typename ')'
- {
- $$ = cat3_str(make2_str(make1_str("cast("), $3) , make1_str("as"), make2_str($5, make1_str(")")));
- }
- | '(' default_expr ')'
- { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | func_name '(' ')'
- { $$ = cat2_str($1, make1_str("()")); }
- | func_name '(' default_list ')'
- { $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")"))); }
- | default_expr Op default_expr
- {
- if (!strcmp("<=", $2) || !strcmp(">=", $2))
- yyerror("boolean expressions not supported in DEFAULT");
- $$ = cat3_str($1, $2, $3);
- }
- | Op default_expr
- { $$ = cat2_str($1, $2); }
- | default_expr Op
- { $$ = cat2_str($1, $2); }
- /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
- | CURRENT_DATE
- { $$ = make1_str("current_date"); }
- | CURRENT_TIME
- { $$ = make1_str("current_time"); }
- | CURRENT_TIME '(' Iconst ')'
- {
- if ($3 != 0)
- fprintf(stderr, "CURRENT_TIME(%s) precision not implemented; zero used instead",$3);
- $$ = "current_time";
- }
- | CURRENT_TIMESTAMP
- { $$ = make1_str("current_timestamp"); }
- | CURRENT_TIMESTAMP '(' Iconst ')'
- {
- if ($3 != 0)
- fprintf(stderr, "CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
- $$ = "current_timestamp";
- }
- | CURRENT_USER
- { $$ = make1_str("current_user"); }
- | USER
- { $$ = make1_str("user"); }
- ;
- /* ConstraintElem specifies constraint syntax which is not embedded into
- * a column definition. ColConstraintElem specifies the embedded form.
- * - thomas 1997-12-03
- */
- TableConstraint: CONSTRAINT name ConstraintElem
- {
- $$ = cat3_str(make1_str("constraint"), $2, $3);
- }
- | ConstraintElem
- { $$ = $1; }
- ;
- ConstraintElem: CHECK '(' constraint_expr ')'
- {
- $$ = make3_str(make1_str("check("), $3, make1_str(")"));
- }
- | UNIQUE '(' columnList ')'
- {
- $$ = make3_str(make1_str("unique("), $3, make1_str(")"));
- }
- | PRIMARY KEY '(' columnList ')'
- {
- $$ = make3_str(make1_str("primary key("), $4, make1_str(")"));
- }
- | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
- {
- fprintf(stderr, "CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
- $$ = "";
- }
- ;
- constraint_list: constraint_list ',' constraint_expr
- {
- $$ = cat3_str($1, make1_str(","), $3);
- }
- | constraint_expr
- {
- $$ = $1;
- }
- ;
- constraint_expr: AexprConst
- { $$ = $1; }
- | NULL_P
- { $$ = make1_str("null"); }
- | ColId
- {
- $$ = $1;
- }
- | '-' constraint_expr %prec UMINUS
- { $$ = cat2_str(make1_str("-"), $2); }
- | constraint_expr '+' constraint_expr
- { $$ = cat3_str($1, make1_str("+"), $3); }
- | constraint_expr '-' constraint_expr
- { $$ = cat3_str($1, make1_str("-"), $3); }
- | constraint_expr '/' constraint_expr
- { $$ = cat3_str($1, make1_str("/"), $3); }
- | constraint_expr '%' constraint_expr
- { $$ = cat3_str($1, make1_str("%"), $3); }
- | constraint_expr '*' constraint_expr
- { $$ = cat3_str($1, make1_str("*"), $3); }
- | constraint_expr '=' constraint_expr
- { $$ = cat3_str($1, make1_str("="), $3); }
- | constraint_expr '<' constraint_expr
- { $$ = cat3_str($1, make1_str("<"), $3); }
- | constraint_expr '>' constraint_expr
- { $$ = cat3_str($1, make1_str(">"), $3); }
- /* this one doesn't work with embedded sql anyway
- | ':' constraint_expr
- { $$ = cat2_str(make1_str(":"), $2); }
- */
- | ';' constraint_expr
- { $$ = cat2_str(make1_str(";"), $2); }
- | '|' constraint_expr
- { $$ = cat2_str(make1_str("|"), $2); }
- | constraint_expr TYPECAST Typename
- {
- $$ = cat3_str($1, make1_str("::"), $3);
- }
- | CAST '(' constraint_expr AS Typename ')'
- {
- $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
- }
- | '(' constraint_expr ')'
- { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | func_name '(' ')'
- {
- { $$ = cat2_str($1, make1_str("()")); }
- }
- | func_name '(' constraint_list ')'
- {
- $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")")));
- }
- | constraint_expr Op constraint_expr
- { $$ = cat3_str($1, $2, $3); }
- | constraint_expr LIKE constraint_expr
- { $$ = cat3_str($1, make1_str("like"), $3); }
- | constraint_expr NOT LIKE constraint_expr
- { $$ = cat3_str($1, make1_str("not like"), $4); }
- | constraint_expr AND constraint_expr
- { $$ = cat3_str($1, make1_str("and"), $3); }
- | constraint_expr OR constraint_expr
- { $$ = cat3_str($1, make1_str("or"), $3); }
- | NOT constraint_expr
- { $$ = cat2_str(make1_str("not"), $2); }
- | Op constraint_expr
- { $$ = cat2_str($1, $2); }
- | constraint_expr Op
- { $$ = cat2_str($1, $2); }
- | constraint_expr ISNULL
- { $$ = cat2_str($1, make1_str("isnull")); }
- | constraint_expr IS NULL_P
- { $$ = cat2_str($1, make1_str("is null")); }
- | constraint_expr NOTNULL
- { $$ = cat2_str($1, make1_str("notnull")); }
- | constraint_expr IS NOT NULL_P
- { $$ = cat2_str($1, make1_str("is not null")); }
- | constraint_expr IS TRUE_P
- { $$ = cat2_str($1, make1_str("is true")); }
- | constraint_expr IS FALSE_P
- { $$ = cat2_str($1, make1_str("is false")); }
- | constraint_expr IS NOT TRUE_P
- { $$ = cat2_str($1, make1_str("is not true")); }
- | constraint_expr IS NOT FALSE_P
- { $$ = cat2_str($1, make1_str("is not false")); }
- | constraint_expr IN '(' c_list ')'
- { $$ = cat4_str($1, make1_str("in ("), $4, make1_str(")")); }
- | constraint_expr NOT IN '(' c_list ')'
- { $$ = cat4_str($1, make1_str("not in ("), $5, make1_str(")")); }
- | constraint_expr BETWEEN c_expr AND c_expr
- { $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5); }
- | constraint_expr NOT BETWEEN c_expr AND c_expr
- { $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6); }
- ;
- c_list: c_list ',' c_expr
- {
- $$ = make3_str($1, make1_str(", "), $3);
- }
- | c_expr
- {
- $$ = $1;
- }
- c_expr: AexprConst
- {
- $$ = $1;
- }
- key_match: MATCH FULL { $$ = make1_str("match full"); }
- | MATCH PARTIAL { $$ = make1_str("match partial"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- key_actions: key_action key_action { $$ = cat2_str($1, $2); }
- | key_action { $$ = $1; }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- key_action: ON DELETE key_reference { $$ = cat2_str(make1_str("on delete"), $3); }
- | ON UPDATE key_reference { $$ = cat2_str(make1_str("on update"), $3); }
- ;
- key_reference: NO ACTION { $$ = make1_str("no action"); }
- | CASCADE { $$ = make1_str("cascade"); }
- | SET DEFAULT { $$ = make1_str("set default"); }
- | SET NULL_P { $$ = make1_str("set null"); }
- ;
- OptInherit: INHERITS '(' relation_name_list ')' { $$ = make3_str(make1_str("inherits ("), $3, make1_str(")")); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS SubSelect
- {
- $$ = cat5_str(cat3_str(make1_str("create"), $2, make1_str("table")), $4, $5, make1_str("as"), $7);
- }
- ;
- OptCreateAs: '(' CreateAsList ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- CreateAsList: CreateAsList ',' CreateAsElement { $$ = cat3_str($1, make1_str(","), $3); }
- | CreateAsElement { $$ = $1; }
- ;
- CreateAsElement: ColId { $$ = $1; }
- ;
- /*****************************************************************************
- *
- * QUERY :
- * CREATE SEQUENCE seqname
- *
- *****************************************************************************/
- CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
- {
- $$ = cat3_str(make1_str("create sequence"), $3, $4);
- }
- ;
- OptSeqList: OptSeqList OptSeqElem
- { $$ = cat2_str($1, $2); }
- | { $$ = make1_str(""); }
- ;
- OptSeqElem: CACHE IntegerOnly
- {
- $$ = cat2_str(make1_str("cache"), $2);
- }
- | CYCLE
- {
- $$ = make1_str("cycle");
- }
- | INCREMENT IntegerOnly
- {
- $$ = cat2_str(make1_str("increment"), $2);
- }
- | MAXVALUE IntegerOnly
- {
- $$ = cat2_str(make1_str("maxvalue"), $2);
- }
- | MINVALUE IntegerOnly
- {
- $$ = cat2_str(make1_str("minvalue"), $2);
- }
- | START IntegerOnly
- {
- $$ = cat2_str(make1_str("start"), $2);
- }
- ;
- NumericOnly: FloatOnly { $$ = $1; }
- | IntegerOnly { $$ = $1; }
- FloatOnly: Fconst
- {
- $$ = $1;
- }
- | '-' Fconst
- {
- $$ = cat2_str(make1_str("-"), $2);
- }
- ;
- IntegerOnly: Iconst
- {
- $$ = $1;
- }
- | '-' Iconst
- {
- $$ = cat2_str(make1_str("-"), $2);
- }
- ;
- /*****************************************************************************
- *
- * QUERIES :
- * CREATE PROCEDURAL LANGUAGE ...
- * DROP PROCEDURAL LANGUAGE ...
- *
- *****************************************************************************/
- CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
- HANDLER def_name LANCOMPILER Sconst
- {
- $$ = cat4_str(cat5_str(make1_str("create"), $2, make1_str("precedural language"), $5, make1_str("handler")), $7, make1_str("langcompiler"), $9);
- }
- ;
- PLangTrusted: TRUSTED { $$ = make1_str("trusted"); }
- | { $$ = make1_str(""); }
- DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
- {
- $$ = cat2_str(make1_str("drop procedural language"), $4);
- }
- ;
- /*****************************************************************************
- *
- * QUERIES :
- * CREATE TRIGGER ...
- * DROP TRIGGER ...
- *
- *****************************************************************************/
- CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
- relation_name TriggerForSpec EXECUTE PROCEDURE
- name '(' TriggerFuncArgs ')'
- {
- $$ = 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(")")));
- }
- ;
- TriggerActionTime: BEFORE { $$ = make1_str("before"); }
- | AFTER { $$ = make1_str("after"); }
- ;
- TriggerEvents: TriggerOneEvent
- {
- $$ = $1;
- }
- | TriggerOneEvent OR TriggerOneEvent
- {
- $$ = cat3_str($1, make1_str("or"), $3);
- }
- | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
- {
- $$ = cat5_str($1, make1_str("or"), $3, make1_str("or"), $5);
- }
- ;
- TriggerOneEvent: INSERT { $$ = make1_str("insert"); }
- | DELETE { $$ = make1_str("delete"); }
- | UPDATE { $$ = make1_str("update"); }
- ;
- TriggerForSpec: FOR TriggerForOpt TriggerForType
- {
- $$ = cat3_str(make1_str("for"), $2, $3);
- }
- ;
- TriggerForOpt: EACH { $$ = make1_str("each"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- TriggerForType: ROW { $$ = make1_str("row"); }
- | STATEMENT { $$ = make1_str("statement"); }
- ;
- TriggerFuncArgs: TriggerFuncArg
- { $$ = $1; }
- | TriggerFuncArgs ',' TriggerFuncArg
- { $$ = cat3_str($1, make1_str(","), $3); }
- | /*EMPTY*/
- { $$ = make1_str(""); }
- ;
- TriggerFuncArg: Iconst
- {
- $$ = $1;
- }
- | Fconst
- {
- $$ = $1;
- }
- | Sconst { $$ = $1; }
- | ident { $$ = $1; }
- ;
- DropTrigStmt: DROP TRIGGER name ON relation_name
- {
- $$ = cat4_str(make1_str("drop trigger"), $3, make1_str("on"), $5);
- }
- ;
- /*****************************************************************************
- *
- * QUERY :
- * define (type,operator,aggregate)
- *
- *****************************************************************************/
- DefineStmt: CREATE def_type def_rest
- {
- $$ = cat3_str(make1_str("create"), $2, $3);
- }
- ;
- def_rest: def_name definition
- {
- $$ = cat2_str($1, $2);
- }
- ;
- def_type: OPERATOR { $$ = make1_str("operator"); }
- | TYPE_P { $$ = make1_str("type"); }
- | AGGREGATE { $$ = make1_str("aggregate"); }
- ;
- def_name: PROCEDURE { $$ = make1_str("procedure"); }
- | JOIN { $$ = make1_str("join"); }
- | ColId { $$ = $1; }
- | MathOp { $$ = $1; }
- | Op { $$ = $1; }
- ;
- definition: '(' def_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- ;
- def_list: def_elem { $$ = $1; }
- | def_list ',' def_elem { $$ = cat3_str($1, make1_str(","), $3); }
- ;
- def_elem: def_name '=' def_arg {
- $$ = cat3_str($1, make1_str("="), $3);
- }
- | def_name
- {
- $$ = $1;
- }
- | DEFAULT '=' def_arg
- {
- $$ = cat2_str(make1_str("default ="), $3);
- }
- ;
- def_arg: ColId { $$ = $1; }
- | all_Op { $$ = $1; }
- | NumericOnly { $$ = $1; }
- | Sconst { $$ = $1; }
- | SETOF ColId
- {
- $$ = cat2_str(make1_str("setof"), $2);
- }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * destroy <relname1> [, <relname2> .. <relnameN> ]
- *
- *****************************************************************************/
- DestroyStmt: DROP TABLE relation_name_list
- {
- $$ = cat2_str(make1_str("drop table"), $3);
- }
- | DROP SEQUENCE relation_name_list
- {
- $$ = cat2_str(make1_str("drop sequence"), $3);
- }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
- * fetch [ forward | backward | absolute | relative ]
- * [ # | all | next | prior ] [ [ in | from ] <portalname> ]
- *
- *****************************************************************************/
- FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name INTO into_list
- {
- if (strncmp($2, "relative", strlen("relative")) == 0 && atol($3) == 0L)
- yyerror("FETCH/RELATIVE at current position is not supported");
- $$ = cat4_str(make1_str("fetch"), $2, $3, $4);
- }
- | MOVE opt_direction fetch_how_many opt_portal_name
- {
- $$ = cat4_str(make1_str("fetch"), $2, $3, $4);
- }
- ;
- opt_direction: FORWARD { $$ = make1_str("forward"); }
- | BACKWARD { $$ = make1_str("backward"); }
- | RELATIVE { $$ = make1_str("relative"); }
- | ABSOLUTE
- {
- fprintf(stderr, "FETCH/ABSOLUTE not supported, using RELATIVE");
- $$ = make1_str("absolute");
- }
- | /*EMPTY*/ { $$ = make1_str(""); /* default */ }
- ;
- fetch_how_many: Iconst { $$ = $1; }
- | '-' Iconst { $$ = make2_str(make1_str("-"), $2); }
- | ALL { $$ = make1_str("all"); }
- | NEXT { $$ = make1_str("next"); }
- | PRIOR { $$ = make1_str("prior"); }
- | /*EMPTY*/ { $$ = make1_str(""); /*default*/ }
- ;
- opt_portal_name: IN name { $$ = cat2_str(make1_str("in"), $2); }
- | FROM name { $$ = cat2_str(make1_str("from"), $2); }
- /* | name { $$ = cat2_str(make1_str("in"), $1); */
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
- *
- *****************************************************************************/
- GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
- {
- $$ = cat2_str(cat5_str(make1_str("grant"), $2, make1_str("on"), $4, make1_str("to")), $6);
- }
- ;
- privileges: ALL PRIVILEGES
- {
- $$ = make1_str("all privileges");
- }
- | ALL
- {
- $$ = make1_str("all");
- }
- | operation_commalist
- {
- $$ = $1;
- }
- ;
- operation_commalist: operation
- {
- $$ = $1;
- }
- | operation_commalist ',' operation
- {
- $$ = cat3_str($1, make1_str(","), $3);
- }
- ;
- operation: SELECT
- {
- $$ = make1_str("select");
- }
- | INSERT
- {
- $$ = make1_str("insert");
- }
- | UPDATE
- {
- $$ = make1_str("update");
- }
- | DELETE
- {
- $$ = make1_str("delete");
- }
- | RULE
- {
- $$ = make1_str("rule");
- }
- ;
- grantee: PUBLIC
- {
- $$ = make1_str("public");
- }
- | GROUP ColId
- {
- $$ = cat2_str(make1_str("group"), $2);
- }
- | ColId
- {
- $$ = $1;
- }
- ;
- opt_with_grant: WITH GRANT OPTION
- {
- yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
- }
- | /*EMPTY*/
- ;
- /*****************************************************************************
- *
- * QUERY:
- * REVOKE [privileges] ON [relation_name] FROM [user]
- *
- *****************************************************************************/
- RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
- {
- $$ = cat2_str(cat5_str(make1_str("revoke"), $2, make1_str("on"), $4, make1_str("from")), $6);
- }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * create index <indexname> on <relname>
- * using <access> "(" (<col> with <op>)+ ")" [with
- * <target_list>]
- *
- * [where <qual>] is not supported anymore
- *****************************************************************************/
- IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
- access_method_clause '(' index_params ')' opt_with
- {
- /* should check that access_method is valid,
- etc ... but doesn't */
- $$ = 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);
- }
- ;
- index_opt_unique: UNIQUE { $$ = make1_str("unique"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- access_method_clause: USING access_method { $$ = cat2_str(make1_str("using"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- index_params: index_list { $$ = $1; }
- | func_index { $$ = $1; }
- ;
- index_list: index_list ',' index_elem { $$ = cat3_str($1, make1_str(","), $3); }
- | index_elem { $$ = $1; }
- ;
- func_index: func_name '(' name_list ')' opt_type opt_class
- {
- $$ = cat4_str($1, make3_str(make1_str("("), $3, ")"), $5, $6);
- }
- ;
- index_elem: attr_name opt_type opt_class
- {
- $$ = cat3_str($1, $2, $3);
- }
- ;
- opt_type: ':' Typename { $$ = cat2_str(make1_str(":"), $2); }
- | FOR Typename { $$ = cat2_str(make1_str("for"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /* opt_class "WITH class" conflicts with preceeding opt_type
- * for Typename of "TIMESTAMP WITH TIME ZONE"
- * So, remove "WITH class" from the syntax. OK??
- * - thomas 1997-10-12
- * | WITH class { $$ = $2; }
- */
- opt_class: class { $$ = $1; }
- | USING class { $$ = cat2_str(make1_str("using"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * extend index <indexname> [where <qual>]
- *
- *****************************************************************************/
- ExtendStmt: EXTEND INDEX index_name where_clause
- {
- $$ = cat3_str(make1_str("extend index"), $3, $4);
- }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * execute recipe <recipeName>
- *
- *****************************************************************************/
- /* NOT USED
- RecipeStmt: EXECUTE RECIPE recipe_name
- {
- $$ = cat2_str(make1_str("execute recipe"), $3);
- }
- ;
- */
- /*****************************************************************************
- *
- * QUERY:
- * define function <fname>
- * (language = <lang>, returntype = <typename>
- * [, arch_pct = <percentage | pre-defined>]
- * [, disk_pct = <percentage | pre-defined>]
- * [, byte_pct = <percentage | pre-defined>]
- * [, perbyte_cpu = <int | pre-defined>]
- * [, percall_cpu = <int | pre-defined>]
- * [, iscachable])
- * [arg is (<type-1> { , <type-n>})]
- * as <filename or code in language as appropriate>
- *
- *****************************************************************************/
- ProcedureStmt: CREATE FUNCTION func_name func_args
- RETURNS func_return opt_with AS Sconst LANGUAGE Sconst
- {
- $$ = 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);
- }
- opt_with: WITH definition { $$ = cat2_str(make1_str("with"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- func_args: '(' func_args_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | '(' ')' { $$ = make1_str("()"); }
- ;
- func_args_list: TypeId { $$ = $1; }
- | func_args_list ',' TypeId
- { $$ = cat3_str($1, make1_str(","), $3); }
- ;
- func_return: set_opt TypeId
- {
- $$ = cat2_str($1, $2);
- }
- ;
- set_opt: SETOF { $$ = make1_str("setof"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /*****************************************************************************
- *
- * QUERY:
- *
- * remove function <funcname>
- * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
- * remove aggregate <aggname>
- * (REMOVE AGGREGATE "aggname" "aggtype")
- * remove operator <opname>
- * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
- * remove type <typename>
- * (REMOVE TYPE "typename")
- * remove rule <rulename>
- * (REMOVE RULE "rulename")
- *
- *****************************************************************************/
- RemoveStmt: DROP remove_type name
- {
- $$ = cat3_str(make1_str("drop"), $2, $3);
- }
- ;
- remove_type: TYPE_P { $$ = make1_str("type"); }
- | INDEX { $$ = make1_str("index"); }
- | RULE { $$ = make1_str("rule"); }
- | VIEW { $$ = make1_str("view"); }
- ;
- RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
- {
- $$ = cat3_str(make1_str("drop aggregate"), $3, $4);
- }
- ;
- aggr_argtype: name { $$ = $1; }
- | '*' { $$ = make1_str("*"); }
- ;
- RemoveFuncStmt: DROP FUNCTION func_name func_args
- {
- $$ = cat3_str(make1_str("drop function"), $3, $4);
- }
- ;
- RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
- {
- $$ = cat3_str(make1_str("drop operator"), $3, make3_str(make1_str("("), $5, make1_str(")")));
- }
- ;
- all_Op: Op | MathOp;
- MathOp: '+' { $$ = make1_str("+"); }
- | '-' { $$ = make1_str("-"); }
- | '*' { $$ = make1_str("*"); }
- | '%' { $$ = make1_str("%"); }
- | '/' { $$ = make1_str("/"); }
- | '<' { $$ = make1_str("<"); }
- | '>' { $$ = make1_str(">"); }
- | '=' { $$ = make1_str("="); }
- ;
- oper_argtypes: name
- {
- yyerror("parser: argument type missing (use NONE for unary operators)");
- }
- | name ',' name
- { $$ = cat3_str($1, make1_str(","), $3); }
- | NONE ',' name /* left unary */
- { $$ = cat2_str(make1_str("none,"), $3); }
- | name ',' NONE /* right unary */
- { $$ = cat2_str($1, make1_str(", none")); }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * rename <attrname1> in <relname> [*] to <attrname2>
- * rename <relname1> to <relname2>
- *
- *****************************************************************************/
- RenameStmt: ALTER TABLE relation_name opt_inh_star
- RENAME opt_column opt_name TO name
- {
- $$ = cat4_str(cat5_str(make1_str("alter table"), $3, $4, make1_str("rename"), $6), $7, make1_str("to"), $9);
- }
- ;
- opt_name: name { $$ = $1; }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- opt_column: COLUMN { $$ = make1_str("colmunn"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /*****************************************************************************
- *
- * QUERY: Define Rewrite Rule , Define Tuple Rule
- * Define Rule <old rules >
- *
- * only rewrite rule is supported -- ay 9/94
- *
- *****************************************************************************/
- RuleStmt: CREATE RULE name AS
- { QueryIsRule=1; }
- ON event TO event_object where_clause
- DO opt_instead RuleActionList
- {
- $$ = 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);
- }
- ;
- RuleActionList: NOTHING { $$ = make1_str("nothing"); }
- | SelectStmt { $$ = $1; }
- | RuleActionStmt { $$ = $1; }
- | '[' RuleActionBlock ']' { $$ = cat3_str(make1_str("["), $2, make1_str("]")); }
- | '(' RuleActionBlock ')' { $$ = cat3_str(make1_str("("), $2, make1_str(")")); }
- ;
- RuleActionBlock: RuleActionMulti { $$ = $1; }
- | RuleActionStmt { $$ = $1; }
- ;
- RuleActionMulti: RuleActionMulti RuleActionStmt
- { $$ = cat2_str($1, $2); }
- | RuleActionMulti RuleActionStmt ';'
- { $$ = cat3_str($1, $2, make1_str(";")); }
- | RuleActionStmt ';'
- { $$ = cat2_str($1, make1_str(";")); }
- ;
- RuleActionStmt: InsertStmt
- | UpdateStmt
- | DeleteStmt
- | NotifyStmt
- ;
- event_object: relation_name '.' attr_name
- {
- $$ = make3_str($1, make1_str("."), $3);
- }
- | relation_name
- {
- $$ = $1;
- }
- ;
- /* change me to select, update, etc. some day */
- event: SELECT { $$ = make1_str("select"); }
- | UPDATE { $$ = make1_str("update"); }
- | DELETE { $$ = make1_str("delete"); }
- | INSERT { $$ = make1_str("insert"); }
- ;
- opt_instead: INSTEAD { $$ = make1_str("instead"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * NOTIFY <relation_name> can appear both in rule bodies and
- * as a query-level command
- *
- *****************************************************************************/
- NotifyStmt: NOTIFY relation_name
- {
- $$ = cat2_str(make1_str("notify"), $2);
- }
- ;
- ListenStmt: LISTEN relation_name
- {
- $$ = cat2_str(make1_str("listen"), $2);
- }
- ;
- UnlistenStmt: UNLISTEN relation_name
- {
- $$ = cat2_str(make1_str("unlisten"), $2);
- }
- | UNLISTEN '*'
- {
- $$ = make1_str("unlisten *");
- }
- ;
- /*****************************************************************************
- *
- * Transactions:
- *
- * abort transaction
- * (ABORT)
- * begin transaction
- * (BEGIN)
- * end transaction
- * (END)
- *
- *****************************************************************************/
- TransactionStmt: ABORT_TRANS opt_trans { $$ = make1_str("rollback"); }
- | BEGIN_TRANS opt_trans { $$ = make1_str("begin transaction"); }
- | COMMIT opt_trans { $$ = make1_str("commit"); }
- | END_TRANS opt_trans { $$ = make1_str("commit"); }
- | ROLLBACK opt_trans { $$ = make1_str("rollback"); }
- opt_trans: WORK { $$ = ""; }
- | TRANSACTION { $$ = ""; }
- | /*EMPTY*/ { $$ = ""; }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * define view <viewname> '('target-list ')' [where <quals> ]
- *
- *****************************************************************************/
- ViewStmt: CREATE VIEW name AS SelectStmt
- {
- $$ = cat4_str(make1_str("create view"), $3, make1_str("as"), $5);
- }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * load make1_str("filename")
- *
- *****************************************************************************/
- LoadStmt: LOAD file_name
- {
- $$ = cat2_str(make1_str("load"), $2);
- }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * createdb dbname
- *
- *****************************************************************************/
- CreatedbStmt: CREATE DATABASE database_name WITH opt_database1 opt_database2
- {
- if (strlen($5) == 0 || strlen($6) == 0)
- yyerror("CREATE DATABASE WITH requires at least an option");
- #ifndef MULTIBYTE
- if (strlen($6) != 0)
- yyerror("WITH ENCODING is not supported");
- #endif
- $$ = cat5_str(make1_str("create database"), $3, make1_str("with"), $5, $6);
- }
- | CREATE DATABASE database_name
- {
- $$ = cat2_str(make1_str("create database"), $3);
- }
- ;
- opt_database1: LOCATION '=' location { $$ = cat2_str(make1_str("location ="), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- opt_database2: ENCODING '=' encoding { $$ = cat2_str(make1_str("encoding ="), $3); }
- | /*EMPTY*/ { $$ = NULL; }
- ;
- location: Sconst { $$ = $1; }
- | DEFAULT { $$ = make1_str("default"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- encoding: Sconst { $$ = $1; }
- | DEFAULT { $$ = make1_str("default"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * destroydb dbname
- *
- *****************************************************************************/
- DestroydbStmt: DROP DATABASE database_name
- {
- $$ = cat2_str(make1_str("drop database"), $3);
- }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * cluster <index_name> on <relation_name>
- *
- *****************************************************************************/
- ClusterStmt: CLUSTER index_name ON relation_name
- {
- $$ = cat4_str(make1_str("cluster"), $2, make1_str("on"), $4);
- }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * vacuum
- *
- *****************************************************************************/
- VacuumStmt: VACUUM opt_verbose opt_analyze
- {
- $$ = cat3_str(make1_str("vacuum"), $2, $3);
- }
- | VACUUM opt_verbose opt_analyze relation_name opt_va_list
- {
- if ( strlen($5) > 0 && strlen($4) == 0 )
- yyerror("parser: syntax error at or near "("");
- $$ = cat5_str(make1_str("vacuum"), $2, $3, $4, $5);
- }
- ;
- opt_verbose: VERBOSE { $$ = make1_str("verbose"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- opt_analyze: ANALYZE { $$ = make1_str("analyse"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- opt_va_list: '(' va_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- va_list: name
- { $$=$1; }
- | va_list ',' name
- { $$=cat3_str($1, make1_str(","), $3); }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * EXPLAIN query
- *
- *****************************************************************************/
- ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
- {
- $$ = cat3_str(make1_str("explain"), $2, $3);
- }
- ;
- /*****************************************************************************
- * *
- * Optimizable Stmts: *
- * *
- * one of the five queries processed by the planner *
- * *
- * [ultimately] produces query-trees as specified *
- * in the query-spec document in ~postgres/ref *
- * *
- *****************************************************************************/
- OptimizableStmt: SelectStmt
- | CursorStmt
- | UpdateStmt
- | InsertStmt
- | NotifyStmt
- | DeleteStmt
- ;
- /*****************************************************************************
- *
- * QUERY:
- * INSERT STATEMENTS
- *
- *****************************************************************************/
- /***S*I***/
- /* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
- * originally. When the second rule of 'insert_rest' was changed to use
- * the new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/red uce
- * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to accept
- * the same statements without any shift/reduce conflicts */
- InsertStmt: INSERT INTO relation_name insert_rest
- {
- $$ = cat3_str(make1_str("insert into"), $3, $4);
- }
- ;
- insert_rest: VALUES '(' res_target_list2 ')'
- {
- $$ = make3_str(make1_str("values("), $3, make1_str(")"));
- }
- | DEFAULT VALUES
- {
- $$ = make1_str("default values");
- }
- | SelectStmt
- {
- $$ = $1;
- }
- | '(' columnList ')' VALUES '(' res_target_list2 ')'
- {
- $$ = make5_str(make1_str("("), $2, make1_str(") values ("), $6, make1_str(")"));
- }
- | '(' columnList ')' SelectStmt
- {
- $$ = make4_str(make1_str("("), $2, make1_str(")"), $4);
- }
- ;
- opt_column_list: '(' columnList ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- columnList:
- columnList ',' columnElem
- { $$ = cat3_str($1, make1_str(","), $3); }
- | columnElem
- { $$ = $1; }
- ;
- columnElem: ColId opt_indirection
- {
- $$ = cat2_str($1, $2);
- }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * DELETE STATEMENTS
- *
- *****************************************************************************/
- DeleteStmt: DELETE FROM relation_name
- where_clause
- {
- $$ = cat3_str(make1_str("delete from"), $3, $4);
- }
- ;
- LockStmt: LOCK_P opt_table relation_name opt_lock
- {
- $$ = cat4_str(make1_str("lock"), $2, $3, $4);
- }
- ;
- opt_lock: IN lock_type MODE { $$ = cat3_str(make1_str("in"), $2, make1_str("mode")); }
- | /*EMPTY*/ { $$ = make1_str("");}
- ;
- lock_type: SHARE ROW EXCLUSIVE { $$ = make1_str("share row exclusive"); }
- | ROW opt_lmode { $$ = cat2_str(make1_str("row"), $2);}
- | ACCESS opt_lmode { $$ = cat2_str(make1_str("access"), $2);}
- | opt_lmode { $$ = $1; }
- ;
- opt_lmode: SHARE { $$ = make1_str("share"); }
- | EXCLUSIVE { $$ = make1_str("exclusive"); }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * UpdateStmt (UPDATE)
- *
- *****************************************************************************/
- UpdateStmt: UPDATE relation_name
- SET res_target_list
- from_clause
- where_clause
- {
- $$ = cat2_str(cat5_str(make1_str("update"), $2, make1_str("set"), $4, $5), $6);
- }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * CURSOR STATEMENTS
- *
- *****************************************************************************/
- CursorStmt: DECLARE name opt_cursor CURSOR FOR
- { ForUpdateNotAllowed = 1; }
- SelectStmt
- {
- struct cursor *ptr, *this;
-
- for (ptr = cur; ptr != NULL; ptr = ptr->next)
- {
- if (strcmp($2, ptr->name) == 0)
- {
- /* re-definition is a bug */
- sprintf(errortext, "cursor %s already defined", $2);
- yyerror(errortext);
- }
- }
-
- this = (struct cursor *) mm_alloc(sizeof(struct cursor));
- /* initial definition */
- this->next = cur;
- this->name = $2;
- this->connection = connection;
- this->command = cat5_str(make1_str("declare"), mm_strdup($2), $3, make1_str("cursor for"), $7);
- this->argsinsert = argsinsert;
- this->argsresult = argsresult;
- argsinsert = argsresult = NULL;
-
- cur = this;
-
- $$ = cat3_str(make1_str("/*"), mm_strdup(this->command), make1_str("*/"));
- }
- ;
- opt_cursor: BINARY { $$ = make1_str("binary"); }
- | INSENSITIVE { $$ = make1_str("insensitive"); }
- | SCROLL { $$ = make1_str("scroll"); }
- | INSENSITIVE SCROLL { $$ = make1_str("insensitive scroll"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- /*****************************************************************************
- *
- * QUERY:
- * SELECT STATEMENTS
- *
- *****************************************************************************/
- /***S*I***/
- /* The new 'SelectStmt' rule adapted for the optional use of INTERSECT EXCEPT a nd UNION
- * accepts the use of '(' and ')' to select an order of set operations.
- * The rule returns a SelectStmt Node having the set operations attached to
- * unionClause and intersectClause (NIL if no set operations were present)
- */
- SelectStmt: select_clause sort_clause for_update_clause opt_select_limit
- {
- if (strlen($3) > 0 && ForUpdateNotAllowed != 0)
- yyerror("FOR UPDATE is not allowed in this context");
- ForUpdateNotAllowed = 0;
- $$ = cat4_str($1, $2, $3, $4);
- }
- /***S*I***/
- /* This rule parses Select statements including UNION INTERSECT and EXCEPT.
- * '(' and ')' can be used to specify the order of the operations
- * (UNION EXCEPT INTERSECT). Without the use of '(' and ')' we want the
- * operations to be left associative.
- *
- * The sort_clause is not handled here!
- */
- select_clause: '(' select_clause ')'
- {
- $$ = make3_str(make1_str("("), $2, make1_str(")"));
- }
- | SubSelect
- {
- $$ = $1;
- }
- | select_clause EXCEPT select_clause
- {
- $$ = cat3_str($1, make1_str("except"), $3);
- ForUpdateNotAllowed = 1;
- }
- | select_clause UNION opt_union select_clause
- {
- $$ = cat4_str($1, make1_str("union"), $3, $4);
- ForUpdateNotAllowed = 1;
- }
- | select_clause INTERSECT opt_union select_clause
- {
- $$ = cat3_str($1, make1_str("intersect"), $3);
- ForUpdateNotAllowed = 1;
- }
- ;
- /***S*I***/
- SubSelect: SELECT opt_unique res_target_list2
- result from_clause where_clause
- group_clause having_clause
- {
- $$ = cat4_str(cat5_str(make1_str("select"), $2, $3, $4, $5), $6, $7, $8);
- if (strlen($7) > 0 || strlen($8) > 0)
- ForUpdateNotAllowed = 1;
- }
- ;
- result: INTO OptTemp opt_table relation_name { $$= cat4_str(make1_str("into"), $2, $3, $4); }
- | INTO into_list { $$ = make1_str(""); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- opt_table: TABLE { $$ = make1_str("table"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- opt_union: ALL { $$ = make1_str("all"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- opt_unique: DISTINCT { $$ = make1_str("distinct"); }
- | DISTINCT ON ColId { $$ = cat2_str(make1_str("distinct on"), $3); }
- | ALL { $$ = make1_str("all"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- sort_clause: ORDER BY sortby_list { $$ = cat2_str(make1_str("order by"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- sortby_list: sortby { $$ = $1; }
- | sortby_list ',' sortby { $$ = cat3_str($1, make1_str(","), $3); }
- ;
- sortby: a_expr OptUseOp
- {
- $$ = cat2_str($1, $2);
- }
- ;
- OptUseOp: USING Op { $$ = cat2_str(make1_str("using"), $2); }
- | USING '<' { $$ = make1_str("using <"); }
- | USING '>' { $$ = make1_str("using >"); }
- | ASC { $$ = make1_str("asc"); }
- | DESC { $$ = make1_str("desc"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- opt_select_limit: LIMIT select_limit_value ',' select_offset_value
- { $$ = cat4_str(make1_str("limit"), $2, make1_str(","), $4); }
- | LIMIT select_limit_value OFFSET select_offset_value
- { $$ = cat4_str(make1_str("limit"), $2, make1_str("offset"), $4); }
- | LIMIT select_limit_value
- { $$ = cat2_str(make1_str("limit"), $2); }
- | OFFSET select_offset_value LIMIT select_limit_value
- { $$ = cat4_str(make1_str("offset"), $2, make1_str("limit"), $4); }
- | OFFSET select_offset_value
- { $$ = cat2_str(make1_str("offset"), $2); }
- | /* EMPTY */
- { $$ = make1_str(""); }
- ;
- select_limit_value: Iconst { $$ = $1; }
- | ALL { $$ = make1_str("all"); }
- | PARAM { $$ = make_name(); }
- ;
- select_offset_value: Iconst { $$ = $1; }
- | PARAM { $$ = make_name(); }
- ;
- /*
- * jimmy bell-style recursive queries aren't supported in the
- * current system.
- *
- * ...however, recursive addattr and rename supported. make special
- * cases for these.
- */
- opt_inh_star: '*' { $$ = make1_str("*"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- relation_name_list: name_list { $$ = $1; };
- name_list: name
- { $$ = $1; }
- | name_list ',' name
- { $$ = cat3_str($1, make1_str(","), $3); }
- ;
- group_clause: GROUP BY expr_list { $$ = cat2_str(make1_str("group by"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- having_clause: HAVING a_expr
- {
- $$ = cat2_str(make1_str("having"), $2);
- }
- | /*EMPTY*/ { $$ = make1_str(""); }
- ;
- for_update_clause: FOR UPDATE update_list
- {
- $$ = make1_str("for update");
- }
- | FOR READ ONLY
- {
- $$ = make1_str("for read only");
- }
- | /* EMPTY */
- {
- $$ = make1_str("");
- }
- ;
- update_list: OF va_list
- {
- $$ = cat2_str(make1_str("of"), $2);
- }
- | /* EMPTY */
- {
- $$ = make1_str("");
- }
- ;
- /*****************************************************************************
- *
- * clauses common to all Optimizable Stmts:
- * from_clause -
- * where_clause -
- *
- *****************************************************************************/
- from_clause: FROM from_expr
- {
- $$ = cat2_str(make1_str("from"), $2);
- }
- | /* EMPTY */
- {
- $$ = make1_str("");
- }
- from_expr: '(' join_clause_with_union ')'
- { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | join_clause
- { $$ = $1; }
- | table_list
- { $$ = $1; }
- ;
- table_list: table_list ',' table_expr
- { $$ = make3_str($1, make1_str(","), $3); }
- | table_expr
- { $$ = $1; }
- ;
- table_expr: relation_expr AS ColLabel
- {
- $$ = cat3_str($1, make1_str("as"), $3);
- }
- | relation_expr ColId
- {
- $$ = cat2_str($1, $2);
- }
- | relation_expr
- {
- $$ = $1;
- }
- ;
- /* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
- * all result rows which would have matched on an INNER JOIN.
- * Let's reject this for now. - thomas 1999-01-08