PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
prepare.c File Reference
#include "postgres_fe.h"
#include <ctype.h>
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
#include "extern.h"
#include "sqlca.h"
Include dependency graph for prepare.c:

Go to the source code of this file.

Data Structures

struct  stmtCacheEntry
 

Macros

#define POSTGRES_ECPG_INTERNAL
 
#define STMTID_SIZE   32
 

Functions

static bool deallocate_one (int lineno, enum COMPAT_MODE c, struct connection *con, struct prepared_statement *prev, struct prepared_statement *this)
 
static bool isvarchar (unsigned char c)
 
static bool replace_variables (char **text, int lineno)
 
static bool prepare_common (int lineno, struct connection *con, const char *name, const char *variable)
 
bool ECPGprepare (int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable)
 
struct prepared_statementecpg_find_prepared_statement (const char *name, struct connection *con, struct prepared_statement **prev_)
 
bool ECPGdeallocate (int lineno, int c, const char *connection_name, const char *name)
 
bool ecpg_deallocate_all_conn (int lineno, enum COMPAT_MODE c, struct connection *con)
 
bool ECPGdeallocate_all (int lineno, int compat, const char *connection_name)
 
char * ecpg_prepared (const char *name, struct connection *con)
 
char * ECPGprepared_statement (const char *connection_name, const char *name, int lineno)
 
static int HashStmt (const char *ecpgQuery)
 
static int SearchStmtCache (const char *ecpgQuery)
 
static int ecpg_freeStmtCacheEntry (int lineno, int compat, int entNo)
 
static int AddStmtToCache (int lineno, const char *stmtID, const char *connection, int compat, const char *ecpgQuery)
 
bool ecpg_auto_prepare (int lineno, const char *connection_name, const int compat, char **name, const char *query)
 

Variables

static int nextStmtID = 1
 
static const int stmtCacheNBuckets = 2039
 
static const int stmtCacheEntPerBucket = 8
 
static stmtCacheEntry stmtCacheEntries [16384] = {{0, {0}, 0, 0, 0}}
 

Macro Definition Documentation

#define POSTGRES_ECPG_INTERNAL

Definition at line 3 of file prepare.c.

#define STMTID_SIZE   32

Definition at line 14 of file prepare.c.

Referenced by ecpg_auto_prepare().

Function Documentation

static int AddStmtToCache ( int  lineno,
const char *  stmtID,
const char *  connection,
int  compat,
const char *  ecpgQuery 
)
static

Definition at line 418 of file prepare.c.

References stmtCacheEntry::connection, connection, ecpg_freeStmtCacheEntry(), ecpg_strdup(), stmtCacheEntry::ecpgQuery, stmtCacheEntry::execs, HashStmt(), stmtCacheEntry::lineno, stmtCacheEntPerBucket, and stmtCacheEntry::stmtID.

Referenced by ecpg_auto_prepare().

