Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd49b20f

Browse files
author
Michael Meskes
committed
Applied patch by ITAGAKI Takahiro <itagaki.takahiro@oss.ntt.co.jp> to get prepare thread-safe.
1 parent689df1b commitd49b20f

20 files changed

+512
-120
lines changed

‎src/interfaces/ecpg/ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,5 +2237,10 @@ Wed, 29 Aug 2007 15:41:58 +0200
22372237
Tue, 04 Sep 2007 11:13:55 +0200
22382238

22392239
- Synced parser and keyword list.
2240+
2241+
Mi 26. Sep 12:45:51 CEST 2007
2242+
2243+
- Applied patch by ITAGAKI Takahiro <itagaki.takahiro@oss.ntt.co.jp>
2244+
to get prepare thread-safe.
22402245
- Set ecpg library version to 6.0.
22412246
- Set ecpg version to 4.4.

‎src/interfaces/ecpg/ecpglib/connect.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.42 2007/08/14 10:01:52 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.43 2007/09/26 10:57:00 meskes Exp $ */
22

33
#definePOSTGRES_ECPG_INTERNAL
44
#include"postgres_fe.h"
@@ -460,6 +460,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
460460
this->name=ECPGstrdup(realname,lineno);
461461

462462
this->cache_head=NULL;
463+
this->prep_stmts=NULL;
463464

464465
if (all_connections==NULL)
465466
this->next=NULL;

‎src/interfaces/ecpg/ecpglib/execute.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.69 2007/09/21 10:59:27 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.70 2007/09/26 10:57:00 meskes Exp $ */
22

33
/*
44
* The aim is to get a simpler inteface to the database routines.
@@ -1515,7 +1515,7 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char
15151515
if (statement_type==ECPGst_execute)
15161516
{
15171517
/* if we have an EXECUTE command, only the name is send */
1518-
char*command=ECPGprepared(stmt->command,lineno);
1518+
char*command=ECPGprepared(stmt->command,con,lineno);
15191519

15201520
if (command)
15211521
{

‎src/interfaces/ecpg/ecpglib/extern.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.26 2007/08/14 10:54:57 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.27 2007/09/26 10:57:00 meskes Exp $ */
22

33
#ifndef_ECPG_LIB_EXTERN_H
44
#define_ECPG_LIB_EXTERN_H
@@ -91,6 +91,7 @@ struct connection
9191
boolcommitted;
9292
intautocommit;
9393
structECPGtype_information_cache*cache_head;
94+
structprepared_statement*prep_stmts;
9495
structconnection*next;
9596
};
9697

@@ -144,7 +145,7 @@ boolECPGstore_input(const int, const bool, const struct variable *, const char
144145
boolECPGcheck_PQresult(PGresult*,int,PGconn*,enumCOMPAT_MODE);
145146
voidECPGraise(intline,intcode,constchar*sqlstate,constchar*str);
146147
voidECPGraise_backend(intline,PGresult*result,PGconn*conn,intcompat);
147-
char*ECPGprepared(constchar*,int);
148+
char*ECPGprepared(constchar*,structconnection*,int);
148149

149150
/* SQLSTATE values generated or processed by ecpglib (intentionally
150151
* not exported -- users should refer to the codes directly) */

‎src/interfaces/ecpg/ecpglib/prepare.c

Lines changed: 109 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.19 2007/08/14 10:01:52 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.20 2007/09/26 10:57:00 meskes Exp $ */
22

33
#definePOSTGRES_ECPG_INTERNAL
44
#include"postgres_fe.h"
@@ -11,13 +11,13 @@
1111
#include"extern.h"
1212
#include"sqlca.h"
1313

14-
staticstructprepared_statement
14+
structprepared_statement
1515
{
16-
char*name;
17-
boolprepared;
18-
structstatement*stmt;
19-
structprepared_statement*next;
20-
}*prep_stmts=NULL;
16+
char*name;
17+
boolprepared;
18+
structstatement*stmt;
19+
structprepared_statement*next;
20+
};
2121

2222
#defineSTMTID_SIZE 32
2323

