PostgreSQL Source Code  git master
connect.c
Go to the documentation of this file.
1 /* src/interfaces/ecpg/ecpglib/connect.c */
2 
3 #define POSTGRES_ECPG_INTERNAL
4 #include "postgres_fe.h"
5 
6 #include "ecpg-pthread-win32.h"
7 #include "ecpgerrno.h"
8 #include "ecpglib.h"
9 #include "ecpglib_extern.h"
10 #include "ecpgtype.h"
11 #include "sqlca.h"
12 
13 #ifdef ENABLE_THREAD_SAFETY
14 static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
15 static pthread_key_t actual_connection_key;
16 static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
17 #endif
18 static struct connection *actual_connection = NULL;
19 static struct connection *all_connections = NULL;
20 
21 #ifdef ENABLE_THREAD_SAFETY
22 static void
23 ecpg_actual_connection_init(void)
24 {
25  pthread_key_create(&actual_connection_key, NULL);
26 }
27 
28 void
29 ecpg_pthreads_init(void)
30 {
31  pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
32 }
33 #endif
34 
35 static struct connection *
36 ecpg_get_connection_nr(const char *connection_name)
37 {
38  struct connection *ret = NULL;
39 
40  if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
41  {
42 #ifdef ENABLE_THREAD_SAFETY
43  ret = pthread_getspecific(actual_connection_key);
44 
45  /*
46  * if no connection in TSD for this thread, get the global default
47  * connection and hope the user knows what they're doing (i.e. using
48  * their own mutex to protect that connection from concurrent accesses
49  */
50  /* if !ret then we got the connection from TSD */
51  if (NULL == ret)
52  /* no TSD connection, going for global */
53  ret = actual_connection;
54 #else
55  ret = actual_connection;
56 #endif
57  }
58  else
59  {
60  struct connection *con;
61 
62  for (con = all_connections; con != NULL; con = con->next)
63  {
64  if (strcmp(connection_name, con->name) == 0)
65  break;
66  }
67  ret = con;
68  }
69 
70  return ret;
71 }
72 
73 struct connection *
74 ecpg_get_connection(const char *connection_name)
75 {
76  struct connection *ret = NULL;
77 
78  if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
79  {
80 #ifdef ENABLE_THREAD_SAFETY
81  ret = pthread_getspecific(actual_connection_key);
82 
83  /*
84  * if no connection in TSD for this thread, get the global default
85  * connection and hope the user knows what they're doing (i.e. using
86  * their own mutex to protect that connection from concurrent accesses
87  */
88  /* if !ret then we got the connection from TSD */
89  if (NULL == ret)
90  /* no TSD connection here either, using global */
91  ret = actual_connection;
92 #else
93  ret = actual_connection;
94 #endif
95  }
96  else
97  {
98 #ifdef ENABLE_THREAD_SAFETY
99  pthread_mutex_lock(&connections_mutex);
100 #endif
101 
102  ret = ecpg_get_connection_nr(connection_name);
103 
104 #ifdef ENABLE_THREAD_SAFETY
105  pthread_mutex_unlock(&connections_mutex);
106 #endif
107  }
108 
109  return ret;
110 }
111 
112 static void
114 {
115  if (act != NULL)
116  {
117  struct ECPGtype_information_cache *cache,
118  *ptr;
119 
121  PQfinish(act->connection);
122 
123  /*
124  * no need to lock connections_mutex - we're always called by
125  * ECPGdisconnect or ECPGconnect, which are holding the lock
126  */
127 
128  /* remove act from the list */
129  if (act == all_connections)
130  all_connections = act->next;
131  else
132  {
133  struct connection *con;
134 
135  for (con = all_connections; con->next && con->next != act; con = con->next);
136  if (con->next)
137  con->next = act->next;
138  }
139 
140 #ifdef ENABLE_THREAD_SAFETY
141  if (pthread_getspecific(actual_connection_key) == act)
142  pthread_setspecific(actual_connection_key, all_connections);
143 #endif
144  if (actual_connection == act)
145  actual_connection = all_connections;
146 
147  ecpg_log("ecpg_finish: connection %s closed\n", act->name ? act->name : "(null)");
148 
149  for (cache = act->cache_head; cache; ptr = cache, cache = cache->next, ecpg_free(ptr));
150  ecpg_free(act->name);
151  ecpg_free(act);
152  /* delete cursor variables when last connection gets closed */
153  if (all_connections == NULL)
154  {
155  struct var_list *iv_ptr;
156 
157  for (; ivlist; iv_ptr = ivlist, ivlist = ivlist->next, ecpg_free(iv_ptr));
158  }
159  }
160  else
161  ecpg_log("ecpg_finish: called an extra time\n");
162 }
163 
164 bool
165 ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
166 {
167  struct connection *con = ecpg_get_connection(connection_name);
168  PGresult *results;
169 
170  if (!ecpg_init(con, connection_name, lineno))
171  return false;
172 
173  ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, mode, con->name);
174 
175  if (con->autocommit && strncmp(mode, "off", strlen("off")) == 0)
176  {
178  {
179  results = PQexec(con->connection, "begin transaction");
180  if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
181  return false;
182  PQclear(results);
183  }
184  con->autocommit = false;
185  }
186  else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
187  {
189  {
190  results = PQexec(con->connection, "commit");
191  if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
192  return false;
193  PQclear(results);
194  }
195  con->autocommit = true;
196  }
197 
198  return true;
199 }
200 
201 bool
202 ECPGsetconn(int lineno, const char *connection_name)
203 {
204  struct connection *con = ecpg_get_connection(connection_name);
205 
206  if (!ecpg_init(con, connection_name, lineno))
207  return false;
208 
209 #ifdef ENABLE_THREAD_SAFETY
210  pthread_setspecific(actual_connection_key, con);
211 #else
212  actual_connection = con;
213 #endif
214  return true;
215 }
216 
217 
218 static void
219 ECPGnoticeReceiver(void *arg, const PGresult *result)
220 {
221  char *sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
222  char *message = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
223  struct sqlca_t *sqlca = ECPGget_sqlca();
224  int sqlcode;
225 
226  if (sqlca == NULL)
227  {
228  ecpg_log("out of memory");
229  return;
230  }
231 
232  (void) arg; /* keep the compiler quiet */
233  if (sqlstate == NULL)
235 
236  if (message == NULL) /* Shouldn't happen, but need to be sure */
237  message = ecpg_gettext("empty message text");
238 
239  /* these are not warnings */
240  if (strncmp(sqlstate, "00", 2) == 0)
241  return;
242 
243  ecpg_log("ECPGnoticeReceiver: %s\n", message);
244 
245  /* map to SQLCODE for backward compatibility */
246  if (strcmp(sqlstate, ECPG_SQLSTATE_INVALID_CURSOR_NAME) == 0)
247  sqlcode = ECPG_WARNING_UNKNOWN_PORTAL;
248  else if (strcmp(sqlstate, ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION) == 0)
249  sqlcode = ECPG_WARNING_IN_TRANSACTION;
250  else if (strcmp(sqlstate, ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION) == 0)
251  sqlcode = ECPG_WARNING_NO_TRANSACTION;
252  else if (strcmp(sqlstate, ECPG_SQLSTATE_DUPLICATE_CURSOR) == 0)
253  sqlcode = ECPG_WARNING_PORTAL_EXISTS;
254  else
255  sqlcode = 0;
256 
257  strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));
258  sqlca->sqlcode = sqlcode;
259  sqlca->sqlwarn[2] = 'W';
260  sqlca->sqlwarn[0] = 'W';
261 
262  strncpy(sqlca->sqlerrm.sqlerrmc, message, sizeof(sqlca->sqlerrm.sqlerrmc));
263  sqlca->sqlerrm.sqlerrmc[sizeof(sqlca->sqlerrm.sqlerrmc) - 1] = 0;
264  sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
265 
266  ecpg_log("raising sqlcode %d\n", sqlcode);
267 }
268 
269 /* this contains some quick hacks, needs to be cleaned up, but it works */
270 bool
271 ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
272 {
273  struct sqlca_t *sqlca = ECPGget_sqlca();
274  enum COMPAT_MODE compat = c;
275  struct connection *this;
276  int i,
277  connect_params = 0;
278  char *dbname = name ? ecpg_strdup(name, lineno) : NULL,
279  *host = NULL,
280  *tmp,
281  *port = NULL,
282  *realname = NULL,
283  *options = NULL;
284  const char **conn_keywords;
285  const char **conn_values;
286 
287  if (sqlca == NULL)
288  {
291  ecpg_free(dbname);
292  return false;
293  }
294 
295  ecpg_init_sqlca(sqlca);
296 
297  /*
298  * clear auto_mem structure because some error handling functions might
299  * access it
300  */
302 
303  if (INFORMIX_MODE(compat))
304  {
305  char *envname;
306 
307  /*
308  * Informix uses an environment variable DBPATH that overrides the
309  * connection parameters given here. We do the same with PG_DBPATH as
310  * the syntax is different.
311  */
312  envname = getenv("PG_DBPATH");
313  if (envname)
314  {
315  ecpg_free(dbname);
316  dbname = ecpg_strdup(envname, lineno);
317  }
318 
319  }
320 
321  if (dbname == NULL && connection_name == NULL)
322  connection_name = "DEFAULT";
323 
324 #if ENABLE_THREAD_SAFETY
325  ecpg_pthreads_init();
326 #endif
327 
328  /* check if the identifier is unique */
329  if (ecpg_get_connection(connection_name))
330  {
331  ecpg_free(dbname);
332  ecpg_log("ECPGconnect: connection identifier %s is already in use\n",
333  connection_name);
334  return false;
335  }
336 
337  if ((this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno)) == NULL)
338  {
339  ecpg_free(dbname);
340  return false;
341  }
342 
343  if (dbname != NULL)
344  {
345  /* get the detail information from dbname */
346  if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0)
347  {
348  int offset = 0;
349 
350  /*
351  * only allow protocols tcp and unix
352  */
353  if (strncmp(dbname, "tcp:", 4) == 0)
354  offset = 4;
355  else if (strncmp(dbname, "unix:", 5) == 0)
356  offset = 5;
357 
358  if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0)
359  {
360 
361  /*------
362  * new style:
363  * <tcp|unix>:postgresql://server[:port][/db-name][?options]
364  *------
365  */
366  offset += strlen("postgresql://");
367 
368  tmp = strrchr(dbname + offset, '?');
369  if (tmp != NULL) /* options given */
370  {
371  options = ecpg_strdup(tmp + 1, lineno);
372  *tmp = '\0';
373  }
374 
375  tmp = last_dir_separator(dbname + offset);
376  if (tmp != NULL) /* database name given */
377  {
378  if (tmp[1] != '\0') /* non-empty database name */
379  {
380  realname = ecpg_strdup(tmp + 1, lineno);
381  connect_params++;
382  }
383  *tmp = '\0';
384  }
385 
386  tmp = strrchr(dbname + offset, ':');
387  if (tmp != NULL) /* port number given */
388  {
389  *tmp = '\0';
390  port = ecpg_strdup(tmp + 1, lineno);
391  connect_params++;
392  }
393 
394  if (strncmp(dbname, "unix:", 5) == 0)
395  {
396  /*
397  * The alternative of using "127.0.0.1" here is deprecated
398  * and undocumented; we'll keep it for backward
399  * compatibility's sake, but not extend it to allow IPv6.
400  */
401  if (strcmp(dbname + offset, "localhost") != 0 &&
402  strcmp(dbname + offset, "127.0.0.1") != 0)
403  {
404  ecpg_log("ECPGconnect: non-localhost access via sockets on line %d\n", lineno);
406  if (host)
407  ecpg_free(host);
408  if (port)
409  ecpg_free(port);
410  if (options)
411  ecpg_free(options);
412  if (realname)
413  ecpg_free(realname);
414  if (dbname)
415  ecpg_free(dbname);
416  free(this);
417  return false;
418  }
419  }
420  else
421  {
422  if (*(dbname + offset) != '\0')
423  {
424  host = ecpg_strdup(dbname + offset, lineno);
425  connect_params++;
426  }
427  }
428  }
429  }
430  else
431  {
432  /* old style: dbname[@server][:port] */
433  tmp = strrchr(dbname, ':');
434  if (tmp != NULL) /* port number given */
435  {
436  port = ecpg_strdup(tmp + 1, lineno);
437  connect_params++;
438  *tmp = '\0';
439  }
440 
441  tmp = strrchr(dbname, '@');
442  if (tmp != NULL) /* host name given */
443  {
444  host = ecpg_strdup(tmp + 1, lineno);
445  connect_params++;
446  *tmp = '\0';
447  }
448 
449  if (strlen(dbname) > 0)
450  {
451  realname = ecpg_strdup(dbname, lineno);
452  connect_params++;
453  }
454  else
455  realname = NULL;
456  }
457  }
458  else
459  realname = NULL;
460 
461  /*
462  * Count options for the allocation done below (this may produce an
463  * overestimate, it's ok).
464  */
465  if (options)
466  for (i = 0; options[i]; i++)
467  if (options[i] == '=')
468  connect_params++;
469 
470  if (user && strlen(user) > 0)
471  connect_params++;
472  if (passwd && strlen(passwd) > 0)
473  connect_params++;
474 
475  /*
476  * Allocate enough space for all connection parameters. These allocations
477  * are done before manipulating the list of connections to ease the error
478  * handling on failure.
479  */
480  conn_keywords = (const char **) ecpg_alloc((connect_params + 1) * sizeof(char *), lineno);
481  conn_values = (const char **) ecpg_alloc(connect_params * sizeof(char *), lineno);
482  if (conn_keywords == NULL || conn_values == NULL)
483  {
484  if (host)
485  ecpg_free(host);
486  if (port)
487  ecpg_free(port);
488  if (options)
489  ecpg_free(options);
490  if (realname)
491  ecpg_free(realname);
492  if (dbname)
493  ecpg_free(dbname);
494  if (conn_keywords)
495  ecpg_free(conn_keywords);
496  if (conn_values)
497  ecpg_free(conn_values);
498  free(this);
499  return false;
500  }
501 
502  /* add connection to our list */
503 #ifdef ENABLE_THREAD_SAFETY
504  pthread_mutex_lock(&connections_mutex);
505 #endif
506  if (connection_name != NULL)
507  this->name = ecpg_strdup(connection_name, lineno);
508  else
509  this->name = ecpg_strdup(realname, lineno);
510 
511  this->cache_head = NULL;
512  this->prep_stmts = NULL;
513 
514  if (all_connections == NULL)
515  this->next = NULL;
516  else
517  this->next = all_connections;
518 
519  all_connections = this;
520 #ifdef ENABLE_THREAD_SAFETY
521  pthread_setspecific(actual_connection_key, all_connections);
522 #endif
523  actual_connection = all_connections;
524 
525  ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
526  realname ? realname : "<DEFAULT>",
527  host ? host : "<DEFAULT>",
528  port ? (ecpg_internal_regression_mode ? "<REGRESSION_PORT>" : port) : "<DEFAULT>",
529  options ? "with options " : "", options ? options : "",
530  (user && strlen(user) > 0) ? "for user " : "", user ? user : "");
531 
532  i = 0;
533  if (realname)
534  {
535  conn_keywords[i] = "dbname";
536  conn_values[i] = realname;
537  i++;
538  }
539  if (host)
540  {
541  conn_keywords[i] = "host";
542  conn_values[i] = host;
543  i++;
544  }
545  if (port)
546  {
547  conn_keywords[i] = "port";
548  conn_values[i] = port;
549  i++;
550  }
551  if (user && strlen(user) > 0)
552  {
553  conn_keywords[i] = "user";
554  conn_values[i] = user;
555  i++;
556  }
557  if (passwd && strlen(passwd) > 0)
558  {
559  conn_keywords[i] = "password";
560  conn_values[i] = passwd;
561  i++;
562  }
563  if (options)
564  {
565  char *str;
566 
567  /*
568  * The options string contains "keyword=value" pairs separated by
569  * '&'s. We must break this up into keywords and values to pass to
570  * libpq (it's okay to scribble on the options string). We ignore
571  * spaces just before each keyword or value.
572  */
573  for (str = options; *str;)
574  {
575  int e,
576  a;
577  char *token1,
578  *token2;
579 
580  /* Skip spaces before keyword */
581  for (token1 = str; *token1 == ' '; token1++)
582  /* skip */ ;
583  /* Find end of keyword */
584  for (e = 0; token1[e] && token1[e] != '='; e++)
585  /* skip */ ;
586  if (token1[e]) /* found "=" */
587  {
588  token1[e] = '\0';
589  /* Skip spaces before value */
590  for (token2 = token1 + e + 1; *token2 == ' '; token2++)
591  /* skip */ ;
592  /* Find end of value */
593  for (a = 0; token2[a] && token2[a] != '&'; a++)
594  /* skip */ ;
595  if (token2[a]) /* found "&" => another option follows */
596  {
597  token2[a] = '\0';
598  str = token2 + a + 1;
599  }
600  else
601  str = token2 + a;
602 
603  conn_keywords[i] = token1;
604  conn_values[i] = token2;
605  i++;
606  }
607  else
608  {
609  /* Bogus options syntax ... ignore trailing garbage */
610  str = token1 + e;
611  }
612  }
613  }
614 
615  Assert(i <= connect_params);
616  conn_keywords[i] = NULL; /* terminator */
617 
618  this->connection = PQconnectdbParams(conn_keywords, conn_values, 0);
619 
620  if (host)
621  ecpg_free(host);
622  if (port)
623  ecpg_free(port);
624  if (options)
625  ecpg_free(options);
626  if (dbname)
627  ecpg_free(dbname);
628  ecpg_free(conn_values);
629  ecpg_free(conn_keywords);
630 
631  if (PQstatus(this->connection) == CONNECTION_BAD)
632  {
633  const char *errmsg = PQerrorMessage(this->connection);
634  const char *db = realname ? realname : ecpg_gettext("<DEFAULT>");
635 
636  /* PQerrorMessage's result already has a trailing newline */
637  ecpg_log("ECPGconnect: %s", errmsg);
638 
639  ecpg_finish(this);
640 #ifdef ENABLE_THREAD_SAFETY
641  pthread_mutex_unlock(&connections_mutex);
642 #endif
643 
645  if (realname)
646  ecpg_free(realname);
647 
648  return false;
649  }
650 
651  if (realname)
652  ecpg_free(realname);
653 
654 #ifdef ENABLE_THREAD_SAFETY
655  pthread_mutex_unlock(&connections_mutex);
656 #endif
657 
658  this->autocommit = autocommit;
659 
660  PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this);
661 
662  return true;
663 }
664 
665 bool
666 ECPGdisconnect(int lineno, const char *connection_name)
667 {
668  struct sqlca_t *sqlca = ECPGget_sqlca();
669  struct connection *con;
670 
671  if (sqlca == NULL)
672  {
675  return false;
676  }
677 
678 #ifdef ENABLE_THREAD_SAFETY
679  pthread_mutex_lock(&connections_mutex);
680 #endif
681 
682  if (strcmp(connection_name, "ALL") == 0)
683  {
684  ecpg_init_sqlca(sqlca);
685  for (con = all_connections; con;)
686  {
687  struct connection *f = con;
688 
689  con = con->next;
690  ecpg_finish(f);
691  }
692  }
693  else
694  {
695  con = ecpg_get_connection_nr(connection_name);
696 
697  if (!ecpg_init(con, connection_name, lineno))
698  {
699 #ifdef ENABLE_THREAD_SAFETY
700  pthread_mutex_unlock(&connections_mutex);
701 #endif
702  return false;
703  }
704  else
705  ecpg_finish(con);
706  }
707 
708 #ifdef ENABLE_THREAD_SAFETY
709  pthread_mutex_unlock(&connections_mutex);
710 #endif
711 
712  return true;
713 }
714 
715 PGconn *
716 ECPGget_PGconn(const char *connection_name)
717 {
718  struct connection *con;
719 
720  con = ecpg_get_connection(connection_name);
721  if (con == NULL)
722  return NULL;
723 
724  return con->connection;
725 }
#define ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION
CRITICAL_SECTION * pthread_mutex_t
Definition: pthread-win32.h:8
static PgChecksumMode mode
Definition: pg_checksums.c:65
struct var_list * next
bool ECPGdisconnect(int lineno, const char *connection_name)
Definition: connect.c:666
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
COMPAT_MODE
static void ecpg_finish(struct connection *act)
Definition: connect.c:113
#define ECPG_CONNECT
Definition: ecpgerrno.h:51
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
static int32 next
Definition: blutils.c:219
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
#define sqlca
Definition: sqlca.h:59
ULONG pthread_key_t
Definition: pthread-win32.h:7
void ecpg_free(void *)
Definition: memory.c:13
char sqlwarn[8]
Definition: sqlca.h:39
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
#define INFORMIX_MODE(X)
int sqlerrml
Definition: sqlca.h:26
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:657
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
#define ecpg_gettext(x)
struct ECPGtype_information_cache * next
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
static struct connection * all_connections
Definition: connect.c:19
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:141
struct ECPGtype_information_cache * cache_head
bool ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit)
Definition: connect.c:271
Definition: sqlca.h:19
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45
char * c
struct connection * next
#define ECPG_WARNING_PORTAL_EXISTS
Definition: ecpgerrno.h:77
bool ecpg_internal_regression_mode
Definition: misc.c:29
char sqlstate[5]
Definition: sqlca.h:53
void ecpg_log(const char *format,...) pg_attribute_printf(1
#define ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION
enum COMPAT_MODE compat
Definition: ecpg.c:25
static int port
Definition: pg_regress.c:92
char * ecpg_alloc(long, int)
Definition: memory.c:19
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6699
void ecpg_clear_auto_mem(void)
Definition: memory.c:158
bool ECPGsetconn(int lineno, const char *connection_name)
Definition: connect.c:202
void ecpg_init_sqlca(struct sqlca_t *sqlca)
Definition: misc.c:98
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
#define ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION
long sqlcode
Definition: sqlca.h:23
char * last_dir_separator(const char *filename)
Definition: path.c:138
struct var_list * ivlist
Definition: misc.c:523
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define free(a)
Definition: header.h:65
bool ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE)
Definition: error.c:282
#define ECPG_WARNING_IN_TRANSACTION
Definition: ecpgerrno.h:72
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3233
PGconn * connection
#define Assert(condition)
Definition: c.h:804
bool autocommit
Definition: ecpg.c:15
int pthread_once_t
Definition: pthread-win32.h:9
char * dbname
Definition: streamutil.c:51
void * pthread_getspecific(pthread_key_t key)
Definition: pthread-win32.c:29
#define ECPG_SQLSTATE_INVALID_CURSOR_NAME
static struct connection * ecpg_get_connection_nr(const char *connection_name)
Definition: connect.c:36
const char * name
Definition: encode.c:561
bool ECPGsetcommit(int lineno, const char *mode, const char *connection_name)
Definition: connect.c:165
e
Definition: preproc-init.c:82
static char * user
Definition: pg_regress.c:95
int errmsg(const char *fmt,...)
Definition: elog.c:909
void pthread_setspecific(pthread_key_t key, void *val)
Definition: pthread-win32.c:24
static struct connection * actual_connection
Definition: connect.c:18
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
char sqlerrmc[SQLERRMC_LEN]
Definition: sqlca.h:27
struct sqlca_t::@146 sqlerrm
PGconn * ECPGget_PGconn(const char *connection_name)
Definition: connect.c:716
int i
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2193
void * arg
static void ECPGnoticeReceiver(void *arg, const PGresult *result)
Definition: connect.c:219
bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *conn)
Definition: prepare.c:337
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6691
bool ecpg_init(const struct connection *, const char *, const int)
Definition: misc.c:104
#define ECPG_WARNING_NO_TRANSACTION
Definition: ecpgerrno.h:75
PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
Definition: fe-connect.c:6895
#define ECPG_SQLSTATE_DUPLICATE_CURSOR
#define ECPG_WARNING_UNKNOWN_PORTAL
Definition: ecpgerrno.h:70
struct prepared_statement * prep_stmts