423 {
424  int ix,
425  initEntNo,
426  luEntNo,
427  entNo;
428  stmtCacheEntry *entry;
429 
430 /* hash the statement */
431  initEntNo = HashStmt(ecpgQuery);
432 
433 /* search for an unused entry */
434  entNo = initEntNo; /* start with the initial entry # for the
435  * bucket */
436  luEntNo = initEntNo; /* use it as the initial 'least used' entry */
437  for (ix = 0; ix < stmtCacheEntPerBucket; ++ix)
438  {
439  entry = &stmtCacheEntries[entNo];
440  if (!entry->stmtID[0]) /* unused entry - use it */
441  break;
442  if (entry->execs < stmtCacheEntries[luEntNo].execs)
443  luEntNo = entNo; /* save new 'least used' entry */
444  ++entNo; /* increment entry # */
445  }
446 
447 /* if no unused entries were found - use the 'least used' entry found in the bucket */
448  if (ix >= stmtCacheEntPerBucket) /* if no unused entries were found */
449  entNo = luEntNo; /* re-use the 'least used' entry */
450 
451 /* 'entNo' is the entry to use - make sure its free */
452  if (ecpg_freeStmtCacheEntry(lineno, compat, entNo) < 0)
453  return -1;
454 
455 /* add the query to the entry */
456  entry = &stmtCacheEntries[entNo];
457  entry->lineno = lineno;
458  entry->ecpgQuery = ecpg_strdup(ecpgQuery, lineno);
459  entry->connection = connection;
460  entry->execs = 0;
461  memcpy(entry->stmtID, stmtID, sizeof(entry->stmtID));
462 
463  return entNo;
464 }
char * ecpgQuery
Definition: prepare.c:20
const char * connection
Definition: prepare.c:22
long execs
Definition: prepare.c:21
char stmtID[STMTID_SIZE]
Definition: prepare.c:19
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
static const int stmtCacheEntPerBucket
Definition: prepare.c:27
char * connection
enum COMPAT_MODE compat
Definition: ecpg.c:25
static stmtCacheEntry stmtCacheEntries[16384]
Definition: prepare.c:28
static int HashStmt(const char *ecpgQuery)
Definition: prepare.c:316
static int ecpg_freeStmtCacheEntry(int lineno, int compat, int entNo)
Definition: prepare.c:383
static bool deallocate_one ( int  lineno,
enum COMPAT_MODE  c,
struct connection con,
struct prepared_statement prev,
struct prepared_statement this 
)
static

Definition at line 201 of file prepare.c.

References statement::command, statement::connection, connection::connection, ecpg_alloc(), ecpg_check_PQresult(), ecpg_free(), ECPG_INVALID_STMT, ecpg_log(), ecpg_raise(), ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, INFORMIX_MODE, statement::lineno, name, prepared_statement::next, next, PQclear(), PQexec(), connection::prep_stmts, prepared_statement::prepared, and prepared_statement::stmt.

Referenced by ecpg_deallocate_all_conn(), ecpg_freeStmtCacheEntry(), ECPGdeallocate(), and ECPGprepare().

