PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 "ecpgtype.h"
8 #include "ecpglib.h"
9 #include "ecpgerrno.h"
10 #include "extern.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
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
113 ecpg_finish(struct connection * act)
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|:/unixsocket/path:]
364  * [/db-name][?options]
365  *------
366  */
367  offset += strlen("postgresql://");
368 
369  tmp = strrchr(dbname + offset, '?');
370  if (tmp != NULL) /* options given */
371  {
372  options = ecpg_strdup(tmp + 1, lineno);
373  *tmp = '\0';
374  }
375 
376  tmp = last_dir_separator(dbname + offset);
377  if (tmp != NULL) /* database name given */
378  {
379  if (tmp[1] != '\0') /* non-empty database name */
380  {
381  realname = ecpg_strdup(tmp + 1, lineno);
382  connect_params++;
383  }
384  *tmp = '\0';
385  }
386 
387  tmp = strrchr(dbname + offset, ':');
388  if (tmp != NULL) /* port number or Unix socket path given */
389  {
390  char *tmp2;
391 
392  *tmp = '\0';
393  if ((tmp2 = strchr(tmp + 1, ':')) != NULL)
394  {
395  *tmp2 = '\0';
396  host = ecpg_strdup(tmp + 1, lineno);
397  connect_params++;
398  if (strncmp(dbname, "unix:", 5) != 0)
399  {
400  ecpg_log("ECPGconnect: socketname %s given for TCP connection on line %d\n", host, lineno);
402  if (host)
403  ecpg_free(host);
404 
405  /*
406  * port not set yet if (port) ecpg_free(port);
407  */
408  if (options)
409  ecpg_free(options);
410  if (realname)
411  ecpg_free(realname);
412  if (dbname)
413  ecpg_free(dbname);
414  free(this);
415  return false;
416  }
417  }
418  else
419  {
420  port = ecpg_strdup(tmp + 1, lineno);
421  connect_params++;
422  }
423  }
424 
425  if (strncmp(dbname, "unix:", 5) == 0)
426  {
427  if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0)
428  {
429  ecpg_log("ECPGconnect: non-localhost access via sockets on line %d\n", lineno);
431  if (host)
432  ecpg_free(host);
433  if (port)
434  ecpg_free(port);
435  if (options)
436  ecpg_free(options);
437  if (realname)
438  ecpg_free(realname);
439  if (dbname)
440  ecpg_free(dbname);
441  free(this);
442  return false;
443  }
444  }
445  else
446  {
447  if (*(dbname + offset) != '\0')
448  {
449  host = ecpg_strdup(dbname + offset, lineno);
450  connect_params++;
451  }
452  }
453 
454  }
455  }
456  else
457  {
458  /* old style: dbname[@server][:port] */
459  tmp = strrchr(dbname, ':');
460  if (tmp != NULL) /* port number given */
461  {
462  port = ecpg_strdup(tmp + 1, lineno);
463  connect_params++;
464  *tmp = '\0';
465  }
466 
467  tmp = strrchr(dbname, '@');
468  if (tmp != NULL) /* host name given */
469  {
470  host = ecpg_strdup(tmp + 1, lineno);
471  connect_params++;
472  *tmp = '\0';
473  }
474 
475  if (strlen(dbname) > 0)
476  {
477  realname = ecpg_strdup(dbname, lineno);
478  connect_params++;
479  }
480  else
481  realname = NULL;
482  }
483  }
484  else
485  realname = NULL;
486 
487  /* add connection to our list */
488 #ifdef ENABLE_THREAD_SAFETY
489  pthread_mutex_lock(&connections_mutex);
490 #endif
491  if (connection_name != NULL)
492  this->name = ecpg_strdup(connection_name, lineno);
493  else
494  this->name = ecpg_strdup(realname, lineno);
495 
496  this->cache_head = NULL;
497  this->prep_stmts = NULL;
498 
499  if (all_connections == NULL)
500  this->next = NULL;
501  else
502  this->next = all_connections;
503 
504  all_connections = this;
505 #ifdef ENABLE_THREAD_SAFETY
506  pthread_setspecific(actual_connection_key, all_connections);
507 #endif
508  actual_connection = all_connections;
509 
510  ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
511  realname ? realname : "<DEFAULT>",
512  host ? host : "<DEFAULT>",
513  port ? (ecpg_internal_regression_mode ? "<REGRESSION_PORT>" : port) : "<DEFAULT>",
514  options ? "with options " : "", options ? options : "",
515  (user && strlen(user) > 0) ? "for user " : "", user ? user : "");
516 
517  if (options)
518  for (i = 0; options[i]; i++)
519  /* count options */
520  if (options[i] == '=')
521  connect_params++;
522 
523  if (user && strlen(user) > 0)
524  connect_params++;
525  if (passwd && strlen(passwd) > 0)
526  connect_params++;
527 
528  /* allocate enough space for all connection parameters */
529  conn_keywords = (const char **) ecpg_alloc((connect_params + 1) * sizeof(char *), lineno);
530  conn_values = (const char **) ecpg_alloc(connect_params * sizeof(char *), lineno);
531  if (conn_keywords == NULL || conn_values == NULL)
532  {
533  if (host)
534  ecpg_free(host);
535  if (port)
536  ecpg_free(port);
537  if (options)
538  ecpg_free(options);
539  if (realname)
540  ecpg_free(realname);
541  if (dbname)
542  ecpg_free(dbname);
543  if (conn_keywords)
544  ecpg_free(conn_keywords);
545  if (conn_values)
546  ecpg_free(conn_values);
547  free(this);
548  return false;
549  }
550 
551  i = 0;
552  if (realname)
553  {
554  conn_keywords[i] = "dbname";
555  conn_values[i] = realname;
556  i++;
557  }
558  if (host)
559  {
560  conn_keywords[i] = "host";
561  conn_values[i] = host;
562  i++;
563  }
564  if (port)
565  {
566  conn_keywords[i] = "port";
567  conn_values[i] = port;
568  i++;
569  }
570  if (user && strlen(user) > 0)
571  {
572  conn_keywords[i] = "user";
573  conn_values[i] = user;
574  i++;
575  }
576  if (passwd && strlen(passwd) > 0)
577  {
578  conn_keywords[i] = "password";
579  conn_values[i] = passwd;
580  i++;
581  }
582  if (options)
583  {
584  char *str;
585 
586  /* options look like this "option1 = value1 option2 = value2 ... */
587  /* we have to break up the string into single options */
588  for (str = options; *str;)
589  {
590  int e,
591  a;
592  char *token1,
593  *token2;
594 
595  for (token1 = str; *token1 && *token1 == ' '; token1++);
596  for (e = 0; token1[e] && token1[e] != '='; e++);
597  if (token1[e]) /* found "=" */
598  {
599  token1[e] = '\0';
600  for (token2 = token1 + e + 1; *token2 && *token2 == ' '; token2++);
601  for (a = 0; token2[a] && token2[a] != '&'; a++);
602  if (token2[a]) /* found "&" => another option follows */
603  {
604  token2[a] = '\0';
605  str = token2 + a + 1;
606  }
607  else
608  str = token2 + a;
609 
610  conn_keywords[i] = token1;
611  conn_values[i] = token2;
612  i++;
613  }
614  else
615  /* the parser should not be able to create this invalid option */
616  str = token1 + e;
617  }
618 
619  }
620  conn_keywords[i] = NULL; /* terminator */
621 
622  this->connection = PQconnectdbParams(conn_keywords, conn_values, 0);
623 
624  if (host)
625  ecpg_free(host);
626  if (port)
627  ecpg_free(port);
628  if (options)
629  ecpg_free(options);
630  if (dbname)
631  ecpg_free(dbname);
632  ecpg_free(conn_values);
633  ecpg_free(conn_keywords);
634 
635  if (PQstatus(this->connection) == CONNECTION_BAD)
636  {
637  const char *errmsg = PQerrorMessage(this->connection);
638  const char *db = realname ? realname : ecpg_gettext("<DEFAULT>");
639 
640  ecpg_log("ECPGconnect: could not open database: %s\n", errmsg);
641 
642  ecpg_finish(this);
643 #ifdef ENABLE_THREAD_SAFETY
644  pthread_mutex_unlock(&connections_mutex);
645 #endif
646 
648  if (realname)
649  ecpg_free(realname);
650 
651  return false;
652  }
653 
654  if (realname)
655  ecpg_free(realname);
656 
657 #ifdef ENABLE_THREAD_SAFETY
658  pthread_mutex_unlock(&connections_mutex);
659 #endif
660 
661  this->autocommit = autocommit;
662 
663  PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this);
664 
665  return true;
666 }
667 
668 bool
669 ECPGdisconnect(int lineno, const char *connection_name)
670 {
671  struct sqlca_t *sqlca = ECPGget_sqlca();
672  struct connection *con;
673 
674  if (sqlca == NULL)
675  {
678  return (false);
679  }
680 
681 #ifdef ENABLE_THREAD_SAFETY
682  pthread_mutex_lock(&connections_mutex);
683 #endif
684 
685  if (strcmp(connection_name, "ALL") == 0)
686  {
687  ecpg_init_sqlca(sqlca);
688  for (con = all_connections; con;)
689  {
690  struct connection *f = con;
691 
692  con = con->next;
693  ecpg_finish(f);
694  }
695  }
696  else
697  {
698  con = ecpg_get_connection_nr(connection_name);
699 
700  if (!ecpg_init(con, connection_name, lineno))
701  {
702 #ifdef ENABLE_THREAD_SAFETY
703  pthread_mutex_unlock(&connections_mutex);
704 #endif
705  return (false);
706  }
707  else
708  ecpg_finish(con);
709  }
710 
711 #ifdef ENABLE_THREAD_SAFETY
712  pthread_mutex_unlock(&connections_mutex);
713 #endif
714 
715  return true;
716 }
717 
718 PGconn *
719 ECPGget_PGconn(const char *connection_name)
720 {
721  struct connection *con;
722 
723  con = ecpg_get_connection(connection_name);
724  if (con == NULL)
725  return NULL;
726 
727  return con->connection;
728 }
bool ecpg_init(const struct connection *, const char *, const int)
Definition: misc.c:105
CRITICAL_SECTION * pthread_mutex_t
Definition: pthread-win32.h:8
struct var_list * next
Definition: extern.h:132
bool ECPGdisconnect(int lineno, const char *connection_name)
Definition: connect.c:669
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5960
static void ecpg_finish(struct connection *act)
Definition: connect.c:113
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
Definition: extern.h:220
#define ECPG_CONNECT
Definition: ecpgerrno.h:51
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:54
static int32 next
Definition: blutils.c:210
bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *conn)
Definition: prepare.c:276
void ecpg_free(void *)
Definition: memory.c:13
#define INFORMIX_MODE(X)
Definition: extern.h:23
#define sqlca
Definition: sqlca.h:59
ULONG pthread_key_t
Definition: pthread-win32.h:7
char * name
Definition: extern.h:81
char sqlwarn[8]
Definition: sqlca.h:39
int sqlerrml
Definition: sqlca.h:26
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
Definition: extern.h:221
bool autocommit
Definition: extern.h:83
struct sqlca_t::@79 sqlerrm
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:53
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:471
struct ECPGtype_information_cache * next
Definition: extern.h:45
void ecpg_log(const char *format,...) pg_attribute_printf(1
#define ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION
Definition: extern.h:211
#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:142
struct ECPGtype_information_cache * cache_head
Definition: extern.h:84
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:46
char * c
struct connection * next
Definition: extern.h:86
#define ECPG_WARNING_PORTAL_EXISTS
Definition: ecpgerrno.h:77
char * ecpg_alloc(long, int)
Definition: memory.c:19
void ecpg_clear_auto_mem(void)
Definition: memory.c:158
char sqlstate[5]
Definition: sqlca.h:53
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
enum COMPAT_MODE compat
Definition: ecpg.c:25
static int port
Definition: pg_regress.c:87
bool ecpg_internal_regression_mode
Definition: misc.c:30
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:5915
bool ECPGsetconn(int lineno, const char *connection_name)
Definition: connect.c:202
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:55
long sqlcode
Definition: sqlca.h:23
#define ecpg_gettext(x)
Definition: ecpglib.h:18
char * last_dir_separator(const char *filename)
Definition: path.c:138
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define free(a)
Definition: header.h:60
#define ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION
Definition: extern.h:210
void ecpg_init_sqlca(struct sqlca_t *sqlca)
Definition: misc.c:99
#define ECPG_WARNING_IN_TRANSACTION
Definition: ecpgerrno.h:72
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2658
PGconn * connection
Definition: extern.h:82
#define NULL
Definition: c.h:226
bool autocommit
Definition: ecpg.c:15
struct var_list * ivlist
Definition: misc.c:515
int pthread_once_t
Definition: pthread-win32.h:9
char * dbname
Definition: streamutil.c:41
void * pthread_getspecific(pthread_key_t key)
Definition: pthread-win32.c:30
bool ecpg_check_PQresult(PGresult *results, int lineno, PGconn *connection, enum COMPAT_MODE compat)
Definition: error.c:283
static struct connection * ecpg_get_connection_nr(const char *connection_name)
Definition: connect.c:36
const char * name
Definition: encode.c:521
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:90
int errmsg(const char *fmt,...)
Definition: elog.c:797
void pthread_setspecific(pthread_key_t key, void *val)
Definition: pthread-win32.c:25
static struct connection * actual_connection
Definition: connect.c:18
#define ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION
Definition: extern.h:205
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
char sqlerrmc[SQLERRMC_LEN]
Definition: sqlca.h:27
PGconn * ECPGget_PGconn(const char *connection_name)
Definition: connect.c:719
int i
COMPAT_MODE
Definition: extern.h:16
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
void * arg
static void ECPGnoticeReceiver(void *arg, const PGresult *result)
Definition: connect.c:219
#define ECPG_SQLSTATE_DUPLICATE_CURSOR
Definition: extern.h:217
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:5907
#define ECPG_SQLSTATE_INVALID_CURSOR_NAME
Definition: extern.h:214
#define ECPG_WARNING_NO_TRANSACTION
Definition: ecpgerrno.h:75
PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
Definition: fe-connect.c:6119
#define ECPG_WARNING_UNKNOWN_PORTAL
Definition: ecpgerrno.h:70
struct prepared_statement * prep_stmts
Definition: extern.h:85