]> granicus.if.org Git - postgresql/commitdiff
Applied patch by Boszormenyi Zoltan <zb@cybertec.at> to fix problem in auto-prepare...
authorMichael Meskes <meskes@postgresql.org>
Fri, 22 Jan 2010 14:13:03 +0000 (14:13 +0000)
committerMichael Meskes <meskes@postgresql.org>
Fri, 22 Jan 2010 14:13:03 +0000 (14:13 +0000)
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/ecpglib/prepare.c
src/interfaces/ecpg/test/expected/preproc-autoprep.c
src/interfaces/ecpg/test/expected/preproc-autoprep.stderr
src/interfaces/ecpg/test/expected/preproc-autoprep.stdout
src/interfaces/ecpg/test/preproc/autoprep.pgc

index acb1e4bfdd536f25eb07f86bf631046e92023305..ec2ca8915e38eabdc4356684ae47ddac812de242 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.88 2010/01/05 16:38:23 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.89 2010/01/22 14:13:03 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -1753,7 +1753,10 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
                        stmt->command = ecpg_strdup(command, lineno);
                }
                else
+               {
                        ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
+                       return (false);
+               }
        }
 
        stmt->connection = con;
index 6be062f4d8fa7b8f5ac07ba918221bbf85cdcb6a..a9eef754604f3bb1c3d291821976a0341f34ed69 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.34 2010/01/15 10:44:34 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.35 2010/01/22 14:13:03 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -99,27 +99,13 @@ replace_variables(char **text, int lineno)
        return true;
 }
 
-/* handle the EXEC SQL PREPARE statement */
-/* questionmarks is not needed but remians in there for the time being to not change the API */
-bool
-ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable)
+static bool
+prepare_common(int lineno, struct connection *con, const bool questionmarks, const char *name, const char *variable)
 {
-       struct connection *con;
        struct statement *stmt;
-       struct prepared_statement *this,
-                          *prev;
+       struct prepared_statement *this;
        PGresult   *query;
 
-       con = ecpg_get_connection(connection_name);
-
-       if (!ecpg_init(con, connection_name, lineno))
-               return false;
-
-       /* check if we already have prepared this statement */
-       this = ecpg_find_prepared_statement(name, con, &prev);
-       if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this))
-               return false;
-
        /* allocate new statement */
        this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno);
        if (!this)
@@ -169,6 +155,28 @@ ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, c
        return true;
 }
 
+/* handle the EXEC SQL PREPARE statement */
+/* questionmarks is not needed but remians in there for the time being to not change the API */
+bool
+ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable)
+{
+       struct connection *con;
+       struct prepared_statement *this,
+                          *prev;
+
+       con = ecpg_get_connection(connection_name);
+
+       if (!ecpg_init(con, connection_name, lineno))
+               return false;
+
+       /* check if we already have prepared this statement */
+       this = ecpg_find_prepared_statement(name, con, &prev);
+       if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this))
+               return false;
+
+       return prepare_common(lineno, con, questionmarks, name, variable);
+}
+
 struct prepared_statement *
 ecpg_find_prepared_statement(const char *name,
                                 struct connection * con, struct prepared_statement ** prev_)