202 {
203  bool r = false;
204 
205  ecpg_log("deallocate_one on line %d: name %s\n", lineno, this->name);
206 
207  /* first deallocate the statement in the backend */
208  if (this->prepared)
209  {
210  char *text;
211  PGresult *query;
212 
213  text = (char *) ecpg_alloc(strlen("deallocate \"\" ") + strlen(this->name), this->stmt->lineno);
214 
215  if (text)
216  {
217  sprintf(text, "deallocate \"%s\"", this->name);
218  query = PQexec(this->stmt->connection->connection, text);
219  ecpg_free(text);
220  if (ecpg_check_PQresult(query, lineno, this->stmt->connection->connection, this->stmt->compat))
221  {
222  PQclear(query);
223  r = true;
224  }
225  }
226  }
227 
228  /*
229  * Just ignore all errors since we do not know the list of cursors we are
230  * allowed to free. We have to trust the software.
231  */
232  if (!r && !INFORMIX_MODE(c))
233  {
235  return false;
236  }
237 
238  /* okay, free all the resources */
239  ecpg_free(this->stmt->command);
240  ecpg_free(this->stmt);
241  ecpg_free(this->name);
242  if (prev != NULL)
243  prev->next = this->next;
244  else
245  con->prep_stmts = this->next;
246 
247  ecpg_free(this);
248  return true;
249 }
static int32 next
Definition: blutils.c:210
void ecpg_free(void *)
Definition: memory.c:13
#define INFORMIX_MODE(X)
Definition: extern.h:23
#define ECPG_INVALID_STMT
Definition: ecpgerrno.h:39
void ecpg_log(const char *format,...) pg_attribute_printf(1
enum COMPAT_MODE compat
Definition: extern.h:57
char * c
struct statement * stmt
Definition: extern.h:74
char * ecpg_alloc(long, int)
Definition: memory.c:19
struct varlena text
Definition: c.h:447
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
struct prepared_statement * next
Definition: extern.h:75
void PQclear(PGresult *res)
Definition: fe-exec.c:671
#define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME
Definition: extern.h:212
bool ecpg_check_PQresult(PGresult *results, int lineno, PGconn *connection, enum COMPAT_MODE compat)
Definition: error.c:283
const char * name
Definition: encode.c:521
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
struct prepared_statement * prep_stmts
Definition: extern.h:85
bool ecpg_auto_prepare ( int  lineno,
const char *  connection_name,
const int  compat,
char **  name,
const char *  query 
)

Definition at line 468 of file prepare.c.

References AddStmtToCache(), ecpg_find_prepared_statement(), ecpg_get_connection(), ecpg_log(), ecpg_strdup(), ECPGprepare(), stmtCacheEntry::execs, nextStmtID, prepare_common(), SearchStmtCache(), stmtCacheEntry::stmtID, and STMTID_SIZE.

Referenced by ecpg_do_prologue().

469 {
470  int entNo;
471 
472  /* search the statement cache for this statement */
473  entNo = SearchStmtCache(query);
474 
475  /* if not found - add the statement to the cache */
476  if (entNo)
477  {
478  char *stmtID;
479  struct connection *con;
480  struct prepared_statement *prep;
481 
482  ecpg_log("ecpg_auto_prepare on line %d: statement found in cache; entry %d\n", lineno, entNo);
483 
484  stmtID = stmtCacheEntries[entNo].stmtID;
485 
486  con = ecpg_get_connection(connection_name);
487  prep = ecpg_find_prepared_statement(stmtID, con, NULL);
488  /* This prepared name doesn't exist on this connection. */
489  if (!prep && !prepare_common(lineno, con, stmtID, query))
490  return false;
491 
492  *name = ecpg_strdup(stmtID, lineno);
493  }
494  else
495  {
496  char stmtID[STMTID_SIZE];
497 
498  ecpg_log("ecpg_auto_prepare on line %d: statement not in cache; inserting\n", lineno);
499 
500  /* generate a statement ID */
501  sprintf(stmtID, "ecpg%d", nextStmtID++);
502 
503  if (!ECPGprepare(lineno, connection_name, 0, stmtID, query))
504  return false;
505  if (AddStmtToCache(lineno, stmtID, connection_name, compat, query) < 0)
506  return false;
507 
508  *name = ecpg_strdup(stmtID, lineno);
509  }
510 
511  /* increase usage counter */
512  stmtCacheEntries[entNo].execs++;
513 
514  return true;
515 }
static int SearchStmtCache(const char *ecpgQuery)
Definition: prepare.c:351
Definition: type.h:102
bool ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable)
Definition: prepare.c:161
long execs
Definition: prepare.c:21
char stmtID[STMTID_SIZE]
Definition: prepare.c:19
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
static int AddStmtToCache(int lineno, const char *stmtID, const char *connection, int compat, const char *ecpgQuery)
Definition: prepare.c:418
void ecpg_log(const char *format,...) pg_attribute_printf(1
enum COMPAT_MODE compat
Definition: ecpg.c:25
static bool prepare_common(int lineno, struct connection *con, const char *name, const char *variable)
Definition: prepare.c:103
static int nextStmtID
Definition: prepare.c:25
static stmtCacheEntry stmtCacheEntries[16384]
Definition: prepare.c:28
struct prepared_statement * ecpg_find_prepared_statement(const char *name, struct connection *con, struct prepared_statement **prev_)
Definition: prepare.c:182
const char * name
Definition: encode.c:521
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
#define STMTID_SIZE
Definition: prepare.c:14
bool ecpg_deallocate_all_conn ( int  lineno,
enum COMPAT_MODE  c,
struct connection con 
)

Definition at line 276 of file prepare.c.

References deallocate_one(), and connection::prep_stmts.

Referenced by ecpg_finish(), and ECPGdeallocate_all().

277 {
278  /* deallocate all prepared statements */
279  while (con->prep_stmts)
280  {
281  if (!deallocate_one(lineno, c, con, NULL, con->prep_stmts))
282  return false;
283  }
284 
285  return true;
286 }
static bool deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con, struct prepared_statement *prev, struct prepared_statement *this)
Definition: prepare.c:201
char * c
struct prepared_statement * prep_stmts
Definition: extern.h:85
struct prepared_statement* ecpg_find_prepared_statement ( const char *  name,
struct connection con,
struct prepared_statement **  prev_ 
)

