1 /* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.23 2004/10/09 02:46:42 momjian Exp $ */
3 #define POSTGRES_ECPG_INTERNAL
4 #include "postgres_fe.h"
8 #ifdef ENABLE_THREAD_SAFETY
13 #include "ecpgerrno.h"
16 #include "pgtypes_numeric.h"
17 #include "pgtypes_date.h"
18 #include "pgtypes_timestamp.h"
19 #include "pgtypes_interval.h"
21 #ifdef HAVE_LONG_LONG_INT_64
24 #define LONG_LONG_MIN LLONG_MIN
26 #define LONG_LONG_MIN LONGLONG_MIN
31 static struct sqlca_t sqlca_init =
34 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
36 sizeof(struct sqlca_t),
45 'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
51 0, 0, 0, 0, 0, 0, 0, 0
54 '0', '0', '0', '0', '0'
58 #ifdef ENABLE_THREAD_SAFETY
59 static pthread_key_t sqlca_key;
60 static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
63 static struct sqlca_t sqlca =
66 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
68 sizeof(struct sqlca_t),
77 'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
83 0, 0, 0, 0, 0, 0, 0, 0
86 '0', '0', '0', '0', '0'
91 #ifdef ENABLE_THREAD_SAFETY
92 static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
93 static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
95 static int simple_debug = 0;
96 static FILE *debugstream = NULL;
99 ECPGinit_sqlca(struct sqlca_t * sqlca)
101 memcpy((char *) sqlca, (char *) &sqlca_init, sizeof(struct sqlca_t));
105 ECPGinit(const struct connection * con, const char *connection_name, const int lineno)
107 struct sqlca_t *sqlca = ECPGget_sqlca();
109 ECPGinit_sqlca(sqlca);
112 ECPGraise(lineno, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
113 connection_name ? connection_name : "NULL");
120 #ifdef ENABLE_THREAD_SAFETY
122 ecpg_sqlca_key_destructor(void *arg)
125 free(arg); /* sqlca structure allocated in
130 ecpg_sqlca_key_init(void)
132 pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor);
139 #ifdef ENABLE_THREAD_SAFETY
140 struct sqlca_t *sqlca;
142 pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
144 sqlca = pthread_getspecific(sqlca_key);
147 sqlca = malloc(sizeof(struct sqlca_t));
148 ECPGinit_sqlca(sqlca);
149 pthread_setspecific(sqlca_key, sqlca);
158 ECPGstatus(int lineno, const char *connection_name)
160 struct connection *con = ECPGget_connection(connection_name);
162 if (!ECPGinit(con, connection_name, lineno))
165 /* are we connected? */
166 if (con->connection == NULL)
168 ECPGraise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, con->name);
176 ECPGtrans(int lineno, const char *connection_name, const char *transaction)
179 struct connection *con = ECPGget_connection(connection_name);
181 if (!ECPGinit(con, connection_name, lineno))
184 ECPGlog("ECPGtrans line %d action = %s connection = %s\n", lineno, transaction, con->name);
186 /* if we have no connection we just simulate the command */
187 if (con && con->connection)
190 * if we are not in autocommit mode, already have committed the
191 * transaction and get another commit, just ignore it
193 if (!con->committed || con->autocommit)
195 if ((res = PQexec(con->connection, transaction)) == NULL)
197 ECPGraise(lineno, ECPG_TRANS, ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN, NULL);
204 if (strcmp(transaction, "commit") == 0 || strcmp(transaction, "rollback") == 0)
206 con->committed = true;
209 /* deallocate all prepared statements */
210 if (!ECPGdeallocate_all(lineno))
220 ECPGdebug(int n, FILE *dbgs)
222 #ifdef ENABLE_THREAD_SAFETY
223 pthread_mutex_lock(&debug_init_mutex);
228 ECPGlog("ECPGdebug: set to %d\n", simple_debug);
230 #ifdef ENABLE_THREAD_SAFETY
231 pthread_mutex_unlock(&debug_init_mutex);
236 ECPGlog(const char *format,...)
240 #ifdef ENABLE_THREAD_SAFETY
241 pthread_mutex_lock(&debug_mutex);
246 char *f = (char *) malloc(strlen(format) + 100);
250 #ifdef ENABLE_THREAD_SAFETY
251 pthread_mutex_unlock(&debug_mutex);
256 sprintf(f, "[%d]: %s", getpid(), format);
258 va_start(ap, format);
259 vfprintf(debugstream, f, ap);
266 #ifdef ENABLE_THREAD_SAFETY
267 pthread_mutex_unlock(&debug_mutex);
272 ECPGset_noind_null(enum ECPGttype type, void *ptr)
277 case ECPGt_unsigned_char:
278 *((char *) ptr) = '\0';
281 case ECPGt_unsigned_short:
282 *((short int *) ptr) = SHRT_MIN;
285 case ECPGt_unsigned_int:
286 *((int *) ptr) = INT_MIN;
289 case ECPGt_unsigned_long:
291 *((long *) ptr) = LONG_MIN;
293 #ifdef HAVE_LONG_LONG_INT_64
294 case ECPGt_long_long:
295 case ECPGt_unsigned_long_long:
296 *((long long *) ptr) = LONG_LONG_MIN;
298 #endif /* HAVE_LONG_LONG_INT_64 */
300 memset((char *) ptr, 0xff, sizeof(float));
303 memset((char *) ptr, 0xff, sizeof(double));
306 *(((struct ECPGgeneric_varchar *) ptr)->arr) = 0x00;
307 ((struct ECPGgeneric_varchar *) ptr)->len = 0;
310 memset((char *) ptr, 0, sizeof(decimal));
311 ((decimal *) ptr)->sign = NUMERIC_NAN;
314 memset((char *) ptr, 0, sizeof(numeric));
315 ((numeric *) ptr)->sign = NUMERIC_NAN;
318 memset((char *) ptr, 0xff, sizeof(interval));
320 case ECPGt_timestamp:
321 memset((char *) ptr, 0xff, sizeof(timestamp));
329 _check(unsigned char *ptr, int length)
331 for (; ptr[--length] == 0xff && length >= 0; length--);
338 ECPGis_noind_null(enum ECPGttype type, void *ptr)
343 case ECPGt_unsigned_char:
344 if (*((char *) ptr) == '\0')
348 case ECPGt_unsigned_short:
349 if (*((short int *) ptr) == SHRT_MIN)
353 case ECPGt_unsigned_int:
354 if (*((int *) ptr) == INT_MIN)
358 case ECPGt_unsigned_long:
360 if (*((long *) ptr) == LONG_MIN)
363 #ifdef HAVE_LONG_LONG_INT_64
364 case ECPGt_long_long:
365 case ECPGt_unsigned_long_long:
366 if (*((long long *) ptr) == LONG_LONG_MIN)
369 #endif /* HAVE_LONG_LONG_INT_64 */
371 return (_check(ptr, sizeof(float)));
374 return (_check(ptr, sizeof(double)));
377 if (*(((struct ECPGgeneric_varchar *) ptr)->arr) == 0x00)
381 if (((decimal *) ptr)->sign == NUMERIC_NAN)
385 if (((numeric *) ptr)->sign == NUMERIC_NAN)
389 return (_check(ptr, sizeof(interval)));
391 case ECPGt_timestamp:
392 return (_check(ptr, sizeof(timestamp)));