1 /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.14 2003/08/08 13:17:58 petere Exp $ */
3 #define POSTGRES_ECPG_INTERNAL
4 #include "postgres_fe.h"
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
23 #define LONG_LONG_MIN LLONG_MIN
27 static struct sqlca_t sqlca_init =
30 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
32 sizeof(struct sqlca_t),
41 'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
47 0, 0, 0, 0, 0, 0, 0, 0
50 '0', '0', '0', '0', '0'
55 static pthread_key_t sqlca_key;
56 static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
59 static struct sqlca_t sqlca =
62 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
64 sizeof(struct sqlca_t),
73 'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
79 0, 0, 0, 0, 0, 0, 0, 0
82 '0', '0', '0', '0', '0'
88 static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
89 static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
91 static int simple_debug = 0;
92 static FILE *debugstream = NULL;
95 ECPGinit_sqlca(struct sqlca_t * sqlca)
97 memcpy((char *) sqlca, (char *) &sqlca_init, sizeof(struct sqlca_t));
101 ECPGinit(const struct connection * con, const char *connection_name, const int lineno)
103 struct sqlca_t *sqlca = ECPGget_sqlca();
105 ECPGinit_sqlca(sqlca);
108 ECPGraise(lineno, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
109 connection_name ? connection_name : "NULL");
118 ecpg_sqlca_key_init(void)
120 pthread_key_create(&sqlca_key, NULL);
128 struct sqlca_t *sqlca;
130 pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
132 sqlca = pthread_getspecific(sqlca_key);
135 sqlca = malloc(sizeof(struct sqlca_t));
136 ECPGinit_sqlca(sqlca);
137 pthread_setspecific(sqlca_key, sqlca);
146 ECPGstatus(int lineno, const char *connection_name)
148 struct connection *con = ECPGget_connection(connection_name);
150 if (!ECPGinit(con, connection_name, lineno))
153 /* are we connected? */
154 if (con->connection == NULL)
156 ECPGraise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, con->name);
164 ECPGtrans(int lineno, const char *connection_name, const char *transaction)
167 struct connection *con = ECPGget_connection(connection_name);
169 if (!ECPGinit(con, connection_name, lineno))
172 ECPGlog("ECPGtrans line %d action = %s connection = %s\n", lineno, transaction, con->name);
174 /* if we have no connection we just simulate the command */
175 if (con && con->connection)
178 * if we are not in autocommit mode, already have committed the
179 * transaction and get another commit, just ignore it
181 if (!con->committed || con->autocommit)
183 if ((res = PQexec(con->connection, transaction)) == NULL)
185 ECPGraise(lineno, ECPG_TRANS, ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN, NULL);
192 if (strcmp(transaction, "commit") == 0 || strcmp(transaction, "rollback") == 0)
194 con->committed = true;
197 /* deallocate all prepared statements */
198 if (!ECPGdeallocate_all(lineno))
208 ECPGdebug(int n, FILE *dbgs)
211 pthread_mutex_lock(&debug_init_mutex);
216 ECPGlog("ECPGdebug: set to %d\n", simple_debug);
219 pthread_mutex_unlock(&debug_init_mutex);
224 ECPGlog(const char *format,...)
229 pthread_mutex_lock(&debug_mutex);
234 char *f = (char *) malloc(strlen(format) + 100);
239 pthread_mutex_unlock(&debug_mutex);
244 sprintf(f, "[%d]: %s", (int) getpid(), format);
246 va_start(ap, format);
247 vfprintf(debugstream, f, ap);
255 pthread_mutex_unlock(&debug_mutex);
260 ECPGset_informix_null(enum ECPGttype type, void *ptr)
265 case ECPGt_unsigned_char:
266 *((char *) ptr) = '\0';
269 case ECPGt_unsigned_short:
270 *((short int *) ptr) = SHRT_MIN;
273 case ECPGt_unsigned_int:
274 *((int *) ptr) = INT_MIN;
277 case ECPGt_unsigned_long:
279 *((long *) ptr) = LONG_MIN;
281 #ifdef HAVE_LONG_LONG_INT_64
282 case ECPGt_long_long:
283 case ECPGt_unsigned_long_long:
284 *((long long *) ptr) = LONG_LONG_MIN;
286 #endif /* HAVE_LONG_LONG_INT_64 */
288 memset((char *) ptr, 0xff, sizeof(float));
291 memset((char *) ptr, 0xff, sizeof(double));
294 *(((struct ECPGgeneric_varchar *) ptr)->arr) = 0x00;
297 memset((char *) ptr, 0, sizeof(Decimal));
298 ((Decimal *) ptr)->sign = NUMERIC_NAN;
301 memset((char *) ptr, 0, sizeof(Numeric));
302 ((Numeric *) ptr)->sign = NUMERIC_NAN;
305 memset((char *) ptr, 0xff, sizeof(Interval));
307 case ECPGt_timestamp:
308 memset((char *) ptr, 0xff, sizeof(Timestamp));
316 _check(unsigned char *ptr, int length)
318 for (; ptr[--length] == 0xff && length >= 0; length--);
325 ECPGis_informix_null(enum ECPGttype type, void *ptr)
330 case ECPGt_unsigned_char:
331 if (*((char *) ptr) == '\0')
335 case ECPGt_unsigned_short:
336 if (*((short int *) ptr) == SHRT_MIN)
340 case ECPGt_unsigned_int:
341 if (*((int *) ptr) == INT_MIN)
345 case ECPGt_unsigned_long:
347 if (*((long *) ptr) == LONG_MIN)
350 #ifdef HAVE_LONG_LONG_INT_64
351 case ECPGt_long_long:
352 case ECPGt_unsigned_long_long:
353 if (*((long long *) ptr) == LONG_LONG_MIN)
356 #endif /* HAVE_LONG_LONG_INT_64 */
358 return (_check(ptr, sizeof(float)));
361 return (_check(ptr, sizeof(double)));
364 if (*(((struct ECPGgeneric_varchar *) ptr)->arr) == 0x00)
368 if (((Decimal *) ptr)->sign == NUMERIC_NAN)
372 if (((Numeric *) ptr)->sign == NUMERIC_NAN)
376 return (_check(ptr, sizeof(Interval)));
378 case ECPGt_timestamp:
379 return (_check(ptr, sizeof(Timestamp)));