Definition at line 182 of file prepare.c.

References prepared_statement::next, and connection::prep_stmts.

Referenced by ecpg_auto_prepare(), ecpg_freeStmtCacheEntry(), ecpg_prepared(), ECPGdeallocate(), ECPGdescribe(), and ECPGprepare().

184 {
185  struct prepared_statement *this,
186  *prev;
187 
188  for (this = con->prep_stmts, prev = NULL; this != NULL; prev = this, this = this->next)
189  {
190  if (strcmp(this->name, name) == 0)
191  {
192  if (prev_)
193  *prev_ = prev;
194  return this;
195  }
196  }
197  return NULL;
198 }
struct prepared_statement * next
Definition: extern.h:75
const char * name
Definition: encode.c:521
struct prepared_statement * prep_stmts
Definition: extern.h:85
static int ecpg_freeStmtCacheEntry ( int  lineno,
int  compat,
int  entNo 
)
static

Definition at line 383 of file prepare.c.

References stmtCacheEntry::connection, deallocate_one(), ecpg_find_prepared_statement(), ecpg_free(), ecpg_get_connection(), stmtCacheEntry::ecpgQuery, and stmtCacheEntry::stmtID.

Referenced by AddStmtToCache().

384 {
385  stmtCacheEntry *entry;
386  struct connection *con;
387  struct prepared_statement *this,
388  *prev;
389 
390  entry = &stmtCacheEntries[entNo];
391  if (!entry->stmtID[0]) /* return if the entry isn't in use */
392  return 0;
393 
394  con = ecpg_get_connection(entry->connection);
395 
396  /* free the 'prepared_statement' list entry */
397  this = ecpg_find_prepared_statement(entry->stmtID, con, &prev);
398  if (this && !deallocate_one(lineno, compat, con, prev, this))
399  return -1;
400 
401  entry->stmtID[0] = '\0';
402 
403  /* free the memory used by the cache entry */
404  if (entry->ecpgQuery)
405  {
406  ecpg_free(entry->ecpgQuery);
407  entry->ecpgQuery = 0;
408  }
409 
410  return entNo;
411 }
char * ecpgQuery
Definition: prepare.c:20
void ecpg_free(void *)
Definition: memory.c:13
const char * connection
Definition: prepare.c:22
char stmtID[STMTID_SIZE]
Definition: prepare.c:19
static bool deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con, struct prepared_statement *prev, struct prepared_statement *this)
Definition: prepare.c:201
enum COMPAT_MODE compat
Definition: ecpg.c:25
static stmtCacheEntry stmtCacheEntries[16384]
Definition: prepare.c:28
struct prepared_statement * ecpg_find_prepared_statement(const char *name, struct connection *con, struct prepared_statement **prev_)
Definition: prepare.c:182
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
char* ecpg_prepared ( const char *  name,
struct connection con 
)

Definition at line 295 of file prepare.c.

References statement::command, ecpg_find_prepared_statement(), and prepared_statement::stmt.

Referenced by ecpg_do_prologue(), and ECPGprepared_statement().

296 {
297  struct prepared_statement *this;
298 
299  this = ecpg_find_prepared_statement(name, con, NULL);
300  return this ? this->stmt->command : NULL;
301 }
struct statement * stmt
Definition: extern.h:74
char * command
Definition: extern.h:54
struct prepared_statement * ecpg_find_prepared_statement(const char *name, struct connection *con, struct prepared_statement **prev_)
Definition: prepare.c:182
const char * name
Definition: encode.c:521
bool ECPGdeallocate ( int  lineno,
int  c,
const char *  connection_name,
const char *  name 
)

Definition at line 253 of file prepare.c.

References deallocate_one(), ecpg_find_prepared_statement(), ecpg_get_connection(), ecpg_init(), ECPG_INVALID_STMT, ecpg_raise(), ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, and INFORMIX_MODE.

Referenced by main().

