]> granicus.if.org Git - postgresql/commitdiff
- Enable FETCH without INTO.
authorMichael Meskes <meskes@postgresql.org>
Fri, 13 Jun 2003 10:50:58 +0000 (10:50 +0000)
committerMichael Meskes <meskes@postgresql.org>
Fri, 13 Jun 2003 10:50:58 +0000 (10:50 +0000)
- Compatibility functions for INFORMIX handling of DECLARE statement.

src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/compatlib/informix.c
src/interfaces/ecpg/ecpglib/connect.c
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/include/ecpg_informix.h
src/interfaces/ecpg/include/ecpglib.h
src/interfaces/ecpg/preproc/ecpg.c
src/interfaces/ecpg/preproc/extern.h
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/test/test2.pgc

index 858c7f911165e7a1bf2709562d6d8637fc904209..284b94f2baf650ee56aa3d77cde01528b6ddb731 100644 (file)
@@ -1482,6 +1482,11 @@ Wed Jun 11 08:30:41 CEST 2003
 
        - Make sure a variable is no longer referenced when it is removed.
        - Fixed counting bug in parsing "->" operator.
+       
+Fri Jun 13 10:11:12 CEST 2003
+
+       - Enable FETCH without INTO.
+       - Compatibility functions for INFORMIX handling of DECLARE statement.
        - Set ecpg version to 2.12.0.
        - Set ecpg library to 3.4.2.
        - Set pgtypes library to 1.0.0
index 078cc1b29599c8ffbeb4c6b7e2448b98ac05a691..3729fe3dd1c85341c1b10c25ee7ed91b781711a9 100644 (file)
@@ -8,6 +8,8 @@
 #include <pgtypes_error.h>
 #include <pgtypes_date.h>
 
+char * ECPGalloc(long, int);
+
 /* we start with the numeric functions */
 int
 decadd(Numeric *arg1, Numeric *arg2, Numeric *sum)
@@ -673,3 +675,56 @@ dtcvfmtasc (char *inbuf, char *fmtstr, dtime_t *dtvalue)
        return 0;
 }
 
+bool
+ECPGconnect_informix(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
+{
+        char *informix_name = (char *)name, *envname;
+
+        /* Informix uses an environment variable DBPATH that overrides
+        * the connection parameters given here.
+        * We do the same with PG_DBPATH as the syntax is different. */
+        envname = getenv("PG_DBPATH");
+        if (envname)
+                informix_name = envname;
+               return (ECPGconnect(lineno, informix_name, user, passwd, connection_name , autocommit));
+}
+
+static struct var_list
+{
+       int number;
+       void *pointer;
+       struct var_list *next;
+} *ivlist = NULL;
+
+void
+ECPG_informix_set_var(int number, void *pointer, int lineno)
+{
+       struct var_list *ptr;
+
+       for (ptr = ivlist; ptr != NULL; ptr = ptr->next)
+       {
+               if (ptr->number == number)
+               {
+                       /* already known => just change pointer value */
+                       ptr->pointer = pointer;
+                       return;
+               }
+       }
+
+       /* a new one has to be added */
+       ptr = (struct var_list *) ECPGalloc (sizeof(struct var_list), lineno);
+       ptr->number = number;
+       ptr->pointer = pointer;
+       ptr->next = ivlist;
+       ivlist = ptr;
+}
+
+void *
+ECPG_informix_get_var(int number)
+{
+       struct var_list *ptr;
+
+       for (ptr = ivlist; ptr != NULL && ptr->number != number; ptr = ptr->next);
+       return (ptr) ? ptr->pointer : NULL;
+}
+
index 0c8ac72f1829c29e8a791c3c20132f76449326b9..61e078da901a39f66d3149f71473dae2b6eecef0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.5 2003/05/20 11:05:27 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.6 2003/06/13 10:50:57 meskes Exp $ */
 
 #include "postgres_fe.h"
 
@@ -257,21 +257,6 @@ ECPGnoticeProcessor(void *arg, const char *message)
        sqlca.sqlwarn[0] = 'W';
 }
 
-/* this contains some quick hacks, needs to be cleaned up, but it works */
-bool
-ECPGconnect_informix(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
-{
-       char *informix_name = (char *)name, *envname;
-       
-       /* Informix uses an environment variable DBPATH that overrides
-        * the connection parameters given here.
-        * We do the same with PG_DBPATH as the syntax is different. */
-       envname = getenv("PG_DBPATH");
-       if (envname)
-               informix_name = envname;
-       return (ECPGconnect(lineno, informix_name, user, passwd, connection_name, autocommit));
-}
-       
 /* this contains some quick hacks, needs to be cleaned up, but it works */
 bool
 ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
@@ -341,7 +326,7 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
                                *tmp = '\0';
                        }
 
-                       tmp = last_path_separator(dbname + offset);
+                       tmp = last_path_separator(dbname + offset); 
                        if (tmp != NULL)        /* database name given */
                        {
                                realname = strdup(tmp + 1);
index 99850664e861f2fb3f66675ead56d54dab57a408..03d1fbd646aa285ff3662c465deb742035fac4f1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.8 2003/04/01 14:37:25 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.9 2003/06/13 10:50:57 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -1239,7 +1239,7 @@ ECPGexecute(struct statement * stmt)
        {
                ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
                                stmt->lineno, notify->relname, notify->be_pid);
-               PQfreemem(notify);
+               PQfreemem(notify); 
        }
 
        return status;
index ff757598374dcb5d3fac1c84ad60c205f473e2ab..4493dc6f29f2f08f88c27bb837eb9e9e4b0735d8 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <decimal.h>
 #include <datetime.h>
