6-pg85-fix-auto-prepare-multiconn-4.patch
text/x-patch
Filename: 6-pg85-fix-auto-prepare-multiconn-4.patch
Type: text/x-patch
Part: 0
Message:
Re: Fix auto-prepare #2
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/interfaces/ecpg/ecpglib/execute.c | 3 | 0 |
| src/interfaces/ecpg/ecpglib/prepare.c | 46 | 22 |
| src/interfaces/ecpg/test/expected/preproc-autoprep.c | 6 | 1 |
| src/interfaces/ecpg/test/expected/preproc-autoprep.stderr | 160 | 0 |
| src/interfaces/ecpg/test/expected/preproc-autoprep.stdout | 9 | 0 |
| src/interfaces/ecpg/test/preproc/autoprep.pgc | 6 | 1 |
diff -dcrpN pgsql.orig/src/interfaces/ecpg/ecpglib/execute.c pgsql.1/src/interfaces/ecpg/ecpglib/execute.c
*** pgsql.orig/src/interfaces/ecpg/ecpglib/execute.c 2010-01-05 18:02:03.000000000 +0100
--- pgsql.1/src/interfaces/ecpg/ecpglib/execute.c 2010-01-18 11:49:17.000000000 +0100
*************** ECPGdo(const int lineno, const int compa
*** 1753,1759 ****
--- 1753,1762 ----
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;
diff -dcrpN pgsql.orig/src/interfaces/ecpg/ecpglib/prepare.c pgsql.1/src/interfaces/ecpg/ecpglib/prepare.c
*** pgsql.orig/src/interfaces/ecpg/ecpglib/prepare.c 2010-01-15 12:55:24.000000000 +0100
--- pgsql.1/src/interfaces/ecpg/ecpglib/prepare.c 2010-01-19 11:53:42.000000000 +0100
*************** replace_variables(char **text, int linen
*** 99,125 ****
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 statement *stmt;
! struct prepared_statement *this,
! *prev;
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)
--- 99,111 ----
return true;
}
! static bool
! prepare_common(int lineno, struct connection *con, const bool questionmarks, const char *name, const char *variable)
{
struct statement *stmt;
! struct prepared_statement *this;
PGresult *query;
/* allocate new statement */
this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno);
if (!this)
*************** ECPGprepare(int lineno, const char *conn
*** 169,174 ****
--- 155,182 ----
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_)
*************** ecpg_auto_prepare(int lineno, const char
*** 465,485 ****
/* if not found - add the statement to the cache */
if (entNo)
{
ecpg_log("ecpg_auto_prepare on line %d: statement found in cache; entry %d\n", lineno, entNo);
! *name = ecpg_strdup(stmtCacheEntries[entNo].stmtID, lineno);
}
else
{
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++);
! if (!ECPGprepare(lineno, connection_name, 0, ecpg_strdup(*name, lineno), query))
return (false);
! if (AddStmtToCache(lineno, *name, connection_name, compat, query) < 0)
return (false);
}
/* increase usage counter */
--- 473,509 ----
/* 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);
!
! 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 */
! sprintf(stmtID, "ecpg%d", nextStmtID++);
! if (!ECPGprepare(lineno, connection_name, 0, stmtID, query))
return (false);
! if (AddStmtToCache(lineno, stmtID, connection_name, compat, query) < 0)
return (false);
+
+ *name = ecpg_strdup(stmtID, lineno);
}
/* increase usage counter */
diff -dcrpN pgsql.orig/src/interfaces/ecpg/test/expected/preproc-autoprep.c pgsql.1/src/interfaces/ecpg/test/expected/preproc-autoprep.c
*** pgsql.orig/src/interfaces/ecpg/test/expected/preproc-autoprep.c 2009-12-16 11:30:27.000000000 +0100
--- pgsql.1/src/interfaces/ecpg/test/expected/preproc-autoprep.c 2010-01-19 11:54:32.000000000 +0100
***************
*** 23,29 ****
#line 6 "autoprep.pgc"
! int main() {
/* exec sql begin declare section */
--- 23,29 ----
#line 6 "autoprep.pgc"
! static void test(void) {
/* exec sql begin declare section */
*************** if (sqlca.sqlwarn[0] == 'W') sqlprint();
*** 246,251 ****
--- 246,256 ----
if (sqlca.sqlcode < 0) sqlprint();}
#line 64 "autoprep.pgc"
+ }
+
+ int main() {
+ test();
+ test(); /* retry */
return 0;
}
diff -dcrpN pgsql.orig/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr pgsql.1/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr
*** pgsql.orig/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr 2009-12-16 11:30:27.000000000 +0100
--- pgsql.1/src/interfaces/ecpg/test/expected/preproc-autoprep.stderr 2010-01-19 11:54:33.000000000 +0100
***************
*** 158,160 ****
--- 158,320 ----
[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
diff -dcrpN pgsql.orig/src/interfaces/ecpg/test/expected/preproc-autoprep.stdout pgsql.1/src/interfaces/ecpg/test/expected/preproc-autoprep.stdout
*** pgsql.orig/src/interfaces/ecpg/test/expected/preproc-autoprep.stdout 2009-12-16 11:30:27.000000000 +0100
--- pgsql.1/src/interfaces/ecpg/test/expected/preproc-autoprep.stdout 2010-01-19 11:54:32.000000000 +0100
*************** item[0] = 1
*** 7,9 ****
--- 7,18 ----
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
diff -dcrpN pgsql.orig/src/interfaces/ecpg/test/preproc/autoprep.pgc pgsql.1/src/interfaces/ecpg/test/preproc/autoprep.pgc
*** pgsql.orig/src/interfaces/ecpg/test/preproc/autoprep.pgc 2009-12-16 11:30:27.000000000 +0100
--- pgsql.1/src/interfaces/ecpg/test/preproc/autoprep.pgc 2010-01-19 11:49:21.000000000 +0100
***************
*** 5,11 ****
/* test automatic prepare for all statements */
EXEC SQL INCLUDE ../regression;
! int main() {
EXEC SQL BEGIN DECLARE SECTION;
int item[4], ind[4], i = 1;
int item1, ind1;
--- 5,11 ----
/* test automatic prepare for all statements */
EXEC SQL INCLUDE ../regression;
! static void test(void) {
EXEC SQL BEGIN DECLARE SECTION;
int item[4], ind[4], i = 1;
int item1, ind1;
*************** int main() {
*** 62,67 ****
--- 62,72 ----
EXEC SQL DROP TABLE T;
EXEC SQL DISCONNECT ALL;
+ }
+
+ int main() {
+ test();
+ test(); /* retry */
return 0;
}