254 {
255  struct connection *con;
256  struct prepared_statement *this,
257  *prev;
258 
259  con = ecpg_get_connection(connection_name);
260 
261  if (!ecpg_init(con, connection_name, lineno))
262  return false;
263 
264  this = ecpg_find_prepared_statement(name, con, &prev);
265  if (this)
266  return deallocate_one(lineno, c, con, prev, this);
267 
268  /* prepared statement is not found */
269  if (INFORMIX_MODE(c))
270  return true;
272  return false;
273 }
bool ecpg_init(const struct connection *, const char *, const int)
Definition: misc.c:105
#define INFORMIX_MODE(X)
Definition: extern.h:23
#define ECPG_INVALID_STMT
Definition: ecpgerrno.h:39
static bool deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con, struct prepared_statement *prev, struct prepared_statement *this)
Definition: prepare.c:201
char * c
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
#define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME
Definition: extern.h:212
struct prepared_statement * ecpg_find_prepared_statement(const char *name, struct connection *con, struct prepared_statement **prev_)
Definition: prepare.c:182
const char * name
Definition: encode.c:521
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
bool ECPGdeallocate_all ( int  lineno,
int  compat,
const char *  connection_name 
)

Definition at line 289 of file prepare.c.

References ecpg_deallocate_all_conn(), and ecpg_get_connection().

Referenced by main().

290 {
291  return ecpg_deallocate_all_conn(lineno, compat, ecpg_get_connection(connection_name));
292 }
bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *con)
Definition: prepare.c:276
enum COMPAT_MODE compat
Definition: ecpg.c:25
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
bool ECPGprepare ( int  lineno,
const char *  connection_name,
const bool  questionmarks,
const char *  name,
const char *  variable 
)

Definition at line 161 of file prepare.c.

References deallocate_one(), ECPG_COMPAT_PGSQL, ecpg_find_prepared_statement(), ecpg_get_connection(), ecpg_init(), and prepare_common().

Referenced by ecpg_auto_prepare(), main(), and test().

162 {
163  struct connection *con;
164  struct prepared_statement *this,
165  *prev;
166 
167  (void) questionmarks; /* quiet the compiler */
168  con = ecpg_get_connection(connection_name);
169 
170  if (!ecpg_init(con, connection_name, lineno))
171  return false;
172 
173  /* check if we already have prepared this statement */
174  this = ecpg_find_prepared_statement(name, con, &prev);
175  if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this))
176  return false;
177 
178  return prepare_common(lineno, con, name, variable);
179 }
bool ecpg_init(const struct connection *, const char *, const int)
Definition: misc.c:105
static bool deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con, struct prepared_statement *prev, struct prepared_statement *this)
Definition: prepare.c:201
bool questionmarks
Definition: ecpg.c:19
static bool prepare_common(int lineno, struct connection *con, const char *name, const char *variable)
Definition: prepare.c:103
struct prepared_statement * ecpg_find_prepared_statement(const char *name, struct connection *con, struct prepared_statement **prev_)
Definition: prepare.c:182
const char * name
Definition: encode.c:521
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
char* ECPGprepared_statement ( const char *  connection_name,
const char *  name,
int  lineno 
)

Definition at line 306 of file prepare.c.

References ecpg_get_connection(), and ecpg_prepared().

Referenced by main(), and test().

307 {
308  (void) lineno; /* keep the compiler quiet */
309  return ecpg_prepared(name, ecpg_get_connection(connection_name));
310 }
char * ecpg_prepared(const char *name, struct connection *con)
Definition: prepare.c:295
const char * name
Definition: encode.c:521
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
static int HashStmt ( const char *  ecpgQuery)
static

Definition at line 316 of file prepare.c.

References stmtCacheEntPerBucket, and stmtCacheNBuckets.

Referenced by AddStmtToCache(), and SearchStmtCache().

