Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5bc7561

Browse files
author
Michael Meskes
committed
Applied patch by Boszormenyi Zoltan <zb@cybertec.at> to fix problem in auto-prepare mode if the connection is closed and re-opened and the previously prepared query is issued again.
1 parent b13da41 commit 5bc7561

File tree

6 files changed

+232
-26
lines changed

6 files changed

+232
-26
lines changed

src/interfaces/ecpg/ecpglib/execute.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.88 2010/01/05 16:38:23 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.89 2010/01/22 14:13:03 meskes Exp $ */
22

33
/*
44
* 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
17531753
stmt->command = ecpg_strdup(command, lineno);
17541754
}
17551755
else
1756+
{
17561757
ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
1758+
return (false);
1759+
}
17571760
}
17581761

17591762
stmt->connection = con;

src/interfaces/ecpg/ecpglib/prepare.c

+47-23
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.34 2010/01/15 10:44:34 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.35 2010/01/22 14:13:03 meskes Exp $ */
22

33
#define POSTGRES_ECPG_INTERNAL
44
#include "postgres_fe.h"
@@ -99,27 +99,13 @@ replace_variables(char **text, int lineno)
9999
return true;
100100
}
101101

102-
/* handle the EXEC SQL PREPARE statement */
103-
/* questionmarks is not needed but remians in there for the time being to not change the API */
104-
bool
105-
ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable)
102+
static bool
103+
prepare_common(int lineno, struct connection *con, const bool questionmarks, const char *name, const char *variable)
106104
{
107-
struct connection *con;
108105
struct statement *stmt;
109-
struct prepared_statement *this,
110-
*prev;
106+
struct prepared_statement *this;
111107
PGresult *query;
112108

113-
con = ecpg_get_connection(connection_name);
114-
115-
if (!ecpg_init(con, connection_name, lineno))
116-
return false;
117-
118-
/* check if we already have prepared this statement */
119-
this = ecpg_find_prepared_statement(name, con, &prev);
120-
if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this))
121-
return false;
122-
123109
/* allocate new statement */
124110
this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno);
125111
if (!this)
@@ -169,6 +155,28 @@ ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, c
169155
return true;
170156
}
171157