@@ -465,21 +473,37 @@ ecpg_auto_prepare(int lineno, const char *connection_name, const int compat, cha
        /* if not found - add the statement to the cache        */
        if (entNo)
        {
+               char       *stmtID;
+               struct connection *con;
+               struct prepared_statement *prep;
+
                ecpg_log("ecpg_auto_prepare on line %d: statement found in cache; entry %d\n", lineno, entNo);
-               *name = ecpg_strdup(stmtCacheEntries[entNo].stmtID, lineno);
+
+               stmtID = stmtCacheEntries[entNo].stmtID;
+
+               con = ecpg_get_connection(connection_name);
+               prep = ecpg_find_prepared_statement(stmtID, con, NULL);
+               /* This prepared name doesn't exist on this connection. */
+               if (!prep && !prepare_common(lineno, con, 0, stmtID, query))
+                       return (false);
+
+               *name = ecpg_strdup(stmtID, lineno);
        }
        else
        {
+               char    stmtID[STMTID_SIZE];
+
                ecpg_log("ecpg_auto_prepare on line %d: statement not in cache; inserting\n", lineno);
 
                /* generate a statement ID */
-               *name = (char *) ecpg_alloc(STMTID_SIZE, lineno);
-               sprintf(*name, "ecpg%d", nextStmtID++);
+               sprintf(stmtID, "ecpg%d", nextStmtID++);
 
-               if (!ECPGprepare(lineno, connection_name, 0, ecpg_strdup(*name, lineno), query))
+               if (!ECPGprepare(lineno, connection_name, 0, stmtID, query))
                        return (false);
-               if (AddStmtToCache(lineno, *name, connection_name, compat, query) < 0)
+               if (AddStmtToCache(lineno, stmtID, connection_name, compat, query) < 0)
                        return (false);
+
+               *name = ecpg_strdup(stmtID, lineno);
        }
 
        /* increase usage counter */
index 039ed43758de41da5744707f321fd18140aec149..430d0710006ffdc0e42ff0fe55ea4e2f96f6068b 100644 (file)
@@ -23,7 +23,7 @@
 #line 6 "autoprep.pgc"
 
 
-int main() {
+static void test(void) {
   /* exec sql begin declare section */
             
          
@@ -246,6 +246,11 @@ if (sqlca.sqlwarn[0] == 'W') sqlprint();
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 64 "autoprep.pgc"
 
+}
+
+int main() {
+  test();
+  test();     /* retry */
 
   return 0;
 }
index 1bed36a7e29d6c295f5fcab634f235ff50d49c32..307ba4211692c4ed1e92fa5bdc482a6b4e36d11d 100644 (file)
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_finish: connection regress1 closed
 [NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGdebug: set to 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 21: query: create table T ( Item1 int , Item2 int ); with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 21: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 21: OK: CREATE TABLE
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_auto_prepare on line 23: statement found in cache; entry 15328
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGprepare on line 23: name ecpg1; query: "insert into T values ( 1 , null )"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 23: query: insert into T values ( 1 , null ); with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 23: using PQexecPrepared for "insert into T values ( 1 , null )"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 23: OK: INSERT 0 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_auto_prepare on line 24: statement found in cache; entry 1640
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGprepare on line 24: name ecpg2; query: "insert into T values ( 1 , $1  )"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 24: query: insert into T values ( 1 , $1  ); with 1 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 24: using PQexecPrepared for "insert into T values ( 1 , $1  )"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: free_params on line 24: parameter 1 = 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 24: OK: INSERT 0 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_auto_prepare on line 26: statement found in cache; entry 1640
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 26: query: insert into T values ( 1 , $1  ); with 1 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 26: using PQexecPrepared for "insert into T values ( 1 , $1  )"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: free_params on line 26: parameter 1 = 2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGprepare on line 27: name i; query: " insert into T values ( 1 , 2 ) "
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 28: query:  insert into T values ( 1 , 2 ) ; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 28: using PQexecPrepared for " insert into T values ( 1 , 2 ) "
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 28: OK: INSERT 0 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_auto_prepare on line 30: statement found in cache; entry 13056
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGprepare on line 30: name ecpg3; query: "select Item2 from T order by Item2 nulls last"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 30: query: select Item2 from T order by Item2 nulls last; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 30: using PQexecPrepared for "select Item2 from T order by Item2 nulls last"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 30: correctly got 4 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 30: RESULT: 1 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 30: RESULT: 2 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 30: RESULT: 2 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 30: RESULT:  offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 37: query: declare C cursor for select Item1 from T; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 37: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 37: OK: DECLARE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 39: query: fetch 1 in C; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 39: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 39: correctly got 1 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 39: RESULT: 1 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 42: query: close C; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 42: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 42: OK: CLOSE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGprepare on line 44: name stmt1; query: "SELECT item2 FROM T ORDER BY item2 NULLS LAST"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 48: query: declare cur1 cursor for SELECT item2 FROM T ORDER BY item2 NULLS LAST; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 48: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 48: OK: DECLARE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: correctly got 1 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 55: RESULT: 1 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: correctly got 1 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 55: RESULT: 2 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: correctly got 1 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 55: RESULT: 2 offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: correctly got 1 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 55: RESULT:  offset: -1; array: yes
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 55: correctly got 0 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: raising sqlcode 100 on line 55: no data found on line 55
+[NO_PID]: sqlca: code: 100, state: 02000
+[NO_PID]: ecpg_execute on line 60: query: close cur1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 60: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 60: OK: CLOSE CURSOR
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 62: query: drop table T; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 62: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 62: OK: DROP TABLE
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGdeallocate on line 0: name stmt1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGdeallocate on line 0: name ecpg3
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGdeallocate on line 0: name i
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGdeallocate on line 0: name ecpg2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGdeallocate on line 0: name ecpg1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_finish: connection regress1 closed
+[NO_PID]: sqlca: code: 0, state: 00000
index ae943aac606c456b72c792bbb6a8b43b700e0ac7..16a3263c44bbd6cd1e9fd5d2052a594a6ff72f2d 100644 (file)
@@ -7,3 +7,12 @@ item[0] = 1
 item[1] = 2
 item[2] = 2
 item[3] = -1
+item[0] = 1
+item[1] = 2
+item[2] = 2
+item[3] = -1
+i = 1
+item[0] = 1
+item[1] = 2
+item[2] = 2
+item[3] = -1
index d774038558df254d866d82d63f217f88c2229111..eeeb879d10520c400bb1b90b037013d4279b9db6 100644 (file)
@@ -5,7 +5,7 @@
 /* test automatic prepare for all statements */
 EXEC SQL INCLUDE ../regression;
 
-int main() {
+static void test(void) {
   EXEC SQL BEGIN DECLARE SECTION;
        int item[4], ind[4], i = 1;
        int item1, ind1;
@@ -62,6 +62,11 @@ int main() {
   EXEC SQL DROP TABLE T;
 
   EXEC SQL DISCONNECT ALL;
+}
+
+int main() {
+  test();
+  test();     /* retry */
 
   return 0;
 }