317 {
318  int stmtIx,
319  bucketNo,
320  hashLeng,
321  stmtLeng;
322  long long hashVal,
323  rotVal;
324 
325  stmtLeng = strlen(ecpgQuery);
326  hashLeng = 50; /* use 1st 50 characters of statement */
327  if (hashLeng > stmtLeng) /* if the statement isn't that long */
328  hashLeng = stmtLeng; /* use its actual length */
329 
330  hashVal = 0;
331  for (stmtIx = 0; stmtIx < hashLeng; ++stmtIx)
332  {
333  hashVal = hashVal + (int) ecpgQuery[stmtIx];
334  hashVal = hashVal << 13;
335  rotVal = (hashVal & 0x1fff00000000LL) >> 32;
336  hashVal = (hashVal & 0xffffffffLL) | rotVal;
337  }
338 
339  bucketNo = hashVal % stmtCacheNBuckets;
340  bucketNo += 1; /* don't use bucket # 0 */
341 
342  return (bucketNo * stmtCacheEntPerBucket);
343 }
static const int stmtCacheEntPerBucket
Definition: prepare.c:27
static const int stmtCacheNBuckets
Definition: prepare.c:26
static bool isvarchar ( unsigned char  c)
static

Definition at line 34 of file prepare.c.

Referenced by replace_variables().

35 {
36  if (isalnum(c))
37  return true;
38 
39  if (c == '_' || c == '>' || c == '-' || c == '.')
40  return true;
41 
42  if (c >= 128)
43  return true;
44 
45  return false;
46 }
char * c
static bool prepare_common ( int  lineno,
struct connection con,
const char *  name,
const char *  variable 
)
static

Definition at line 103 of file prepare.c.

References statement::command, statement::compat, statement::connection, connection::connection, ecpg_alloc(), ecpg_check_PQresult(), ecpg_free(), ecpg_log(), ecpg_strdup(), statement::inlist, statement::lineno, next, statement::outlist, PQclear(), PQprepare(), connection::prep_stmts, and replace_variables().

Referenced by ecpg_auto_prepare(), and ECPGprepare().