158+
/* handle the EXEC SQL PREPARE statement */
159+
/* questionmarks is not needed but remians in there for the time being to not change the API */
160+
bool
161+
ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable)
162+
{
163+
struct connection *con;
164+
struct prepared_statement *this,
165+
*prev;
166+
167+
con = ecpg_get_connection(connection_name);
168+
169+
if (!ecpg_init(con, connection_name, lineno))
170+
return false;
171+
172+
/* check if we already have prepared this statement */
173+
this = ecpg_find_prepared_statement(name, con, &prev);
174+
if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this))
175+
return false;
176+
177+
return prepare_common(lineno, con, questionmarks, name, variable);
178+
}
179+
172180
struct prepared_statement *
173181
ecpg_find_prepared_statement(const char *name,
174182
struct connection * con, struct prepared_statement ** prev_)
@@ -465,21 +473,37 @@ ecpg_auto_prepare(int lineno, const char *connection_name, const int compat, cha
465473
/* if not found - add the statement to the cache */
466474
if (entNo)
467475
{
476+
char *stmtID;
477+
struct connection *con;
478+
struct prepared_statement *prep;
479+
468480
ecpg_log("ecpg_auto_prepare on line %d: statement found in cache; entry %d\n", lineno, entNo);
469-
*name = ecpg_strdup(stmtCacheEntries[entNo].stmtID, lineno);
481+
482+
stmtID = stmtCacheEntries[entNo].stmtID;
483+
484+
con = ecpg_get_connection(connection_name);
485+
prep = ecpg_find_prepared_statement(stmtID, con, NULL);
486+
/* This prepared name doesn't exist on this connection. */
487+
if (!prep && !prepare_common(lineno, con, 0, stmtID, query))
488+
return (false);
489+
490+
*name = ecpg_strdup(stmtID, lineno);
470491
}
471492
else
472493
{
494+
char stmtID[STMTID_SIZE];
495+
473496
ecpg_log("ecpg_auto_prepare on line %d: statement not in cache; inserting\n", lineno);
474497

475498
/* generate a statement ID */
476-
*name = (char *) ecpg_alloc(STMTID_SIZE, lineno);
477-
sprintf(*name, "ecpg%d", nextStmtID++);
499+
sprintf(stmtID, "ecpg%d", nextStmtID++);
478500

479-
if (!ECPGprepare(lineno, connection_name, 0, ecpg_strdup(*name, lineno), query))
501+
if (!ECPGprepare(lineno, connection_name, 0, stmtID, query))
480502
return (false);
481-
if (AddStmtToCache(lineno, *name, connection_name, compat, query) < 0)
503+
if (AddStmtToCache(lineno, stmtID, connection_name, compat, query) < 0)
482504
return (false);
505+
506+
*name = ecpg_strdup(stmtID, lineno);
483507
}
484508

485509
/* increase usage counter */

src/interfaces/ecpg/test/expected/preproc-autoprep.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#line 6 "autoprep.pgc"
2424

2525

26-
int main() {
26+
static void test(void) {
2727
/* exec sql begin declare section */
2828

2929

@@ -246,6 +246,11 @@ if (sqlca.sqlwarn[0] == 'W') sqlprint();
246246
if (sqlca.sqlcode < 0) sqlprint();}
247247
#line 64 "autoprep.pgc"
248248

249+
}
250+
251+
int main() {
252+
test();
253+
test(); /* retry */
249254

250255
return 0;
251256
}

src/interfaces/ecpg/test/expected/preproc-autoprep.stderr

+160
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,163 @@
158158
[NO_PID]: sqlca: code: 0, state: 00000
159159
[NO_PID]: ecpg_finish: connection regress1 closed
160160
[NO_PID]: sqlca: code: 0, state: 00000
161+
[NO_PID]: ECPGdebug: set to 1
162+
[NO_PID]: sqlca: code: 0, state: 00000
163+
[NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>
164+
[NO_PID]: sqlca: code: 0, state: 00000
165+
[NO_PID]: ecpg_execute on line 21: query: create table T ( Item1 int , Item2 int ); with 0 parameter(s) on connection regress1
166+
[NO_PID]: sqlca: code: 0, state: 00000
167+
[NO_PID]: ecpg_execute on line 21: using PQexec
168+
[NO_PID]: sqlca: code: 0, state: 00000
169+
[NO_PID]: ecpg_execute on line 21: OK: CREATE TABLE
170+
[NO_PID]: sqlca: code: 0, state: 00000
171+
[NO_PID]: ecpg_auto_prepare on line 23: statement found in cache; entry 15328
172+
[NO_PID]: sqlca: code: 0, state: 00000
173+
[NO_PID]: ECPGprepare on line 23: name ecpg1; query: "insert into T values ( 1 , null )"
174+
[NO_PID]: sqlca: code: 0, state: 00000
175+
[NO_PID]: ecpg_execute on line 23: query: insert into T values ( 1 , null ); with 0 parameter(s) on connection regress1
176+
[NO_PID]: sqlca: code: 0, state: 00000
177+
[NO_PID]: ecpg_execute on line 23: using PQexecPrepared for "insert into T values ( 1 , null )"
178+
[NO_PID]: sqlca: code: 0, state: 00000
179+
[NO_PID]: ecpg_execute on line 23: OK: INSERT 0 1
180+
[NO_PID]: sqlca: code: 0, state: 00000
181+
[NO_PID]: ecpg_auto_prepare on line 24: statement found in cache; entry 1640
182+
[NO_PID]: sqlca: code: 0, state: 00000
183+
[NO_PID]: ECPGprepare on line 24: name ecpg2; query: "insert into T values ( 1 , $1 )"
184+
[NO_PID]: sqlca: code: 0, state: 00000
185+
[NO_PID]: ecpg_execute on line 24: query: insert into T values ( 1 , $1 ); with 1 parameter(s) on connection regress1
186+
[NO_PID]: sqlca: code: 0, state: 00000
187+
[NO_PID]: ecpg_execute on line 24: using PQexecPrepared for "insert into T values ( 1 , $1 )"
188+
[NO_PID]: sqlca: code: 0, state: 00000
189+
[NO_PID]: free_params on line 24: parameter 1 = 1
190+
[NO_PID]: sqlca: code: 0, state: 00000
191+
[NO_PID]: ecpg_execute on line 24: OK: INSERT 0 1
192+
[NO_PID]: sqlca: code: 0, state: 00000
193+
[NO_PID]: ecpg_auto_prepare on line 26: statement found in cache; entry 1640
194+
[NO_PID]: sqlca: code: 0, state: 00000
195+
[NO_PID]: ecpg_execute on line 26: query: insert into T values ( 1 , $1 ); with 1 parameter(s) on connection regress1
196+
[NO_PID]: sqlca: code: 0, state: 00000
197+
[NO_PID]: ecpg_execute on line 26: using PQexecPrepared for "insert into T values ( 1 , $1 )"
198+
[NO_PID]: sqlca: code: 0, state: 00000
199+
[NO_PID]: free_params on line 26: parameter 1 = 2
200+
[NO_PID]: sqlca: code: 0, state: 00000
201+
[NO_PID]: ecpg_execute on line 26: OK: INSERT 0 1
202+
[NO_PID]: sqlca: code: 0, state: 00000
203+
[NO_PID]: ECPGprepare on line 27: name i; query: " insert into T values ( 1 , 2 ) "
204+
[NO_PID]: sqlca: code: 0, state: 00000
205+
[NO_PID]: ecpg_execute on line 28: query: insert into T values ( 1 , 2 ) ; with 0 parameter(s) on connection regress1
206+
[NO_PID]: sqlca: code: 0, state: 00000
207+
[NO_PID]: ecpg_execute on line 28: using PQexecPrepared for " insert into T values ( 1 , 2 ) "
208+
[NO_PID]: sqlca: code: 0, state: 00000
209+
[NO_PID]: ecpg_execute on line 28: OK: INSERT 0 1
210+
[NO_PID]: sqlca: code: 0, state: 00000
211+
[NO_PID]: ecpg_auto_prepare on line 30: statement found in cache; entry 13056
212+
[NO_PID]: sqlca: code: 0, state: 00000
213+
[NO_PID]: ECPGprepare on line 30: name ecpg3; query: "select Item2 from T order by Item2 nulls last"
214+
[NO_PID]: sqlca: code: 0, state: 00000
215+
[NO_PID]: ecpg_execute on line 30: query: select Item2 from T order by Item2 nulls last; with 0 parameter(s) on connection regress1
216+
[NO_PID]: sqlca: code: 0, state: 00000
217+
[NO_PID]: ecpg_execute on line 30: using PQexecPrepared for "select Item2 from T order by Item2 nulls last"
218+
[NO_PID]: sqlca: code: 0, state: 00000
219+
[NO_PID]: ecpg_execute on line 30: correctly got 4 tuples with 1 fields
220+
[NO_PID]: sqlca: code: 0, state: 00000
221+
[NO_PID]: ecpg_get_data on line 30: RESULT: 1 offset: -1; array: yes
222+
[NO_PID]: sqlca: code: 0, state: 00000
223+
[NO_PID]: ecpg_get_data on line 30: RESULT: 2 offset: -1; array: yes
224+
[NO_PID]: sqlca: code: 0, state: 00000
225+
[NO_PID]: ecpg_get_data on line 30: RESULT: 2 offset: -1; array: yes
226+
[NO_PID]: sqlca: code: 0, state: 00000
227+
[NO_PID]: ecpg_get_data on line 30: RESULT: offset: -1; array: yes
228+
[NO_PID]: sqlca: code: 0, state: 00000
229+
[NO_PID]: ecpg_execute on line 37: query: declare C cursor for select Item1 from T; with 0 parameter(s) on connection regress1
230+
[NO_PID]: sqlca: code: 0, state: 00000
231+
[NO_PID]: ecpg_execute on line 37: using PQexec
232+
[NO_PID]: sqlca: code: 0, state: 00000
233+
[NO_PID]: ecpg_execute on line 37: OK: DECLARE CURSOR
234+
[NO_PID]: sqlca: code: 0, state: 00000
235+
[NO_PID]: ecpg_execute on line 39: query: fetch 1 in C; with 0 parameter(s) on connection regress1
236+
[NO_PID]: sqlca: code: 0, state: 00000
237+
[NO_PID]: ecpg_execute on line 39: using PQexec
238+
[NO_PID]: sqlca: code: 0, state: 00000
239+
[NO_PID]: ecpg_execute on line 39: correctly got 1 tuples with 1 fields
240+
[NO_PID]: sqlca: code: 0, state: 00000
241+
[NO_PID]: ecpg_get_data on line 39: RESULT: 1 offset: -1; array: yes
242+
[NO_PID]: sqlca: code: 0, state: 00000
243+
[NO_PID]: ecpg_execute on line 42: query: close C; with 0 parameter(s) on connection regress1
244+
[NO_PID]: sqlca: code: 0, state: 00000
245+
[NO_PID]: ecpg_execute on line 42: using PQexec
246+
[NO_PID]: sqlca: code: 0, state: 00000
247+
[NO_PID]: ecpg_execute on line 42: OK: CLOSE CURSOR
248+
[NO_PID]: sqlca: code: 0, state: 00000
249+
[NO_PID]: ECPGprepare on line 44: name stmt1; query: "SELECT item2 FROM T ORDER BY item2 NULLS LAST"
250+
[NO_PID]: sqlca: code: 0, state: 00000
251+
[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
252+
[NO_PID]: sqlca: code: 0, state: 00000
253+
[NO_PID]: ecpg_execute on line 48: using PQexec
254+
[NO_PID]: sqlca: code: 0, state: 00000
255+
[NO_PID]: ecpg_execute on line 48: OK: DECLARE CURSOR
256+
[NO_PID]: sqlca: code: 0, state: 00000
257+
[NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
258+
[NO_PID]: sqlca: code: 0, state: 00000
259+
[NO_PID]: ecpg_execute on line 55: using PQexec
260+
[NO_PID]: sqlca: code: 0, state: 00000
261+
[NO_PID]: ecpg_execute on line 55: correctly got 1 tuples with 1 fields
262+
[NO_PID]: sqlca: code: 0, state: 00000
263+
[NO_PID]: ecpg_get_data on line 55: RESULT: 1 offset: -1; array: yes
264+
[NO_PID]: sqlca: code: 0, state: 00000
265+
[NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
266+
[NO_PID]: sqlca: code: 0, state: 00000
267+
[NO_PID]: ecpg_execute on line 55: using PQexec
268+
[NO_PID]: sqlca: code: 0, state: 00000
269+
[NO_PID]: ecpg_execute on line 55: correctly got 1 tuples with 1 fields
270+
[NO_PID]: sqlca: code: 0, state: 00000
271+
[NO_PID]: ecpg_get_data on line 55: RESULT: 2 offset: -1; array: yes
272+
[NO_PID]: sqlca: code: 0, state: 00000
273+
[NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
274+
[NO_PID]: sqlca: code: 0, state: 00000
275+
[NO_PID]: ecpg_execute on line 55: using PQexec
276+
[NO_PID]: sqlca: code: 0, state: 00000
277+
[NO_PID]: ecpg_execute on line 55: correctly got 1 tuples with 1 fields
278+
[NO_PID]: sqlca: code: 0, state: 00000
279+
[NO_PID]: ecpg_get_data on line 55: RESULT: 2 offset: -1; array: yes
280+
[NO_PID]: sqlca: code: 0, state: 00000
281+
[NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
282+
[NO_PID]: sqlca: code: 0, state: 00000
283+
[NO_PID]: ecpg_execute on line 55: using PQexec
284+
[NO_PID]: sqlca: code: 0, state: 00000
285+
[NO_PID]: ecpg_execute on line 55: correctly got 1 tuples with 1 fields
286+
[NO_PID]: sqlca: code: 0, state: 00000
287+
[NO_PID]: ecpg_get_data on line 55: RESULT: offset: -1; array: yes
288+
[NO_PID]: sqlca: code: 0, state: 00000
289+
[NO_PID]: ecpg_execute on line 55: query: fetch cur1; with 0 parameter(s) on connection regress1
290+
[NO_PID]: sqlca: code: 0, state: 00000
291+
[NO_PID]: ecpg_execute on line 55: using PQexec
292+
[NO_PID]: sqlca: code: 0, state: 00000
293+
[NO_PID]: ecpg_execute on line 55: correctly got 0 tuples with 1 fields
294+
[NO_PID]: sqlca: code: 0, state: 00000
295+
[NO_PID]: raising sqlcode 100 on line 55: no data found on line 55
296+
[NO_PID]: sqlca: code: 100, state: 02000
297+
[NO_PID]: ecpg_execute on line 60: query: close cur1; with 0 parameter(s) on connection regress1
298+
[NO_PID]: sqlca: code: 0, state: 00000
299+
[NO_PID]: ecpg_execute on line 60: using PQexec
300+
[NO_PID]: sqlca: code: 0, state: 00000
301+
[NO_PID]: ecpg_execute on line 60: OK: CLOSE CURSOR
302+
[NO_PID]: sqlca: code: 0, state: 00000
303+
[NO_PID]: ecpg_execute on line 62: query: drop table T; with 0 parameter(s) on connection regress1
304+
[NO_PID]: sqlca: code: 0, state: 00000
305+
[NO_PID]: ecpg_execute on line 62: using PQexec
306+
[NO_PID]: sqlca: code: 0, state: 00000
307+
[NO_PID]: ecpg_execute on line 62: OK: DROP TABLE
308+
[NO_PID]: sqlca: code: 0, state: 00000
309+
[NO_PID]: ECPGdeallocate on line 0: name stmt1
310+
[NO_PID]: sqlca: code: 0, state: 00000
311+
[NO_PID]: ECPGdeallocate on line 0: name ecpg3
312+
[NO_PID]: sqlca: code: 0, state: 00000
313+
[NO_PID]: ECPGdeallocate on line 0: name i
314+
[NO_PID]: sqlca: code: 0, state: 00000
315+
[NO_PID]: ECPGdeallocate on line 0: name ecpg2
316+
[NO_PID]: sqlca: code: 0, state: 00000
317+
[NO_PID]: ECPGdeallocate on line 0: name ecpg1
318+
[NO_PID]: sqlca: code: 0, state: 00000
319+
[NO_PID]: ecpg_finish: connection regress1 closed
320+
[NO_PID]: sqlca: code: 0, state: 00000

src/interfaces/ecpg/test/expected/preproc-autoprep.stdout

+9
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,12 @@ item[0] = 1
77
item[1] = 2
88
item[2] = 2
99
item[3] = -1
10+
item[0] = 1
11+
item[1] = 2
12+
item[2] = 2
13+
item[3] = -1
14+
i = 1
15+
item[0] = 1
16+
item[1] = 2
17+
item[2] = 2
18+
item[3] = -1

src/interfaces/ecpg/test/preproc/autoprep.pgc

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/* test automatic prepare for all statements */
66
EXEC SQL INCLUDE ../regression;
77

8-
int main() {
8+
static void test(void) {
99
EXEC SQL BEGIN DECLARE SECTION;
1010
int item[4], ind[4], i = 1;
1111
int item1, ind1;
@@ -62,6 +62,11 @@ int main() {
6262
EXEC SQL DROP TABLE T;
6363

6464
EXEC SQL DISCONNECT ALL;
65+
}
66+
67+
int main() {
68+
test();
69+
test(); /* retry */
6570

6671
return 0;
6772
}

0 commit comments

Comments
 (0)