From: Michael Meskes
authorMarc G. Fournier
Tue, 25 Aug 1998 12:17:27 +0000 (12:17 +0000)
committerMarc G. Fournier
Tue, 25 Aug 1998 12:17:27 +0000 (12:17 +0000)
+
+ 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
+

src/interfaces/ecpg/lib/Makefile.in
src/interfaces/ecpg/lib/ecpglib.c
src/interfaces/ecpg/preproc/Makefile
src/interfaces/ecpg/preproc/ecpg.c
src/interfaces/ecpg/preproc/extern.h
src/interfaces/ecpg/preproc/pgc.l
src/interfaces/ecpg/preproc/preproc.y

index e236487d6aaec05d351744292689d85f7e14712b..53f3d5ac44abf91be8b3dfc81b971583a469384a 100644 (file)
@@ -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@
 
index 0d3d4fa0e6a471ca82607d4c8fb6cebf2657c467..e2b8e2ce5993ac5130ae7a05c93313e949256bd1 100644 (file)
 #include 
 #include 
 
-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;
    }
index 2b73c8ed88e09f278eefb1908ede0a172b7d9e02..207259559586243f6b0c45084e9686fedb95a82e 100644 (file)
@@ -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) \
index 1fe777845b7ad3979130c06bbd75347a669da60a..3d8624b334aabbb75208146a6192d2901879af06 100644 (file)
@@ -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 \n#include \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 \n#include \n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
 
                /* and parse the source */
                yyparse();
index 43a15394af3d86c92f548255e471c6778c7c1b67..1f25d0824dd0c736d1a63f89199b76e3f3a92046 100644 (file)
@@ -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
 {
index f578ec8c766fe1c572ceebdc4ce034eabb82d518..5336d132bf9121ef99690a8b5d31fd34265fc056 100644 (file)
@@ -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*
 
 
 {typecast}            {   return TYPECAST; }
-
 {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);
                }
-
 {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}    {
+{integer}/{space}*-{number}   {
                    char* endptr;
 
                    BEGIN(xm);
@@ -372,7 +398,7 @@ cppline     {space}*#.*(\\{space}*\n)*\n*
                    }
                    return (ICONST);
                }
-{real}/{space}*-{number} {
+{real}/{space}*-{number} {
                    char* endptr;
 
                    BEGIN(xm);
@@ -382,7 +408,7 @@ cppline     {space}*#.*(\\{space}*\n)*\n*
                        yyerror("ERROR: Bad float8 input");
                    return (FCONST);
                }
-{integer}      {
+{integer}     {
                    char* endptr;
 
                    errno = 0;
@@ -398,7 +424,7 @@ cppline     {space}*#.*(\\{space}*\n)*\n*
                    }
                    return (ICONST);
                }
-{real}         {
+{real}            {
                    char* endptr;
 
                    errno = 0;
@@ -407,7 +433,39 @@ cppline        {space}*#.*(\\{space}*\n)*\n*
                        yyerror("ERROR: Bad float input");
                    return (FCONST);
                }
+{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);
+               }
+{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);
+               }
 :{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);
+                           }
                        }
                    }
                }
 {space}           { /* ignore */ }
 ";"                   { BEGIN C; return SQL_SEMI; }
 {other}           { return (yytext[0]); }
-
 {exec}{space}{sql}      { BEGIN SQL; return SQL_START; }
 {ccomment}          { /* ignore */ } 
 {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);
+                       }
                    }
                }
 ";"                 { return(';'); }
@@ -470,6 +575,45 @@ cppline        {space}*#.*(\\{space}*\n)*\n*
 \]          { return(']'); }
 \=          { return('='); }
 {other}         { return (S_ANYTHING); }
+{exec}{space}{sql}{space}{define}   {BEGIN(def_ident);}
+{space} {}
+{identifier}    {
+               old = strdup(yytext);
+               BEGIN(def);
+               llen = 0;
+               *literal = '\0';
+           }
+{space}       /* eat the whitespace */
+";"       {
+               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);
+           }
+[^";"]        {
+               if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
+                   yyerror("ERROR: define statement parse buffer exceeded");
+               memcpy(literal+llen, yytext, yyleng+1);
+               llen += yyleng;
+           }
 {exec}{space}{sql}{space}{include}  { BEGIN(incl); }
 {space}      /* eat the whitespace */
 [^ \t\n]+    { /* got the include file name */
index 4d6960e406bd3d526c6f0cc3959b9499b5ce10e4..5f67ff48d4236e8fe19f8ea978a38d4eeebea111 100644 (file)
@@ -620,7 +620,7 @@ output_statement(char * stmt, int mode)
 %type     ColId default_expr ColQualifier columnDef ColQualList
 %type      ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
 %type      OptTableElementList OptTableElement TableConstraint
-%type      ConstraintElem key_actions constraint_list TypeId
+%type      ConstraintElem key_actions constraint_list
 %type      res_target_list res_target_el res_target_list2
 %type      res_target_el2 opt_id relation_name database_name
 %type      access_method attr_name class index_name name func_name
@@ -636,12 +636,12 @@ output_statement(char * stmt, int mode)
 %type     SelectStmt union_clause select_list SubSelect result
 %type     opt_table opt_union opt_unique sort_clause sortby_list
 %type     sortby OptUseOp opt_inh_star relation_name_list name_list
-%type     group_clause groupby_list groupby having_clause from_clause
+%type     group_clause having_clause from_clause c_list 
 %type     from_list from_val join_expr join_outer join_spec join_list
 %type     join_using where_clause relation_expr row_op sub_type
 %type     opt_column_list insert_rest InsertStmt OptimizableStmt
 %type      columnList DeleteStmt LockStmt UpdateStmt CursorStmt
-%type      NotifyStmt columnElem copy_dirn SubUnion
+%type      NotifyStmt columnElem copy_dirn SubUnion c_expr
 %type      copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
 %type      opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name
 %type      ClosePortalStmt DestroyStmt VacuumStmt opt_verbose
@@ -652,7 +652,7 @@ output_statement(char * stmt, int mode)
 %type      def_elem def_list definition def_name def_type DefineStmt
 %type      opt_instead event event_object OptStmtMulti OptStmtBlock
 %type      OptStmtList RuleStmt opt_column opt_name oper_argtypes
-%type      MathOp RemoveOperStmt RemoveFuncStmt aggr_argtype
+%type      MathOp RemoveFuncStmt aggr_argtype
 %type      RemoveAggrStmt remove_type RemoveStmt ExtendStmt RecipeStmt
 %type      RemoveOperStmt RenameStmt all_Op user_valid_clause
 %type      VariableSetStmt var_value zone_value VariableShowStmt
@@ -661,7 +661,7 @@ output_statement(char * stmt, int mode)
 %type      user_createuser_clause user_group_list user_group_clause
 %type      CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
 %type      OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
-%type     TriggerFuncArgs DropTrigStmt TriggerOneEvent TriggerEvents
+%type     DropTrigStmt TriggerOneEvent TriggerEvents
 %type      TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
 %type      CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
 %type      ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
@@ -669,7 +669,7 @@ output_statement(char * stmt, int mode)
 %type     GrantStmt privileges operation_commalist operation
 
 %type     ECPGWhenever ECPGConnect connection_target ECPGOpen open_opts
-%type     indicator ECPGExecute c_expr variable_list dotext
+%type     indicator ECPGExecute ecpg_expr dotext
 %type      storage_clause opt_initializer vartext c_anything blockstart
 %type      blockend variable_list variable var_anything do_anything
 %type     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(";;"); }