104 {
105  struct statement *stmt;
106  struct prepared_statement *this;
107  PGresult *query;
108 
109  /* allocate new statement */
110  this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno);
111  if (!this)
112  return false;
113 
114  stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno);
115  if (!stmt)
116  {
117  ecpg_free(this);
118  return false;
119  }
120 
121  /* create statement */
122  stmt->lineno = lineno;
123  stmt->connection = con;
125  stmt->inlist = stmt->outlist = NULL;
126 
127  /* if we have C variables in our statement replace them with '?' */
128  replace_variables(&(stmt->command), lineno);
129 
130  /* add prepared statement to our list */
131  this->name = ecpg_strdup(name, lineno);
132  this->stmt = stmt;
133 
134  /* and finally really prepare the statement */
135  query = PQprepare(stmt->connection->connection, name, stmt->command, 0, NULL);
136  if (!ecpg_check_PQresult(query, stmt->lineno, stmt->connection->connection, stmt->compat))
137  {
138  ecpg_free(stmt->command);
139  ecpg_free(this->name);
140  ecpg_free(this);
141  ecpg_free(stmt);
142  return false;
143  }
144 
145  ecpg_log("prepare_common on line %d: name %s; query: \"%s\"\n", stmt->lineno, name, stmt->command);
146  PQclear(query);
147  this->prepared = true;
148 
149  if (con->prep_stmts == NULL)
150  this->next = NULL;
151  else
152  this->next = con->prep_stmts;
153 
154  con->prep_stmts = this;
155  return true;
156 }
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
Definition: fe-exec.c:1941
static int32 next
Definition: blutils.c:210
void ecpg_free(void *)
Definition: memory.c:13
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
void ecpg_log(const char *format,...) pg_attribute_printf(1
struct connection * connection
Definition: extern.h:56
enum COMPAT_MODE compat
Definition: extern.h:57
int lineno
Definition: extern.h:53
char * ecpg_alloc(long, int)
Definition: memory.c:19
char * command
Definition: extern.h:54
void PQclear(PGresult *res)
Definition: fe-exec.c:671
struct variable * inlist
Definition: extern.h:61
PGconn * connection
Definition: extern.h:82
bool ecpg_check_PQresult(PGresult *results, int lineno, PGconn *connection, enum COMPAT_MODE compat)
Definition: error.c:283
const char * name
Definition: encode.c:521
static bool replace_variables(char **text, int lineno)
Definition: prepare.c:49
struct variable * outlist
Definition: extern.h:62
struct prepared_statement * prep_stmts
Definition: extern.h:85
static bool replace_variables ( char **  text,
int  lineno 
)
static

Definition at line 49 of file prepare.c.

References buffer, ecpg_alloc(), ecpg_free(), isvarchar(), and snprintf().

Referenced by prepare_common().

50 {
51  bool string = false;
52  int counter = 1,
53  ptr = 0;
54 
55  for (; (*text)[ptr] != '\0'; ptr++)
56  {
57  if ((*text)[ptr] == '\'')
58  string = string ? false : true;
59 
60  if (string || (((*text)[ptr] != ':') && ((*text)[ptr] != '?')))
61  continue;
62 
63  if (((*text)[ptr] == ':') && ((*text)[ptr + 1] == ':'))
64  ptr += 2; /* skip '::' */
65  else
66  {
67  int len;
68  int buffersize = sizeof(int) * CHAR_BIT * 10 / 3; /* a rough guess of the
69  * size we need */
70  char *buffer,
71  *newcopy;
72 
73  if (!(buffer = (char *) ecpg_alloc(buffersize, lineno)))
74  return false;
75 
76  snprintf(buffer, buffersize, "$%d", counter++);
77 
78  for (len = 1; (*text)[ptr + len] && isvarchar((*text)[ptr + len]); len++);
79  if (!(newcopy = (char *) ecpg_alloc(strlen(*text) -len + strlen(buffer) + 1, lineno)))
80  {
81  ecpg_free(buffer);
82  return false;
83  }
84 
85  memcpy(newcopy, *text, ptr);
86  strcpy(newcopy + ptr, buffer);
87  strcat(newcopy, (*text) +ptr + len);
88 
89  ecpg_free(*text);
90  ecpg_free(buffer);
91 
92  *text = newcopy;
93 
94  if ((*text)[ptr] == '\0') /* we reached the end */
95  ptr--; /* since we will (*text)[ptr]++ in the top
96  * level for loop */
97  }
98  }
99  return true;
100 }
void ecpg_free(void *)
Definition: memory.c:13
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
int lineno
Definition: extern.h:53
char * ecpg_alloc(long, int)
Definition: memory.c:19
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
Definition: c.h:433
static bool isvarchar(unsigned char c)
Definition: prepare.c:34
static int SearchStmtCache ( const char *  ecpgQuery)
static

Definition at line 351 of file prepare.c.

References HashStmt(), and stmtCacheEntPerBucket.

Referenced by ecpg_auto_prepare().

352 {
353  int entNo,
354  entIx;
355 
356 /* hash the statement */
357  entNo = HashStmt(ecpgQuery);
358 
359 /* search the cache */
360  for (entIx = 0; entIx < stmtCacheEntPerBucket; ++entIx)
361  {
362  if (stmtCacheEntries[entNo].stmtID[0]) /* check if entry is in use */
363  {
364  if (strcmp(ecpgQuery, stmtCacheEntries[entNo].ecpgQuery) == 0)
365  break; /* found it */
366  }
367  ++entNo; /* incr entry # */
368  }
369 
370 /* if entry wasn't found - set entry # to zero */
371  if (entIx >= stmtCacheEntPerBucket)
372  entNo = 0;
373 
374  return entNo;
375 }
static const int stmtCacheEntPerBucket
Definition: prepare.c:27
static stmtCacheEntry stmtCacheEntries[16384]
Definition: prepare.c:28
static int HashStmt(const char *ecpgQuery)
Definition: prepare.c:316

Variable Documentation

int nextStmtID = 1
static

Definition at line 25 of file prepare.c.

Referenced by ecpg_auto_prepare().

const int stmtCacheEntPerBucket = 8
static

Definition at line 27 of file prepare.c.

Referenced by AddStmtToCache(), HashStmt(), and SearchStmtCache().

stmtCacheEntry stmtCacheEntries[16384] = {{0, {0}, 0, 0, 0}}
static

Definition at line 28 of file prepare.c.

const int stmtCacheNBuckets = 2039
static

Definition at line 26 of file prepare.c.

Referenced by HashStmt().