+#include <ecpglib.h>
 
 #define SQLNOTFOUND 100
 
@@ -31,4 +32,7 @@ extern void rupshift(char *);
 
 extern int byleng(char *, int);
 extern void ldchar(char *, int, char *);
-       
+
+extern bool ECPGconnect_informix(int, const char *, const char *, const char *, const char *, int);
+extern void ECPG_informix_set_var(int, void *, int);
+extern void *ECPG_informix_get_var(int);
index 679ff1a7638477346e88d74950b6c6d2d1439a3b..21e2db33f0435861d29e4446ce9ae721292f039f 100644 (file)
@@ -42,7 +42,6 @@ void          ECPGdebug(int, FILE *);
 bool           ECPGstatus(int, const char *);
 bool           ECPGsetcommit(int, const char *, const char *);
 bool           ECPGsetconn(int, const char *);
-bool           ECPGconnect_informix(int, const char *, const char *, const char *, const char *, int);
 bool           ECPGconnect(int, const char *, const char *, const char *, const char *, int);
 bool           ECPGdo(int, const char *, char *,...);
 bool           ECPGtrans(int, const char *, const char *);
index d219047df7d1c40fdf9eac40777152c6b5480be6..bba130792d23c410c0cda3937af6ffb15362ce59 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.72 2003/05/30 08:39:00 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.73 2003/06/13 10:50:57 meskes Exp $ */
 
 /* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
 /* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
@@ -359,6 +359,9 @@ main(int argc, char *const argv[])
                                /* and structure member lists */
                                memset(struct_member_list, 0, sizeof(struct_member_list));
 
+                               /* and our variable counter for Informix compatibility */
+                               ecpg_informix_var = 0;
+
                                /* finally the actual connection */
                                connection = NULL;
                                
index bc0cceaae9998eb963859cac8c0b926a32a7df34..ae6c5bc20491d66356855a05b5580546bf8822af 100644 (file)
@@ -17,7 +17,8 @@ extern int    braces_open,
                        auto_create_c,
                        system_includes,
                        ret_value,
-                       struct_level;
+                       struct_level,
+                       ecpg_informix_var;
 extern char *descriptor_index;
 extern char *descriptor_name;
 extern char *connection;
index 83015d04a59a4a7a56f683ce2d5773cdc57ff520..fa622f314bdfeffd46879d207052f9844a4cee33 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.230 2003/06/11 06:39:12 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.231 2003/06/13 10:50:57 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -11,6 +11,7 @@
  */
 int struct_level = 0;
 int braces_open; /* brace level counter */
+int ecpg_informix_var = 0;
 char   errortext[128];
 char   *connection = NULL;
 char   *input_filename = NULL;
@@ -141,6 +142,7 @@ make3_str(char *str1, char *str2, char *str3)
        return(res_str);
 }
 
+/* and the rest */
 static char *
 make_name(void)
 {
@@ -186,6 +188,36 @@ create_questionmarks(char *name, bool array)
        return(result);
 }
 
+static char *
+adjust_informix(struct arguments *list)
+{
+       /* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
+        * 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[sizeof(int)+sizeof(", &()")];
+               char *original_var;
+               
+               /* change variable name to "ECPG_informix_get_var(<counter>)" */
+               original_var = ptr->variable->name;
+               sprintf(temp, "%d))", ecpg_informix_var);
+               ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ECPGtype_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), 0);
+               
+               /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
+               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;
+}
+
 %}
 
 %union {
@@ -1098,7 +1130,10 @@ opt_drop_behavior: CASCADE                       { $$ = make_str("cascade"); }
  *
  *****************************************************************************/
 
-ClosePortalStmt:  CLOSE name   { $$ = cat2_str(make_str("close"), $2); }
+ClosePortalStmt:  CLOSE name
+               {
+                       $$ = cat2_str(make_str("close"), $2);
+               }
                ;
 
 /*****************************************************************************
@@ -1734,6 +1769,10 @@ FetchStmt: FETCH fetch_direction from_in name ecpg_into_using
                        { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
                | FETCH name ecpg_into_using
                        { $$ = cat2_str(make_str("fetch"), $2); }
+               | FETCH fetch_direction from_in name
+                       { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
+               | FETCH name 
+                       { $$ = cat2_str(make_str("fetch"), $2); }
                | MOVE fetch_direction from_in name
                        { $$ = cat_str(4, make_str("move"), $2, $3, $4); }
                | MOVE name
@@ -2630,10 +2669,12 @@ DeclareCursorStmt:  DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
                        this->argsinsert = argsinsert;
                        this->argsresult = argsresult;
                        argsinsert = argsresult = NULL;
-
                        cur = this;
 
-                       $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
+                       if (compat == ECPG_COMPAT_INFORMIX)
+                               $$ = 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("*/"));
                }
                ;
 
index 701b11afb5c1be297bcee1d356f20ca1cf161a1c..0d11c0c38a8613a5ed98ceaf48c73cdc1aebafce 100644 (file)
@@ -12,6 +12,9 @@ typedef union { int integer; short smallint; } ind;
 #define BUFFERSIZ 8
 exec sql type str is varchar[BUFFERSIZ];
 
+exec sql declare cur cursor for
+       select name, born, age, married, children from meskes;
+
 int
 main ()
 {
@@ -34,9 +37,6 @@ exec sql end declare section;
 
        exec sql var ind_married is long;
 
-       exec sql declare cur cursor for
-              select name, born, age, married, children from meskes;
-
        char msg[128];
        FILE *dbgs;