Re: [HACKERS] ECPG, threading and pooling - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | Re: [HACKERS] ECPG, threading and pooling |
Date | |
Msg-id | 200306150456.h5F4uW401699@candle.pha.pa.us Whole thread Raw |
List | pgsql-patches |
I had to make the following changes to the patch. You had this: sqlca = pthread_getspecific(&sqlca_key); but my prototypes say it should be: sqlca = pthread_getspecific(sqlca_key); The applied patch also includes some prototype cleanups. --------------------------------------------------------------------------- pgman wrote: > > Patch applied. I made adjustments to use the new configure thread > settings, and I added documentation. I also updated the interface > version numbers as included in the patch. > > --------------------------------------------------------------------------- > > Lee Kindness wrote: > Content-Description: message body text > > > Michael, > > > > Michael Meskes writes: > > > On Thu, Jan 23, 2003 at 02:40:33PM +0530, Shridhar Daithankar<shridhar_daithankar@persistent.co.in> wrote: > > > > I would like to use ECPG as it is relatively easy to code. However my > > > > application is multithreaded and also uses connecion pools. > > > > > > I'm afraid it needs some work to be thread-safe. sqlca is defined > > > statically. No big deal it seems to implement a thread safe version but > > > I haven't yet found the time. > > > > I've spent a bit of time on making ecpg thread safe over Christmas, > > while it's not finished i'm sure the attached patch is at least useful > > and a step in the right direction. > > > > Lee. > > > > [ Attachment, skipping... ] > > > > > ---------------------------(end of broadcast)--------------------------- > > TIP 3: if posting/reading through Usenet, please send an appropriate > > subscribe-nomail command to majordomo@postgresql.org so that your > > message can get through to the mailing list cleanly > > -- > Bruce Momjian | http://candle.pha.pa.us > pgman@candle.pha.pa.us | (610) 359-1001 > + If your life is a hard drive, | 13 Roberts Road > + Christ can be your backup. | Newtown Square, Pennsylvania 19073 > Index: configure.in > =================================================================== > RCS file: /cvsroot/pgsql-server/configure.in,v > retrieving revision 1.264 > diff -c -c -r1.264 configure.in > *** configure.in 14 Jun 2003 19:21:42 -0000 1.264 > --- configure.in 15 Jun 2003 04:02:55 -0000 > *************** > *** 323,330 **** > # Enable libpq to be thread-safe > # > AC_MSG_CHECKING([allow threaded libpq]) > ! PGAC_ARG_BOOL(with, threads, no, [ --with-threads allow libpq to be thread-safe], > ! [AC_DEFINE([USE_THREADS], 1, [Define to 1 to build libpq with threads. (--with-threads)])]) > > AC_MSG_RESULT([$with_threads]) > AC_SUBST(with_threads) > --- 323,330 ---- > # Enable libpq to be thread-safe > # > AC_MSG_CHECKING([allow threaded libpq]) > ! PGAC_ARG_BOOL(with, threads, no, [ --with-threads allow libpq and ecpg to be thread-safe], > ! [AC_DEFINE([USE_THREADS], 1, [Define to 1 to build libpq and ecpg to be thread-safe. (--with-threads)])]) > > AC_MSG_RESULT([$with_threads]) > AC_SUBST(with_threads) > Index: doc/src/sgml/ecpg.sgml > =================================================================== > RCS file: /cvsroot/pgsql-server/doc/src/sgml/ecpg.sgml,v > retrieving revision 1.43 > diff -c -c -r1.43 ecpg.sgml > *** doc/src/sgml/ecpg.sgml 25 Mar 2003 16:15:35 -0000 1.43 > --- doc/src/sgml/ecpg.sgml 15 Jun 2003 04:02:56 -0000 > *************** > *** 750,755 **** > --- 750,762 ---- > </para> > > <para> > + <application>ecpg</application> is thread-safe if it is compiled using > + the <literal>--with-threads</> <filename>configure</filename> > + command-line option. (You might need to use other threading > + command-line options to compile your client code.) > + </para> > + > + <para> > The preprocessor program is called <filename>ecpg</filename> and is > included in a normal <productname>PostgreSQL</> installation. > Embedded SQL programs are typically named with an extension > Index: doc/src/sgml/installation.sgml > =================================================================== > RCS file: /cvsroot/pgsql-server/doc/src/sgml/installation.sgml,v > retrieving revision 1.134 > diff -c -c -r1.134 installation.sgml > *** doc/src/sgml/installation.sgml 13 Jun 2003 23:10:07 -0000 1.134 > --- doc/src/sgml/installation.sgml 15 Jun 2003 04:02:59 -0000 > *************** > *** 918,924 **** > <term><option>--with-threads</option></term> > <listitem> > <para> > ! Allow separate libpq threads to safely control their private connection handles. > </para> > </listitem> > </varlistentry> > --- 918,925 ---- > <term><option>--with-threads</option></term> > <listitem> > <para> > ! Allow separate libpq and ecpg threads to safely control their > ! private connection handles. > </para> > </listitem> > </varlistentry> > Index: src/interfaces/ecpg/ecpglib/Makefile > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/Makefile,v > retrieving revision 1.3 > diff -c -c -r1.3 Makefile > *** src/interfaces/ecpg/ecpglib/Makefile 22 May 2003 17:20:44 -0000 1.3 > --- src/interfaces/ecpg/ecpglib/Makefile 15 Jun 2003 04:03:01 -0000 > *************** > *** 13,27 **** > include $(top_builddir)/src/Makefile.global > > NAME= ecpg > ! SO_MAJOR_VERSION= 3 > ! SO_MINOR_VERSION= 4.2 > > ! override CPPFLAGS := -I$(top_srcdir)/src/interfaces/ecpg/include -I$(libpq_srcdir) $(CPPFLAGS) > > OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \ > connect.o misc.o > > ! SHLIB_LINK = -L../pgtypeslib -lpgtypes $(libpq) > > all: all-lib > > --- 13,27 ---- > include $(top_builddir)/src/Makefile.global > > NAME= ecpg > ! SO_MAJOR_VERSION= 4 > ! SO_MINOR_VERSION= 1.1 > > ! override CPPFLAGS := -I$(top_srcdir)/src/interfaces/ecpg/include -I$(libpq_srcdir) $(CPPFLAGS) $(THREAD_CFLAGS) > > OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \ > connect.o misc.o > > ! SHLIB_LINK = -L../pgtypeslib -lpgtypes $(libpq) $(THREAD_LIBS) > > all: all-lib > > Index: src/interfaces/ecpg/ecpglib/connect.c > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/connect.c,v > retrieving revision 1.6 > diff -c -c -r1.6 connect.c > *** src/interfaces/ecpg/ecpglib/connect.c 13 Jun 2003 10:50:57 -0000 1.6 > --- src/interfaces/ecpg/ecpglib/connect.c 15 Jun 2003 04:03:01 -0000 > *************** > *** 1,29 **** > /* $Header: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/connect.c,v 1.6 2003/06/13 10:50:57 meskes Exp $ */ > > #include "postgres_fe.h" > > #include "ecpgtype.h" > #include "ecpglib.h" > #include "ecpgerrno.h" > #include "extern.h" > #include "sqlca.h" > > ! static struct connection *all_connections = NULL, > ! *actual_connection = NULL; > > struct connection * > ECPGget_connection(const char *connection_name) > { > ! struct connection *con = all_connections; > > ! if (connection_name == NULL || strcmp(connection_name, "CURRENT") == 0) > ! return actual_connection; > > ! for (; con && strcmp(connection_name, con->name) != 0; con = con->next); > ! if (con) > ! return con; > ! else > ! return NULL; > } > > static void > --- 1,53 ---- > /* $Header: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/connect.c,v 1.6 2003/06/13 10:50:57 meskes Exp $ */ > > + #define POSTGRES_ECPG_INTERNAL > #include "postgres_fe.h" > > + #ifdef USE_THREADS > + #include <pthread.h> > + #endif > #include "ecpgtype.h" > #include "ecpglib.h" > #include "ecpgerrno.h" > #include "extern.h" > #include "sqlca.h" > > ! #ifdef USE_THREADS > ! static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER; > ! #endif > ! static struct connection *all_connections = NULL; > ! static struct connection *actual_connection = NULL; > > struct connection * > ECPGget_connection(const char *connection_name) > { > ! struct connection *ret = NULL; > > ! #ifdef USE_THREADS > ! pthread_mutex_lock(&connections_mutex); > ! #endif > ! > ! if( (connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0) ) > ! { > ! ret = actual_connection; > ! } > ! else > ! { > ! struct connection *con; > ! > ! for( con = all_connections; con != NULL; con = con->next) > ! { > ! if( strcmp(connection_name, con->name) == 0 ) > ! break; > ! } > ! ret = con; > ! } > ! > ! #ifdef USE_THREADS > ! pthread_mutex_unlock(&connections_mutex); > ! #endif > > ! return( ret ); > } > > static void > *************** > *** 37,42 **** > --- 61,70 ---- > ECPGlog("ecpg_finish: finishing %s.\n", act->name); > PQfinish(act->connection); > > + /* no need to lock connections_mutex - we're always called > + by ECPGdisconnect or ECPGconnect, which are holding > + the lock */ > + > /* remove act from the list */ > if (act == all_connections) > all_connections = act->next; > *************** > *** 118,134 **** > static void > ECPGnoticeProcessor_raise(int code, const char *message) > { > ! sqlca.sqlcode = code; > ! strncpy(sqlca.sqlerrm.sqlerrmc, message, sizeof(sqlca.sqlerrm.sqlerrmc)); > ! sqlca.sqlerrm.sqlerrmc[sizeof(sqlca.sqlerrm.sqlerrmc) - 1] = 0; > ! sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc); > > /* remove trailing newline */ > ! if (sqlca.sqlerrm.sqlerrml > ! && sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml - 1] == '\n') > { > ! sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml - 1] = 0; > ! sqlca.sqlerrm.sqlerrml--; > } > > ECPGlog("raising sqlcode %d\n", code); > --- 146,163 ---- > static void > ECPGnoticeProcessor_raise(int code, const char *message) > { > ! struct sqlca_t *sqlca = ECPGget_sqlca(); > ! sqlca->sqlcode = code; > ! strncpy(sqlca->sqlerrm.sqlerrmc, message, sizeof(sqlca->sqlerrm.sqlerrmc)); > ! sqlca->sqlerrm.sqlerrmc[sizeof(sqlca->sqlerrm.sqlerrmc) - 1] = 0; > ! sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc); > > /* remove trailing newline */ > ! if (sqlca->sqlerrm.sqlerrml > ! && sqlca->sqlerrm.sqlerrmc[sqlca->sqlerrm.sqlerrml - 1] == '\n') > { > ! sqlca->sqlerrm.sqlerrmc[sqlca->sqlerrm.sqlerrml - 1] = 0; > ! sqlca->sqlerrm.sqlerrml--; > } > > ECPGlog("raising sqlcode %d\n", code); > *************** > *** 141,146 **** > --- 170,177 ---- > static void > ECPGnoticeProcessor(void *arg, const char *message) > { > + struct sqlca_t *sqlca = ECPGget_sqlca(); > + > /* these notices raise an error */ > if (strncmp(message, "WARNING: ", 9)) > { > *************** > *** 245,251 **** > if (strstr(message, "cannot be rolled back")) > return; > > ! /* these and other unmentioned should set sqlca.sqlwarn[2] */ > /* WARNING: The ':' operator is deprecated. Use exp(x) instead. */ > /* WARNING: Rel *: Uninitialized page 0 - fixing */ > /* WARNING: PortalHeapMemoryFree: * not in alloc set! */ > --- 276,282 ---- > if (strstr(message, "cannot be rolled back")) > return; > > ! /* these and other unmentioned should set sqlca->sqlwarn[2] */ > /* WARNING: The ':' operator is deprecated. Use exp(x) instead. */ > /* WARNING: Rel *: Uninitialized page 0 - fixing */ > /* WARNING: PortalHeapMemoryFree: * not in alloc set! */ > *************** > *** 253,266 **** > /* WARNING: identifier "*" will be truncated to "*" */ > /* WARNING: InvalidateSharedInvalid: cache state reset */ > /* WARNING: RegisterSharedInvalid: SI buffer overflow */ > ! sqlca.sqlwarn[2] = 'W'; > ! sqlca.sqlwarn[0] = 'W'; > } > > /* this contains some quick hacks, needs to be cleaned up, but it works */ > bool > ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit) > { > struct connection *this; > char *dbname = strdup(name), > *host = NULL, > --- 284,298 ---- > /* WARNING: identifier "*" will be truncated to "*" */ > /* WARNING: InvalidateSharedInvalid: cache state reset */ > /* WARNING: RegisterSharedInvalid: SI buffer overflow */ > ! sqlca->sqlwarn[2] = 'W'; > ! sqlca->sqlwarn[0] = 'W'; > } > > /* this contains some quick hacks, needs to be cleaned up, but it works */ > bool > ECPGconnect(int lineno, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit) > { > + struct sqlca_t *sqlca = ECPGget_sqlca(); > struct connection *this; > char *dbname = strdup(name), > *host = NULL, > *************** > *** 269,275 **** > *realname = NULL, > *options = NULL; > > ! ECPGinit_sqlca(); > > if ((this = (struct connection *) ECPGalloc(sizeof(struct connection), lineno)) == NULL) > return false; > --- 301,307 ---- > *realname = NULL, > *options = NULL; > > ! ECPGinit_sqlca(sqlca); > > if ((this = (struct connection *) ECPGalloc(sizeof(struct connection), lineno)) == NULL) > return false; > *************** > *** 394,399 **** > --- 426,434 ---- > realname = strdup(dbname); > > /* add connection to our list */ > + #ifdef USE_THREADS > + pthread_mutex_lock(&connections_mutex); > + #endif > if (connection_name != NULL) > this->name = ECPGstrdup(connection_name, lineno); > else > *************** > *** 424,429 **** > --- 459,467 ---- > > set_backend_err(errmsg, lineno); > ecpg_finish(this); > + #ifdef USE_THREADS > + pthread_mutex_unlock(&connections_mutex); > + #endif > ECPGlog("connect: could not open database %s on %s port %s %s%s%s%s in line %d\n\t%s\n", > db, > host ? host : "<DEFAULT>", > *************** > *** 445,450 **** > --- 483,491 ---- > ECPGfree(dbname); > return false; > } > + #ifdef USE_THREADS > + pthread_mutex_unlock(&connections_mutex); > + #endif > > if (host) > ECPGfree(host); > *************** > *** 468,478 **** > bool > ECPGdisconnect(int lineno, const char *connection_name) > { > struct connection *con; > > if (strcmp(connection_name, "ALL") == 0) > { > ! ECPGinit_sqlca(); > for (con = all_connections; con;) > { > struct connection *f = con; > --- 509,524 ---- > bool > ECPGdisconnect(int lineno, const char *connection_name) > { > + struct sqlca_t *sqlca = ECPGget_sqlca(); > struct connection *con; > > + #ifdef USE_THREADS > + pthread_mutex_lock(&connections_mutex); > + #endif > + > if (strcmp(connection_name, "ALL") == 0) > { > ! ECPGinit_sqlca(sqlca); > for (con = all_connections; con;) > { > struct connection *f = con; > *************** > *** 486,495 **** > con = ECPGget_connection(connection_name); > > if (!ECPGinit(con, connection_name, lineno)) > ! return (false); > else > ! ecpg_finish(con); > } > > return true; > } > --- 532,550 ---- > con = ECPGget_connection(connection_name); > > if (!ECPGinit(con, connection_name, lineno)) > ! { > ! #ifdef USE_THREADS > ! pthread_mutex_unlock(&connections_mutex); > ! #endif > ! return (false); > ! } > else > ! ecpg_finish(con); > } > + > + #ifdef USE_THREADS > + pthread_mutex_unlock(&connections_mutex); > + #endif > > return true; > } > Index: src/interfaces/ecpg/ecpglib/data.c > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/data.c,v > retrieving revision 1.4 > diff -c -c -r1.4 data.c > *** src/interfaces/ecpg/ecpglib/data.c 1 Apr 2003 14:37:25 -0000 1.4 > --- src/interfaces/ecpg/ecpglib/data.c 15 Jun 2003 04:03:01 -0000 > *************** > *** 1,5 **** > --- 1,6 ---- > /* $Header: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/data.c,v 1.4 2003/04/01 14:37:25 meskes Exp $ */ > > + #define POSTGRES_ECPG_INTERNAL > #include "postgres_fe.h" > > #include <stdlib.h> > *************** > *** 21,26 **** > --- 22,28 ---- > char *var, char *ind, long varcharsize, long offset, > long ind_offset, bool isarray) > { > + struct sqlca_t *sqlca = ECPGget_sqlca(); > char *pval = (char *) PQgetvalue(results, act_tuple, act_field); > > ECPGlog("ECPGget_data line %d: RESULT: %s offset: %ld\n", lineno, pval ? pval : "", offset); > *************** > *** 328,334 **** > default: > break; > } > ! sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W'; > } > } > break; > --- 330,336 ---- > default: > break; > } > ! sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W'; > } > } > break; > *************** > *** 373,379 **** > default: > break; > } > ! sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W'; > > variable->len = varcharsize; > } > --- 375,381 ---- > default: > break; > } > ! sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W'; > > variable->len = varcharsize; > } > Index: src/interfaces/ecpg/ecpglib/descriptor.c > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/descriptor.c,v > retrieving revision 1.2 > diff -c -c -r1.2 descriptor.c > *** src/interfaces/ecpg/ecpglib/descriptor.c 30 May 2003 13:22:02 -0000 1.2 > --- src/interfaces/ecpg/ecpglib/descriptor.c 15 Jun 2003 04:03:02 -0000 > *************** > *** 3,8 **** > --- 3,9 ---- > * $Header: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.2 2003/05/30 13:22:02 meskes Exp $ > */ > > + #define POSTGRES_ECPG_INTERNAL > #include "postgres_fe.h" > #include "pg_type.h" > > *************** > *** 51,64 **** > ECPGget_desc_header(int lineno, char *desc_name, int *count) > { > PGresult *ECPGresult; > > ! ECPGinit_sqlca(); > ECPGresult = ECPGresultByDescriptor(lineno, desc_name); > if (!ECPGresult) > return false; > > *count = PQnfields(ECPGresult); > ! sqlca.sqlerrd[2] = 1; > ECPGlog("ECPGget_desc_header: found %d attributes.\n", *count); > return true; > } > --- 52,66 ---- > ECPGget_desc_header(int lineno, char *desc_name, int *count) > { > PGresult *ECPGresult; > + struct sqlca_t *sqlca = ECPGget_sqlca(); > > ! ECPGinit_sqlca(sqlca); > ECPGresult = ECPGresultByDescriptor(lineno, desc_name); > if (!ECPGresult) > return false; > > *count = PQnfields(ECPGresult); > ! sqlca->sqlerrd[2] = 1; > ECPGlog("ECPGget_desc_header: found %d attributes.\n", *count); > return true; > } > *************** > *** 149,157 **** > int ntuples, > act_tuple; > struct variable data_var; > > va_start(args, index); > ! ECPGinit_sqlca(); > ECPGresult = ECPGresultByDescriptor(lineno, desc_name); > if (!ECPGresult) > return (false); > --- 151,160 ---- > int ntuples, > act_tuple; > struct variable data_var; > + struct sqlca_t *sqlca = ECPGget_sqlca(); > > va_start(args, index); > ! ECPGinit_sqlca(sqlca); > ECPGresult = ECPGresultByDescriptor(lineno, desc_name); > if (!ECPGresult) > return (false); > *************** > *** 378,384 **** > ECPGlog("ECPGget_desc: INDICATOR[%d] = %d\n", act_tuple, -PQgetisnull(ECPGresult, act_tuple, index)); > } > } > ! sqlca.sqlerrd[2] = ntuples; > return (true); > } > > --- 381,387 ---- > ECPGlog("ECPGget_desc: INDICATOR[%d] = %d\n", act_tuple, -PQgetisnull(ECPGresult, act_tuple, index)); > } > } > ! sqlca->sqlerrd[2] = ntuples; > return (true); > } > > *************** > *** 387,394 **** > { > struct descriptor *i; > struct descriptor **lastptr = &all_descriptors; > > ! ECPGinit_sqlca(); > for (i = all_descriptors; i; lastptr = &i->next, i = i->next) > { > if (!strcmp(name, i->name)) > --- 390,398 ---- > { > struct descriptor *i; > struct descriptor **lastptr = &all_descriptors; > + struct sqlca_t *sqlca = ECPGget_sqlca(); > > ! ECPGinit_sqlca(sqlca); > for (i = all_descriptors; i; lastptr = &i->next, i = i->next) > { > if (!strcmp(name, i->name)) > *************** > *** 408,415 **** > ECPGallocate_desc(int line, const char *name) > { > struct descriptor *new; > > ! ECPGinit_sqlca(); > new = (struct descriptor *) ECPGalloc(sizeof(struct descriptor), line); > if (!new) > return false; > --- 412,420 ---- > ECPGallocate_desc(int line, const char *name) > { > struct descriptor *new; > + struct sqlca_t *sqlca = ECPGget_sqlca(); > > ! ECPGinit_sqlca(sqlca); > new = (struct descriptor *) ECPGalloc(sizeof(struct descriptor), line); > if (!new) > return false; > Index: src/interfaces/ecpg/ecpglib/error.c > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/error.c,v > retrieving revision 1.1 > diff -c -c -r1.1 error.c > *** src/interfaces/ecpg/ecpglib/error.c 16 Mar 2003 10:42:53 -0000 1.1 > --- src/interfaces/ecpg/ecpglib/error.c 15 Jun 2003 04:03:02 -0000 > *************** > *** 1,5 **** > --- 1,6 ---- > /* $Header: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/error.c,v 1.1 2003/03/16 10:42:53 meskes Exp $ */ > > + #define POSTGRES_ECPG_INTERNAL > #include "postgres_fe.h" > > #include <stdio.h> > *************** > *** 17,133 **** > void > ECPGraise(int line, int code, const char *str) > { > ! sqlca.sqlcode = code; > > switch (code) > { > case ECPG_NOT_FOUND: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "No data found in line %d.", line); > break; > > case ECPG_OUT_OF_MEMORY: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Out of memory in line %d.", line); > break; > > case ECPG_UNSUPPORTED: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Unsupported type %s in line %d.", str, line); > break; > > case ECPG_TOO_MANY_ARGUMENTS: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Too many arguments in line %d.", line); > break; > > case ECPG_TOO_FEW_ARGUMENTS: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Too few arguments in line %d.", line); > break; > > case ECPG_INT_FORMAT: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Not correctly formatted int type: %s line %d.", str, line); > break; > > case ECPG_UINT_FORMAT: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Not correctly formatted unsigned type: %s in line %d.", str, line); > break; > > case ECPG_FLOAT_FORMAT: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Not correctly formatted floating-point type: %s in line %d.", str, line); > break; > > case ECPG_CONVERT_BOOL: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Unable to convert %s to bool on line %d.", str, line); > break; > > case ECPG_EMPTY: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Empty query in line %d.", line); > break; > > case ECPG_MISSING_INDICATOR: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "NULL value without indicator in line %d.", line); > break; > > case ECPG_NO_ARRAY: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Variable is not an array in line %d.", line); > break; > > case ECPG_DATA_NOT_ARRAY: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Data read from backend is not an array in line %d.", line); > break; > > case ECPG_ARRAY_INSERT: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Trying to insert an array of variables in line %d.", line); > break; > > case ECPG_NO_CONN: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "No such connection %s in line %d.", str, line); > break; > > case ECPG_NOT_CONN: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Not connected to '%s' in line %d.", str, line); > break; > > case ECPG_INVALID_STMT: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Invalid statement name %s in line %d.", str, line); > break; > > case ECPG_UNKNOWN_DESCRIPTOR: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Descriptor %s not found in line %d.", str, line); > break; > > case ECPG_INVALID_DESCRIPTOR_INDEX: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Descriptor index out of range in line %d.", line); > break; > > case ECPG_UNKNOWN_DESCRIPTOR_ITEM: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Unknown descriptor item %s in line %d.", str, line); > break; > > case ECPG_VAR_NOT_NUMERIC: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Variable is not a numeric type in line %d.", line); > break; > > case ECPG_VAR_NOT_CHAR: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Variable is not a character type in line %d.", line); > break; > > --- 18,135 ---- > void > ECPGraise(int line, int code, const char *str) > { > ! struct sqlca_t *sqlca = ECPGget_sqlca(); > ! sqlca->sqlcode = code; > > switch (code) > { > case ECPG_NOT_FOUND: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "No data found in line %d.", line); > break; > > case ECPG_OUT_OF_MEMORY: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Out of memory in line %d.", line); > break; > > case ECPG_UNSUPPORTED: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Unsupported type %s in line %d.", str, line); > break; > > case ECPG_TOO_MANY_ARGUMENTS: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Too many arguments in line %d.", line); > break; > > case ECPG_TOO_FEW_ARGUMENTS: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Too few arguments in line %d.", line); > break; > > case ECPG_INT_FORMAT: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Not correctly formatted int type: %s line %d.", str, line); > break; > > case ECPG_UINT_FORMAT: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Not correctly formatted unsigned type: %s in line %d.", str, line); > break; > > case ECPG_FLOAT_FORMAT: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Not correctly formatted floating-point type: %s in line %d.", str, line); > break; > > case ECPG_CONVERT_BOOL: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Unable to convert %s to bool on line %d.", str, line); > break; > > case ECPG_EMPTY: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Empty query in line %d.", line); > break; > > case ECPG_MISSING_INDICATOR: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "NULL value without indicator in line %d.", line); > break; > > case ECPG_NO_ARRAY: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Variable is not an array in line %d.", line); > break; > > case ECPG_DATA_NOT_ARRAY: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Data read from backend is not an array in line %d.", line); > break; > > case ECPG_ARRAY_INSERT: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Trying to insert an array of variables in line %d.", line); > break; > > case ECPG_NO_CONN: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "No such connection %s in line %d.", str, line); > break; > > case ECPG_NOT_CONN: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Not connected to '%s' in line %d.", str, line); > break; > > case ECPG_INVALID_STMT: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Invalid statement name %s in line %d.", str, line); > break; > > case ECPG_UNKNOWN_DESCRIPTOR: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Descriptor %s not found in line %d.", str, line); > break; > > case ECPG_INVALID_DESCRIPTOR_INDEX: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Descriptor index out of range in line %d.", line); > break; > > case ECPG_UNKNOWN_DESCRIPTOR_ITEM: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Unknown descriptor item %s in line %d.", str, line); > break; > > case ECPG_VAR_NOT_NUMERIC: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Variable is not a numeric type in line %d.", line); > break; > > case ECPG_VAR_NOT_CHAR: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Variable is not a character type in line %d.", line); > break; > > *************** > *** 138,166 **** > /* strip trailing newline */ > if (slen > 0 && str[slen - 1] == '\n') > slen--; > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "'%.*s' in line %d.", slen, str, line); > break; > } > > case ECPG_TRANS: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Error in transaction processing in line %d.", line); > break; > > case ECPG_CONNECT: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "Could not connect to database %s in line %d.", str, line); > break; > > default: > ! snprintf(sqlca.sqlerrm.sqlerrmc, sizeof(sqlca.sqlerrm.sqlerrmc), > "SQL error #%d in line %d.", code, line); > break; > } > > ! sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc); > ! ECPGlog("raising sqlcode %d in line %d, '%s'.\n", code, line, sqlca.sqlerrm.sqlerrmc); > > /* free all memory we have allocated for the user */ > ECPGfree_auto_mem(); > --- 140,168 ---- > /* strip trailing newline */ > if (slen > 0 && str[slen - 1] == '\n') > slen--; > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "'%.*s' in line %d.", slen, str, line); > break; > } > > case ECPG_TRANS: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Error in transaction processing in line %d.", line); > break; > > case ECPG_CONNECT: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "Could not connect to database %s in line %d.", str, line); > break; > > default: > ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), > "SQL error #%d in line %d.", code, line); > break; > } > > ! sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc); > ! ECPGlog("raising sqlcode %d in line %d, '%s'.\n", code, line, sqlca->sqlerrm.sqlerrmc); > > /* free all memory we have allocated for the user */ > ECPGfree_auto_mem(); > *************** > *** 193,198 **** > void > sqlprint(void) > { > ! sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0'; > ! fprintf(stderr, "sql error %s\n", sqlca.sqlerrm.sqlerrmc); > } > --- 195,202 ---- > void > sqlprint(void) > { > ! struct sqlca_t *sqlca = ECPGget_sqlca(); > ! > ! sqlca->sqlerrm.sqlerrmc[sqlca->sqlerrm.sqlerrml] = '\0'; > ! fprintf(stderr, "sql error %s\n", sqlca->sqlerrm.sqlerrmc); > } > Index: src/interfaces/ecpg/ecpglib/execute.c > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/execute.c,v > retrieving revision 1.9 > diff -c -c -r1.9 execute.c > *** src/interfaces/ecpg/ecpglib/execute.c 13 Jun 2003 10:50:57 -0000 1.9 > --- src/interfaces/ecpg/ecpglib/execute.c 15 Jun 2003 04:03:02 -0000 > *************** > *** 13,18 **** > --- 13,19 ---- > /* Taken over as part of PostgreSQL by Michael Meskes <meskes@postgresql.org> > on Feb. 5th, 1998 */ > > + #define POSTGRES_ECPG_INTERNAL > #include "postgres_fe.h" > > #include <stdio.h> > *************** > *** 31,64 **** > #include "pgtypes_timestamp.h" > #include "pgtypes_interval.h" > > - /* variables visible to the programs */ > - struct sqlca sqlca = > - { > - { > - 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' ' > - }, > - sizeof(struct sqlca), > - 0, > - { > - 0, > - { > - 0 > - } > - }, > - { > - 'N', 'O', 'T', ' ', 'S', 'E', 'T', ' ' > - }, > - { > - 0, 0, 0, 0, 0, 0 > - }, > - { > - 0, 0, 0, 0, 0, 0, 0, 0 > - }, > - { > - 0, 0, 0, 0, 0, 0, 0, 0 > - } > - }; > - > /* This function returns a newly malloced string that has the \ > in the argument quoted with \ and the ' quoted with ' as SQL92 says. > */ > --- 32,37 ---- > *************** > *** 1130,1135 **** > --- 1103,1110 ---- > */ > { > bool clear_result = TRUE; > + struct sqlca_t *sqlca = ECPGget_sqlca(); > + > errmsg = PQresultErrorMessage(results); > set_backend_err(errmsg, stmt->lineno); > > *************** > *** 1142,1148 **** > > case PGRES_TUPLES_OK: > nfields = PQnfields(results); > ! sqlca.sqlerrd[2] = ntuples = PQntuples(results); > status = true; > > if (ntuples < 1) > --- 1117,1123 ---- > > case PGRES_TUPLES_OK: > nfields = PQnfields(results); > ! sqlca->sqlerrd[2] = ntuples = PQntuples(results); > status = true; > > if (ntuples < 1) > *************** > *** 1199,1208 **** > case PGRES_COMMAND_OK: > status = true; > cmdstat = PQcmdStatus(results); > ! sqlca.sqlerrd[1] = PQoidValue(results); > ! sqlca.sqlerrd[2] = atol(PQcmdTuples(results)); > ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, cmdstat); > ! if (!sqlca.sqlerrd[2] && ( !strncmp(cmdstat, "UPDATE", 6) > || !strncmp(cmdstat, "INSERT", 6) > || !strncmp(cmdstat, "DELETE", 6))) > ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL); > --- 1174,1183 ---- > case PGRES_COMMAND_OK: > status = true; > cmdstat = PQcmdStatus(results); > ! sqlca->sqlerrd[1] = PQoidValue(results); > ! sqlca->sqlerrd[2] = atol(PQcmdTuples(results)); > ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, cmdstat); > ! if (!sqlca->sqlerrd[2] && ( !strncmp(cmdstat, "UPDATE", 6) > || !strncmp(cmdstat, "INSERT", 6) > || !strncmp(cmdstat, "DELETE", 6))) > ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL); > Index: src/interfaces/ecpg/ecpglib/extern.h > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/extern.h,v > retrieving revision 1.1 > diff -c -c -r1.1 extern.h > *** src/interfaces/ecpg/ecpglib/extern.h 16 Mar 2003 10:42:53 -0000 1.1 > --- src/interfaces/ecpg/ecpglib/extern.h 15 Jun 2003 04:03:02 -0000 > *************** > *** 3,8 **** > --- 3,9 ---- > > #include "postgres_fe.h" > #include "libpq-fe.h" > + #include "sqlca.h" > > /* Here are some methods used by the lib. */ > > *************** > *** 19,25 **** > bool ECPGget_data(const PGresult *, int, int, int, enum ECPGttype type, > enum ECPGttype, char *, char *, long, long, long, bool); > struct connection *ECPGget_connection(const char *); > - void ECPGinit_sqlca(void); > char *ECPGalloc(long, int); > char *ECPGrealloc(void *, long, int); > void ECPGfree(void *); > --- 20,25 ---- > Index: src/interfaces/ecpg/ecpglib/memory.c > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/memory.c,v > retrieving revision 1.1 > diff -c -c -r1.1 memory.c > *** src/interfaces/ecpg/ecpglib/memory.c 16 Mar 2003 10:42:53 -0000 1.1 > --- src/interfaces/ecpg/ecpglib/memory.c 15 Jun 2003 04:03:02 -0000 > *************** > *** 1,5 **** > --- 1,6 ---- > /* $Header: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/memory.c,v 1.1 2003/03/16 10:42:53 meskes Exp $ */ > > + #define POSTGRES_ECPG_INTERNAL > #include "postgres_fe.h" > > #include "ecpgtype.h" > Index: src/interfaces/ecpg/ecpglib/misc.c > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/misc.c,v > retrieving revision 1.2 > diff -c -c -r1.2 misc.c > *** src/interfaces/ecpg/ecpglib/misc.c 21 Mar 2003 15:31:04 -0000 1.2 > --- src/interfaces/ecpg/ecpglib/misc.c 15 Jun 2003 04:03:03 -0000 > *************** > *** 1,20 **** > /* $Header: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/misc.c,v 1.2 2003/03/21 15:31:04 meskes Exp $ */ > > #include "postgres_fe.h" > > #include <unistd.h> > #include "ecpgtype.h" > #include "ecpglib.h" > #include "ecpgerrno.h" > #include "extern.h" > #include "sqlca.h" > > ! static struct sqlca sqlca_init = > { > { > 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' ' > }, > ! sizeof(struct sqlca), > 0, > { > 0, > --- 1,24 ---- > /* $Header: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/misc.c,v 1.2 2003/03/21 15:31:04 meskes Exp $ */ > > + #define POSTGRES_ECPG_INTERNAL > #include "postgres_fe.h" > > #include <unistd.h> > + #ifdef USE_THREADS > + #include <pthread.h> > + #endif > #include "ecpgtype.h" > #include "ecpglib.h" > #include "ecpgerrno.h" > #include "extern.h" > #include "sqlca.h" > > ! static struct sqlca_t sqlca_init = > { > { > 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' ' > }, > ! sizeof(struct sqlca_t), > 0, > { > 0, > *************** > *** 36,54 **** > } > }; > > ! static int simple_debug = 0; > static FILE *debugstream = NULL; > > ! void > ! ECPGinit_sqlca(void) > { > ! memcpy((char *) &sqlca, (char *) &sqlca_init, sizeof(sqlca)); > } > > bool > ECPGinit(const struct connection * con, const char *connection_name, const int lineno) > { > ! ECPGinit_sqlca(); > if (con == NULL) > { > ECPGraise(lineno, ECPG_NO_CONN, connection_name ? connection_name : "NULL"); > --- 40,93 ---- > } > }; > > ! #ifdef USE_THREADS > ! static pthread_key_t sqlca_key; > ! static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT; > ! #else > ! static struct sqlca_t sqlca = > ! { > ! { > ! 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' ' > ! }, > ! sizeof(struct sqlca_t), > ! 0, > ! { > ! 0, > ! { > ! 0 > ! } > ! }, > ! { > ! 'N', 'O', 'T', ' ', 'S', 'E', 'T', ' ' > ! }, > ! { > ! 0, 0, 0, 0, 0, 0 > ! }, > ! { > ! 0, 0, 0, 0, 0, 0, 0, 0 > ! }, > ! { > ! 0, 0, 0, 0, 0, 0, 0, 0 > ! } > ! }; > ! #endif > ! > ! #ifdef USE_THREADS > ! static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER; > ! #endif > ! static int simple_debug = 0; > static FILE *debugstream = NULL; > > ! void ECPGinit_sqlca(struct sqlca_t *sqlca) > { > ! memcpy((char *)sqlca, (char *)&sqlca_init, sizeof(struct sqlca_t)); > } > > bool > ECPGinit(const struct connection * con, const char *connection_name, const int lineno) > { > ! struct sqlca_t *sqlca = ECPGget_sqlca(); > ! ECPGinit_sqlca(sqlca); > if (con == NULL) > { > ECPGraise(lineno, ECPG_NO_CONN, connection_name ? connection_name : "NULL"); > *************** > *** 58,63 **** > --- 97,129 ---- > return (true); > } > > + #ifdef USE_THREADS > + static void ecpg_sqlca_key_init(void) > + { > + pthread_key_create(&sqlca_key, NULL); > + } > + #endif > + > + struct sqlca_t *ECPGget_sqlca(void) > + { > + #ifdef USE_THREADS > + struct sqlca_t *sqlca; > + > + pthread_once(&sqlca_key_once, ecpg_sqlca_key_init); > + > + sqlca = pthread_getspecific(&sqlca_key); > + if( sqlca == NULL ) > + { > + sqlca = malloc(sizeof(struct sqlca_t)); > + ECPGinit_sqlca(sqlca); > + pthread_setspecific(&sqlca_key, sqlca); > + } > + return( sqlca ); > + #else > + return( &sqlca ); > + #endif > + } > + > bool > ECPGstatus(int lineno, const char *connection_name) > { > *************** > *** 123,131 **** > --- 189,205 ---- > void > ECPGdebug(int n, FILE *dbgs) > { > + #ifdef USE_THREADS > + pthread_mutex_lock(&debug_mutex); > + #endif > + > simple_debug = n; > debugstream = dbgs; > ECPGlog("ECPGdebug: set to %d\n", simple_debug); > + > + #ifdef USE_THREADS > + pthread_mutex_unlock(&debug_mutex); > + #endif > } > > void > *************** > *** 133,144 **** > { > va_list ap; > > ! if (simple_debug) > ! { > ! char *f = (char *) malloc(strlen(format) + 100); > > ! if (!f) > return; > > sprintf(f, "[%d]: %s", (int) getpid(), format); > > --- 207,226 ---- > { > va_list ap; > > ! #ifdef USE_THREADS > ! pthread_mutex_lock(&debug_mutex); > ! #endif > > ! if( simple_debug ) > ! { > ! char *f = (char *)malloc(strlen(format) + 100); > ! if( f == NULL ) > ! { > ! #ifdef USE_THREADS > ! pthread_mutex_unlock(&debug_mutex); > ! #endif > return; > + } > > sprintf(f, "[%d]: %s", (int) getpid(), format); > > *************** > *** 148,151 **** > --- 230,237 ---- > > ECPGfree(f); > } > + > + #ifdef USE_THREADS > + pthread_mutex_unlock(&debug_mutex); > + #endif > } > Index: src/interfaces/ecpg/ecpglib/prepare.c > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/prepare.c,v > retrieving revision 1.1 > diff -c -c -r1.1 prepare.c > *** src/interfaces/ecpg/ecpglib/prepare.c 16 Mar 2003 10:42:53 -0000 1.1 > --- src/interfaces/ecpg/ecpglib/prepare.c 15 Jun 2003 04:03:03 -0000 > *************** > *** 1,5 **** > --- 1,6 ---- > /* $Header: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/prepare.c,v 1.1 2003/03/16 10:42:53 meskes Exp $ */ > > + #define POSTGRES_ECPG_INTERNAL > #include "postgres_fe.h" > > #include <ctype.h> > Index: src/interfaces/ecpg/ecpglib/typename.c > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/typename.c,v > retrieving revision 1.3 > diff -c -c -r1.3 typename.c > *** src/interfaces/ecpg/ecpglib/typename.c 27 Mar 2003 14:29:17 -0000 1.3 > --- src/interfaces/ecpg/ecpglib/typename.c 15 Jun 2003 04:03:03 -0000 > *************** > *** 1,5 **** > --- 1,6 ---- > /* $Header: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/typename.c,v 1.3 2003/03/27 14:29:17 meskes Exp $ */ > > + #define POSTGRES_ECPG_INTERNAL > #include "postgres_fe.h" > > #include <stdlib.h> > Index: src/interfaces/ecpg/include/sqlca.h > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/include/sqlca.h,v > retrieving revision 1.23 > diff -c -c -r1.23 sqlca.h > *** src/interfaces/ecpg/include/sqlca.h 18 Apr 2003 01:03:42 -0000 1.23 > --- src/interfaces/ecpg/include/sqlca.h 15 Jun 2003 04:03:03 -0000 > *************** > *** 16,22 **** > { > #endif > > ! struct sqlca > { > char sqlcaid[8]; > long sqlabc; > --- 16,22 ---- > { > #endif > > ! struct sqlca_t > { > char sqlcaid[8]; > long sqlabc; > *************** > *** 53,60 **** > char sqlext[8]; > }; > > ! extern DLLIMPORT struct sqlca sqlca; > > > #ifdef __cplusplus > } > --- 53,63 ---- > char sqlext[8]; > }; > > ! struct sqlca_t *ECPGget_sqlca(void); > > + #ifndef POSTGRES_ECPG_INTERNAL > + # define sqlca (*ECPGget_sqlca()) > + #endif > > #ifdef __cplusplus > } > Index: src/interfaces/ecpg/preproc/Makefile > =================================================================== > RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/preproc/Makefile,v > retrieving revision 1.91 > diff -c -c -r1.91 Makefile > *** src/interfaces/ecpg/preproc/Makefile 18 Mar 2003 10:46:39 -0000 1.91 > --- src/interfaces/ecpg/preproc/Makefile 15 Jun 2003 04:03:03 -0000 > *************** > *** 4,11 **** > top_builddir = ../../../.. > include $(top_builddir)/src/Makefile.global > > ! MAJOR_VERSION=2 > ! MINOR_VERSION=12 > PATCHLEVEL=0 > > override CPPFLAGS := -I$(srcdir)/../include -I$(srcdir) $(CPPFLAGS) \ > --- 4,11 ---- > top_builddir = ../../../.. > include $(top_builddir)/src/Makefile.global > > ! MAJOR_VERSION=3 > ! MINOR_VERSION=0 > PATCHLEVEL=0 > > override CPPFLAGS := -I$(srcdir)/../include -I$(srcdir) $(CPPFLAGS) \ -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 Index: src/interfaces/ecpg/ecpglib/misc.c =================================================================== RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/misc.c,v retrieving revision 1.3 diff -c -c -r1.3 misc.c *** src/interfaces/ecpg/ecpglib/misc.c 15 Jun 2003 04:07:58 -0000 1.3 --- src/interfaces/ecpg/ecpglib/misc.c 15 Jun 2003 04:46:37 -0000 *************** *** 78,84 **** static int simple_debug = 0; static FILE *debugstream = NULL; ! void ECPGinit_sqlca(struct sqlca_t *sqlca) { memcpy((char *)sqlca, (char *)&sqlca_init, sizeof(struct sqlca_t)); } --- 78,85 ---- static int simple_debug = 0; static FILE *debugstream = NULL; ! void ! ECPGinit_sqlca(struct sqlca_t *sqlca) { memcpy((char *)sqlca, (char *)&sqlca_init, sizeof(struct sqlca_t)); } *************** *** 98,122 **** } #ifdef USE_THREADS ! static void ecpg_sqlca_key_init(void) { pthread_key_create(&sqlca_key, NULL); } #endif ! struct sqlca_t *ECPGget_sqlca(void) { #ifdef USE_THREADS struct sqlca_t *sqlca; pthread_once(&sqlca_key_once, ecpg_sqlca_key_init); ! sqlca = pthread_getspecific(&sqlca_key); if( sqlca == NULL ) { sqlca = malloc(sizeof(struct sqlca_t)); ECPGinit_sqlca(sqlca); ! pthread_setspecific(&sqlca_key, sqlca); } return( sqlca ); #else --- 99,125 ---- } #ifdef USE_THREADS ! static void ! ecpg_sqlca_key_init(void) { pthread_key_create(&sqlca_key, NULL); } #endif ! struct sqlca_t * ! ECPGget_sqlca(void) { #ifdef USE_THREADS struct sqlca_t *sqlca; pthread_once(&sqlca_key_once, ecpg_sqlca_key_init); ! sqlca = pthread_getspecific(sqlca_key); if( sqlca == NULL ) { sqlca = malloc(sizeof(struct sqlca_t)); ECPGinit_sqlca(sqlca); ! pthread_setspecific(sqlca_key, sqlca); } return( sqlca ); #else Index: src/interfaces/ecpg/include/ecpglib.h =================================================================== RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/include/ecpglib.h,v retrieving revision 1.49 diff -c -c -r1.49 ecpglib.h *** src/interfaces/ecpg/include/ecpglib.h 13 Jun 2003 10:50:57 -0000 1.49 --- src/interfaces/ecpg/include/ecpglib.h 15 Jun 2003 04:46:37 -0000 *************** *** 38,43 **** --- 38,46 ---- { #endif + struct sqlca_t; + + void ECPGinit_sqlca(struct sqlca_t *sqlca); void ECPGdebug(int, FILE *); bool ECPGstatus(int, const char *); bool ECPGsetcommit(int, const char *, const char *); *************** *** 49,58 **** bool ECPGprepare(int, char *, char *); bool ECPGdeallocate(int, char *); bool ECPGdeallocate_all(int); ! char *ECPGprepared_statement(char *); void ECPGlog(const char *format,...); ! char *ECPGerrmsg(void); /* print an error message */ void sqlprint(void); --- 52,61 ---- bool ECPGprepare(int, char *, char *); bool ECPGdeallocate(int, char *); bool ECPGdeallocate_all(int); ! char *ECPGprepared_statement(char *); void ECPGlog(const char *format,...); ! char *ECPGerrmsg(void); /* print an error message */ void sqlprint(void);
pgsql-patches by date: