summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc G. Fournier1998-08-25 12:17:27 +0000
committerMarc G. Fournier1998-08-25 12:17:27 +0000
commit35478b8028a2332a3e9c4da230091b031a65ed28 (patch)
tree63261b80336af1ff7abe4ef045ee503425f0118d
parent32cfc4aa00f19750b1786430d5cffad5ec7887ac (diff)
From: Michael Meskes <[email protected]>
+ + Fri Aug 14 12:44:21 CEST 1998 + + - Added EXEC SQL DEFINE statement + - Set version to 2.4.0 + + Tue Aug 18 09:24:15 CEST 1998 + + - Removed keyword IS from DEFINE statement + - Added latest changes from gram.y + - Removed duplicate symbols from preproc.y + - Initialize sqlca structure + - Added check for connection to ecpglib + - Set version to 2.4.1 + + Thu Aug 20 15:31:29 CEST 1998 + + - Cleaned up memory allocation in ecpglib.c + - Set library version to 2.6 +
-rw-r--r--src/interfaces/ecpg/lib/Makefile.in2
-rw-r--r--src/interfaces/ecpg/lib/ecpglib.c204
-rw-r--r--src/interfaces/ecpg/preproc/Makefile4
-rw-r--r--src/interfaces/ecpg/preproc/ecpg.c21
-rw-r--r--src/interfaces/ecpg/preproc/extern.h9
-rw-r--r--src/interfaces/ecpg/preproc/pgc.l172
-rw-r--r--src/interfaces/ecpg/preproc/preproc.y115
7 files changed, 340 insertions, 187 deletions
diff --git a/src/interfaces/ecpg/lib/Makefile.in b/src/interfaces/ecpg/lib/Makefile.in
index e236487d6aa..53f3d5ac44a 100644
--- a/src/interfaces/ecpg/lib/Makefile.in
+++ b/src/interfaces/ecpg/lib/Makefile.in
@@ -4,7 +4,7 @@ include $(SRCDIR)/Makefile.global
PQ_INCLUDE=-I$(SRCDIR)/interfaces/libpq
SO_MAJOR_VERSION=2
-SO_MINOR_VERSION=5
+SO_MINOR_VERSION=6
PORTNAME=@PORTNAME@
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c
index 0d3d4fa0e6a..e2b8e2ce599 100644
--- a/src/interfaces/ecpg/lib/ecpglib.c
+++ b/src/interfaces/ecpg/lib/ecpglib.c
@@ -24,7 +24,32 @@
#include <ecpglib.h>
#include <sqlca.h>
-extern int no_auto_trans;
+/* variables visible to the programs */
+int no_auto_trans;
+
+static struct sqlca sqlca_init =
+{
+ {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '},
+ sizeof(struct sqlca),
+ 0,
+ { 0, {0}},
+ {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0}
+};
+
+struct sqlca sqlca =
+{
+ {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '},
+ sizeof(struct sqlca),
+ 0,
+ { 0, {0}},
+ {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0}
+};
static struct connection
{
@@ -72,39 +97,6 @@ register_error(long code, char *fmt,...)
sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
}
-/* This function returns a newly malloced string that has the ' and \
- in the argument quoted with \.
- */
-static
-char *
-quote_postgres(char *arg)
-{
- char *res = (char *) malloc(2 * strlen(arg) + 1);
- int i,
- ri;
-
- if (!res)
- return(res);
-
- for (i = 0, ri = 0; arg[i]; i++, ri++)
- {
- switch (arg[i])
- {
- case '\'':
- case '\\':
- res[ri++] = '\\';
- default:
- ;
- }
-
- res[ri] = arg[i];
- }
- res[ri] = '\0';
-
- return res;
-}
-
-
static void
ECPGfinish(struct connection *act)
{
@@ -139,6 +131,54 @@ ECPGfinish(struct connection *act)
ECPGlog("ECPGfinish: called an extra time.\n");
}
+static char *ecpg_alloc(long size, int lineno)
+{
+ char *new = (char *) malloc(size);
+
+ if (!new)
+ {
+ ECPGfinish(actual_connection);
+ ECPGlog("out of memory\n");
+ register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
+ return NULL;
+ }
+
+ memset(new, '\0', size);
+ return(new);
+}
+
+/* This function returns a newly malloced string that has the ' and \
+ in the argument quoted with \.
+ */
+static
+char *
+quote_postgres(char *arg, int lineno)
+{
+ char *res = (char *) ecpg_alloc(2 * strlen(arg) + 1, lineno);
+ int i,
+ ri;
+
+ if (!res)
+ return(res);
+
+ for (i = 0, ri = 0; arg[i]; i++, ri++)
+ {
+ switch (arg[i])
+ {
+ case '\'':
+ case '\\':
+ res[ri++] = '\\';
+ default:
+ ;
+ }
+
+ res[ri] = arg[i];
+ }
+ res[ri] = '\0';
+
+ return res;
+}
+
/* create a list of variables */
static bool
create_statement(int lineno, struct statement **stmt, char *query, va_list ap)
@@ -146,15 +186,8 @@ create_statement(int lineno, struct statement **stmt, char *query, va_list ap)
struct variable **list = &((*stmt)->inlist);
enum ECPGttype type;
- *stmt = calloc(sizeof(struct statement), 1);
-
- if (!*stmt)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
- return false;
- }
+ if (!(*stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
+ return false;
(*stmt)->command = query;
(*stmt)->lineno = lineno;
@@ -173,14 +206,8 @@ create_statement(int lineno, struct statement **stmt, char *query, va_list ap)
{
struct variable *var, *ptr;
- var = malloc(sizeof(struct variable));
- if (!var)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
+ if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
return false;
- }
var->type = type;
var->value = va_arg(ap, void *);
@@ -217,8 +244,8 @@ ECPGexecute(struct statement *stmt)
PGnotify *notify;
struct variable *var;
- memset((char *) &sqlca, 0, sizeof (sqlca));
-
+ memcpy((char *)&sqlca, (char *)&sqlca_init, sizeof(sqlca));
+
copiedquery = strdup(stmt->command);
/*
@@ -314,36 +341,19 @@ ECPGexecute(struct statement *stmt)
int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize;
char * tmp;
- newcopy = (char *) malloc(slen + 1);
- if (!newcopy)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+ if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno)))
return false;
- }
strncpy(newcopy, (char *) var->value, slen);
newcopy[slen] = '\0';
- mallocedval = (char *) malloc(2 * strlen(newcopy) + 3);
- if (!mallocedval)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+ if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno)))
return false;
- }
strcpy(mallocedval, "'");
- tmp = quote_postgres(newcopy);
+ tmp = quote_postgres(newcopy, stmt->lineno);
if (!tmp)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
return false;
- }
strcat(mallocedval, tmp);
strcat(mallocedval, "'");
@@ -360,36 +370,19 @@ ECPGexecute(struct statement *stmt)
(struct ECPGgeneric_varchar *) (var->value);
char *tmp;
- newcopy = (char *) malloc(variable->len + 1);
- if (!newcopy)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+ if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, stmt->lineno)))
return false;
- }
strncpy(newcopy, variable->arr, variable->len);
newcopy[variable->len] = '\0';
- mallocedval = (char *) malloc(2 * strlen(newcopy) + 3);
- if (!mallocedval)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+ if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno)))
return false;
- }
strcpy(mallocedval, "'");
- tmp = quote_postgres(newcopy);
+ tmp = quote_postgres(newcopy, stmt->lineno);
if (!tmp)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
return false;
- }
strcat(mallocedval, tmp);
strcat(mallocedval, "'");
@@ -415,16 +408,8 @@ ECPGexecute(struct statement *stmt)
* Now tobeinserted points to an area that is to be inserted at
* the first %s
*/
- newcopy = (char *) malloc(strlen(copiedquery)
- + strlen(tobeinserted)
- + 1);
- if (!newcopy)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+ if (!(newcopy = (char *) ecpg_alloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
return false;
- }
strcpy(newcopy, copiedquery);
if ((p = strstr(newcopy, ";;")) == NULL)
@@ -857,7 +842,15 @@ ECPGdo(int lineno, char *query, ...)
if (create_statement(lineno, &stmt, query, args) == false)
return(false);
va_end(args);
-
+
+ /* are we connected? */
+ if (actual_connection == NULL || actual_connection->connection == NULL)
+ {
+ ECPGlog("ECPGdo: not connected\n");
+ register_error(ECPG_NOT_CONN, "Not connected in line %d", lineno);
+ return false;
+ }
+
return(ECPGexecute(stmt));
}
@@ -902,14 +895,10 @@ ECPGsetconn(int lineno, const char *connection_name)
bool
ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char * connection_name)
{
- struct connection *this = malloc(sizeof(struct connection));
+ struct connection *this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno);
if (!this)
- {
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
return false;
- }
if (dbname == NULL && connection_name == NULL)
connection_name = "DEFAULT";
@@ -937,7 +926,6 @@ ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd
{
ECPGfinish(this);
ECPGlog("connect: could not open database %s %s%s in line %d\n", dbname ? dbname : "NULL", user ? "for user ": "", user ? user : "", lineno);
-
register_error(ECPG_CONNECT, "connect: could not open database %s.", dbname ? dbname : "NULL");
return false;
}
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index 2b73c8ed88e..20725955958 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -2,8 +2,8 @@ SRCDIR= ../../..
include $(SRCDIR)/Makefile.global
MAJOR_VERSION=2
-MINOR_VERSION=3
-PATCHLEVEL=5
+MINOR_VERSION=4
+PATCHLEVEL=1
CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index 1fe777845b7..3d8624b334a 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -22,7 +22,7 @@ extern char *optarg;
#include "extern.h"
struct _include_path *include_paths;
-static int no_auto_trans = 0;
+int no_auto_trans = 0;
struct cursor *cur = NULL;
static void
@@ -138,10 +138,12 @@ main(int argc, char *const argv[])
else
{
struct cursor *ptr;
+ struct _defines *defptr;
/* remove old cursor definitions if any are still there */
- for (ptr = cur; ptr != NULL; ptr=ptr->next)
+ for (ptr = cur; ptr != NULL;)
{
+ struct cursor *this = ptr;
struct arguments *l1, *l2;
free(ptr->command);
@@ -156,12 +158,25 @@ main(int argc, char *const argv[])
l2 = l1->next;
free(l1);
}
+ ptr = ptr->next;
+ free(this);
}
+
+ /* remove old defines as well */
+ for (defptr = defines; defptr != NULL;)
+ {
+ struct _defines *this = defptr;
+ free(defptr->new);
+ free(defptr->old);
+ defptr = defptr->next;
+ free(this);
+ }
+
/* initialize lex */
lex_init();
/* we need two includes and a constant */
- fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/*These two include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n\nconst int no_auto_trans = %d;\n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, no_auto_trans);
+ fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/* These two include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
/* and parse the source */
yyparse();
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index 43a15394af3..1f25d0824dd 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -3,7 +3,7 @@
/* variables */
-extern int braces_open;
+extern int braces_open, no_auto_trans;
extern char *yytext;
extern int yylineno,
yyleng;
@@ -25,6 +25,13 @@ struct cursor { char *name;
extern struct cursor *cur;
+struct _defines { char *old;
+ char *new;
+ struct _defines *next;
+ };
+
+extern struct _defines *defines;
+
/* This is a linked list of the variable names and types. */
struct variable
{
diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index f578ec8c766..5336d132bf9 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -46,9 +46,12 @@ struct _yy_buffer { YY_BUFFER_STATE buffer;
struct _yy_buffer * next;
} *yy_buffer = NULL;
+struct _defines *defines = NULL;
+static char *old;
+
%}
%option yylineno
-%s C SQL incl
+%s C SQL incl def def_ident
/* OK, here is a short description of lex/flex rules behavior.
* The longest pattern which matches an input string is always chosen.
* For equal-length patterns, the first occurring in the rules list is chosen.
@@ -156,6 +159,7 @@ other .
/* some stuff needed for ecpg */
ccomment "//".*\n
exec [eE][xX][eE][cC]
+define [dD][eE][fF][iI][nN][eE]
include [iI][nN][cC][lL][uU][dD][eE]
sql [sS][qQ][lL]
@@ -307,7 +311,6 @@ cppline {space}*#.*(\\{space}*\n)*\n*
<SQL>{typecast} { return TYPECAST; }
-
<SQL>{self}/{space}*-[\.0-9] {
BEGIN(xm);
return (yytext[0]);
@@ -328,7 +331,6 @@ cppline {space}*#.*(\\{space}*\n)*\n*
yylval.ival = atoi((char*)&yytext[1]);
return (PARAM);
}
-
<SQL>{identifier}/{space}*-{number} {
int i;
ScanKeyword *keyword;
@@ -350,12 +352,36 @@ cppline {space}*#.*(\\{space}*\n)*\n*
}
else
{
- yylval.str = strdup((char*)yytext);
- return (IDENT);
+ struct _defines *ptr;
+
+ for (ptr = defines; ptr; ptr = ptr->next)
+ {
+ if (strcmp(yytext, ptr->old) == 0)
+ {
+ struct _yy_buffer *yb;
+
+ yb = mm_alloc(sizeof(struct _yy_buffer));
+
+ yb->buffer = YY_CURRENT_BUFFER;
+ yb->lineno = yylineno;
+ yb->filename = strdup(input_filename);
+ yb->next = yy_buffer;
+
+ yy_buffer = yb;
+
+ yy_scan_string(ptr->new);
+ break;
+ }
+ }
+ if (ptr == NULL)
+ {
+ yylval.str = strdup((char*)yytext);
+ return (IDENT);
+ }
}
}
}
-{integer}/{space}*-{number} {
+<SQL>{integer}/{space}*-{number} {
char* endptr;
BEGIN(xm);
@@ -372,7 +398,7 @@ cppline {space}*#.*(\\{space}*\n)*\n*
}
return (ICONST);
}
-{real}/{space}*-{number} {
+<SQL>{real}/{space}*-{number} {
char* endptr;
BEGIN(xm);
@@ -382,7 +408,7 @@ cppline {space}*#.*(\\{space}*\n)*\n*
yyerror("ERROR: Bad float8 input");
return (FCONST);
}
-{integer} {
+<SQL>{integer} {
char* endptr;
errno = 0;
@@ -398,7 +424,7 @@ cppline {space}*#.*(\\{space}*\n)*\n*
}
return (ICONST);
}
-{real} {
+<SQL>{real} {
char* endptr;
errno = 0;
@@ -407,7 +433,39 @@ cppline {space}*#.*(\\{space}*\n)*\n*
yyerror("ERROR: Bad float input");
return (FCONST);
}
+<C>{integer}/{space}*-{number} {
+ char* endptr;
+ BEGIN(xm);
+ errno = 0;
+ yylval.ival = strtol((char *)yytext,&endptr,10);
+ if (*endptr != '\0' || errno == ERANGE)
+ {
+ errno = 0;
+ yylval.dval = strtod(((char *)yytext),&endptr);
+ if (*endptr != '\0' || errno == ERANGE)
+ yyerror("ERROR: Bad integer input");
+ yyerror("WARNING: Integer input is out of range; promoted to float");
+ return (FCONST);
+ }
+ return (ICONST);
+ }
+<C>{integer} {
+ char* endptr;
+
+ errno = 0;
+ yylval.ival = strtol((char *)yytext,&endptr,10);
+ if (*endptr != '\0' || errno == ERANGE)
+ {
+ errno = 0;
+ yylval.dval = strtod(((char *)yytext),&endptr);
+ if (*endptr != '\0' || errno == ERANGE)
+ yyerror("ERROR: Bad integer input");
+ yyerror("WARNING: Integer input is out of range; promoted to float");
+ return (FCONST);
+ }
+ return (ICONST);
+ }
<SQL>:{identifier}(("->"|\.){identifier})* {
yylval.str = strdup((char*)yytext+1);
return(CVARIABLE);
@@ -432,15 +490,38 @@ cppline {space}*#.*(\\{space}*\n)*\n*
}
else
{
- yylval.str = strdup((char*)yytext);
- return (IDENT);
+ struct _defines *ptr;
+
+ for (ptr = defines; ptr; ptr = ptr->next)
+ {
+ if (strcmp(yytext, ptr->old) == 0)
+ {
+ struct _yy_buffer *yb;
+
+ yb = mm_alloc(sizeof(struct _yy_buffer));
+
+ yb->buffer = YY_CURRENT_BUFFER;
+ yb->lineno = yylineno;
+ yb->filename = strdup(input_filename);
+ yb->next = yy_buffer;
+
+ yy_buffer = yb;
+
+ yy_scan_string(ptr->new);
+ break;
+ }
+ }
+ if (ptr == NULL)
+ {
+ yylval.str = strdup((char*)yytext);
+ return (IDENT);
+ }
}
}
}
<SQL>{space} { /* ignore */ }
<SQL>";" { BEGIN C; return SQL_SEMI; }
<SQL>{other} { return (yytext[0]); }
-
<C>{exec}{space}{sql} { BEGIN SQL; return SQL_START; }
<C>{ccomment} { /* ignore */ }
<C>{cppline} {
@@ -456,8 +537,32 @@ cppline {space}*#.*(\\{space}*\n)*\n*
}
else
{
- yylval.str = strdup((char*)yytext);
- return (IDENT);
+ struct _defines *ptr;
+
+ for (ptr = defines; ptr; ptr = ptr->next)
+ {
+ if (strcmp(yytext, ptr->old) == 0)
+ {
+ struct _yy_buffer *yb;
+
+ yb = mm_alloc(sizeof(struct _yy_buffer));
+
+ yb->buffer = YY_CURRENT_BUFFER;
+ yb->lineno = yylineno;
+ yb->filename = strdup(input_filename);
+ yb->next = yy_buffer;
+
+ yy_buffer = yb;
+
+ yy_scan_string(ptr->new);
+ break;
+ }
+ }
+ if (ptr == NULL)
+ {
+ yylval.str = strdup((char*)yytext);
+ return (IDENT);
+ }
}
}
<C>";" { return(';'); }
@@ -470,6 +575,45 @@ cppline {space}*#.*(\\{space}*\n)*\n*
<C>\] { return(']'); }
<C>\= { return('='); }
<C>{other} { return (S_ANYTHING); }
+<C>{exec}{space}{sql}{space}{define} {BEGIN(def_ident);}
+<def_ident>{space} {}
+<def_ident>{identifier} {
+ old = strdup(yytext);
+ BEGIN(def);
+ llen = 0;
+ *literal = '\0';
+ }
+<def>{space} /* eat the whitespace */
+<def>";" {
+ struct _defines *ptr, *this;
+
+ for (ptr = defines; ptr != NULL; ptr = ptr->next)
+ {
+ if (strcmp(old, ptr->old) == 0)
+ {
+ free(ptr->new);
+ ptr->new = strdup(scanstr(literal));
+ }
+ }
+ if (ptr == NULL)
+ {
+ this = (struct _defines *) mm_alloc(sizeof(struct _defines));
+
+ /* initial definition */
+ this->old = old;
+ this->new = strdup(scanstr(literal));
+ this->next = defines;
+ defines = this;
+ }
+
+ BEGIN(C);
+ }
+<def>[^";"] {
+ if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
+ yyerror("ERROR: define statement parse buffer exceeded");
+ memcpy(literal+llen, yytext, yyleng+1);
+ llen += yyleng;
+ }
<C>{exec}{space}{sql}{space}{include} { BEGIN(incl); }
<incl>{space} /* eat the whitespace */
<incl>[^ \t\n]+ { /* got the include file name */
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 4d6960e406b..5f67ff48d42 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -620,7 +620,7 @@ output_statement(char * stmt, int mode)
%type <str> ColId default_expr ColQualifier columnDef ColQualList
%type <str> ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
%type <str> OptTableElementList OptTableElement TableConstraint
-%type <str> ConstraintElem key_actions constraint_list TypeId
+%type <str> ConstraintElem key_actions constraint_list
%type <str> res_target_list res_target_el res_target_list2
%type <str> res_target_el2 opt_id relation_name database_name
%type <str> access_method attr_name class index_name name func_name
@@ -636,12 +636,12 @@ output_statement(char * stmt, int mode)
%type <str> SelectStmt union_clause select_list SubSelect result
%type <str> opt_table opt_union opt_unique sort_clause sortby_list
%type <str> sortby OptUseOp opt_inh_star relation_name_list name_list
-%type <str> group_clause groupby_list groupby having_clause from_clause
+%type <str> group_clause having_clause from_clause c_list
%type <str> from_list from_val join_expr join_outer join_spec join_list
%type <str> join_using where_clause relation_expr row_op sub_type
%type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
%type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
-%type <str> NotifyStmt columnElem copy_dirn SubUnion
+%type <str> NotifyStmt columnElem copy_dirn SubUnion c_expr
%type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
%type <str> opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name
%type <str> ClosePortalStmt DestroyStmt VacuumStmt opt_verbose
@@ -652,7 +652,7 @@ output_statement(char * stmt, int mode)
%type <str> def_elem def_list definition def_name def_type DefineStmt
%type <str> opt_instead event event_object OptStmtMulti OptStmtBlock
%type <str> OptStmtList RuleStmt opt_column opt_name oper_argtypes
-%type <str> MathOp RemoveOperStmt RemoveFuncStmt aggr_argtype
+%type <str> MathOp RemoveFuncStmt aggr_argtype
%type <str> RemoveAggrStmt remove_type RemoveStmt ExtendStmt RecipeStmt
%type <str> RemoveOperStmt RenameStmt all_Op user_valid_clause
%type <str> VariableSetStmt var_value zone_value VariableShowStmt
@@ -661,7 +661,7 @@ output_statement(char * stmt, int mode)
%type <str> user_createuser_clause user_group_list user_group_clause
%type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
%type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
-%type <str> TriggerFuncArgs DropTrigStmt TriggerOneEvent TriggerEvents
+%type <str> DropTrigStmt TriggerOneEvent TriggerEvents
%type <str> TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
%type <str> CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
%type <str> ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
@@ -669,7 +669,7 @@ output_statement(char * stmt, int mode)
%type <str> GrantStmt privileges operation_commalist operation
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen open_opts
-%type <str> indicator ECPGExecute c_expr variable_list dotext
+%type <str> indicator ECPGExecute ecpg_expr dotext
%type <str> storage_clause opt_initializer vartext c_anything blockstart
%type <str> blockend variable_list variable var_anything do_anything
%type <str> opt_pointer cvariable ECPGDisconnect dis_name
@@ -756,6 +756,7 @@ stmt: AddAttrStmt { output_statement($1, 0); }
| VariableShowStmt { output_statement($1, 0); }
| VariableResetStmt { output_statement($1, 0); }
| ECPGConnect {
+ fprintf(yyout, "no_auto_trans = %d;\n", no_auto_trans);
fprintf(yyout, "ECPGconnect(__LINE__, %s);", $1);
whenever_action(0);
free($1);
@@ -1307,6 +1308,8 @@ constraint_expr: AexprConst
{ $$ = cat3_str($1, $2, $3); }
| constraint_expr LIKE constraint_expr
{ $$ = cat3_str($1, make1_str("like"), $3); }
+ | constraint_expr NOT LIKE constraint_expr
+ { $$ = cat3_str($1, make1_str("not like"), $4); }
| constraint_expr AND constraint_expr
{ $$ = cat3_str($1, make1_str("and"), $3); }
| constraint_expr OR constraint_expr
@@ -1333,7 +1336,28 @@ constraint_expr: AexprConst
{ $$ = cat2_str($1, make1_str("is not true")); }
| constraint_expr IS NOT FALSE_P
{ $$ = cat2_str($1, make1_str("is not false")); }
- ;
+ | constraint_expr IN '(' c_list ')'
+ { $$ = cat4_str($1, make1_str("in ("), $4, make1_str(")")); }
+ | constraint_expr NOT IN '(' c_list ')'
+ { $$ = cat4_str($1, make1_str("not in ("), $5, make1_str(")")); }
+ | constraint_expr BETWEEN c_expr AND c_expr
+ { $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5); }
+ | constraint_expr NOT BETWEEN c_expr AND c_expr
+ { $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6); }
+ ;
+c_list: c_list ',' c_expr
+ {
+ $$ = make3_str($1, make1_str(", "), $3);
+ }
+ | c_expr
+ {
+ $$ = $1;
+ }
+
+c_expr: AexprConst
+ {
+ $$ = $1;
+ }
key_match: MATCH FULL { $$ = make1_str("match full"); }
| MATCH PARTIAL { $$ = make1_str("match partial"); }
@@ -2025,6 +2049,7 @@ RuleStmt: CREATE RULE name AS
OptStmtList: NOTHING { $$ = make1_str("nothing"); }
| OptimizableStmt { $$ = $1; }
| '[' OptStmtBlock ']' { $$ = cat3_str(make1_str("["), $2, make1_str("]")); }
+ | '(' OptStmtBlock ')' { $$ = cat3_str(make1_str("("), $2, make1_str(")")); }
;
OptStmtBlock: OptStmtMulti
@@ -2480,18 +2505,10 @@ sortby_list: sortby { $$ = $1; }
| sortby_list ',' sortby { $$ = cat3_str($1, make1_str(","), $3); }
;
-sortby: ColId OptUseOp
- {
- $$ = cat2_str($1, $2);
- }
- | ColId '.' ColId OptUseOp
+sortby: a_expr OptUseOp
{
- $$ = cat2_str(make3_str($1, make1_str("."), $3), $4);
- }
- | Iconst OptUseOp
- {
- $$ = cat2_str($1, $2);
- }
+ $$ = cat2_str($1, $2);
+ }
;
OptUseOp: USING Op { $$ = cat2_str(make1_str("using"), $2); }
@@ -2521,28 +2538,10 @@ name_list: name
{ $$ = cat3_str($1, make1_str(","), $3); }
;
-group_clause: GROUP BY groupby_list { $$ = cat2_str(make1_str("groub by"), $3); }
+group_clause: GROUP BY expr_list { $$ = cat2_str(make1_str("groub by"), $3); }
| /*EMPTY*/ { $$ = make1_str(""); }
;
-groupby_list: groupby { $$ = $1; }
- | groupby_list ',' groupby { $$ = cat3_str($1, make1_str(","), $3); }
- ;
-
-groupby: ColId
- {
- $$ = $1;
- }
- | ColId '.' ColId
- {
- $$ = make3_str($1, make1_str(","), $3);
- }
- | Iconst
- {
- $$ = $1;
- }
- ;
-
having_clause: HAVING a_expr
{
$$ = cat2_str(make1_str("having"), $2);
@@ -3410,11 +3409,11 @@ b_expr: attr opt_indirection
{ $$ = make1_str(";;"); }
;
-opt_indirection: '[' c_expr ']' opt_indirection
+opt_indirection: '[' ecpg_expr ']' opt_indirection
{
$$ = cat4_str(make1_str("["), $2, make1_str("]"), $4);
}
- | '[' c_expr ':' c_expr ']' opt_indirection
+ | '[' ecpg_expr ':' ecpg_expr ']' opt_indirection
{
$$ = cat2_str(cat5_str(make1_str("["), $2, make1_str(":"), $4, make1_str("]")), $6);
}
@@ -4353,7 +4352,7 @@ action : SQL_CONTINUE {
/* some other stuff for ecpg */
-c_expr: attr opt_indirection
+ecpg_expr: attr opt_indirection
{
$$ = cat2_str($1, $2);
}
@@ -4365,27 +4364,27 @@ c_expr: attr opt_indirection
{
$$ = $1;
}
- | '-' c_expr %prec UMINUS
+ | '-' ecpg_expr %prec UMINUS
{ $$ = cat2_str(make1_str("-"), $2); }
- | a_expr '+' c_expr
+ | a_expr '+' ecpg_expr
{ $$ = cat3_str($1, make1_str("+"), $3); }
- | a_expr '-' c_expr
+ | a_expr '-' ecpg_expr
{ $$ = cat3_str($1, make1_str("-"), $3); }
- | a_expr '/' c_expr
+ | a_expr '/' ecpg_expr
{ $$ = cat3_str($1, make1_str("/"), $3); }
- | a_expr '*' c_expr
+ | a_expr '*' ecpg_expr
{ $$ = cat3_str($1, make1_str("*"), $3); }
- | a_expr '<' c_expr
+ | a_expr '<' ecpg_expr
{ $$ = cat3_str($1, make1_str("<"), $3); }
- | a_expr '>' c_expr
+ | a_expr '>' ecpg_expr
{ $$ = cat3_str($1, make1_str(">"), $3); }
- | a_expr '=' c_expr
+ | a_expr '=' ecpg_expr
{ $$ = cat3_str($1, make1_str("="), $3); }
- /* | ':' c_expr
+ /* | ':' ecpg_expr
{ $$ = cat2_str(make1_str(":"), $2); }*/
- | ';' c_expr
+ | ';' ecpg_expr
{ $$ = cat2_str(make1_str(";"), $2); }
- | '|' c_expr
+ | '|' ecpg_expr
{ $$ = cat2_str(make1_str("|"), $2); }
| a_expr TYPECAST Typename
{
@@ -4397,13 +4396,13 @@ c_expr: attr opt_indirection
}
| '(' a_expr_or_null ')'
{ $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | a_expr Op c_expr
+ | a_expr Op ecpg_expr
{ $$ = cat3_str($1, $2, $3); }
- | a_expr LIKE c_expr
+ | a_expr LIKE ecpg_expr
{ $$ = cat3_str($1, make1_str("like"), $3); }
- | a_expr NOT LIKE c_expr
+ | a_expr NOT LIKE ecpg_expr
{ $$ = cat3_str($1, make1_str("not like"), $4); }
- | Op c_expr
+ | Op ecpg_expr
{ $$ = cat2_str($1, $2); }
| a_expr Op
{ $$ = cat2_str($1, $2); }
@@ -4621,11 +4620,11 @@ c_expr: attr opt_indirection
{
$$ = make4_str($1, make1_str("=all("), $5, make1_str(")"));
}
- | a_expr AND c_expr
+ | a_expr AND ecpg_expr
{ $$ = cat3_str($1, make1_str("and"), $3); }
- | a_expr OR c_expr
+ | a_expr OR ecpg_expr
{ $$ = cat3_str($1, make1_str("or"), $3); }
- | NOT c_expr
+ | NOT ecpg_expr
{ $$ = cat2_str(make1_str("not"), $2); }
| civariableonly
{ $$ = make1_str(";;"); }