@@ -35,6 +35,11 @@ static int stmtCacheNBuckets = 2039; /* # buckets - a pri
3535
staticintstmtCacheEntPerBucket=8;/* # entries/bucket */
3636
staticstmtCacheEntrystmtCacheEntries[16384]= {{0,{0},0,0,0}};
3737

38+
staticstructprepared_statement*find_prepared_statement(constchar*name,
39+
structconnection*con,structprepared_statement**prev);
40+
staticbooldeallocate_one(intlineno,enumCOMPAT_MODEc,structconnection*con,
41+
structprepared_statement*prev,structprepared_statement*this);
42+
3843
staticbool
3944
isvarchar(unsignedcharc)
4045
{
@@ -105,23 +110,23 @@ replace_variables(char **text, int lineno, bool questionmarks)
105110
bool
106111
ECPGprepare(intlineno,constchar*connection_name,constintquestionmarks,constchar*name,constchar*variable)
107112
{
108-
structstatement*stmt;
109-
structprepared_statement*this;
113+
structconnection*con;
114+
structstatement*stmt;
115+
structprepared_statement*this,
116+
*prev;
110117
structsqlca_t*sqlca=ECPGget_sqlca();
111118
PGresult*query;
112119

113120
ECPGinit_sqlca(sqlca);
114121

115-
/* check if we already have prepared this statement */
116-
for (this=prep_stmts;this!=NULL&&strcmp(this->name,name)!=0;this=this->next);
117-
if (this)
118-
{
119-
boolb=ECPGdeallocate(lineno,ECPG_COMPAT_PGSQL,name);
122+
con=ECPGget_connection(connection_name);
120123

121-
if (!b)
122-
return false;
123-
}
124+
/* check if we already have prepared this statement */
125+
this=find_prepared_statement(name,con,&prev);
126+
if (this&& !deallocate_one(lineno,ECPG_COMPAT_PGSQL,con,prev,this))
127+
return false;
124128

129+
/* allocate new statement */
125130
this= (structprepared_statement*)ECPGalloc(sizeof(structprepared_statement),lineno);
126131
if (!this)
127132
return false;
@@ -135,7 +140,7 @@ ECPGprepare(int lineno, const char *connection_name, const int questionmarks, co
135140

136141
/* create statement */
137142
stmt->lineno=lineno;
138-
stmt->connection=ECPGget_connection(connection_name);
143+
stmt->connection=con;
139144
stmt->command=ECPGstrdup(variable,lineno);
140145
stmt->inlist=stmt->outlist=NULL;
141146

@@ -160,113 +165,133 @@ ECPGprepare(int lineno, const char *connection_name, const int questionmarks, co
160165
PQclear(query);
161166
this->prepared= true;
162167

163-
if (prep_stmts==NULL)
168+
if (con->prep_stmts==NULL)
164169
this->next=NULL;
165170
else
166-
this->next=prep_stmts;
171+
this->next=con->prep_stmts;
167172

168-
prep_stmts=this;
173+
con->prep_stmts=this;
169174
return true;
170175
}
171176

177+
staticstructprepared_statement*find_prepared_statement(constchar*name,
178+
structconnection*con,structprepared_statement**prev_)
179+
{
180+
structprepared_statement*this,
181+
*prev;
182+
183+
for (this=con->prep_stmts,prev=NULL;this!=NULL;prev=this,this=this->next)
184+
{
185+
if (strcmp(this->name,name)==0)
186+
{
187+
if (prev_)
188+
*prev_=prev;
189+
returnthis;
190+
}
191+
}
192+
returnNULL;
193+
}
194+
172195
staticbool
173-
deallocate_one(intlineno,constchar*name)
196+
deallocate_one(intlineno,enumCOMPAT_MODEc,structconnection*con,structprepared_statement*prev,structprepared_statement*this)
174197
{
175-
structprepared_statement*this,
176-
*prev;
198+
boolr= false;
177199

178-
/* check if we really have prepared this statement */
179-
for (this=prep_stmts,prev=NULL;this!=NULL&&strcmp(this->name,name)!=0;prev=this,this=this->next);
180-
if (this)
200+
ECPGlog("ECPGdeallocate line %d: NAME: %s\n",lineno,this->name);
201+
202+
/* first deallocate the statement in the backend */
203+
if (this->prepared)
181204
{
182-
/* first deallocate the statement in the backend */
183-
if (this->prepared)
205+
char*text;
206+
PGresult*query;
207+
208+
text= (char*)ECPGalloc(strlen("deallocate \"\" ")+strlen(this->name),this->stmt->lineno);
209+
if (text)
184210
{
185-
char*text;
186-
PGresult*query;
187-
188-
if (!(text= (char*)ECPGalloc(strlen("deallocate \"\" ")+strlen(this->name),this->stmt->lineno)))
189-
return false;
190-
else
211+
sprintf(text,"deallocate \"%s\"",this->name);
212+
query=PQexec(this->stmt->connection->connection,text);
213+
ECPGfree(text);
214+
if (ECPGcheck_PQresult(query,lineno,this->stmt->connection->connection,this->stmt->compat))
191215
{
192-
sprintf(text,"deallocate \"%s\"",this->name);
193-
query=PQexec(this->stmt->connection->connection,text);
194-
ECPGfree(text);
195-
if (!ECPGcheck_PQresult(query,lineno,this->stmt->connection->connection,this->stmt->compat))
196-
return false;
197216
PQclear(query);
217+
r= true;
198218
}
199219
}
200-
201-
/* okay, free all the resources */
202-
ECPGfree(this->stmt->command);
203-
ECPGfree(this->stmt);
204-
if (prev!=NULL)
205-
prev->next=this->next;
206-
else
207-
prep_stmts=this->next;
220+
}
208221

209-
ECPGfree(this);
210-
return true;
222+
/*
223+
* Just ignore all errors since we do not know the list of cursors we
224+
* are allowed to free. We have to trust the software.
225+
*/
226+
if (!r&& !INFORMIX_MODE(c))
227+
{
228+
ECPGraise(lineno,ECPG_INVALID_STMT,ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME,this->name);
229+
return false;
211230
}
212-
return false;
231+
232+
/* okay, free all the resources */
233+
ECPGfree(this->stmt->command);
234+
ECPGfree(this->stmt);
235+
if (prev!=NULL)
236+
prev->next=this->next;
237+
else
238+
con->prep_stmts=this->next;
239+
240+
ECPGfree(this);
241+
return true;
213242
}
214243

215244
/* handle the EXEC SQL DEALLOCATE PREPARE statement */
216245
bool
217-
ECPGdeallocate(intlineno,intc,constchar*name)
246+
ECPGdeallocate(intlineno,intc,constchar*connection_name,constchar*name)
218247
{
219-
boolret=deallocate_one(lineno,name);
220-
enumCOMPAT_MODEcompat=c;
248+
structconnection*con;
249+
structprepared_statement*this,
250+
*prev;
221251

222-
ECPGlog("ECPGdeallocate line %d: NAME: %s\n",lineno,name);
223-
if (INFORMIX_MODE(compat))
224-
{
225-
/*
226-
* Just ignore all errors since we do not know the list of cursors we
227-
* are allowed to free. We have to trust the software.
228-
*/
229-
return true;
230-
}
252+
con=ECPGget_connection(connection_name);
231253

232-
if (!ret)
233-
ECPGraise(lineno,ECPG_INVALID_STMT,ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME,name);
254+
this=find_prepared_statement(name,con,&prev);
255+
if (this)
256+
returndeallocate_one(lineno,c,con,prev,this);
234257

235-
returnret;
258+
/* prepared statement is not found */
259+
if (INFORMIX_MODE(c))
260+
return true;
261+
ECPGraise(lineno,ECPG_INVALID_STMT,ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME,name);
262+
return false;
236263
}
237264

238265
bool
239-
ECPGdeallocate_all(intlineno,intcompat)
266+
ECPGdeallocate_all(intlineno,intcompat,constchar*connection_name)
240267
{
268+
structconnection*con;
269+
270+
con=ECPGget_connection(connection_name);
271+
241272
/* deallocate all prepared statements */
242-
while (prep_stmts!=NULL)
273+
while (con->prep_stmts)
243274
{
244-
boolb=ECPGdeallocate(lineno,compat,prep_stmts->name);
245-
246-
if (!b)
275+
if (!deallocate_one(lineno,compat,con,NULL,con->prep_stmts))
247276
return false;
248277
}
249278

250279
return true;
251280
}
252281

253282
char*
254-
ECPGprepared(constchar*name,intlineno)
283+
ECPGprepared(constchar*name,structconnection*con,intlineno)
255284
{
256-
structprepared_statement*this;
257-
258-
for (this=prep_stmts;this!=NULL&& ((strcmp(this->name,name)!=0)||this->prepared== false);this=this->next);
259-
return (this) ?this->stmt->command :NULL;
285+
structprepared_statement*this;
286+
this=find_prepared_statement(name,con,NULL);
287+
returnthis ?this->stmt->command :NULL;
260288
}
261289

262290
/* return the prepared statement */
263291
char*
264-
ECPGprepared_statement(constchar*name,intlineno)
292+
ECPGprepared_statement(constchar*connection_name,constchar*name,intlineno)
265293
{
266-
structprepared_statement*this;
267-
268-
for (this=prep_stmts;this!=NULL&&strcmp(this->name,name)!=0;this=this->next);
269-
return (this) ?this->stmt->command :NULL;
294+
returnECPGprepared(name,ECPGget_connection(connection_name),lineno);
270295
}
271296

272297
/*
@@ -426,14 +451,14 @@ ECPGauto_prepare(int lineno, const char *connection_name, const int questionmark
426451
entNo=SearchStmtCache(query);
427452

428453
/* if not found - add the statement to the cache */
429-
if(entNo)
454+
if(entNo)
430455
{
431-
ECPGlog("ECPGauto_prepare line %d: stmt found in cache, entry %d\n",lineno,entNo);
456+
ECPGlog("ECPGauto_prepare line %d: stmt found in cache, entry %d\n",lineno,entNo);
432457
*name=ECPGstrdup(stmtCacheEntries[entNo].stmtID,lineno);
433458
}
434459
else
435460
{
436-
ECPGlog("ECPGauto_prepare line %d: stmt not in cache; inserting\n",lineno);
461+
ECPGlog("ECPGauto_prepare line %d: stmt not in cache; inserting\n",lineno);
437462

438463
/* generate a statement ID */
439464
*name= (char*)ECPGalloc(STMTID_SIZE,lineno);
@@ -450,4 +475,3 @@ ECPGauto_prepare(int lineno, const char *connection_name, const int questionmark
450475

451476
return(true);
452477
}
453-

‎src/interfaces/ecpg/include/ecpglib.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* this is a small part of c.h since we don't want to leak all postgres
33
* definitions into ecpg programs
4-
* $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpglib.h,v 1.71 2007/08/14 10:01:52 meskes Exp $
4+
* $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpglib.h,v 1.72 2007/09/26 10:57:00 meskes Exp $
55
*/
66

77
#ifndef_ECPGLIB_H
@@ -49,9 +49,9 @@ boolECPGtrans(int, const char *, const char *);
4949
boolECPGdisconnect(int,constchar*);
5050
boolECPGprepare(int,constchar*,constint,constchar*,constchar*);
5151
boolECPGauto_prepare(int,constchar*,constint,char**,constchar*);
52-
boolECPGdeallocate(int,int,constchar*);
53-
boolECPGdeallocate_all(int,int);
54-
char*ECPGprepared_statement(constchar*,int);
52+
boolECPGdeallocate(int,int,constchar*connection_name,constchar*name);
53+
boolECPGdeallocate_all(int,int,constchar*connection_name);
54+
char*ECPGprepared_statement(constchar*connection_name,constchar*name,int);
5555

5656
voidECPGlog(constchar*format,...);
5757
char*ECPGerrmsg(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp