+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.373 2008/10/04 21:56:55 tgl Exp $ */
+
/* Copyright comment */
%{
#include "postgres_fe.h"
#include "extern.h"
+#include <unistd.h>
+
+/* Location tracking support --- simpler than bison's default */
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do { \
+ if (N) \
+ (Current) = (Rhs)[1]; \
+ else \
+ (Current) = (Rhs)[0]; \
+ } while (0)
+
+/*
+ * The %name-prefix option below will make bison call base_yylex, but we
+ * really want it to call filtered_base_yylex (see parser.c).
+ */
+#define base_yylex filtered_base_yylex
/*
* Variables containing simple states.
*/
-int struct_level = 0;
-int braces_open; /* brace level counter */
-char errortext[128];
+int struct_level = 0;
+int braces_open; /* brace level counter */
+int ecpg_informix_var = 0;
char *connection = NULL;
-char *input_filename = NULL;
+char *input_filename = NULL;
-static int QueryIsRule = 0, FoundInto = 0;
+static int QueryIsRule = 0, FoundInto = 0;
static int initializer = 0;
+static int pacounter = 1;
+static char pacounter_buffer[sizeof(int) * CHAR_BIT * 10 / 3]; /* a rough guess at the size we need */
static struct this_type actual_type[STRUCT_DEPTH];
-static char *actual_storage[STRUCT_DEPTH];
-static char *actual_startline[STRUCT_DEPTH];
+static char *actual_startline[STRUCT_DEPTH];
/* temporarily store struct members while creating the data structure */
struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
/* also store struct type so we can do a sizeof() later */
static char *ECPGstruct_sizeof = NULL;
-struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, NULL, {NULL}};
+/* for forward declarations we have to store some data as well */
+static char *forward_name = NULL;
+
+struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, NULL, NULL, {NULL}, 0};
struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
-struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, NULL, {NULL}};
+struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, {NULL}, 0};
/*
* Handle parsing errors and warnings
*/
void
-mmerror(int error_code, enum errortype type, char * error)
+mmerror(int error_code, enum errortype type, char * error, ...)
{
- switch(type)
- {
- case ET_WARNING:
- fprintf(stderr, "%s:%d: WARNING: %s\n", input_filename, yylineno, error);
- break;
- case ET_ERROR:
- fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
- ret_value = error_code;
- break;
- case ET_FATAL:
- fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
- exit(error_code);
- }
+ va_list ap;
+
+ /* internationalize the error message string */
+ error = _(error);
+
+ fprintf(stderr, "%s:%d: ", input_filename, yylineno);
+
+ switch(type)
+ {
+ case ET_WARNING:
+ fprintf(stderr, _("WARNING: "));
+ break;
+ case ET_ERROR:
+ case ET_FATAL:
+ fprintf(stderr, _("ERROR: "));
+ break;
+ }
+
+ va_start(ap, error);
+ vfprintf(stderr, error, ap);
+ va_end(ap);
+
+ fprintf(stderr, "\n");
+
+ switch(type)
+ {
+ case ET_WARNING:
+ break;
+ case ET_ERROR:
+ ret_value = error_code;
+ break;
+ case ET_FATAL:
+ if (yyin)
+ fclose(yyin);
+ if (yyout)
+ fclose(yyout);
+ if (unlink(output_filename) != 0 && *output_filename != '-')
+ fprintf(stderr, _("could not remove output file \"%s\"\n"), output_filename);
+ exit(error_code);
+ }
}
/*
static char *
cat2_str(char *str1, char *str2)
-{
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
+{
+ char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
strcpy(res_str, str1);
strcat(res_str, " ");
cat_str(int count, ...)
{
va_list args;
- int i;
+ int i;
char *res_str;
va_start(args, count);
static char *
make2_str(char *str1, char *str2)
-{
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
+{
+ char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
strcpy(res_str, str1);
strcat(res_str, str2);
static char *
make3_str(char *str1, char *str2, char *str3)
-{
- char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1);
+{
+ char * res_str = (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1);
strcpy(res_str, str1);
strcat(res_str, str2);
return(res_str);
}
+/* and the rest */
static char *
make_name(void)
{
return(name);
}
+static char *
+create_questionmarks(char *name, bool array)
+{
+ struct variable *p = find_variable(name);
+ int count;
+ char *result = EMPTY;
+
+ /* In case we have a struct, we have to print as many "?" as there are attributes in the struct
+ * An array is only allowed together with an element argument
+ * This is essantially only used for inserts, but using a struct as input parameter is an error anywhere else
+ * so we don't have to worry here. */
+
+ if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->u.element->type == ECPGt_struct))
+ {
+ struct ECPGstruct_member *m;
+
+ if (p->type->type == ECPGt_struct)
+ m = p->type->u.members;
+ else
+ m = p->type->u.element->u.members;
+
+ for (count = 0; m != NULL; m=m->next, count++);
+ }
+ else
+ count = 1;
+
+ for (; count > 0; count --)
+ {
+ sprintf(pacounter_buffer, "$%d", pacounter++);
+ result = cat_str(3, result, strdup(pacounter_buffer), make_str(" , "));
+ }
+
+ /* removed the trailing " ," */
+
+ result[strlen(result)-3] = '\0';
+ return(result);
+}
+
+static char *
+adjust_informix(struct arguments *list)
+{
+ /* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
+ * for instance you can declare variables in a function, and then subsequently use them
+ * {
+ * declare_vars();
+ * exec sql ... which uses vars declared in the above function
+ *
+ * This breaks standard and leads to some very dangerous programming.
+ * Since they do, we have to work around and accept their syntax as well.
+ * But we will do so ONLY in Informix mode.
+ * We have to change the variables to our own struct and just store the pointer instead of the variable
+ */
+
+ struct arguments *ptr;
+ char *result = make_str("");
+
+ for (ptr = list; ptr != NULL; ptr = ptr->next)
+ {
+ char temp[20]; /* this should be sufficient unless you have 8 byte integers */
+ char *original_var;
+
+ /* change variable name to "ECPG_informix_get_var(<counter>)" */
+ original_var = ptr->variable->name;
+ sprintf(temp, "%d))", ecpg_informix_var);
+
+ if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
+ {
+ ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1"), ptr->variable->type->u.element->lineno), ptr->variable->type->size), 0);
+ sprintf(temp, "%d, (", ecpg_informix_var++);
+ }
+ else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char || ptr->variable->type->type == ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
+ {
+ ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
+ sprintf(temp, "%d, (", ecpg_informix_var++);
+ }
+ else
+ {
+ ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
+ sprintf(temp, "%d, &(", ecpg_informix_var++);
+ }
+
+ /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
+ result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
+
+ /* now the indicator if there is one */
+ if (ptr->indicator->type->type != ECPGt_NO_INDICATOR)
+ {
+ /* change variable name to "ECPG_informix_get_var(<counter>)" */
+ original_var = ptr->indicator->name;
+ sprintf(temp, "%d))", ecpg_informix_var);
+
+ /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
+ if (atoi(ptr->indicator->type->size) > 1)
+ {
+ ptr->indicator = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
+ sprintf(temp, "%d, (", ecpg_informix_var++);
+ }
+ else
+ {
+ ptr->indicator = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
+ sprintf(temp, "%d, &(", ecpg_informix_var++);
+ }
+ result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
+ }
+ }
+
+ return result;
+}
+
+static struct cursor *
+add_additional_variables(char *name, bool insert)
+{
+ struct cursor *ptr;
+ struct arguments *p;
+
+ for (ptr = cur; ptr != NULL; ptr=ptr->next)
+ {
+ if (strcmp(ptr->name, name) == 0)
+ break;
+ }
+
+ if (ptr == NULL)
+ {
+ mmerror(PARSE_ERROR, ET_ERROR, "trying to access an undeclared cursor \"%s\"\n", name);
+ return NULL;
+ }
+
+ if (insert)
+ {
+ /* add all those input variables that were given earlier
+ * note that we have to append here but have to keep the existing order */
+ for (p = ptr->argsinsert; p; p = p->next)
+ add_variable_to_tail(&argsinsert, p->variable, p->indicator);
+ }
+
+ /* add all those output variables that were given earlier */
+ for (p = ptr->argsresult; p; p = p->next)
+ add_variable_to_tail(&argsresult, p->variable, p->indicator);
+
+ return ptr;
+}
+
+static void
+add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enum, char *type_dimension, char *type_index, int initializer, int array)
+{
+ /* add entry to list */
+ struct typedefs *ptr, *this;
+
+ if ((type_enum == ECPGt_struct ||
+ type_enum == ECPGt_union) &&
+ initializer == 1)
+ mmerror(PARSE_ERROR, ET_ERROR, "initializer not allowed in typedef command");
+ else
+ {
+ for (ptr = types; ptr != NULL; ptr = ptr->next)
+ {
+ if (strcmp(name, ptr->name) == 0)
+ /* re-definition is a bug */
+ mmerror(PARSE_ERROR, ET_ERROR, "type %s already defined", name);
+ }
+ adjust_array(type_enum, &dimension, &length, type_dimension, type_index, array, true);
+
+ this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
+
+ /* initial definition */
+ this->next = types;
+ this->name = name;
+ this->brace_level = braces_open;
+ this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
+ this->type->type_enum = type_enum;
+ this->type->type_str = mm_strdup(name);
+ this->type->type_dimension = dimension; /* dimension of array */
+ this->type->type_index = length; /* length of string */
+ this->type->type_sizeof = ECPGstruct_sizeof;
+ this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ?
+ ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
+
+ if (type_enum != ECPGt_varchar &&
+ type_enum != ECPGt_char &&
+ type_enum != ECPGt_unsigned_char &&
+ atoi(this->type->type_index) >= 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "no multidimensional array support for simple data types");
+
+ types = this;
+ }
+}
%}
+%name-prefix="base_yy"
+%locations
+
%union {
- double dval;
- int ival;
- char * str;
- struct when action;
- struct index index;
- int tagname;
- struct this_type type;
- enum ECPGttype type_enum;
- enum ECPGdtype dtype_enum;
- struct fetch_desc descriptor;
+ double dval;
+ char *str;
+ int ival;
+ struct when action;
+ struct index index;
+ int tagname;
+ struct this_type type;
+ enum ECPGttype type_enum;
+ enum ECPGdtype dtype_enum;
+ struct fetch_desc descriptor;
+ struct su_symbol struct_union;
+ struct prep prep;
}
/* special embedded SQL token */
-%token SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
-%token SQL_CALL SQL_CARDINALITY SQL_CONNECT SQL_CONNECTION
-%token SQL_CONTINUE SQL_COUNT
-%token SQL_DATA SQL_DATETIME_INTERVAL_CODE SQL_DATETIME_INTERVAL_PRECISION
-%token SQL_DEALLOCATE SQL_DESCRIPTOR SQL_DISCONNECT SQL_ENUM
-%token SQL_FOUND SQL_FREE SQL_GET SQL_GO SQL_GOTO
-%token SQL_IDENTIFIED SQL_INDICATOR SQL_INT SQL_KEY_MEMBER
-%token SQL_LENGTH SQL_LONG
-%token SQL_NAME SQL_NULLABLE
-%token SQL_OCTET_LENGTH SQL_OPEN SQL_PREPARE
-%token SQL_RELEASE SQL_REFERENCE SQL_RETURNED_LENGTH
-%token SQL_RETURNED_OCTET_LENGTH
-%token SQL_SCALE SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL
-%token SQL_SQLERROR SQL_SQLPRINT
-%token SQL_SQLWARNING SQL_START SQL_STOP SQL_STRUCT SQL_UNSIGNED
-%token SQL_VALUE SQL_VAR SQL_WHENEVER
+%token SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
+ SQL_CALL SQL_CARDINALITY SQL_CONNECT
+ SQL_COUNT SQL_DATA
+ SQL_DATETIME_INTERVAL_CODE
+ SQL_DATETIME_INTERVAL_PRECISION SQL_DESCRIBE
+ SQL_DESCRIPTOR SQL_DISCONNECT SQL_FOUND
+ SQL_FREE SQL_GET SQL_GO SQL_GOTO SQL_IDENTIFIED
+ SQL_INDICATOR SQL_KEY_MEMBER SQL_LENGTH
+ SQL_LONG SQL_NULLABLE SQL_OCTET_LENGTH
+ SQL_OPEN SQL_OUTPUT SQL_REFERENCE
+ SQL_RETURNED_LENGTH SQL_RETURNED_OCTET_LENGTH SQL_SCALE
+ SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL SQL_SQLERROR
+ SQL_SQLPRINT SQL_SQLWARNING SQL_START SQL_STOP
+ SQL_STRUCT SQL_UNSIGNED SQL_VAR SQL_WHENEVER
/* C token */
-%token S_ADD S_AND S_ANYTHING S_AUTO S_CONST S_DEC S_DIV S_DOTPOINT
-%token S_EQUAL S_EXTERN S_INC S_LSHIFT
-%token S_MEMPOINT S_MEMBER S_MOD S_MUL S_NEQUAL S_OR
-%token S_REGISTER S_RSHIFT S_STATIC S_SUB S_VOLATILE
+%token S_ADD S_AND S_ANYTHING S_AUTO S_CONST S_DEC S_DIV
+ S_DOTPOINT S_EQUAL S_EXTERN S_INC S_LSHIFT S_MEMPOINT
+ S_MEMBER S_MOD S_MUL S_NEQUAL S_OR S_REGISTER S_RSHIFT
+ S_STATIC S_SUB S_VOLATILE
+ S_TYPEDEF
/* 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, AT, AUTHORIZATION,
- BEGIN_TRANS, BETWEEN, BOTH, BY,
- CASCADE, CASE, CAST, CHAIN, CHAR, CHARACTER,
- CHARACTERISTICS, CHECK, CLOSE,
- COALESCE, COLLATE, COLUMN, COMMIT,
- CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT, CURRENT_DATE,
- CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
- DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
- ELSE, ENCRYPTED, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
- FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
- GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
- IN, INNER_P, INOUT, 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, OFF, OLD, ON, ONLY, OPTION, OR, ORDER, OUT, OUTER_P, OVERLAPS,
- PARTIAL, PATH_P, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
- READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
- SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING,
- TABLE, TEMPORARY, THEN, TIME, TIMESTAMP
- TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
- UNENCRYPTED, UNION, UNIQUE, UNKNOWN, UPDATE, USAGE, USER, USING,
- VALUES, VARCHAR, VARYING, VIEW,
- WHEN, WHERE, WITH, WITHOUT, WORK, YEAR_P, ZONE
-
-/* Keywords (in SQL3 reserved words) */
-%token DEFERRABLE, DEFERRED,
- IMMEDIATE, INITIALLY,
- PENDANT,
- REPLACE, RESTRICT,
- 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, ANALYSE, ANALYZE,
- BACKWARD, BEFORE, BINARY, BIT, CACHE, CHECKPOINT, CLUSTER,
- COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE, DATABASE,
- DELIMITERS, DO, EACH, ENCODING, EXCLUSIVE, EXPLAIN,
- FORCE, FORWARD, FREEZE, 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, OWNER, PASSWORD, PROCEDURAL, REINDEX, RENAME, RESET,
- RETURNS, ROW, RULE, SEQUENCE, SETOF, SHARE,
- SHOW, START, STATEMENT, STATISTICS, STDIN, STDOUT, STORAGE,
- SYSID, TEMP,
- TEMPLATE, TOAST, TRUNCATE, TRUSTED, UNLISTEN, UNTIL, VACUUM,
- VALID, VERBOSE, VERSION
+%token TYPECAST
+
+/* ordinary key words in alphabetical order */
+%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
+ AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
+ ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
+
+ BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
+ BOOLEAN_P BOTH BY
+
+ CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
+ CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
+ CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
+ COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
+ CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
+ CREATEROLE CREATEUSER CROSS CSV CTYPE CURRENT_P CURRENT_DATE CURRENT_ROLE
+ CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
+
+ DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
+ DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DESC
+ DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
+
+ EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EXCEPT EXCLUSIVE EXCLUDING
+ EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
+
+ FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM
+ FULL FUNCTION
+
+ GLOBAL GRANT GRANTED GREATEST GROUP_P
+
+ HANDLER HAVING HEADER_P HOLD HOUR_P
+
+ IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P
+ INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY
+ INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
+ INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
+
+ JOIN
+
+ KEY
+
+ LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
+ LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
+ LOCK_P LOGIN_P
+
+ MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
+
+ NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
+ NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
+ NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC
+
+ OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER
+ OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER
+
+ PARSER PARTIAL PASSWORD PLACING PLANS POSITION
+ PRECISION PRESERVE PREPARE PREPARED PRIMARY
+ PRIOR PRIVILEGES PROCEDURAL PROCEDURE
+
+ QUOTE
+
+ READ REAL REASSIGN RECHECK RECURSIVE REFERENCES REINDEX RELATIVE_P RELEASE RENAME
+ REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
+ RIGHT ROLE ROLLBACK ROW ROWS RULE
+
+ SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
+ SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
+ SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
+ STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
+ SYMMETRIC SYSID SYSTEM_P
+
+ TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP TO
+ TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P
+
+ UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
+ UPDATE USER USING
+
+ VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING
+ VERBOSE VERSION_P VIEW VOLATILE
+ WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE
+
+ XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
+ XMLPI XMLROOT XMLSERIALIZE
+
+ YEAR_P YES_P
+
+ ZONE
/* The grammar thinks these are keywords, but they are not in the keywords.c
* list and so can never be entered directly. The filter in parser.c
* creates these tokens when required.
*/
-%token UNIONJOIN
-
-/* Special keywords, not in the query language - see the "lex" file */
-%token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE IP BITCONST
-%token <ival> ICONST PARAM
-%token <dval> FCONST
+%token NULLS_FIRST NULLS_LAST WITH_CASCADED WITH_LOCAL WITH_CHECK
-/* these are not real. they are here so that they get generated as #define's*/
-%token OP
+/* Special token types, not actually keywords - see the "lex" file */
+%token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE IP BCONST
+%token <str> XCONST DOLCONST ECONST NCONST
+%token <ival> ICONST PARAM
+%token <dval> FCONST
/* precedence: lowest to highest */
+%nonassoc SET /* see relation_expr_opt_alias */
%left UNION EXCEPT
%left INTERSECT
-%left JOIN UNIONJOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
%left OR
%left AND
%right NOT
%right '='
%nonassoc '<' '>'
-%nonassoc LIKE ILIKE
+%nonassoc LIKE ILIKE SIMILAR
%nonassoc ESCAPE
%nonassoc OVERLAPS
%nonassoc BETWEEN
-%nonassoc IN
-%left POSTFIXOP /* dummy for postfix Op rules */
-%left Op /* multi-character ops and user-defined operators */
+%nonassoc IN_P
+%left POSTFIXOP /* dummy for postfix Op rules */
+%nonassoc IDENT /* to support target_el without AS */
+%left Op OPERATOR /* multi-character ops and user-defined operators */
%nonassoc NOTNULL
%nonassoc ISNULL
%nonassoc IS NULL_P TRUE_P FALSE_P UNKNOWN
%left '*' '/' '%'
%left '^'
/* Unary Operators */
-%left AT ZONE
+%left AT ZONE
%right UMINUS
-%left '.'
%left '[' ']'
%left '(' ')'
%left TYPECAST
+%left '.'
+%left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
+/* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */
+%right PRESERVE STRIP_P
-%type <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId
+%type <str> Iconst Fconst Sconst TransactionStmt CreateStmt RoleId
%type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt
-%type <str> key_reference comment_text ConstraintDeferrabilitySpec
-%type <str> key_match ColLabel SpecialRuleRelation ColId columnDef
-%type <str> ColConstraint ColConstraintElem drop_type Bitconst
-%type <str> OptTableElementList OptTableElement TableConstraint
-%type <str> ConstraintElem key_actions ColQualList type_name DropSchemaStmt
-%type <str> target_list target_el update_target_list alias_clause
-%type <str> update_target_el opt_id relation_name database_name
-%type <str> access_method attr_name class index_name name func_name
-%type <str> file_name AexprConst ParamNo c_expr ConstTypename
-%type <str> in_expr_nodes a_expr b_expr TruncateStmt CommentStmt
-%type <str> opt_indirection expr_list extract_list extract_arg
+%type <str> comment_text ConstraintDeferrabilitySpec TableElementList
+%type <str> key_match ColLabel SpecialRuleRelation ColId columnDef
+%type <str> ColConstraint ColConstraintElem drop_type Bconst Iresult
+%type <str> TableConstraint OptTableElementList Xconst opt_transaction
+%type <str> ConstraintElem key_actions ColQualList cluster_index_specification
+%type <str> target_list target_el alias_clause type_func_name_keyword
+%type <str> qualified_name database_name alter_using type_function_name
+%type <str> access_method attr_name index_name name func_name opt_restart_seqs
+%type <str> file_name AexprConst c_expr ConstTypename var_list
+%type <str> a_expr b_expr TruncateStmt CommentStmt OnCommitOption opt_by
+%type <str> opt_indirection expr_list extract_list extract_arg OptSeqOptList
%type <str> position_list substr_list substr_from alter_column_default
-%type <str> trim_list in_expr substr_for attr attrs drop_behavior
-%type <str> Typename SimpleTypename Generic Numeric opt_float opt_numeric
-%type <str> opt_decimal Character character opt_varying opt_charset
-%type <str> opt_collate opt_timezone opt_interval table_ref
-%type <str> row_expr row_descriptor row_list ConstDatetime opt_chain
+%type <str> trim_list in_expr substr_for attrs TableFuncElement
+%type <str> Typename SimpleTypename Numeric opt_float DiscardStmt
+%type <str> Character character opt_varying opt_charset enum_val_list
+%type <str> opt_timezone opt_interval table_ref fetch_direction
+%type <str> ConstDatetime AlterDomainStmt AlterSeqStmt table_func_column
%type <str> SelectStmt into_clause OptTemp ConstraintAttributeSpec
-%type <str> opt_table opt_all sort_clause sortby_list ConstraintAttr
-%type <str> sortby OptUseOp relation_name_list name_list ColId_or_Sconst
-%type <str> group_clause having_clause from_clause opt_distinct
-%type <str> join_outer where_clause relation_expr sub_type opt_arg
-%type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
-%type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
-%type <str> NotifyStmt columnElem copy_dirn UnlistenStmt copy_null
-%type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
-%type <str> opt_with_copy FetchStmt direction fetch_how_many from_in
-%type <str> ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
-%type <str> opt_full func_arg OptWithOids opt_freeze opt_ecpg_into
-%type <str> analyze_keyword opt_name_list ExplainStmt index_params
-%type <str> index_list func_index index_elem opt_class access_method_clause
-%type <str> index_opt_unique IndexStmt func_return ConstInterval
-%type <str> func_args_list func_args opt_with ProcedureStmt def_arg
-%type <str> def_elem def_list definition DefineStmt select_with_parens
-%type <str> opt_instead event event_object RuleActionList opt_using
+%type <str> opt_table opt_all sort_clause sortby_list ConstraintAttr
+%type <str> sortby qualified_name_list name_list ColId_or_Sconst
+%type <str> group_clause having_clause from_clause opt_distinct opt_hold
+%type <str> join_outer where_clause relation_expr sub_type arg_class
+%type <str> opt_column_list insert_rest InsertStmt param_name
+%type <str> columnList DeleteStmt UpdateStmt DeclareCursorStmt
+%type <str> NotifyStmt columnElem UnlistenStmt TableElement fetch_count
+%type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
+%type <str> FetchStmt from_in CreateOpClassStmt returning_clause
+%type <str> ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
+%type <str> opt_full func_arg OptWith opt_freeze alter_table_cmd
+%type <str> analyze_keyword opt_name_list ExplainStmt index_params
+%type <str> index_elem opt_class access_method_clause alter_table_cmds
+%type <str> index_opt_unique IndexStmt func_return ConstInterval
+%type <str> func_args_list func_args opt_with def_arg overlay_placing
+%type <str> def_elem def_list definition DefineStmt select_with_parens
+%type <str> opt_instead event RuleActionList opt_using CreateAssertStmt
%type <str> RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type
-%type <str> RuleStmt opt_column opt_name oper_argtypes NumConst
-%type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
-%type <str> RemoveAggrStmt opt_procedural select_no_parens
-%type <str> RemoveOperStmt RenameStmt all_Op opt_Trusted opt_lancompiler
-%type <str> VariableSetStmt var_value zone_value VariableShowStmt
-%type <str> VariableResetStmt AlterTableStmt DropUserStmt from_list
-%type <str> opt_trans user_list OptUserList OptUserElem
-%type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
-%type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
+%type <str> RuleStmt opt_column oper_argtypes NumConst var_name
+%type <str> MathOp RemoveFuncStmt ECPGunreserved_con opt_database_name
+%type <str> RemoveAggrStmt opt_procedural select_no_parens CreateCastStmt
+%type <str> RemoveOperStmt RenameStmt all_Op opt_trusted opt_lancompiler
+%type <str> VariableSetStmt var_value zone_value VariableShowStmt
+%type <str> VariableResetStmt AlterTableStmt from_list overlay_list
+%type <str> relation_name OptTableSpace LockStmt opt_lock table_func_column_list
+%type <str> CreateUserStmt AlterUserStmt CreateSeqStmt SeqOptList
+%type <str> SeqOptElem TriggerForSpec TriggerForOpt TriggerForType
%type <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
-%type <str> TriggerActionTime CreateTrigStmt DropPLangStmt
-%type <str> CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
-%type <str> ViewStmt LoadStmt CreatedbStmt createdb_opt_item
+%type <str> TriggerActionTime CreateTrigStmt DropPLangStmt DropCastStmt
+%type <str> CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
+%type <str> ViewStmt LoadStmt CreatedbStmt createdb_opt_item ExplainableStmt
%type <str> createdb_opt_list opt_encoding OptInherit opt_equal
-%type <str> AlterUserSetStmt privilege_list privilege privilege_target
-%type <str> opt_grant_grant_option opt_revoke_grant_option
-%type <str> function_with_argtypes_list function_with_argtypes
-%type <str> DropdbStmt ClusterStmt grantee RevokeStmt Bit bit
-%type <str> GrantStmt privileges PosAllConst
-%type <str> opt_cursor ConstraintsSetStmt AllConst
+%type <str> privilege_list privilege privilege_target opt_if_exists
+%type <str> opt_grant_grant_option cursor_options DropOwnedStmt
+%type <str> transaction_mode_list_or_empty transaction_mode_list
+%type <str> function_with_argtypes_list function_with_argtypes IntConstVar
+%type <str> DropdbStmt ClusterStmt grantee RevokeStmt Bit DropOpClassStmt
+%type <str> GrantStmt privileges PosAllConst constraints_set_list
+%type <str> ConstraintsSetStmt AllConst CreateDomainStmt opt_nowait
%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> ConstraintTimeSpec AlterDatabaseSetStmt
-%type <str> select_offset_value ReindexStmt join_type opt_boolean
-%type <str> join_qual update_list AlterSchemaStmt joined_table
-%type <str> opt_level opt_lock lock_type OptGroupList OptGroupElem
-%type <str> OptConstrFromTable OptTempTableName StringConst
-%type <str> constraints_set_list constraints_set_namelist
-%type <str> constraints_set_mode comment_type opt_empty_parentheses
+%type <str> select_clause opt_select_limit select_limit_value opt_recheck
+%type <str> ConstraintTimeSpec AlterDatabaseSetStmt DropAssertStmt
+%type <str> select_offset_value ReindexStmt join_type opt_boolean
+%type <str> join_qual joined_table opclass_item relation_expr_opt_alias
+%type <str> lock_type array_expr_list ReassignOwnedStmt for_locking_item
+%type <str> OptConstrFromTable OptTempTableName StringConst array_expr
+%type <str> constraints_set_mode comment_type opt_check_option
%type <str> CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
%type <str> opt_force key_update CreateSchemaStmt PosIntStringConst
-%type <str> IntConst PosIntConst grantee_list func_type opt_or_replace
-%type <str> select_limit opt_for_update_clause CheckPointStmt
-
+%type <str> IntConst PosIntConst grantee_list func_type opt_or_replace
+%type <str> select_limit CheckPointStmt ECPGColId old_aggr_list
+%type <str> OptSchemaName OptSchemaEltList schema_stmt opt_drop_behavior
+%type <str> handler_name any_name_list any_name opt_as insert_column_list
+%type <str> columnref values_clause AllConstVar prep_type_clause ExecuteStmt
+%type <str> insert_column_item DropRuleStmt ctext_expr execute_param_clause
+%type <str> createfunc_opt_item set_rest
+%type <str> CreateFunctionStmt createfunc_opt_list func_table
+%type <str> DropUserStmt copy_from copy_opt_list copy_opt_item
+%type <str> opt_oids TableLikeClause key_action opt_definition
+%type <str> cast_context row qual_Op qual_all_Op opt_default
+%type <str> CreateConversionStmt any_operator opclass_item_list
+%type <str> iso_level type_list CharacterWithLength ConstCharacter
+%type <str> CharacterWithoutLength BitWithLength BitWithoutLength
+%type <str> ConstBit GenericType TableFuncElementList opt_analyze
+%type <str> opt_sort_clause subquery_Op transaction_mode_item
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen
-%type <str> indicator ECPGExecute ECPGPrepare ecpg_using ecpg_into
-%type <str> storage_clause opt_initializer c_anything blockstart
-%type <str> blockend variable_list variable c_thing c_term
+%type <str> indicator ecpg_using ecpg_into DeallocateStmt
+%type <str> storage_declaration storage_clause opt_initializer c_anything
+%type <str> variable_list variable c_thing c_term ECPGKeywords_vanames
%type <str> opt_pointer ECPGDisconnect dis_name storage_modifier
-%type <str> stmt ECPGRelease execstring server_name
+%type <str> execstring server_name ECPGVarDeclaration func_expr
%type <str> connection_object opt_server opt_port c_stuff c_stuff_item
-%type <str> user_name opt_user char_variable ora_user ident opt_reference
-%type <str> quoted_ident_stringvar
-%type <str> db_prefix server opt_options opt_connection_name c_list
-%type <str> ECPGSetConnection cpp_line ECPGTypedef c_args ECPGKeywords
-%type <str> enum_type civar civarind ECPGCursorStmt ECPGDeallocate
-%type <str> ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
-%type <str> struct_type s_struct declaration declarations variable_declarations
-%type <str> s_union union_type ECPGSetAutocommit on_off
-%type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol
-%type <str> ECPGGetDescriptorHeader ECPGColLabel
-%type <str> reserved_keyword unreserved_keyword
-%type <str> col_name_keyword func_name_keyword
-%type <str> ECPGTypeName variablelist cvariable
-
-%type <descriptor> ECPGGetDescriptor
+%type <str> user_name opt_user char_variable ora_user ident opt_reference
+%type <str> var_type_declarations quoted_ident_stringvar ECPGKeywords_rest
+%type <str> db_prefix server connect_options opt_options opt_connection_name c_list
+%type <str> ECPGSetConnection ECPGTypedef c_args ECPGKeywords ECPGCKeywords
+%type <str> enum_type civar civarind ECPGCursorStmt PreparableStmt
+%type <str> ECPGFree ECPGDeclare ECPGVar at enum_definition opt_opt_value
+%type <str> struct_union_type s_struct_union vt_declarations execute_rest
+%type <str> var_declaration type_declaration single_vt_declaration
+%type <str> ECPGSetAutocommit on_off variable_declarations ECPGDescribe
+%type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol opt_output
+%type <str> ECPGGetDescriptorHeader ECPGColLabel SetResetClause AlterUserSetStmt
+%type <str> reserved_keyword unreserved_keyword ecpg_interval opt_ecpg_using
+%type <str> col_name_keyword precision opt_scale ECPGExecuteImmediateStmt
+%type <str> ECPGTypeName using_list ECPGColLabelCommon UsingConst
+%type <str> using_descriptor into_descriptor opt_nulls_order opt_asc_desc
+%type <str> prepared_name struct_union_type_with_symbol OptConsTableSpace
+%type <str> ECPGunreserved ECPGunreserved_interval cvariable opt_bit_field
+%type <str> AlterOwnerStmt OptTableSpaceOwner CreateTableSpaceStmt
+%type <str> DropTableSpaceStmt indirection indirection_el ECPGSetDescriptorHeader
+%type <str> AlterDatabaseStmt CreateRoleStmt OptRoleList AlterRoleStmt AlterRoleSetStmt
+%type <str> DropRoleStmt add_drop opt_validator common_func_opt_item
+%type <str> opt_grant_admin_option AlterFunctionStmt alterfunc_opt_list opt_restrict
+%type <str> AlterObjectSchemaStmt alterdb_opt_list for_locking_clause opt_for_locking_clause
+%type <str> locked_rels_list opt_granted_by RevokeRoleStmt alterdb_opt_item using_clause
+%type <str> GrantRoleStmt opt_asymmetric aggr_args old_aggr_definition
+%type <str> old_aggr_elem for_locking_items TableLikeOptionList TableLikeOption
+%type <str> set_target_list set_clause_list set_clause multiple_set_clause
+%type <str> ctext_expr_list ctext_row single_set_clause set_target opt_type_modifiers
+%type <str> opclass_drop_list opclass_drop DropOpFamilyStmt opt_opfamily
+%type <str> CreateOpFamilyStmt AlterOpFamilyStmt create_as_target
+%type <str> xml_attributes xml_attribute_list document_or_content xml_whitespace_option
+%type <str> opt_xml_root_standalone xml_root_version xml_attribute_el
+%type <str> where_or_current_clause AlterTSConfigurationStmt AlterTSDictionaryStmt
+
+%type <struct_union> s_struct_union_symbol
+
+%type <descriptor> ECPGGetDescriptor ECPGSetDescriptor
%type <type_enum> simple_type signed_type unsigned_type
%type <dtype_enum> descriptor_item desc_header_item
-%type <type> type
+%type <type> var_type
-%type <action> action
+%type <prep> PrepareStmt
-%type <index> opt_array_bounds opt_type_array_bounds
+%type <action> action
-%type <ival> Iresult
+%type <index> opt_array_bounds
-%token YYERROR_VERBOSE
%%
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: AT connection_target {
- connection = $2;
- /*
- if we have a variable as connection
- target, remove it from the variable
- list or else it will be used twice
- */
- if (argsinsert != NULL)
- argsinsert = NULL;
- };
-
-stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
- | AlterGroupStmt { output_statement($1, 0, connection); }
- | AlterSchemaStmt { output_statement($1, 0, connection); }
- | AlterTableStmt { output_statement($1, 0, connection); }
- | AlterUserStmt { output_statement($1, 0, connection); }
- | AlterUserSetStmt { output_statement($1, 0, connection); }
- | ClosePortalStmt { output_statement($1, 0, connection); }
- | CommentStmt { output_statement($1, 0, connection); }
- | CopyStmt { output_statement($1, 0, connection); }
- | CreateStmt { output_statement($1, 0, connection); }
- | CreateAsStmt { output_statement($1, 0, connection); }
- | CreateSchemaStmt { output_statement($1, 0, connection); }
- | CreateGroupStmt { output_statement($1, 0, connection); }
- | CreateSeqStmt { output_statement($1, 0, connection); }
- | CreatePLangStmt { output_statement($1, 0, connection); }
- | CreateTrigStmt { output_statement($1, 0, connection); }
- | CreateUserStmt { output_statement($1, 0, connection); }
- | ClusterStmt { output_statement($1, 0, connection); }
- | DefineStmt { output_statement($1, 0, connection); }
- | DropStmt { output_statement($1, 0, connection); }
- | DropSchemaStmt { output_statement($1, 0, connection); }
- | TruncateStmt { output_statement($1, 0, connection); }
- | DropGroupStmt { output_statement($1, 0, connection); }
- | DropPLangStmt { output_statement($1, 0, connection); }
- | DropTrigStmt { output_statement($1, 0, connection); }
- | DropUserStmt { output_statement($1, 0, connection); }
- | ExplainStmt { output_statement($1, 0, connection); }
- | FetchStmt { output_statement($1, 1, connection); }
- | GrantStmt { output_statement($1, 0, connection); }
- | IndexStmt { output_statement($1, 0, connection); }
- | ListenStmt { output_statement($1, 0, connection); }
- | UnlistenStmt { output_statement($1, 0, connection); }
- | LockStmt { output_statement($1, 0, connection); }
- | NotifyStmt { output_statement($1, 0, connection); }
- | ProcedureStmt { output_statement($1, 0, connection); }
- | ReindexStmt { output_statement($1, 0, connection); }
- | RemoveAggrStmt { output_statement($1, 0, connection); }
- | RemoveOperStmt { output_statement($1, 0, connection); }
- | RemoveFuncStmt { output_statement($1, 0, connection); }
- | RenameStmt { output_statement($1, 0, connection); }
- | RevokeStmt { output_statement($1, 0, connection); }
- | OptimizableStmt {
- if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
- output_simple_statement($1);
- else
- output_statement($1, 1, connection);
- }
- | RuleStmt { output_statement($1, 0, connection); }
- | TransactionStmt {
- fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
- whenever_action(2);
- free($1);
- }
- | ViewStmt { output_statement($1, 0, connection); }
- | LoadStmt { output_statement($1, 0, connection); }
- | CreatedbStmt { output_statement($1, 0, connection); }
- | DropdbStmt { output_statement($1, 0, connection); }
- | VacuumStmt { output_statement($1, 0, connection); }
- | AnalyzeStmt { output_statement($1, 0, connection); }
- | VariableSetStmt { output_statement($1, 0, connection); }
- | VariableShowStmt { output_statement($1, 0, connection); }
- | VariableResetStmt { output_statement($1, 0, connection); }
- | ConstraintsSetStmt { output_statement($1, 0, connection); }
- | CheckPointStmt { output_statement($1, 0, connection); }
- | ECPGAllocateDescr { fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
- whenever_action(0);
- free($1);
- }
- | ECPGConnect {
- if (connection)
- mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement.\n");
-
- fprintf(yyout, "{ ECPGconnect(__LINE__, %s, %d); ", $1, autocommit);
-
- reset_variables();
-
- whenever_action(2);
- free($1);
- }
- | ECPGCursorStmt {
- output_simple_statement($1);
- }
- | ECPGDeallocate {
- if (connection)
- mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement.\n");
+statements: /*EMPTY*/
+ | statements statement
+ ;
- fputc('{', yyout);
- fputs($1, yyout);
- whenever_action(2);
- free($1);
- }
- | ECPGDeallocateDescr { fprintf(yyout,"ECPGdeallocate_desc(__LINE__, %s);",$1);
- whenever_action(0);
- free($1);
- }
- | ECPGDeclare {
- output_simple_statement($1);
- }
- | ECPGDisconnect {
- if (connection)
- mmerror(PARSE_ERROR, ET_ERROR, "no at option for disconnect statement.\n");
+statement: ecpgstart at stmt ';' { connection = NULL; }
+ | ecpgstart stmt ';'
+ | ecpgstart ECPGVarDeclaration
+ {
+ fprintf(yyout, "%s", $2);
+ free($2);
+ output_line_number();
+ }
+ | ECPGDeclaration
+ | c_thing { fprintf(yyout, "%s", $1); free($1); }
+ | CPP_LINE { fprintf(yyout, "%s", $1); free($1); }
+ | '{' { braces_open++; fputs("{", yyout); }
+ | '}' { remove_typedefs(braces_open); remove_variables(braces_open--); fputs("}", yyout); }
+ ;
- fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);", $1);
- whenever_action(2);
- free($1);
- }
- | ECPGExecute { output_statement($1, 0, connection); }
- | ECPGFree {
- fprintf(yyout, "{ ECPGdeallocate(__LINE__, \"%s\");", $1);
+at: AT connection_object
+ {
+ connection = $2;
+ /*
+ * Do we have a variable as connection target?
+ * Remove the variable from the variable
+ * list or else it will be used twice
+ */
+ if (argsinsert != NULL)
+ argsinsert = NULL;
+ }
+ ;
- whenever_action(2);
- free($1);
- }
- | ECPGGetDescriptor {
- lookup_descriptor($1.name, connection);
- output_get_descr($1.name, $1.str);
- free($1.name);
- free($1.str);
- }
- | ECPGGetDescriptorHeader {
- lookup_descriptor($1, connection);
- output_get_descr_header($1);
- free($1);
- }
- | ECPGOpen {
- struct cursor *ptr;
- struct arguments *p;
-
- for (ptr = cur; ptr != NULL; ptr=ptr->next)
- {
- if (strcmp(ptr->name, $1) == 0)
- break;
- }
-
- if (ptr == NULL)
+stmt: AlterDatabaseStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterDatabaseSetStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterDomainStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterFunctionStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterGroupStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterObjectSchemaStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterOwnerStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterSeqStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterTableStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterRoleSetStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterRoleStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterTSConfigurationStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterTSDictionaryStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterUserStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterUserSetStmt { output_statement($1, 0, ECPGst_normal); }
+ | AnalyzeStmt { output_statement($1, 0, ECPGst_normal); }
+ | CheckPointStmt { output_statement($1, 0, ECPGst_normal); }
+ | ClosePortalStmt
+ {
+ if (INFORMIX_MODE)
+ {
+ /*
+ * Informix also has a CLOSE DATABASE command that
+ * essantially works like a DISCONNECT CURRENT
+ * as far as I know.
+ */
+ if (pg_strcasecmp($1+strlen("close "), "database") == 0)
+ {
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for close database statement\n");
+
+ fprintf(yyout, "{ ECPGdisconnect(__LINE__, \"CURRENT\");");
+ whenever_action(2);
+ free($1);
+ }
+ else
+ output_statement($1, 0, ECPGst_normal);
+ }
+ else
+ output_statement($1, 0, ECPGst_normal);
+ }
+ | ClusterStmt { output_statement($1, 0, ECPGst_normal); }
+ | CommentStmt { output_statement($1, 0, ECPGst_normal); }
+ | ConstraintsSetStmt { output_statement($1, 0, ECPGst_normal); }
+ | CopyStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateAsStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateAssertStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateCastStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateConversionStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateDomainStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateFunctionStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateGroupStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreatePLangStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateOpClassStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateOpFamilyStmt { output_statement($1, 0, ECPGst_normal); }
+ | AlterOpFamilyStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateRoleStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateSchemaStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateSeqStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateTableSpaceStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateTrigStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreateUserStmt { output_statement($1, 0, ECPGst_normal); }
+ | CreatedbStmt { output_statement($1, 0, ECPGst_normal); }
+ | DeallocateStmt
+ {
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for deallocate statement\n");
+
+ output_deallocate_prepare_statement($1);
+ }
+ | DeclareCursorStmt { output_simple_statement($1); }
+ | DefineStmt { output_statement($1, 0, ECPGst_normal); }
+ | DeleteStmt { output_statement($1, 1, ECPGst_normal); }
+ | DiscardStmt { output_statement($1, 1, ECPGst_normal); }
+ | DropAssertStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropCastStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropGroupStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropOpClassStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropOpFamilyStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropOwnedStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropPLangStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropRoleStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropRuleStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropTableSpaceStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropTrigStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropUserStmt { output_statement($1, 0, ECPGst_normal); }
+ | DropdbStmt { output_statement($1, 0, ECPGst_normal); }
+ | ExplainStmt { output_statement($1, 0, ECPGst_normal); }
+ | ExecuteStmt { output_statement($1, 1, ECPGst_execute); }
+ | FetchStmt { output_statement($1, 1, ECPGst_normal); }
+ | GrantStmt { output_statement($1, 0, ECPGst_normal); }
+ | GrantRoleStmt { output_statement($1, 0, ECPGst_normal); }
+ | IndexStmt { output_statement($1, 0, ECPGst_normal); }
+ | InsertStmt { output_statement($1, 1, ECPGst_normal); }
+ | ListenStmt { output_statement($1, 0, ECPGst_normal); }
+ | LoadStmt { output_statement($1, 0, ECPGst_normal); }
+ | LockStmt { output_statement($1, 0, ECPGst_normal); }
+ | NotifyStmt { output_statement($1, 0, ECPGst_normal); }
+ | PrepareStmt {
+ if ($1.type == NULL || strlen($1.type) == 0) /* use PQprepare without type parameters */
+ output_prepare_statement($1.name, $1.stmt);
+ else /* use PQexec and let backend do its stuff */
{
- sprintf(errortext, "trying to open undeclared cursor %s\n", $1);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
+ char *txt = cat_str(5, make_str("prepare"), $1.name, $1.type, make_str("as"), $1.stmt);
+ output_statement(txt, 0, ECPGst_normal);
}
+ }
+ | ReassignOwnedStmt { output_statement($1, 0, ECPGst_normal); }
+ | ReindexStmt { output_statement($1, 0, ECPGst_normal); }
+ | RemoveAggrStmt { output_statement($1, 0, ECPGst_normal); }
+ | RemoveOperStmt { output_statement($1, 0, ECPGst_normal); }
+ | RemoveFuncStmt { output_statement($1, 0, ECPGst_normal); }
+ | RenameStmt { output_statement($1, 0, ECPGst_normal); }
+ | RevokeStmt { output_statement($1, 0, ECPGst_normal); }
+ | RevokeRoleStmt { output_statement($1, 0, ECPGst_normal); }
+ | RuleStmt { output_statement($1, 0, ECPGst_normal); }
+ | SelectStmt { output_statement($1, 1, ECPGst_normal); }
+ | TransactionStmt
+ {
+ fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
+ whenever_action(2);
+ free($1);
+ }
+ | TruncateStmt { output_statement($1, 0, ECPGst_normal); }
+ | UnlistenStmt { output_statement($1, 0, ECPGst_normal); }
+ | UpdateStmt { output_statement($1, 1, ECPGst_normal); }
+ | VacuumStmt { output_statement($1, 0, ECPGst_normal); }
+ | VariableSetStmt { output_statement($1, 0, ECPGst_normal); }
+ | VariableShowStmt { output_statement($1, 0, ECPGst_normal); }
+ | VariableResetStmt { output_statement($1, 0, ECPGst_normal); }
+ | ViewStmt { output_statement($1, 0, ECPGst_normal); }
+ | ECPGAllocateDescr
+ {
+ fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
+ whenever_action(0);
+ free($1);
+ }
+ | ECPGConnect
+ {
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement\n");
- /* merge variables given in prepare statement with those given here */
- for (p = ptr->argsinsert; p; p = p->next)
- append_variable(&argsinsert, p->variable, p->indicator);
+ fprintf(yyout, "{ ECPGconnect(__LINE__, %d, %s, %d); ", compat, $1, autocommit);
+ reset_variables();
+ whenever_action(2);
+ free($1);
+ }
+ | ECPGCursorStmt
+ {
+ output_simple_statement($1);
+ }
+ | ECPGDeallocateDescr
+ {
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for deallocate statement\n");
+ fprintf(yyout,"ECPGdeallocate_desc(__LINE__, %s);",$1);
+ whenever_action(0);
+ free($1);
+ }
+ | ECPGDeclare
+ {
+ output_simple_statement($1);
+ }
+ | ECPGDescribe
+ {
+ fprintf(yyout, "{ ECPGdescribe(__LINE__, %s,", $1);
+ dump_variables(argsresult, 1);
+ fputs("ECPGt_EORT);", yyout);
+ fprintf(yyout, "}");
+ output_line_number();
+
+ /* whenever_action(2); */
+ free($1);
+ }
+ | ECPGDisconnect
+ {
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for disconnect statement\n");
- for (p = ptr->argsresult; p; p = p->next)
- add_variable(&argsresult, p->variable, p->indicator);
+ fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);",
+ $1 ? $1 : "\"CURRENT\"");
+ whenever_action(2);
+ free($1);
+ }
+ | ECPGExecuteImmediateStmt { output_statement($1, 0, ECPGst_exec_immediate); }
+ | ECPGFree
+ {
+ const char *con = connection ? connection : "NULL";
+ if (strcmp($1, "all"))
+ fprintf(yyout, "{ ECPGdeallocate(__LINE__, %d, %s, \"%s\");", compat, con, $1);
+ else
+ fprintf(yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
- output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL);
- }
- | ECPGPrepare {
- if (connection)
- mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement.\n");
+ whenever_action(2);
+ free($1);
+ }
+ | ECPGGetDescriptor
+ {
+ lookup_descriptor($1.name, connection);
+ output_get_descr($1.name, $1.str);
+ free($1.name);
+ free($1.str);
+ }
+ | ECPGGetDescriptorHeader
+ {
+ lookup_descriptor($1, connection);
+ output_get_descr_header($1);
+ free($1);
+ }
+ | ECPGOpen
+ {
+ struct cursor *ptr;
- 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)
- mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement.\n");
+ if ((ptr = add_additional_variables($1, true)) != NULL)
+ {
+ connection = ptr->connection ? mm_strdup(ptr->connection) : NULL;
+ output_statement(mm_strdup(ptr->command), 0, 0);
+ ptr->opened = true;
+ }
+ }
+ | ECPGSetAutocommit
+ {
+ fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
+ whenever_action(2);
+ free($1);
+ }
+ | ECPGSetConnection
+ {
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement\n");
- fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
- whenever_action(2);
- free($1);
- }
- | ECPGTypedef {
- if (connection)
- mmerror(PARSE_ERROR, ET_ERROR, "no at option for typedef statement.\n");
+ fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
+ whenever_action(2);
+ free($1);
+ }
+ | ECPGSetDescriptor
+ {
+ lookup_descriptor($1.name, connection);
+ output_set_descr($1.name, $1.str);
+ free($1.name);
+ free($1.str);
+ }
+ | ECPGSetDescriptorHeader
+ {
+ lookup_descriptor($1, connection);
+ output_set_descr_header($1);
+ free($1);
+ }
+ | ECPGTypedef
+ {
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for typedef statement\n");
- output_simple_statement($1);
- }
- | ECPGVar {
- if (connection)
- mmerror(PARSE_ERROR, ET_ERROR, "no at option for var statement.\n");
+ fprintf(yyout, "%s", $1);
+ free($1);
+ output_line_number();
+ }
+ | ECPGVar
+ {
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for var statement\n");
- output_simple_statement($1);
- }
- | ECPGWhenever {
- if (connection)
- mmerror(PARSE_ERROR, ET_ERROR, "no at option for whenever statement.\n");
+ output_simple_statement($1);
+ }
+ | ECPGWhenever
+ {
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for whenever statement\n");
- output_simple_statement($1);
- }
+ output_simple_statement($1);
+ }
;
/*****************************************************************************
*
- * Create a new Postgres DBMS user
+ * Create a new Postgres DBMS role
*
*
*****************************************************************************/
-CreateUserStmt: CREATE USER UserId OptUserList
- {
- $$ = cat_str(3, make_str("create user"), $3, $4);
- }
- | CREATE USER UserId WITH OptUserList
- {
- $$ = cat_str(4, make_str("create user"), $3, make_str("with"), $5);
- }
+CreateRoleStmt: CREATE ROLE RoleId opt_with OptRoleList
+ { $$ = cat_str(4, make_str("create role"), $3, make_str("with"), $5); }
+ ;
+
+opt_with: WITH { $$ = make_str("with"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
+/*
+ * Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER
+ * for backwards compatibility). Note: the only option required by SQL99
+ * is "WITH ADMIN name".
+ */
+OptRoleList:
+ PASSWORD Sconst { $$ = cat2_str(make_str("password"), $2); }
+ | PASSWORD NULL_P { $$ = make_str("password null"); }
+ | ENCRYPTED PASSWORD Sconst { $$ = cat2_str(make_str("encrypted password"), $3); }
+ | UNENCRYPTED PASSWORD Sconst { $$ = cat2_str(make_str("unencrypted password"), $3); }
+ | SUPERUSER_P { $$ = make_str("superuser"); }
+ | NOSUPERUSER { $$ = make_str("nosuperuser"); }
+ | INHERIT { $$ = make_str("inherit"); }
+ | NOINHERIT { $$ = make_str("noinherit"); }
+ | CREATEDB { $$ = make_str("createdb"); }
+ | NOCREATEDB { $$ = make_str("nocreatedb"); }
+ | CREATEROLE { $$ = make_str("createrole"); }
+ | NOCREATEROLE { $$ = make_str("nocreaterole"); }
+ | LOGIN_P { $$ = make_str("login"); }
+ | NOLOGIN_P { $$ = make_str("nologin"); }
+ | CONNECTION LIMIT IntConst { $$ = cat2_str(make_str("connection limit"), $3); }
+ | VALID UNTIL Sconst { $$ = cat2_str(make_str("valid until"), $3); }
+ | USER name_list { $$ = cat2_str(make_str("user"), $2); }
+ | SYSID PosIntConst { $$ = cat2_str(make_str("sysid"), $2); }
+ | ADMIN name_list { $$ = cat2_str(make_str("admin"), $2); }
+ | ROLE name_list { $$ = cat2_str(make_str("role"), $2); }
+ | IN_P ROLE name_list { $$ = cat2_str(make_str("in role"), $3); }
+ | IN_P GROUP_P name_list { $$ = cat2_str(make_str("in group"), $3); }
+ ;
+
/*****************************************************************************
*
- * Alter a postgresql DBMS user
- *
+ * Create a new Postgres DBMS user (role with implied login ability)
*
*****************************************************************************/
-AlterUserStmt: ALTER USER UserId OptUserList
- {
- $$ = cat_str(3, make_str("alter user"), $3, $4);
- }
- | ALTER USER UserId WITH OptUserList
- {
- $$ = cat_str(4, make_str("alter user"), $3, make_str("with"), $5);
- }
+CreateUserStmt:
+ CREATE USER RoleId opt_with OptRoleList
+ {$$ = cat_str(4, make_str("create user"), $3, $4, $5); }
+ ;
+
+ /*****************************************************************************
+ *
+ * Alter a postgresql DBMS role
+ *
+ *
+ *****************************************************************************/
+
+ AlterRoleStmt: ALTER ROLE RoleId opt_with OptRoleList
+ { $$ = cat_str(4, make_str("alter role"), $3, $4, $5); }
;
-AlterUserSetStmt: ALTER USER UserId VariableSetStmt
- {
- $$ = cat_str(3, make_str("alter user"), $3, $4);
- }
- | ALTER USER UserId VariableResetStmt
- {
- $$ = cat_str(3, make_str("alter user"), $3, $4);
- }
+ AlterRoleSetStmt: ALTER ROLE RoleId SetResetClause
+ { $$ = cat_str(3, make_str("alter role"), $3, $4); }
;
-/*****************************************************************************
- *
- * Drop a postgresql DBMS user
- *
- *
- *****************************************************************************/
+ /*****************************************************************************
+ *
+ * Alter a postgresql DBMS user
+ *
+ *****************************************************************************/
-DropUserStmt: DROP USER user_list
- {
- $$ = cat2_str(make_str("drop user"), $3);
- }
+ AlterUserStmt: ALTER USER RoleId opt_with OptRoleList
+ { $$ = cat_str(4, make_str("alter user"), $3, $4, $5); };
+
+ AlterUserSetStmt: ALTER USER RoleId SetResetClause
+ { $$ = cat_str(3, make_str("alter user"), $3, $4); }
;
-/*
- * Options for CREATE USER and ALTER USER
- */
-OptUserList: OptUserList OptUserElem { $$ = cat2_str($1, $2); }
- | /* EMPTY */ { $$ = EMPTY; }
+ /*****************************************************************************
+ *
+ * Drop a postgresql DBMS role
+ *
+ *
+ *****************************************************************************/
+ DropRoleStmt: DROP ROLE name_list
+ { $$ = cat2_str(make_str("drop role"), $3);}
+ | DROP ROLE IF_P EXISTS name_list
+ { $$ = cat2_str(make_str("drop role if exists"), $5);}
;
-OptUserElem: PASSWORD Sconst
- {
- $$ = cat2_str(make_str("password"), $2);
- }
- | SYSID Iconst
- {
- $$ = cat2_str(make_str("sysid"), $2);
- }
- | CREATEDB
- {
- $$ = make_str("createdb");
- }
- | NOCREATEDB
- {
- $$ = make_str("nocreatedb");
- }
- | CREATEUSER
- {
- $$ = make_str("createuser");
- }
- | NOCREATEUSER
- {
- $$ = make_str("nocreateuser");
- }
- | IN GROUP user_list
- {
- $$ = cat2_str(make_str("in group"), $3);
- }
- | VALID UNTIL Sconst
- {
- $$ = cat2_str(make_str("valid until"), $3);
- }
- ;
+ /*****************************************************************************
+ *
+ * Drop a postgresql DBMS user
+ *
+ *
+ *****************************************************************************/
+ DropUserStmt: DROP USER name_list
+ { $$ = cat2_str(make_str("drop user"), $3);}
+ | DROP USER IF_P EXISTS name_list
+ { $$ = cat2_str(make_str("drop user if exists"), $5);}
-user_list: user_list ',' UserId
- {
- $$ = cat_str(3, $1, make_str(","), $3);
- }
- | UserId
- {
- $$ = $1;
- }
;
+ /*****************************************************************************
+ *
+ * Create a postgresql group
+ *
+ *
+ ****************************************************************************/
+ CreateGroupStmt: CREATE GROUP_P RoleId opt_with OptRoleList
+ { $$ = cat_str(4, make_str("create group"), $3, $4, $5); }
+ ;
-/*****************************************************************************
- *
- * Create a postgresql group
- *
- *
- ****************************************************************************/
-CreateGroupStmt: CREATE GROUP UserId OptGroupList
- {
- $$ = cat_str(3, make_str("create group"), $3, $4);
- }
- | CREATE GROUP UserId WITH OptGroupList
- {
- $$ = cat_str(4, make_str("create group"), $3, make_str("with"), $5);
- }
+ /*****************************************************************************
+ *
+ * Alter a postgresql group
+ *
+ *
+ *****************************************************************************/
+ AlterGroupStmt: ALTER GROUP_P RoleId add_drop USER name_list
+ { $$ = cat_str(5, make_str("alter group"), $3, $4, make_str("user"), $6); }
;
-/*
- * Options for CREATE GROUP
- */
-OptGroupList: OptGroupList OptGroupElem { $$ = cat2_str($1, $2); }
- | /* EMPTY */ { $$ = EMPTY; }
+ add_drop: ADD_P { $$ = make_str("add"); }
+ | DROP { $$ = make_str("drop"); }
;
-OptGroupElem: USER user_list
- {
- $$ = cat2_str(make_str("user"), $2);
- }
- | SYSID Iconst
- {
- $$ = cat2_str(make_str("sysid"), $2);
- }
- ;
-
-
-/*****************************************************************************
- *
- * Alter a postgresql group
- *
- *
- *****************************************************************************/
-AlterGroupStmt: ALTER GROUP UserId ADD USER user_list
- {
- $$ = cat_str(4, make_str("alter group"), $3, make_str("add user"), $6);
- }
- | ALTER GROUP UserId DROP USER user_list
- {
- $$ = cat_str(4, make_str("alter group"), $3, make_str("drop user"), $6);
- }
- ;
+ /*****************************************************************************
+ *
+ * Drop a postgresql group
+ *
+ *
+ *****************************************************************************/
+ DropGroupStmt: DROP GROUP_P name_list
+ { $$ = cat2_str(make_str("drop group"), $3); }
+ | DROP GROUP_P IF_P EXISTS name_list
+ { $$ = cat2_str(make_str("drop group if exists"), $5); }
+ ;
-/*****************************************************************************
- *
- * Drop a postgresql group
- *
- *
- *****************************************************************************/
-DropGroupStmt: DROP GROUP UserId
- {
- $$ = cat2_str(make_str("drop group"), $3);
- }
- ;
+ /*****************************************************************************
+ *
+ * Manipulate a schema
+ *
+ *
+ *****************************************************************************/
-/*****************************************************************************
- *
- * Manipulate a schema
- *
- *
- *****************************************************************************/
-
-CreateSchemaStmt: CREATE SCHEMA UserId
- {
- $$ = cat2_str(make_str("create scheme"), $3);
- }
+ CreateSchemaStmt: CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList
+ { $$ = cat_str(5, make_str("create schema"), $3, make_str("authorization"), $5, $6); }
+ | CREATE SCHEMA ColId OptSchemaEltList
+ { $$ = cat_str(3, make_str("create schema"), $3, $4); }
;
-AlterSchemaStmt: ALTER SCHEMA UserId
- {
- $$ = cat2_str(make_str("alter scheme"), $3);
- }
+ OptSchemaName: ColId { $$ = $1; }
+ | /* EMPTY */ { $$ = EMPTY; }
;
-DropSchemaStmt: DROP SCHEMA UserId
- {
- $$ = cat2_str(make_str("drop scheme"), $3);
- }
+OptSchemaEltList: OptSchemaEltList schema_stmt { $$ = cat2_str($1, $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
;
+/*
+ * schema_stmt are the ones that can show up inside a CREATE SCHEMA
+ * statement (in addition to by themselves).
+ */
+schema_stmt: CreateStmt { $$ = $1; }
+ | IndexStmt { $$ = $1; }
+ | CreateSeqStmt { $$ = $1; }
+ | CreateTrigStmt { $$ = $1; }
+ | GrantStmt { $$ = $1; }
+ | ViewStmt { $$ = $1; }
+ ;
+
+
+
/*****************************************************************************
*
* Set PG internal variable
* SET name TO 'var_value'
* Include SQL92 syntax (thomas 1997-10-22):
- * SET TIME ZONE 'var_value'
+ * SET TIME ZONE 'var_value'
*
*****************************************************************************/
+VariableSetStmt: SET set_rest
+ { $$ = cat2_str(make_str("set"), $2 ); }
+ | SET LOCAL set_rest
+ { $$ = cat2_str(make_str("set local"), $3 ); }
+ | SET SESSION set_rest
+ { $$ = cat2_str(make_str("set session"), $3 ); }
+ ;
+
+set_rest: /* Generic SET syntaxes: */
+ var_name TO var_list
+ { $$ = cat_str(3, $1, make_str("to"), $3); }
+ | var_name "=" var_list
+ { $$ = cat_str(3, $1, make_str("="), $3); }
+ | var_name TO DEFAULT
+ { $$ = cat2_str($1, make_str("to default")); }
+ | var_name "=" DEFAULT
+ { $$ = cat2_str($1, make_str("= default")); }
+ | var_name FROM CURRENT_P
+ { $$ = cat2_str($1, make_str("from current")); }
+ /* Special syntaxes mandated by SQL standard: */
+ | TIME ZONE zone_value
+ { $$ = cat2_str(make_str("time zone"), $3); }
+ | TRANSACTION transaction_mode_list
+ { $$ = cat2_str(make_str("transaction"), $2); }
+ | SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list
+ { $$ = cat2_str(make_str("session characteristics as transaction"), $5); }
+ | NAMES opt_encoding
+ { $$ = cat2_str(make_str("names"), $2); }
+ | ROLE ColId_or_Sconst
+ { $$ = cat2_str(make_str("role"), $2); }
+ | SESSION AUTHORIZATION ColId_or_Sconst
+ { $$ = cat2_str(make_str("session authorization"), $3); }
+ | SESSION AUTHORIZATION DEFAULT
+ { $$ = make_str("session authorization default"); }
+ | XML_P OPTION document_or_content
+ { $$ = cat2_str(make_str("xml option"), $3); }
+ ;
+
+var_name: ECPGColId { $$ = $1; }
+ | var_name '.' ColId { $$ = cat_str(3, $1, make_str("."), $3); }
+ ;
+
+
+var_list: var_value
+ { $$ = $1; }
+ | var_list ',' var_value
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
-VariableSetStmt: SET ColId TO var_value
- {
- $$ = cat_str(4, make_str("set"), $2, make_str("to"), $4);
- }
- | SET ColId '=' var_value
- {
- $$ = cat_str(4, make_str("set"), $2, make_str("="), $4);
- }
- | SET TIME ZONE zone_value
- {
- $$ = cat2_str(make_str("set time zone"), $4);
- }
- | SET TRANSACTION ISOLATION LEVEL opt_level
- {
- $$ = cat2_str(make_str("set transaction isolation level"), $5);
- }
- | SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL opt_level
- {
- $$ = cat2_str(make_str("set session characteristics as transaction isolation level"), $8);
- }
- | SET NAMES opt_encoding
- {
- $$ = cat2_str(make_str("set names"), $3);
- }
- | SET SESSION AUTHORIZATION ColId_or_Sconst
- {
- $$ = cat2_str(make_str("set session authorization"), $4);
- }
- ;
-
-opt_level: READ COMMITTED { $$ = make_str("read committed"); }
- | SERIALIZABLE { $$ = make_str("serializable"); }
- ;
-
-
-var_value: opt_boolean { $$ = $1; }
- | AllConst { $$ = $1; }
- | name_list {
- if (strlen($1) == 0)
- mmerror(PARSE_ERROR, ET_ERROR, "SET must have at least one argument.");
-
- $$ = $1;
- }
- | DEFAULT { $$ = make_str("default"); }
+iso_level: READ UNCOMMITTED { $$ = make_str("read uncommitted"); }
+ | READ COMMITTED { $$ = make_str("read committed"); }
+ | REPEATABLE READ { $$ = make_str("repeatable read"); }
+ | SERIALIZABLE { $$ = make_str("serializable"); }
;
-opt_boolean: TRUE_P { $$ = make_str("true"); }
- | FALSE_P { $$ = make_str("false"); }
- | ON { $$ = make_str("on"); }
- | OFF { $$ = make_str("off"); }
+var_value: opt_boolean { $$ = $1; }
+ | AllConst { /* we have to check for a variable here because it has to be
+ replaced with its value on the client side */
+ if ($1[1] == '$')
+ {
+ $$ = make_str("$0");
+ free($1);
+ }
+ else
+ $$ = $1;
+ }
+ | ColId { $$ = $1; }
;
+opt_boolean: TRUE_P { $$ = make_str("true"); }
+ | FALSE_P { $$ = make_str("false"); }
+ | ON { $$ = make_str("on"); }
+ | OFF { $$ = make_str("off"); }
+ ;
/* Timezone values can be:
-* - a string such as 'pst8pdt'
-* - an integer or floating point number
-* - a time interval per SQL99
-*/
+ * - a string such as 'pst8pdt'
+ * - a column identifier such as "pst8pdt"
+ * - an integer or floating point number
+ * - a time interval per SQL99
+ * ConstInterval and ColId give shift/reduce errors,
+ * so use IDENT and reject anything which is a reserved word.
+ */
zone_value: AllConst { $$ = $1; }
+ | ident { $$ = $1; }
| ConstInterval StringConst opt_interval
- {
- $$ = cat_str(3, $1, $2, $3);
- }
+ { $$ = cat_str(3, $1, $2, $3); }
| ConstInterval '(' PosIntConst ')' StringConst opt_interval
- {
- $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6);
- }
- | DEFAULT { $$ = make_str("default"); }
- | LOCAL { $$ = make_str("local"); }
+ { $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6); }
+ | DEFAULT
+ { $$ = make_str("default"); }
+ | LOCAL
+ { $$ = make_str("local"); }
;
-opt_encoding: StringConst { $$ = $1; }
- | DEFAULT { $$ = make_str("default"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_encoding: StringConst { $$ = $1; }
+ | DEFAULT { $$ = make_str("default"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-ColId_or_Sconst: ColId { $$ = $1; }
- | StringConst { $$ = $1; }
+ColId_or_Sconst: ColId { $$ = $1; }
+ | StringConst { $$ = $1; }
;
-VariableShowStmt: SHOW ColId
- {
- $$ = cat2_str(make_str("show"), $2);
- }
- | SHOW TIME ZONE
- {
- $$ = make_str("show time zone");
- }
+VariableShowStmt: SHOW var_name ecpg_into
+ { $$ = cat2_str(make_str("show"), $2); }
+ | SHOW TIME ZONE ecpg_into
+ { $$ = make_str("show time zone"); }
+ | SHOW TRANSACTION ISOLATION LEVEL ecpg_into
+ { $$ = make_str("show transaction isolation level"); }
+ | SHOW SESSION AUTHORIZATION ecpg_into
+ { $$ = make_str("show session authorization"); }
| SHOW ALL
- {
- $$ = make_str("show all");
- }
- | SHOW TRANSACTION ISOLATION LEVEL
- {
- $$ = make_str("show transaction isolation level");
- }
+ {
+ mmerror(PARSE_ERROR, ET_ERROR, "SHOW ALL not implemented");
+ $$ = EMPTY;
+ }
;
-VariableResetStmt: RESET ColId
- {
- $$ = cat2_str(make_str("reset"), $2);
- }
+VariableResetStmt: RESET var_name
+ { $$ = cat2_str(make_str("reset"), $2); }
| RESET TIME ZONE
- {
- $$ = make_str("reset time zone");
- }
+ { $$ = make_str("reset time zone"); }
| RESET TRANSACTION ISOLATION LEVEL
- {
- $$ = make_str("reset transaction isolation level");
- }
+ { $$ = make_str("reset transaction isolation level"); }
+ | RESET SESSION AUTHORIZATION
+ { $$ = make_str("reset session authorization"); }
| RESET ALL
- {
- $$ = make_str("reset all");
- }
+ { $$ = make_str("reset all"); }
+ ;
+
+/* SetResetClause allows SET or RESET without LOCAL */
+SetResetClause:
+ SET set_rest { $$ = cat2_str(make_str("set"), $2); }
+ | VariableResetStmt { $$ = $1; }
;
ConstraintsSetStmt: SET CONSTRAINTS constraints_set_list constraints_set_mode
- {
- $$ = cat_str(3, make_str("set constraints"), $3, $4);
- }
- ;
+ { $$ = cat_str(3, make_str("set constraints"), $3, $4); }
+ ;
constraints_set_list: ALL
- {
- $$ = make_str("all");
- }
- | constraints_set_namelist
- {
- $$ = $1;
- }
- ;
-
-
-constraints_set_namelist: ColId
- {
- $$ = $1;
- }
- | constraints_set_namelist ',' ColId
- {
- $$ = cat_str(3, $1, make_str(","), $3);
- }
- ;
+ { $$ = make_str("all"); }
+ | qualified_name_list
+ { $$ = $1; }
+ ;
-constraints_set_mode: DEFERRED
- {
- $$ = make_str("deferred");
- }
- | IMMEDIATE
- {
- $$ = make_str("immediate");
- }
- ;
+constraints_set_mode: DEFERRED { $$ = make_str("deferred"); }
+ | IMMEDIATE { $$ = make_str("immediate"); }
+ ;
/*
* Checkpoint statement
*/
-CheckPointStmt: CHECKPOINT { $$= make_str("checkpoint"); }
- ;
+CheckPointStmt: CHECKPOINT { $$= make_str("checkpoint"); }
+ ;
+DiscardStmt:
+ DISCARD ALL { $$ = make_str("discard all"); }
+ | DISCARD TEMP { $$ = make_str("discard temp"); }
+ | DISCARD TEMPORARY { $$ = make_str("discard temporary"); }
+ | DISCARD PLANS { $$ = make_str("discard plans"); }
+ ;
/*****************************************************************************
*
- * ALTER TABLE variations
+ * ALTER [ TABLE | INDEX | SEQUENCE | VIEW ] variations
*
*****************************************************************************/
AlterTableStmt:
-/* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
- ALTER TABLE relation_expr ADD opt_column columnDef
- {
- $$ = cat_str(5, make_str("alter table"), $3, make_str("add"), $5, $6);
- }
-/* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
- | ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default
- {
- $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, $7);
- }
-/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <Iconst> */
- | ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS Iconst
- {
- $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set statistics"), $9);
- }
-/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
- | ALTER TABLE relation_expr ALTER opt_column ColId SET STORAGE ColId
- {
- $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set storage"), $9);
- }
-/* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
- | ALTER TABLE relation_expr DROP opt_column ColId drop_behavior
- {
- $$ = cat_str(6, make_str("alter table"), $3, make_str("drop"), $5, $6, $7);
- }
-/* ALTER TABLE <relation> ADD CONSTRAINT ... */
- | ALTER TABLE relation_expr ADD TableConstraint
- {
- $$ = cat_str(4, make_str("alter table"), $3, make_str("add"), $5);
- }
-/* ALTER TABLE <relation> DROP CONSTRAINT ... */
- | ALTER TABLE relation_expr DROP CONSTRAINT name drop_behavior
- {
- $$ = cat_str(5, make_str("alter table"), $3, make_str("drop constraint"), $6, $7);
- }
-/* ALTER TABLE <name> OWNER TO UserId */
- | ALTER TABLE relation_name OWNER TO UserId
- {
- $$ = cat_str(4, make_str("alter table"), $3, make_str("owner to"), $6);
- }
+ ALTER TABLE relation_expr alter_table_cmds
+ { $$ = cat_str(3, make_str("alter table"), $3, $4); }
+ | ALTER INDEX relation_expr alter_table_cmds
+ { $$ = cat_str(3, make_str("alter index"), $3, $4); }
+ | ALTER SEQUENCE relation_expr alter_table_cmds
+ { $$ = cat_str(3, make_str("alter sequence"), $3, $4); }
+ | ALTER VIEW relation_expr alter_table_cmds
+ { $$ = cat_str(3, make_str("alter view"), $3, $4); }
+ ;
+
+alter_table_cmds:
+ alter_table_cmd { $$ = $1; }
+ | alter_table_cmds ',' alter_table_cmd { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+alter_table_cmd:
+/* ALTER TABLE <name> ADD [COLUMN] <coldef> */
+ ADD_P opt_column columnDef
+ { $$ = cat_str(3, make_str("add"), $2, $3); }
+/* ALTER TABLE <name> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
+ | ALTER opt_column ColId alter_column_default
+ { $$ = cat_str(4, make_str("alter"), $2, $3, $4); }
+/* ALTER TABLE <name> ALTER [COLUMN] <colname> DROP NOT NULL */
+ | ALTER opt_column ColId DROP NOT NULL_P
+ { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("drop not null")); }
+/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET NOT NULL */
+ | ALTER opt_column ColId SET NOT NULL_P
+ { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("set not null")); }
+/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STATISTICS <IntegerOnly> */
+ | ALTER opt_column ColId SET STATISTICS PosIntConst
+ { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set statistics"), $6); }
+/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
+ | ALTER opt_column ColId SET STORAGE ColId
+ { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set storage"), $6); }
+/* ALTER TABLE <name> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
+ | DROP opt_column ColId opt_drop_behavior
+ { $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
+/* ALTER TABLE <name> ALTER [COLUMN] <colname> TYPE <typename> [ USING <expression> ] */
+ | ALTER opt_column ColId TYPE_P Typename alter_using
+ { $$ = cat_str(6, make_str("alter"), $2, $3, make_str("type"), $5, $6); }
+/* ALTER TABLE <name> ADD CONSTRAINT ... */
+ | ADD_P TableConstraint
+ { $$ = cat_str(2, make_str("add"), $2); }
+/* ALTER TABLE <name> DROP CONSTRAINT ... */
+ | DROP CONSTRAINT name opt_drop_behavior
+ { $$ = cat_str(3, make_str("drop constraint"), $3, $4); }
+/* ALTER TABLE <name> SET WITHOUT OIDS */
+ | SET WITHOUT OIDS
+ { $$ = make_str("set without oids"); }
+/* ALTER TABLE <name> CLUSTER ON <indexname> */
+ | CLUSTER ON name
+ { $$ = cat_str(2, make_str("cluster on"), $3); }
+/* ALTER TABLE <name> SET WITHOUT CLUSTER */
+ | SET WITHOUT CLUSTER
+ { $$ = make_str("set without cluster"); }
+/* ALTER TABLE <name> ENABLE TRIGGER <trig> */
+ | ENABLE_P TRIGGER name
+ { $$ = cat2_str(make_str("enable trigger"), $3); }
+/* ALTER TABLE <name> ENABLE ALWAYS TRIGGER <trig> */
+ | ENABLE_P ALWAYS TRIGGER name
+ { $$ = cat2_str(make_str("enable always trigger"), $4); }
+/* ALTER TABLE <name> ENABLE REPLICA TRIGGER <trig> */
+ | ENABLE_P REPLICA TRIGGER name
+ { $$ = cat2_str(make_str("enable replica trigger"), $4); }
+/* ALTER TABLE <name> ENABLE TRIGGER ALL */
+ | ENABLE_P TRIGGER ALL
+ { $$ = make_str("enable trigger all"); }
+/* ALTER TABLE <name> ENABLE TRIGGER USER */
+ | ENABLE_P TRIGGER USER
+ { $$ = make_str("enable trigger user"); }
+/* ALTER TABLE <name> DISABLE TRIGGER <trig> */
+ | DISABLE_P TRIGGER name
+ { $$ = cat2_str(make_str("disable trigger"), $3); }
+/* ALTER TABLE <name> DISABLE TRIGGER ALL */
+ | DISABLE_P TRIGGER ALL
+ { $$ = make_str("disable trigger all"); }
+/* ALTER TABLE <name> DISABLE TRIGGER USER */
+ | DISABLE_P TRIGGER USER
+ { $$ = make_str("disable trigger user"); }
+/* ALTER TABLE <name> ENABLE RULE <rule> */
+ | ENABLE_P RULE name
+ { $$ = cat2_str(make_str("enable rule"), $3); }
+/* ALTER TABLE <name> ENABLE ALWAYS RULE <rule> */
+ | ENABLE_P ALWAYS RULE name
+ { $$ = cat2_str(make_str("enable always rule"), $4); }
+/* ALTER TABLE <name> ENABLE REPLICA RULE <rule> */
+ | ENABLE_P REPLICA RULE name
+ { $$ = cat2_str(make_str("enable replica rule"), $4); }
+/* ALTER TABLE <name> DISABLE RULE <rule> */
+ | DISABLE_P RULE name
+ { $$ = cat2_str(make_str("disable rule"), $3); }
+/* ALTER TABLE <name> ALTER INHERITS ADD <parent> */
+ | INHERIT qualified_name
+ { $$ = cat2_str(make_str("inherit"), $2); }
+/* ALTER TABLE <name> NO INHERITS <parent> */
+ | NO INHERIT qualified_name
+ { $$ = cat2_str(make_str("no inherit"), $3); }
+ /* ALTER <name> OWNER TO RoleId */
+ | OWNER TO RoleId
+ { $$ = cat2_str(make_str("owner to"), $3); }
+ /* ALTER <name> SET TABLESPACE <tablespacename> */
+ | SET TABLESPACE name
+ { $$ = cat2_str(make_str("set tablespace"), $3); }
+ | SET definition
+ { $$ = cat2_str(make_str("set"), $2); }
+ | RESET definition
+ { $$ = cat2_str(make_str("reset"), $2); }
;
alter_column_default:
- SET DEFAULT a_expr { $$ = cat2_str(make_str("set default"), $3); }
- | DROP DEFAULT { $$ = make_str("drop default"); }
- ;
-
-drop_behavior: CASCADE { $$ = make_str("cascade"); }
- | RESTRICT { $$ = make_str("restrict"); }
- ;
-
-/*****************************************************************************
- *
- * QUERY :
- * close <optname>
- *
- *****************************************************************************/
+ SET DEFAULT a_expr { $$ = cat2_str(make_str("set default"), $3); }
+ | DROP DEFAULT { $$ = make_str("drop default"); }
+ ;
-ClosePortalStmt: CLOSE opt_id
- {
- $$ = cat2_str(make_str("close"), $2);
- }
+opt_drop_behavior: CASCADE { $$ = make_str("cascade"); }
+ | RESTRICT { $$ = make_str("restrict"); }
+ | /* EMPTY */ { $$ = EMPTY; }
;
-opt_id: ColId { $$ = $1; }
- | /*EMPTY*/ { $$ = NULL; }
- ;
+alter_using: USING a_expr { $$ = cat2_str(make_str("using"), $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
/*****************************************************************************
*
* QUERY :
- * COPY [BINARY] <relname> FROM/TO
- * [USING DELIMITERS <delimiter>]
+ * close <portalname>
*
*****************************************************************************/
-CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
- {
- $$ = cat_str(8, make_str("copy"), $2, $3, $4, $5, $6, $7, $8);
- }
+ClosePortalStmt: CLOSE name
+ { $$ = cat2_str(make_str("close"), $2); }
+ | CLOSE ALL
+ { $$ = make_str("close all"); }
+ ;
+
+CopyStmt: COPY opt_binary qualified_name opt_oids copy_from
+ copy_file_name copy_delimiter opt_with copy_opt_list
+ {
+ if (strcmp($5, "to") == 0 && strcmp($6, "stdin") == 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "copy to stdin not possible\n");
+ else if (strcmp($5, "from") == 0 && strcmp($6, "stdout") == 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "copy from stdout not possible\n");
+ else if (strcmp($5, "from") == 0 && strcmp($6, "stdin") == 0)
+ mmerror(PARSE_ERROR, ET_WARNING, "copy from stdin not implemented\n");
+
+ $$ = cat_str(9, make_str("copy"), $2, $3, $4, $5, $6, $7, $8, $9);
+ }
+ | COPY select_with_parens TO copy_file_name opt_with copy_opt_list
+ {
+ if (strcmp($4, "stdin") == 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "copy to stdin is not possible\n");
+
+ $$ = cat_str(6, make_str("copy"), $2, make_str("to"), $4, $5, $6);
+ }
;
-copy_dirn: TO
- { $$ = make_str("to"); }
- | FROM
- { $$ = make_str("from"); }
+copy_from: TO { $$ = make_str("to"); }
+ | FROM { $$ = make_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: StringConst { $$ = $1; }
+copy_file_name: StringConst { $$ = $1; }
| STDIN { $$ = make_str("stdin"); }
| STDOUT { $$ = make_str("stdout"); }
;
-opt_binary: BINARY { $$ = make_str("binary"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+copy_opt_list: copy_opt_list copy_opt_item { $$ = cat2_str($1, $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
;
-opt_with_copy: WITH OIDS { $$ = make_str("with oids"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+copy_opt_item: BINARY { $$ = make_str("binary"); }
+ | OIDS { $$ = make_str("oids"); }
+ | DELIMITER opt_as StringConst
+ { $$ = cat_str(3, make_str("delimiter"), $2, $3); }
+ | NULL_P opt_as StringConst
+ { $$ = cat_str(3, make_str("null"), $2, $3); }
+ | CSV { $$ = make_str("csv"); }
+ | HEADER_P { $$ = make_str("header"); }
+ | QUOTE opt_as Sconst
+ { $$ = cat_str(3, make_str("quote"), $2, $3); }
+ | ESCAPE opt_as Sconst
+ { $$ = cat_str(3, make_str("escape"), $2, $3); }
+ | FORCE QUOTE columnList
+ { $$ = cat2_str(make_str("force quote"), $3); }
+ | FORCE NOT NULL_P columnList
+ { $$ = cat2_str(make_str("force not null"), $4); }
+
+ ;
+
+opt_binary: BINARY { $$ = make_str("binary"); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+opt_oids: WITH OIDS { $$ = make_str("with oids"); }
+ | /* EMPTY */ { $$ = EMPTY; }
;
+
/*
* the default copy delimiter is tab but the user can configure it
*/
-copy_delimiter: opt_using DELIMITERS StringConst { $$ = cat_str(3, $1, make_str("delimiters"), $3); }
- | /*EMPTY*/ { $$ = EMPTY; }
+copy_delimiter: opt_using DELIMITERS StringConst
+ { $$ = cat_str(3, $1, make_str("delimiters"), $3); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
;
opt_using: USING { $$ = make_str("using"); }
| /* EMPTY */ { $$ = EMPTY; }
;
-copy_null: WITH NULL_P AS StringConst { $$ = cat2_str(make_str("with null as"), $4); }
- | /* EMPTY */ { $$ = EMPTY; }
- ;
-
/*****************************************************************************
*
* QUERY :
- * CREATE relname
+ * CREATE TABLE relname
*
*****************************************************************************/
-CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
- OptInherit OptWithOids
- {
- $$ = cat_str(9, make_str("create"), $2, make_str("table"), $4, make_str("("), $6, make_str(")"), $8, $9);
- }
+CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
+ OptInherit OptWith OnCommitOption OptTableSpace
+ { $$ = cat_str(11, make_str("create"), $2, make_str("table"), $4, make_str("("), $6, make_str(")"), $8, $9, $10, $11); }
+ | CREATE OptTemp TABLE qualified_name OF qualified_name
+ '(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace
+ { $$ = cat_str(12, make_str("create"), $2, make_str("table"), $4, make_str("of"), $6, make_str("("), $8, make_str(")"), $10, $11, $12); }
;
/*
* since TEMP is not a reserved word. See also OptTempTableName.
*/
-OptTemp: TEMPORARY { $$ = make_str("temporary"); }
- | TEMP { $$ = make_str("temp"); }
+OptTemp: TEMPORARY { $$ = make_str("temporary"); }
+ | TEMP { $$ = make_str("temp"); }
| LOCAL TEMPORARY { $$ = make_str("local temporary"); }
| LOCAL TEMP { $$ = make_str("local temp"); }
- | GLOBAL TEMPORARY {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
- $$ = make_str("global temporary");
- }
- | GLOBAL TEMP {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
- $$ = make_str("global temp");
- }
- | /*EMPTY*/ { $$ = EMPTY; }
+ | GLOBAL TEMPORARY { $$ = make_str("global temporary"); }
+ | GLOBAL TEMP { $$ = make_str("global temp"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-OptTableElementList: OptTableElementList ',' OptTableElement
- {
- $$ = cat_str(3, $1, make_str(","), $3);
- }
- | OptTableElement
- {
- $$ = $1;
- }
- | /*EMPTY*/ { $$ = EMPTY; }
+
+OptTableElementList: TableElementList
+ { $$ = $1; }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
+ ;
+TableElementList: TableElement
+ { $$ = $1; }
+ | TableElementList ',' TableElement
+ { $$ = cat_str(3, $1, make_str(","), $3); }
;
-OptTableElement: columnDef { $$ = $1; }
- | TableConstraint { $$ = $1; }
+TableElement: columnDef { $$ = $1; }
+ | TableLikeClause { $$ = $1; }
+ | TableConstraint { $$ = $1; }
;
-columnDef: ColId Typename ColQualList opt_collate
- {
- if (strlen($4) > 0)
- {
- sprintf(errortext, "Currently unsupported CREATE TABLE / COLLATE %s will be passed to backend", $4);
- mmerror(PARSE_ERROR, ET_WARNING, errortext);
- }
- $$ = cat_str(4, $1, $2, $3, $4);
- }
+columnDef: ColId Typename ColQualList
+ {$$ = cat_str(3, $1, $2, $3); }
;
-ColQualList: ColQualList ColConstraint { $$ = cat2_str($1,$2); }
- | /*EMPTY*/ { $$ = EMPTY; }
+ColQualList: ColQualList ColConstraint { $$ = cat2_str($1,$2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
ColConstraint: CONSTRAINT name ColConstraintElem
- {
- $$ = cat_str(3, make_str("constraint"), $2, $3);
- }
- | ColConstraintElem
- { $$ = $1; }
- | ConstraintAttr
- { $$ = $1; }
+ { $$ = cat_str(3, make_str("constraint"), $2, $3); }
+ | ColConstraintElem { $$ = $1; }
+ | ConstraintAttr { $$ = $1; }
;
/* DEFAULT NULL is already the default for Postgres.
* shift/reduce conflicts with WITH TIME ZONE anyway.
* - thomas 1999-01-08
*/
-ColConstraintElem: NOT NULL_P
- {
- $$ = make_str("not null");
- }
- | NULL_P
- {
- $$ = make_str("null");
- }
- | UNIQUE
- {
- $$ = make_str("unique");
- }
- | PRIMARY KEY
- {
- $$ = make_str("primary key");
- }
- | CHECK '(' a_expr ')'
- {
- $$ = cat_str(3, make_str("check ("), $3, make_str(")"));
- }
- | DEFAULT b_expr
- {
- $$ = cat2_str(make_str("default"), $2);
- }
- | REFERENCES ColId opt_column_list key_match key_actions
- {
- $$ = cat_str(5, make_str("references"), $2, $3, $4, $5);
- }
- ;
+ColConstraintElem: NOT NULL_P
+ { $$ = make_str("not null"); }
+ | NULL_P
+ { $$ = make_str("null"); }
+ | UNIQUE opt_definition OptConsTableSpace
+ { $$ = cat_str(3, make_str("unique"), $2, $3); }
+ | PRIMARY KEY opt_definition OptConsTableSpace
+ { $$ = cat_str(3, make_str("primary key"), $3, $4); }
+ | CHECK '(' a_expr ')'
+ { $$ = cat_str(3, make_str("check ("), $3, make_str(")")); }
+ | DEFAULT b_expr
+ { $$ = cat2_str(make_str("default"), $2); }
+ | REFERENCES qualified_name opt_column_list key_match key_actions
+ { $$ = cat_str(5, make_str("references"), $2, $3, $4, $5); }
+ ;
/*
* ConstraintAttr represents constraint attributes, which we parse as if
| INITIALLY IMMEDIATE { $$ = make_str("initially immediate"); }
;
+TableLikeClause: LIKE qualified_name TableLikeOptionList
+ {$$ = cat_str(3, make_str("like"), $2, $3); }
+ ;
+
+TableLikeOptionList: TableLikeOptionList TableLikeOption
+ { $$ = cat2_str($1, $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+TableLikeOption:
+ INCLUDING DEFAULTS { $$ = make_str("including defaults"); }
+ | EXCLUDING DEFAULTS { $$ = make_str("excluding defaults"); }
+ | INCLUDING CONSTRAINTS { $$ = make_str("including constraints"); }
+ | EXCLUDING CONSTRAINTS { $$ = make_str("excluding constraints"); }
+ | INCLUDING INDEXES { $$ = make_str("including indexes"); }
+ | EXCLUDING INDEXES { $$ = make_str("excluding indexes"); }
+ ;
+
/* ConstraintElem specifies constraint syntax which is not embedded into
- * a column definition. ColConstraintElem specifies the embedded form.
+ * a column definition. ColConstraintElem specifies the embedded form.
* - thomas 1997-12-03
*/
TableConstraint: CONSTRAINT name ConstraintElem
- {
- $$ = cat_str(3, make_str("constraint"), $2, $3);
- }
+ { $$ = cat_str(3, make_str("constraint"), $2, $3); }
| ConstraintElem
- { $$ = $1; }
+ { $$ = $1; }
;
ConstraintElem: CHECK '(' a_expr ')'
- {
- $$ = cat_str(3, make_str("check("), $3, make_str(")"));
- }
- | UNIQUE '(' columnList ')'
- {
- $$ = cat_str(3, make_str("unique("), $3, make_str(")"));
- }
- | PRIMARY KEY '(' columnList ')'
- {
- $$ = cat_str(3, make_str("primary key("), $4, make_str(")"));
- }
- | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list
+ { $$ = cat_str(3, make_str("check("), $3, make_str(")")); }
+ | UNIQUE '(' columnList ')' opt_definition OptConsTableSpace
+ { $$ = cat_str(5, make_str("unique("), $3, make_str(")"), $5, $6); }
+ | PRIMARY KEY '(' columnList ')' opt_definition OptConsTableSpace
+ { $$ = cat_str(5, make_str("primary key("), $4, make_str(")"), $6, $7); }
+ | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list
key_match key_actions ConstraintAttributeSpec
- {
- $$ = cat_str(8, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10, $11);
- }
+ { $$ = cat_str(8, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10, $11); }
;
-key_match: MATCH FULL
- {
- $$ = make_str("match full");
- }
- | MATCH PARTIAL
+opt_column_list: '(' columnList ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+columnList: columnList ',' columnElem
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ | columnElem
+ { $$ = $1; }
+ ;
+
+columnElem: ColId { $$ = $1; }
+ ;
+
+key_match: MATCH FULL
+ { $$ = make_str("match full"); }
+ | MATCH PARTIAL
{
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported FOREIGN KEY/MATCH PARTIAL will be passed to backend");
+ mmerror(PARSE_ERROR, ET_WARNING, "currently unsupported FOREIGN KEY/MATCH PARTIAL will be passed to backend");
$$ = make_str("match partial");
}
| /*EMPTY*/
- {
- $$ = EMPTY;
- }
+ { $$ = EMPTY; }
;
-key_actions: key_delete { $$ = $1; }
- | key_update { $$ = $1; }
- | key_delete key_update { $$ = cat2_str($1, $2); }
- | key_update key_delete { $$ = cat2_str($1, $2); }
- | /*EMPTY*/ { $$ = EMPTY; }
+key_actions: key_delete { $$ = $1; }
+ | key_update { $$ = $1; }
+ | key_delete key_update { $$ = cat2_str($1, $2); }
+ | key_update key_delete { $$ = cat2_str($1, $2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-key_delete: ON DELETE key_reference { $$ = cat2_str(make_str("on delete"), $3); }
+key_delete: ON DELETE_P key_action
+ { $$ = cat2_str(make_str("on delete"), $3); }
+ ;
+
+key_update: ON UPDATE key_action
+ { $$ = cat2_str(make_str("on update"), $3); }
+ ;
+
+key_action: NO ACTION { $$ = make_str("no action"); }
+ | RESTRICT { $$ = make_str("restrict"); }
+ | CASCADE { $$ = make_str("cascade"); }
+ | SET DEFAULT { $$ = make_str("set default"); }
+ | SET NULL_P { $$ = make_str("set null"); }
+ ;
-key_update: ON UPDATE key_reference { $$ = cat2_str(make_str("on update"), $3); }
+OptInherit: INHERITS '(' qualified_name_list ')'
+ { $$ = cat_str(3, make_str("inherits ("), $3, make_str(")")); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
+ ;
-key_reference: NO ACTION { $$ = make_str("no action"); }
- | RESTRICT { $$ = make_str("restrict"); }
- | CASCADE { $$ = make_str("cascade"); }
- | SET DEFAULT { $$ = make_str("set default"); }
- | SET NULL_P { $$ = make_str("set null"); }
+OptWith: WITH definition { $$ = cat2_str(make_str("with"), $2); }
+ | WITH OIDS { $$ = make_str("with oids"); }
+ | WITHOUT OIDS { $$ = make_str("without oids"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-OptInherit: INHERITS '(' relation_name_list ')' { $$ = cat_str(3, make_str("inherits ("), $3, make_str(")")); }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
+OnCommitOption: ON COMMIT DROP { $$ = make_str("on commit drop"); }
+ | ON COMMIT DELETE_P ROWS { $$ = make_str("on commit delete rows"); }
+ | ON COMMIT PRESERVE ROWS { $$ = make_str("on commit preserve rows"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
-OptWithOids: WITH OIDS { $$ = make_str("with oids"); }
- | WITHOUT OIDS { $$ = make_str("without oids"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+OptTableSpace: TABLESPACE name { $$ = cat2_str(make_str("tablespace"), $2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
+OptConsTableSpace: USING INDEX TABLESPACE name { $$ = cat2_str(make_str("using index tablespace"), $4); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
/*
* Note: CREATE TABLE ... AS SELECT ... is just another spelling for
* SELECT ... INTO.
*/
-CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS
- { FoundInto = 0; } SelectStmt
+CreateAsStmt: CREATE OptTemp TABLE create_as_target AS
+ { FoundInto = 0; }
+ SelectStmt
{
if (FoundInto == 1)
- mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE / AS SELECT may not specify INTO");
+ mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE / AS SELECT cannot specify INTO");
- $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4, $5, make_str("as"), $8);
+ $$ = cat_str(6, make_str("create"), $2, make_str("table"), $4, make_str("as"), $7);
+ }
+ ;
+
+create_as_target: qualified_name OptCreateAs OptWith OnCommitOption OptTableSpace
+ {
+ $$ = cat_str(5, $1, $2, $3, $4, $5);
}
;
-OptCreateAs: '(' CreateAsList ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
- | /*EMPTY*/ { $$ = EMPTY; }
+OptCreateAs: '(' CreateAsList ')'
+ { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
;
-CreateAsList: CreateAsList ',' CreateAsElement { $$ = cat_str(3, $1, make_str(","), $3); }
- | CreateAsElement { $$ = $1; }
+CreateAsList: CreateAsList ',' CreateAsElement
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ | CreateAsElement
+ { $$ = $1; }
;
CreateAsElement: ColId { $$ = $1; }
*
* QUERY :
* CREATE SEQUENCE seqname
+ * ALTER SEQUENCE seqname
*
*****************************************************************************/
-CreateSeqStmt: CREATE OptTemp SEQUENCE relation_name OptSeqList
- {
- $$ = cat_str(4, make_str("create sequence"), $2, $4, $5);
- }
+CreateSeqStmt: CREATE OptTemp SEQUENCE qualified_name OptSeqOptList
+ { $$ = cat_str(5, make_str("create"), $2, make_str("sequence"), $4, $5); }
;
-OptSeqList: OptSeqList OptSeqElem
- { $$ = cat2_str($1, $2); }
- | { $$ = EMPTY; }
+AlterSeqStmt: ALTER SEQUENCE relation_expr SeqOptList
+ { $$ = cat_str(3,make_str("alter sequence"), $3, $4); }
;
-OptSeqElem: CACHE NumConst
- {
- $$ = cat2_str(make_str("cache"), $2);
- }
- | CYCLE
- {
- $$ = make_str("cycle");
- }
- | INCREMENT NumConst
- {
- $$ = cat2_str(make_str("increment"), $2);
- }
- | MAXVALUE NumConst
- {
- $$ = cat2_str(make_str("maxvalue"), $2);
- }
- | MINVALUE NumConst
- {
- $$ = cat2_str(make_str("minvalue"), $2);
- }
- | START NumConst
- {
- $$ = cat2_str(make_str("start"), $2);
- }
+OptSeqOptList: SeqOptList { $$ = $1; }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+SeqOptList: SeqOptElem { $$ = $1; }
+ | SeqOptList SeqOptElem { $$ = cat2_str($1, $2); }
+ ;
+
+SeqOptElem: CACHE NumConst
+ { $$ = cat2_str(make_str("cache"), $2); }
+ | CYCLE
+ { $$ = make_str("cycle"); }
+ | NO CYCLE
+ { $$ = make_str("no cycle"); }
+ | INCREMENT opt_by NumConst
+ { $$ = cat_str(3, make_str("increment"), $2, $3); }
+ | MAXVALUE NumConst
+ { $$ = cat2_str(make_str("maxvalue"), $2); }
+ | MINVALUE NumConst
+ { $$ = cat2_str(make_str("minvalue"), $2); }
+ | NO MAXVALUE
+ { $$ = make_str("no maxvalue"); }
+ | NO MINVALUE
+ { $$ = make_str("no minvalue"); }
+ | OWNED BY any_name
+ { $$ = cat2_str(make_str("owned by"), $3); }
+ | START opt_with NumConst
+ { $$ = cat_str(3, make_str("start"), $2, $3); }
+ | RESTART
+ { $$ = make_str("restart"); }
+ | RESTART opt_with NumConst
+ { $$ = cat_str(3, make_str("restart"), $2, $3); }
+ ;
+
+opt_by: BY { $$ = make_str("by"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/*****************************************************************************
*
*****************************************************************************/
-CreatePLangStmt: CREATE opt_Trusted opt_procedural LANGUAGE ColId_or_Sconst
- HANDLER func_name opt_lancompiler
- {
- $$ = cat_str(8, make_str("create"), $2, $3, make_str("language"), $5, make_str("handler"), $7, $8);
- }
+CreatePLangStmt: CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
+ { $$ = cat_str(5, make_str("create"), $2, $3, make_str("language"), $5); }
+ | CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
+ HANDLER handler_name opt_validator opt_lancompiler
+ { $$ = cat_str(9, make_str("create"), $2, $3, make_str("language"), $5, make_str("handler"), $7, $8, $9); }
;
-opt_Trusted: TRUSTED { $$ = make_str("trusted"); }
- | { $$ = EMPTY; }
- ;
+opt_trusted: TRUSTED { $$ = make_str("trusted"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
-opt_lancompiler: LANCOMPILER StringConst { $$ = cat2_str(make_str("lancompiler"), $2); }
- | /*EMPTY*/ { $$ = ""; }
- ;
+/* This ought to be just func_name, but that causes reduce/reduce conflicts
+ * (CREATE LANGUAGE is the only place where func_name isn't followed by '(').
+ * Work around by using simple names instead.
+ */
+handler_name: name { $$ = $1; }
+ | name attrs { $$ = cat2_str($1, $2); }
+ ;
-DropPLangStmt: DROP opt_procedural LANGUAGE StringConst
- {
- $$ = cat_str(4, make_str("drop"), $2, make_str("language"), $4);
- }
+opt_validator: VALIDATOR handler_name
+ { $$ = cat2_str(make_str("validator"), $2); }
+ | /*EMPTY*/
+ { $$ = ""; }
+ ;
+opt_lancompiler: LANCOMPILER StringConst
+ { $$ = cat2_str(make_str("lancompiler"), $2); }
+ | /*EMPTY*/
+ { $$ = ""; }
+ ;
+
+DropPLangStmt: DROP opt_procedural LANGUAGE StringConst opt_drop_behavior
+ { $$ = cat_str(5, make_str("drop"), $2, make_str("language"), $4, $5); }
+ | DROP opt_procedural LANGUAGE IF_P EXISTS StringConst opt_drop_behavior
+ { $$ = cat_str(5, make_str("drop"), $2, make_str("language if exists"), $6, $7); }
+ ;
+
+opt_procedural: PROCEDURAL { $$ = make_str("prcedural"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+/*****************************************************************************
+ *
+ * QUERY:
+ * CREATE TABLESPACE tablespace LOCATION '/path/to/tablespace/'
+ *
+ *****************************************************************************/
+
+CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst
+ { $$ = cat_str(5,make_str("create tablespace"), $3, $4, make_str("location"), $6); }
+ ;
+
+OptTableSpaceOwner: OWNER name { $$ = cat2_str(make_str("owner"), $2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+/*****************************************************************************
+ *
+ * QUERY :
+ * DROP TABLESPACE <tablespace>
+ *
+ * No need for drop behaviour as we cannot implement dependencies for
+ * objects in other databases; we can only support RESTRICT.
+ *
+ ****************************************************************************/
+
+
+DropTableSpaceStmt: DROP TABLESPACE name
+ { $$ = cat2_str(make_str("drop tablespace"), $3); }
+ | DROP TABLESPACE IF_P EXISTS name
+ { $$ = cat2_str(make_str("drop tablespace if exists"), $5); }
;
-opt_procedural: PROCEDURAL { $$ = make_str("prcedural"); }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
/*****************************************************************************
*
*****************************************************************************/
CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
- relation_name TriggerForSpec EXECUTE PROCEDURE
- name '(' TriggerFuncArgs ')'
- {
- $$ = cat_str(12, make_str("create trigger"), $3, $4, $5, make_str("on"), $7, $8, make_str("execute procedure"), $11, make_str("("), $13, make_str(")"));
- }
- | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
- relation_name OptConstrFromTable
- ConstraintAttributeSpec
- FOR EACH ROW EXECUTE PROCEDURE
- name '(' TriggerFuncArgs ')'
- {
- $$ = cat_str(13, make_str("create constraint trigger"), $4, make_str("after"), $6, make_str("on"), $8, $9, $10, make_str("for each row execute procedure"), $16, make_str("("), $18, make_str(")"));
- }
+ qualified_name TriggerForSpec EXECUTE PROCEDURE name
+ '(' TriggerFuncArgs ')'
+ { $$ = cat_str(12, make_str("create trigger"), $3, $4, $5, make_str("on"), $7, $8, make_str("execute procedure"), $11, make_str("("), $13, make_str(")")); }
+ | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
+ qualified_name OptConstrFromTable ConstraintAttributeSpec
+ FOR EACH ROW EXECUTE PROCEDURE
+ func_name '(' TriggerFuncArgs ')'
+ { $$ = cat_str(13, make_str("create constraint trigger"), $4, make_str("after"), $6, make_str("on"), $8, $9, $10, make_str("for each row execute procedure"), $16, make_str("("), $18, make_str(")")); }
;
-TriggerActionTime: BEFORE { $$ = make_str("before"); }
- | AFTER { $$ = make_str("after"); }
+TriggerActionTime: BEFORE { $$ = make_str("before"); }
+ | AFTER { $$ = make_str("after"); }
;
TriggerEvents: TriggerOneEvent
- {
- $$ = $1;
- }
- | TriggerOneEvent OR TriggerOneEvent
- {
- $$ = cat_str(3, $1, make_str("or"), $3);
- }
- | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
- {
- $$ = cat_str(5, $1, make_str("or"), $3, make_str("or"), $5);
- }
+ { $$ = $1; }
+ | TriggerOneEvent OR TriggerOneEvent
+ { $$ = cat_str(3, $1, make_str("or"), $3); }
+ | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
+ { $$ = cat_str(5, $1, make_str("or"), $3, make_str("or"), $5); }
;
-TriggerOneEvent: INSERT { $$ = make_str("insert"); }
- | DELETE { $$ = make_str("delete"); }
- | UPDATE { $$ = make_str("update"); }
+TriggerOneEvent: INSERT { $$ = make_str("insert"); }
+ | DELETE_P { $$ = make_str("delete"); }
+ | UPDATE { $$ = make_str("update"); }
;
TriggerForSpec: FOR TriggerForOpt TriggerForType
- {
- $$ = cat_str(3, make_str("for"), $2, $3);
- }
+ { $$ = cat_str(3, make_str("for"), $2, $3); }
+ | /* EMPTY */
+ { $$ = EMPTY; }
;
-TriggerForOpt: EACH { $$ = make_str("each"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+TriggerForOpt: EACH { $$ = make_str("each"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-TriggerForType: ROW { $$ = make_str("row"); }
- | STATEMENT { $$ = make_str("statement"); }
+TriggerForType: ROW { $$ = make_str("row"); }
+ | STATEMENT { $$ = make_str("statement"); }
;
TriggerFuncArgs: TriggerFuncArg
- { $$ = $1; }
- | TriggerFuncArgs ',' TriggerFuncArg
- { $$ = cat_str(3, $1, make_str(","), $3); }
- | /*EMPTY*/
- { $$ = EMPTY; }
+ { $$ = $1; }
+ | TriggerFuncArgs ',' TriggerFuncArg
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
;
-TriggerFuncArg: PosAllConst
- {
- $$ = $1;
- }
- | ColId { $$ = $1; }
- ;
-
-OptConstrFromTable: /* Empty */
- {
- $$ = EMPTY;
- }
- | FROM relation_name
- {
- $$ = cat2_str(make_str("from"), $2);
- }
- ;
-
-ConstraintAttributeSpec: ConstraintDeferrabilitySpec
- { $$ = $1; }
- | ConstraintDeferrabilitySpec ConstraintTimeSpec
- {
+TriggerFuncArg: PosAllConst { $$ = $1; }
+ | ColId { $$ = $1; }
+ ;
+
+OptConstrFromTable: /* Empty */ { $$ = EMPTY; }
+ | FROM qualified_name { $$ = cat2_str(make_str("from"), $2); }
+ ;
+
+ConstraintAttributeSpec: ConstraintDeferrabilitySpec { $$ = $1; }
+ | ConstraintDeferrabilitySpec ConstraintTimeSpec
+ {
if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 )
mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
$$ = cat2_str($1, $2);
}
- | ConstraintTimeSpec
- { $$ = $1; }
- | ConstraintTimeSpec ConstraintDeferrabilitySpec
+ | ConstraintTimeSpec { $$ = $1; }
+ | ConstraintTimeSpec ConstraintDeferrabilitySpec
{
if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
- $$ = cat2_str($1, $2);
+ $$ = cat2_str($1, $2);
}
- ;
+ | /* EMPTY */
+ {
+ $$ = EMPTY;
+ }
+ ;
-ConstraintDeferrabilitySpec: NOT DEFERRABLE { $$ = make_str("not deferrable"); }
- | DEFERRABLE { $$ = make_str("deferrable"); }
- ;
+ConstraintDeferrabilitySpec: NOT DEFERRABLE
+ { $$ = make_str("not deferrable"); }
+ | DEFERRABLE
+ { $$ = make_str("deferrable"); }
+ ;
-ConstraintTimeSpec: INITIALLY IMMEDIATE { $$ = make_str("initially immediate"); }
- | INITIALLY DEFERRED { $$ = make_str("initially deferred"); }
- ;
+ConstraintTimeSpec: INITIALLY IMMEDIATE
+ { $$ = make_str("initially immediate"); }
+ | INITIALLY DEFERRED
+ { $$ = make_str("initially deferred"); }
+ ;
-DropTrigStmt: DROP TRIGGER name ON relation_name
- {
- $$ = cat_str(4, make_str("drop trigger"), $3, make_str("on"), $5);
- }
+DropTrigStmt: DROP TRIGGER name ON qualified_name opt_drop_behavior
+ { $$ = cat_str(5, make_str("drop trigger"), $3, make_str("on"), $5, $6); }
+ | DROP TRIGGER IF_P EXISTS name ON qualified_name opt_drop_behavior
+ { $$ = cat_str(5, make_str("drop trigger if exists"), $5, make_str("on"), $7, $8); }
;
/*****************************************************************************
*
- * QUERY :
- * define (type,operator,aggregate)
+ * QUERIES :
+ * CREATE ASSERTION ...
+ * DROP ASSERTION ...
*
*****************************************************************************/
-
-DefineStmt: CREATE AGGREGATE func_name definition
+CreateAssertStmt: CREATE ASSERTION name
+ CHECK '(' a_expr ')' ConstraintAttributeSpec
{
- $$ = cat_str(3, make_str("create aggregate"), $3, $4);
+ mmerror(PARSE_ERROR, ET_ERROR, "CREATE ASSERTION is not yet supported");
+ $$ = cat_str(6, make_str("create assertion"), $3, make_str("check ("), $6, make_str(")"), $8);
}
- | CREATE OPERATOR all_Op definition
- {
- $$ = cat_str(3, make_str("create operator"), $3, $4);
- }
- | CREATE TYPE_P name definition
+ ;
+
+DropAssertStmt: DROP ASSERTION name
{
- $$ = cat_str(3, make_str("create type"), $3, $4);
+ mmerror(PARSE_ERROR, ET_ERROR, "DROP ASSERTION is not yet supported");
+ $$ = cat2_str(make_str("drop assertion"), $3);
}
;
-definition: '(' def_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+
+/*****************************************************************************
+ *
+ * QUERY :
+ * define (type,operator,aggregate)
+ *
+ *****************************************************************************/
+
+DefineStmt: CREATE AGGREGATE func_name aggr_args definition
+ { $$ = cat_str(4, make_str("create aggregate"), $3, $4, $5); }
+ | CREATE AGGREGATE func_name old_aggr_definition
+ { $$ = cat_str(3, make_str("create aggregate"), $3, $4); }
+ | CREATE OPERATOR all_Op definition
+ { $$ = cat_str(3, make_str("create operator"), $3, $4); }
+ | CREATE TYPE_P any_name definition
+ { $$ = cat_str(3, make_str("create type"), $3, $4); }
+ | CREATE TYPE_P any_name
+ { $$ = cat2_str(make_str("create type"), $3); }
+ | CREATE TYPE_P any_name AS '(' TableFuncElementList ')'
+ { $$ = cat_str(5, make_str("create type"), $3, make_str("as ("), $6, make_str(")")); }
+ | CREATE TYPE_P any_name AS ENUM_P '(' enum_val_list ')'
+ { $$ = cat_str(5, make_str("create type"), $3, make_str("as enum ("), $7, make_str(")")); }
+ | CREATE TEXT_P SEARCH PARSER any_name definition
+ { $$ = cat_str(3, make_str("create text search parser"), $5, $6); }
+ | CREATE TEXT_P SEARCH DICTIONARY any_name definition
+ { $$ = cat_str(3, make_str("create text search dictionary"), $5, $6); }
+ | CREATE TEXT_P SEARCH TEMPLATE any_name definition
+ { $$ = cat_str(3, make_str("create text search template"), $5, $6); }
+ | CREATE TEXT_P SEARCH CONFIGURATION any_name definition
+ { $$ = cat_str(3, make_str("create text search configuration"), $5, $6); }
+ ;
+
+definition: '(' def_list ')'
+ { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
;
def_list: def_elem { $$ = $1; }
- | def_list ',' def_elem { $$ = cat_str(3, $1, make_str(","), $3); }
+ | def_list ',' def_elem { $$ = cat_str(3, $1, make_str(","), $3); }
;
-def_elem: ColLabel '=' def_arg {
- $$ = cat_str(3, $1, make_str("="), $3);
- }
- | ColLabel
- {
- $$ = $1;
- }
+def_elem: ColLabel '=' def_arg { $$ = cat_str(3, $1, make_str("="), $3); }
+ | ColLabel { $$ = $1; }
;
/* Note: any simple identifier will be returned as a type name! */
-def_arg: func_return { $$ = $1; }
- | all_Op { $$ = $1; }
- | AllConst { $$ = $1; }
+def_arg: func_type { $$ = $1; }
+ | reserved_keyword { $$ = $1; }
+ | qual_all_Op { $$ = $1; }
+ | AllConst { $$ = $1; }
;
-/*****************************************************************************
- *
- * QUERY:
- *
- * DROP itemtype itemname [, itemname ...]
- *
- *****************************************************************************/
+aggr_args: '(' type_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | '(' '*' ')' { $$ = make_str("(*)"); }
+ ;
-DropStmt: DROP drop_type relation_name_list
- {
- $$ = cat_str(3, make_str("drop"), $2, $3);
+old_aggr_definition: '(' old_aggr_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ ;
+
+old_aggr_list: old_aggr_elem { $$ = $1; }
+ | old_aggr_list ',' old_aggr_elem { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+old_aggr_elem: ident '=' def_arg { $$ = cat_str(3, $1, make_str("="), $3); }
+ ;
+
+enum_val_list: StringConst { $$ = $1; }
+ | enum_val_list ',' StringConst { $$ = cat_str(3, $1, make_str(","), $3);}
+ ;
+
+CreateOpClassStmt: CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename
+ USING access_method opt_opfamily AS opclass_item_list
+ {
+ $$ = cat_str(10, make_str("create operator class"), $4, $5, make_str("for type"), $8, make_str("using"), $10, $11, make_str("as"), $13);
+ }
+ ;
+
+opclass_item_list: opclass_item { $$ = $1; }
+ | opclass_item_list ',' opclass_item { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+opclass_item: OPERATOR PosIntConst any_operator opt_recheck
+ { $$ = cat_str(4, make_str("operator"), $2, $3, $4); }
+ | OPERATOR PosIntConst any_operator '(' oper_argtypes ')' opt_recheck
+ { $$ = cat_str(7, make_str("operator"), $2, $3, make_str("("), $5, make_str(")"), $7); }
+ | FUNCTION PosIntConst func_name func_args
+ { $$ = cat_str(4, make_str("function"), $2, $3, $4); }
+ | FUNCTION PosIntConst '(' type_list ')' func_name func_args
+ { $$ = cat_str(7, make_str("function"), $2, make_str("("), $4, make_str(")"), $6, $7); }
+ | STORAGE Typename
+ { $$ = cat2_str(make_str("storage"), $2); }
+ ;
+
+opt_default: DEFAULT { $$ = make_str("default"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+opt_opfamily: FAMILY any_name { $$ = cat2_str(make_str("family"), $2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+opt_recheck: RECHECK {
+ mmerror(PARSE_ERROR, ET_WARNING, "no longer supported RECHECK OPTION will be passed to backend");
+ $$ = make_str("recheck");
}
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-drop_type: TABLE { $$ = make_str("table"); }
- | SEQUENCE { $$ = make_str("sequence"); }
- | VIEW { $$ = make_str("view"); }
- | INDEX { $$ = make_str("index"); }
- | RULE { $$ = make_str("rule"); }
- | TYPE_P { $$ = make_str("type"); }
- ;
+CreateOpFamilyStmt: CREATE OPERATOR FAMILY any_name USING access_method
+ { $$ = cat_str(4, make_str("create operator family"), $4, make_str("using"), $6); }
+ ;
+
+AlterOpFamilyStmt: ALTER OPERATOR FAMILY any_name USING access_method ADD_P opclass_item_list
+ { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("add"), $8); }
+ | ALTER OPERATOR FAMILY any_name USING access_method DROP opclass_drop_list
+ { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("drop"), $8); }
+ ;
+
+opclass_drop_list: opclass_drop { $$ = $1; }
+ | opclass_drop_list ',' opclass_drop { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+opclass_drop:
+ OPERATOR PosIntConst '(' type_list ')'
+ { $$ = cat_str(5, make_str("operator"), $2, make_str("("), $4, make_str(")")); }
+ | FUNCTION PosIntConst '(' type_list ')'
+ { $$ = cat_str(5, make_str("function"), $2, make_str("("), $4, make_str(")")); }
+ ;
+
+DropOpClassStmt: DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
+ { $$ = cat_str(5,make_str("drop operator class"), $4, make_str("using"), $6, $7); }
+ | DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior
+ { $$ = cat_str(5,make_str("drop operator class if exists"), $6, make_str("using"), $8, $9); }
+ ;
+
+DropOpFamilyStmt: DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior
+ { $$ = cat_str(5,make_str("drop operator family"), $4, make_str("using"), $6, $7); }
+ | DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior
+ { $$ = cat_str(5,make_str("drop operator family if exists"), $6, make_str("using"), $8, $9); }
+ ;
/*****************************************************************************
*
- * QUERY:
- * truncate table relname
+ * QUERY:
+ *
+ * DROP OWNED BY username [, username ...] [ RESTRICT | CASCADE ]
+ * REASSIGN OWNED BY username [, username ...] TO username
*
*****************************************************************************/
-TruncateStmt: TRUNCATE opt_table relation_name
- {
- $$ = cat2_str(make_str("truncate table"), $3);
- }
- ;
+DropOwnedStmt:
+ DROP OWNED BY name_list opt_drop_behavior
+ {$$ = cat_str(3, make_str("drop owned by"), $4, $5); }
+ ;
+
+ReassignOwnedStmt:
+ REASSIGN OWNED BY name_list TO name
+ {$$ = cat_str(4, make_str("reassign owned by"), $4, make_str("to"), $6); }
+ ;
/*****************************************************************************
*
* QUERY:
- * fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
- * fetch [ forward | backward | absolute | relative ]
- * [ # | all | next | prior ] [ [ in | from ] <portalname> ]
+ *
+ * DROP itemtype [ IF EXISTS ] itemname [, itemname ...] [ RESTRICT | CASCADE ]
*
*****************************************************************************/
-FetchStmt: FETCH direction fetch_how_many from_in name ecpg_into
- {
- if (strcmp($2, "relative") == 0 && atol($3) == 0L)
- mmerror(PARSE_ERROR, ET_ERROR, "FETCH/RELATIVE at current position is not supported");
+DropStmt: DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior
+ { $$ = cat_str(5, make_str("drop"), $2, make_str("if exists"), $5, $6); }
+ | DROP drop_type any_name_list opt_drop_behavior
+ { $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
+ ;
- $$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5);
- }
- | FETCH fetch_how_many from_in name ecpg_into
- {
- $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
- }
- | FETCH direction from_in name ecpg_into
- {
- $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
- }
- | FETCH from_in name ecpg_into
- {
- $$ = cat_str(3, make_str("fetch"), $2, $3);
- }
- | FETCH name ecpg_into
- {
- $$ = cat2_str(make_str("fetch"), $2);
- }
- | MOVE direction fetch_how_many from_in name
- {
- $$ = cat_str(5, make_str("move"), $2, $3, $4, $5);
- }
- | MOVE fetch_how_many from_in name
- {
- $$ = cat_str(4, make_str("move"), $2, $3, $4);
- }
- | MOVE direction from_in name
- {
- $$ = cat_str(4, make_str("move"), $2, $3, $4);
- }
- | MOVE from_in name
- {
- $$ = cat_str(3, make_str("move"), $2, $3);
- }
- | MOVE name
- {
- $$ = cat2_str(make_str("move"), $2);
- }
+drop_type: TABLE { $$ = make_str("table"); }
+ | SEQUENCE { $$ = make_str("sequence"); }
+ | VIEW { $$ = make_str("view"); }
+ | INDEX { $$ = make_str("index"); }
+ | TYPE_P { $$ = make_str("type"); }
+ | DOMAIN_P { $$ = make_str("domain"); }
+ | CONVERSION_P { $$ = make_str("conversion"); }
+ | SCHEMA { $$ = make_str("schema"); }
+ | TEXT_P SEARCH PARSER { $$ = make_str("text search parser"); }
+ | TEXT_P SEARCH DICTIONARY { $$ = make_str("text search dictionary"); }
+ | TEXT_P SEARCH TEMPLATE { $$ = make_str("text search template"); }
+ | TEXT_P SEARCH CONFIGURATION { $$ = make_str("text search configuration"); }
;
-direction: FORWARD { $$ = make_str("forward"); }
- | BACKWARD { $$ = make_str("backward"); }
- | RELATIVE { $$ = make_str("relative"); }
- | ABSOLUTE {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported FETCH/ABSOLUTE will be passed to backend, backend will use RELATIVE");
- $$ = make_str("absolute");
- }
+any_name_list: any_name
+ { $$ = $1; }
+ | any_name_list ',' any_name
+ { $$ = cat_str(3, $1, make_str(","), $3); }
;
-fetch_how_many: IntConst { $$ = $1; }
- | ALL { $$ = make_str("all"); }
- | NEXT { $$ = make_str("next"); }
- | PRIOR { $$ = make_str("prior"); }
+any_name: ColId { $$ = $1; }
+ | ColId attrs { $$ = cat2_str($1, $2); }
;
-from_in: IN { $$ = make_str("in"); }
- | FROM { $$ = make_str("from"); }
- ;
+attrs: '.' attr_name { $$ = cat2_str(make_str("."), $2); }
+ | attrs '.' attr_name { $$ = cat_str(3, $1, make_str("."), $3); }
+ ;
/*****************************************************************************
*
- * The COMMENT ON statement can take different forms based upon the type of
- * the object associated with the comment. The form of the statement is:
+ * QUERY:
+ * truncate table relname1, relname2, ....
*
- * COMMENT ON [ [ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ]
- * <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION
- * <funcname> (arg1, arg2, ...) | OPERATOR <op>
- * (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
- * <relname> ] IS 'text'
+ *****************************************************************************/
+TruncateStmt: TRUNCATE opt_table qualified_name_list opt_restart_seqs opt_drop_behavior
+ { $$ = cat_str(5, make_str("truncate table"), $2, $3, $4, $5); }
+ ;
+
+opt_restart_seqs:
+ CONTINUE_P IDENTITY_P { $$ = cat2_str(make_str("continue"), make_str("identity")); }
+ | RESTART IDENTITY_P { $$ = cat2_str(make_str("restart"), make_str("identity")); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+/*****************************************************************************
+ *
+ * QUERY:
+ * fetch/move
*
*****************************************************************************/
-CommentStmt: COMMENT ON comment_type name IS comment_text
- {
- $$ = cat_str(5, make_str("comment on"), $3, $4, make_str("is"), $6);
- }
- | COMMENT ON COLUMN relation_name '.' attr_name IS comment_text
- {
- $$ = cat_str(6, make_str("comment on column"), $4, make_str("."), $6, make_str("is"), $8);
+
+/* This is different from the backend as we try to be compatible with many other
+ * embedded SQL implementations. So we accept their syntax as well and
+ * translate it to the PGSQL syntax. */
+
+FetchStmt: FETCH fetch_direction from_in name ecpg_into
+ {
+ add_additional_variables($4, false);
+ $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
}
- | COMMENT ON AGGREGATE name '(' aggr_argtype ')' IS comment_text
- {
- $$ = cat_str(6, make_str("comment on aggregate"), $4, make_str("("), $6, make_str(") is"), $9);
+ | FETCH fetch_direction name ecpg_into
+ {
+ add_additional_variables($3, false);
+ $$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
}
- | COMMENT ON AGGREGATE name aggr_argtype IS comment_text
- {
- $$ = cat_str(5, make_str("comment on aggregate"), $4, $5, make_str("is"), $7);
+ | FETCH from_in name ecpg_into
+ {
+ add_additional_variables($3, false);
+ $$ = cat_str(3, make_str("fetch"), $2, $3);
}
- | COMMENT ON FUNCTION func_name func_args IS comment_text
+ | FETCH name ecpg_into
{
- $$ = cat_str(5, make_str("comment on function"), $4, $5, make_str("is"), $7);
+ add_additional_variables($2, false);
+ $$ = cat2_str(make_str("fetch"), $2);
}
- | COMMENT ON OPERATOR all_Op '(' oper_argtypes ')' IS comment_text
+ | FETCH fetch_direction from_in name
{
- $$ = cat_str(6, make_str("comment on operator"), $4, make_str("("), $6, make_str(") is"), $9);
+ add_additional_variables($4, false);
+ $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
}
- | COMMENT ON TRIGGER name ON relation_name IS comment_text
- {
- $$ = cat_str(6, make_str("comment on trigger"), $4, make_str("on"), $6, make_str("is"), $8);
+ | FETCH fetch_direction name
+ {
+ add_additional_variables($3, false);
+ $$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
}
- ;
+ | FETCH from_in name
+ {
+ add_additional_variables($3, false);
+ $$ = cat_str(3, make_str("fetch"), $2, $3);
+ }
+ | FETCH name
+ {
+ add_additional_variables($2, false);
+ $$ = cat2_str(make_str("fetch"), $2);
+ }
+ | MOVE fetch_direction from_in name
+ { $$ = cat_str(4, make_str("move"), $2, $3, $4); }
+ | MOVE name
+ { $$ = cat2_str(make_str("move"), $2); }
+ ;
+
+fetch_direction: NEXT { $$ = make_str("next"); }
+ | PRIOR { $$ = make_str("prior"); }
+ | FIRST_P { $$ = make_str("first"); }
+ | LAST_P { $$ = make_str("last"); }
+ | ABSOLUTE_P fetch_count { $$ = cat2_str(make_str("absolute"), $2); }
+ | RELATIVE_P fetch_count { $$ = cat2_str(make_str("relative"), $2); }
+ | fetch_count { $$ = $1; }
+ | ALL { $$ = make_str("all"); }
+ | FORWARD { $$ = make_str("forward"); }
+ | FORWARD fetch_count { $$ = cat2_str(make_str("forward"), $2); }
+ | FORWARD ALL { $$ = make_str("forward all"); }
+ | BACKWARD { $$ = make_str("backward"); }
+ | BACKWARD fetch_count { $$ = cat2_str(make_str("backward"), $2); }
+ | BACKWARD ALL { $$ = make_str("backward all"); }
+ ;
+
+fetch_count: IntConst {
+ if ($1[1] == '$')
+ {
+ /* a variable here has to be replaced on the client side, thus we have to use '$0' here */
+ $$ = make_str("$0");
+ free($1);
+ }
+ else
+ $$ = $1;
+ }
-comment_type: DATABASE { $$ = make_str("database"); }
- | INDEX { $$ = make_str("idnex"); }
- | RULE { $$ = make_str("rule"); }
- | SEQUENCE { $$ = make_str("sequence"); }
- | TABLE { $$ = make_str("table"); }
- | TYPE_P { $$ = make_str("type"); }
- | VIEW { $$ = make_str("view"); }
+from_in: IN_P { $$ = make_str("in"); }
+ | FROM { $$ = make_str("from"); }
;
-comment_text: StringConst { $$ = $1; }
- | NULL_P { $$ = make_str("null"); }
- ;
+CommentStmt: COMMENT ON comment_type name IS comment_text
+ { $$ = cat_str(5, make_str("comment on"), $3, $4, make_str("is"), $6); }
+ | COMMENT ON AGGREGATE func_name aggr_args IS comment_text
+ { $$ = cat_str(5, make_str("comment on aggregate"), $4, $5, make_str("is"), $7); }
+ | COMMENT ON FUNCTION func_name func_args IS comment_text
+ { $$ = cat_str(5, make_str("comment on function"), $4, $5, make_str("is"), $7); }
+ | COMMENT ON OPERATOR all_Op '(' oper_argtypes ')' IS comment_text
+ { $$ = cat_str(6, make_str("comment on operator"), $4, make_str("("), $6, make_str(") is"), $9); }
+ | COMMENT ON TRIGGER name ON any_name IS comment_text
+ { $$ = cat_str(6, make_str("comment on trigger"), $4, make_str("on"), $6, make_str("is"), $8); }
+ | COMMENT ON RULE name ON any_name IS comment_text
+ { $$ = cat_str(6, make_str("comment on rule"), $4, make_str("on"), $6, make_str("is"), $8); }
+ | COMMENT ON RULE name IS comment_text
+ { $$ = cat_str(4, make_str("comment on rule"), $4, make_str("is"), $6); }
+ | COMMENT ON OPERATOR CLASS any_name USING access_method IS comment_text
+ { $$ = cat_str(6, make_str("comment on operator class"), $5, make_str("using"), $7, make_str("is"), $9); }
+ | COMMENT ON OPERATOR FAMILY any_name USING access_method IS comment_text
+ { $$ = cat_str(6, make_str("comment on operator family"), $5, make_str("using"), $7, make_str("is"), $9); }
+ | COMMENT ON LARGE_P OBJECT_P NumConst IS comment_text
+ { $$ = cat_str(4, make_str("comment on large object"), $5, make_str("is"), $7); }
+ | COMMENT ON CAST '(' Typename AS Typename ')' IS comment_text
+ { $$ = cat_str(6, make_str("comment on cast ("), $5, make_str("as"), $7, make_str(") is"), $10); }
+ | COMMENT ON opt_procedural LANGUAGE any_name IS comment_text
+ { $$ = cat_str(6, make_str("comment on"), $3, make_str("language"), $5, make_str("is"), $7); }
+ | COMMENT ON TEXT_P SEARCH PARSER any_name IS comment_text
+ { $$ = cat_str(4, make_str("comment on test search parser"), $6, make_str("is"), $8); }
+ | COMMENT ON TEXT_P SEARCH DICTIONARY any_name IS comment_text
+ { $$ = cat_str(4, make_str("comment on test search dictionary"), $6, make_str("is"), $8); }
+ | COMMENT ON TEXT_P SEARCH TEMPLATE any_name IS comment_text
+ { $$ = cat_str(4, make_str("comment on test search template"), $6, make_str("is"), $8); }
+ | COMMENT ON TEXT_P SEARCH CONFIGURATION any_name IS comment_text
+ { $$ = cat_str(4, make_str("comment on test search configuration"), $6, make_str("is"), $8); }
+ ;
+
+comment_type: COLUMN { $$ = make_str("column"); }
+ | DATABASE { $$ = make_str("database"); }
+ | SCHEMA { $$ = make_str("schema"); }
+ | INDEX { $$ = make_str("idnex"); }
+ | SEQUENCE { $$ = make_str("sequence"); }
+ | TABLE { $$ = make_str("table"); }
+ | DOMAIN_P { $$ = make_str("domain"); }
+ | TYPE_P { $$ = make_str("type"); }
+ | VIEW { $$ = make_str("view"); }
+ | CONVERSION_P { $$ = make_str("conversion"); }
+ | TABLESPACE { $$ = make_str("tablespace"); }
+ | ROLE { $$ = make_str("role"); }
+ ;
+
+comment_text: StringConst { $$ = $1; }
+ | NULL_P { $$ = make_str("null"); }
+ ;
/*****************************************************************************
*
*
*****************************************************************************/
-GrantStmt: GRANT privileges ON privilege_target TO grantee_list opt_grant_grant_option
- {
- $$ = cat_str(7, make_str("grant"), $2, make_str("on"), $4, make_str("to"), $6, $7);
- }
+GrantStmt: GRANT privileges ON privilege_target TO grantee_list opt_grant_grant_option
+ { $$ = cat_str(7, make_str("grant"), $2, make_str("on"), $4, make_str("to"), $6, $7); }
;
-RevokeStmt: REVOKE opt_revoke_grant_option privileges ON privilege_target FROM grantee_list
- {
- $$ = cat_str(8, make_str("revoke"), $2, $3, make_str("on"), $5, make_str("from"), $7);
- }
+RevokeStmt: REVOKE privileges ON privilege_target FROM grantee_list opt_drop_behavior
+ {$$ = cat_str(7, make_str("revoke"), $2, make_str("on"), $4, make_str("from"), $6, $7); }
+ | REVOKE GRANT OPTION FOR privileges ON privilege_target FROM grantee_list opt_drop_behavior
+ {$$ = cat_str(7, make_str("revoke grant option for"), $5, make_str("on"), $7, make_str("from"), $9, $10); }
;
-privileges: ALL PRIVILEGES
- {
- $$ = make_str("all privileges");
- }
- | ALL
- {
- $$ = make_str("all");
- }
- | privilege_list
- {
- $$ = $1;
- }
+privileges: ALL PRIVILEGES { $$ = make_str("all privileges"); }
+ | ALL { $$ = make_str("all"); }
+ | privilege_list { $$ = $1; }
;
privilege_list: privilege
- {
- $$ = $1;
- }
+ { $$ = $1; }
| privilege_list ',' privilege
- {
- $$ = cat_str(3, $1, make_str(","), $3);
- }
+ { $$ = cat_str(3, $1, make_str(","), $3); }
;
-privilege: SELECT
- {
- $$ = make_str("select");
- }
- | INSERT
- {
- $$ = make_str("insert");
- }
- | UPDATE
- {
- $$ = make_str("update");
- }
- | DELETE
- {
- $$ = make_str("delete");
- }
- | RULE
- {
- $$ = make_str("rule");
- }
- | REFERENCES
- {
- $$ = make_str("references");
- }
- | TRIGGER
- {
- $$ = make_str("trigger");
- }
- | EXECUTE
- {
- $$ = make_str("execute");
- }
- | USAGE
- {
- $$ = make_str("usage");
- }
+privilege: SELECT { $$ = make_str("select"); }
+ | REFERENCES { $$ = make_str("references"); }
+ | CREATE { $$ = make_str("create"); }
+ | ColId { $$ = $1; }
;
-privilege_target: relation_name_list
- {
- $$ = $1;
- }
- | TABLE relation_name_list
- {
- $$ = cat2_str(make_str("table"), $2);
- }
+privilege_target: qualified_name_list
+ { $$ = $1; }
+ | TABLE qualified_name_list
+ { $$ = cat2_str(make_str("table"), $2); }
+ | SEQUENCE qualified_name_list
+ { $$ = cat2_str(make_str("sequence"), $2); }
| FUNCTION function_with_argtypes_list
- {
- $$ = cat2_str(make_str("function"), $2);
- }
+ { $$ = cat2_str(make_str("function"), $2); }
+ | DATABASE name_list
+ { $$ = cat2_str(make_str("database"), $2); }
| LANGUAGE name_list
- {
- $$ = cat2_str(make_str("language") , $2);
- }
+ { $$ = cat2_str(make_str("language") , $2); }
+ | SCHEMA name_list
+ { $$ = cat2_str(make_str("schema") , $2); }
+ | TABLESPACE name_list
+ { $$ = cat2_str(make_str("tablespace") , $2); }
;
-
-grantee_list: grantee { $$ = $1; }
- | grantee_list ',' grantee { $$ = cat_str(3, $1, make_str(","), $3); }
+
+grantee_list: grantee
+ { $$ = $1; }
+ | grantee_list ',' grantee
+ { $$ = cat_str(3, $1, make_str(","), $3); }
;
-
-grantee: PUBLIC
- {
- $$ = make_str("public");
- }
- | GROUP ColId
- {
- $$ = cat2_str(make_str("group"), $2);
- }
- | ColId
- {
- $$ = $1;
- }
+
+grantee: RoleId { $$ = $1; }
+ | GROUP_P RoleId { $$ = cat2_str(make_str("group"), $2); }
;
opt_grant_grant_option: WITH GRANT OPTION
- {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported GRANT/WITH GRANT OPTION will be passed to backend");
+ {
+ mmerror(PARSE_ERROR, ET_WARNING, "currently unsupported GRANT/WITH GRANT OPTION will be passed to backend");
$$ = make_str("with grant option");
}
- | /*EMPTY*/ { $$ = EMPTY; }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-opt_revoke_grant_option: GRANT OPTION FOR
- {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported REVOKE/GRANT OPTION FOR will be passed to backend");
- $$ = make_str("with grant option");
- }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
-
function_with_argtypes_list: function_with_argtypes
- { $$ = $1; }
+ { $$ = $1; }
| function_with_argtypes_list ',' function_with_argtypes
{ $$ = cat_str(3, $1, make_str(","), $3); }
;
-function_with_argtypes: func_name func_args
- { $$ = cat2_str($1, $2); };
+function_with_argtypes: func_name func_args { $$ = cat2_str($1, $2); };
/*****************************************************************************
*
- * QUERY:
- * create index <indexname> on <relname>
- * [ using <access> ] "(" (<col> with <op>)+ ")"
- * [ where <predicate> ]
+ * GRANT and REVOKE ROLE statements
*
*****************************************************************************/
-IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
- access_method_clause '(' index_params ')' where_clause
- {
- $$ = cat_str(11, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11);
- }
+GrantRoleStmt:
+ GRANT privilege_list TO name_list opt_grant_admin_option opt_granted_by
+ { $$ = cat_str(6, make_str("grant"), $2, make_str("to"), $4, $5, $6); }
;
-index_opt_unique: UNIQUE { $$ = make_str("unique"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+RevokeRoleStmt:
+ REVOKE privilege_list FROM name_list opt_granted_by opt_drop_behavior
+ { $$ = cat_str(6, make_str("revoke"), $2, make_str("from"), $4, $5, $6); }
;
-access_method_clause: USING access_method { $$ = cat2_str(make_str("using"), $2); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_grant_admin_option: WITH ADMIN OPTION { $$ = make_str("with admin option"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-index_params: index_list { $$ = $1; }
- | func_index { $$ = $1; }
+opt_granted_by: GRANTED BY RoleId { $$ = cat2_str(make_str("granted by"), $3); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-index_list: index_list ',' index_elem { $$ = cat_str(3, $1, make_str(","), $3); }
- | index_elem { $$ = $1; }
+/*****************************************************************************
+ *
+ * QUERY:
+ * QUERY: CREATE INDEX
+ *
+ * Note: we can't factor CONCURRENTLY into a separate production without
+ * making it a reserved word.
+ *
+ * Note: we cannot put TABLESPACE clause after WHERE clause unless we are
+ * willing to make TABLESPACE a fully reserved word.
+ *
+ *****************************************************************************/
+
+IndexStmt: CREATE index_opt_unique INDEX index_name ON qualified_name
+ access_method_clause '(' index_params ')' opt_definition OptTableSpace where_clause
+ { $$ = cat_str(13, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11, $12, $13); }
+ | CREATE index_opt_unique INDEX CONCURRENTLY index_name ON qualified_name
+ access_method_clause '(' index_params ')' opt_definition OptTableSpace where_clause
+ { $$ = cat_str(13, make_str("create"), $2, make_str("index concurrently"), $5, make_str("on"), $7, $8, make_str("("), $10, make_str(")"), $12, $13, $14); }
;
-func_index: func_name '(' name_list ')' opt_class
- {
- $$ = cat_str(5, $1, make_str("("), $3, ")", $5);
- }
- ;
+index_opt_unique: UNIQUE { $$ = make_str("unique"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
-index_elem: attr_name opt_class
- {
- $$ = cat2_str($1, $2);
- }
+access_method_clause: USING access_method
+ { $$ = cat2_str(make_str("using"), $2); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
;
-opt_class: class {
- /*
- * Release 7.0 removed network_ops, timespan_ops, and
- * datetime_ops, so we suppress it from being passed to
- * the parser so the default *_ops is used. This can be
- * removed in some later release. bjm 2000/02/07
- *
- * Release 7.1 removes lztext_ops, so suppress that too
- * for a while. tgl 2000/07/30
- */
- if (strcmp($1, "network_ops") != 0 &&
- strcmp($1, "timespan_ops") != 0 &&
- strcmp($1, "datetime_ops") != 0 &&
- strcmp($1, "lztext_ops") != 0)
- $$ = $1;
- else
- $$ = EMPTY;
- }
- | USING class { $$ = cat2_str(make_str("using"), $2); }
- | /*EMPTY*/ { $$ = EMPTY; }
+index_params: index_elem { $$ = $1; }
+ | index_params ',' index_elem { $$ = cat_str(3, $1, make_str(","), $3); }
;
+index_elem: ColId opt_class opt_asc_desc opt_nulls_order
+ { $$ = cat_str(4, $1, $2, $3, $4); }
+ | func_expr opt_class opt_asc_desc opt_nulls_order
+ { $$ = cat_str(4, $1, $2, $3, $4); }
+ | '(' a_expr ')' opt_class opt_asc_desc opt_nulls_order
+ { $$ = cat_str(6, make_str("("), $2, make_str(")"), $4, $5, $6); }
+ ;
-/*****************************************************************************
- *
- * QUERY:
- * execute recipe <recipeName>
- *
- *****************************************************************************/
-/* NOT USED
-RecipeStmt: EXECUTE RECIPE recipe_name
- {
- $$ = cat2_str(make_str("execute recipe"), $3);
- }
+opt_class: any_name { $$ = $1; }
+ | USING any_name { $$ = cat2_str(make_str("using"), $2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-*/
-/*****************************************************************************
- *
- * QUERY:
- * create [or replace] function <fname>
- * [(<type-1> { , <type-n>})]
- * returns <type-r>
- * as <filename or code in language as appropriate>
- * language <lang> [with parameters]
- *
- *****************************************************************************/
-ProcedureStmt: CREATE opt_or_replace FUNCTION func_name func_args
- RETURNS func_return AS func_as LANGUAGE ColId_or_Sconst opt_with
- {
- $$ = cat_str(12, make_str("create"), $2, make_str("function"), $4, $5, make_str("returns"), $7, make_str("as"), $9, make_str("language"), $11, $12);
- }
+opt_asc_desc: ASC { $$ = make_str("asc"); }
+ | DESC { $$ = make_str("desc"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
-opt_or_replace: OR REPLACE { $$ = make_str("or replace"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_nulls_order: NULLS_FIRST { $$ = make_str("nulls first"); }
+ | NULLS_LAST { $$ = make_str("nulls last"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+CreateFunctionStmt: CREATE opt_or_replace FUNCTION func_name func_args
+ RETURNS func_return createfunc_opt_list opt_definition
+ { $$ = cat_str(8, make_str("create"), $2, make_str("function"), $4, $5, make_str("returns"), $7, $8); }
+ | CREATE opt_or_replace FUNCTION func_name func_args
+ RETURNS TABLE '(' table_func_column_list ')' createfunc_opt_list opt_definition
+ { $$ = cat_str(9, make_str("create"), $2, make_str("function"), $4, $5, make_str("returns table ("), $9, make_str(")"), $11, $12); }
+ | CREATE opt_or_replace FUNCTION func_name func_args
+ createfunc_opt_list opt_definition
+ { $$ = cat_str(6, make_str("create"), $2, make_str("function"), $4, $5, $6, $7); }
;
-opt_with: WITH definition { $$ = cat2_str(make_str("with"), $2); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_or_replace: OR REPLACE { $$ = make_str("or replace"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-func_args: '(' func_args_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
- | '(' ')' { $$ = make_str("()"); }
+func_args: '(' func_args_list ')'
+ { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | '(' ')'
+ { $$ = make_str("()"); }
;
-func_args_list: func_arg { $$ = $1; }
+func_args_list: func_arg
+ { $$ = $1; }
| func_args_list ',' func_arg
- { $$ = cat_str(3, $1, make_str(","), $3); }
- ;
-
-func_arg: opt_arg func_type
- {
- /* We can catch over-specified arguments here if we want to,
- * but for now better to silently swallow typmod, etc.
- * - thomas 2000-03-22
- */
- $$ = cat2_str($1, $2);
- }
- | func_type
- {
- $$ = $1;
- }
- ;
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
-opt_arg: IN { $$ = make_str("in"); }
- | OUT {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE FUNCTION/OUT will be passed to backend");
+func_arg: arg_class param_name func_type { $$ = cat_str(3, $1, $2, $3); }
+ | param_name arg_class func_type { $$ = cat_str(3, $1, $2, $3); }
+ | param_name func_type { $$ = cat2_str($1, $2); }
+ | arg_class func_type { $$ = cat2_str($1, $2); }
+ | func_type { $$ = $1; }
+ ;
- $$ = make_str("out");
- }
- | INOUT {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE FUNCTION/INOUT will be passed to backend");
+arg_class: IN_P { $$ = make_str("in"); }
+ | OUT_P { $$ = make_str("out"); }
+ | INOUT { $$ = make_str("inout"); }
+ | IN_P OUT_P { $$ = make_str("in out"); }
+ | VARIADIC { $$ = make_str("variadic"); }
+ ;
- $$ = make_str("inout");
- }
- ;
+func_as: StringConst
+ { $$ = $1; }
+ | StringConst ',' StringConst
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
-func_as: StringConst { $$ = $1; }
- | StringConst ',' StringConst { $$ = cat_str(3, $1, make_str(","), $3); }
+param_name: type_function_name { $$ = $1; };
func_return: func_type
- {
- /* We can catch over-specified arguments here if we want to,
- * but for now better to silently swallow typmod, etc.
- * - thomas 2000-03-22
- */
- $$ = $1;
- }
+ {
+ /* We can catch over-specified arguments here if we want to,
+ * but for now better to silently swallow typmod, etc.
+ * - thomas 2000-03-22
+ */
+ $$ = $1;
+ }
;
func_type: Typename
- {
- $$ = $1;
- }
- | type_name '.' ColId '%' TYPE_P
- {
- $$ = cat_str(4, $1, make_str("."), $3, make_str("% type"));
- }
+ { $$ = $1; }
+ | type_function_name attrs '%' TYPE_P
+ { $$ = cat_str(3, $1, $2, make_str("% type")); }
+ | SETOF type_function_name attrs '%' TYPE_P
+ { $$ = cat_str(4, make_str("setof"), $2, $3, make_str("% type")); }
+ ;
+
+
+createfunc_opt_list: createfunc_opt_item
+ { $$ = $1; }
+ | createfunc_opt_list createfunc_opt_item
+ { $$ = cat2_str($1, $2); }
+ ;
+
+common_func_opt_item:
+ CALLED ON NULL_P INPUT_P
+ { $$ = make_str("called on null input"); }
+ | RETURNS NULL_P ON NULL_P INPUT_P
+ { $$ = make_str("returns null on null input"); }
+ | STRICT_P
+ { $$ = make_str("strict"); }
+ | IMMUTABLE
+ { $$ = make_str("immutable"); }
+ | STABLE
+ { $$ = make_str("stable"); }
+ | VOLATILE
+ { $$ = make_str("volatile"); }
+ | EXTERNAL SECURITY DEFINER
+ { $$ = make_str("external security definer"); }
+ | EXTERNAL SECURITY INVOKER
+ { $$ = make_str("external security invoker"); }
+ | SECURITY DEFINER
+ { $$ = make_str("security definer"); }
+ | SECURITY INVOKER
+ { $$ = make_str("security invoker"); }
+ | COST NumConst
+ { $$ = cat2_str(make_str("cost"), $2); }
+ | ROWS NumConst
+ { $$ = cat2_str(make_str("rows"), $2); }
+ | SetResetClause
+ { $$ = $1; }
+ ;
+
+createfunc_opt_item: AS func_as
+ { $$ = cat2_str(make_str("as"), $2); }
+ | LANGUAGE ColId_or_Sconst
+ { $$ = cat2_str(make_str("language"), $2); }
+ | common_func_opt_item
+ { $$ = $1; }
+ ;
+
+opt_definition: WITH definition { $$ = cat2_str(make_str("with"), $2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+table_func_column: param_name func_type { $$ = cat2_str($1, $2); }
+ ;
+
+table_func_column_list:
+ table_func_column { $$ = $1; }
+ | table_func_column_list ',' table_func_column { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+AlterFunctionStmt:
+ ALTER FUNCTION function_with_argtypes alterfunc_opt_list opt_restrict
+ { $$ = cat_str(4, make_str("alter function"), $3, $4, $5); }
+ ;
+
+alterfunc_opt_list: common_func_opt_item { $$ = $1; }
+ | alterfunc_opt_list common_func_opt_item { $$ = cat2_str($1, $2);}
+ ;
+
+opt_restrict: RESTRICT { $$ = make_str("restrict"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/*****************************************************************************
*
* QUERY:
*
- * DROP FUNCTION funcname (arg1, arg2, ...)
- * DROP AGGREGATE aggname (aggtype)
- * DROP OPERATOR opname (leftoperand_typ rightoperand_typ)
+ * DROP FUNCTION funcname (arg1, arg2, ...)
+ * DROP AGGREGATE (arg1, ...) [ RESTRICT | CASCADE ]
+ * DROP OPERATOR opname (leftoperand_typ rightoperand_typ)
*
*****************************************************************************/
-RemoveFuncStmt: DROP FUNCTION func_name func_args
- {
- $$ = cat_str(3, make_str("drop function"), $3, $4);
- }
- ;
-
-RemoveAggrStmt: DROP AGGREGATE func_name '(' aggr_argtype ')'
- {
- $$ = cat_str(5, make_str("drop aggregate"), $3, make_str("("), $5, make_str(")"));
- }
- | DROP AGGREGATE func_name aggr_argtype
- {
- /* Obsolete syntax, but must support for awhile */
- $$ = cat_str(3, make_str("drop aggregate"), $3, $4);
- }
+RemoveFuncStmt: DROP FUNCTION func_name func_args opt_drop_behavior
+ { $$ = cat_str(4, make_str("drop function"), $3, $4, $5); }
+ | DROP FUNCTION IF_P EXISTS func_name func_args opt_drop_behavior
+ { $$ = cat_str(4, make_str("drop function if exists"), $5, $6, $7); }
;
-aggr_argtype: Typename { $$ = $1; }
- | '*' { $$ = make_str("*"); }
+RemoveAggrStmt: DROP AGGREGATE func_name aggr_args opt_drop_behavior
+ { $$ = cat_str(4, make_str("drop aggregate"), $3, $4, $5); }
+ | DROP AGGREGATE IF_P EXISTS func_name aggr_args opt_drop_behavior
+ { $$ = cat_str(4, make_str("drop aggregate if exists"), $5, $6, $7); }
;
-
-RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
- {
- $$ = cat_str(5, make_str("drop operator"), $3, make_str("("), $5, make_str(")"));
- }
+RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')' opt_drop_behavior
+ { $$ = cat_str(6, make_str("drop operator"), $3, make_str("("), $5, make_str(")"), $7); }
+ | DROP OPERATOR IF_P EXISTS any_operator '(' oper_argtypes ')' opt_drop_behavior
+ { $$ = cat_str(6, make_str("drop operator if exists"), $5, make_str("("), $7, make_str(")"), $9); }
;
oper_argtypes: Typename
- {
- mmerror(PARSE_ERROR, ET_ERROR, "parser: argument type missing (use NONE for unary operators)");
- }
+ {
+ mmerror(PARSE_ERROR, ET_ERROR, "parser: argument type missing (use NONE for unary operators)");
+ $$ = make_str("none");
+ }
| Typename ',' Typename
- { $$ = cat_str(3, $1, make_str(","), $3); }
+ { $$ = cat_str(3, $1, make_str(","), $3); }
| NONE ',' Typename /* left unary */
- { $$ = cat2_str(make_str("none,"), $3); }
+ { $$ = cat2_str(make_str("none,"), $3); }
| Typename ',' NONE /* right unary */
- { $$ = cat2_str($1, make_str(", none")); }
+ { $$ = cat2_str($1, make_str(", none")); }
+ ;
+
+any_operator:
+ all_Op
+ { $$ = $1; }
+ | ColId '.' any_operator
+ { $$ = cat_str(3, $1, make_str("."), $3); }
+ ;
+
+CreateCastStmt: CREATE CAST '(' Typename AS Typename ')'
+ WITH FUNCTION function_with_argtypes cast_context
+ { $$ = cat_str(6, make_str("create cast ("), $4, make_str("as"), $6, make_str(") with function"), $10); }
+ | CREATE CAST '(' Typename AS Typename ')'
+ WITHOUT FUNCTION cast_context
+ { $$ = cat_str(6, make_str("create cast ("), $4, make_str("as"), $6, make_str(") without function"), $10); }
+ ;
+
+cast_context: AS ASSIGNMENT { $$ = make_str("as assignment"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+
+DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_behavior
+ { $$ = cat_str(8, make_str("drop cast"), $3, make_str("("), $5, make_str("as"), $7, make_str(")"), $9); }
+ ;
+
+opt_if_exists: IF_P EXISTS { $$ = make_str("if exists"); }
+ | /* EMPTY */ { $$ = EMPTY; }
;
/*****************************************************************************
*
- * QUERY:
+ * QUERY:
*
- * REINDEX type <typename> [FORCE] [ALL]
+ * REINDEX type <typename> [FORCE] [ALL]
*
*****************************************************************************/
-ReindexStmt: REINDEX reindex_type name opt_force
- {
- $$ = cat_str(4, make_str("reindex"), $2, $3, $4);
- }
+ReindexStmt: REINDEX reindex_type qualified_name opt_force
+ { $$ = cat_str(4, make_str("reindex"), $2, $3, $4); }
+ | REINDEX SYSTEM_P name opt_force
+ { $$ = cat_str(3, make_str("reindex system"), $3, $4); }
+ | REINDEX DATABASE name opt_force
+ { $$ = cat_str(3, make_str("reindex database"), $3, $4); }
+ ;
+
+reindex_type: INDEX { $$ = make_str("index"); }
+ | TABLE { $$ = make_str("table"); }
+ ;
-reindex_type: INDEX { $$ = make_str("index"); }
- | TABLE { $$ = make_str("table"); }
- | DATABASE { $$ = make_str("database"); }
- ;
-opt_force: FORCE { $$ = make_str("force"); }
- | /* EMPTY */ { $$ = EMPTY; }
- ;
+opt_force: FORCE { $$ = make_str("force"); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
/*****************************************************************************
*
*
*****************************************************************************/
-RenameStmt: ALTER TABLE relation_expr RENAME opt_column opt_name TO name
- {
- $$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8);
- }
+RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
+ { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("rename to"), $7); }
+ | ALTER CONVERSION_P any_name RENAME TO name
+ { $$ = cat_str(4, make_str("alter conversion"), $3, make_str("rename to"), $6); }
+ | ALTER DATABASE database_name RENAME TO database_name
+ { $$ = cat_str(4, make_str("alter database"), $3, make_str("rename to"), $6); }
+ | ALTER FUNCTION function_with_argtypes RENAME TO name
+ { $$ = cat_str(4, make_str("alter function"), $3, make_str("rename to"), $6); }
+ | ALTER GROUP_P RoleId RENAME TO RoleId
+ { $$ = cat_str(4, make_str("alter group"), $3, make_str("rename to"), $6); }
+ | ALTER opt_procedural LANGUAGE name RENAME TO name
+ { $$ = cat_str(6, make_str("alter"), $2, make_str("language"), $4, make_str("rename to"), $7); }
+ | ALTER OPERATOR CLASS any_name USING access_method RENAME TO name
+ { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("rename to"), $9); }
+ | ALTER OPERATOR FAMILY any_name USING access_method RENAME TO name
+ { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("rename to"), $9); }
+ | ALTER SCHEMA name RENAME TO name
+ { $$ = cat_str(4, make_str("alter schema"), $3, make_str("rename to"), $6); }
+ | ALTER TABLE relation_expr RENAME TO name
+ { $$ = cat_str(4, make_str("alter table"), $3, make_str("rename to"), $6); }
+ | ALTER TABLE relation_expr SET SCHEMA name
+ { $$ = cat_str(4, make_str("alter table"), $3, make_str("set schema"), $6); }
+ | ALTER SEQUENCE relation_expr RENAME TO name
+ { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("rename to"), $6); }
+ | ALTER VIEW relation_expr RENAME TO name
+ { $$ = cat_str(4, make_str("alter view"), $3, make_str("rename to"), $6); }
+ | ALTER INDEX relation_expr RENAME TO name
+ { $$ = cat_str(4, make_str("alter index"), $3, make_str("rename to"), $6); }
+ | ALTER TABLE relation_expr RENAME opt_column name TO name
+ { $$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8); }
+ | ALTER TRIGGER name ON relation_expr RENAME TO name
+ { $$ = cat_str(6, make_str("alter trigger"), $3, make_str("on"), $5, make_str("rename to"), $8); }
+ | ALTER USER RoleId RENAME TO RoleId
+ { $$ = cat_str(4, make_str("alter user"), $3, make_str("rename to"), $6); }
+ | ALTER TABLESPACE name RENAME TO name
+ { $$ = cat_str(4, make_str("alter tablespace"), $3, make_str("rename to"), $6); }
+ | ALTER TEXT_P SEARCH PARSER any_name RENAME TO name
+ { $$ = cat_str(4, make_str("alter text search parser"), $5, make_str("rename to"), $8); }
+ | ALTER TEXT_P SEARCH DICTIONARY any_name RENAME TO name
+ { $$ = cat_str(4, make_str("alter text search dictionary"), $5, make_str("rename to"), $8); }
+ | ALTER TEXT_P SEARCH TEMPLATE any_name RENAME TO name
+ { $$ = cat_str(4, make_str("alter text search template"), $5, make_str("rename to"), $8); }
+ | ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name
+ { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("rename to"), $8); }
+ | ALTER TYPE_P any_name RENAME TO name
+ { $$ = cat_str(4, make_str("alter type"), $3, make_str("rename to"), $6); }
+ ;
+
+opt_column: COLUMN { $$ = make_str("column"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-opt_name: name { $$ = $1; }
- | /*EMPTY*/ { $$ = EMPTY; }
+/*****************************************************************************
+ *
+ * ALTER THING name SET SCHEMA name
+ *
+ *****************************************************************************/
+
+AlterObjectSchemaStmt:
+ ALTER AGGREGATE func_name aggr_args SET SCHEMA name
+ { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("set schema"), $7); }
+ | ALTER DOMAIN_P any_name SET SCHEMA name
+ { $$ = cat_str(4, make_str("alter domain"), $3, make_str("set schema"), $6); }
+ | ALTER FUNCTION function_with_argtypes SET SCHEMA name
+ { $$ = cat_str(4, make_str("alter function"), $3, make_str("set schema"), $6); }
+ | ALTER SEQUENCE relation_expr SET SCHEMA name
+ { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("set schema"), $6); }
+ | ALTER VIEW relation_expr SET SCHEMA name
+ { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("set schema"), $6); }
+ | ALTER TYPE_P any_name SET SCHEMA name
+ { $$ = cat_str(4, make_str("alter type"), $3, make_str("set schema"), $6); }
;
-opt_column: COLUMN { $$ = make_str("column"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+/*****************************************************************************
+ *
+ * ALTER THING name OWNER TO newname
+ *
+ *****************************************************************************/
+
+AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
+ { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("owner to"), $7); }
+ | ALTER CONVERSION_P any_name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter conversion"), $3, make_str("owner to"), $6); }
+ | ALTER DATABASE database_name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter database"), $3, make_str("owner to"), $6); }
+ | ALTER DOMAIN_P database_name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter domain"), $3, make_str("owner to"), $6); }
+ | ALTER FUNCTION function_with_argtypes OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter function"), $3, make_str("owner to"), $6); }
+ | ALTER opt_procedural LANGUAGE name OWNER TO RoleId
+ { $$ = cat_str(6, make_str("alter"), $2, make_str("language"), $4, make_str("owner to"), $7); }
+ | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
+ { $$ = cat_str(6, make_str("alter operator"), $3, make_str("("), $5, make_str(") owner to"), $9); }
+ | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId
+ { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("owner to"), $9); }
+ | ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleId
+ { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("owner to"), $9); }
+ | ALTER SCHEMA name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter schema"), $3, make_str("owner to"), $6); }
+ | ALTER TYPE_P any_name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter type"), $3, make_str("owner to"), $6); }
+ | ALTER TABLESPACE name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter tablespace"), $3, make_str("owner to"), $6); }
+ | ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter text search dictionary"), $5, make_str("owner to"), $8); }
+ | ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("owner to"), $8); }
;
/*****************************************************************************
*
- * QUERY: Define Rewrite Rule , Define Tuple Rule
- * Define Rule <old rules >
- *
- * only rewrite rule is supported -- ay 9/94
+ * QUERY: Define Rewrite Rule
*
*****************************************************************************/
-RuleStmt: CREATE RULE name AS
+RuleStmt: CREATE opt_or_replace RULE name AS
{ QueryIsRule=1; }
- ON event TO event_object where_clause
+ ON event TO qualified_name where_clause
DO opt_instead RuleActionList
- {
- QueryIsRule=0;
- $$ = cat_str(10, make_str("create rule"), $3, make_str("as on"), $7, make_str("to"), $9, $10, make_str("do"), $12, $13);
- }
+ {
+ QueryIsRule=0;
+ $$ = cat_str(12, make_str("create"), $2, make_str("rule"), $4, make_str("as on"), $8, make_str("to"), $10, $11, make_str("do"), $13, $14);
+ }
;
-RuleActionList: NOTHING { $$ = make_str("nothing"); }
- | RuleActionStmt { $$ = $1; }
- | '(' RuleActionMulti ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
- ;
+RuleActionList: NOTHING { $$ = make_str("nothing"); }
+ | RuleActionStmt { $$ = $1; }
+ | '(' RuleActionMulti ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ ;
/* the thrashing around here is to discard "empty" statements... */
RuleActionMulti: RuleActionMulti ';' RuleActionStmtOrEmpty
- { $$ = cat_str(3, $1, make_str(";"), $3); }
+ { $$ = cat_str(3, $1, make_str(";"), $3); }
| RuleActionStmtOrEmpty
- { $$ = cat2_str($1, make_str(";")); }
+ { $$ = cat2_str($1, make_str(";")); }
;
RuleActionStmt: SelectStmt
| InsertStmt
- | UpdateStmt
- | DeleteStmt
+ | UpdateStmt
+ | DeleteStmt
| NotifyStmt
- ;
-RuleActionStmtOrEmpty: RuleActionStmt { $$ = $1; }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
+ ;
-event_object: relation_name '.' attr_name
- {
- $$ = make3_str($1, make_str("."), $3);
- }
- | relation_name
- {
- $$ = $1;
- }
+RuleActionStmtOrEmpty: RuleActionStmt { $$ = $1; }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/* change me to select, update, etc. some day */
-event: SELECT { $$ = make_str("select"); }
+event: SELECT { $$ = make_str("select"); }
| UPDATE { $$ = make_str("update"); }
- | DELETE { $$ = make_str("delete"); }
+ | DELETE_P { $$ = make_str("delete"); }
| INSERT { $$ = make_str("insert"); }
- ;
+ | TRUNCATE { $$ = make_str("truncate"); }
+ ;
-opt_instead: INSTEAD { $$ = make_str("instead"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_instead: INSTEAD { $$ = make_str("instead"); }
+ | ALSO { $$ = make_str("also"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
+DropRuleStmt: DROP RULE name ON qualified_name opt_drop_behavior
+ { $$ = cat_str(5, make_str("drop rule"), $3, make_str("on"), $5, $6);}
+ | DROP RULE IF_P EXISTS name ON qualified_name opt_drop_behavior
+ { $$ = cat_str(5, make_str("drop rule if exists"), $5, make_str("on"), $7, $8);}
+ ;
/*****************************************************************************
*
* QUERY:
- * NOTIFY <relation_name> can appear both in rule bodies and
+ * NOTIFY <qualified_name> can appear both in rule bodies and
* as a query-level command
*
*****************************************************************************/
-NotifyStmt: NOTIFY relation_name
- {
- $$ = cat2_str(make_str("notify"), $2);
- }
+NotifyStmt: NOTIFY ColId
+ { $$ = cat2_str(make_str("notify"), $2); }
;
-ListenStmt: LISTEN relation_name
- {
- $$ = cat2_str(make_str("listen"), $2);
- }
-;
+ListenStmt: LISTEN ColId
+ { $$ = cat2_str(make_str("listen"), $2); }
+ ;
-UnlistenStmt: UNLISTEN relation_name
- {
- $$ = cat2_str(make_str("unlisten"), $2);
- }
+UnlistenStmt: UNLISTEN ColId
+ { $$ = cat2_str(make_str("unlisten"), $2); }
| UNLISTEN '*'
- {
- $$ = make_str("unlisten *");
- }
-;
+ { $$ = make_str("unlisten *"); }
+ ;
+
/*****************************************************************************
*
- * Transactions:
+ * Transactions:
*
* BEGIN / COMMIT / ROLLBACK
- * (also older versions END / ABORT)
+ * (also older versions END / ABORT)
*
*****************************************************************************/
-TransactionStmt: ABORT_TRANS opt_trans { $$ = make_str("rollback"); }
- | BEGIN_TRANS opt_trans { $$ = make_str("begin transaction"); }
- | COMMIT opt_trans { $$ = make_str("commit"); }
- | COMMIT opt_trans opt_chain { $$ = cat2_str(make_str("commit"), $3); }
- | END_TRANS opt_trans { $$ = make_str("commit"); }
- | ROLLBACK opt_trans { $$ = make_str("rollback"); }
- | ROLLBACK opt_trans opt_chain { $$ = cat2_str(make_str("rollback"), $3); }
- ;
+TransactionStmt: ABORT_P opt_transaction { $$ = make_str("rollback"); }
+ | BEGIN_P opt_transaction transaction_mode_list_or_empty { $$ = cat2_str(make_str("begin transaction"), $3); }
+ | START TRANSACTION transaction_mode_list_or_empty { $$ = cat2_str(make_str("start transaction"), $3); }
+ | COMMIT opt_transaction { $$ = make_str("commit"); }
+ | END_P opt_transaction { $$ = make_str("commit"); }
+ | ROLLBACK opt_transaction { $$ = make_str("rollback"); }
+ | SAVEPOINT ColId { $$ = cat2_str(make_str("savepoint"), $2); }
+ | RELEASE SAVEPOINT ColId { $$ = cat2_str(make_str("release savepoint"), $3); }
+ | RELEASE ColId { $$ = cat2_str(make_str("release"), $2); }
+ | ROLLBACK opt_transaction TO SAVEPOINT ColId { $$ = cat_str(4, make_str("rollback"), $2, make_str("to savepoint"), $5); }
+ | ROLLBACK opt_transaction TO ColId { $$ = cat_str(4, make_str("rollback"), $2, make_str("to"), $4); }
+ | PREPARE TRANSACTION StringConst { $$ = cat2_str(make_str("prepare transaction"), $3); }
+ | COMMIT PREPARED StringConst { $$ = cat2_str(make_str("commit prepared"), $3); }
+ | ROLLBACK PREPARED StringConst { $$ = cat2_str(make_str("rollback prepared"), $3); }
+ ;
+
+opt_transaction: WORK { $$ = EMPTY; }
+ | TRANSACTION { $$ = EMPTY; }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
-opt_trans: WORK { $$ = EMPTY; }
- | TRANSACTION { $$ = EMPTY; }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
+transaction_mode_item:
+ ISOLATION LEVEL iso_level
+ { $$ = cat2_str(make_str("isolation level"), $3); }
+ | READ ONLY { $$ = make_str("read only"); }
+ | READ WRITE { $$ = make_str("read write"); }
+ ;
-opt_chain: AND NO CHAIN { $$ = make_str("and no chain"); }
- | AND CHAIN {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported COMMIT/CHAIN will be passed to backend");
+transaction_mode_list:
+ transaction_mode_item { $$ = $1; }
+ | transaction_mode_list ',' transaction_mode_item { $$ = cat_str(3, $1, make_str(","), $3); }
+ | transaction_mode_list transaction_mode_item { $$ = cat_str(3, $1, make_str(" "), $2); }
+ ;
- $$ = make_str("and chain");
- }
- ;
+transaction_mode_list_or_empty:
+ transaction_mode_list { $$ = $1; }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
/*****************************************************************************
*
- * QUERY:
- * define view <viewname> '('target-list ')' [where <quals> ]
+ * QUERY:
+ * CREATE [ OR REPLACE ] [ TEMP ] VIEW <viewname> '('target-list ')'
+ * AS <query> [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
*
*****************************************************************************/
-ViewStmt: CREATE VIEW name opt_column_list AS SelectStmt
- {
- $$ = cat_str(5, make_str("create view"), $3, $4, make_str("as"), $6);
- }
+ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list AS SelectStmt opt_check_option
+ { $$ = cat_str(8, make_str("create"), $2, make_str("view"), $4, $5, make_str("as"), $7, $8); }
+ | CREATE OR REPLACE OptTemp VIEW qualified_name opt_column_list AS SelectStmt opt_check_option
+ { $$ = cat_str(8, make_str("create or replace"), $4, make_str("view"), $6, $7, make_str("as"), $9, $10); }
;
+/*
+ * We use merged tokens here to avoid creating shift/reduce conflicts against
+ * a whole lot of other uses of WITH.
+ */
+opt_check_option:
+ WITH_CHECK OPTION
+ {
+ mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
+ $$ = EMPTY;
+ }
+ | WITH_CASCADED CHECK OPTION
+ {
+ mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
+ $$ = EMPTY;
+ }
+ | WITH_LOCAL CHECK OPTION
+ {
+ mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
+ $$ = EMPTY;
+ }
+ | /* EMPTY */
+ { $$ = EMPTY; }
+ ;
/*****************************************************************************
*
*****************************************************************************/
LoadStmt: LOAD file_name
- {
- $$ = cat2_str(make_str("load"), $2);
- }
+ { $$ = cat2_str(make_str("load"), $2); }
;
*****************************************************************************/
CreatedbStmt: CREATE DATABASE database_name WITH createdb_opt_list
- {
- $$ = cat_str(4, make_str("create database"), $3, make_str("with"), $5);
- }
+ { $$ = cat_str(4, make_str("create database"), $3, make_str("with"), $5); }
| CREATE DATABASE database_name
- {
- $$ = cat2_str(make_str("create database"), $3);
- }
+ { $$ = cat2_str(make_str("create database"), $3); }
;
-createdb_opt_list: createdb_opt_item
- { $$ = $1; }
- | createdb_opt_list createdb_opt_item
- { $$ = cat2_str($1, $2); }
- ;
-
-createdb_opt_item: LOCATION opt_equal StringConst { $$ = cat_str(3,make_str("location"), $2, $3); }
- | LOCATION opt_equal DEFAULT { $$ = cat_str(3, make_str("location"), $2, make_str("default")); }
- | TEMPLATE opt_equal name { $$ = cat_str(3, make_str("template"), $2, $3); }
- | TEMPLATE opt_equal DEFAULT { $$ = cat_str(3, make_str("template"), $2, make_str("default")); }
- | ENCODING opt_equal PosIntStringConst
- {
- $$ = cat_str(3, make_str("encoding"), $2, $3);
- }
+createdb_opt_list: createdb_opt_item
+ { $$ = $1; }
+ | createdb_opt_list createdb_opt_item
+ { $$ = cat2_str($1, $2); }
+ ;
+
+createdb_opt_item: TABLESPACE opt_equal name
+ { $$ = cat_str(3,make_str("tablespace"), $2, $3); }
+ | TABLESPACE opt_equal DEFAULT
+ { $$ = cat_str(3, make_str("tablespace"), $2, make_str("default")); }
+ | LOCATION opt_equal StringConst
+ { $$ = cat_str(3,make_str("location"), $2, $3); }
+ | LOCATION opt_equal DEFAULT
+ { $$ = cat_str(3, make_str("location"), $2, make_str("default")); }
+ | TEMPLATE opt_equal name
+ { $$ = cat_str(3, make_str("template"), $2, $3); }
+ | TEMPLATE opt_equal DEFAULT
+ { $$ = cat_str(3, make_str("template"), $2, make_str("default")); }
+ | ENCODING opt_equal PosIntStringConst
+ { $$ = cat_str(3, make_str("encoding"), $2, $3); }
| ENCODING opt_equal DEFAULT
- {
- $$ = cat_str(3, make_str("encoding"), $2, make_str("default"));
- }
- | OWNER opt_equal name
- {
- $$ = cat_str(3, make_str("owner"), $2, $3);
- }
+ { $$ = cat_str(3, make_str("encoding"), $2, make_str("default")); }
+ | CONNECTION LIMIT opt_equal PosIntConst
+ { $$ = cat_str(3, make_str("connection limit"), $3, $4); }
+ | OWNER opt_equal name
+ { $$ = cat_str(3, make_str("owner"), $2, $3); }
| OWNER opt_equal DEFAULT
- {
- $$ = cat_str(3, make_str("owner"), $2, make_str("default"));
- }
- ;
+ { $$ = cat_str(3, make_str("owner"), $2, make_str("default")); }
+ ;
+
+opt_equal: '=' { $$ = make_str("="); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
-opt_equal: '=' { $$ = make_str("="); }
- | /* EMPTY */ { $$ = EMPTY; }
- ;
/*****************************************************************************
*
- * ALTER DATABASE
+ * ALTER DATABASE
*
*
*****************************************************************************/
-AlterDatabaseSetStmt: ALTER DATABASE database_name VariableSetStmt
- {
- $$ = cat_str(3, make_str("alter database"), $3, $4);
- }
- | ALTER DATABASE database_name VariableResetStmt
- {
- $$ = cat_str(3, make_str("alter database"), $3, $4);
- }
- ;
-
+AlterDatabaseStmt: ALTER DATABASE database_name opt_with alterdb_opt_list
+ { $$ = cat_str(4, make_str("alter database"), $3, $4, $5); }
+ ;
+
+AlterDatabaseSetStmt: ALTER DATABASE database_name SetResetClause
+ { $$ = cat_str(3, make_str("alter database"), $3, $4); }
+ ;
+
+alterdb_opt_list:
+ alterdb_opt_list alterdb_opt_item { $$ = cat2_str($1, $2);}
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+alterdb_opt_item:
+ CONNECTION LIMIT opt_equal PosIntConst { $$ = cat_str(3, make_str("connection limit"), $3, $4); }
+ ;
+
/*****************************************************************************
*
- * DROP DATABASE
+ * DROP DATABASE [ IF EXISTS ]
*
*
*****************************************************************************/
-DropdbStmt: DROP DATABASE database_name
- {
- $$ = cat2_str(make_str("drop database"), $3);
- }
+DropdbStmt: DROP DATABASE database_name
+ { $$ = cat2_str(make_str("drop database"), $3); }
+ | DROP DATABASE IF_P EXISTS database_name
+ { $$ = cat2_str(make_str("drop database if exists"), $5); }
;
/*****************************************************************************
*
- * QUERY:
- * cluster <index_name> on <relation_name>
+ * Manipulate a domain
*
*****************************************************************************/
-ClusterStmt: CLUSTER index_name ON relation_name
- {
- $$ = cat_str(4, make_str("cluster"), $2, make_str("on"), $4);
- }
- ;
+CreateDomainStmt: CREATE DOMAIN_P any_name opt_as Typename ColQualList
+ {
+ $$ = cat_str(5, make_str("create domain"), $3, $4, $5, $6);
+ }
+ ;
+
+AlterDomainStmt:
+ ALTER DOMAIN_P any_name alter_column_default
+ { $$ = cat_str(3, make_str("alter domain"), $3, $4); }
+ | ALTER DOMAIN_P any_name DROP NOT NULL_P
+ { $$ = cat_str(3, make_str("alter domain"), $3, make_str("drop not null")); }
+ | ALTER DOMAIN_P any_name SET NOT NULL_P
+ { $$ = cat_str(3, make_str("alter domain"), $3, make_str("set not null")); }
+ | ALTER DOMAIN_P any_name ADD_P TableConstraint
+ { $$ = cat_str(4, make_str("alter domain"), $3, make_str("add"), $5); }
+ | ALTER DOMAIN_P any_name DROP CONSTRAINT name opt_drop_behavior
+ { $$ = cat_str(5, make_str("alter domain"), $3, make_str("drop constraint"), $6, $7); }
+ ;
+
+opt_as: AS {$$ = make_str("as"); }
+ | /* EMPTY */ {$$ = EMPTY; }
+ ;
+
+AlterTSDictionaryStmt:
+ ALTER TEXT_P SEARCH DICTIONARY any_name definition
+ { $$ = cat_str(3, make_str("alter text search dictionary"), $5, $6); }
+ ;
+
+AlterTSConfigurationStmt:
+ ALTER TEXT_P SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list WITH any_name_list
+ { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("add mapping for"), $9, make_str("with"), $11); }
+ | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list WITH any_name_list
+ { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("alter mapping for"), $9, make_str("with"), $11); }
+ | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name WITH any_name
+ { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("alter mapping replace"), $9, make_str("with"), $11); }
+ | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name WITH any_name
+ { $$ = cat_str(8, make_str("alter text search configuration"), $5, make_str("alter mapping for"), $9, make_str("replace"), $11, make_str("with"), $13); }
+ | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list
+ { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("drop mapping for"), $9); }
+ | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list
+ { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("drop mapping if exists for"), $11); }
+ ;
+
+CreateConversionStmt:
+ CREATE opt_default CONVERSION_P any_name FOR StringConst
+ TO StringConst FROM any_name
+ { $$ = cat_str(10, make_str("create"), $2, make_str("conversion"), $4, make_str("for"), $6, make_str("to"), $8, make_str("from"), $10); }
+ ;
+/*****************************************************************************
+ *
+ * QUERY:
+ * cluster <index_name> on <qualified_name>
+ * cluster <qualified_name>
+ * cluster
+ *
+ *****************************************************************************/
+
+ClusterStmt: CLUSTER qualified_name cluster_index_specification
+ { $$ = cat_str(3,make_str("cluster"), $2, $3); }
+ | CLUSTER
+ { $$ = make_str("cluster"); }
+ | CLUSTER qualified_name ON qualified_name
+ { $$ = cat_str(4, make_str("cluster"), $2, make_str("on"), $4); }
+ ;
+
+cluster_index_specification:
+ USING index_name { $$ = cat2_str(make_str("using"), $2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
/*****************************************************************************
*
*****************************************************************************/
VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
- {
- $$ = cat_str(4, make_str("vacuum"), $2, $3, $4);
- }
- | VACUUM opt_full opt_freeze opt_verbose relation_name
- {
- $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5);
- }
+ { $$ = cat_str(4, make_str("vacuum"), $2, $3, $4); }
+ | VACUUM opt_full opt_freeze opt_verbose qualified_name
+ { $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5); }
| VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
- {
- $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5);
- }
+ { $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5); }
;
AnalyzeStmt: analyze_keyword opt_verbose
- {
- $$ = cat_str(2, $1, $2);
- }
- | analyze_keyword opt_verbose relation_name opt_name_list
- {
- $$ = cat_str(4, $1, $2, $3, $4);
- }
+ { $$ = cat_str(2, $1, $2); }
+ | analyze_keyword opt_verbose qualified_name opt_name_list
+ { $$ = cat_str(4, $1, $2, $3, $4); }
;
-analyze_keyword: ANALYZE { $$ = make_str("analyze"); }
- | ANALYSE { $$ = make_str("analyse"); }
+analyze_keyword: ANALYZE { $$ = make_str("analyze"); }
+ | ANALYSE { $$ = make_str("analyse"); }
;
-opt_verbose: VERBOSE { $$ = make_str("verbose"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_verbose: VERBOSE { $$ = make_str("verbose"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-opt_full: FULL { $$ = make_str("full"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_full: FULL { $$ = make_str("full"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-opt_freeze: FREEZE { $$ = make_str("freeze"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_freeze: FREEZE { $$ = make_str("freeze"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-opt_name_list: '(' name_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_name_list: '(' name_list ')'
+ { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
;
*
*****************************************************************************/
-ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
- {
- $$ = cat_str(3, make_str("explain"), $2, $3);
- }
- | EXPLAIN analyze_keyword opt_verbose OptimizableStmt
- {
- $$ = cat_str(4, make_str("explain"), $2, $3, $4);
- }
+ExplainStmt: EXPLAIN opt_analyze opt_verbose ExplainableStmt
+ { $$ = cat_str(4, make_str("explain"), $2, $3, $4); }
;
+ExplainableStmt:
+ SelectStmt
+ | InsertStmt
+ | UpdateStmt
+ | DeleteStmt
+ | DeclareCursorStmt
+ | ExecuteStmt
+ ;
+opt_analyze:
+ analyze_keyword { $$ = $1; }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
-/*****************************************************************************
- * *
- * 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 *
- * *
- *****************************************************************************/
+PrepareStmt: PREPARE prepared_name prep_type_clause AS PreparableStmt
+ {
+ $$.name = $2;
+ $$.type = $3;
+ $$.stmt = cat_str(3, make_str("\""), $5, make_str("\""));
+ }
+ | PREPARE prepared_name FROM execstring /* ECPG addon */
+ {
+ $$.name = $2;
+ $$.type = NULL;
+ $$.stmt = $4;
+ }
+ ;
-OptimizableStmt: SelectStmt
- | CursorStmt
- | UpdateStmt
+PreparableStmt:
+ SelectStmt
| InsertStmt
+ | UpdateStmt
| DeleteStmt
;
+prep_type_clause: '(' type_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+ExecuteStmt: EXECUTE prepared_name execute_param_clause execute_rest /* execute_rest is an ecpg addon */
+ {
+ /* $$ = cat_str(3, make_str("ECPGprepared_statement("), connection, $2, make_str("__LINE__)"));*/
+ $$ = $2;
+ }
+ | CREATE OptTemp TABLE create_as_target AS
+ EXECUTE prepared_name execute_param_clause
+ { $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4, make_str("as execute"), $7, $8); }
+ ;
+
+execute_param_clause: '(' expr_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+DeallocateStmt: DEALLOCATE prepared_name { $$ = $2; }
+ | DEALLOCATE PREPARE prepared_name { $$ = $3; }
+ | DEALLOCATE ALL { $$ = make_str("all"); }
+ | DEALLOCATE PREPARE ALL { $$ = make_str("all"); }
+ ;
/*****************************************************************************
*
*
*****************************************************************************/
-/* 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/reduce
- * 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
- {
- $$ = cat_str(3, make_str("insert into"), $3, $4);
- }
+InsertStmt: INSERT INTO qualified_name insert_rest returning_clause
+ { $$ = cat_str(4, make_str("insert into"), $3, $4, $5); }
;
-insert_rest: VALUES '(' target_list ')'
- {
- $$ = cat_str(3, make_str("values("), $3, make_str(")"));
- }
+insert_rest:
+ SelectStmt
+ { $$ = $1; }
+ | '(' insert_column_list ')' SelectStmt
+ { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
| DEFAULT VALUES
- {
- $$ = make_str("default values");
- }
- | SelectStmt
- {
- $$ = $1;
- }
- | '(' columnList ')' VALUES '(' target_list ')'
- {
- $$ = cat_str(5, make_str("("), $2, make_str(") values ("), $6, make_str(")"));
- }
- | '(' columnList ')' SelectStmt
- {
- $$ = cat_str(4, make_str("("), $2, make_str(")"), $4);
- }
+ { $$ = make_str("default values"); }
;
-opt_column_list: '(' columnList ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
- | /*EMPTY*/ { $$ = EMPTY; }
+insert_column_list: insert_column_list ',' insert_column_item
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ | insert_column_item
+ { $$ = $1; }
;
-columnList:
- columnList ',' columnElem
- { $$ = cat_str(3, $1, make_str(","), $3); }
- | columnElem
- { $$ = $1; }
+insert_column_item: ColId opt_indirection
+ { $$ = cat2_str($1, $2); }
;
-columnElem: ColId opt_indirection
- {
- $$ = cat2_str($1, $2);
- }
+returning_clause: RETURNING target_list { $$ = cat2_str(make_str("returning"), $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
;
-
/*****************************************************************************
*
* QUERY:
*
*****************************************************************************/
-DeleteStmt: DELETE FROM relation_expr where_clause
- {
- $$ = cat_str(3, make_str("delete from"), $3, $4);
- }
+DeleteStmt: DELETE_P FROM relation_expr_opt_alias using_clause where_or_current_clause returning_clause
+ { $$ = cat_str(5, make_str("delete from"), $3, $4, $5, $6); }
;
-LockStmt: LOCK_P opt_table relation_name_list opt_lock
- {
- $$ = cat_str(4, make_str("lock"), $2, $3, $4);
- }
+using_clause: USING from_list { $$ = cat2_str(make_str("using"), $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+LockStmt: LOCK_P opt_table qualified_name_list opt_lock opt_nowait
+ { $$ = cat_str(5, make_str("lock"), $2, $3, $4, $5); }
;
-opt_lock: IN lock_type MODE { $$ = cat_str(3, make_str("in"), $2, make_str("mode")); }
- | /*EMPTY*/ { $$ = EMPTY;}
- ;
+opt_lock: IN_P lock_type MODE
+ { $$ = cat_str(3, make_str("in"), $2, make_str("mode")); }
+ | /*EMPTY*/
+ { $$ = EMPTY;}
+ ;
-lock_type: ACCESS SHARE { $$ = make_str("access share"); }
+lock_type: ACCESS SHARE { $$ = make_str("access share"); }
| ROW SHARE { $$ = make_str("access share"); }
| ROW EXCLUSIVE { $$ = make_str("row exclusive"); }
| SHARE UPDATE EXCLUSIVE { $$ = make_str("share update exclusive"); }
| ACCESS EXCLUSIVE { $$ = make_str("access exclusive"); }
;
+opt_nowait: NOWAIT { $$ = make_str("nowait"); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
/*****************************************************************************
*
* QUERY:
*
*****************************************************************************/
-UpdateStmt: UPDATE relation_expr
- SET update_target_list
- from_clause
- where_clause
- {
- $$ = cat_str(6, make_str("update"), $2, make_str("set"), $4, $5, $6);
- }
+UpdateStmt: UPDATE relation_expr_opt_alias
+ SET set_clause_list
+ from_clause
+ where_or_current_clause
+ returning_clause
+ {$$ = cat_str(7, make_str("update"), $2, make_str("set"), $4, $5, $6, $7); }
+ ;
+
+set_clause_list:
+ set_clause { $$ = $1; }
+ | set_clause_list ',' set_clause { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+set_clause:
+ single_set_clause { $$ = $1; }
+ | multiple_set_clause { $$ = $1; }
;
+single_set_clause:
+ set_target '=' ctext_expr { $$ = cat_str(3, $1, make_str("="), $3); };
+
+multiple_set_clause:
+ '(' set_target_list ')' '=' ctext_row { $$ = cat_str(4, make_str("("), $2, make_str(")="), $5); };
+
+set_target:
+ ColId opt_indirection { $$ = cat2_str($1, $2); };
+
+set_target_list:
+ set_target { $$ = $1; }
+ | set_target_list ',' set_target { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
/*****************************************************************************
*
* CURSOR STATEMENTS
*
*****************************************************************************/
-CursorStmt: DECLARE name opt_cursor CURSOR FOR 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);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
- }
-
- this = (struct cursor *) mm_alloc(sizeof(struct cursor));
-
- /* initial definition */
- this->next = cur;
- this->name = $2;
- this->connection = connection;
- this->command = cat_str(5, make_str("declare"), mm_strdup($2), $3, make_str("cursor for"), $6);
- this->argsinsert = argsinsert;
- this->argsresult = argsresult;
- argsinsert = argsresult = NULL;
-
- cur = this;
-
- $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
- }
+DeclareCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
+ {
+ struct cursor *ptr, *this;
+
+ for (ptr = cur; ptr != NULL; ptr = ptr->next)
+ {
+ if (strcmp($2, ptr->name) == 0)
+ /* re-definition is a bug */
+ mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" already defined", $2);
+ }
+
+ this = (struct cursor *) mm_alloc(sizeof(struct cursor));
+
+ /* initial definition */
+ this->next = cur;
+ this->name = $2;
+ this->connection = connection;
+ this->opened = false;
+ this->command = cat_str(7, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for"), $7);
+ this->argsinsert = argsinsert;
+ this->argsresult = argsresult;
+ argsinsert = argsresult = NULL;
+ cur = this;
+
+ if (INFORMIX_MODE)
+ $$ = cat_str(5, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("/*"), mm_strdup(this->command), make_str("*/"));
+ else
+ $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
+ }
;
-opt_cursor: BINARY { $$ = make_str("binary"); }
- | INSENSITIVE { $$ = make_str("insensitive"); }
- | SCROLL { $$ = make_str("scroll"); }
- | INSENSITIVE SCROLL { $$ = make_str("insensitive scroll"); }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
+cursor_options: /* EMPTY */ { $$ = EMPTY; }
+ | cursor_options BINARY { $$ = cat2_str($1, make_str("binary")); }
+ | cursor_options INSENSITIVE { $$ = cat2_str($1, make_str("insensitive")); }
+ | cursor_options SCROLL { $$ = cat2_str($1, make_str("scroll")); }
+ | cursor_options NO SCROLL { $$ = cat2_str($1, make_str("no scroll")); }
+ ;
+
+opt_hold: /* EMPTY */
+ {
+ if (compat == ECPG_COMPAT_INFORMIX_SE && autocommit == true)
+ $$ = make_str("with hold");
+ else
+ $$ = EMPTY;
+ }
+ | WITH HOLD { $$ = make_str("with hold"); }
+ | WITHOUT HOLD { $$ = make_str("without hold"); }
+ ;
/*****************************************************************************
*
*
*****************************************************************************/
-SelectStmt: select_no_parens %prec UMINUS
- { $$ = $1; }
- | select_with_parens %prec UMINUS
- { $$ = $1; }
- ;
+SelectStmt: select_no_parens %prec UMINUS
+ { $$ = $1; }
+ | select_with_parens %prec UMINUS
+ { $$ = $1; }
+ ;
-select_with_parens: '(' select_no_parens ')'
- {
- $$ = cat_str(3, make_str("("), $2, make_str(")"));
- }
- | '(' select_with_parens ')'
- {
- $$ = cat_str(3, make_str("("), $2, make_str(")"));
- }
- ;
-
-select_no_parens: simple_select
- {
- $$ = $1;
- }
- | select_clause sort_clause opt_for_update_clause opt_select_limit
- {
- $$ = cat_str(4, $1, $2, $3, $4);
- }
- | select_clause for_update_clause opt_select_limit
- {
- $$ = cat_str(3, $1, $2, $3);
- }
- | select_clause select_limit
- {
- $$ = cat2_str($1, $2);
- }
+select_with_parens: '(' select_no_parens ')'
+ { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | '(' select_with_parens ')'
+ { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ ;
-select_clause: simple_select
- {
- $$ = $1;
+select_no_parens: simple_select
+ { $$ = $1; }
+ | select_clause sort_clause
+ { $$ = cat2_str($1, $2); }
+ | select_clause opt_sort_clause for_locking_clause opt_select_limit
+ { $$ = cat_str(4, $1, $2, $3, $4); }
+ | select_clause opt_sort_clause select_limit opt_for_locking_clause
+ { $$ = cat_str(4, $1, $2, $3, $4); }
+ ;
- }
- | select_with_parens
- {
- $$ = $1;
- }
+select_clause: simple_select { $$ = $1; }
+ | select_with_parens { $$ = $1; }
;
-simple_select: SELECT opt_distinct target_list
- into_clause from_clause where_clause
- group_clause having_clause
- {
- $$ = cat_str(8, make_str("select"), $2, $3, $4, $5, $6, $7, $8);
- }
- | select_clause UNION opt_all select_clause
- {
- $$ = cat_str(4, $1, make_str("union"), $3, $4);
- }
- | select_clause INTERSECT opt_all select_clause
- {
- $$ = cat_str(4, $1, make_str("intersect"), $3, $4);
- }
- | select_clause EXCEPT opt_all select_clause
- {
- $$ = cat_str(4, $1, make_str("except"), $3, $4);
- }
+simple_select: SELECT opt_distinct target_list
+ into_clause from_clause where_clause
+ group_clause having_clause
+ { $$ = cat_str(8, make_str("select"), $2, $3, $4, $5, $6, $7, $8); }
+ | values_clause
+ { $$ = $1; }
+ | select_clause UNION opt_all select_clause
+ { $$ = cat_str(4, $1, make_str("union"), $3, $4); }
+ | select_clause INTERSECT opt_all select_clause
+ { $$ = cat_str(4, $1, make_str("intersect"), $3, $4); }
+ | select_clause EXCEPT opt_all select_clause
+ { $$ = cat_str(4, $1, make_str("except"), $3, $4); }
;
-into_clause: INTO OptTempTableName {
- FoundInto = 1;
- $$= cat2_str(make_str("into"), $2);
- }
- | ecpg_into { $$ = EMPTY; }
- | /*EMPTY*/ { $$ = EMPTY; }
+into_clause: INTO OptTempTableName
+ {
+ FoundInto = 1;
+ $$= cat2_str(make_str("into"), $2);
+ }
+ | ecpg_into { $$ = EMPTY; }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/*
* The result is a cons cell (not a true list!) containing
* a boolean and a table name.
*/
-OptTempTableName: TEMPORARY opt_table relation_name
- {
- $$ = cat_str(3, make_str("temporary"), $2, $3);
- }
- | TEMP opt_table relation_name
- {
- $$ = cat_str(3, make_str("temp"), $2, $3);
- }
- | LOCAL TEMPORARY opt_table relation_name
- {
- $$ = cat_str(3, make_str("local temporary"), $3, $4);
- }
- | LOCAL TEMP opt_table relation_name
- {
- $$ = cat_str(3, make_str("local temp"), $3, $4);
- }
- | GLOBAL TEMPORARY opt_table relation_name
- {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
- $$ = cat_str(3, make_str("global temporary"), $3, $4);
- }
- | GLOBAL TEMP opt_table relation_name
- {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
- $$ = cat_str(3, make_str("global temp"), $3, $4);
- }
- | TABLE relation_name
- {
- $$ = cat2_str(make_str("table"), $2);
- }
- | relation_name
- {
- $$ = $1;
- }
- ;
+OptTempTableName: TEMPORARY opt_table qualified_name
+ { $$ = cat_str(3, make_str("temporary"), $2, $3); }
+ | TEMP opt_table qualified_name
+ { $$ = cat_str(3, make_str("temp"), $2, $3); }
+ | LOCAL TEMPORARY opt_table qualified_name
+ { $$ = cat_str(3, make_str("local temporary"), $3, $4); }
+ | LOCAL TEMP opt_table qualified_name
+ { $$ = cat_str(3, make_str("local temp"), $3, $4); }
+ | GLOBAL TEMPORARY opt_table qualified_name
+ { $$ = cat_str(3, make_str("global temporary"), $3, $4); }
+ | GLOBAL TEMP opt_table qualified_name
+ { $$ = cat_str(3, make_str("global temp"), $3, $4); }
+ | TABLE qualified_name
+ { $$ = cat2_str(make_str("table"), $2); }
+ | qualified_name
+ { $$ = $1; }
+ ;
-opt_table: TABLE { $$ = make_str("table"); }
+opt_table: TABLE { $$ = make_str("table"); }
| /*EMPTY*/ { $$ = EMPTY; }
;
-opt_all: ALL { $$ = make_str("all"); }
+opt_all: ALL { $$ = make_str("all"); }
| /*EMPTY*/ { $$ = EMPTY; }
;
-opt_distinct: DISTINCT { $$ = make_str("distinct"); }
- | DISTINCT ON '(' expr_list ')' { $$ = cat_str(3, make_str("distinct on ("), $4, make_str(")")); }
- | ALL { $$ = make_str("all"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_distinct: DISTINCT
+ { $$ = make_str("distinct"); }
+ | DISTINCT ON '(' expr_list ')'
+ { $$ = cat_str(3, make_str("distinct on ("), $4, make_str(")")); }
+ | ALL
+ { $$ = make_str("all"); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
;
-sort_clause: ORDER BY sortby_list {
- $$ = cat2_str(make_str("order by"), $3);
- }
+opt_sort_clause: sort_clause { $$ = $1; }
+ | /* EMPTY */ { $$ = EMPTY; }
;
-sortby_list: sortby { $$ = $1; }
- | sortby_list ',' sortby { $$ = cat_str(3, $1, make_str(","), $3); }
+sort_clause: ORDER BY sortby_list
+ { $$ = cat2_str(make_str("order by"), $3); }
;
-sortby: a_expr OptUseOp
- {
- $$ = cat2_str($1, $2);
- }
+sortby_list: sortby { $$ = $1; }
+ | sortby_list ',' sortby { $$ = cat_str(3, $1, make_str(","), $3); }
;
-OptUseOp: USING all_Op { $$ = cat2_str(make_str("using"), $2); }
- | ASC { $$ = make_str("asc"); }
- | DESC { $$ = make_str("desc"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+sortby: a_expr USING qual_all_Op opt_nulls_order
+ { $$ = cat_str(4, $1, make_str("using"), $3, $4); }
+ | a_expr opt_asc_desc opt_nulls_order
+ { $$ = cat_str(3, $1, $2, $3); }
;
-select_limit: LIMIT select_limit_value OFFSET select_offset_value
- { $$ = cat_str(4, make_str("limit"), $2, make_str("offset"), $4); }
+select_limit: LIMIT select_limit_value OFFSET select_offset_value
+ { $$ = cat_str(4, make_str("limit"), $2, make_str("offset"), $4); }
| OFFSET select_offset_value LIMIT select_limit_value
- { $$ = cat_str(4, make_str("offset"), $2, make_str("limit"), $4); }
- | LIMIT select_limit_value
- { $$ = cat2_str(make_str("limit"), $2); }
- | OFFSET select_offset_value
- { $$ = cat2_str(make_str("offset"), $2); }
+ { $$ = cat_str(4, make_str("offset"), $2, make_str("limit"), $4); }
+ | LIMIT select_limit_value
+ { $$ = cat2_str(make_str("limit"), $2); }
+ | OFFSET select_offset_value
+ { $$ = cat2_str(make_str("offset"), $2); }
| LIMIT select_limit_value ',' select_offset_value
- { mmerror(PARSE_ERROR, ET_WARNING, "No longer supported LIMIT #,# syntax passed to backend."); }
- ;
+ {
+ mmerror(PARSE_ERROR, ET_WARNING, "no longer supported LIMIT #,# syntax passed to backend");
+ $$ = cat_str(4, make_str("limit"), $2, make_str(","), $4);
+ }
+ ;
-opt_select_limit: select_limit { $$ = $1; }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
+opt_select_limit: select_limit { $$ = $1; }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
-select_limit_value: PosIntConst {
- if (atoi($1) < 0)
- mmerror(PARSE_ERROR, ET_ERROR, "LIMIT must not be negative");
- $$ = $1;
- }
- | ALL { $$ = make_str("all"); }
- | PARAM { $$ = make_name(); }
- ;
+select_limit_value: a_expr { $$ = $1; }
+ | ALL { $$ = make_str("all"); }
+ ;
-select_offset_value: PosIntConst {
- if (atoi($1) < 0)
- mmerror(PARSE_ERROR, ET_ERROR, "OFFSET must not be negative");
- $$ = $1;
- }
- | PARAM { $$ = make_name(); }
- ;
+select_offset_value: a_expr { $$ = $1; }
+ ;
/*
* jimmy bell-style recursive queries aren't supported in the
* ...however, recursive addattr and rename supported. make special
* cases for these.
*/
-relation_name_list: name_list { $$ = $1; };
+group_clause: GROUP_P BY expr_list
+ { $$ = cat2_str(make_str("group by"), $3); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
+ ;
-name_list: name
- { $$ = $1; }
- | name_list ',' name
- { $$ = cat_str(3, $1, make_str(","), $3); }
+having_clause: HAVING a_expr
+ { $$ = cat2_str(make_str("having"), $2); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
;
-group_clause: GROUP BY expr_list { $$ = cat2_str(make_str("group by"), $3); }
- | /*EMPTY*/ { $$ = EMPTY; }
+for_locking_clause:
+ for_locking_items { $$ = $1; }
+ | FOR READ ONLY { $$ = make_str("for read only");}
;
-having_clause: HAVING a_expr
- {
- $$ = cat2_str(make_str("having"), $2);
- }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_for_locking_clause:
+ for_locking_clause { $$ = $1; }
+ | /* EMPTY */ { $$ = EMPTY; }
;
-for_update_clause: FOR UPDATE update_list
- {
- $$ = make_str("for update");
- }
- | FOR READ ONLY
- {
- $$ = make_str("for read only");
- }
+for_locking_items:
+ for_locking_item { $$ = $1; }
+ | for_locking_items for_locking_item { $$ = cat2_str($1, $2); }
;
-opt_for_update_clause: for_update_clause { $$ = $1; }
- | /* EMPTY */ { $$ = EMPTY; }
- ;
-
-update_list: OF name_list
- {
- $$ = cat2_str(make_str("of"), $2);
- }
- | /* EMPTY */
- {
- $$ = EMPTY;
- }
- ;
+for_locking_item:
+ FOR UPDATE locked_rels_list opt_nowait
+ { $$ = cat_str(3, make_str("for update"), $3, $4); }
+ | FOR SHARE locked_rels_list opt_nowait
+ { $$ = cat_str(3, make_str("for share"), $3, $4); }
+ ;
+
+locked_rels_list:
+ OF name_list { $$ = cat2_str(make_str("of"), $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+values_clause: VALUES ctext_row
+ { $$ = cat2_str(make_str("values"), $2); }
+ | values_clause ',' ctext_row
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
/*****************************************************************************
*
* clauses common to all Optimizable Stmts:
- * from_clause - allow list of both JOIN expressions and table names
+ * from_clause - allow list of both JOIN expressions and table names
* where_clause - qualifications for joins or restrictions
*
*****************************************************************************/
-from_clause: FROM from_list { $$ = cat2_str(make_str("from"), $2); }
- | /* EMPTY */ { $$ = EMPTY; }
+from_clause: FROM from_list { $$ = cat2_str(make_str("from"), $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
;
-from_list: from_list ',' table_ref { $$ = cat_str(3, $1, make_str(","), $3); }
- | table_ref { $$ = $1; }
- ;
+from_list: from_list ',' table_ref { $$ = cat_str(3, $1, make_str(","), $3); }
+ | table_ref { $$ = $1; }
+ ;
/*
- * table_ref is where an alias clause can be attached. Note we cannot make
+ * table_ref is where an alias clause can be attached. Note we cannot make
* alias_clause have an empty production because that causes parse conflicts
* between table_ref := '(' joined_table ')' alias_clause
* and joined_table := '(' joined_table ')'. So, we must have the
* redundant-looking productions here instead.
- */
-table_ref: relation_expr
- {
- $$ = $1;
- }
- | relation_expr alias_clause
- {
- $$= cat2_str($1, $2);
- }
- | select_with_parens
- {
- mmerror(PARSE_ERROR, ET_ERROR, "sub-SELECT in FROM must have an alias");
- }
- | select_with_parens alias_clause
- {
- $$=cat2_str($1, $2);
- }
- | joined_table
- {
- $$ = $1;
- }
- | '(' joined_table ')' alias_clause
- {
- $$=cat_str(4, make_str("("), $2, make_str(")"), $4);
- }
- ;
+ */
+table_ref: relation_expr
+ { $$ = $1; }
+ | relation_expr alias_clause
+ { $$ = cat2_str($1, $2); }
+ | func_table
+ { $$ = $1; }
+ | func_table alias_clause
+ { $$ = cat2_str($1, $2); }
+ | func_table AS '(' TableFuncElementList ')'
+ { $$ = cat_str(4, $1, make_str("as ("), $4, make_str(")")); }
+ | func_table AS ColId '(' TableFuncElementList ')'
+ { $$ = cat_str(6, $1, make_str("as"), $3, make_str("("), $5, make_str(")"));}
+ | func_table ColId '(' TableFuncElementList ')'
+ { $$ = cat_str(5, $1, $2, make_str("("), $4, make_str(")")); }
+ | select_with_parens
+ {
+ mmerror(PARSE_ERROR, ET_ERROR, "sub-SELECT in FROM must have an alias");
+ $$ = $1;
+ }
+ | select_with_parens alias_clause
+ { $$ = cat2_str($1, $2); }
+ | joined_table
+ { $$ = $1; }
+ | '(' joined_table ')' alias_clause
+ { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
+ ;
/*
* It may seem silly to separate joined_table from table_ref, but there is
* treat 'JOIN' and 'join_type JOIN' separately, rather than allowing
* join_type to expand to empty; if we try it, the parser generator can't
* figure out when to reduce an empty join_type right after table_ref.
- *
- * Note that a CROSS JOIN is the same as an unqualified
+ *
+ * Note that a CROSS JOIN is the same as an unqualified
* INNER JOIN, and an INNER JOIN/ON has the same shape
* but a qualification expression to limit membership.
* A NATURAL JOIN implicitly matches column names between
* tables and the shape is determined by which columns are
* in common. We'll collect columns during the later transformations.
- */
+ */
-joined_table: '(' joined_table ')'
- {
- $$ = cat_str(3, make_str("("), $2, make_str(")"));
- }
- | table_ref CROSS JOIN table_ref
- {
- $$ = cat_str(3, $1, make_str("cross join"), $4);
- }
- | table_ref UNIONJOIN table_ref
- {
- $$ = cat_str(3, $1, make_str("unionjoin"), $3);
- }
- | table_ref join_type JOIN table_ref join_qual
- {
- $$ = cat_str(5, $1, $2, make_str("join"), $4, $5);
- }
- | table_ref JOIN table_ref join_qual
- {
- $$ = cat_str(4, $1, make_str("join"), $3, $4);
- }
- | table_ref NATURAL join_type JOIN table_ref
- {
- $$ = cat_str(5, $1, make_str("natural"), $3, make_str("join"), $5);
- }
- | table_ref NATURAL JOIN table_ref
- {
- $$ = cat_str(3, $1, make_str("natural join"), $4);
- }
- ;
+joined_table: '(' joined_table ')'
+ { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | table_ref CROSS JOIN table_ref
+ { $$ = cat_str(3, $1, make_str("cross join"), $4); }
+ | table_ref join_type JOIN table_ref join_qual
+ { $$ = cat_str(5, $1, $2, make_str("join"), $4, $5); }
+ | table_ref JOIN table_ref join_qual
+ { $$ = cat_str(4, $1, make_str("join"), $3, $4); }
+ | table_ref NATURAL join_type JOIN table_ref
+ { $$ = cat_str(5, $1, make_str("natural"), $3, make_str("join"), $5); }
+ | table_ref NATURAL JOIN table_ref
+ { $$ = cat_str(3, $1, make_str("natural join"), $4); }
+ ;
alias_clause: AS ColId '(' name_list ')'
{ $$ = cat_str(5, make_str("as"), $2, make_str("("), $4, make_str(")")); }
{ $$ = $1; }
;
-join_type: FULL join_outer { $$ = cat2_str(make_str("full"), $2); }
- | LEFT join_outer { $$ = cat2_str(make_str("left"), $2); }
- | RIGHT join_outer { $$ = cat2_str(make_str("right"), $2); }
- | INNER_P { $$ = make_str("inner"); }
+join_type: FULL join_outer { $$ = cat2_str(make_str("full"), $2); }
+ | LEFT join_outer { $$ = cat2_str(make_str("left"), $2); }
+ | RIGHT join_outer { $$ = cat2_str(make_str("right"), $2); }
+ | INNER_P { $$ = make_str("inner"); }
;
/* OUTER is just noise... */
-join_outer: OUTER_P { $$ = make_str("outer"); }
- | /*EMPTY*/ { $$ = EMPTY; /* no qualifiers */ }
+join_outer: OUTER_P { $$ = make_str("outer"); }
+ | /*EMPTY*/ { $$ = EMPTY; /* no qualifiers */ }
;
/* JOIN qualification clauses
* Possibilities are:
- * USING ( column list ) allows only unqualified column names,
- * which must match between tables.
- * ON expr allows more general qualifications.
+ * USING ( column list ) allows only unqualified column names,
+ * which must match between tables.
+ * ON expr allows more general qualifications.
*/
-join_qual: USING '(' name_list ')' { $$ = cat_str(3, make_str("using ("), $3, make_str(")")); }
- | ON a_expr { $$ = cat2_str(make_str("on"), $2); }
- ;
+join_qual: USING '(' name_list ')'
+ { $$ = cat_str(3, make_str("using ("), $3, make_str(")")); }
+ | ON a_expr
+ { $$ = cat2_str(make_str("on"), $2); }
+ ;
-relation_expr: relation_name
- {
- /* normal relations */
- $$ = $1;
- }
- | relation_name '*'
- {
- /* inheritance query */
- $$ = cat2_str($1, make_str("*"));
- }
- | ONLY relation_name
- {
- /* inheritance query */
- $$ = cat2_str(make_str("ONLY "), $2);
- }
+relation_expr: qualified_name
+ { /* normal relations */ $$ = $1; }
+ | qualified_name '*'
+ { /* inheritance query */ $$ = cat2_str($1, make_str("*")); }
+ | ONLY qualified_name
+ { /* inheritance query */ $$ = cat2_str(make_str("only "), $2); }
+ | ONLY '(' qualified_name ')'
+ { /* inheritance query */ $$ = cat_str(3, make_str("only ("), $3, make_str(")")); }
+ ;
+
+relation_expr_opt_alias: relation_expr %prec UMINUS
+ { $$ = $1; }
+ | relation_expr ColId
+ { $$ = cat2_str($1, $2); }
+ | relation_expr AS ColId
+ { $$ = cat_str(3, $1, make_str("as"), $3); }
+ ;
+
+func_table: func_expr { $$ = $1; }
+ ;
+
+where_clause: WHERE a_expr { $$ = cat2_str(make_str("where"), $2); }
+ | /*EMPTY*/ { $$ = EMPTY; /* no qualifiers */ }
+ ;
-where_clause: WHERE a_expr { $$ = cat2_str(make_str("where"), $2); }
+where_or_current_clause: WHERE a_expr { $$ = cat2_str(make_str("where"), $2); }
+ | WHERE CURRENT_P OF name { $$ = cat2_str(make_str("where current of"), $4); }
+ | WHERE CURRENT_P OF PARAM { $$ = make_str("where current of param"); }
| /*EMPTY*/ { $$ = EMPTY; /* no qualifiers */ }
;
+TableFuncElementList: TableFuncElement
+ { $$ = $1; }
+ | TableFuncElementList ',' TableFuncElement
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+TableFuncElement: ColId Typename { $$ = cat2_str($1, $2); }
+ ;
+
/*****************************************************************************
*
* Type syntax
*****************************************************************************/
Typename: SimpleTypename opt_array_bounds
- {
- $$ = cat2_str($1, $2.str);
- }
- | SETOF SimpleTypename
- {
- $$ = cat2_str(make_str("setof"), $2);
- }
+ { $$ = cat2_str($1, $2.str); }
+ | SETOF SimpleTypename opt_array_bounds
+ { $$ = cat_str(3, make_str("setof"), $2, $3); }
+ | SimpleTypename ARRAY '[' PosIntConst ']'
+ { $$ = cat_str(4, $1, make_str("array ["), $4, make_str("]")); }
+ | SETOF SimpleTypename ARRAY '[' PosIntConst ']'
+ { $$ = cat_str(5, make_str("setof"), $2, make_str("array ["), $5, make_str("]")); }
;
opt_array_bounds: '[' ']' opt_array_bounds
- {
- $$.index1 = 0;
- $$.index2 = $3.index1;
- $$.str = cat2_str(make_str("[]"), $3.str);
- }
+ {
+ $$.index1 = make_str("0");
+ $$.index2 = $3.index1;
+ $$.str = cat2_str(make_str("[]"), $3.str);
+ }
| '[' Iresult ']' opt_array_bounds
- {
- char *txt = mm_alloc(20L);
-
- sprintf (txt, "%d", $2);
- $$.index1 = $2;
- $$.index2 = $4.index1;
- $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
- }
+ {
+ $$.index1 = strdup($2);
+ $$.index2 = $4.index1;
+ $$.str = cat_str(4, make_str("["), $2, make_str("]"), $4.str);
+ }
| /* EMPTY */
- {
- $$.index1 = -1;
- $$.index2 = -1;
- $$.str= EMPTY;
- }
- ;
-
-Iresult: PosIntConst { $$ = atol($1); }
- | '(' Iresult ')' { $$ = $2; }
- | Iresult '+' Iresult { $$ = $1 + $3; }
- | Iresult '-' Iresult { $$ = $1 - $3; }
- | Iresult '*' Iresult { $$ = $1 * $3; }
- | Iresult '/' Iresult { $$ = $1 / $3; }
- | Iresult '%' Iresult { $$ = $1 % $3; }
- ;
+ {
+ $$.index1 = make_str("-1");
+ $$.index2 = make_str("-1");
+ $$.str= EMPTY;
+ }
+ ;
-SimpleTypename: ConstTypename { $$ = $1; }
- | ConstInterval opt_interval { $$ = cat2_str($1, $2); }
- | ConstInterval '(' PosIntConst ')' opt_interval { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
- ;
+Iresult: PosIntConst { $$ = $1; }
+ | '(' Iresult ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | Iresult '+' Iresult { $$ = cat_str(3, $1, make_str("+"), $3); }
+ | Iresult '-' Iresult { $$ = cat_str(3, $1, make_str("-"), $3); }
+ | Iresult '*' Iresult { $$ = cat_str(3, $1, make_str("*"), $3); }
+ | Iresult '/' Iresult { $$ = cat_str(3, $1, make_str("/"), $3); }
+ | Iresult '%' Iresult { $$ = cat_str(3, $1, make_str("%"), $3); }
+ | Sconst { $$ = $1; }
+ | ColId { $$ = $1; }
+ ;
+
+SimpleTypename: GenericType { $$ = $1; }
+ | ConstDatetime { $$ = $1; }
+ | Numeric { $$ = $1; }
+ | Bit { $$ = $1; }
+ | Character { $$ = $1; }
+ | ConstInterval opt_interval
+ { $$ = cat2_str($1, $2); }
+ | ConstInterval '(' PosIntConst ')' opt_interval
+ { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
+ ;
-ConstTypename: Generic { $$ = $1; }
- | ConstDatetime { $$ = $1; }
- | Numeric { $$ = $1; }
- | Bit { $$ = $1; }
- | Character { $$ = $1; }
+ConstTypename: Numeric { $$ = $1; }
+ | ConstBit { $$ = $1; }
+ | ConstCharacter { $$ = $1; }
+ | ConstDatetime { $$ = $1; }
;
-Generic: type_name { $$ = $1; }
+GenericType: type_function_name opt_type_modifiers { $$ = cat2_str($1, $2); }
+ | type_function_name attrs opt_type_modifiers { $$ = cat_str(3, $1, $2, $3); }
;
+opt_type_modifiers: '(' expr_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
/* SQL92 numeric data types
* Check FLOAT() precision limits assuming IEEE floating types.
* Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
* - thomas 1997-09-18
*/
-Numeric: FLOAT opt_float
- {
- $$ = cat2_str(make_str("float"), $2);
- }
- | DOUBLE PRECISION
- {
- $$ = make_str("double precision");
- }
- | DECIMAL opt_decimal
- {
- $$ = cat2_str(make_str("decimal"), $2);
- }
- | DEC opt_decimal
- {
- $$ = cat2_str(make_str("dec"), $2);
- }
- | NUMERIC opt_numeric
- {
- $$ = cat2_str(make_str("numeric"), $2);
- }
- ;
-
-opt_float: '(' PosIntConst ')'
- {
- $$ = cat_str(3, make_str("("), $2, make_str(")"));
- }
- | /*EMPTY*/
- {
- $$ = EMPTY;
- }
- ;
-
-opt_numeric: '(' PosIntConst ',' PosIntConst ')'
- {
- $$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")"));
- }
- | '(' PosIntConst ')'
- {
- $$ = cat_str(3, make_str("("), $2, make_str(")"));
- }
- | /*EMPTY*/
- {
- $$ = EMPTY;
- }
- ;
-
-opt_decimal: '(' PosIntConst ',' PosIntConst ')'
- {
- $$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")"));
- }
- | '(' PosIntConst ')'
- {
- $$ = cat_str(3, make_str("("), $2, make_str(")"));
- }
+Numeric: INT_P
+ { $$ = make_str("int"); }
+ | INTEGER
+ { $$ = make_str("integer"); }
+ | SMALLINT
+ { $$ = make_str("smallint"); }
+ | BIGINT
+ { $$ = make_str("bigint"); }
+ | REAL
+ { $$ = make_str("real"); }
+ | FLOAT_P opt_float
+ { $$ = cat2_str(make_str("float"), $2); }
+ | DOUBLE_P PRECISION
+ { $$ = make_str("double precision"); }
+ | DECIMAL_P opt_type_modifiers
+ { $$ = cat2_str(make_str("decimal"), $2); }
+ | DEC opt_type_modifiers
+ { $$ = cat2_str(make_str("dec"), $2); }
+ | NUMERIC opt_type_modifiers
+ { $$ = cat2_str(make_str("numeric"), $2); }
+ | BOOLEAN_P
+ { $$ = make_str("boolean"); }
+ ;
+
+opt_float: '(' PosIntConst ')'
+ { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
| /*EMPTY*/
- {
- $$ = EMPTY;
- }
+ { $$ = EMPTY; }
;
/*
* SQL92 bit-field data types
* The following implements BIT() and BIT VARYING().
*/
-Bit: bit '(' PosIntConst ')'
- {
- $$ = cat_str(4, $1, make_str("("), $3, make_str(")"));
- }
- | bit
- {
- $$ = $1;
- }
+
+Bit: BitWithLength { $$ = $1; }
+ | BitWithoutLength { $$ = $1; }
;
-bit: BIT opt_varying
- {
- $$ = cat2_str(make_str("bit"), $2);
- }
+ConstBit: BitWithLength { $$ = $1; }
+ | BitWithoutLength { $$ = $1; }
+ ;
-/*
+BitWithLength: BIT opt_varying '(' expr_list ')'
+ { $$ = cat_str(5, make_str("bit"), $2, make_str("("), $4, make_str(")")); }
+ ;
+
+BitWithoutLength: BIT opt_varying
+ { $$ = cat2_str(make_str("bit"), $2); }
+ ;
+
+/*
* SQL92 character data types
* The following implements CHAR() and VARCHAR().
* - ay 6/95
*/
-Character: character '(' PosIntConst ')' opt_charset
- {
- $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5);
- }
- | character opt_charset
- {
- $$ = cat2_str($1, $2);
- }
+Character: CharacterWithLength { $$ = $1; }
+ | CharacterWithoutLength { $$ = $1; }
;
-character: CHARACTER opt_varying
- {
- $$ = cat2_str(make_str("character"), $2);
- }
- | CHAR opt_varying { $$ = cat2_str(make_str("char"), $2); }
- | VARCHAR { $$ = make_str("varchar"); }
- | NATIONAL CHARACTER opt_varying { $$ = cat2_str(make_str("national character"), $3); }
- | NATIONAL CHAR opt_varying { $$ = cat2_str(make_str("national char"), $3); }
- | NCHAR opt_varying { $$ = cat2_str(make_str("nchar"), $2); }
+ConstCharacter: CharacterWithLength { $$ = $1; }
+ | CharacterWithoutLength { $$ = $1; }
;
-opt_varying: VARYING { $$ = make_str("varying"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+CharacterWithLength: character '(' PosIntConst ')' opt_charset
+ { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
;
-opt_charset: CHARACTER SET ColId { $$ = cat2_str(make_str("character set"), $3); }
- | /*EMPTY*/ { $$ = EMPTY; }
+CharacterWithoutLength: character opt_charset
+ { $$ = cat2_str($1, $2); }
;
-opt_collate: COLLATE ColId { $$ = cat2_str(make_str("collate"), $2); }
- | /*EMPTY*/ { $$ = EMPTY; }
+character: CHARACTER opt_varying
+ { $$ = cat2_str(make_str("character"), $2); }
+ | CHAR_P opt_varying
+ { $$ = cat2_str(make_str("char"), $2); }
+ | VARCHAR
+ { $$ = make_str("varchar"); }
+ | NATIONAL CHARACTER opt_varying
+ { $$ = cat2_str(make_str("national character"), $3); }
+ | NATIONAL CHAR_P opt_varying
+ { $$ = cat2_str(make_str("national char"), $3); }
+ | NCHAR opt_varying
+ { $$ = cat2_str(make_str("nchar"), $2); }
;
-ConstDatetime: TIMESTAMP '(' PosIntConst ')' opt_timezone
- {
- $$ = cat_str(4, make_str("timestamp("), $3, make_str(")"), $5);
- }
+opt_varying: VARYING
+ { $$ = make_str("varying"); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
+ ;
+
+opt_charset: CHARACTER SET ColId
+ { $$ = cat2_str(make_str("character set"), $3); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
+ ;
+
+ConstDatetime: TIMESTAMP '(' PosIntConst ')' opt_timezone
+ { $$ = cat_str(4, make_str("timestamp("), $3, make_str(")"), $5); }
| TIMESTAMP opt_timezone
- {
- $$ = cat2_str(make_str("timestamp"), $2);
- }
+ { $$ = cat2_str(make_str("timestamp"), $2); }
| TIME '(' PosIntConst ')' opt_timezone
- {
- $$ = cat_str(4, make_str("time("), $3, make_str(")"), $5);
- }
+ { $$ = cat_str(4, make_str("time("), $3, make_str(")"), $5); }
| TIME opt_timezone
- {
- $$ = cat2_str(make_str("time"), $2);
- }
+ { $$ = cat2_str(make_str("time"), $2); }
;
ConstInterval: INTERVAL
- {
- $$ = make_str("interval");
- }
+ { $$ = make_str("interval"); }
;
-opt_timezone: WITH TIME ZONE { $$ = make_str("with time zone"); }
- | WITHOUT TIME ZONE { $$ = make_str("without time zone"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_timezone: WITH TIME ZONE
+ { $$ = make_str("with time zone"); }
+ | WITHOUT TIME ZONE
+ { $$ = make_str("without time zone"); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
;
-opt_interval: YEAR_P { $$ = make_str("year"); }
- | MONTH_P { $$ = make_str("month"); }
- | DAY_P { $$ = make_str("day"); }
- | HOUR_P { $$ = make_str("hour"); }
- | MINUTE_P { $$ = make_str("minute"); }
- | SECOND_P { $$ = make_str("second"); }
+opt_interval: YEAR_P { $$ = make_str("year"); }
+ | MONTH_P { $$ = make_str("month"); }
+ | DAY_P { $$ = make_str("day"); }
+ | HOUR_P { $$ = make_str("hour"); }
+ | MINUTE_P { $$ = make_str("minute"); }
+ | SECOND_P { $$ = make_str("second"); }
| YEAR_P TO MONTH_P { $$ = make_str("year to month"); }
| DAY_P TO HOUR_P { $$ = make_str("day to hour"); }
| DAY_P TO MINUTE_P { $$ = make_str("day to minute"); }
| DAY_P TO SECOND_P { $$ = make_str("day to second"); }
- | HOUR_P TO MINUTE_P { $$ = make_str("hour to minute"); }
- | MINUTE_P TO SECOND_P { $$ = make_str("minute to second"); }
- | HOUR_P TO SECOND_P { $$ = make_str("hour to second"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+ | HOUR_P TO MINUTE_P { $$ = make_str("hour to minute"); }
+ | MINUTE_P TO SECOND_P { $$ = make_str("minute to second"); }
+ | HOUR_P TO SECOND_P { $$ = make_str("hour to second"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
*
*****************************************************************************/
-/* Expressions using row descriptors
- * Define row_descriptor to allow yacc to break the reduce/reduce conflict
- * with singleton expressions.
- */
-row_expr: '(' row_descriptor ')' IN select_with_parens
- {
- $$ = cat_str(4, make_str("("), $2, make_str(") in "), $5);
- }
- | '(' row_descriptor ')' NOT IN select_with_parens
- {
- $$ = cat_str(4, make_str("("), $2, make_str(") not in "), $6);
- }
- | '(' row_descriptor ')' all_Op sub_type select_with_parens
- {
- $$ = cat_str(6, make_str("("), $2, make_str(")"), $4, $5, $6);
- }
- | '(' row_descriptor ')' all_Op select_with_parens
- {
- $$ = cat_str(5, make_str("("), $2, make_str(")"), $4, $5);
- }
- | '(' row_descriptor ')' all_Op '(' row_descriptor ')'
- {
- $$ = cat_str(7, make_str("("), $2, make_str(")"), $4, make_str("("), $6, make_str(")"));
- }
- | '(' row_descriptor ')' OVERLAPS '(' row_descriptor ')'
- {
- $$ = cat_str(5, make_str("("), $2, make_str(") overlaps ("), $6, make_str(")"));
- }
- ;
-
-row_descriptor: row_list ',' a_expr
- {
- $$ = cat_str(3, $1, make_str(","), $3);
- }
- ;
-
-sub_type: ANY { $$ = make_str("ANY"); }
- | SOME { $$ = make_str("SOME"); }
- | ALL { $$ = make_str("ALL"); }
- ;
-
-
-row_list: row_list ',' a_expr
- {
- $$ = cat_str(3, $1, make_str(","), $3);
- }
- | a_expr
- {
- $$ = $1;
- }
- ;
-
-all_Op: Op | MathOp;
-
-MathOp: '+' { $$ = make_str("+"); }
- | '-' { $$ = make_str("-"); }
- | '*' { $$ = make_str("*"); }
- | '%' { $$ = make_str("%"); }
- | '^' { $$ = make_str("^"); }
- | '/' { $$ = make_str("/"); }
- | '<' { $$ = make_str("<"); }
- | '>' { $$ = make_str(">"); }
- | '=' { $$ = make_str("="); }
- ;
-
/* General expressions
* This is the heart of the expression syntax.
*
*/
a_expr: c_expr
- { $$ = $1; }
+ { $$ = $1; }
| a_expr TYPECAST Typename
- { $$ = cat_str(3, $1, make_str("::"), $3); }
- | a_expr AT TIME ZONE c_expr
- { $$ = cat_str(3, $1, make_str("at time zone"), $5); }
+ { $$ = cat_str(3, $1, make_str("::"), $3); }
+ | a_expr AT TIME ZONE a_expr
+ { $$ = cat_str(3, $1, make_str("at time zone"), $5); }
/*
- * These operators must be called out explicitly in order to make use
- * of yacc/bison's automatic operator-precedence handling. All other
- * operator names are handled by the generic productions using "Op",
- * below; and all those operators will have the same precedence.
- *
- * If you add more explicitly-known operators, be sure to add them
- * also to b_expr and to the MathOp list above.
- */
+ * These operators must be called out explicitly in order to make use
+ * of yacc/bison's automatic operator-precedence handling. All other
+ * operator names are handled by the generic productions using "Op",
+ * below; and all those operators will have the same precedence.
+ *
+ * If you add more explicitly-known operators, be sure to add them
+ * also to b_expr and to the MathOp list above.
+ */
| '+' a_expr %prec UMINUS
- { $$ = cat2_str(make_str("+"), $2); }
+ { $$ = cat2_str(make_str("+"), $2); }
| '-' a_expr %prec UMINUS
- { $$ = cat2_str(make_str("-"), $2); }
- | '%' a_expr
- { $$ = cat2_str(make_str("%"), $2); }
- | '^' a_expr
- { $$ = cat2_str(make_str("^"), $2); }
- | a_expr '%'
- { $$ = cat2_str($1, make_str("%")); }
- | a_expr '^'
- { $$ = cat2_str($1, make_str("^")); }
+ { $$ = cat2_str(make_str("-"), $2); }
| a_expr '+' a_expr
- { $$ = cat_str(3, $1, make_str("+"), $3); }
+ { $$ = cat_str(3, $1, make_str("+"), $3); }
| a_expr '-' a_expr
- { $$ = cat_str(3, $1, make_str("-"), $3); }
+ { $$ = cat_str(3, $1, make_str("-"), $3); }
| a_expr '*' a_expr
- { $$ = cat_str(3, $1, make_str("*"), $3); }
+ { $$ = cat_str(3, $1, make_str("*"), $3); }
| a_expr '/' a_expr
- { $$ = cat_str(3, $1, make_str("/"), $3); }
+ { $$ = cat_str(3, $1, make_str("/"), $3); }
| a_expr '%' a_expr
- { $$ = cat_str(3, $1, make_str("%"), $3); }
+ { $$ = cat_str(3, $1, make_str("%"), $3); }
| a_expr '^' a_expr
- { $$ = cat_str(3, $1, make_str("^"), $3); }
+ { $$ = cat_str(3, $1, make_str("^"), $3); }
| a_expr '<' a_expr
- { $$ = cat_str(3, $1, make_str("<"), $3); }
+ { $$ = cat_str(3, $1, make_str("<"), $3); }
| a_expr '>' a_expr
- { $$ = cat_str(3, $1, make_str(">"), $3); }
+ { $$ = cat_str(3, $1, make_str(">"), $3); }
| a_expr '=' a_expr
- { $$ = cat_str(3, $1, make_str("="), $3); }
- | a_expr Op a_expr
- { $$ = cat_str(3, $1, $2, $3); }
- | Op a_expr
- { $$ = cat2_str($1, $2); }
- | a_expr Op %prec POSTFIXOP
- { $$ = cat2_str($1, $2); }
+ { $$ = cat_str(3, $1, make_str("="), $3); }
+ | a_expr qual_Op a_expr %prec Op
+ { $$ = cat_str(3, $1, $2, $3); }
+ | qual_Op a_expr %prec Op
+ { $$ = cat2_str($1, $2); }
+ | a_expr qual_Op %prec POSTFIXOP
+ { $$ = cat2_str($1, $2); }
| a_expr AND a_expr
- { $$ = cat_str(3, $1, make_str("and"), $3); }
+ { $$ = cat_str(3, $1, make_str("and"), $3); }
| a_expr OR a_expr
- { $$ = cat_str(3, $1, make_str("or"), $3); }
+ { $$ = cat_str(3, $1, make_str("or"), $3); }
| NOT a_expr
- { $$ = cat2_str(make_str("not"), $2); }
+ { $$ = cat2_str(make_str("not"), $2); }
| a_expr LIKE a_expr
- { $$ = cat_str(3, $1, make_str("like"), $3); }
+ { $$ = cat_str(3, $1, make_str("like"), $3); }
| a_expr LIKE a_expr ESCAPE a_expr
- { $$ = cat_str(5, $1, make_str("like"), $3, make_str("escape"), $5); }
+ { $$ = cat_str(5, $1, make_str("like"), $3, make_str("escape"), $5); }
| a_expr NOT LIKE a_expr
- { $$ = cat_str(3, $1, make_str("not like"), $4); }
+ { $$ = cat_str(3, $1, make_str("not like"), $4); }
| a_expr NOT LIKE a_expr ESCAPE a_expr
- { $$ = cat_str(5, $1, make_str("not like"), $4, make_str("escape"), $6); }
+ { $$ = cat_str(5, $1, make_str("not like"), $4, make_str("escape"), $6); }
| a_expr ILIKE a_expr
- { $$ = cat_str(3, $1, make_str("ilike"), $3); }
+ { $$ = cat_str(3, $1, make_str("ilike"), $3); }
| a_expr ILIKE a_expr ESCAPE a_expr
- { $$ = cat_str(5, $1, make_str("ilike"), $3, make_str("escape"), $5); }
+ { $$ = cat_str(5, $1, make_str("ilike"), $3, make_str("escape"), $5); }
| a_expr NOT ILIKE a_expr
- { $$ = cat_str(3, $1, make_str("not ilike"), $4); }
+ { $$ = cat_str(3, $1, make_str("not ilike"), $4); }
| a_expr NOT ILIKE a_expr ESCAPE a_expr
- { $$ = cat_str(5, $1, make_str("not ilike"), $4, make_str("escape"), $6); }
+ { $$ = cat_str(5, $1, make_str("not ilike"), $4, make_str("escape"), $6); }
+ | a_expr SIMILAR TO a_expr %prec SIMILAR
+ { $$ = cat_str(3, $1, make_str("similar to"), $4); }
+ | a_expr SIMILAR TO a_expr ESCAPE a_expr
+ { $$ = cat_str(5, $1, make_str("similar to"), $4, make_str("escape"), $6); }
+ | a_expr NOT SIMILAR TO a_expr %prec SIMILAR
+ { $$ = cat_str(3, $1, make_str("not similar to"), $5); }
+ | a_expr NOT SIMILAR TO a_expr ESCAPE a_expr
+ { $$ = cat_str(5, $1, make_str("not similar to"), $5, make_str("escape"), $7); }
| a_expr ISNULL
- { $$ = cat2_str($1, make_str("isnull")); }
+ { $$ = cat2_str($1, make_str("isnull")); }
| a_expr IS NULL_P
- { $$ = cat2_str($1, make_str("is null")); }
+ { $$ = cat2_str($1, make_str("is null")); }
| a_expr NOTNULL
- { $$ = cat2_str($1, make_str("notnull")); }
+ { $$ = cat2_str($1, make_str("notnull")); }
| a_expr IS NOT NULL_P
- { $$ = cat2_str($1, make_str("is not null")); }
+ { $$ = cat2_str($1, make_str("is not null")); }
+ | row OVERLAPS row
+ { $$ = cat_str(3, $1, make_str("overlaps"), $3); }
/* IS TRUE, IS FALSE, etc used to be function calls
- * but let's make them expressions to allow the optimizer
- * a chance to eliminate them if a_expr is a constant string.
+ * but let's make them expressions to allow the optimizer
+ * a chance to eliminate them if a_expr is a constant string.
* - thomas 1997-12-22
*
- * Created BooleanTest Node type, and changed handling
- * for NULL inputs
+ * Created BooleanTest Node type, and changed handling
+ * for NULL inputs
* - jec 2001-06-18
*/
| a_expr IS TRUE_P
- { $$ = cat2_str($1, make_str("is true")); }
+ { $$ = cat2_str($1, make_str("is true")); }
| a_expr IS NOT TRUE_P
- { $$ = cat2_str($1, make_str("is not true")); }
+ { $$ = cat2_str($1, make_str("is not true")); }
| a_expr IS FALSE_P
- { $$ = cat2_str($1, make_str("is false")); }
+ { $$ = cat2_str($1, make_str("is false")); }
| a_expr IS NOT FALSE_P
- { $$ = cat2_str($1, make_str("is not false")); }
+ { $$ = cat2_str($1, make_str("is not false")); }
| a_expr IS UNKNOWN
- { $$ = cat2_str($1, make_str("is unknown")); }
+ { $$ = cat2_str($1, make_str("is unknown")); }
| a_expr IS NOT UNKNOWN
- { $$ = cat2_str($1, make_str("is not unknown")); }
- | a_expr BETWEEN b_expr AND b_expr %prec BETWEEN
- {
- $$ = cat_str(5, $1, make_str("between"), $3, make_str("and"), $5);
- }
- | a_expr NOT BETWEEN b_expr AND b_expr %prec BETWEEN
- {
- $$ = cat_str(5, $1, make_str("not between"), $4, make_str("and"), $6);
- }
- | a_expr IN in_expr
- {
- $$ = cat_str(3, $1, make_str(" in"), $3);
- }
- | a_expr NOT IN in_expr
- {
- $$ = cat_str(3, $1, make_str(" not in "), $4);
- }
- | a_expr all_Op sub_type select_with_parens %prec Op
- {
- $$ = cat_str(4, $1, $2, $3, $4);
- }
- | row_expr
- { $$ = $1; }
+ { $$ = cat2_str($1, make_str("is not unknown")); }
+ | a_expr IS DISTINCT FROM a_expr %prec IS
+ { $$ = cat_str(3, $1, make_str("is distinct from"), $5); }
+ | a_expr IS NOT DISTINCT FROM a_expr %prec IS
+ { $$ = cat_str(3, $1, make_str("is not distinct from"), $6); }
+ | a_expr IS OF '(' type_list ')' %prec IS
+ { $$ = cat_str(4, $1, make_str("is of ("), $5, make_str(")")); }
+ | a_expr IS NOT OF '(' type_list ')' %prec IS
+ { $$ = cat_str(4, $1, make_str("is not of ("), $6, make_str(")")); }
+ | a_expr BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN
+ { $$ = cat_str(6, $1, make_str("between"), $3, $4, make_str("and"), $6); }
+ | a_expr NOT BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN
+ { $$ = cat_str(6, $1, make_str("not between"), $4, $5, make_str("and"), $7); }
+ | a_expr BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN
+ { $$ = cat_str(5, $1, make_str("between symmetric"), $4, make_str("and"), $6); }
+ | a_expr NOT BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN
+ { $$ = cat_str(5, $1, make_str("not between symmetric"), $5, make_str("and"), $7); }
+ | a_expr IN_P in_expr
+ { $$ = cat_str(3, $1, make_str("in"), $3); }
+ | a_expr NOT IN_P in_expr
+ { $$ = cat_str(3, $1, make_str("not in"), $4); }
+ | a_expr subquery_Op sub_type select_with_parens %prec Op
+ { $$ = cat_str(4, $1, $2, $3, $4); }
+ | a_expr subquery_Op sub_type '(' a_expr ')' %prec Op
+ { $$ = cat_str(6, $1, $2, $3, make_str("("), $5, make_str(")")); }
+ | UNIQUE select_with_parens
+ { $$ = cat2_str(make_str("unique"), $2); }
+ | a_expr IS DOCUMENT_P
+ { $$ = cat2_str($1, make_str("is document")); }
+ | a_expr IS NOT DOCUMENT_P
+ { $$ = cat2_str($1, make_str("is not document")); }
;
/* Restricted expressions
* just eliminate all the boolean-keyword-operator productions from b_expr.
*/
b_expr: c_expr
- {
- $$ = $1;
- }
+ { $$ = $1; }
| b_expr TYPECAST Typename
- {
- $$ = cat_str(3, $1, make_str("::"), $3);
- }
+ { $$ = cat_str(3, $1, make_str("::"), $3); }
| '-' b_expr %prec UMINUS
- { $$ = cat2_str(make_str("-"), $2); }
- | '%' b_expr
- { $$ = cat2_str(make_str("%"), $2); }
- | '^' b_expr
- { $$ = cat2_str(make_str("^"), $2); }
- | b_expr '%'
- { $$ = cat2_str($1, make_str("%")); }
- | b_expr '^'
- { $$ = cat2_str($1, make_str("^")); }
+ { $$ = cat2_str(make_str("-"), $2); }
| b_expr '+' b_expr
- { $$ = cat_str(3, $1, make_str("+"), $3); }
+ { $$ = cat_str(3, $1, make_str("+"), $3); }
| b_expr '-' b_expr
- { $$ = cat_str(3, $1, make_str("-"), $3); }
+ { $$ = cat_str(3, $1, make_str("-"), $3); }
| b_expr '*' b_expr
- { $$ = cat_str(3, $1, make_str("*"), $3); }
+ { $$ = cat_str(3, $1, make_str("*"), $3); }
| b_expr '/' b_expr
- { $$ = cat_str(3, $1, make_str("/"), $3); }
+ { $$ = cat_str(3, $1, make_str("/"), $3); }
| b_expr '%' b_expr
- { $$ = cat_str(3, $1, make_str("%"), $3); }
+ { $$ = cat_str(3, $1, make_str("%"), $3); }
| b_expr '^' b_expr
- { $$ = cat_str(3, $1, make_str("^"), $3); }
+ { $$ = cat_str(3, $1, make_str("^"), $3); }
| b_expr '<' b_expr
- { $$ = cat_str(3, $1, make_str("<"), $3); }
+ { $$ = cat_str(3, $1, make_str("<"), $3); }
| b_expr '>' b_expr
- { $$ = cat_str(3, $1, make_str(">"), $3); }
+ { $$ = cat_str(3, $1, make_str(">"), $3); }
| b_expr '=' b_expr
- { $$ = cat_str(3, $1, make_str("="), $3); }
+ { $$ = cat_str(3, $1, make_str("="), $3); }
| b_expr Op b_expr
- { $$ = cat_str(3, $1, $2, $3); }
- | Op b_expr
- { $$ = cat2_str($1, $2); }
- | b_expr Op %prec POSTFIXOP
- { $$ = cat2_str($1, $2); }
+ { $$ = cat_str(3, $1, $2, $3); }
+ | qual_Op b_expr %prec Op
+ { $$ = cat2_str($1, $2); }
+ | b_expr qual_Op %prec POSTFIXOP
+ { $$ = cat2_str($1, $2); }
+ | b_expr IS DISTINCT FROM b_expr %prec IS
+ { $$ = cat_str(3, $1, make_str("is distinct from"), $5); }
+ | b_expr IS NOT DISTINCT FROM b_expr %prec IS
+ { $$ = cat_str(3, $1, make_str("is not distinct from"), $6); }
+ | b_expr IS OF '(' b_expr ')' %prec IS
+ { $$ = cat_str(4, $1, make_str("is of ("), $5, make_str(")")); }
+ | b_expr IS NOT OF '(' b_expr ')' %prec IS
+ { $$ = cat_str(4, $1, make_str("is not of ("), $6, make_str(")")); }
+ | b_expr IS DOCUMENT_P
+ { $$ = cat2_str($1, make_str("is document")); }
+ | b_expr IS NOT DOCUMENT_P
+ { $$ = cat2_str($1, make_str("is not document")); }
;
/*
* Productions that can be used in both a_expr and b_expr.
*
* Note: productions that refer recursively to a_expr or b_expr mostly
- * cannot appear here. However, it's OK to refer to a_exprs that occur
+ * cannot appear here. However, it's OK to refer to a_exprs that occur
* inside parentheses, such as function arguments; that cannot introduce
* ambiguity to the b_expr syntax.
*/
-c_expr: attr
- { $$ = $1; }
- | ColId opt_indirection
- { $$ = cat2_str($1, $2); }
+c_expr: columnref
+ { $$ = $1; }
| AexprConst
- { $$ = $1; }
- | '(' a_expr ')'
- { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
- | CAST '(' a_expr AS Typename ')'
- { $$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); }
+ { $$ = $1; }
+ | PARAM opt_indirection
+ { $$ = cat2_str(make_str("param"), $2); }
+ | '(' a_expr ')' opt_indirection
+ { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
| case_expr
- { $$ = $1; }
- | func_name '(' ')'
- { $$ = cat2_str($1, make_str("()")); }
+ { $$ = $1; }
+ | func_expr
+ { $$ = $1; }
+ | select_with_parens %prec UMINUS
+ { $$ = $1; }
+ | EXISTS select_with_parens
+ { $$ = cat2_str(make_str("exists"), $2); }
+ | ARRAY select_with_parens
+ { $$ = cat2_str(make_str("array"), $2); }
+ | ARRAY array_expr
+ { $$ = cat2_str(make_str("array"), $2); }
+ | row
+ { $$ = $1; }
+ ;
+
+/*
+ * func_expr is split out from c_expr just so that we have a classification
+ * for "everything that is a function call or looks like one". This isn't
+ * very important, but it saves us having to document which variants are
+ * legal in the backwards-compatible functional-index syntax for CREATE INDEX.
+ * (Note that many of the special SQL functions wouldn't actually make any
+ * sense as functional index entries, but we ignore that consideration here.)
+ */
+func_expr: func_name '(' ')'
+ { $$ = cat2_str($1, make_str("()")); }
| func_name '(' expr_list ')'
- { $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
+ { $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
+ | func_name '(' VARIADIC a_expr ')'
+ { $$ = cat_str(4, $1, make_str("( variadic "), $4, make_str(")")); }
+ | func_name '(' expr_list ',' VARIADIC a_expr ')'
+ { $$ = cat_str(6, $1, make_str("("), $3, make_str(", variadic "), $6, make_str(")")); }
| func_name '(' ALL expr_list ')'
- { $$ = cat_str(4, $1, make_str("( all"), $4, make_str(")")); }
+ { $$ = cat_str(4, $1, make_str("( all"), $4, make_str(")")); }
| func_name '(' DISTINCT expr_list ')'
- { $$ = cat_str(4, $1, make_str("( distinct"), $4, make_str(")")); }
+ { $$ = cat_str(4, $1, make_str("( distinct"), $4, make_str(")")); }
| func_name '(' '*' ')'
- { $$ = cat2_str($1, make_str("(*)")); }
+ { $$ = cat2_str($1, make_str("(*)")); }
| CURRENT_DATE
- { $$ = make_str("current_date"); }
- | CURRENT_TIME opt_empty_parentheses
- { $$ = cat2_str(make_str("current_time"), $2); }
+ { $$ = make_str("current_date"); }
+ | CURRENT_TIME
+ { $$ = make_str("current_time"); }
| CURRENT_TIME '(' PosIntConst ')'
- {
- $$ = make_str("current_time");
- }
- | CURRENT_TIMESTAMP opt_empty_parentheses
- { $$ = cat2_str(make_str("current_timestamp"), $2); }
+ { $$ = cat_str(3, make_str("current_time ("), $3, make_str(")")); }
+ | CURRENT_TIMESTAMP
+ { $$ = make_str("current_timestamp"); }
| CURRENT_TIMESTAMP '(' PosIntConst ')'
- {
- $$ = make_str("current_timestamp");
- }
- | CURRENT_USER opt_empty_parentheses
- { $$ = cat2_str(make_str("current_user"), $2); }
- | SESSION_USER opt_empty_parentheses
- { $$ = cat2_str(make_str("session_user"), $2); }
- | USER opt_empty_parentheses
- { $$ = cat2_str(make_str("user"), $2); }
+ { $$ = cat_str(3, make_str("current_timestamp ("), $3, make_str(")")); }
+ | LOCALTIME
+ { $$ = make_str("localtime"); }
+ | LOCALTIME '(' PosIntConst ')'
+ { $$ = cat_str(3, make_str("localtime ("), $3, make_str(")")); }
+ | LOCALTIMESTAMP
+ { $$ = make_str("local_timestamp"); }
+ | LOCALTIMESTAMP '(' PosIntConst ')'
+ { $$ = cat_str(3, make_str("locale_timestamp ("), $3, make_str(")")); }
+ | CURRENT_ROLE
+ { $$ = make_str("current_role"); }
+ | CURRENT_USER
+ { $$ = make_str("current_user"); }
+ | SESSION_USER
+ { $$ = make_str("session_user"); }
+ | USER
+ { $$ = make_str("user"); }
+ | CAST '(' a_expr AS Typename ')'
+ { $$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); }
| EXTRACT '(' extract_list ')'
- { $$ = cat_str(3, make_str("extract("), $3, make_str(")")); }
+ { $$ = cat_str(3, make_str("extract("), $3, make_str(")")); }
+ | OVERLAY '(' overlay_list ')'
+ { $$ = cat_str(3, make_str("overlay("), $3, make_str(")")); }
| POSITION '(' position_list ')'
- { $$ = cat_str(3, make_str("position("), $3, make_str(")")); }
+ { $$ = cat_str(3, make_str("position("), $3, make_str(")")); }
| SUBSTRING '(' substr_list ')'
- { $$ = cat_str(3, make_str("substring("), $3, make_str(")")); }
+ { $$ = cat_str(3, make_str("substring("), $3, make_str(")")); }
+ | TREAT '(' a_expr AS Typename ')'
+ { $$ = cat_str(5, make_str("treat("), $3, make_str("as"), $5, make_str(")")); }
/* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
| TRIM '(' BOTH trim_list ')'
- { $$ = cat_str(3, make_str("trim(both"), $4, make_str(")")); }
+ { $$ = cat_str(3, make_str("trim(both"), $4, make_str(")")); }
| TRIM '(' LEADING trim_list ')'
- { $$ = cat_str(3, make_str("trim(leading"), $4, make_str(")")); }
+ { $$ = cat_str(3, make_str("trim(leading"), $4, make_str(")")); }
| TRIM '(' TRAILING trim_list ')'
- { $$ = cat_str(3, make_str("trim(trailing"), $4, make_str(")")); }
+ { $$ = cat_str(3, make_str("trim(trailing"), $4, make_str(")")); }
| TRIM '(' trim_list ')'
- { $$ = cat_str(3, make_str("trim("), $3, make_str(")")); }
- | select_with_parens %prec UMINUS
- { $$ = $1; }
- | EXISTS select_with_parens
- { $$ = cat2_str(make_str("exists"), $2); }
+ { $$ = cat_str(3, make_str("trim("), $3, make_str(")")); }
+ | NULLIF '(' a_expr ',' a_expr ')'
+ { $$ = cat_str(5, make_str("nullif("), $3, make_str(","), $5, make_str(")")); }
+ | COALESCE '(' expr_list ')'
+ { $$ = cat_str(3, make_str("coalesce("), $3, make_str(")")); }
+ | GREATEST '(' expr_list ')'
+ { $$ = cat_str(3, make_str("greatest("), $3, make_str(")")); }
+ | LEAST '(' expr_list ')'
+ { $$ = cat_str(3, make_str("least("), $3, make_str(")")); }
+ | XMLCONCAT '(' expr_list ')'
+ { $$ = cat_str(3, make_str("xmlconcat("), $3, make_str(")")); }
+ | XMLELEMENT '(' NAME_P ColLabel ')'
+ { $$ = cat_str(3, make_str("xmlelement( name"), $4, make_str(")")); }
+ | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'
+ { $$ = cat_str(5, make_str("xmlelement( name"), $4, make_str(","), $6, make_str(")")); }
+ | XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'
+ { $$ = cat_str(5, make_str("xmlelement( name"), $4, make_str(","), $6, make_str(")")); }
+ | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'
+ { $$ = cat_str(7, make_str("xmlelement( name"), $4, make_str(","), $6, make_str(","), $8, make_str(")")); }
+ | XMLFOREST '(' xml_attribute_list ')'
+ { $$ = cat_str(3, make_str("xmlforest("), $3, make_str(")")); }
+ | XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
+ { $$ = cat_str(5, make_str("xmlparse("), $3, $4, $5, make_str(")")); }
+ | XMLPI '(' NAME_P ColLabel ')'
+ { $$ = cat_str(3, make_str("xmlpi( name"), $4, make_str(")")); }
+ | XMLPI '(' NAME_P ColLabel ',' a_expr ')'
+ { $$ = cat_str(5, make_str("xmlpi( name"), $4, make_str(","), $6, make_str(")")); }
+ | XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')'
+ { $$ = cat_str(6, make_str("xmlroot("), $3, make_str(","), $5, $6, make_str(")")); }
;
-/*
- * This used to use ecpg_expr, but since there is no shift/reduce conflict
- * anymore, we can remove ecpg_expr. - MM
+
+/*
+ * SQL/XML support
*/
-opt_indirection: '[' a_expr ']' opt_indirection
- {
- $$ = cat_str(4, make_str("["), $2, make_str("]"), $4);
- }
- | '[' a_expr ':' a_expr ']' opt_indirection
- {
- $$ = cat_str(6, make_str("["), $2, make_str(":"), $4, make_str("]"), $6);
- }
- | /* EMPTY */
- { $$ = EMPTY; }
+
+xml_root_version: VERSION_P a_expr
+ { $$ = cat2_str(make_str("version"), $2); }
+ | VERSION_P NO VALUE_P
+ { $$ = make_str("version no value"); }
;
-expr_list: a_expr
+opt_xml_root_standalone: ',' STANDALONE_P YES_P
+ { $$ = make_str(", standalone yes"); }
+ | ',' STANDALONE_P NO
+ { $$ = make_str(", standalone no"); }
+ | ',' STANDALONE_P NO VALUE_P
+ { $$ = make_str(", standalone no value"); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
+ ;
+
+xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')'
+ { $$ = cat_str(3, make_str("xmlattributes("), $3, make_str(")")); }
+ ;
+
+xml_attribute_list: xml_attribute_el
{ $$ = $1; }
- | expr_list ',' a_expr
+ | xml_attribute_list ',' xml_attribute_el
{ $$ = cat_str(3, $1, make_str(","), $3); }
- | expr_list USING a_expr
- { $$ = cat_str(3, $1, make_str("using"), $3); }
+ ;
+
+xml_attribute_el: a_expr AS ColLabel
+ { $$ = cat_str(3, $1, make_str("as"), $3); }
+ | a_expr
+ { $$ = $1; }
+ ;
+
+document_or_content: DOCUMENT_P { $$ = make_str("document"); }
+ | CONTENT_P { $$ = make_str("content"); }
+ ;
+
+xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = make_str("preserve whitespace"); }
+ | STRIP_P WHITESPACE_P { $$ = make_str("strip whitespace"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+row: ROW '(' expr_list ')'
+ { $$ = cat_str(3, make_str("row ("), $3, make_str(")")); }
+ | ROW '(' ')'
+ { $$ = make_str("row()"); }
+ | '(' expr_list ',' a_expr ')'
+ { $$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")")); }
+ ;
+
+sub_type: ANY { $$ = make_str("ANY"); }
+ | SOME { $$ = make_str("SOME"); }
+ | ALL { $$ = make_str("ALL"); }
+ ;
+
+all_Op: Op { $$ = $1; }
+ | MathOp { $$ = $1; }
+ ;
+
+MathOp: '+' { $$ = make_str("+"); }
+ | '-' { $$ = make_str("-"); }
+ | '*' { $$ = make_str("*"); }
+ | '%' { $$ = make_str("%"); }
+ | '^' { $$ = make_str("^"); }
+ | '/' { $$ = make_str("/"); }
+ | '<' { $$ = make_str("<"); }
+ | '>' { $$ = make_str(">"); }
+ | '=' { $$ = make_str("="); }
+ ;
+
+qual_Op: Op { $$ = $1; }
+ | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
+ ;
+
+qual_all_Op: all_Op { $$ = $1; }
+ | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
+ ;
+
+subquery_Op: all_Op { $$ = $1; }
+ | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
+ | LIKE { $$ = make_str("like"); }
+ | NOT LIKE { $$ = make_str("not like"); }
+ | ILIKE { $$ = make_str("ilike"); }
+ | NOT ILIKE { $$ = make_str("not ilike"); }
+ ;
+
+expr_list: a_expr
+ { $$ = $1; }
+ | expr_list ',' a_expr
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+type_list: Typename
+ { $$ = $1; }
+ | type_list ',' Typename
+ { $$ = cat_str(3, $1, ',', $3); }
+ ;
+
+array_expr: '[' expr_list ']' { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+ | '[' array_expr_list ']' { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+ | '[' ']' { $$ = make_str("[]"); }
+ ;
+
+array_expr_list: array_expr { $$ = $1; }
+ | array_expr_list ',' array_expr { $$ = cat_str(3, $1, make_str(","), $3); }
;
extract_list: extract_arg FROM a_expr
- {
- $$ = cat_str(3, $1, make_str("from"), $3);
- }
+ { $$ = cat_str(3, $1, make_str("from"), $3); }
| /* EMPTY */
- { $$ = EMPTY; }
+ { $$ = EMPTY; }
;
-/* Allow delimited string SCONST in extract_arg as an SQL extension.
- * - thomas 2001-04-12
- */
+extract_arg: ident { $$ = $1; }
+ | YEAR_P { $$ = make_str("year"); }
+ | MONTH_P { $$ = make_str("month"); }
+ | DAY_P { $$ = make_str("day"); }
+ | HOUR_P { $$ = make_str("hour"); }
+ | MINUTE_P { $$ = make_str("minute"); }
+ | SECOND_P { $$ = make_str("second"); }
+ | StringConst { $$ = $1; }
+ ;
+
+overlay_list:
+ a_expr overlay_placing substr_from substr_for
+ { $$ = cat_str(4, $1, 42, $3, $4); }
+ | a_expr overlay_placing substr_from
+ { $$ = cat_str(3, $1, $2, $3); }
+ ;
-extract_arg: IDENT { $$ = $1; }
- | YEAR_P { $$ = make_str("year"); }
- | MONTH_P { $$ = make_str("month"); }
- | DAY_P { $$ = make_str("day"); }
- | HOUR_P { $$ = make_str("hour"); }
- | MINUTE_P { $$ = make_str("minute"); }
- | SECOND_P { $$ = make_str("second"); }
- | StringConst { $$ = $1; }
+overlay_placing:
+ PLACING a_expr { $$ = cat2_str(make_str("placing"), $2); }
;
/* position_list uses b_expr not a_expr to avoid conflict with general IN */
-position_list: b_expr IN b_expr
- { $$ = cat_str(3, $1, make_str("in"), $3); }
+position_list: b_expr IN_P b_expr
+ { $$ = cat_str(3, $1, make_str("in"), $3); }
| /* EMPTY */
- { $$ = EMPTY; }
+ { $$ = EMPTY; }
;
substr_list: a_expr substr_from substr_for
- {
- $$ = cat_str(3, $1, $2, $3);
- }
- | a_expr substr_for substr_from
- {
- $$ = cat_str(3, $1, $2, $3);
- }
- | a_expr substr_from
- {
- $$ = cat2_str($1, $2);
- }
+ { $$ = cat_str(3, $1, $2, $3); }
+ | a_expr substr_for substr_from
+ { $$ = cat_str(3, $1, $2, $3); }
+ | a_expr substr_from
+ { $$ = cat2_str($1, $2); }
| a_expr substr_for
- {
- $$ = cat2_str($1, $2);
- }
+ { $$ = cat2_str($1, $2); }
| expr_list
- {
- $$ = $1;
- }
+ { $$ = $1; }
| /* EMPTY */
- { $$ = EMPTY; }
+ { $$ = EMPTY; }
;
substr_from: FROM a_expr
- { $$ = cat2_str(make_str("from"), $2); }
+ { $$ = cat2_str(make_str("from"), $2); }
;
substr_for: FOR a_expr
- { $$ = cat2_str(make_str("for"), $2); }
+ { $$ = cat2_str(make_str("for"), $2); }
;
-trim_list: a_expr FROM expr_list
- { $$ = cat_str(3, $1, make_str("from"), $3); }
+trim_list: a_expr FROM expr_list
+ { $$ = cat_str(3, $1, make_str("from"), $3); }
| FROM expr_list
- { $$ = cat2_str(make_str("from"), $2); }
+ { $$ = cat2_str(make_str("from"), $2); }
| expr_list
- { $$ = $1; }
+ { $$ = $1; }
;
in_expr: select_with_parens
- {
- $$ = $1;
- }
- | '(' in_expr_nodes ')'
- { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
- ;
-
-in_expr_nodes: a_expr
- { $$ = $1; }
- | in_expr_nodes ',' a_expr
- { $$ = cat_str(3, $1, make_str(","), $3);}
+ { $$ = $1; }
+ | '(' expr_list ')'
+ { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
;
/* Case clause
* Define SQL92-style case clause.
- * Allow all four forms described in the standard:
- * - Full specification
- * CASE WHEN a = b THEN c ... ELSE d END
- * - Implicit argument
- * CASE a WHEN b THEN c ... ELSE d END
- * - Conditional NULL
- * NULLIF(x,y)
- * same as CASE WHEN x = y THEN NULL ELSE x END
- * - Conditional substitution from list, use first non-null argument
- * COALESCE(a,b,...)
- * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
- * - thomas 1998-11-09
*/
-case_expr: CASE case_arg when_clause_list case_default END_TRANS
- { $$ = cat_str(5, make_str("case"), $2, $3, $4, make_str("end")); }
- | NULLIF '(' a_expr ',' a_expr ')'
- {
- $$ = cat_str(5, make_str("nullif("), $3, make_str(","), $5, make_str(")"));
- }
- | COALESCE '(' expr_list ')'
- {
- $$ = cat_str(3, make_str("coalesce("), $3, make_str(")"));
- }
+case_expr: CASE case_arg when_clause_list case_default END_P
+ { $$ = cat_str(5, make_str("case"), $2, $3, $4, make_str("end")); }
;
when_clause_list: when_clause_list when_clause
- { $$ = cat2_str($1, $2); }
- | when_clause
- { $$ = $1; }
- ;
+ { $$ = cat2_str($1, $2); }
+ | when_clause
+ { $$ = $1; }
+ ;
when_clause: WHEN a_expr THEN a_expr
- {
- $$ = cat_str(4, make_str("when"), $2, make_str("then"), $4);
- }
- ;
+ { $$ = cat_str(4, make_str("when"), $2, make_str("then"), $4); }
+ ;
-case_default: ELSE a_expr { $$ = cat2_str(make_str("else"), $2); }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
+case_default: ELSE a_expr
+ { $$ = cat2_str(make_str("else"), $2); }
+ | /*EMPTY*/
+ { $$ = EMPTY; }
+ ;
-case_arg: a_expr {
- $$ = $1;
- }
- | /*EMPTY*/
- { $$ = EMPTY; }
- ;
+case_arg: a_expr { $$ = $1; }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
-attr: relation_name '.' attrs opt_indirection
- {
- $$ = cat_str(4, $1, make_str("."), $3, $4);
- }
- | ParamNo '.' attrs opt_indirection
- {
- $$ = cat_str(4, $1, make_str("."), $3, $4);
- }
+columnref: relation_name { $$ = $1; }
+ | relation_name indirection { $$ = cat2_str($1, $2); }
;
-attrs: attr_name
- { $$ = $1; }
- | attrs '.' attr_name
- { $$ = cat_str(3, $1, make_str("."), $3); }
- | attrs '.' '*'
- { $$ = make2_str($1, make_str(".*")); }
+indirection_el:
+ '.' attr_name { $$ = cat2_str(make_str("."), $2); }
+ | '.' '*' { $$ = make_str(".*"); }
+ | '[' a_expr ']' { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+ | '[' a_expr ':' a_expr ']' { $$ = cat_str(5, make_str("["), $2, make_str(":"), $4, make_str("]")); }
+ ;
+
+indirection: indirection_el { $$ = $1; }
+ | indirection indirection_el { $$ = cat2_str($1, $2); }
;
-opt_empty_parentheses: '(' ')' { $$ = make_str("()"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+opt_indirection:
+ /*EMPTY*/ { $$ = EMPTY; }
+ | opt_indirection indirection_el { $$ = cat2_str($1, $2);}
+ ;
+
+opt_asymmetric: ASYMMETRIC { $$ = make_str("asymmetric"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+ctext_expr:
+ a_expr { $$ = $1; }
+ | DEFAULT { $$ = make_str("default"); }
+ ;
+
+ctext_expr_list:
+ ctext_expr { $$ = $1; }
+ | ctext_expr_list ',' ctext_expr { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+ctext_row: '(' ctext_expr_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")"));};
/*****************************************************************************
*
- * target lists
+ * target lists for SELECT
*
*****************************************************************************/
-/* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
target_list: target_list ',' target_el
- { $$ = cat_str(3, $1, make_str(","), $3); }
+ { $$ = cat_str(3, $1, make_str(","), $3); }
| target_el
- { $$ = $1; }
+ { $$ = $1; }
;
-/* AS is not optional because shift/red conflict with unary ops */
-target_el: a_expr AS ColLabel
- {
- $$ = cat_str(3, $1, make_str("as"), $3);
- }
+target_el: a_expr AS ColLabel
+ { $$ = cat_str(3, $1, make_str("as"), $3); }
+ /*
+ * We support omitting AS only for column labels that aren't
+ * any known keyword. There is an ambiguity against postfix
+ * operators: is "a ! b" an infix expression, or a postfix
+ * expression and a column label? We prefer to resolve this
+ * as an infix expression, which we accomplish by assigning
+ * IDENT a precedence higher than POSTFIXOP.
+ */
+ | a_expr IDENT
+ { $$ = cat_str(3, $1, make_str("as"), $2); }
| a_expr
+ { $$ = $1; }
+ | '*'
+ { $$ = make_str("*"); }
+ ;
+
+/* INFORMIX workaround, no longer needed
+update_target_list: '(' inf_col_list ')' '=' '(' inf_val_list ')'
+ {
+ struct inf_compat_col *ptrc;
+ struct inf_compat_val *ptrv;
+ char *cols = make_str( "(" );
+ char *vals = make_str( "(" );
+
+ for (ptrc = informix_col, ptrv = informix_val; ptrc != NULL && ptrv != NULL; ptrc = ptrc->next, ptrv = ptrv->next)
+ {
+ if ( ptrc->next != NULL )
{
- $$ = $1;
- }
- | relation_name '.' '*'
- {
- $$ = make2_str($1, make_str(".*"));
+ cols = cat_str(4, cols, ptrc->name, ptrc->indirection, make_str(",") );
}
- | '*'
+ else
{
- $$ = make_str("*");
+ cols = cat_str(4, cols, ptrc->name, ptrc->indirection, make_str(")") );
}
+ if (ptrv->next != NULL )
+ vals = cat_str(3, vals, ptrv->val, make_str("," ) );
+ else
+ vals = cat_str( 3, vals, ptrv->val, make_str(")") );
+ }
+ $$ = cat_str( 3, cols, make_str("="), vals );
+ }
;
-/* Target list as found in UPDATE table SET ... */
-update_target_list: update_target_list ',' update_target_el
- { $$ = cat_str(3, $1, make_str(","),$3); }
- | update_target_el
- { $$ = $1; }
- | '*' { $$ = make_str("*"); }
+inf_col_list: ColId opt_indirection
+ {
+ struct inf_compat_col *ptr = mm_alloc(sizeof(struct inf_compat_col));
+
+ ptr->name = $1;
+ ptr->indirection = $2;
+ ptr->next = NULL;
+ informix_col = ptr;
+ }
+ | ColId opt_indirection ',' inf_col_list
+ {
+ struct inf_compat_col *ptr = mm_alloc(sizeof(struct inf_compat_col));
+
+ ptr->name = $1;
+ ptr->indirection = $2;
+ ptr->next = informix_col;
+ informix_col = ptr;
+ }
;
-update_target_el: ColId opt_indirection '=' a_expr
- {
- $$ = cat_str(4, $1, $2, make_str("="), $4);
- }
+inf_val_list: a_expr
+ {
+ struct inf_compat_val *ptr = mm_alloc(sizeof(struct inf_compat_val));
+
+ ptr->val = $1;
+ ptr->next = NULL;
+ informix_val = ptr;
+ }
+ | a_expr ',' inf_val_list
+ {
+ struct inf_compat_val *ptr = mm_alloc(sizeof(struct inf_compat_val));
+
+ ptr->val = $1;
+ ptr->next = informix_val;
+ informix_val = ptr;
+ }
;
+*/
/*****************************************************************************
*
- * Names and constants
+ * Names and constants
*
*****************************************************************************/
-relation_name: SpecialRuleRelation
- {
- $$ = $1;
- }
- | ColId
- {
- $$ = $1;
- }
+relation_name: SpecialRuleRelation { $$ = $1; }
+ | ColId { $$ = $1; }
;
+qualified_name_list: qualified_name
+ { $$ = $1; }
+ | qualified_name_list ',' qualified_name
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+qualified_name: relation_name
+ { $$ = $1; }
+ | relation_name indirection
+ { $$ = cat2_str($1, $2); }
+ ;
+
+name_list: name
+ { $$ = $1; }
+ | name_list ',' name
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+
name: ColId { $$ = $1; };
-database_name: ColId { $$ = $1; };
-access_method: ColId { $$ = $1; };
-attr_name: ColId { $$ = $1; };
-class: ColId { $$ = $1; };
-index_name: ColId { $$ = $1; };
+database_name: ColId { $$ = $1; };
+access_method: ColId { $$ = $1; };
+attr_name: ColLabel { $$ = $1; };
+index_name: ColId { $$ = $1; };
+
+file_name: StringConst { $$ = $1; };
+
+func_name: type_function_name
+ { $$ = $1; }
+ | relation_name indirection
+ { $$ = cat2_str($1, $2); }
+ ;
-file_name: StringConst { $$ = $1; };
/* Constants
* Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
*/
AexprConst: PosAllConst
- {
- $$ = $1;
- }
+ { $$ = $1; }
| ConstTypename StringConst
- {
- $$ = cat2_str($1, $2);
- }
- | ConstInterval StringConst opt_interval
- {
- $$ = cat_str(3, $1, $2, $3);
- }
+ { $$ = cat2_str($1, $2); }
+ | ConstInterval StringConst opt_interval
+ { $$ = cat_str(3, $1, $2, $3); }
| ConstInterval '(' PosIntConst ')' StringConst opt_interval
- {
- $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6);
- }
- | ParamNo
- { $$ = $1; }
+ { $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6); }
| TRUE_P
- {
- $$ = make_str("true");
- }
+ { $$ = make_str("true"); }
| FALSE_P
- {
- $$ = make_str("false");
- }
+ { $$ = make_str("false"); }
| NULL_P
- {
- $$ = make_str("null");
- }
+ { $$ = make_str("null"); }
| civarind
- { $$ = make_str("?"); }
+ { $$ = $1; }
;
-ParamNo: PARAM opt_indirection
- {
- $$ = cat2_str(make_name(), $2);
- }
- ;
+Iconst: ICONST { $$ = make_name();};
+Fconst: FCONST { $$ = make_name();};
+Bconst: BCONST { $$ = make_name();};
+Xconst: XCONST { $$ = make_name();};
+Sconst: SCONST
+ {
+ /* could have been input as '' or $$ */
+ $$ = (char *)mm_alloc(strlen($1) + 3);
+ $$[0]='\'';
+ strcpy($$+1, $1);
+ $$[strlen($1)+1]='\'';
+ $$[strlen($1)+2]='\0';
+ free($1);
+ }
+ | ECONST
+ {
+ /* escaped quote starting with E */
+ $$ = (char *)mm_alloc(strlen($1) + 4);
+ $$[0]='E';
+ $$[1]='\'';
+ strcpy($$+2, $1);
+ $$[strlen($1)+2]='\'';
+ $$[strlen($1)+3]='\0';
+ free($1);
+ }
+ | NCONST
+ {
+ /* escaped quote starting with rNE */
+ $$ = (char *)mm_alloc(strlen($1) + 4);
+ $$[0]='N';
+ $$[1]='\'';
+ strcpy($$+2, $1);
+ $$[strlen($1)+2]='\'';
+ $$[strlen($1)+3]='\0';
+ free($1);
+ }
+ | DOLCONST
+ {
+ $$ = $1;
+ }
+ ;
-Iconst: ICONST { $$ = make_name();};
-Fconst: FCONST { $$ = make_name();};
-Bitconst: BITCONST { $$ = make_name();};
-Sconst: SCONST {
- $$ = (char *)mm_alloc(strlen($1) + 3);
- $$[0]='\'';
- strcpy($$+1, $1);
- $$[strlen($1)+2]='\0';
- $$[strlen($1)+1]='\'';
- free($1);
- }
PosIntConst: Iconst { $$ = $1; }
- | civar { $$ = make_str("?"); }
+ | civar { $$ = $1; }
;
IntConst: PosIntConst { $$ = $1; }
| '-' PosIntConst { $$ = cat2_str(make_str("-"), $2); }
;
+IntConstVar: Iconst
+ {
+ char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+
+ sprintf(length, "%d", (int) strlen($1));
+ new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
+ $$ = $1;
+ }
+ | cvariable { $$ = $1; }
+ ;
+
+AllConstVar: Fconst
+ {
+ char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+
+ sprintf(length, "%d", (int) strlen($1));
+ new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
+ $$ = $1;
+ }
+ | IntConstVar { $$ = $1; }
+ | '-' Fconst
+ {
+ char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+ char *var = cat2_str(make_str("-"), $2);
+
+ sprintf(length, "%d", (int) strlen(var));
+ new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
+ $$ = var;
+ }
+ | '-' Iconst
+ {
+ char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+ char *var = cat2_str(make_str("-"), $2);
+
+ sprintf(length, "%d", (int) strlen(var));
+ new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
+ $$ = var;
+ }
+ | Sconst
+ {
+ char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+ char *var = $1 + 1;
+
+ var[strlen(var) - 1] = '\0';
+ sprintf(length, "%d", (int) strlen(var));
+ new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
+ $$ = var;
+ }
+ ;
+
StringConst: Sconst { $$ = $1; }
- | civar { $$ = make_str("?"); }
+ | civar { $$ = $1; }
;
-PosIntStringConst: Iconst { $$ = $1; }
- | Sconst { $$ = $1; }
- | civar { $$ = make_str("?"); }
- ;
+PosIntStringConst: Iconst { $$ = $1; }
+ | Sconst { $$ = $1; }
+ | civar { $$ = $1; }
+ ;
-NumConst: Fconst { $$ = $1; }
- | Iconst { $$ = $1; }
- | '-' Fconst { $$ = cat2_str(make_str("-"), $2); }
- | '-' Iconst { $$ = cat2_str(make_str("-"), $2); }
- | civar { $$ = make_str("?"); }
+NumConst: Fconst { $$ = $1; }
+ | Iconst { $$ = $1; }
+ | '-' Fconst { $$ = cat2_str(make_str("-"), $2); }
+ | '-' Iconst { $$ = cat2_str(make_str("-"), $2); }
+ | civar { $$ = $1; }
;
-AllConst: Sconst { $$ = $1; }
- | NumConst { $$ = $1; }
+AllConst: Sconst { $$ = $1; }
+ | NumConst { $$ = $1; }
;
-PosAllConst: Sconst { $$ = $1; }
- | Fconst { $$ = $1; }
- | Iconst { $$ = $1; }
- | Bitconst { $$ = $1; }
- | civar { $$ = make_str("?"); }
+PosAllConst: Sconst { $$ = $1; }
+ | Fconst { $$ = $1; }
+ | Iconst { $$ = $1; }
+ | Bconst { $$ = $1; }
+ | Xconst { $$ = $1; }
+ | func_name Sconst { $$ = cat2_str($1, $2); }
+ | func_name '(' expr_list ')' Sconst
+ { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
+ | civar { $$ = $1; }
;
-UserId: ColId { $$ = $1;};
+RoleId: ColId { $$ = $1;};
SpecialRuleRelation: OLD
- {
- if (!QueryIsRule)
- mmerror(PARSE_ERROR, ET_ERROR, "OLD used in non-rule query");
+ {
+ if (!QueryIsRule)
+ mmerror(PARSE_ERROR, ET_ERROR, "OLD used in non-rule query");
- $$ = make_str("old");
- }
+ $$ = make_str("old");
+ }
| NEW
- {
- if (!QueryIsRule)
- mmerror(PARSE_ERROR, ET_ERROR, "NEW used in non-rule query");
+ {
+ if (!QueryIsRule)
+ mmerror(PARSE_ERROR, ET_ERROR, "NEW used in non-rule query");
- $$ = make_str("new");
- }
+ $$ = make_str("new");
+ }
;
/*
*/
/*
- * the exec sql connect statement: connect to the given database
+ * the exec sql connect statement: connect to the given database
*/
ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
+ { $$ = cat_str(5, $3, make_str(","), $5, make_str(","), $4); }
+ | SQL_CONNECT TO DEFAULT
+ { $$ = make_str("NULL, NULL, NULL, \"DEFAULT\""); }
+ /* also allow ORACLE syntax */
+ | SQL_CONNECT ora_user
+ { $$ = cat_str(3, make_str("NULL,"), $2, make_str(", NULL")); }
+ | DATABASE connection_target
+ { $$ = cat2_str($2, make_str(", NULL, NULL, NULL")); }
+ ;
+
+connection_target: opt_database_name opt_server opt_port
{
- $$ = cat_str(5, $3, make_str(","), $5, make_str(","), $4);
- }
- | SQL_CONNECT TO DEFAULT
- {
- $$ = make_str("NULL,NULL,NULL,\"DEFAULT\"");
- }
- /* also allow ORACLE syntax */
- | SQL_CONNECT ora_user
- {
- $$ = cat_str(3, make_str("NULL,"), $2, make_str(",NULL"));
+ /* old style: dbname[@server][:port] */
+ if (strlen($2) > 0 && *($2) != '@')
+ mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\", found \"%s\"", $2);
+
+ /* C strings need to be handled differently */
+ if ($1[0] == '\"')
+ $$ = $1;
+ else
+ $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
}
+ | db_prefix ':' server opt_port '/' opt_database_name opt_options
+ {
+ /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
+ if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported");
+
+ if (strncmp($3, "//", strlen("//")) != 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "expected \"://\", found \"%s\"", $3);
-connection_target: database_name opt_server opt_port
- {
- /* old style: dbname[@server][:port] */
- if (strlen($2) > 0 && *($2) != '@')
- {
- sprintf(errortext, "Expected '@', found '%s'", $2);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ if (strncmp($1, "unix", strlen("unix")) == 0 &&
+ strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 &&
+ strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "unix domain sockets only work on \"localhost\" but not on \"%s\"", $3 + strlen("//"));
- $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
+ $$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6), $7, make_str("\"")));
}
- | db_prefix ':' server opt_port '/' database_name opt_options
- {
- /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
- if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0)
- {
- sprintf(errortext, "only protocols 'tcp' and 'unix' and database type 'postgresql' are supported");
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
-
- if (strncmp($3, "//", strlen("//")) != 0)
- {
- sprintf(errortext, "Expected '://', found '%s'", $3);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
-
- if (strncmp($1, "unix", strlen("unix")) == 0 &&
- strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 &&
- strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0)
- {
- sprintf(errortext, "unix domain sockets only work on 'localhost' but not on '%9.9s'", $3 + strlen("//"));
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
-
- $$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6), $7, make_str("\"")));
+ | char_variable
+ {
+ $$ = $1;
}
- | StringConst
+ | Sconst
{
- if ($1[0] == '\"')
+ /* We can only process double quoted strings not single quotes ones,
+ * so we change the quotes.
+ * Note, that the rule for Sconst adds these single quotes. */
+ $1[0] = '\"';
+ $1[strlen($1)-1] = '\"';
$$ = $1;
- else if (strcmp($1, "?") == 0) /* variable */
- {
- enum ECPGttype type = argsinsert->variable->type->type;
-
- /* if array see what's inside */
- if (type == ECPGt_array)
- type = argsinsert->variable->type->u.element->type;
-
- /* handle varchars */
- if (type == ECPGt_varchar)
- $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
- else
- $$ = mm_strdup(argsinsert->variable->name);
- }
- else
- $$ = make3_str(make_str("\""), $1, make_str("\""));
}
+ ;
+
+opt_database_name: database_name { $$ = $1; }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
db_prefix: ident cvariable
- {
- if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
- {
- sprintf(errortext, "Expected 'postgresql', found '%s'", $2);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
-
- if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
- {
- sprintf(errortext, "Illegal connection type %s", $1);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
-
- $$ = make3_str($1, make_str(":"), $2);
+ {
+ if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "expected \"postgresql\", found \"%s\"", $2);
+
+ if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "illegal connection type %s", $1);
+
+ $$ = make3_str($1, make_str(":"), $2);
}
-
+ ;
+
server: Op server_name
- {
- if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
- {
- sprintf(errortext, "Expected '@' or '://', found '%s'", $1);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ {
+ if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\" or \"://\", found \"%s\"", $1);
- $$ = make2_str($1, $2);
- }
+ $$ = make2_str($1, $2);
+ }
+ ;
-opt_server: server { $$ = $1; }
- | /* empty */ { $$ = EMPTY; }
+opt_server: server { $$ = $1; }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
-server_name: ColId { $$ = $1; }
- | ColId '.' server_name { $$ = make3_str($1, make_str("."), $3); }
- | IP { $$ = make_name(); }
+server_name: ColId { $$ = $1; }
+ | ColId '.' server_name { $$ = make3_str($1, make_str("."), $3); }
+ | IP { $$ = make_name(); }
+ ;
-opt_port: ':' PosIntConst { $$ = make2_str(make_str(":"), $2); }
- | /* empty */ { $$ = EMPTY; }
+opt_port: ':' PosIntConst { $$ = make2_str(make_str(":"), $2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
-opt_connection_name: AS connection_target { $$ = $2; }
- | /* empty */ { $$ = make_str("NULL"); }
+opt_connection_name: AS connection_object { $$ = $2; }
+ | /*EMPTY*/ { $$ = make_str("NULL"); }
+ ;
-opt_user: USER ora_user { $$ = $2; }
- | /* empty */ { $$ = make_str("NULL,NULL"); }
+opt_user: USER ora_user { $$ = $2; }
+ | /*EMPTY*/ { $$ = make_str("NULL, NULL"); }
+ ;
ora_user: user_name
+ { $$ = cat2_str($1, make_str(", NULL")); }
+ | user_name '/' user_name
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ | user_name SQL_IDENTIFIED BY user_name
+ { $$ = cat_str(3, $1, make_str(","), $4); }
+ | user_name USING user_name
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+user_name: RoleId
{
- $$ = cat2_str($1, make_str(", NULL"));
- }
- | user_name '/' user_name
- {
- $$ = cat_str(3, $1, make_str(","), $3);
- }
- | user_name SQL_IDENTIFIED BY user_name
- {
- $$ = cat_str(3, $1, make_str(","), $4);
- }
- | user_name USING user_name
- {
- $$ = cat_str(3, $1, make_str(","), $3);
- }
-
-user_name: UserId {
- if ($1[0] == '\"')
+ if ($1[0] == '\"')
$$ = $1;
- else
+ else
$$ = make3_str(make_str("\""), $1, make_str("\""));
- }
- | StringConst {
- if ($1[0] == '\"')
+ }
+ | StringConst
+ {
+ if ($1[0] == '\"')
$$ = $1;
- else if (strcmp($1, "?") == 0) /* variable */
- {
- enum ECPGttype type = argsinsert->variable->type->type;
-
- /* if array see what's inside */
- if (type == ECPGt_array)
- type = argsinsert->variable->type->u.element->type;
-
- /* handle varchars */
- if (type == ECPGt_varchar)
- $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
- else
- $$ = mm_strdup(argsinsert->variable->name);
- }
- else
- $$ = make3_str(make_str("\""), $1, make_str("\""));
+ else if ($1[1] == '$') /* variable */
+ {
+ enum ECPGttype type = argsinsert->variable->type->type;
+
+ /* if array see what's inside */
+ if (type == ECPGt_array)
+ type = argsinsert->variable->type->u.element->type;
+
+ /* handle varchars */
+ if (type == ECPGt_varchar)
+ $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
+ else
+ $$ = mm_strdup(argsinsert->variable->name);
}
+ else
+ $$ = make3_str(make_str("\""), $1, make_str("\""));
+ }
+ ;
char_variable: cvariable
- { /* check if we have a char variable */
+ {
+ /* check if we have a string variable */
struct variable *p = find_variable($1);
enum ECPGttype type = p->type->type;
- /* if array see what's inside */
- if (type == ECPGt_array)
- type = p->type->u.element->type;
-
- switch (type)
- {
- case ECPGt_char:
- case ECPGt_unsigned_char:
- $$ = $1;
- break;
- case ECPGt_varchar:
- $$ = make2_str($1, make_str(".arr"));
- break;
- default:
- mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
- break;
- }
+ /* If we have just one character this is not a string */
+ if (atol(p->type->size) == 1)
+ mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
+ else
+ {
+ /* if array see what's inside */
+ if (type == ECPGt_array)
+ type = p->type->u.element->type;
+
+ switch (type)
+ {
+ case ECPGt_char:
+ case ECPGt_unsigned_char:
+ $$ = $1;
+ break;
+ case ECPGt_varchar:
+ $$ = make2_str($1, make_str(".arr"));
+ break;
+ default:
+ mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
+ $$ = $1;
+ break;
+ }
+ }
}
+ ;
-opt_options: Op ColId
+opt_options: Op connect_options
{
if (strlen($1) == 0)
mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
-
+
if (strcmp($1, "?") != 0)
- {
- sprintf(errortext, "unrecognised token '%s'", $1);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
-
+ mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $1);
+
$$ = make2_str(make_str("?"), $2);
}
- | /* empty */ { $$ = EMPTY; }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+connect_options: ColId opt_opt_value
+ { $$ = make2_str($1, $2); }
+ | ColId opt_opt_value Op connect_options
+ {
+ if (strlen($3) == 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
+
+ if (strcmp($3, "&") != 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $3);
+
+ $$ = cat_str(3, make2_str($1, $2), $3, $4);
+ }
;
+opt_opt_value: /*EMPTY*/
+ { $$ = EMPTY; }
+ | '=' Iconst
+ { $$ = make2_str(make_str("="), $2); }
+ | '=' IDENT
+ { $$ = make2_str(make_str("="), $2); }
+ ;
/*
* Declare a prepared cursor. The syntax is different from the standard
* declare statement, so we create a new rule.
*/
-ECPGCursorStmt: DECLARE name opt_cursor CURSOR FOR ident
- {
- struct cursor *ptr, *this;
- struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
+ECPGCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR prepared_name
+ {
+ struct cursor *ptr, *this;
+ struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
+ const char *con = connection ? connection : "NULL";
- 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);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
- }
-
- this = (struct cursor *) mm_alloc(sizeof(struct cursor));
-
- /* initial definition */
- this->next = cur;
- this->name = $2;
- this->connection = connection;
- this->command = cat_str(4, make_str("declare"), mm_strdup($2), $3, make_str("cursor for ?"));
- this->argsresult = NULL;
-
- thisquery->type = &ecpg_query;
- thisquery->brace_level = 0;
- thisquery->next = NULL;
- thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($6));
- sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $6);
-
- this->argsinsert = NULL;
- add_variable(&(this->argsinsert), thisquery, &no_indicator);
-
- cur = this;
-
- $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
- }
+ for (ptr = cur; ptr != NULL; ptr = ptr->next)
+ {
+ if (strcmp($2, ptr->name) == 0)
+ /* re-definition is a bug */
+ mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" already defined", $2);
+ }
+
+ this = (struct cursor *) mm_alloc(sizeof(struct cursor));
+
+ /* initial definition */
+ this->next = cur;
+ this->name = $2;
+ this->connection = connection;
+ this->command = cat_str(6, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for $1"));
+ this->argsresult = NULL;
+
+ thisquery->type = &ecpg_query;
+ thisquery->brace_level = 0;
+ thisquery->next = NULL;
+ thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($7));
+ sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7);
+
+ this->argsinsert = NULL;
+ add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator);
+
+ cur = this;
+
+ $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
+ }
;
+ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring
+ {
+ /* execute immediate means prepare the statement and
+ * immediately execute it */
+ $$ = $3;
+ };
/*
- * the exec sql deallocate prepare command to deallocate a previously
- * prepared statement
+ * variable decalartion outside exec sql declare block
*/
-ECPGDeallocate: SQL_DEALLOCATE SQL_PREPARE ident { $$ = cat_str(3, make_str("ECPGdeallocate(__LINE__, \""), $3, make_str("\");")); };
+ECPGVarDeclaration: single_vt_declaration;
+
+single_vt_declaration: type_declaration { $$ = $1; }
+ | var_declaration { $$ = $1; }
+ ;
+
+precision: NumConst { $$ = $1; };
+
+opt_scale: ',' NumConst { $$ = $2; }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+ecpg_interval: opt_interval { $$ = $1; }
+ | YEAR_P TO MINUTE_P { $$ = make_str("year to minute"); }
+ | YEAR_P TO SECOND_P { $$ = make_str("year to second"); }
+ | DAY_P TO DAY_P { $$ = make_str("day to day"); }
+ | MONTH_P TO MONTH_P { $$ = make_str("month to month"); }
+ ;
/*
- * variable declaration inside the exec sql declare block
+ * variable declaration inside exec sql declare block
*/
ECPGDeclaration: sql_startdeclare
- {
- fputs("/* exec sql begin declare section */", yyout);
- }
- variable_declarations sql_enddeclare
- {
- fprintf(yyout, "%s/* exec sql end declare section */", $3);
- free($3);
- output_line_number();
- };
+ { fputs("/* exec sql begin declare section */", yyout); }
+ var_type_declarations sql_enddeclare
+ {
+ fprintf(yyout, "%s/* exec sql end declare section */", $3);
+ free($3);
+ output_line_number();
+ }
+ ;
-sql_startdeclare: ecpgstart BEGIN_TRANS DECLARE SQL_SECTION ';' {};
+sql_startdeclare: ecpgstart BEGIN_P DECLARE SQL_SECTION ';' {};
-sql_enddeclare: ecpgstart END_TRANS DECLARE SQL_SECTION ';' {};
+sql_enddeclare: ecpgstart END_P DECLARE SQL_SECTION ';' {};
-variable_declarations: /* empty */ { $$ = EMPTY; }
- | declarations { $$ = $1; }
- ;
+var_type_declarations: /*EMPTY*/ { $$ = EMPTY; }
+ | vt_declarations { $$ = $1; }
+ | CPP_LINE { $$ = $1; }
+ ;
-declarations: declaration { $$ = $1; }
- | declarations declaration { $$ = cat2_str($1, $2); }
- ;
+vt_declarations: var_declaration { $$ = $1; }
+ | type_declaration { $$ = $1; }
+ | vt_declarations var_declaration { $$ = cat2_str($1, $2); }
+ | vt_declarations type_declaration { $$ = cat2_str($1, $2); }
+ | vt_declarations CPP_LINE { $$ = cat2_str($1, $2); }
+ ;
+
+variable_declarations: var_declaration { $$ = $1; }
+ | variable_declarations var_declaration { $$ = cat2_str($1, $2); }
+ ;
-declaration: storage_clause storage_modifier
+type_declaration: S_TYPEDEF
{
- actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2));
- actual_startline[struct_level] = hashline_number();
+ /* reset this variable so we see if there was */
+ /* an initializer specified */
+ initializer = 0;
}
- type
+ var_type opt_pointer ECPGColLabelCommon opt_array_bounds ';'
{
- actual_type[struct_level].type_enum = $4.type_enum;
- actual_type[struct_level].type_dimension = $4.type_dimension;
- actual_type[struct_level].type_index = $4.type_index;
+ add_typedef($5, $6.index1, $6.index2, $3.type_enum, $3.type_dimension, $3.type_index, initializer, *$4 ? 1 : 0);
- /* we do not need the string "varchar" for output */
- /* so replace it with an empty string */
- if ($4.type_enum == ECPGt_varchar)
+ fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4 ? "*" : "", $5, $6.str);
+ output_line_number();
+ $$ = make_str("");
+ };
+
+var_declaration: storage_declaration
+ var_type
{
- free($4.type_str);
- $4.type_str=EMPTY;
+ actual_type[struct_level].type_enum = $2.type_enum;
+ actual_type[struct_level].type_dimension = $2.type_dimension;
+ actual_type[struct_level].type_index = $2.type_index;
+ actual_type[struct_level].type_sizeof = $2.type_sizeof;
+
+ actual_startline[struct_level] = hashline_number();
}
- }
- variable_list ';'
- {
- $$ = cat_str(6, actual_startline[struct_level], $1, $2, $4.type_str, $6, make_str(";\n"));
- };
+ variable_list ';'
+ {
+ $$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
+ }
+ | var_type
+ {
+ actual_type[struct_level].type_enum = $1.type_enum;
+ actual_type[struct_level].type_dimension = $1.type_dimension;
+ actual_type[struct_level].type_index = $1.type_index;
+ actual_type[struct_level].type_sizeof = $1.type_sizeof;
+
+ actual_startline[struct_level] = hashline_number();
+ }
+ variable_list ';'
+ {
+ $$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, make_str(";\n"));
+ }
+ | struct_union_type_with_symbol ';'
+ {
+ $$ = cat2_str($1, make_str(";"));
+ }
+ ;
+
+opt_bit_field: ':' Iconst { $$ =cat2_str(make_str(":"), $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+storage_declaration: storage_clause storage_modifier
+ {$$ = cat2_str ($1, $2); }
+ | storage_clause {$$ = $1; }
+ | storage_modifier {$$ = $1; }
+ ;
storage_clause : S_EXTERN { $$ = make_str("extern"); }
- | S_STATIC { $$ = make_str("static"); }
- | S_REGISTER { $$ = make_str("register"); }
- | S_AUTO { $$ = make_str("auto"); }
- | /* empty */ { $$ = EMPTY; }
- ;
+ | S_STATIC { $$ = make_str("static"); }
+ | S_REGISTER { $$ = make_str("register"); }
+ | S_AUTO { $$ = make_str("auto"); }
+ ;
-storage_modifier : S_CONST { $$ = make_str("const"); }
- | S_VOLATILE { $$ = make_str("volatile"); }
- | /* empty */ { $$ = EMPTY; }
- ;
+storage_modifier : S_CONST { $$ = make_str("const"); }
+ | S_VOLATILE { $$ = make_str("volatile"); }
+ ;
-type: simple_type
+var_type: simple_type
{
$$.type_enum = $1;
- $$.type_str = mm_strdup(ECPGtype_name($1));
- $$.type_dimension = -1;
- $$.type_index = -1;
+ $$.type_str = mm_strdup(ecpg_type_name($1));
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
}
- | struct_type
+ | struct_union_type
{
- $$.type_enum = ECPGt_struct;
$$.type_str = $1;
- $$.type_dimension = -1;
- $$.type_index = -1;
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+
+ if (strncmp($1, "struct", sizeof("struct")-1) == 0)
+ {
+ $$.type_enum = ECPGt_struct;
+ $$.type_sizeof = ECPGstruct_sizeof;
+ }
+ else
+ {
+ $$.type_enum = ECPGt_union;
+ $$.type_sizeof = NULL;
+ }
}
- | union_type
+ | enum_type
{
- $$.type_enum = ECPGt_union;
$$.type_str = $1;
- $$.type_dimension = -1;
- $$.type_index = -1;
+ $$.type_enum = ECPGt_int;
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
}
- | enum_type
+ | ECPGColLabelCommon '(' precision opt_scale ')'
{
- $$.type_str = $1;
- $$.type_enum = ECPGt_int;
- $$.type_dimension = -1;
- $$.type_index = -1;
+ if (strcmp($1, "numeric") == 0)
+ {
+ $$.type_enum = ECPGt_numeric;
+ $$.type_str = make_str("numeric");
+ }
+ else if (strcmp($1, "decimal") == 0)
+ {
+ $$.type_enum = ECPGt_decimal;
+ $$.type_str = make_str("decimal");
+ }
+ else
+ {
+ mmerror(PARSE_ERROR, ET_ERROR, "only numeric/decimal have precision/scale argument");
+ $$.type_enum = ECPGt_numeric;
+ $$.type_str = make_str("numeric");
+ }
+
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
}
- | ECPGColLabel
+ | ECPGColLabelCommon ecpg_interval
{
+ if (strlen($2) != 0 && strcmp ($1, "datetime") != 0 && strcmp ($1, "interval") != 0)
+ mmerror (PARSE_ERROR, ET_ERROR, "interval specification not allowed here");
+
/*
* Check for type names that the SQL grammar treats as
* unreserved keywords
if (strcmp($1, "varchar") == 0)
{
$$.type_enum = ECPGt_varchar;
- $$.type_str = make_str("varchar");
- $$.type_dimension = -1;
- $$.type_index = -1;
+ $$.type_str = EMPTY; /*make_str("varchar");*/
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
}
else if (strcmp($1, "float") == 0)
{
$$.type_enum = ECPGt_float;
$$.type_str = make_str("float");
- $$.type_dimension = -1;
- $$.type_index = -1;
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
}
else if (strcmp($1, "double") == 0)
{
$$.type_enum = ECPGt_double;
$$.type_str = make_str("double");
- $$.type_dimension = -1;
- $$.type_index = -1;
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
+ }
+ else if (strcmp($1, "numeric") == 0)
+ {
+ $$.type_enum = ECPGt_numeric;
+ $$.type_str = make_str("numeric");
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
+ }
+ else if (strcmp($1, "decimal") == 0)
+ {
+ $$.type_enum = ECPGt_decimal;
+ $$.type_str = make_str("decimal");
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
+ }
+ else if (strcmp($1, "date") == 0)
+ {
+ $$.type_enum = ECPGt_date;
+ $$.type_str = make_str("date");
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
+ }
+ else if (strcmp($1, "timestamp") == 0)
+ {
+ $$.type_enum = ECPGt_timestamp;
+ $$.type_str = make_str("timestamp");
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
+ }
+ else if (strcmp($1, "interval") == 0)
+ {
+ $$.type_enum = ECPGt_interval;
+ $$.type_str = make_str("interval");
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
+ }
+ else if (strcmp($1, "datetime") == 0)
+ {
+ $$.type_enum = ECPGt_timestamp;
+ $$.type_str = make_str("timestamp");
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = NULL;
}
else
{
$$.type_enum = this->type->type_enum;
$$.type_dimension = this->type->type_dimension;
$$.type_index = this->type->type_index;
+ if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0)
+ $$.type_sizeof = this->type->type_sizeof;
+ else
+ $$.type_sizeof = cat_str(3, make_str("sizeof("), mm_strdup(this->name), make_str(")"));
+
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
}
}
- ;
+ | s_struct_union_symbol
+ {
+ /* this is for named structs/unions */
+ char *name;
+ struct typedefs *this;
+ bool forward = (forward_name != NULL && strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0);
+
+ name = cat2_str($1.su, $1.symbol);
+ /* Do we have a forward definition? */
+ if (!forward)
+ {
+ /* No */
-enum_type: SQL_ENUM opt_symbol enum_definition
- {
- $$ = cat_str(3, make_str("enum"), $2, $3);
- }
- | SQL_ENUM symbol
- {
- $$ = cat2_str(make_str("enum"), $2);
- }
- ;
+ this = get_typedef(name);
+ $$.type_str = mm_strdup(this->name);
+ $$.type_enum = this->type->type_enum;
+ $$.type_dimension = this->type->type_dimension;
+ $$.type_index = this->type->type_index;
+ $$.type_sizeof = this->type->type_sizeof;
+ struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
+ free(name);
+ }
+ else
+ {
+ $$.type_str = name;
+ $$.type_enum = ECPGt_long;
+ $$.type_dimension = make_str("-1");
+ $$.type_index = make_str("-1");
+ $$.type_sizeof = make_str("");
+ struct_member_list[struct_level] = NULL;
+ }
+ }
+ ;
-enum_definition: '{' c_list '}' { $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
+enum_type: ENUM_P symbol enum_definition
+ { $$ = cat_str(3, make_str("enum"), $2, $3); }
+ | ENUM_P enum_definition
+ { $$ = cat2_str(make_str("enum"), $2); }
+ | ENUM_P symbol
+ { $$ = cat2_str(make_str("enum"), $2); }
+ ;
-struct_type: s_struct '{' variable_declarations '}'
- {
- ECPGfree_struct_member(struct_member_list[struct_level]);
- free(actual_storage[struct_level--]);
- $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
- };
+enum_definition: '{' c_list '}'
+ { $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
-union_type: s_union '{' variable_declarations '}'
- {
- ECPGfree_struct_member(struct_member_list[struct_level]);
- free(actual_storage[struct_level--]);
- $$ = cat_str(4, $1, make_str("{"), $3, make_str("}"));
- };
+struct_union_type_with_symbol: s_struct_union_symbol
+ {
+ struct_member_list[struct_level++] = NULL;
+ if (struct_level >= STRUCT_DEPTH)
+ mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition");
+ forward_name = mm_strdup($1.symbol);
+ }
+ '{' variable_declarations '}'
+ {
+ struct typedefs *ptr, *this;
+ struct this_type su_type;
+
+ ECPGfree_struct_member(struct_member_list[struct_level]);
+ struct_member_list[struct_level] = NULL;
+ struct_level--;
+ if (strncmp($1.su, "struct", sizeof("struct")-1) == 0)
+ su_type.type_enum = ECPGt_struct;
+ else
+ su_type.type_enum = ECPGt_union;
+ su_type.type_str = cat2_str($1.su, $1.symbol);
+ free(forward_name);
+ forward_name = NULL;
-s_struct: SQL_STRUCT opt_symbol
- {
- struct_member_list[struct_level++] = NULL;
- $$ = cat2_str(make_str("struct"), $2);
- ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), strdup($$), make_str(")"));
- if (struct_level >= STRUCT_DEPTH)
- mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition");
- };
+ /* This is essantially a typedef but needs the keyword struct/union as well.
+ * So we create the typedef for each struct definition with symbol */
+ for (ptr = types; ptr != NULL; ptr = ptr->next)
+ {
+ if (strcmp(su_type.type_str, ptr->name) == 0)
+ /* re-definition is a bug */
+ mmerror(PARSE_ERROR, ET_ERROR, "type \"%s\" already defined", su_type.type_str);
+ }
-s_union: UNION opt_symbol
- {
- struct_member_list[struct_level++] = NULL;
- if (struct_level >= STRUCT_DEPTH)
- mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure definition");
+ this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
- $$ = cat2_str(make_str("union"), $2);
- };
+ /* initial definition */
+ this->next = types;
+ this->name = mm_strdup(su_type.type_str);
+ this->brace_level = braces_open;
+ this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
+ this->type->type_enum = su_type.type_enum;
+ this->type->type_str = mm_strdup(su_type.type_str);
+ this->type->type_dimension = make_str("-1"); /* dimension of array */
+ this->type->type_index = make_str("-1"); /* length of string */
+ this->type->type_sizeof = ECPGstruct_sizeof;
+ this->struct_member_list = struct_member_list[struct_level];
+
+ types = this;
+ $$ = cat_str(4, su_type.type_str, make_str("{"), $4, make_str("}"));
+ }
+ ;
-simple_type: unsigned_type { $$=$1; }
- | opt_signed signed_type { $$=$2; }
- ;
+struct_union_type: struct_union_type_with_symbol { $$ = $1; }
+ | s_struct_union
+ {
+ struct_member_list[struct_level++] = NULL;
+ if (struct_level >= STRUCT_DEPTH)
+ mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition");
+ }
+ '{' variable_declarations '}'
+ {
+ ECPGfree_struct_member(struct_member_list[struct_level]);
+ struct_member_list[struct_level] = NULL;
+ struct_level--;
+ $$ = cat_str(4, $1, make_str("{"), $4, make_str("}"));
+ }
+ ;
+
+s_struct_union_symbol: SQL_STRUCT symbol
+ {
+ $$.su = make_str("struct");
+ $$.symbol = $2;
+ ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), cat2_str(mm_strdup($$.su), mm_strdup($$.symbol)), make_str(")"));
+ }
+ | UNION symbol
+ {
+ $$.su = make_str("union");
+ $$.symbol = $2;
+ }
+ ;
+
+s_struct_union: SQL_STRUCT
+ {
+ ECPGstruct_sizeof = make_str(""); /* This must not be NULL to distinguish from simple types. */
+ $$ = make_str("struct");
+ }
+ | UNION { $$ = make_str("union"); }
+ ;
-unsigned_type: SQL_UNSIGNED SQL_SHORT { $$ = ECPGt_unsigned_short; }
- | SQL_UNSIGNED SQL_SHORT SQL_INT { $$ = ECPGt_unsigned_short; }
- | SQL_UNSIGNED { $$ = ECPGt_unsigned_int; }
- | SQL_UNSIGNED SQL_INT { $$ = ECPGt_unsigned_int; }
+simple_type: unsigned_type { $$=$1; }
+ | opt_signed signed_type { $$=$2; }
+ ;
+
+unsigned_type: SQL_UNSIGNED SQL_SHORT { $$ = ECPGt_unsigned_short; }
+ | SQL_UNSIGNED SQL_SHORT INT_P { $$ = ECPGt_unsigned_short; }
+ | SQL_UNSIGNED { $$ = ECPGt_unsigned_int; }
+ | SQL_UNSIGNED INT_P { $$ = ECPGt_unsigned_int; }
| SQL_UNSIGNED SQL_LONG { $$ = ECPGt_unsigned_long; }
- | SQL_UNSIGNED SQL_LONG SQL_INT { $$ = ECPGt_unsigned_long; }
- | SQL_UNSIGNED SQL_LONG SQL_LONG {
+ | SQL_UNSIGNED SQL_LONG INT_P { $$ = ECPGt_unsigned_long; }
+ | SQL_UNSIGNED SQL_LONG SQL_LONG
+ {
#ifdef HAVE_LONG_LONG_INT_64
- $$ = ECPGt_unsigned_long_long;
+ $$ = ECPGt_unsigned_long_long;
#else
- $$ = ECPGt_unsigned_long;
+ $$ = ECPGt_unsigned_long;
#endif
- }
- | SQL_UNSIGNED SQL_LONG SQL_LONG SQL_INT {
+ }
+ | SQL_UNSIGNED SQL_LONG SQL_LONG INT_P
+ {
#ifdef HAVE_LONG_LONG_INT_64
- $$ = ECPGt_unsigned_long_long;
+ $$ = ECPGt_unsigned_long_long;
#else
- $$ = ECPGt_unsigned_long;
+ $$ = ECPGt_unsigned_long;
#endif
- }
- | SQL_UNSIGNED CHAR { $$ = ECPGt_unsigned_char; }
+ }
+ | SQL_UNSIGNED CHAR_P { $$ = ECPGt_unsigned_char; }
;
-signed_type: SQL_SHORT { $$ = ECPGt_short; }
- | SQL_SHORT SQL_INT { $$ = ECPGt_short; }
- | SQL_INT { $$ = ECPGt_int; }
- | SQL_LONG { $$ = ECPGt_long; }
- | SQL_LONG SQL_INT { $$ = ECPGt_long; }
- | SQL_LONG SQL_LONG {
+signed_type: SQL_SHORT { $$ = ECPGt_short; }
+ | SQL_SHORT INT_P { $$ = ECPGt_short; }
+ | INT_P { $$ = ECPGt_int; }
+ | SQL_LONG { $$ = ECPGt_long; }
+ | SQL_LONG INT_P { $$ = ECPGt_long; }
+ | SQL_LONG SQL_LONG
+ {
#ifdef HAVE_LONG_LONG_INT_64
- $$ = ECPGt_long_long;
+ $$ = ECPGt_long_long;
#else
- $$ = ECPGt_long;
+ $$ = ECPGt_long;
#endif
- }
- | SQL_LONG SQL_LONG SQL_INT {
+ }
+ | SQL_LONG SQL_LONG INT_P
+ {
#ifdef HAVE_LONG_LONG_INT_64
- $$ = ECPGt_long_long;
+ $$ = ECPGt_long_long;
#else
- $$ = ECPGt_long;
+ $$ = ECPGt_long;
#endif
- }
- | SQL_BOOL { $$ = ECPGt_bool; }
- | CHAR { $$ = ECPGt_char; }
- ;
+ }
+ | SQL_BOOL { $$ = ECPGt_bool; }
+ | CHAR_P { $$ = ECPGt_char; }
+ | DOUBLE_P { $$ = ECPGt_double; }
+ ;
-opt_signed: SQL_SIGNED
- | /* EMPTY */
- ;
+opt_signed: SQL_SIGNED
+ | /* EMPTY */
+ ;
-variable_list: variable
- {
- $$ = $1;
- }
- | variable_list ',' variable
- {
- $$ = cat_str(3, $1, make_str(","), $3);
- }
- ;
+variable_list: variable
+ { $$ = $1; }
+ | variable_list ',' variable
+ { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
-variable: opt_pointer ECPGColLabel opt_array_bounds opt_initializer
+variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initializer
{
struct ECPGtype * type;
- int dimension = $3.index1; /* dimension of array */
- int length = $3.index2; /* lenght of string */
- char dim[14L], ascii_len[12];
+ char *dimension = $3.index1; /* dimension of array */
+ char *length = $3.index2; /* length of string */
+ char dim[14L];
+ char *vcn;
- adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
+ adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1), false);
switch (actual_type[struct_level].type_enum)
{
- case ECPGt_struct:
- case ECPGt_union:
- if (dimension < 0)
- type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, ECPGstruct_sizeof);
- else
- type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, ECPGstruct_sizeof), dimension);
-
- $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
- break;
- case ECPGt_varchar:
- if (dimension < 0)
- type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
- else
- type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
-
- switch(dimension)
- {
- case 0:
- case -1:
- case 1:
- *dim = '\0';
- break;
- default:
- sprintf(dim, "[%d]", dimension);
- break;
- }
- sprintf(ascii_len, "%d", length);
-
- if (length == 0)
- mmerror(PARSE_ERROR, ET_ERROR, "pointer to varchar are not implemented");
-
- if (dimension == 0)
- $$ = cat_str(7, mm_strdup(actual_storage[struct_level]), make2_str(make_str(" struct varchar_"), mm_strdup($2)), make_str(" { int len; char arr["), mm_strdup(ascii_len), make_str("]; } *"), mm_strdup($2), $4);
- else
- $$ = cat_str(8, mm_strdup(actual_storage[struct_level]), make2_str(make_str(" struct varchar_"), mm_strdup($2)), make_str(" { int len; char arr["), mm_strdup(ascii_len), make_str("]; } "), mm_strdup($2), mm_strdup(dim), $4);
-
- break;
- case ECPGt_char:
- case ECPGt_unsigned_char:
- if (dimension == -1)
- type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
- else
- type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
-
- $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
- break;
- default:
- if (dimension < 0)
- type = ECPGmake_simple_type(actual_type[struct_level].type_enum, 1);
- else
- type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, 1), dimension);
-
- $$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
- break;
+ case ECPGt_struct:
+ case ECPGt_union:
+ if (atoi(dimension) < 0)
+ type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_sizeof);
+ else
+ type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_sizeof), dimension);
+
+ $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
+ break;
+
+ case ECPGt_varchar:
+ if (atoi(dimension) < 0)
+ type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, yylineno);
+ else
+ type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, yylineno), dimension);
+
+ if (strcmp(dimension, "0") == 0 || abs(atoi(dimension)) == 1)
+ *dim = '\0';
+ else
+ sprintf(dim, "[%s]", dimension);
+ /* cannot check for atoi <= 0 because a defined constant will yield 0 here as well */
+ if (atoi(length) < 0 || strcmp(length, "0") == 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "pointer to varchar are not implemented");
+
+ /* make sure varchar struct name is unique by adding linenumer of its definition */
+ vcn = (char *) mm_alloc(strlen($2) + sizeof(int) * CHAR_BIT * 10 / 3);
+ sprintf(vcn, "%s_%d", $2, yylineno);
+ if (strcmp(dimension, "0") == 0)
+ $$ = cat_str(7, make2_str(make_str(" struct varchar_"), vcn), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } *"), mm_strdup($2), $4, $5);
+ else
+ $$ = cat_str(8, make2_str(make_str(" struct varchar_"), vcn), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } "), mm_strdup($2), mm_strdup(dim), $4, $5);
+ break;
+
+ case ECPGt_char:
+ case ECPGt_unsigned_char:
+ if (atoi(dimension) == -1)
+ {
+ int i = strlen($5);
+
+ if (atoi(length) == -1 && i > 0) /* char <var>[] = "string" */
+ {
+ /* if we have an initializer but no string size set, let's use the initializer's length */
+ free(length);
+ length = mm_alloc(i+sizeof("sizeof()"));
+ sprintf(length, "sizeof(%s)", $5+2);
+ }
+ type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0);
+ }
+ else
+ type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0), dimension);
+
+ $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
+ break;
+
+ default:
+ if (atoi(dimension) < 0)
+ type = ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"), 0);
+ else
+ type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"), 0), dimension);
+
+ $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
+ break;
}
if (struct_level == 0)
ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
free($2);
- };
+ }
+ ;
-opt_initializer: /* empty */ { $$ = EMPTY; }
- | '=' c_term {
- initializer = 1;
- $$ = cat2_str(make_str("="), $2);
- }
- ;
+opt_initializer: /*EMPTY*/
+ { $$ = EMPTY; }
+ | '=' c_term
+ {
+ initializer = 1;
+ $$ = cat2_str(make_str("="), $2);
+ }
+ ;
-opt_pointer: /* empty */ { $$ = EMPTY; }
- | '*' { $$ = make_str("*"); }
- | '*' '*' { $$ = make_str("**"); }
- ;
+opt_pointer: /*EMPTY*/ { $$ = EMPTY; }
+ | '*' { $$ = make_str("*"); }
+ | '*' '*' { $$ = make_str("**"); }
+ ;
/*
- * As long as the prepare statement is not supported by the backend, we will
- * try to simulate it here so we get dynamic SQL
+ * We try to simulate the correct DECLARE syntax here so we get dynamic SQL
*/
ECPGDeclare: DECLARE STATEMENT ident
- {
- /* this is only supported for compatibility */
- $$ = cat_str(3, make_str("/* declare statement"), $3, make_str("*/"));
- };
+ {
+ /* this is only supported for compatibility */
+ $$ = cat_str(3, make_str("/* declare statement"), $3, make_str("*/"));
+ }
+ ;
/*
- * the exec sql disconnect statement: disconnect from the given database
+ * the exec sql disconnect statement: disconnect from the given database
*/
ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
+ ;
-dis_name: connection_object { $$ = $1; }
- | CURRENT { $$ = make_str("\"CURRENT\""); }
- | ALL { $$ = make_str("\"ALL\""); }
- | /* empty */ { $$ = make_str("\"CURRENT\""); }
- ;
+dis_name: connection_object { $$ = $1; }
+ | CURRENT_P { $$ = make_str("\"CURRENT\""); }
+ | ALL { $$ = make_str("\"ALL\""); }
+ | /* EMPTY */ { $$ = make_str("\"CURRENT\""); }
+ ;
-connection_object: connection_target { $$ = $1; }
- | DEFAULT { $$ = make_str("\"DEFAULT\""); }
- ;
+connection_object: database_name { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+ | DEFAULT { $$ = make_str("\"DEFAULT\""); }
+ | char_variable { $$ = $1; }
+ ;
+
+execute_rest: ecpg_using ecpg_into { $$ = EMPTY; }
+ | ecpg_into ecpg_using { $$ = EMPTY; }
+ | ecpg_using { $$ = EMPTY; }
+ | ecpg_into { $$ = EMPTY; }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+execstring: char_variable
+ { $$ = $1; }
+ | CSTRING
+ { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+ ;
+
+prepared_name: name {
+ if ($1[0] == '\"' && $1[strlen($1)-1] == '\"') /* already quoted? */
+ $$ = $1;
+ else /* not quoted => convert to lowercase */
+ {
+ int i;
+
+ for (i = 0; i< strlen($1); i++)
+ $1[i] = tolower((unsigned char) $1[i]);
+
+ $$ = make3_str(make_str("\""), $1, make_str("\""));
+ }
+ }
+ | char_variable { $$ = $1; }
+ ;
/*
- * execute a given string as sql command
+ * the exec sql free command to deallocate a previously
+ * prepared statement
*/
-ECPGExecute : EXECUTE IMMEDIATE execstring
- {
- struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
+ECPGFree: SQL_FREE name { $$ = $2; }
+ | SQL_FREE ALL { $$ = make_str("all"); }
+ ;
- thisquery->type = &ecpg_query;
- thisquery->brace_level = 0;
- thisquery->next = NULL;
- thisquery->name = $3;
+/*
+ * open is an open cursor, at the moment this has to be removed
+ */
+ECPGOpen: SQL_OPEN name opt_ecpg_using { $$ = $2; };
- add_variable(&argsinsert, thisquery, &no_indicator);
+opt_ecpg_using: /*EMPTY*/ { $$ = EMPTY; }
+ | ecpg_using { $$ = $1; }
+ ;
- $$ = make_str("?");
- }
- | EXECUTE ident
- {
- struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
+ecpg_using: USING using_list { $$ = EMPTY; }
+ | using_descriptor { $$ = $1; }
+ ;
+
+using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
+ {
+ add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
+ $$ = EMPTY;
+ }
+ ;
+
+into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
+ {
+ add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
+ $$ = EMPTY;
+ }
+ ;
- thisquery->type = &ecpg_query;
- thisquery->brace_level = 0;
- thisquery->next = NULL;
- thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($2));
- sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2);
+opt_sql: /*EMPTY*/ | SQL_SQL;
- add_variable(&argsinsert, thisquery, &no_indicator);
- } ecpg_using opt_ecpg_into
+ecpg_into: INTO into_list { $$ = EMPTY; }
+ | into_descriptor { $$ = $1; }
+ ;
+
+using_list: UsingConst | UsingConst ',' using_list;
+
+UsingConst: AllConst
+ {
+ if ($1[1] != '$') /* found a constant */
+ {
+ char *length = mm_alloc(32);
+
+ sprintf(length, "%d", (int) strlen($1));
+ add_variable_to_head(&argsinsert, new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator);
+ }
+ }
+ | civarind { $$ = EMPTY; }
+ ;
+
+
+/*
+ * We accept descibe but do nothing with it so far.
+ */
+ECPGDescribe: SQL_DESCRIBE INPUT_P name using_descriptor
+ {
+ const char *con = connection ? connection : "NULL";
+ mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement\n");
+ $$ = (char *) mm_alloc(sizeof("1, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
+ sprintf($$, "1, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
+ }
+ | SQL_DESCRIBE opt_output name using_descriptor
{
- $$ = make_str("?");
+ const char *con = connection ? connection : "NULL";
+ mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement\n");
+ $$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
+ sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
+ }
+ | SQL_DESCRIBE opt_output name into_descriptor
+ {
+ const char *con = connection ? connection : "NULL";
+ mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement\n");
+ $$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
+ sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
}
;
-execstring: char_variable { $$ = $1; }
- | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+opt_output: SQL_OUTPUT { $$ = make_str("output"); }
+ | /* EMPTY */ { $$ = EMPTY; }
;
/*
- * the exec sql free command to deallocate a previously
- * prepared statement
+ * dynamic SQL: descriptor based access
+ * originall written by Christof Petig <christof.petig@wtal.de>
+ * and Peter Eisentraut <peter.eisentraut@credativ.de>
*/
-ECPGFree: SQL_FREE ident { $$ = $2; };
/*
- * open is an open cursor, at the moment this has to be removed
+ * allocate a descriptor
*/
-ECPGOpen: SQL_OPEN name ecpg_using { $$ = $2; };
+ECPGAllocateDescr: SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
+ {
+ add_descriptor($3,connection);
+ $$ = $3;
+ }
+ ;
-ecpg_using: /* empty */ { $$ = EMPTY; }
- | USING variablelist {
- /* mmerror ("open cursor with variables not implemented yet"); */
- $$ = EMPTY;
- }
- ;
-opt_sql: /* empty */ | SQL_SQL;
+/*
+ * deallocate a descriptor
+ */
+ECPGDeallocateDescr: DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
+ {
+ drop_descriptor($3,connection);
+ $$ = $3;
+ }
+ ;
-ecpg_into: INTO into_list {
- $$ = EMPTY;
- }
- | INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
- {
- add_variable(&argsresult, descriptor_variable($4,0), &no_indicator);
- $$ = EMPTY;
- }
- ;
+/*
+ * manipulate a descriptor header
+ */
+
+ECPGGetDescriptorHeader: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
+ { $$ = $3; }
+ ;
+
+ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
+ | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
+ ;
+
+ECPGGetDescHeaderItem: cvariable '=' desc_header_item
+ { push_assignment($1, $3); }
+ ;
+
+
+ECPGSetDescriptorHeader: SET SQL_DESCRIPTOR quoted_ident_stringvar ECPGSetDescHeaderItems
+ { $$ = $3; }
+ ;
-opt_ecpg_into: /* empty */ { $$ = EMPTY; }
- | ecpg_into { $$ = $1; }
+ECPGSetDescHeaderItems: ECPGSetDescHeaderItem
+ | ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem
;
-variable: civarind | civar
-variablelist: variable | variable ',' variablelist;
+ECPGSetDescHeaderItem: desc_header_item '=' IntConstVar
+ {
+ push_assignment($3, $1);
+ }
+ ;
-/*
- * As long as the prepare statement is not supported by the backend, we will
- * try to simulate it here so we get dynamic SQL
- */
-ECPGPrepare: SQL_PREPARE ident FROM execstring
- {
- $$ = cat2_str(make3_str(make_str("\""), $2, make_str("\",")), $4);
- };
-/*
- * dynamic SQL: descriptor based access
- * written by Christof Petig <christof.petig@wtal.de>
- */
+desc_header_item: SQL_COUNT { $$ = ECPGd_count; }
+ ;
/*
- * deallocate a descriptor
+ * manipulate a descriptor
*/
-ECPGDeallocateDescr: SQL_DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
- {
- drop_descriptor($3,connection);
- $$ = $3;
- };
-/*
- * allocate a descriptor
- */
-ECPGAllocateDescr: SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
- {
- add_descriptor($3,connection);
- $$ = $3;
- };
+ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems
+ { $$.str = $5; $$.name = $3; }
+ ;
-/*
- * read from descriptor
- */
+ECPGGetDescItems: ECPGGetDescItem
+ | ECPGGetDescItems ',' ECPGGetDescItem
+ ;
-ECPGGetDescHeaderItem: cvariable '=' desc_header_item { push_assignment($1, $3); };
+ECPGGetDescItem: cvariable '=' descriptor_item { push_assignment($1, $3); };
-desc_header_item: SQL_COUNT { $$ = ECPGd_count; };
-ECPGGetDescItem: cvariable '=' descriptor_item { push_assignment($1, $3); };
+ECPGSetDescriptor: SET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGSetDescItems
+ { $$.str = $5; $$.name = $3; }
+ ;
-descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; }
- | SQL_DATA { $$ = ECPGd_data; }
- | SQL_DATETIME_INTERVAL_CODE { $$ = ECPGd_di_code; }
- | SQL_DATETIME_INTERVAL_PRECISION { $$ = ECPGd_di_precision; }
- | SQL_INDICATOR { $$ = ECPGd_indicator; }
- | SQL_KEY_MEMBER { $$ = ECPGd_key_member; }
- | SQL_LENGTH { $$ = ECPGd_length; }
- | SQL_NAME { $$ = ECPGd_name; }
- | SQL_NULLABLE { $$ = ECPGd_nullable; }
- | SQL_OCTET_LENGTH { $$ = ECPGd_octet; }
- | PRECISION { $$ = ECPGd_precision; }
- | SQL_RETURNED_LENGTH { $$ = ECPGd_length; }
- | SQL_RETURNED_OCTET_LENGTH { $$ = ECPGd_ret_octet; }
- | SQL_SCALE { $$ = ECPGd_scale; }
- | TYPE_P { $$ = ECPGd_type; }
+ECPGSetDescItems: ECPGSetDescItem
+ | ECPGSetDescItems ',' ECPGSetDescItem
;
-ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
- | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
- ;
-
-ECPGGetDescItems: ECPGGetDescItem
- | ECPGGetDescItems ',' ECPGGetDescItem
- ;
-
-ECPGGetDescriptorHeader: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
- { $$ = $3; };
-
-ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE cvariable ECPGGetDescItems
- { $$.str = $5; $$.name = $3; }
- | SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE Iconst ECPGGetDescItems
- { $$.str = $5; $$.name = $3; }
- ;
+ECPGSetDescItem: descriptor_item '=' AllConstVar
+ {
+ push_assignment($3, $1);
+ }
+ ;
-/*
- * for compatibility with ORACLE we will also allow the keyword RELEASE
- * after a transaction statement to disconnect from the database.
- */
-ECPGRelease: TransactionStmt SQL_RELEASE
- {
- if (strcmp($1, "begin") == 0)
- mmerror(PARSE_ERROR, ET_ERROR, "RELEASE does not make sense when beginning a transaction");
-
- fprintf(yyout, "ECPGtrans(__LINE__, %s, \"%s\");",
- connection ? connection : "NULL", $1);
- whenever_action(0);
- fprintf(yyout, "ECPGdisconnect(__LINE__, \"\");");
- whenever_action(0);
- free($1);
- };
+descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; }
+ | SQL_DATA { $$ = ECPGd_data; }
+ | SQL_DATETIME_INTERVAL_CODE { $$ = ECPGd_di_code; }
+ | SQL_DATETIME_INTERVAL_PRECISION { $$ = ECPGd_di_precision; }
+ | SQL_INDICATOR { $$ = ECPGd_indicator; }
+ | SQL_KEY_MEMBER { $$ = ECPGd_key_member; }
+ | SQL_LENGTH { $$ = ECPGd_length; }
+ | NAME_P { $$ = ECPGd_name; }
+ | SQL_NULLABLE { $$ = ECPGd_nullable; }
+ | SQL_OCTET_LENGTH { $$ = ECPGd_octet; }
+ | PRECISION { $$ = ECPGd_precision; }
+ | SQL_RETURNED_LENGTH { $$ = ECPGd_length; }
+ | SQL_RETURNED_OCTET_LENGTH { $$ = ECPGd_ret_octet; }
+ | SQL_SCALE { $$ = ECPGd_scale; }
+ | TYPE_P { $$ = ECPGd_type; }
+ ;
-/*
+/*
* set/reset the automatic transaction mode, this needs a differnet handling
* as the other set commands
*/
-ECPGSetAutocommit: SET SQL_AUTOCOMMIT to_equal on_off
- {
- $$ = $4;
- };
-
-on_off: ON { $$ = make_str("on"); }
- | OFF { $$ = make_str("off"); }
- ;
+ECPGSetAutocommit: SET SQL_AUTOCOMMIT '=' on_off { $$ = $4; }
+ | SET SQL_AUTOCOMMIT TO on_off { $$ = $4; }
+ ;
-to_equal: TO | '=';
+on_off: ON { $$ = make_str("on"); }
+ | OFF { $$ = make_str("off"); }
+ ;
-/*
+/*
* set the actual connection, this needs a differnet handling as the other
* set commands
*/
-ECPGSetConnection: SET SQL_CONNECTION to_equal connection_object
- {
- $$ = $4;
- };
+ECPGSetConnection: SET CONNECTION TO connection_object { $$ = $4; }
+ | SET CONNECTION '=' connection_object { $$ = $4; }
+ | SET CONNECTION connection_object { $$ = $3; }
+ ;
/*
* define a new type for embedded SQL
*/
ECPGTypedef: TYPE_P
- {
- /* reset this variable so we see if there was */
- /* an initializer specified */
- initializer = 0;
- }
- ColLabel IS type opt_type_array_bounds opt_reference
- {
- /* add entry to list */
- struct typedefs *ptr, *this;
- int dimension = $6.index1;
- int length = $6.index2;
-
- if (($5.type_enum == ECPGt_struct ||
- $5.type_enum == ECPGt_union) &&
- initializer == 1)
{
- mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
+ /* reset this variable so we see if there was */
+ /* an initializer specified */
+ initializer = 0;
}
- else
+ ECPGColLabelCommon IS var_type opt_array_bounds opt_reference
{
- for (ptr = types; ptr != NULL; ptr = ptr->next)
- {
- if (strcmp($3, ptr->name) == 0)
- {
- /* re-definition is a bug */
- sprintf(errortext, "Type %s already defined", $3);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
- }
-
- adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0);
+ add_typedef($3, $6.index1, $6.index2, $5.type_enum, $5.type_dimension, $5.type_index, initializer, *$7 ? 1 : 0);
- this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
-
- /* initial definition */
- this->next = types;
- this->name = $3;
- this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
- this->type->type_enum = $5.type_enum;
- this->type->type_str = mm_strdup($3);
- this->type->type_dimension = dimension; /* dimension of array */
- this->type->type_index = length; /* lenght of string */
- this->struct_member_list = ($5.type_enum == ECPGt_struct || $5.type_enum == ECPGt_union) ?
- struct_member_list[struct_level] : NULL;
-
- if ($5.type_enum != ECPGt_varchar &&
- $5.type_enum != ECPGt_char &&
- $5.type_enum != ECPGt_unsigned_char &&
- this->type->type_index >= 0)
- mmerror(PARSE_ERROR, ET_ERROR, "No multi-dimensional array support for simple data types");
-
- types = this;
+ if (auto_create_c == false)
+ $$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
+ else
+ $$ = cat_str(6, make_str("typedef "), mm_strdup($5.type_str), *$7?make_str("*"):make_str(""), mm_strdup($6.str), mm_strdup($3), make_str(";"));
}
-
- $$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
- };
-
-opt_type_array_bounds: '[' ']' opt_type_array_bounds
- {
- $$.index1 = 0;
- $$.index2 = $3.index1;
- $$.str = cat2_str(make_str("[]"), $3.str);
- }
- | '(' ')' opt_type_array_bounds
- {
- $$.index1 = 0;
- $$.index2 = $3.index1;
- $$.str = cat2_str(make_str("[]"), $3.str);
- }
- | '[' Iresult ']' opt_type_array_bounds
- {
- char *txt = mm_alloc(20L);
-
- sprintf (txt, "%d", $2);
- $$.index1 = $2;
- $$.index2 = $4.index1;
- $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
- }
- | '(' Iresult ')' opt_type_array_bounds
- {
- char *txt = mm_alloc(20L);
-
- sprintf (txt, "%d", $2);
- $$.index1 = $2;
- $$.index2 = $4.index1;
- $$.str = cat_str(4, make_str("["), txt, make_str("]"), $4.str);
- }
- | /* EMPTY */
- {
- $$.index1 = -1;
- $$.index2 = -1;
- $$.str= EMPTY;
- }
;
-opt_reference: SQL_REFERENCE { $$ = make_str("reference"); }
- | /* empty */ { $$ = EMPTY; }
- ;
+opt_reference: SQL_REFERENCE { $$ = make_str("reference"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
/*
* define the type of one variable for embedded SQL
*/
ECPGVar: SQL_VAR
- {
- /* reset this variable so we see if there was */
- /* an initializer specified */
- initializer = 0;
- }
- ColLabel IS type opt_type_array_bounds opt_reference
- {
- struct variable *p = find_variable($3);
- int dimension = $6.index1;
- int length = $6.index2;
- struct ECPGtype * type;
-
- if (($5.type_enum == ECPGt_struct ||
- $5.type_enum == ECPGt_union) &&
- initializer == 1)
{
- mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
+ /* reset this variable so we see if there was */
+ /* an initializer specified */
+ initializer = 0;
}
- else
+ ColLabel IS var_type opt_array_bounds opt_reference
{
- adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0);
+ struct variable *p = find_variable($3);
+ char *dimension = $6.index1;
+ char *length = $6.index2;
+ struct ECPGtype * type;
- switch ($5.type_enum)
+ if (($5.type_enum == ECPGt_struct ||
+ $5.type_enum == ECPGt_union) &&
+ initializer == 1)
+ mmerror(PARSE_ERROR, ET_ERROR, "initializer not allowed in EXEC SQL VAR command");
+ else
{
- case ECPGt_struct:
- case ECPGt_union:
- if (dimension < 0)
- type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, ECPGstruct_sizeof);
- else
- type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, ECPGstruct_sizeof), dimension);
- break;
- case ECPGt_varchar:
- if (dimension == -1)
- type = ECPGmake_simple_type($5.type_enum, length);
- else
- type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length), dimension);
-
- break;
- case ECPGt_char:
- case ECPGt_unsigned_char:
- if (dimension == -1)
- type = ECPGmake_simple_type($5.type_enum, length);
- else
- type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length), dimension);
-
- break;
- default:
- if (length >= 0)
- mmerror(PARSE_ERROR, ET_ERROR, "No multi-dimensional array support for simple data types");
-
- if (dimension < 0)
- type = ECPGmake_simple_type($5.type_enum, 1);
- else
- type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, 1), dimension);
-
- break;
- }
-
- ECPGfree_type(p->type);
- p->type = type;
- }
+ adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false);
- $$ = cat_str(7, make_str("/* exec sql var"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
- };
+ switch ($5.type_enum)
+ {
+ case ECPGt_struct:
+ case ECPGt_union:
+ if (atoi(dimension) < 0)
+ type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_sizeof);
+ else
+ type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum,$5.type_sizeof), dimension);
+ break;
+
+ case ECPGt_varchar:
+ if (atoi(dimension) == -1)
+ type = ECPGmake_simple_type($5.type_enum, length, 0);
+ else
+ type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
+ break;
+
+ case ECPGt_char:
+ case ECPGt_unsigned_char:
+ if (atoi(dimension) == -1)
+ type = ECPGmake_simple_type($5.type_enum, length, 0);
+ else
+ type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
+ break;
+
+ default:
+ if (atoi(length) >= 0)
+ mmerror(PARSE_ERROR, ET_ERROR, "no multidimensional array support for simple data types");
+
+ if (atoi(dimension) < 0)
+ type = ECPGmake_simple_type($5.type_enum, make_str("1"), 0);
+ else
+ type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, make_str("1"), 0), dimension);
+ break;
+ }
+
+ ECPGfree_type(p->type);
+ p->type = type;
+ }
+
+ $$ = cat_str(7, make_str("/* exec sql var"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
+ }
+ ;
/*
* whenever statement: decide what to do in case of error/no data found
* according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
*/
ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
- {
- when_error.code = $<action>3.code;
- when_error.command = $<action>3.command;
- $$ = cat_str(3, make_str("/* exec sql whenever sqlerror "), $3.str, make_str("; */\n"));
- }
- | SQL_WHENEVER NOT SQL_FOUND action
- {
- when_nf.code = $<action>4.code;
- when_nf.command = $<action>4.command;
- $$ = cat_str(3, make_str("/* exec sql whenever not found "), $4.str, make_str("; */\n"));
- }
- | SQL_WHENEVER SQL_SQLWARNING action
- {
- when_warn.code = $<action>3.code;
- when_warn.command = $<action>3.command;
- $$ = cat_str(3, make_str("/* exec sql whenever sql_warning "), $3.str, make_str("; */\n"));
- }
- ;
+ {
+ when_error.code = $<action>3.code;
+ when_error.command = $<action>3.command;
+ $$ = cat_str(3, make_str("/* exec sql whenever sqlerror "), $3.str, make_str("; */"));
+ }
+ | SQL_WHENEVER NOT SQL_FOUND action
+ {
+ when_nf.code = $<action>4.code;
+ when_nf.command = $<action>4.command;
+ $$ = cat_str(3, make_str("/* exec sql whenever not found "), $4.str, make_str("; */"));
+ }
+ | SQL_WHENEVER SQL_SQLWARNING action
+ {
+ when_warn.code = $<action>3.code;
+ when_warn.command = $<action>3.command;
+ $$ = cat_str(3, make_str("/* exec sql whenever sql_warning "), $3.str, make_str("; */"));
+ }
+ ;
-action : SQL_CONTINUE
- {
- $<action>$.code = W_NOTHING;
- $<action>$.command = NULL;
- $<action>$.str = make_str("continue");
- }
- | SQL_SQLPRINT
- {
- $<action>$.code = W_SQLPRINT;
- $<action>$.command = NULL;
- $<action>$.str = make_str("sqlprint");
- }
- | SQL_STOP
- {
- $<action>$.code = W_STOP;
- $<action>$.command = NULL;
- $<action>$.str = make_str("stop");
- }
- | SQL_GOTO name
- {
- $<action>$.code = W_GOTO;
- $<action>$.command = strdup($2);
- $<action>$.str = cat2_str(make_str("goto "), $2);
- }
- | SQL_GO TO name
- {
- $<action>$.code = W_GOTO;
- $<action>$.command = strdup($3);
- $<action>$.str = cat2_str(make_str("goto "), $3);
- }
- | DO name '(' c_args ')'
- {
- $<action>$.code = W_DO;
- $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
- $<action>$.str = cat2_str(make_str("do"), mm_strdup($<action>$.command));
- }
- | DO SQL_BREAK
- {
- $<action>$.code = W_BREAK;
- $<action>$.command = NULL;
- $<action>$.str = make_str("break");
- }
- | SQL_CALL name '(' c_args ')'
- {
- $<action>$.code = W_DO;
- $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
- $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
- }
- ;
+action : CONTINUE_P
+ {
+ $<action>$.code = W_NOTHING;
+ $<action>$.command = NULL;
+ $<action>$.str = make_str("continue");
+ }
+ | SQL_SQLPRINT
+ {
+ $<action>$.code = W_SQLPRINT;
+ $<action>$.command = NULL;
+ $<action>$.str = make_str("sqlprint");
+ }
+ | SQL_STOP
+ {
+ $<action>$.code = W_STOP;
+ $<action>$.command = NULL;
+ $<action>$.str = make_str("stop");
+ }
+ | SQL_GOTO name
+ {
+ $<action>$.code = W_GOTO;
+ $<action>$.command = strdup($2);
+ $<action>$.str = cat2_str(make_str("goto "), $2);
+ }
+ | SQL_GO TO name
+ {
+ $<action>$.code = W_GOTO;
+ $<action>$.command = strdup($3);
+ $<action>$.str = cat2_str(make_str("goto "), $3);
+ }
+ | DO name '(' c_args ')'
+ {
+ $<action>$.code = W_DO;
+ $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
+ $<action>$.str = cat2_str(make_str("do"), mm_strdup($<action>$.command));
+ }
+ | DO SQL_BREAK
+ {
+ $<action>$.code = W_BREAK;
+ $<action>$.command = NULL;
+ $<action>$.str = make_str("break");
+ }
+ | SQL_CALL name '(' c_args ')'
+ {
+ $<action>$.code = W_DO;
+ $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
+ $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
+ }
+ | SQL_CALL name
+ {
+ $<action>$.code = W_DO;
+ $<action>$.command = cat2_str($2, make_str("()"));
+ $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
+ }
+ ;
/* some other stuff for ecpg */
/* additional unreserved keywords */
-ECPGKeywords: SQL_BREAK { $$ = make_str("break"); }
- | SQL_CALL { $$ = make_str("call"); }
- | SQL_CARDINALITY { $$ = make_str("cardinality"); }
- | SQL_CONNECT { $$ = make_str("connect"); }
- | SQL_CONTINUE { $$ = make_str("continue"); }
- | SQL_COUNT { $$ = make_str("count"); }
- | SQL_DATA { $$ = make_str("data"); }
+ECPGKeywords: ECPGKeywords_vanames { $$ = $1; }
+ | ECPGKeywords_rest { $$ = $1; }
+ ;
+
+ECPGKeywords_vanames: SQL_BREAK { $$ = make_str("break"); }
+ | SQL_CALL { $$ = make_str("call"); }
+ | SQL_CARDINALITY { $$ = make_str("cardinality"); }
+ | SQL_COUNT { $$ = make_str("count"); }
+ | SQL_DATA { $$ = make_str("data"); }
| SQL_DATETIME_INTERVAL_CODE { $$ = make_str("datetime_interval_code"); }
| SQL_DATETIME_INTERVAL_PRECISION { $$ = make_str("datetime_interval_precision"); }
- | SQL_DEALLOCATE { $$ = make_str("deallocate"); }
- | SQL_DISCONNECT { $$ = make_str("disconnect"); }
- | SQL_FOUND { $$ = make_str("found"); }
- | SQL_GO { $$ = make_str("go"); }
- | SQL_GOTO { $$ = make_str("goto"); }
- | SQL_IDENTIFIED { $$ = make_str("identified"); }
- | SQL_INDICATOR { $$ = make_str("indicator"); }
- | SQL_KEY_MEMBER { $$ = make_str("key_member"); }
- | SQL_LENGTH { $$ = make_str("length"); }
- | SQL_NAME { $$ = make_str("name"); }
- | SQL_NULLABLE { $$ = make_str("nullable"); }
- | SQL_OCTET_LENGTH { $$ = make_str("octet_length"); }
- | SQL_OPEN { $$ = make_str("open"); }
- | SQL_PREPARE { $$ = make_str("prepare"); }
- | SQL_RELEASE { $$ = make_str("release"); }
+ | SQL_FOUND { $$ = make_str("found"); }
+ | SQL_GO { $$ = make_str("go"); }
+ | SQL_GOTO { $$ = make_str("goto"); }
+ | SQL_IDENTIFIED { $$ = make_str("identified"); }
+ | SQL_INDICATOR { $$ = make_str("indicator"); }
+ | SQL_KEY_MEMBER { $$ = make_str("key_member"); }
+ | SQL_LENGTH { $$ = make_str("length"); }
+ | SQL_NULLABLE { $$ = make_str("nullable"); }
+ | SQL_OCTET_LENGTH { $$ = make_str("octet_length"); }
| SQL_RETURNED_LENGTH { $$ = make_str("returned_length"); }
| SQL_RETURNED_OCTET_LENGTH { $$ = make_str("returned_octet_length"); }
- | SQL_SCALE { $$ = make_str("scale"); }
- | SQL_SECTION { $$ = make_str("section"); }
- | SQL_SQLERROR { $$ = make_str("sqlerror"); }
- | SQL_SQLPRINT { $$ = make_str("sqlprint"); }
- | SQL_SQLWARNING { $$ = make_str("sqlwarning"); }
- | SQL_STOP { $$ = make_str("stop"); }
- | SQL_VAR { $$ = make_str("var"); }
- | SQL_WHENEVER { $$ = make_str("whenever"); }
+ | SQL_SCALE { $$ = make_str("scale"); }
+ | SQL_SECTION { $$ = make_str("section"); }
+ | SQL_SQL { $$ = make_str("sql"); }
+ | SQL_SQLERROR { $$ = make_str("sqlerror"); }
+ | SQL_SQLPRINT { $$ = make_str("sqlprint"); }
+ | SQL_SQLWARNING { $$ = make_str("sqlwarning"); }
+ | SQL_STOP { $$ = make_str("stop"); }
;
-/* additional keywords that can be SQL type names (but not ECPGColLabels) */
-ECPGTypeName: SQL_BOOL { $$ = make_str("bool"); }
- | SQL_INT { $$ = make_str("int"); }
- | SQL_LONG { $$ = make_str("long"); }
- | SQL_SHORT { $$ = make_str("short"); }
- | SQL_STRUCT { $$ = make_str("struct"); }
- | SQL_SIGNED { $$ = make_str("signed"); }
- | SQL_UNSIGNED { $$ = make_str("unsigned"); }
+ECPGKeywords_rest: SQL_CONNECT { $$ = make_str("connect"); }
+ | SQL_DESCRIBE { $$ = make_str("describe"); }
+ | SQL_DISCONNECT { $$ = make_str("disconnect"); }
+ | SQL_OPEN { $$ = make_str("open"); }
+ | SQL_VAR { $$ = make_str("var"); }
+ | SQL_WHENEVER { $$ = make_str("whenever"); }
;
-opt_symbol: symbol { $$ = $1; }
- | /*EMPTY*/ { $$ = EMPTY; }
+/* additional keywords that can be SQL type names (but not ECPGColLabels) */
+ECPGTypeName: SQL_BOOL { $$ = make_str("bool"); }
+ | SQL_LONG { $$ = make_str("long"); }
+ | SQL_OUTPUT { $$ = make_str("output"); }
+ | SQL_SHORT { $$ = make_str("short"); }
+ | SQL_STRUCT { $$ = make_str("struct"); }
+ | SQL_SIGNED { $$ = make_str("signed"); }
+ | SQL_UNSIGNED { $$ = make_str("unsigned"); }
;
-symbol: ColLabel { $$ = $1; };
+symbol: ColLabel { $$ = $1; }
+ ;
/*
* Name classification hierarchy.
*
* IDENT is the lexeme returned by the lexer for identifiers that match
* no known keyword. In most cases, we can accept certain keywords as
- * names, not only IDENTs. We prefer to accept as many such keywords
+ * names, not only IDENTs. We prefer to accept as many such keywords
* as possible to minimize the impact of "reserved words" on programmers.
* So, we divide names into several possible classes. The classification
* is chosen in part to make keywords acceptable as names wherever possible.
*/
-/* Column identifier --- names that can be column, table, etc names.
- */
-ColId: ident { $$ = $1; }
- | unreserved_keyword { $$ = $1; }
- | col_name_keyword { $$ = $1; }
- | ECPGKeywords { $$ = $1; }
- | CHAR { $$ = make_str("char"); }
+ECPGColId:ident { $$ = $1; }
+ | ECPGunreserved_interval { $$ = $1; }
+ | ECPGunreserved_con { $$ = $1; }
+ | col_name_keyword { $$ = $1; }
+ | ECPGKeywords { $$ = $1; }
+ | ECPGCKeywords { $$ = $1; }
+ | CHAR_P { $$ = make_str("char"); }
+ | VALUES { $$ = make_str("values"); }
;
-
-/* Type identifier --- names that can be type names.
+/* Column identifier --- names that can be column, table, etc names.
*/
-type_name: ident { $$ = $1; }
- | unreserved_keyword { $$ = $1; }
- | ECPGKeywords { $$ = $1; }
- | ECPGTypeName { $$ = $1; }
- ;
-
-/* Function identifier --- names that can be function names.
+ColId: ident { $$ = $1; }
+ | unreserved_keyword { $$ = $1; }
+ | col_name_keyword { $$ = $1; }
+ | ECPGKeywords { $$ = $1; }
+ | ECPGCKeywords { $$ = $1; }
+ | CHAR_P { $$ = make_str("char"); }
+ | VALUES { $$ = make_str("values"); }
+ ;
+/* Type/function identifier --- names that can be type names.
*/
-func_name: ident { $$ = $1; }
- | unreserved_keyword { $$ = $1; }
- | func_name_keyword { $$ = $1; }
- | ECPGKeywords { $$ = $1; }
+type_function_name: ident { $$ = $1; }
+ | unreserved_keyword { $$ = $1; }
+ | type_func_name_keyword { $$ = $1; }
+ | ECPGKeywords { $$ = $1; }
+ | ECPGTypeName { $$ = $1; }
+ | ECPGCKeywords { $$ = $1; }
;
/* Column label --- allowed labels in "AS" clauses.
* This presently includes *all* Postgres keywords.
*/
-ColLabel: ECPGColLabel { $$ = $1; }
- | ECPGTypeName { $$ = $1; }
- | CHAR { $$ = make_str("char"); }
- | UNION { $$ = make_str("union"); }
+ColLabel: ECPGColLabel { $$ = $1; }
+ | ECPGTypeName { $$ = $1; }
+ | CHAR_P { $$ = make_str("char"); }
+ | INPUT_P { $$ = make_str("input"); }
+ | INT_P { $$ = make_str("int"); }
+ | UNION { $$ = make_str("union"); }
+ | TO { $$ = make_str("to"); }
+ | ECPGCKeywords { $$ = $1; }
+ | ECPGunreserved_interval { $$ = $1; }
+ ;
+
+ECPGColLabelCommon: ident { $$ = $1; }
+ | col_name_keyword { $$ = $1; }
+ | type_func_name_keyword { $$ = $1; }
+ | ECPGKeywords_vanames { $$ = $1; }
;
-ECPGColLabel: ident { $$ = $1; }
- | unreserved_keyword { $$ = $1; }
- | col_name_keyword { $$ = $1; }
- | func_name_keyword { $$ = $1; }
- | reserved_keyword { $$ = $1; }
- | ECPGKeywords { $$ = $1; }
+ECPGColLabel: ECPGColLabelCommon { $$ = $1; }
+ | reserved_keyword { $$ = $1; }
+ | ECPGunreserved { $$ = $1; }
+ | ECPGKeywords_rest { $$ = $1; }
;
+ECPGCKeywords: S_AUTO { $$ = make_str("auto"); }
+ | S_CONST { $$ = make_str("const"); }
+ | S_EXTERN { $$ = make_str("extern"); }
+ | S_REGISTER { $$ = make_str("register"); }
+ | S_STATIC { $$ = make_str("static"); }
+ | S_TYPEDEF { $$ = make_str("typedef"); }
+ | S_VOLATILE { $$ = make_str("volatile"); }
+ ;
/*
* Keyword classification lists. Generally, every keyword present in
/* "Unreserved" keywords --- available for use as any kind of name.
*/
-unreserved_keyword:
- ABORT_TRANS { $$ = make_str("abort"); }
- | ABSOLUTE { $$ = make_str("absolute"); }
- | ACCESS { $$ = make_str("access"); }
- | ACTION { $$ = make_str("action"); }
- | ADD { $$ = make_str("add"); }
- | AFTER { $$ = make_str("after"); }
- | AGGREGATE { $$ = make_str("aggregate"); }
- | ALTER { $$ = make_str("alter"); }
- | AT { $$ = make_str("at"); }
- | AUTHORIZATION { $$ = make_str("authorization"); }
- | BACKWARD { $$ = make_str("backward"); }
- | BEFORE { $$ = make_str("before"); }
- | BEGIN_TRANS { $$ = make_str("begin"); }
- | BY { $$ = make_str("by"); }
- | CACHE { $$ = make_str("cache"); }
- | CASCADE { $$ = make_str("cascade"); }
- | CHAIN { $$ = make_str("chain"); }
- | CHARACTERISTICS { $$ = make_str("characteristics"); }
- | CHECKPOINT { $$ = make_str("checkpoint"); }
- | CLOSE { $$ = make_str("close"); }
- | CLUSTER { $$ = make_str("cluster"); }
- | COMMENT { $$ = make_str("comment"); }
- | COMMIT { $$ = make_str("commit"); }
- | COMMITTED { $$ = make_str("committed"); }
- | CONSTRAINTS { $$ = make_str("constraints"); }
- | COPY { $$ = make_str("copy"); }
- | CREATE { $$ = make_str("create"); }
- | CREATEDB { $$ = make_str("createdb"); }
- | CREATEUSER { $$ = make_str("createuser"); }
- | CURSOR { $$ = make_str("cursor"); }
- | CYCLE { $$ = make_str("cycle"); }
- | DATABASE { $$ = make_str("database"); }
- | DAY_P { $$ = make_str("day"); }
- | DECLARE { $$ = make_str("declare"); }
- | DEFERRED { $$ = make_str("deferred"); }
- | DELETE { $$ = make_str("delete"); }
- | DELIMITERS { $$ = make_str("delimiters"); }
- | DOUBLE { $$ = make_str("double"); }
- | DROP { $$ = make_str("drop"); }
- | EACH { $$ = make_str("each"); }
- | ENCODING { $$ = make_str("encoding"); }
- | ENCRYPTED { $$ = make_str("encrypted"); }
- | ESCAPE { $$ = make_str("escape"); }
- | EXCLUSIVE { $$ = make_str("exclusive"); }
- | EXECUTE { $$ = make_str("execute"); }
- | EXPLAIN { $$ = make_str("explain"); }
- | FETCH { $$ = make_str("fetch"); }
- | FORCE { $$ = make_str("force"); }
- | FORWARD { $$ = make_str("forward"); }
- | FUNCTION { $$ = make_str("function"); }
- | GLOBAL { $$ = make_str("global"); }
- | GRANT { $$ = make_str("grant"); }
- | HANDLER { $$ = make_str("handler"); }
- | HOUR_P { $$ = make_str("hour"); }
- | IMMEDIATE { $$ = make_str("immediate"); }
- | INCREMENT { $$ = make_str("increment"); }
- | INDEX { $$ = make_str("index"); }
- | INHERITS { $$ = make_str("inherits"); }
- | INOUT { $$ = make_str("inout"); }
- | INSENSITIVE { $$ = make_str("insensitive"); }
- | INSERT { $$ = make_str("insert"); }
- | INSTEAD { $$ = make_str("instead"); }
- | ISOLATION { $$ = make_str("isolation"); }
- | KEY { $$ = make_str("key"); }
- | LANGUAGE { $$ = make_str("language"); }
- | LANCOMPILER { $$ = make_str("lancompiler"); }
- | LEVEL { $$ = make_str("level"); }
- | LISTEN { $$ = make_str("listen"); }
- | LOAD { $$ = make_str("load"); }
- | LOCAL { $$ = make_str("local"); }
- | LOCATION { $$ = make_str("location"); }
- | LOCK_P { $$ = make_str("lock"); }
- | MATCH { $$ = make_str("match"); }
- | MAXVALUE { $$ = make_str("maxvalue"); }
- | MINUTE_P { $$ = make_str("minute"); }
- | MINVALUE { $$ = make_str("minvalue"); }
- | MODE { $$ = make_str("mode"); }
- | MONTH_P { $$ = make_str("month"); }
- | MOVE { $$ = make_str("move"); }
- | NAMES { $$ = make_str("names"); }
- | NATIONAL { $$ = make_str("national"); }
- | NEXT { $$ = make_str("next"); }
- | NO { $$ = make_str("no"); }
- | NOCREATEDB { $$ = make_str("nocreatedb"); }
- | NOCREATEUSER { $$ = make_str("nocreateuser"); }
- | NOTHING { $$ = make_str("nothing"); }
- | NOTIFY { $$ = make_str("notify"); }
- | OF { $$ = make_str("of"); }
- | OIDS { $$ = make_str("oids"); }
- | OPERATOR { $$ = make_str("operator"); }
- | OPTION { $$ = make_str("option"); }
- | OUT { $$ = make_str("out"); }
- | OWNER { $$ = make_str("owner"); }
- | PARTIAL { $$ = make_str("partial"); }
- | PASSWORD { $$ = make_str("password"); }
- | PATH_P { $$ = make_str("path"); }
- | PENDANT { $$ = make_str("pendant"); }
- | PRECISION { $$ = make_str("precision"); }
- | PRIOR { $$ = make_str("prior"); }
- | PRIVILEGES { $$ = make_str("privileges"); }
- | PROCEDURAL { $$ = make_str("procedural"); }
- | PROCEDURE { $$ = make_str("procedure"); }
- | READ { $$ = make_str("read"); }
- | REINDEX { $$ = make_str("reindex"); }
- | RELATIVE { $$ = make_str("relative"); }
- | RENAME { $$ = make_str("rename"); }
- | REPLACE { $$ = make_str("replace"); }
- | RESET { $$ = make_str("reset"); }
- | RESTRICT { $$ = make_str("restrict"); }
- | RETURNS { $$ = make_str("returns"); }
- | REVOKE { $$ = make_str("revoke"); }
- | ROLLBACK { $$ = make_str("rollback"); }
- | ROW { $$ = make_str("row"); }
- | RULE { $$ = make_str("rule"); }
- | SCHEMA { $$ = make_str("schema"); }
- | SCROLL { $$ = make_str("scroll"); }
- | SECOND_P { $$ = make_str("second"); }
- | SESSION { $$ = make_str("session"); }
- | SEQUENCE { $$ = make_str("sequence"); }
- | SERIALIZABLE { $$ = make_str("serializable"); }
- | SET { $$ = make_str("set"); }
- | SHARE { $$ = make_str("share"); }
- | SHOW { $$ = make_str("show"); }
- | START { $$ = make_str("start"); }
- | STATEMENT { $$ = make_str("statement"); }
- | STATISTICS { $$ = make_str("statistics"); }
- | STDIN { $$ = make_str("stdin"); }
- | STDOUT { $$ = make_str("stdout"); }
- | STORAGE { $$ = make_str("storage"); }
- | SYSID { $$ = make_str("sysid"); }
- | TEMP { $$ = make_str("temp"); }
- | TEMPLATE { $$ = make_str("template"); }
- | TEMPORARY { $$ = make_str("temporary"); }
- | TOAST { $$ = make_str("toast"); }
- | TRANSACTION { $$ = make_str("transaction"); }
- | TRIGGER { $$ = make_str("trigger"); }
- | TRUNCATE { $$ = make_str("truncate"); }
- | TRUSTED { $$ = make_str("trusted"); }
- | TYPE_P { $$ = make_str("type"); }
- | UNENCRYPTED { $$ = make_str("unencrypted"); }
- | UNKNOWN { $$ = make_str("unknown"); }
- | UNLISTEN { $$ = make_str("unlisten"); }
- | UNTIL { $$ = make_str("until"); }
- | UPDATE { $$ = make_str("update"); }
- | USAGE { $$ = make_str("usage"); }
- | VACUUM { $$ = make_str("vacuum"); }
- | VALID { $$ = make_str("valid"); }
- | VALUES { $$ = make_str("values"); }
- | VARYING { $$ = make_str("varying"); }
- | VERSION { $$ = make_str("version"); }
- | VIEW { $$ = make_str("view"); }
- | WITH { $$ = make_str("with"); }
- | WITHOUT { $$ = make_str("without"); }
- | WORK { $$ = make_str("work"); }
- | YEAR_P { $$ = make_str("year"); }
- | ZONE { $$ = make_str("zone"); }
+/* The following symbols must be excluded from ECPGColLabel and directly included into ColLabel
+ to enable C variables to get names from ECPGColLabel:
+ DAY_P, HOUR_P, MINUTE_P, MONTH_P, SECOND_P, YEAR_P
+ */
+unreserved_keyword: ECPGunreserved_interval | ECPGunreserved;
+
+ECPGunreserved_interval: DAY_P { $$ = make_str("day"); }
+ | HOUR_P { $$ = make_str("hour"); }
+ | MINUTE_P { $$ = make_str("minute"); }
+ | MONTH_P { $$ = make_str("month"); }
+ | SECOND_P { $$ = make_str("second"); }
+ | YEAR_P { $$ = make_str("year"); }
+ ;
+
+/* The following symbol must be excluded from var_name but still included in ColId
+ to enable ecpg special postgresql variables with this name: CONNECTION
+ */
+ECPGunreserved: ECPGunreserved_con { $$ = $1; }
+ | CONNECTION { $$ = make_str("connection"); }
+ ;
+
+ECPGunreserved_con: ABORT_P { $$ = make_str("abort"); }
+ | ABSOLUTE_P { $$ = make_str("absolute"); }
+ | ACCESS { $$ = make_str("access"); }
+ | ACTION { $$ = make_str("action"); }
+ | ADD_P { $$ = make_str("add"); }
+ | ADMIN { $$ = make_str("admin"); }
+ | AFTER { $$ = make_str("after"); }
+ | AGGREGATE { $$ = make_str("aggregate"); }
+ | ALSO { $$ = make_str("also"); }
+ | ALTER { $$ = make_str("alter"); }
+ | ALWAYS { $$ = make_str("always"); }
+ | ASSERTION { $$ = make_str("assertion"); }
+ | ASSIGNMENT { $$ = make_str("assignment"); }
+ | AT { $$ = make_str("at"); }
+ | BACKWARD { $$ = make_str("backward"); }
+ | BEFORE { $$ = make_str("before"); }
+ | BEGIN_P { $$ = make_str("begin"); }
+ | BY { $$ = make_str("by"); }
+ | CACHE { $$ = make_str("cache"); }
+ | CASCADE { $$ = make_str("cascade"); }
+ | CASCADED { $$ = make_str("cascaded"); }
+ | CHAIN { $$ = make_str("chain"); }
+ | CHARACTERISTICS { $$ = make_str("characteristics"); }
+ | CHECKPOINT { $$ = make_str("checkpoint"); }
+ | CLASS { $$ = make_str("class"); }
+ | CLOSE { $$ = make_str("close"); }
+ | CLUSTER { $$ = make_str("cluster"); }
+ | COMMENT { $$ = make_str("comment"); }
+ | COMMIT { $$ = make_str("commit"); }
+ | COMMITTED { $$ = make_str("committed"); }
+ | CONCURRENTLY { $$ = make_str("concurrently"); }
+ | CONFIGURATION { $$ = make_str("configuration"); }
+/* | CONNECTION { $$ = make_str("connection"); }*/
+ | CONSTRAINTS { $$ = make_str("constraints"); }
+ | CONTENT_P { $$ = make_str("content"); }
+ | CONTINUE_P { $$ = make_str("continue"); }
+ | CONVERSION_P { $$ = make_str("conversion"); }
+ | COPY { $$ = make_str("copy"); }
+ | COST { $$ = make_str("cost"); }
+ | CREATEDB { $$ = make_str("createdb"); }
+ | CREATEROLE { $$ = make_str("createrole"); }
+ | CREATEUSER { $$ = make_str("createuser"); }
+ | CSV { $$ = make_str("csv"); }
+ | CURSOR { $$ = make_str("cursor"); }
+ | CYCLE { $$ = make_str("cycle"); }
+ | DATABASE { $$ = make_str("database"); }
+/* | DAY_P { $$ = make_str("day"); }*/
+ | DEALLOCATE { $$ = make_str("deallocate"); }
+ | DECLARE { $$ = make_str("declare"); }
+ | DEFAULTS { $$ = make_str("defaults"); }
+ | DEFERRED { $$ = make_str("deferred"); }
+ | DELETE_P { $$ = make_str("delete"); }
+ | DELIMITER { $$ = make_str("delimiter"); }
+ | DELIMITERS { $$ = make_str("delimiters"); }
+ | DICTIONARY { $$ = make_str("dictionary"); }
+ | DISABLE_P { $$ = make_str("disable"); }
+ | DISCARD { $$ = make_str("discard"); }
+ | DOCUMENT_P { $$ = make_str("document"); }
+ | DOMAIN_P { $$ = make_str("domain"); }
+ | DOUBLE_P { $$ = make_str("double"); }
+ | DROP { $$ = make_str("drop"); }
+ | EACH { $$ = make_str("each"); }
+ | ENABLE_P { $$ = make_str("enable"); }
+ | ENCODING { $$ = make_str("encoding"); }
+ | ENCRYPTED { $$ = make_str("encrypted"); }
+/* | ENUM_P { $$ = make_str("enum"); }*/
+ | ESCAPE { $$ = make_str("escape"); }
+ | EXCLUDING { $$ = make_str("excluding"); }
+ | EXCLUSIVE { $$ = make_str("exclusive"); }
+ | EXECUTE { $$ = make_str("execute"); }
+ | EXPLAIN { $$ = make_str("explain"); }
+ | EXTERNAL { $$ = make_str("external"); }
+ | FAMILY { $$ = make_str("family"); }
+ | FETCH { $$ = make_str("fetch"); }
+ | FIRST_P { $$ = make_str("first"); }
+ | FORCE { $$ = make_str("force"); }
+ | FORWARD { $$ = make_str("forward"); }
+ | FUNCTION { $$ = make_str("function"); }
+ | GLOBAL { $$ = make_str("global"); }
+ | GRANTED { $$ = make_str("granted"); }
+ | HANDLER { $$ = make_str("handler"); }
+ | HEADER_P { $$ = make_str("header"); }
+ | HOLD { $$ = make_str("hold"); }
+/* | HOUR_P { $$ = make_str("hour"); }*/
+ | IDENTITY_P { $$ = make_str("identity"); }
+ | IF_P { $$ = make_str("if"); }
+ | IMMEDIATE { $$ = make_str("immediate"); }
+ | IMMUTABLE { $$ = make_str("immutable"); }
+ | IMPLICIT_P { $$ = make_str("implicit"); }
+ | INCLUDING { $$ = make_str("including"); }
+ | INCREMENT { $$ = make_str("increment"); }
+ | INDEX { $$ = make_str("index"); }
+ | INDEXES { $$ = make_str("indexes"); }
+ | INHERIT { $$ = make_str("inherit"); }
+ | INHERITS { $$ = make_str("inherits"); }
+ | INSENSITIVE { $$ = make_str("insensitive"); }
+ | INSERT { $$ = make_str("insert"); }
+ | INSTEAD { $$ = make_str("instead"); }
+ | ISOLATION { $$ = make_str("isolation"); }
+ | KEY { $$ = make_str("key"); }
+ | LANCOMPILER { $$ = make_str("lancompiler"); }
+ | LANGUAGE { $$ = make_str("language"); }
+ | LARGE_P { $$ = make_str("large"); }
+ | LAST_P { $$ = make_str("last"); }
+ | LEVEL { $$ = make_str("level"); }
+ | LISTEN { $$ = make_str("listen"); }
+ | LOAD { $$ = make_str("load"); }
+ | LOCAL { $$ = make_str("local"); }
+ | LOCATION { $$ = make_str("location"); }
+ | LOCK_P { $$ = make_str("lock"); }
+ | LOGIN_P { $$ = make_str("login"); }
+ | MAPPING { $$ = make_str("mapping"); }
+ | MATCH { $$ = make_str("match"); }
+ | MAXVALUE { $$ = make_str("maxvalue"); }
+/* | MINUTE_P { $$ = make_str("minute"); }*/
+ | MINVALUE { $$ = make_str("minvalue"); }
+ | MODE { $$ = make_str("mode"); }
+/* | MONTH_P { $$ = make_str("month"); }*/
+ | MOVE { $$ = make_str("move"); }
+ | NAME_P { $$ = make_str("name"); }
+ | NAMES { $$ = make_str("names"); }
+ | NEXT { $$ = make_str("next"); }
+ | NO { $$ = make_str("no"); }
+ | NOCREATEDB { $$ = make_str("nocreatedb"); }
+ | NOCREATEROLE { $$ = make_str("nocreaterole"); }
+ | NOCREATEUSER { $$ = make_str("nocreateuser"); }
+ | NOINHERIT { $$ = make_str("noinherit"); }
+ | NOLOGIN_P { $$ = make_str("nologin"); }
+ | NOSUPERUSER { $$ = make_str("nosuperuser"); }
+ | NOTHING { $$ = make_str("nothing"); }
+ | NOTIFY { $$ = make_str("notify"); }
+ | NOWAIT { $$ = make_str("nowait"); }
+ | NULLS_P { $$ = make_str("nulls"); }
+ | OBJECT_P { $$ = make_str("object"); }
+ | OF { $$ = make_str("of"); }
+ | OIDS { $$ = make_str("oids"); }
+ | OPERATOR { $$ = make_str("operator"); }
+ | OPTION { $$ = make_str("option"); }
+ | OWNED { $$ = make_str("owned"); }
+ | OWNER { $$ = make_str("owner"); }
+ | PARSER { $$ = make_str("parser"); }
+ | PARTIAL { $$ = make_str("partial"); }
+ | PASSWORD { $$ = make_str("password"); }
+ | PLANS { $$ = make_str("plans"); }
+ | PREPARE { $$ = make_str("prepare"); }
+ | PREPARED { $$ = make_str("prepared"); }
+ | PRESERVE { $$ = make_str("preserver"); }
+ | PRIOR { $$ = make_str("prior"); }
+ | PRIVILEGES { $$ = make_str("privileges"); }
+ | PROCEDURAL { $$ = make_str("procedural"); }
+ | PROCEDURE { $$ = make_str("procedure"); }
+ | QUOTE { $$ = make_str("quote"); }
+ | READ { $$ = make_str("read"); }
+ | REASSIGN { $$ = make_str("reassign"); }
+ | RECHECK { $$ = make_str("recheck"); }
+ | REINDEX { $$ = make_str("reindex"); }
+ | RELATIVE_P { $$ = make_str("relative"); }
+ | RELEASE { $$ = make_str("release"); }
+ | RENAME { $$ = make_str("rename"); }
+ | REPEATABLE { $$ = make_str("repeatable"); }
+ | REPLACE { $$ = make_str("replace"); }
+ | REPLICA { $$ = make_str("replica"); }
+ | RESET { $$ = make_str("reset"); }
+ | RESTART { $$ = make_str("restart"); }
+ | RESTRICT { $$ = make_str("restrict"); }
+ | RETURNS { $$ = make_str("returns"); }
+ | REVOKE { $$ = make_str("revoke"); }
+ | ROLE { $$ = make_str("role"); }
+ | ROLLBACK { $$ = make_str("rollback"); }
+ | ROWS { $$ = make_str("rows"); }
+ | RULE { $$ = make_str("rule"); }
+ | SAVEPOINT { $$ = make_str("savepoint"); }
+ | SCHEMA { $$ = make_str("schema"); }
+ | SCROLL { $$ = make_str("scroll"); }
+ | SEARCH { $$ = make_str("search"); }
+/* | SECOND_P { $$ = make_str("second"); }*/
+ | SEQUENCE { $$ = make_str("sequence"); }
+ | SERIALIZABLE { $$ = make_str("serializable"); }
+ | SESSION { $$ = make_str("session"); }
+ | SET { $$ = make_str("set"); }
+ | SHARE { $$ = make_str("share"); }
+ | SHOW { $$ = make_str("show"); }
+ | SIMPLE { $$ = make_str("simple"); }
+ | STABLE { $$ = make_str("stable"); }
+ | STANDALONE_P { $$ = make_str("standalone"); }
+ | START { $$ = make_str("start"); }
+ | STATEMENT { $$ = make_str("statement"); }
+ | STATISTICS { $$ = make_str("statistics"); }
+ | STDIN { $$ = make_str("stdin"); }
+ | STDOUT { $$ = make_str("stdout"); }
+ | STORAGE { $$ = make_str("storage"); }
+ | STRICT_P { $$ = make_str("strict"); }
+ | STRIP_P { $$ = make_str("strip"); }
+ | SUPERUSER_P { $$ = make_str("superuser"); }
+ | SYSTEM_P { $$ = make_str("system"); }
+ | SYSID { $$ = make_str("sysid"); }
+ | TABLESPACE { $$ = make_str("tablespace"); }
+ | TEMP { $$ = make_str("temp"); }
+ | TEMPLATE { $$ = make_str("template"); }
+ | TEMPORARY { $$ = make_str("temporary"); }
+ | TEXT_P { $$ = make_str("text"); }
+ | TRANSACTION { $$ = make_str("transaction"); }
+ | TRIGGER { $$ = make_str("trigger"); }
+ | TRUNCATE { $$ = make_str("truncate"); }
+ | TRUSTED { $$ = make_str("trusted"); }
+ | TYPE_P { $$ = make_str("type"); }
+ | UNCOMMITTED { $$ = make_str("uncommitted"); }
+ | UNENCRYPTED { $$ = make_str("unencrypted"); }
+ | UNKNOWN { $$ = make_str("unknown"); }
+ | UNLISTEN { $$ = make_str("unlisten"); }
+ | UNTIL { $$ = make_str("until"); }
+ | UPDATE { $$ = make_str("update"); }
+ | VACUUM { $$ = make_str("vacuum"); }
+ | VALID { $$ = make_str("valid"); }
+ | VALIDATOR { $$ = make_str("validator"); }
+ | VALUE_P { $$ = make_str("value"); }
+ | VARYING { $$ = make_str("varying"); }
+ | VERSION_P { $$ = make_str("version"); }
+ | VIEW { $$ = make_str("view"); }
+ | VOLATILE { $$ = make_str("volatile"); }
+ | WHITESPACE_P { $$ = make_str("whitespace"); }
+ | WITH { $$ = make_str("with"); }
+ | WITHOUT { $$ = make_str("without"); }
+ | WORK { $$ = make_str("work"); }
+ | WRITE { $$ = make_str("write"); }
+ | XML_P { $$ = make_str("xml"); }
+ | YES_P { $$ = make_str("yes"); }
+/* | YEAR_P { $$ = make_str("year"); }*/
+ | ZONE { $$ = make_str("zone"); }
;
/* Column identifier --- keywords that can be column, table, etc names.
* looks too much like a function call for an LR(1) parser.
*/
col_name_keyword:
- BIT { $$ = make_str("bit"); }
+ BIGINT { $$ = make_str("bigint");}
+ | BIT { $$ = make_str("bit"); }
/* CHAR must be excluded from ECPGColLabel because of conflict with UNSIGNED
- | CHAR { $$ = make_str("char"); }
+ | CHAR_P { $$ = make_str("char"); }
*/
- | CHARACTER { $$ = make_str("character"); }
- | COALESCE { $$ = make_str("coalesce"); }
- | DEC { $$ = make_str("dec"); }
- | DECIMAL { $$ = make_str("decimal"); }
- | EXISTS { $$ = make_str("exists"); }
- | EXTRACT { $$ = make_str("extract"); }
- | FLOAT { $$ = make_str("float"); }
- | INTERVAL { $$ = make_str("interval"); }
- | NCHAR { $$ = make_str("nchar"); }
- | NONE { $$ = make_str("none"); }
- | NULLIF { $$ = make_str("nullif"); }
- | NUMERIC { $$ = make_str("numeric"); }
- | POSITION { $$ = make_str("position"); }
- | SETOF { $$ = make_str("setof"); }
- | SUBSTRING { $$ = make_str("substring"); }
- | TIME { $$ = make_str("time"); }
- | TIMESTAMP { $$ = make_str("timestamp"); }
- | TRIM { $$ = make_str("trim"); }
- | VARCHAR { $$ = make_str("varchar"); }
+ | CHARACTER { $$ = make_str("character"); }
+ | COALESCE { $$ = make_str("coalesce"); }
+ | DEC { $$ = make_str("dec"); }
+ | DECIMAL_P { $$ = make_str("decimal"); }
+ | EXISTS { $$ = make_str("exists"); }
+ | EXTRACT { $$ = make_str("extract"); }
+ | FLOAT_P { $$ = make_str("float"); }
+ | GREATEST { $$ = make_str("greatest"); }
+ | INOUT { $$ = make_str("inout"); }
+/* INT must be excluded from ECPGColLabel because of conflict
+ | INT_P { $$ = make_str("int"); }
+ */
+ | INTEGER { $$ = make_str("integer"); }
+ | INTERVAL { $$ = make_str("interval"); }
+ | LEAST { $$ = make_str("least"); }
+ | NATIONAL { $$ = make_str("national"); }
+ | NCHAR { $$ = make_str("nchar"); }
+ | NONE { $$ = make_str("none"); }
+ | NULLIF { $$ = make_str("nullif"); }
+ | NUMERIC { $$ = make_str("numeric"); }
+ | OUT_P { $$ = make_str("out"); }
+ | OVERLAY { $$ = make_str("overlay"); }
+ | POSITION { $$ = make_str("position"); }
+ | PRECISION { $$ = make_str("precision"); }
+ | REAL { $$ = make_str("real"); }
+ | ROW { $$ = make_str("row"); }
+ | SETOF { $$ = make_str("setof"); }
+ | SMALLINT { $$ = make_str("smallint"); }
+ | SUBSTRING { $$ = make_str("substring"); }
+ | TIME { $$ = make_str("time"); }
+ | TIMESTAMP { $$ = make_str("timestamp"); }
+ | TREAT { $$ = make_str("treat"); }
+ | TRIM { $$ = make_str("trim"); }
+ /* VALUES creates a shift/reduce problem if listed here
+ | VALUES { $$ = make_str("values"); } */
+ | VARCHAR { $$ = make_str("varchar"); }
+ | XMLATTRIBUTES { $$ = make_str("xmlattributes"); }
+ | XMLCONCAT { $$ = make_str("xmlconcat"); }
+ | XMLELEMENT { $$ = make_str("xmlelement"); }
+ | XMLFOREST { $$ = make_str("xmlforest"); }
+ | XMLPARSE { $$ = make_str("xmlparse"); }
+ | XMLPI { $$ = make_str("xmlpi"); }
+ | XMLROOT { $$ = make_str("xmlroot"); }
+ | XMLSERIALIZE { $$ = make_str("xmlserialize"); }
;
/* Function identifier --- keywords that can be function names.
*
* Do not include POSITION, SUBSTRING, etc here since they have explicit
* productions in a_expr to support the goofy SQL9x argument syntax.
- * - thomas 2000-11-28
+ * - thomas 2000-11-28
*/
-func_name_keyword:
- BETWEEN { $$ = make_str("between"); }
- | BINARY { $$ = make_str("binary"); }
- | CROSS { $$ = make_str("cross"); }
- | FREEZE { $$ = make_str("freeze"); }
- | FULL { $$ = make_str("full"); }
- | ILIKE { $$ = make_str("ilike"); }
- | IN { $$ = make_str("in"); }
- | INNER_P { $$ = make_str("inner"); }
- | IS { $$ = make_str("is"); }
- | ISNULL { $$ = make_str("isnull"); }
- | JOIN { $$ = make_str("join"); }
- | LEFT { $$ = make_str("left"); }
- | LIKE { $$ = make_str("like"); }
- | NATURAL { $$ = make_str("natural"); }
- | NOTNULL { $$ = make_str("notnull"); }
- | OUTER_P { $$ = make_str("outer"); }
- | OVERLAPS { $$ = make_str("overlaps"); }
- | PUBLIC { $$ = make_str("public"); }
- | RIGHT { $$ = make_str("right"); }
- | VERBOSE { $$ = make_str("verbose"); }
+type_func_name_keyword:
+ AUTHORIZATION { $$ = make_str("authorization"); }
+ | BETWEEN { $$ = make_str("between"); }
+ | BINARY { $$ = make_str("binary"); }
+ | CROSS { $$ = make_str("cross"); }
+ | FREEZE { $$ = make_str("freeze"); }
+ | FULL { $$ = make_str("full"); }
+ | ILIKE { $$ = make_str("ilike"); }
+ | INNER_P { $$ = make_str("inner"); }
+ | IS { $$ = make_str("is"); }
+ | ISNULL { $$ = make_str("isnull"); }
+ | JOIN { $$ = make_str("join"); }
+ | LEFT { $$ = make_str("left"); }
+ | LIKE { $$ = make_str("like"); }
+ | NATURAL { $$ = make_str("natural"); }
+ | NOTNULL { $$ = make_str("notnull"); }
+ | OUTER_P { $$ = make_str("outer"); }
+ | OVERLAPS { $$ = make_str("overlaps"); }
+ | RIGHT { $$ = make_str("right"); }
+ | SIMILAR { $$ = make_str("similar"); }
+ | VERBOSE { $$ = make_str("verbose"); }
;
/* Reserved keyword --- these keywords are usable only as a ColLabel.
* forced to.
*/
reserved_keyword:
- ALL { $$ = make_str("all"); }
- | ANALYSE { $$ = make_str("analyse"); } /* British */
- | ANALYZE { $$ = make_str("analyze"); }
- | AND { $$ = make_str("and"); }
- | ANY { $$ = make_str("any"); }
- | AS { $$ = make_str("as"); }
- | ASC { $$ = make_str("asc"); }
- | BOTH { $$ = make_str("both"); }
- | CASE { $$ = make_str("case"); }
- | CAST { $$ = make_str("cast"); }
- | CHECK { $$ = make_str("check"); }
- | COLLATE { $$ = make_str("collate"); }
- | COLUMN { $$ = make_str("column"); }
- | CONSTRAINT { $$ = make_str("constraint"); }
- | CURRENT_DATE { $$ = make_str("current_date"); }
- | CURRENT_TIME { $$ = make_str("current_time"); }
- | CURRENT_TIMESTAMP { $$ = make_str("current_timestamp"); }
- | CURRENT_USER { $$ = make_str("current_user"); }
- | DEFAULT { $$ = make_str("default"); }
- | DEFERRABLE { $$ = make_str("deferrable"); }
- | DESC { $$ = make_str("desc"); }
- | DISTINCT { $$ = make_str("distinct"); }
- | DO { $$ = make_str("do"); }
- | ELSE { $$ = make_str("else"); }
- | END_TRANS { $$ = make_str("end"); }
- | EXCEPT { $$ = make_str("except"); }
- | FALSE_P { $$ = make_str("false"); }
- | FOR { $$ = make_str("for"); }
- | FOREIGN { $$ = make_str("foreign"); }
- | FROM { $$ = make_str("from"); }
- | GROUP { $$ = make_str("group"); }
- | HAVING { $$ = make_str("having"); }
- | INITIALLY { $$ = make_str("initially"); }
- | INTERSECT { $$ = make_str("intersect"); }
- | INTO { $$ = make_str("into"); }
- | LEADING { $$ = make_str("leading"); }
- | LIMIT { $$ = make_str("limit"); }
- | NEW { $$ = make_str("new"); }
- | NOT { $$ = make_str("not"); }
- | NULL_P { $$ = make_str("null"); }
- | OFF { $$ = make_str("off"); }
- | OFFSET { $$ = make_str("offset"); }
- | OLD { $$ = make_str("old"); }
- | ON { $$ = make_str("on"); }
- | ONLY { $$ = make_str("only"); }
- | OR { $$ = make_str("or"); }
- | ORDER { $$ = make_str("order"); }
- | PRIMARY { $$ = make_str("primary"); }
- | REFERENCES { $$ = make_str("references"); }
- | SELECT { $$ = make_str("select"); }
- | SESSION_USER { $$ = make_str("session_user"); }
- | SOME { $$ = make_str("some"); }
- | TABLE { $$ = make_str("table"); }
- | THEN { $$ = make_str("then"); }
- | TO { $$ = make_str("to"); }
- | TRAILING { $$ = make_str("trailing"); }
- | TRUE_P { $$ = make_str("true"); }
+ ALL { $$ = make_str("all"); }
+ | ANALYSE { $$ = make_str("analyse"); } /* British */
+ | ANALYZE { $$ = make_str("analyze"); }
+ | AND { $$ = make_str("and"); }
+ | ANY { $$ = make_str("any"); }
+ | ARRAY { $$ = make_str("array"); }
+ | AS { $$ = make_str("as"); }
+ | ASC { $$ = make_str("asc"); }
+ | ASYMMETRIC { $$ = make_str("asymmetric"); }
+ | BOTH { $$ = make_str("both"); }
+ | CASE { $$ = make_str("case"); }
+ | CAST { $$ = make_str("cast"); }
+ | CHECK { $$ = make_str("check"); }
+ | COLLATE { $$ = make_str("collate"); }
+ | COLUMN { $$ = make_str("column"); }
+ | CONSTRAINT { $$ = make_str("constraint"); }
+ | CREATE { $$ = make_str("create"); }
+ | CURRENT_P { $$ = make_str("current"); }
+ | CURRENT_DATE { $$ = make_str("current_date"); }
+ | CURRENT_TIME { $$ = make_str("current_time"); }
+ | CURRENT_TIMESTAMP { $$ = make_str("current_timestamp"); }
+ | CURRENT_ROLE { $$ = make_str("current_role"); }
+ | CURRENT_USER { $$ = make_str("current_user"); }
+ | DEFAULT { $$ = make_str("default"); }
+ | DEFERRABLE { $$ = make_str("deferrable"); }
+ | DESC { $$ = make_str("desc"); }
+ | DISTINCT { $$ = make_str("distinct"); }
+ | DO { $$ = make_str("do"); }
+ | ELSE { $$ = make_str("else"); }
+ | END_P { $$ = make_str("end"); }
+ | EXCEPT { $$ = make_str("except"); }
+ | FALSE_P { $$ = make_str("false"); }
+ | FOR { $$ = make_str("for"); }
+ | FOREIGN { $$ = make_str("foreign"); }
+ | FROM { $$ = make_str("from"); }
+ | GRANT { $$ = make_str("grant"); }
+ | GROUP_P { $$ = make_str("group"); }
+ | HAVING { $$ = make_str("having"); }
+ | IN_P { $$ = make_str("in"); }
+ | INITIALLY { $$ = make_str("initially"); }
+ | INTERSECT { $$ = make_str("intersect"); }
+ | INTO { $$ = make_str("into"); }
+ | LEADING { $$ = make_str("leading"); }
+ | LIMIT { $$ = make_str("limit"); }
+ | NEW { $$ = make_str("new"); }
+ | NOT { $$ = make_str("not"); }
+ | NULL_P { $$ = make_str("null"); }
+ | OFF { $$ = make_str("off"); }
+ | OFFSET { $$ = make_str("offset"); }
+ | OLD { $$ = make_str("old"); }
+ | ON { $$ = make_str("on"); }
+ | ONLY { $$ = make_str("only"); }
+ | OR { $$ = make_str("or"); }
+ | ORDER { $$ = make_str("order"); }
+ | PRIMARY { $$ = make_str("primary"); }
+ | REFERENCES { $$ = make_str("references"); }
+ | RETURNING { $$ = make_str("returning"); }
+ | SELECT { $$ = make_str("select"); }
+ | SESSION_USER { $$ = make_str("session_user"); }
+ | SOME { $$ = make_str("some"); }
+ | SYMMETRIC { $$ = make_str("symmetric"); }
+ | TABLE { $$ = make_str("table"); }
+ | THEN { $$ = make_str("then"); }
+/* TO must be excluded from ECPGColLabel because of a conflict in variable name parsing
+ | TO { $$ = make_str("to"); }
+ */
+ | TRAILING { $$ = make_str("trailing"); }
+ | TRUE_P { $$ = make_str("true"); }
/* UNION must be excluded from ECPGColLabel because of conflict with s_union
- | UNION { $$ = make_str("union"); }
+ | UNION { $$ = make_str("union"); }
*/
- | UNIQUE { $$ = make_str("unique"); }
- | USER { $$ = make_str("user"); }
- | USING { $$ = make_str("using"); }
- | WHEN { $$ = make_str("when"); }
- | WHERE { $$ = make_str("where"); }
+ | UNIQUE { $$ = make_str("unique"); }
+ | USER { $$ = make_str("user"); }
+ | USING { $$ = make_str("using"); }
+ | VARIADIC { $$ = make_str("variadic"); }
+ | WHEN { $$ = make_str("when"); }
+ | WHERE { $$ = make_str("where"); }
;
-into_list : coutputvariable | into_list ',' coutputvariable;
+into_list : coutputvariable | into_list ',' coutputvariable
+ ;
-ecpgstart: SQL_START { reset_variables(); };
+ecpgstart: SQL_START {
+ reset_variables();
+ pacounter = 1;
+ }
+ ;
-c_args: /* empty */ { $$ = EMPTY; }
- | c_list { $$ = $1; }
- ;
+c_args: /*EMPTY*/ { $$ = EMPTY; }
+ | c_list { $$ = $1; }
+ ;
coutputvariable: cvariable indicator
- {
- add_variable(&argsresult, find_variable($1), find_variable($2));
- }
- | cvariable
- {
- add_variable(&argsresult, find_variable($1), &no_indicator);
- }
- ;
+ { add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); }
+ | cvariable
+ { add_variable_to_head(&argsresult, find_variable($1), &no_indicator); }
+ ;
civarind: cvariable indicator
- {
- if ($2 != NULL && (find_variable($2))->type->type == ECPGt_array)
- mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
+ {
+ if (find_variable($2)->type->type == ECPGt_array)
+ mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
- add_variable(&argsinsert, find_variable($1), ($2 == NULL) ? &no_indicator : find_variable($2));
- };
+ add_variable_to_head(&argsinsert, find_variable($1), find_variable($2));
+ $$ = create_questionmarks($1, false);
+ }
+ ;
civar: cvariable
- {
- add_variable(&argsinsert, find_variable($1), &no_indicator);
- $$ = $1;
- };
-
-cvariable: CVARIABLE { $$ = $1; }
-
-indicator: CVARIABLE { check_indicator((find_variable($1))->type); $$ = $1; }
- | SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; }
- | SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
- ;
-
-ident: IDENT { $$ = $1; }
- | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
- ;
-
-quoted_ident_stringvar: IDENT { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
- | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
- | char_variable
- { $$ = make3_str(make_str("("), $1, make_str(")"));
+ {
+ add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
+ $$ = create_questionmarks($1, false);
}
- ;
+ ;
-/*
- * C stuff
- */
+indicator: cvariable { check_indicator((find_variable($1))->type); $$ = $1; }
+ | SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; }
+ | SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
+ ;
-cpp_line: CPP_LINE { $$ = $1; };
+cvariable: CVARIABLE
+ {
+ /* As long as multidimensional arrays are not implemented we have to check for those here */
+ char *ptr = $1;
+ int brace_open=0, brace = false;
-c_stuff_item: c_anything { $$ = $1; }
- | '(' ')' { $$ = make_str("()"); }
- | '(' c_stuff ')'
+ for (; *ptr; ptr++)
{
- $$ = cat_str(3, make_str("("), $2, make_str(")"));
+ switch (*ptr)
+ {
+ case '[':
+ if (brace)
+ mmerror(PARSE_ERROR, ET_FATAL, "no multidimensional array support for simple data types");
+ brace_open++;
+ break;
+ case ']':
+ brace_open--;
+ if (brace_open == 0)
+ brace = true;
+ break;
+ case '\t':
+ case ' ':
+ break;
+ default:
+ if (brace_open == 0)
+ brace = false;
+ break;
+ }
}
- ;
+ $$ = $1;
+ }
+ ;
+ident: IDENT { $$ = $1; }
+ | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+ ;
-c_stuff: c_stuff_item { $$ = $1; }
- | c_stuff c_stuff_item
- {
- $$ = cat2_str($1, $2);
- }
- ;
+quoted_ident_stringvar: name
+ { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+ | char_variable
+ { $$ = make3_str(make_str("("), $1, make_str(")")); }
+ ;
-c_list: c_term { $$ = $1; }
- | c_list ',' c_term { $$ = cat_str(3, $1, make_str(","), $3); }
- ;
+/*
+ * C stuff
+ */
-c_term: c_stuff { $$ = $1; }
- | '{' c_list '}' { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
- ;
+c_stuff_item: c_anything { $$ = $1; }
+ | '(' ')' { $$ = make_str("()"); }
+ | '(' c_stuff ')'
+ { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+ ;
+
+c_stuff: c_stuff_item { $$ = $1; }
+ | c_stuff c_stuff_item
+ { $$ = cat2_str($1, $2); }
+ ;
+
+c_list: c_term { $$ = $1; }
+ | c_list ',' c_term { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+c_term: c_stuff { $$ = $1; }
+ | '{' c_list '}' { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
+ ;
+
+c_thing: c_anything { $$ = $1; }
+ | '(' { $$ = make_str("("); }
+ | ')' { $$ = make_str(")"); }
+ | ',' { $$ = make_str(","); }
+ | ';' { $$ = make_str(";"); }
+ ;
+
+c_anything: IDENT { $$ = $1; }
+ | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+ | Iconst { $$ = $1; }
+ | Fconst { $$ = $1; }
+ | Sconst { $$ = $1; }
+ | '*' { $$ = make_str("*"); }
+ | '+' { $$ = make_str("+"); }
+ | '-' { $$ = make_str("-"); }
+ | '/' { $$ = make_str("/"); }
+ | '%' { $$ = make_str("%"); }
+ | NULL_P { $$ = make_str("NULL"); }
+ | S_ADD { $$ = make_str("+="); }
+ | S_AND { $$ = make_str("&&"); }
+ | S_ANYTHING { $$ = make_name(); }
+ | S_AUTO { $$ = make_str("auto"); }
+ | S_CONST { $$ = make_str("const"); }
+ | S_DEC { $$ = make_str("--"); }
+ | S_DIV { $$ = make_str("/="); }
+ | S_DOTPOINT { $$ = make_str(".*"); }
+ | S_EQUAL { $$ = make_str("=="); }
+ | S_EXTERN { $$ = make_str("extern"); }
+ | S_INC { $$ = make_str("++"); }
+ | S_LSHIFT { $$ = make_str("<<"); }
+ | S_MEMBER { $$ = make_str("->"); }
+ | S_MEMPOINT { $$ = make_str("->*"); }
+ | S_MOD { $$ = make_str("%="); }
+ | S_MUL { $$ = make_str("*="); }
+ | S_NEQUAL { $$ = make_str("!="); }
+ | S_OR { $$ = make_str("||"); }
+ | S_REGISTER { $$ = make_str("register"); }
+ | S_RSHIFT { $$ = make_str(">>"); }
+ | S_STATIC { $$ = make_str("static"); }
+ | S_SUB { $$ = make_str("-="); }
+ | S_TYPEDEF { $$ = make_str("typedef"); }
+ | S_VOLATILE { $$ = make_str("volatile"); }
+ | SQL_BOOL { $$ = make_str("bool"); }
+ | ENUM_P { $$ = make_str("enum"); }
+ | HOUR_P { $$ = make_str("hour"); }
+ | INT_P { $$ = make_str("int"); }
+ | SQL_LONG { $$ = make_str("long"); }
+ | MINUTE_P { $$ = make_str("minute"); }
+ | MONTH_P { $$ = make_str("month"); }
+ | SECOND_P { $$ = make_str("second"); }
+ | SQL_SHORT { $$ = make_str("short"); }
+ | SQL_SIGNED { $$ = make_str("signed"); }
+ | SQL_STRUCT { $$ = make_str("struct"); }
+ | SQL_UNSIGNED { $$ = make_str("unsigned"); }
+ | YEAR_P { $$ = make_str("year"); }
+ | CHAR_P { $$ = make_str("char"); }
+ | FLOAT_P { $$ = make_str("float"); }
+ | TO { $$ = make_str("to"); }
+ | UNION { $$ = make_str("union"); }
+ | VARCHAR { $$ = make_str("varchar"); }
+ | '[' { $$ = make_str("["); }
+ | ']' { $$ = make_str("]"); }
+ | '=' { $$ = make_str("="); }
+ | ':' { $$ = make_str(":"); }
+ ;
-c_thing: c_anything { $$ = $1; }
- | '(' { $$ = make_str("("); }
- | ')' { $$ = make_str(")"); }
- | ',' { $$ = make_str(","); }
- | ';' { $$ = make_str(";"); }
- ;
+%%
-c_anything: IDENT { $$ = $1; }
- | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
- | PosIntConst { $$ = $1; }
- | Fconst { $$ = $1; }
- | Sconst { $$ = $1; }
- | '*' { $$ = make_str("*"); }
- | '+' { $$ = make_str("+"); }
- | '-' { $$ = make_str("-"); }
- | '/' { $$ = make_str("/"); }
- | '%' { $$ = make_str("%"); }
- | NULL_P { $$ = make_str("NULL"); }
- | S_ADD { $$ = make_str("+="); }
- | S_AND { $$ = make_str("&&"); }
- | S_ANYTHING { $$ = make_name(); }
- | S_AUTO { $$ = make_str("auto"); }
- | S_CONST { $$ = make_str("const"); }
- | S_DEC { $$ = make_str("--"); }
- | S_DIV { $$ = make_str("/="); }
- | S_DOTPOINT { $$ = make_str(".*"); }
- | S_EQUAL { $$ = make_str("=="); }
- | S_EXTERN { $$ = make_str("extern"); }
- | S_INC { $$ = make_str("++"); }
- | S_LSHIFT { $$ = make_str("<<"); }
- | S_MEMBER { $$ = make_str("->"); }
- | S_MEMPOINT { $$ = make_str("->*"); }
- | S_MOD { $$ = make_str("%="); }
- | S_MUL { $$ = make_str("*="); }
- | S_NEQUAL { $$ = make_str("!="); }
- | S_OR { $$ = make_str("||"); }
- | S_REGISTER { $$ = make_str("register"); }
- | S_RSHIFT { $$ = make_str(">>"); }
- | S_STATIC { $$ = make_str("static"); }
- | S_SUB { $$ = make_str("-="); }
- | SQL_BOOL { $$ = make_str("bool"); }
- | SQL_ENUM { $$ = make_str("enum"); }
- | SQL_INT { $$ = make_str("int"); }
- | SQL_LONG { $$ = make_str("long"); }
- | SQL_SHORT { $$ = make_str("short"); }
- | SQL_SIGNED { $$ = make_str("signed"); }
- | SQL_STRUCT { $$ = make_str("struct"); }
- | SQL_UNSIGNED { $$ = make_str("unsigned"); }
- | CHAR { $$ = make_str("char"); }
- | DOUBLE { $$ = make_str("double"); }
- | FLOAT { $$ = make_str("float"); }
- | UNION { $$ = make_str("union"); }
- | VARCHAR { $$ = make_str("varchar"); }
- | '[' { $$ = make_str("["); }
- | ']' { $$ = make_str("]"); }
- | '=' { $$ = make_str("="); }
- ;
+void base_yyerror(const char * error)
+{
+ char buf[1024];
-blockstart : '{'
- {
- braces_open++;
- $$ = make_str("{");
- };
+ snprintf(buf,sizeof buf, _("%s at or near \"%s\""), error, token_start ? token_start : yytext);
+ buf[sizeof(buf)-1]=0;
+ mmerror(PARSE_ERROR, ET_ERROR, buf);
+}
-blockend : '}'
- {
- remove_variables(braces_open--);
- $$ = make_str("}");
- };
+void parser_init(void)
+{
+ /* This function is empty. It only exists for compatibility with the backend parser right now. */
+}
-%%
+/*
+ * Must undefine base_yylex before including pgc.c, since we want it
+ * to create the function base_yylex not filtered_base_yylex.
+ */
+#undef base_yylex
-void yyerror( char * error)
-{ char buf[1024];
- snprintf(buf,sizeof buf,"%s at or near \"%s\"",error,yytext);
- buf[sizeof(buf)-1]=0;
- mmerror(PARSE_ERROR, ET_ERROR, buf);
-}
+#include "pgc.c"