1 /* src/interfaces/ecpg/ecpglib/execute.c */
2
3 /*
4 * The aim is to get a simpler interface to the database routines.
5 * All the tedious messing around with tuples is supposed to be hidden
6 * by this function.
7 */
8 /* Author: Linus Tolke
9 (actually most if the code is "borrowed" from the distribution and just
10 slightly modified)
11 */
12
13 /* Taken over as part of PostgreSQL by Michael Meskes <meskes@postgresql.org>
14 on Feb. 5th, 1998 */
15
16 #define POSTGRES_ECPG_INTERNAL
17 #include "postgres_fe.h"
18
19 #include <math.h>
20
21 #include "catalog/pg_type_d.h"
22
23 #include "ecpgtype.h"
24 #include "ecpglib.h"
25 #include "ecpgerrno.h"
26 #include "ecpglib_extern.h"
27 #include "sqlca.h"
28 #include "sqlda-native.h"
29 #include "sqlda-compat.h"
30 #include "sql3types.h"
31 #include "pgtypes_numeric.h"
32 #include "pgtypes_date.h"
33 #include "pgtypes_timestamp.h"
34 #include "pgtypes_interval.h"
35
36 /*
37 * This function returns a newly malloced string that has ' and \
38 * escaped.
39 */
40 static char *
quote_postgres(char * arg,bool quote,int lineno)41 quote_postgres(char *arg, bool quote, int lineno)
42 {
43 char *res;
44 size_t length;
45 size_t escaped_len;
46 size_t buffer_len;
47
48 /*
49 * if quote is false we just need to store things in a descriptor they
50 * will be quoted once they are inserted in a statement
51 */
52 if (!quote)
53 return arg;
54 else
55 {
56 length = strlen(arg);
57 buffer_len = 2 * length + 1;
58 res = (char *) ecpg_alloc(buffer_len + 3, lineno);
59 if (!res)
60 return res;
61 escaped_len = PQescapeString(res + 1, arg, buffer_len);
62 if (length == escaped_len)
63 {
64 res[0] = res[escaped_len + 1] = '\'';
65 res[escaped_len + 2] = '\0';
66 }
67 else
68 {
69 /*
70 * We don't know if the target database is using
71 * standard_conforming_strings, so we always use E'' strings.
72 */
73 memmove(res + 2, res + 1, escaped_len);
74 res[0] = ESCAPE_STRING_SYNTAX;
75 res[1] = res[escaped_len + 2] = '\'';
76 res[escaped_len + 3] = '\0';
77 }
78 ecpg_free(arg);
79 return res;
80 }
81 }
82
83 static void
free_variable(struct variable * var)84 free_variable(struct variable *var)
85 {
86 struct variable *var_next;
87
88 while (var)
89 {
90 var_next = var->next;
91 ecpg_free(var);
92 var = var_next;
93 }
94 }
95
96 static void
free_statement(struct statement * stmt)97 free_statement(struct statement *stmt)
98 {
99 if (stmt == NULL)
100 return;
101 free_variable(stmt->inlist);
102 free_variable(stmt->outlist);
103 ecpg_free(stmt->command);
104 ecpg_free(stmt->name);
105 #ifdef HAVE_USELOCALE
106 if (stmt->clocale)
107 freelocale(stmt->clocale);
108 #else
109 ecpg_free(stmt->oldlocale);
110 #endif
111 ecpg_free(stmt);
112 }
113
114 static int
next_insert(char * text,int pos,bool questionmarks,bool std_strings)115 next_insert(char *text, int pos, bool questionmarks, bool std_strings)
116 {
117 bool string = false;
118 int p = pos;
119
120 for (; text[p] != '\0'; p++)
121 {
122 if (string && !std_strings && text[p] == '\\') /* escape character */
123 p++;
124 else if (text[p] == '\'')
125 string = string ? false : true;
126 else if (!string)
127 {
128 if (text[p] == '$' && isdigit((unsigned char) text[p + 1]))
129 {
130 /* this can be either a dollar quote or a variable */
131 int i;
132
133 for (i = p + 1; isdigit((unsigned char) text[i]); i++)
134 /* empty loop body */ ;
135 if (!isalpha((unsigned char) text[i]) &&
136 isascii((unsigned char) text[i]) &&text[i] != '_')
137 /* not dollar delimited quote */
138 return p;
139 }
140 else if (questionmarks && text[p] == '?')
141 {
142 /* also allow old style placeholders */
143 return p;
144 }
145 }
146 }
147
148 return -1;
149 }
150
151 static bool
ecpg_type_infocache_push(struct ECPGtype_information_cache ** cache,int oid,enum ARRAY_TYPE isarray,int lineno)152 ecpg_type_infocache_push(struct ECPGtype_information_cache **cache, int oid, enum ARRAY_TYPE isarray, int lineno)
153 {
154 struct ECPGtype_information_cache *new_entry
155 = (struct ECPGtype_information_cache *) ecpg_alloc(sizeof(struct ECPGtype_information_cache), lineno);
156
157 if (new_entry == NULL)
158 return false;
159
160 new_entry->oid = oid;
161 new_entry->isarray = isarray;
162 new_entry->next = *cache;
163 *cache = new_entry;
164 return true;
165 }
166
167 static enum ARRAY_TYPE
ecpg_is_type_an_array(int type,const struct statement * stmt,const struct variable * var)168 ecpg_is_type_an_array(int type, const struct statement *stmt, const struct variable *var)
169 {
170 char *array_query;
171 enum ARRAY_TYPE isarray = ECPG_ARRAY_NOT_SET;
172 PGresult *query;
173 struct ECPGtype_information_cache *cache_entry;
174
175 if ((stmt->connection->cache_head) == NULL)
176 {
177 /*
178 * Text like types are not an array for ecpg, but postgres counts them
179 * as an array. This define reminds you to not 'correct' these values.
180 */
181 #define not_an_array_in_ecpg ECPG_ARRAY_NONE
182
183 /* populate cache with well known types to speed things up */
184 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), BOOLOID, ECPG_ARRAY_NONE, stmt->lineno))
185 return ECPG_ARRAY_ERROR;
186 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), BYTEAOID, ECPG_ARRAY_NONE, stmt->lineno))
187 return ECPG_ARRAY_ERROR;
188 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CHAROID, ECPG_ARRAY_NONE, stmt->lineno))
189 return ECPG_ARRAY_ERROR;
190 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), NAMEOID, not_an_array_in_ecpg, stmt->lineno))
191 return ECPG_ARRAY_ERROR;
192 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INT8OID, ECPG_ARRAY_NONE, stmt->lineno))
193 return ECPG_ARRAY_ERROR;
194 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INT2OID, ECPG_ARRAY_NONE, stmt->lineno))
195 return ECPG_ARRAY_ERROR;
196 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INT2VECTOROID, ECPG_ARRAY_VECTOR, stmt->lineno))
197 return ECPG_ARRAY_ERROR;
198 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INT4OID, ECPG_ARRAY_NONE, stmt->lineno))
199 return ECPG_ARRAY_ERROR;
200 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), REGPROCOID, ECPG_ARRAY_NONE, stmt->lineno))
201 return ECPG_ARRAY_ERROR;
202 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TEXTOID, ECPG_ARRAY_NONE, stmt->lineno))
203 return ECPG_ARRAY_ERROR;
204 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), OIDOID, ECPG_ARRAY_NONE, stmt->lineno))
205 return ECPG_ARRAY_ERROR;
206 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIDOID, ECPG_ARRAY_NONE, stmt->lineno))
207 return ECPG_ARRAY_ERROR;
208 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), XIDOID, ECPG_ARRAY_NONE, stmt->lineno))
209 return ECPG_ARRAY_ERROR;
210 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CIDOID, ECPG_ARRAY_NONE, stmt->lineno))
211 return ECPG_ARRAY_ERROR;
212 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), OIDVECTOROID, ECPG_ARRAY_VECTOR, stmt->lineno))
213 return ECPG_ARRAY_ERROR;
214 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), POINTOID, ECPG_ARRAY_VECTOR, stmt->lineno))
215 return ECPG_ARRAY_ERROR;
216 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), LSEGOID, ECPG_ARRAY_VECTOR, stmt->lineno))
217 return ECPG_ARRAY_ERROR;
218 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), PATHOID, ECPG_ARRAY_NONE, stmt->lineno))
219 return ECPG_ARRAY_ERROR;
220 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), BOXOID, ECPG_ARRAY_VECTOR, stmt->lineno))
221 return ECPG_ARRAY_ERROR;
222 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), POLYGONOID, ECPG_ARRAY_NONE, stmt->lineno))
223 return ECPG_ARRAY_ERROR;
224 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), LINEOID, ECPG_ARRAY_VECTOR, stmt->lineno))
225 return ECPG_ARRAY_ERROR;
226 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), FLOAT4OID, ECPG_ARRAY_NONE, stmt->lineno))
227 return ECPG_ARRAY_ERROR;
228 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), FLOAT8OID, ECPG_ARRAY_NONE, stmt->lineno))
229 return ECPG_ARRAY_ERROR;
230 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), UNKNOWNOID, ECPG_ARRAY_NONE, stmt->lineno))
231 return ECPG_ARRAY_ERROR;
232 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CIRCLEOID, ECPG_ARRAY_NONE, stmt->lineno))
233 return ECPG_ARRAY_ERROR;
234 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CASHOID, ECPG_ARRAY_NONE, stmt->lineno))
235 return ECPG_ARRAY_ERROR;
236 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INETOID, ECPG_ARRAY_NONE, stmt->lineno))
237 return ECPG_ARRAY_ERROR;
238 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CIDROID, ECPG_ARRAY_NONE, stmt->lineno))
239 return ECPG_ARRAY_ERROR;
240 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), BPCHAROID, ECPG_ARRAY_NONE, stmt->lineno))
241 return ECPG_ARRAY_ERROR;
242 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), VARCHAROID, ECPG_ARRAY_NONE, stmt->lineno))
243 return ECPG_ARRAY_ERROR;
244 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), DATEOID, ECPG_ARRAY_NONE, stmt->lineno))
245 return ECPG_ARRAY_ERROR;
246 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIMEOID, ECPG_ARRAY_NONE, stmt->lineno))
247 return ECPG_ARRAY_ERROR;
248 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIMESTAMPOID, ECPG_ARRAY_NONE, stmt->lineno))
249 return ECPG_ARRAY_ERROR;
250 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIMESTAMPTZOID, ECPG_ARRAY_NONE, stmt->lineno))
251 return ECPG_ARRAY_ERROR;
252 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INTERVALOID, ECPG_ARRAY_NONE, stmt->lineno))
253 return ECPG_ARRAY_ERROR;
254 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIMETZOID, ECPG_ARRAY_NONE, stmt->lineno))
255 return ECPG_ARRAY_ERROR;
256 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), BITOID, ECPG_ARRAY_NONE, stmt->lineno))
257 return ECPG_ARRAY_ERROR;
258 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), VARBITOID, ECPG_ARRAY_NONE, stmt->lineno))
259 return ECPG_ARRAY_ERROR;
260 if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), NUMERICOID, ECPG_ARRAY_NONE, stmt->lineno))
261 return ECPG_ARRAY_ERROR;
262 }
263
264 for (cache_entry = (stmt->connection->cache_head); cache_entry != NULL; cache_entry = cache_entry->next)
265 {
266 if (cache_entry->oid == type)
267 return cache_entry->isarray;
268 }
269
270 array_query = (char *) ecpg_alloc(strlen("select typlen from pg_type where oid= and typelem<>0") + 11, stmt->lineno);
271 if (array_query == NULL)
272 return ECPG_ARRAY_ERROR;
273
274 sprintf(array_query, "select typlen from pg_type where oid=%d and typelem<>0", type);
275 query = PQexec(stmt->connection->connection, array_query);
276 ecpg_free(array_query);
277 if (!ecpg_check_PQresult(query, stmt->lineno, stmt->connection->connection, stmt->compat))
278 return ECPG_ARRAY_ERROR;
279 else if (PQresultStatus(query) == PGRES_TUPLES_OK)
280 {
281 if (PQntuples(query) == 0)
282 isarray = ECPG_ARRAY_NONE;
283 else
284 {
285 isarray = (atol((char *) PQgetvalue(query, 0, 0)) == -1) ? ECPG_ARRAY_ARRAY : ECPG_ARRAY_VECTOR;
286 if (ecpg_dynamic_type(type) == SQL3_CHARACTER ||
287 ecpg_dynamic_type(type) == SQL3_CHARACTER_VARYING)
288 {
289 /*
290 * arrays of character strings are not yet implemented
291 */
292 isarray = ECPG_ARRAY_NONE;
293 }
294 }
295 PQclear(query);
296 }
297 else
298 return ECPG_ARRAY_ERROR;
299
300 ecpg_type_infocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno);
301 ecpg_log("ecpg_is_type_an_array on line %d: type (%d); C (%d); array (%s)\n", stmt->lineno, type, var->type, ECPG_IS_ARRAY(isarray) ? "yes" : "no");
302 return isarray;
303 }
304
305
306 bool
ecpg_store_result(const PGresult * results,int act_field,const struct statement * stmt,struct variable * var)307 ecpg_store_result(const PGresult *results, int act_field,
308 const struct statement *stmt, struct variable *var)
309 {
310 enum ARRAY_TYPE isarray;
311 int act_tuple,
312 ntuples = PQntuples(results);
313 bool status = true;
314
315 if ((isarray = ecpg_is_type_an_array(PQftype(results, act_field), stmt, var)) == ECPG_ARRAY_ERROR)
316 {
317 ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
318 return false;
319 }
320
321 if (isarray == ECPG_ARRAY_NONE)
322 {
323 /*
324 * if we don't have enough space, we cannot read all tuples
325 */
326 if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
327 {
328 ecpg_log("ecpg_store_result on line %d: incorrect number of matches; %d don't fit into array of %ld\n",
329 stmt->lineno, ntuples, var->arrsize);
330 ecpg_raise(stmt->lineno, INFORMIX_MODE(stmt->compat) ? ECPG_INFORMIX_SUBSELECT_NOT_ONE : ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
331 return false;
332 }
333 }
334 else
335 {
336 /*
337 * since we read an array, the variable has to be an array too
338 */
339 if (var->arrsize == 0)
340 {
341 ecpg_raise(stmt->lineno, ECPG_NO_ARRAY, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
342 return false;
343 }
344 }
345
346 /*
347 * allocate memory for NULL pointers
348 */
349 if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL)
350 {
351 int len = 0;
352
353 if (!PQfformat(results, act_field))
354 {
355 switch (var->type)
356 {
357 case ECPGt_char:
358 case ECPGt_unsigned_char:
359 case ECPGt_string:
360 if (!var->varcharsize && !var->arrsize)
361 {
362 /* special mode for handling char**foo=0 */
363 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
364 len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
365 len *= var->offset; /* should be 1, but YMNK */
366 len += (ntuples + 1) * sizeof(char *);
367 }
368 else
369 {
370 var->varcharsize = 0;
371 /* check strlen for each tuple */
372 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
373 {
374 int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
375
376 if (len > var->varcharsize)
377 var->varcharsize = len;
378 }
379 var->offset *= var->varcharsize;
380 len = var->offset * ntuples;
381 }
382 break;
383 case ECPGt_varchar:
384 len = ntuples * (var->varcharsize + sizeof(int));
385 break;
386 default:
387 len = var->offset * ntuples;
388 break;
389 }
390 }
391 else
392 {
393 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
394 len += PQgetlength(results, act_tuple, act_field);
395 }
396
397 ecpg_log("ecpg_store_result on line %d: allocating memory for %d tuples\n", stmt->lineno, ntuples);
398 var->value = (char *) ecpg_auto_alloc(len, stmt->lineno);
399 if (!var->value)
400 return false;
401 *((char **) var->pointer) = var->value;
402 }
403
404 /* allocate indicator variable if needed */
405 if ((var->ind_arrsize == 0 || var->ind_varcharsize == 0) && var->ind_value == NULL && var->ind_pointer != NULL)
406 {
407 int len = var->ind_offset * ntuples;
408
409 var->ind_value = (char *) ecpg_auto_alloc(len, stmt->lineno);
410 if (!var->ind_value)
411 return false;
412 *((char **) var->ind_pointer) = var->ind_value;
413 }
414
415 /* fill the variable with the tuple(s) */
416 if (!var->varcharsize && !var->arrsize &&
417 (var->type == ECPGt_char || var->type == ECPGt_unsigned_char || var->type == ECPGt_string))
418 {
419 /* special mode for handling char**foo=0 */
420
421 /* filling the array of (char*)s */
422 char **current_string = (char **) var->value;
423
424 /* storing the data (after the last array element) */
425 char *current_data_location = (char *) ¤t_string[ntuples + 1];
426
427 for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
428 {
429 int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
430
431 if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
432 var->type, var->ind_type, current_data_location,
433 var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
434 status = false;
435 else
436 {
437 *current_string = current_data_location;
438 current_data_location += len;
439 current_string++;
440 }
441 }
442
443 /* terminate the list */
444 *current_string = NULL;
445 }
446 else
447 {
448 for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
449 {
450 if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
451 var->type, var->ind_type, var->value,
452 var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
453 status = false;
454 }
455 }
456 return status;
457 }
458
459 static void
sprintf_double_value(char * ptr,double value,const char * delim)460 sprintf_double_value(char *ptr, double value, const char *delim)
461 {
462 if (isnan(value))
463 sprintf(ptr, "%s%s", "NaN", delim);
464 else if (isinf(value))
465 {
466 if (value < 0)
467 sprintf(ptr, "%s%s", "-Infinity", delim);
468 else
469 sprintf(ptr, "%s%s", "Infinity", delim);
470 }
471 else
472 sprintf(ptr, "%.15g%s", value, delim);
473 }
474
475 static void
sprintf_float_value(char * ptr,float value,const char * delim)476 sprintf_float_value(char *ptr, float value, const char *delim)
477 {
478 if (isnan(value))
479 sprintf(ptr, "%s%s", "NaN", delim);
480 else if (isinf(value))
481 {
482 if (value < 0)
483 sprintf(ptr, "%s%s", "-Infinity", delim);
484 else
485 sprintf(ptr, "%s%s", "Infinity", delim);
486 }
487 else
488 sprintf(ptr, "%.15g%s", value, delim);
489 }
490
491 static char *
convert_bytea_to_string(char * from_data,int from_len,int lineno)492 convert_bytea_to_string(char *from_data, int from_len, int lineno)
493 {
494 char *to_data;
495 int to_len = ecpg_hex_enc_len(from_len) + 4 + 1; /* backslash + 'x' +
496 * quote + quote */
497
498 to_data = ecpg_alloc(to_len, lineno);
499 if (!to_data)
500 return NULL;
501
502 strcpy(to_data, "'\\x");
503 ecpg_hex_encode(from_data, from_len, to_data + 3);
504 strcpy(to_data + 3 + ecpg_hex_enc_len(from_len), "\'");
505
506 return to_data;
507 }
508
509 bool
ecpg_store_input(const int lineno,const bool force_indicator,const struct variable * var,char ** tobeinserted_p,bool quote)510 ecpg_store_input(const int lineno, const bool force_indicator, const struct variable *var,
511 char **tobeinserted_p, bool quote)
512 {
513 char *mallocedval = NULL;
514 char *newcopy = NULL;
515
516 /*
517 * arrays are not possible unless the column is an array, too FIXME: we do
518 * not know if the column is an array here array input to singleton column
519 * will result in a runtime error
520 */
521
522 /*
523 * Some special treatment is needed for records since we want their
524 * contents to arrive in a comma-separated list on insert (I think).
525 */
526
527 *tobeinserted_p = "";
528
529 /* check for null value and set input buffer accordingly */
530 switch (var->ind_type)
531 {
532 case ECPGt_short:
533 case ECPGt_unsigned_short:
534 if (*(short *) var->ind_value < 0)
535 *tobeinserted_p = NULL;
536 break;
537 case ECPGt_int:
538 case ECPGt_unsigned_int:
539 if (*(int *) var->ind_value < 0)
540 *tobeinserted_p = NULL;
541 break;
542 case ECPGt_long:
543 case ECPGt_unsigned_long:
544 if (*(long *) var->ind_value < 0L)
545 *tobeinserted_p = NULL;
546 break;
547 #ifdef HAVE_LONG_LONG_INT
548 case ECPGt_long_long:
549 case ECPGt_unsigned_long_long:
550 if (*(long long int *) var->ind_value < (long long) 0)
551 *tobeinserted_p = NULL;
552 break;
553 #endif /* HAVE_LONG_LONG_INT */
554 case ECPGt_NO_INDICATOR:
555 if (force_indicator == false)
556 {
557 if (ECPGis_noind_null(var->type, var->value))
558 *tobeinserted_p = NULL;
559 }
560 break;
561 default:
562 break;
563 }
564 if (*tobeinserted_p != NULL)
565 {
566 int asize = var->arrsize ? var->arrsize : 1;
567
568 switch (var->type)
569 {
570 int element;
571
572 case ECPGt_short:
573 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
574 return false;
575
576 if (asize > 1)
577 {
578 strcpy(mallocedval, "{");
579
580 for (element = 0; element < asize; element++)
581 sprintf(mallocedval + strlen(mallocedval), "%hd,", ((short *) var->value)[element]);
582
583 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
584 }
585 else
586 sprintf(mallocedval, "%hd", *((short *) var->value));
587
588 *tobeinserted_p = mallocedval;
589 break;
590
591 case ECPGt_int:
592 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
593 return false;
594
595 if (asize > 1)
596 {
597 strcpy(mallocedval, "{");
598
599 for (element = 0; element < asize; element++)
600 sprintf(mallocedval + strlen(mallocedval), "%d,", ((int *) var->value)[element]);
601
602 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
603 }
604 else
605 sprintf(mallocedval, "%d", *((int *) var->value));
606
607 *tobeinserted_p = mallocedval;
608 break;
609
610 case ECPGt_unsigned_short:
611 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
612 return false;
613
614 if (asize > 1)
615 {
616 strcpy(mallocedval, "{");
617
618 for (element = 0; element < asize; element++)
619 sprintf(mallocedval + strlen(mallocedval), "%hu,", ((unsigned short *) var->value)[element]);
620
621 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
622 }
623 else
624 sprintf(mallocedval, "%hu", *((unsigned short *) var->value));
625
626 *tobeinserted_p = mallocedval;
627 break;
628
629 case ECPGt_unsigned_int:
630 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
631 return false;
632
633 if (asize > 1)
634 {
635 strcpy(mallocedval, "{");
636
637 for (element = 0; element < asize; element++)
638 sprintf(mallocedval + strlen(mallocedval), "%u,", ((unsigned int *) var->value)[element]);
639
640 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
641 }
642 else
643 sprintf(mallocedval, "%u", *((unsigned int *) var->value));
644
645 *tobeinserted_p = mallocedval;
646 break;
647
648 case ECPGt_long:
649 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
650 return false;
651
652 if (asize > 1)
653 {
654 strcpy(mallocedval, "{");
655
656 for (element = 0; element < asize; element++)
657 sprintf(mallocedval + strlen(mallocedval), "%ld,", ((long *) var->value)[element]);
658
659 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
660 }
661 else
662 sprintf(mallocedval, "%ld", *((long *) var->value));
663
664 *tobeinserted_p = mallocedval;
665 break;
666
667 case ECPGt_unsigned_long:
668 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
669 return false;
670
671 if (asize > 1)
672 {
673 strcpy(mallocedval, "{");
674
675 for (element = 0; element < asize; element++)
676 sprintf(mallocedval + strlen(mallocedval), "%lu,", ((unsigned long *) var->value)[element]);
677
678 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
679 }
680 else
681 sprintf(mallocedval, "%lu", *((unsigned long *) var->value));
682
683 *tobeinserted_p = mallocedval;
684 break;
685 #ifdef HAVE_LONG_LONG_INT
686 case ECPGt_long_long:
687 if (!(mallocedval = ecpg_alloc(asize * 30, lineno)))
688 return false;
689
690 if (asize > 1)
691 {
692 strcpy(mallocedval, "{");
693
694 for (element = 0; element < asize; element++)
695 sprintf(mallocedval + strlen(mallocedval), "%lld,", ((long long int *) var->value)[element]);
696
697 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
698 }
699 else
700 sprintf(mallocedval, "%lld", *((long long int *) var->value));
701
702 *tobeinserted_p = mallocedval;
703 break;
704
705 case ECPGt_unsigned_long_long:
706 if (!(mallocedval = ecpg_alloc(asize * 30, lineno)))
707 return false;
708
709 if (asize > 1)
710 {
711 strcpy(mallocedval, "{");
712
713 for (element = 0; element < asize; element++)
714 sprintf(mallocedval + strlen(mallocedval), "%llu,", ((unsigned long long int *) var->value)[element]);
715
716 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
717 }
718 else
719 sprintf(mallocedval, "%llu", *((unsigned long long int *) var->value));
720
721 *tobeinserted_p = mallocedval;
722 break;
723 #endif /* HAVE_LONG_LONG_INT */
724 case ECPGt_float:
725 if (!(mallocedval = ecpg_alloc(asize * 25, lineno)))
726 return false;
727
728 if (asize > 1)
729 {
730 strcpy(mallocedval, "{");
731
732 for (element = 0; element < asize; element++)
733 sprintf_float_value(mallocedval + strlen(mallocedval), ((float *) var->value)[element], ",");
734
735 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
736 }
737 else
738 sprintf_float_value(mallocedval, *((float *) var->value), "");
739
740 *tobeinserted_p = mallocedval;
741 break;
742
743 case ECPGt_double:
744 if (!(mallocedval = ecpg_alloc(asize * 25, lineno)))
745 return false;
746
747 if (asize > 1)
748 {
749 strcpy(mallocedval, "{");
750
751 for (element = 0; element < asize; element++)
752 sprintf_double_value(mallocedval + strlen(mallocedval), ((double *) var->value)[element], ",");
753
754 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
755 }
756 else
757 sprintf_double_value(mallocedval, *((double *) var->value), "");
758
759 *tobeinserted_p = mallocedval;
760 break;
761
762 case ECPGt_bool:
763 if (!(mallocedval = ecpg_alloc(var->arrsize + sizeof("{}"), lineno)))
764 return false;
765
766 if (var->arrsize > 1)
767 {
768 strcpy(mallocedval, "{");
769
770 for (element = 0; element < asize; element++)
771 sprintf(mallocedval + strlen(mallocedval), "%c,", (((bool *) var->value)[element]) ? 't' : 'f');
772
773 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
774 }
775 else
776 {
777 if (var->offset == sizeof(char))
778 sprintf(mallocedval, "%c", (*((char *) var->value)) ? 't' : 'f');
779 else if (var->offset == sizeof(int))
780 sprintf(mallocedval, "%c", (*((int *) var->value)) ? 't' : 'f');
781 else
782 ecpg_raise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
783 }
784
785 *tobeinserted_p = mallocedval;
786 break;
787
788 case ECPGt_char:
789 case ECPGt_unsigned_char:
790 case ECPGt_string:
791 {
792 /* set slen to string length if type is char * */
793 int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : (unsigned int) var->varcharsize;
794
795 if (!(newcopy = ecpg_alloc(slen + 1, lineno)))
796 return false;
797
798 strncpy(newcopy, (char *) var->value, slen);
799 newcopy[slen] = '\0';
800
801 mallocedval = quote_postgres(newcopy, quote, lineno);
802 if (!mallocedval)
803 {
804 ecpg_free(newcopy);
805 return false;
806 }
807
808 *tobeinserted_p = mallocedval;
809 }
810 break;
811 case ECPGt_const:
812 case ECPGt_char_variable:
813 {
814 int slen = strlen((char *) var->value);
815
816 if (!(mallocedval = ecpg_alloc(slen + 1, lineno)))
817 return false;
818
819 strncpy(mallocedval, (char *) var->value, slen);
820 mallocedval[slen] = '\0';
821
822 *tobeinserted_p = mallocedval;
823 }
824 break;
825
826 case ECPGt_bytea:
827 {
828 struct ECPGgeneric_bytea *variable =
829 (struct ECPGgeneric_bytea *) (var->value);
830
831 if (!(mallocedval = (char *) ecpg_alloc(variable->len, lineno)))
832 return false;
833
834 memcpy(mallocedval, variable->arr, variable->len);
835 *tobeinserted_p = mallocedval;
836 }
837 break;
838
839 case ECPGt_varchar:
840 {
841 struct ECPGgeneric_varchar *variable =
842 (struct ECPGgeneric_varchar *) (var->value);
843
844 if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, lineno)))
845 return false;
846
847 strncpy(newcopy, variable->arr, variable->len);
848 newcopy[variable->len] = '\0';
849
850 mallocedval = quote_postgres(newcopy, quote, lineno);
851 if (!mallocedval)
852 {
853 ecpg_free(newcopy);
854 return false;
855 }
856
857 *tobeinserted_p = mallocedval;
858 }
859 break;
860
861 case ECPGt_decimal:
862 case ECPGt_numeric:
863 {
864 char *str = NULL;
865 int slen;
866 numeric *nval;
867
868 if (var->arrsize > 1)
869 mallocedval = ecpg_strdup("{", lineno);
870 else
871 mallocedval = ecpg_strdup("", lineno);
872
873 if (!mallocedval)
874 return false;
875
876 for (element = 0; element < asize; element++)
877 {
878 int result;
879
880 nval = PGTYPESnumeric_new();
881 if (!nval)
882 {
883 ecpg_free(mallocedval);
884 return false;
885 }
886
887 if (var->type == ECPGt_numeric)
888 result = PGTYPESnumeric_copy(&(((numeric *) (var->value))[element]), nval);
889 else
890 result = PGTYPESnumeric_from_decimal(&(((decimal *) (var->value))[element]), nval);
891
892 if (result != 0)
893 {
894 PGTYPESnumeric_free(nval);
895 ecpg_free(mallocedval);
896 return false;
897 }
898
899 str = PGTYPESnumeric_to_asc(nval, nval->dscale);
900 slen = strlen(str);
901 PGTYPESnumeric_free(nval);
902
903 if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
904 {
905 ecpg_free(mallocedval);
906 ecpg_free(str);
907 return false;
908 }
909 mallocedval = newcopy;
910
911 /* also copy trailing '\0' */
912 memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
913 if (var->arrsize > 1)
914 strcpy(mallocedval + strlen(mallocedval), ",");
915
916 ecpg_free(str);
917 }
918
919 if (var->arrsize > 1)
920 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
921
922 *tobeinserted_p = mallocedval;
923 }
924 break;
925
926 case ECPGt_interval:
927 {
928 char *str = NULL;
929 int slen;
930
931 if (var->arrsize > 1)
932 mallocedval = ecpg_strdup("{", lineno);
933 else
934 mallocedval = ecpg_strdup("", lineno);
935
936 if (!mallocedval)
937 return false;
938
939 for (element = 0; element < asize; element++)
940 {
941 str = quote_postgres(PGTYPESinterval_to_asc(&(((interval *) (var->value))[element])), quote, lineno);
942 if (!str)
943 {
944 ecpg_free(mallocedval);
945 return false;
946 }
947
948 slen = strlen(str);
949
950 if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
951 {
952 ecpg_free(mallocedval);
953 ecpg_free(str);
954 return false;
955 }
956 mallocedval = newcopy;
957
958 /* also copy trailing '\0' */
959 memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
960 if (var->arrsize > 1)
961 strcpy(mallocedval + strlen(mallocedval), ",");
962
963 ecpg_free(str);
964 }
965
966 if (var->arrsize > 1)
967 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
968
969 *tobeinserted_p = mallocedval;
970 }
971 break;
972
973 case ECPGt_date:
974 {
975 char *str = NULL;
976 int slen;
977
978 if (var->arrsize > 1)
979 mallocedval = ecpg_strdup("{", lineno);
980 else
981 mallocedval = ecpg_strdup("", lineno);
982
983 if (!mallocedval)
984 return false;
985
986 for (element = 0; element < asize; element++)
987 {
988 str = quote_postgres(PGTYPESdate_to_asc(((date *) (var->value))[element]), quote, lineno);
989 if (!str)
990 {
991 ecpg_free(mallocedval);
992 return false;
993 }
994
995 slen = strlen(str);
996
997 if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
998 {
999 ecpg_free(mallocedval);
1000 ecpg_free(str);
1001 return false;
1002 }
1003 mallocedval = newcopy;
1004
1005 /* also copy trailing '\0' */
1006 memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
1007 if (var->arrsize > 1)
1008 strcpy(mallocedval + strlen(mallocedval), ",");
1009
1010 ecpg_free(str);
1011 }
1012
1013 if (var->arrsize > 1)
1014 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
1015
1016 *tobeinserted_p = mallocedval;
1017 }
1018 break;
1019
1020 case ECPGt_timestamp:
1021 {
1022 char *str = NULL;
1023 int slen;
1024
1025 if (var->arrsize > 1)
1026 mallocedval = ecpg_strdup("{", lineno);
1027 else
1028 mallocedval = ecpg_strdup("", lineno);
1029
1030 if (!mallocedval)
1031 return false;
1032
1033 for (element = 0; element < asize; element++)
1034 {
1035 str = quote_postgres(PGTYPEStimestamp_to_asc(((timestamp *) (var->value))[element]), quote, lineno);
1036 if (!str)
1037 {
1038 ecpg_free(mallocedval);
1039 return false;
1040 }
1041
1042 slen = strlen(str);
1043
1044 if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
1045 {
1046 ecpg_free(mallocedval);
1047 ecpg_free(str);
1048 return false;
1049 }
1050 mallocedval = newcopy;
1051
1052 /* also copy trailing '\0' */
1053 memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
1054 if (var->arrsize > 1)
1055 strcpy(mallocedval + strlen(mallocedval), ",");
1056
1057 ecpg_free(str);
1058 }
1059
1060 if (var->arrsize > 1)
1061 strcpy(mallocedval + strlen(mallocedval) - 1, "}");
1062
1063 *tobeinserted_p = mallocedval;
1064 }
1065 break;
1066
1067 case ECPGt_descriptor:
1068 case ECPGt_sqlda:
1069 break;
1070
1071 default:
1072 /* Not implemented yet */
1073 ecpg_raise(lineno, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ecpg_type_name(var->type));
1074 return false;
1075 break;
1076 }
1077 }
1078 return true;
1079 }
1080
1081 static void
print_param_value(char * value,int len,int is_binary,int lineno,int nth)1082 print_param_value(char *value, int len, int is_binary, int lineno, int nth)
1083 {
1084 char *value_s;
1085 bool malloced = false;
1086
1087 if (value == NULL)
1088 value_s = "null";
1089 else if (!is_binary)
1090 value_s = value;
1091 else
1092 {
1093 value_s = ecpg_alloc(ecpg_hex_enc_len(len) + 1, lineno);
1094 if (value_s != NULL)
1095 {
1096 ecpg_hex_encode(value, len, value_s);
1097 value_s[ecpg_hex_enc_len(len)] = '\0';
1098 malloced = true;
1099 }
1100 else
1101 value_s = "no memory for logging of parameter";
1102 }
1103
1104 ecpg_log("ecpg_free_params on line %d: parameter %d = %s\n",
1105 lineno, nth, value_s);
1106
1107 if (malloced)
1108 ecpg_free(value_s);
1109 }
1110
1111 void
ecpg_free_params(struct statement * stmt,bool print)1112 ecpg_free_params(struct statement *stmt, bool print)
1113 {
1114 int n;
1115
1116 for (n = 0; n < stmt->nparams; n++)
1117 {
1118 if (print)
1119 print_param_value(stmt->paramvalues[n], stmt->paramlengths[n],
1120 stmt->paramformats[n], stmt->lineno, n + 1);
1121 ecpg_free(stmt->paramvalues[n]);
1122 }
1123 ecpg_free(stmt->paramvalues);
1124 ecpg_free(stmt->paramlengths);
1125 ecpg_free(stmt->paramformats);
1126 stmt->paramvalues = NULL;
1127 stmt->paramlengths = NULL;
1128 stmt->paramformats = NULL;
1129 stmt->nparams = 0;
1130 }
1131
1132 static bool
insert_tobeinserted(int position,int ph_len,struct statement * stmt,char * tobeinserted)1133 insert_tobeinserted(int position, int ph_len, struct statement *stmt, char *tobeinserted)
1134 {
1135 char *newcopy;
1136
1137 if (!(newcopy = (char *) ecpg_alloc(strlen(stmt->command)
1138 + strlen(tobeinserted)
1139 + 1, stmt->lineno)))
1140 {
1141 ecpg_free(tobeinserted);
1142 return false;
1143 }
1144
1145 strcpy(newcopy, stmt->command);
1146 strcpy(newcopy + position - 1, tobeinserted);
1147
1148 /*
1149 * The strange thing in the second argument is the rest of the string from
1150 * the old string
1151 */
1152 strcat(newcopy,
1153 stmt->command
1154 + position
1155 + ph_len - 1);
1156
1157 ecpg_free(stmt->command);
1158 stmt->command = newcopy;
1159
1160 ecpg_free(tobeinserted);
1161 return true;
1162 }
1163
1164 static bool
store_input_from_desc(struct statement * stmt,struct descriptor_item * desc_item,char ** tobeinserted)1165 store_input_from_desc(struct statement *stmt, struct descriptor_item *desc_item,
1166 char **tobeinserted)
1167 {
1168 struct variable var;
1169
1170 /*
1171 * In case of binary data, only allocate memory and memcpy because binary
1172 * data have been already stored into desc_item->data with
1173 * ecpg_store_input() at ECPGset_desc().
1174 */
1175 if (desc_item->is_binary)
1176 {
1177 if (!(*tobeinserted = ecpg_alloc(desc_item->data_len, stmt->lineno)))
1178 return false;
1179 memcpy(*tobeinserted, desc_item->data, desc_item->data_len);
1180 return true;
1181 }
1182
1183 var.type = ECPGt_char;
1184 var.varcharsize = strlen(desc_item->data);
1185 var.value = desc_item->data;
1186 var.pointer = &(desc_item->data);
1187 var.arrsize = 1;
1188 var.offset = 0;
1189
1190 if (!desc_item->indicator)
1191 {
1192 var.ind_type = ECPGt_NO_INDICATOR;
1193 var.ind_value = var.ind_pointer = NULL;
1194 var.ind_varcharsize = var.ind_arrsize = var.ind_offset = 0;
1195 }
1196 else
1197 {
1198 var.ind_type = ECPGt_int;
1199 var.ind_value = &(desc_item->indicator);
1200 var.ind_pointer = &(var.ind_value);
1201 var.ind_varcharsize = var.ind_arrsize = 1;
1202 var.ind_offset = 0;
1203 }
1204
1205 if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &var, tobeinserted, false))
1206 return false;
1207
1208 return true;
1209 }
1210
1211 /*
1212 * ecpg_build_params
1213 * Build statement parameters
1214 *
1215 * The input values are taken from user variables, and the results are stored
1216 * in arrays which can be used by PQexecParams().
1217 */
1218 bool
ecpg_build_params(struct statement * stmt)1219 ecpg_build_params(struct statement *stmt)
1220 {
1221 struct variable *var;
1222 int desc_counter = 0;
1223 int position = 0;
1224 const char *value;
1225 bool std_strings = false;
1226
1227 /* Get standard_conforming_strings setting. */
1228 value = PQparameterStatus(stmt->connection->connection, "standard_conforming_strings");
1229 if (value && strcmp(value, "on") == 0)
1230 std_strings = true;
1231
1232 /*
1233 * If the type is one of the fill in types then we take the argument and
1234 * enter it to our parameter array at the first position. Then if there
1235 * are any more fill in types we add more parameters.
1236 */
1237 var = stmt->inlist;
1238 while (var)
1239 {
1240 char *tobeinserted;
1241 int counter = 1;
1242 bool binary_format;
1243 int binary_length;
1244
1245
1246 tobeinserted = NULL;
1247 binary_length = 0;
1248 binary_format = false;
1249
1250 /*
1251 * A descriptor is a special case since it contains many variables but
1252 * is listed only once.
1253 */
1254 if (var->type == ECPGt_descriptor)
1255 {
1256 /*
1257 * We create an additional variable list here, so the same logic
1258 * applies.
1259 */
1260 struct descriptor *desc;
1261 struct descriptor_item *desc_item;
1262
1263 desc = ecpg_find_desc(stmt->lineno, var->pointer);
1264 if (desc == NULL)
1265 return false;
1266
1267 desc_counter++;
1268 for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
1269 {
1270 if (desc_item->num != desc_counter)
1271 continue;
1272
1273 if (!store_input_from_desc(stmt, desc_item, &tobeinserted))
1274 return false;
1275
1276 if (desc_item->is_binary)
1277 {
1278 binary_length = desc_item->data_len;
1279 binary_format = true;
1280 }
1281 break;
1282 }
1283 if (desc->count == desc_counter)
1284 desc_counter = 0;
1285 }
1286 else if (var->type == ECPGt_sqlda)
1287 {
1288 if (INFORMIX_MODE(stmt->compat))
1289 {
1290 struct sqlda_compat *sqlda = *(struct sqlda_compat **) var->pointer;
1291 struct variable desc_inlist;
1292 int i;
1293
1294 if (sqlda == NULL)
1295 return false;
1296
1297 desc_counter++;
1298 for (i = 0; i < sqlda->sqld; i++)
1299 {
1300 if (i + 1 == desc_counter)
1301 {
1302 desc_inlist.type = sqlda->sqlvar[i].sqltype;
1303 desc_inlist.value = sqlda->sqlvar[i].sqldata;
1304 desc_inlist.pointer = &(sqlda->sqlvar[i].sqldata);
1305 switch (desc_inlist.type)
1306 {
1307 case ECPGt_char:
1308 case ECPGt_varchar:
1309 desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
1310 break;
1311 default:
1312 desc_inlist.varcharsize = 0;
1313 break;
1314 }
1315 desc_inlist.arrsize = 1;
1316 desc_inlist.offset = 0;
1317 if (sqlda->sqlvar[i].sqlind)
1318 {
1319 desc_inlist.ind_type = ECPGt_short;
1320 /* ECPG expects indicator value < 0 */
1321 if (*(sqlda->sqlvar[i].sqlind))
1322 *(sqlda->sqlvar[i].sqlind) = -1;
1323 desc_inlist.ind_value = sqlda->sqlvar[i].sqlind;
1324 desc_inlist.ind_pointer = &(sqlda->sqlvar[i].sqlind);
1325 desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;
1326 desc_inlist.ind_offset = 0;
1327 }
1328 else
1329 {
1330 desc_inlist.ind_type = ECPGt_NO_INDICATOR;
1331 desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
1332 desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
1333 }
1334 if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))
1335 return false;
1336
1337 break;
1338 }
1339 }
1340 if (sqlda->sqld == desc_counter)
1341 desc_counter = 0;
1342 }
1343 else
1344 {
1345 struct sqlda_struct *sqlda = *(struct sqlda_struct **) var->pointer;
1346 struct variable desc_inlist;
1347 int i;
1348
1349 if (sqlda == NULL)
1350 return false;
1351
1352 desc_counter++;
1353 for (i = 0; i < sqlda->sqln; i++)
1354 {
1355 if (i + 1 == desc_counter)
1356 {
1357 desc_inlist.type = sqlda->sqlvar[i].sqltype;
1358 desc_inlist.value = sqlda->sqlvar[i].sqldata;
1359 desc_inlist.pointer = &(sqlda->sqlvar[i].sqldata);
1360 switch (desc_inlist.type)
1361 {
1362 case ECPGt_char:
1363 case ECPGt_varchar:
1364 desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
1365 break;
1366 default:
1367 desc_inlist.varcharsize = 0;
1368 break;
1369 }
1370 desc_inlist.arrsize = 1;
1371 desc_inlist.offset = 0;
1372 if (sqlda->sqlvar[i].sqlind)
1373 {
1374 desc_inlist.ind_type = ECPGt_short;
1375 /* ECPG expects indicator value < 0 */
1376 if (*(sqlda->sqlvar[i].sqlind))
1377 *(sqlda->sqlvar[i].sqlind) = -1;
1378 desc_inlist.ind_value = sqlda->sqlvar[i].sqlind;
1379 desc_inlist.ind_pointer = &(sqlda->sqlvar[i].sqlind);
1380 desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;
1381 desc_inlist.ind_offset = 0;
1382 }
1383 else
1384 {
1385 desc_inlist.ind_type = ECPGt_NO_INDICATOR;
1386 desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
1387 desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
1388 }
1389 if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))
1390 return false;
1391
1392 break;
1393 }
1394 }
1395 if (sqlda->sqln == desc_counter)
1396 desc_counter = 0;
1397 }
1398
1399 }
1400 else
1401 {
1402 if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, false))
1403 return false;
1404
1405 if (var->type == ECPGt_bytea)
1406 {
1407 binary_length = ((struct ECPGgeneric_bytea *) (var->value))->len;
1408 binary_format = true;
1409 }
1410 }
1411
1412 /*
1413 * now tobeinserted points to an area that contains the next
1414 * parameter; now find the position in the string where it belongs
1415 */
1416 if ((position = next_insert(stmt->command, position, stmt->questionmarks, std_strings) + 1) == 0)
1417 {
1418 /*
1419 * We have an argument but we don't have the matched up
1420 * placeholder in the string
1421 */
1422 ecpg_raise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS,
1423 ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS,
1424 NULL);
1425 ecpg_free_params(stmt, false);
1426 ecpg_free(tobeinserted);
1427 return false;
1428 }
1429
1430 /*
1431 * if var->type=ECPGt_char_variable we have a dynamic cursor we have
1432 * to simulate a dynamic cursor because there is no backend
1433 * functionality for it
1434 */
1435 if (var->type == ECPGt_char_variable)
1436 {
1437 int ph_len = (stmt->command[position] == '?') ? strlen("?") : strlen("$1");
1438
1439 if (!insert_tobeinserted(position, ph_len, stmt, tobeinserted))
1440 {
1441 ecpg_free_params(stmt, false);
1442 return false;
1443 }
1444 tobeinserted = NULL;
1445 }
1446
1447 /*
1448 * if the placeholder is '$0' we have to replace it on the client side
1449 * this is for places we want to support variables at that are not
1450 * supported in the backend
1451 */
1452 else if (stmt->command[position] == '0')
1453 {
1454 if (stmt->statement_type == ECPGst_prepare ||
1455 stmt->statement_type == ECPGst_exec_with_exprlist)
1456 {
1457 /* Need to double-quote the inserted statement name. */
1458 char *str = ecpg_alloc(strlen(tobeinserted) + 2 + 1,
1459 stmt->lineno);
1460
1461 if (!str)
1462 {
1463 ecpg_free(tobeinserted);
1464 ecpg_free_params(stmt, false);
1465 return false;
1466 }
1467 sprintf(str, "\"%s\"", tobeinserted);
1468 ecpg_free(tobeinserted);
1469 tobeinserted = str;
1470 }
1471
1472 if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
1473 {
1474 ecpg_free_params(stmt, false);
1475 return false;
1476 }
1477 tobeinserted = NULL;
1478 }
1479 else if (stmt->statement_type == ECPGst_exec_with_exprlist)
1480 {
1481 if (binary_format)
1482 {
1483 char *p = convert_bytea_to_string(tobeinserted,
1484 binary_length,
1485 stmt->lineno);
1486
1487 ecpg_free(tobeinserted);
1488 if (!p)
1489 {
1490 ecpg_free_params(stmt, false);
1491 return false;
1492 }
1493 tobeinserted = p;
1494 }
1495
1496 if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
1497 {
1498 ecpg_free_params(stmt, false);
1499 return false;
1500 }
1501 tobeinserted = NULL;
1502 }
1503 else
1504 {
1505 bool realloc_failed = false;
1506 char **newparamvalues;
1507 int *newparamlengths;
1508 int *newparamformats;
1509
1510 /* enlarge all the param arrays */
1511 if ((newparamvalues = (char **) ecpg_realloc(stmt->paramvalues, sizeof(char *) * (stmt->nparams + 1), stmt->lineno)))
1512 stmt->paramvalues = newparamvalues;
1513 else
1514 realloc_failed = true;
1515
1516 if ((newparamlengths = (int *) ecpg_realloc(stmt->paramlengths, sizeof(int) * (stmt->nparams + 1), stmt->lineno)))
1517 stmt->paramlengths = newparamlengths;
1518 else
1519 realloc_failed = true;
1520
1521 if ((newparamformats = (int *) ecpg_realloc(stmt->paramformats, sizeof(int) * (stmt->nparams + 1), stmt->lineno)))
1522 stmt->paramformats = newparamformats;
1523 else
1524 realloc_failed = true;
1525
1526 if (realloc_failed)
1527 {
1528 ecpg_free_params(stmt, false);
1529 ecpg_free(tobeinserted);
1530 return false;
1531 }
1532
1533 /* only now can we assign ownership of "tobeinserted" to stmt */
1534 stmt->paramvalues[stmt->nparams] = tobeinserted;
1535 stmt->paramlengths[stmt->nparams] = binary_length;
1536 stmt->paramformats[stmt->nparams] = (binary_format ? 1 : 0);
1537 stmt->nparams++;
1538
1539 /* let's see if this was an old style placeholder */
1540 if (stmt->command[position] == '?')
1541 {
1542 /* yes, replace with new style */
1543 int buffersize = sizeof(int) * CHAR_BIT * 10 / 3; /* a rough guess of the
1544 * size we need */
1545
1546 if (!(tobeinserted = (char *) ecpg_alloc(buffersize, stmt->lineno)))
1547 {
1548 ecpg_free_params(stmt, false);
1549 return false;
1550 }
1551
1552 snprintf(tobeinserted, buffersize, "$%d", counter++);
1553
1554 if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
1555 {
1556 ecpg_free_params(stmt, false);
1557 return false;
1558 }
1559 tobeinserted = NULL;
1560 }
1561 }
1562
1563 if (desc_counter == 0)
1564 var = var->next;
1565 }
1566
1567 /*
1568 * Check if there are unmatched things left. PREPARE AS has no parameter.
1569 * Check other statement.
1570 */
1571 if (stmt->statement_type != ECPGst_prepare &&
1572 next_insert(stmt->command, position, stmt->questionmarks, std_strings) >= 0)
1573 {
1574 ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS,
1575 ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
1576 ecpg_free_params(stmt, false);
1577 return false;
1578 }
1579
1580 return true;
1581 }
1582
1583 /*
1584 * ecpg_autostart_transaction
1585 * If we are in non-autocommit mode, automatically start a transaction.
1586 */
1587 bool
ecpg_autostart_transaction(struct statement * stmt)1588 ecpg_autostart_transaction(struct statement *stmt)
1589 {
1590 if (PQtransactionStatus(stmt->connection->connection) == PQTRANS_IDLE && !stmt->connection->autocommit)
1591 {
1592 stmt->results = PQexec(stmt->connection->connection, "begin transaction");
1593 if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
1594 {
1595 ecpg_free_params(stmt, false);
1596 return false;
1597 }
1598 PQclear(stmt->results);
1599 stmt->results = NULL;
1600 }
1601 return true;
1602 }
1603
1604 /*
1605 * ecpg_execute
1606 * Execute the SQL statement.
1607 */
1608 bool
ecpg_execute(struct statement * stmt)1609 ecpg_execute(struct statement *stmt)
1610 {
1611 ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);
1612 if (stmt->statement_type == ECPGst_execute)
1613 {
1614 stmt->results = PQexecPrepared(stmt->connection->connection,
1615 stmt->name,
1616 stmt->nparams,
1617 (const char *const *) stmt->paramvalues,
1618 (const int *) stmt->paramlengths,
1619 (const int *) stmt->paramformats,
1620 0);
1621 ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command);
1622 }
1623 else
1624 {
1625 if (stmt->nparams == 0)
1626 {
1627 stmt->results = PQexec(stmt->connection->connection, stmt->command);
1628 ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt->lineno);
1629 }
1630 else
1631 {
1632 stmt->results = PQexecParams(stmt->connection->connection,
1633 stmt->command, stmt->nparams, NULL,
1634 (const char *const *) stmt->paramvalues,
1635 (const int *) stmt->paramlengths,
1636 (const int *) stmt->paramformats,
1637 0);
1638
1639 ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);
1640 }
1641
1642 if (stmt->statement_type == ECPGst_prepare)
1643 {
1644 if (!ecpg_register_prepared_stmt(stmt))
1645 {
1646 ecpg_free_params(stmt, true);
1647 return false;
1648 }
1649 }
1650 }
1651
1652 ecpg_free_params(stmt, true);
1653
1654 if (!ecpg_check_PQresult(stmt->results, stmt->lineno, stmt->connection->connection, stmt->compat))
1655 return false;
1656
1657 return true;
1658 }
1659
1660 /*-------
1661 * ecpg_process_output
1662 *
1663 * Process the statement result and store it into application variables. This
1664 * function can be called repeatedly during the same statement in case cursor
1665 * readahead is used and the application does FETCH N which overflows the
1666 * readahead window.
1667 *
1668 * Parameters
1669 * stmt statement structure holding the PGresult and
1670 * the list of output variables
1671 * clear_result
1672 * PQclear() the result upon returning from this function
1673 *
1674 * Returns success as boolean. Also an SQL error is raised in case of failure.
1675 *-------
1676 */
1677 bool
ecpg_process_output(struct statement * stmt,bool clear_result)1678 ecpg_process_output(struct statement *stmt, bool clear_result)
1679 {
1680 struct variable *var;
1681 bool status = false;
1682 char *cmdstat;
1683 PGnotify *notify;
1684 struct sqlca_t *sqlca = ECPGget_sqlca();
1685 int nfields,
1686 ntuples,
1687 act_field;
1688
1689 if (sqlca == NULL)
1690 {
1691 ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY,
1692 ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
1693 return false;
1694 }
1695
1696 var = stmt->outlist;
1697 switch (PQresultStatus(stmt->results))
1698 {
1699 case PGRES_TUPLES_OK:
1700 nfields = PQnfields(stmt->results);
1701 sqlca->sqlerrd[2] = ntuples = PQntuples(stmt->results);
1702
1703 ecpg_log("ecpg_process_output on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);
1704 status = true;
1705
1706 if (ntuples < 1)
1707 {
1708 if (ntuples)
1709 ecpg_log("ecpg_process_output on line %d: incorrect number of matches (%d)\n",
1710 stmt->lineno, ntuples);
1711 ecpg_raise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
1712 status = false;
1713 break;
1714 }
1715
1716 if (var != NULL && var->type == ECPGt_descriptor)
1717 {
1718 struct descriptor *desc = ecpg_find_desc(stmt->lineno, var->pointer);
1719
1720 if (desc == NULL)
1721 status = false;
1722 else
1723 {
1724 if (desc->result)
1725 PQclear(desc->result);
1726 desc->result = stmt->results;
1727 clear_result = false;
1728 ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",
1729 stmt->lineno, PQntuples(stmt->results), (const char *) var->pointer);
1730 }
1731 var = var->next;
1732 }
1733 else if (var != NULL && var->type == ECPGt_sqlda)
1734 {
1735 if (INFORMIX_MODE(stmt->compat))
1736 {
1737 struct sqlda_compat **_sqlda = (struct sqlda_compat **) var->pointer;
1738 struct sqlda_compat *sqlda = *_sqlda;
1739 struct sqlda_compat *sqlda_new;
1740 int i;
1741
1742 /*
1743 * If we are passed in a previously existing sqlda (chain)
1744 * then free it.
1745 */
1746 while (sqlda)
1747 {
1748 sqlda_new = sqlda->desc_next;
1749 free(sqlda);
1750 sqlda = sqlda_new;
1751 }
1752 *_sqlda = sqlda = sqlda_new = NULL;
1753 for (i = ntuples - 1; i >= 0; i--)
1754 {
1755 /*
1756 * Build a new sqlda structure. Note that only
1757 * fetching 1 record is supported
1758 */
1759 sqlda_new = ecpg_build_compat_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
1760
1761 if (!sqlda_new)
1762 {
1763 /* cleanup all SQLDAs we created up */
1764 while (sqlda)
1765 {
1766 sqlda_new = sqlda->desc_next;
1767 free(sqlda);
1768 sqlda = sqlda_new;
1769 }
1770 *_sqlda = NULL;
1771
1772 ecpg_log("ecpg_process_output on line %d: out of memory allocating a new sqlda\n", stmt->lineno);
1773 status = false;
1774 break;
1775 }
1776 else
1777 {
1778 ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
1779
1780 *_sqlda = sqlda_new;
1781
1782 ecpg_set_compat_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
1783 ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
1784 stmt->lineno, PQnfields(stmt->results));
1785
1786 sqlda_new->desc_next = sqlda;
1787 sqlda = sqlda_new;
1788 }
1789 }
1790 }
1791 else
1792 {
1793 struct sqlda_struct **_sqlda = (struct sqlda_struct **) var->pointer;
1794 struct sqlda_struct *sqlda = *_sqlda;
1795 struct sqlda_struct *sqlda_new;
1796 int i;
1797
1798 /*
1799 * If we are passed in a previously existing sqlda (chain)
1800 * then free it.
1801 */
1802 while (sqlda)
1803 {
1804 sqlda_new = sqlda->desc_next;
1805 free(sqlda);
1806 sqlda = sqlda_new;
1807 }
1808 *_sqlda = sqlda = sqlda_new = NULL;
1809 for (i = ntuples - 1; i >= 0; i--)
1810 {
1811 /*
1812 * Build a new sqlda structure. Note that only
1813 * fetching 1 record is supported
1814 */
1815 sqlda_new = ecpg_build_native_sqlda(stmt->lineno, stmt->results, i, stmt->compat);
1816
1817 if (!sqlda_new)
1818 {
1819 /* cleanup all SQLDAs we created up */
1820 while (sqlda)
1821 {
1822 sqlda_new = sqlda->desc_next;
1823 free(sqlda);
1824 sqlda = sqlda_new;
1825 }
1826 *_sqlda = NULL;
1827
1828 ecpg_log("ecpg_process_output on line %d: out of memory allocating a new sqlda\n", stmt->lineno);
1829 status = false;
1830 break;
1831 }
1832 else
1833 {
1834 ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);
1835
1836 *_sqlda = sqlda_new;
1837
1838 ecpg_set_native_sqlda(stmt->lineno, _sqlda, stmt->results, i, stmt->compat);
1839 ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",
1840 stmt->lineno, PQnfields(stmt->results));
1841
1842 sqlda_new->desc_next = sqlda;
1843 sqlda = sqlda_new;
1844 }
1845 }
1846 }
1847
1848 var = var->next;
1849 }
1850 else
1851 for (act_field = 0; act_field < nfields && status; act_field++)
1852 {
1853 if (var != NULL)
1854 {
1855 status = ecpg_store_result(stmt->results, act_field, stmt, var);
1856 var = var->next;
1857 }
1858 else if (!INFORMIX_MODE(stmt->compat))
1859 {
1860 ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS, NULL);
1861 return false;
1862 }
1863 }
1864
1865 if (status && var != NULL)
1866 {
1867 ecpg_raise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS, NULL);
1868 status = false;
1869 }
1870
1871 break;
1872 case PGRES_COMMAND_OK:
1873 status = true;
1874 cmdstat = PQcmdStatus(stmt->results);
1875 sqlca->sqlerrd[1] = PQoidValue(stmt->results);
1876 sqlca->sqlerrd[2] = atol(PQcmdTuples(stmt->results));
1877 ecpg_log("ecpg_process_output on line %d: OK: %s\n", stmt->lineno, cmdstat);
1878 if (stmt->compat != ECPG_COMPAT_INFORMIX_SE &&
1879 !sqlca->sqlerrd[2] &&
1880 (strncmp(cmdstat, "UPDATE", 6) == 0
1881 || strncmp(cmdstat, "INSERT", 6) == 0
1882 || strncmp(cmdstat, "DELETE", 6) == 0))
1883 ecpg_raise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
1884 break;
1885 case PGRES_COPY_OUT:
1886 {
1887 char *buffer;
1888 int res;
1889
1890 ecpg_log("ecpg_process_output on line %d: COPY OUT data transfer in progress\n", stmt->lineno);
1891 while ((res = PQgetCopyData(stmt->connection->connection,
1892 &buffer, 0)) > 0)
1893 {
1894 printf("%s", buffer);
1895 PQfreemem(buffer);
1896 }
1897 if (res == -1)
1898 {
1899 /* COPY done */
1900 PQclear(stmt->results);
1901 stmt->results = PQgetResult(stmt->connection->connection);
1902 if (PQresultStatus(stmt->results) == PGRES_COMMAND_OK)
1903 ecpg_log("ecpg_process_output on line %d: got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt->lineno);
1904 else
1905 ecpg_log("ecpg_process_output on line %d: got error after PGRES_COPY_OUT: %s", stmt->lineno, PQresultErrorMessage(stmt->results));
1906 }
1907 break;
1908 }
1909 default:
1910
1911 /*
1912 * execution should never reach this code because it is already
1913 * handled in ECPGcheck_PQresult()
1914 */
1915 ecpg_log("ecpg_process_output on line %d: unknown execution status type\n",
1916 stmt->lineno);
1917 ecpg_raise_backend(stmt->lineno, stmt->results, stmt->connection->connection, stmt->compat);
1918 status = false;
1919 break;
1920 }
1921
1922 if (clear_result)
1923 {
1924 PQclear(stmt->results);
1925 stmt->results = NULL;
1926 }
1927
1928 /* check for asynchronous returns */
1929 PQconsumeInput(stmt->connection->connection);
1930 while ((notify = PQnotifies(stmt->connection->connection)) != NULL)
1931 {
1932 ecpg_log("ecpg_process_output on line %d: asynchronous notification of \"%s\" from backend PID %d received\n",
1933 stmt->lineno, notify->relname, notify->be_pid);
1934 PQfreemem(notify);
1935 PQconsumeInput(stmt->connection->connection);
1936 }
1937
1938 return status;
1939 }
1940
1941 /*
1942 * ecpg_do_prologue
1943 *
1944 * Initialize various infrastructure elements for executing the statement:
1945 *
1946 * - create the statement structure
1947 * - set the C numeric locale for communicating with the backend
1948 * - preprocess the variable list of input/output parameters into
1949 * linked lists
1950 */
1951 bool
ecpg_do_prologue(int lineno,const int compat,const int force_indicator,const char * connection_name,const bool questionmarks,enum ECPG_statement_type statement_type,const char * query,va_list args,struct statement ** stmt_out)1952 ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
1953 const char *connection_name, const bool questionmarks,
1954 enum ECPG_statement_type statement_type, const char *query,
1955 va_list args, struct statement **stmt_out)
1956 {
1957 struct statement *stmt = NULL;
1958 struct connection *con;
1959 enum ECPGttype type;
1960 struct variable **list;
1961 char *prepname;
1962 bool is_prepared_name_set;
1963
1964 *stmt_out = NULL;
1965
1966 if (!query)
1967 {
1968 ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
1969 return false;
1970 }
1971
1972 stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno);
1973
1974 if (stmt == NULL)
1975 return false;
1976
1977 /*
1978 * Make sure we do NOT honor the locale for numeric input/output since the
1979 * database wants the standard decimal point. If available, use
1980 * uselocale() for this because it's thread-safe. Windows doesn't have
1981 * that, but it usually does have _configthreadlocale(). In some versions
1982 * of MinGW, _configthreadlocale() exists but always returns -1 --- so
1983 * treat that situation as if the function doesn't exist.
1984 */
1985 #ifdef HAVE_USELOCALE
1986 stmt->clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
1987 if (stmt->clocale == (locale_t) 0)
1988 {
1989 ecpg_do_epilogue(stmt);
1990 return false;
1991 }
1992 stmt->oldlocale = uselocale(stmt->clocale);
1993 if (stmt->oldlocale == (locale_t) 0)
1994 {
1995 ecpg_do_epilogue(stmt);
1996 return false;
1997 }
1998 #else
1999 #ifdef HAVE__CONFIGTHREADLOCALE
2000 stmt->oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
2001 #endif
2002 stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
2003 if (stmt->oldlocale == NULL)
2004 {
2005 ecpg_do_epilogue(stmt);
2006 return false;
2007 }
2008 setlocale(LC_NUMERIC, "C");
2009 #endif
2010
2011 #ifdef ENABLE_THREAD_SAFETY
2012 ecpg_pthreads_init();
2013 #endif
2014
2015 con = ecpg_get_connection(connection_name);
2016
2017 if (!ecpg_init(con, connection_name, lineno))
2018 {
2019 ecpg_do_epilogue(stmt);
2020 return false;
2021 }
2022
2023 /*
2024 * If statement type is ECPGst_prepnormal we are supposed to prepare the
2025 * statement before executing them
2026 */
2027 if (statement_type == ECPGst_prepnormal)
2028 {
2029 if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
2030 {
2031 ecpg_do_epilogue(stmt);
2032 return false;
2033 }
2034
2035 /*
2036 * statement is now prepared, so instead of the query we have to
2037 * execute the name
2038 */
2039 stmt->command = prepname;
2040 statement_type = ECPGst_execute;
2041 }
2042 else
2043 stmt->command = ecpg_strdup(query, lineno);
2044
2045 stmt->name = NULL;
2046
2047 if (statement_type == ECPGst_execute)
2048 {
2049 /* if we have an EXECUTE command, only the name is send */
2050 char *command = ecpg_prepared(stmt->command, con);
2051
2052 if (command)
2053 {
2054 stmt->name = stmt->command;
2055 stmt->command = ecpg_strdup(command, lineno);
2056 }
2057 else
2058 {
2059 ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
2060 ecpg_do_epilogue(stmt);
2061 return false;
2062 }
2063 }
2064 /* name of PREPARE AS will be set in loop of inlist */
2065
2066 stmt->connection = con;
2067 stmt->lineno = lineno;
2068 stmt->compat = compat;
2069 stmt->force_indicator = force_indicator;
2070 stmt->questionmarks = questionmarks;
2071 stmt->statement_type = statement_type;
2072
2073 /*------
2074 * create a list of variables
2075 *
2076 * The variables are listed with input variables preceding outputvariables
2077 * The end of each group is marked by an end marker. per variable we list:
2078 *
2079 * type - as defined in ecpgtype.h
2080 * value - where to store the data
2081 * varcharsize - length of string in case we have a stringvariable, else 0
2082 * arraysize - 0 for pointer (we don't know the size of the array), 1 for
2083 * simple variable, size for arrays
2084 * offset - offset between ith and (i+1)th entry in an array, normally
2085 * that means sizeof(type)
2086 * ind_type - type of indicator variable
2087 * ind_value - pointer to indicator variable
2088 * ind_varcharsize - empty
2089 * ind_arraysize - arraysize of indicator array
2090 * ind_offset - indicator offset
2091 *------
2092 */
2093
2094 is_prepared_name_set = false;
2095
2096 list = &(stmt->inlist);
2097
2098 type = va_arg(args, enum ECPGttype);
2099
2100 while (type != ECPGt_EORT)
2101 {
2102 if (type == ECPGt_EOIT)
2103 list = &(stmt->outlist);
2104 else
2105 {
2106 struct variable *var,
2107 *ptr;
2108
2109 if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
2110 {
2111 ecpg_do_epilogue(stmt);
2112 return false;
2113 }
2114
2115 var->type = type;
2116 var->pointer = va_arg(args, char *);
2117
2118 var->varcharsize = va_arg(args, long);
2119 var->arrsize = va_arg(args, long);
2120 var->offset = va_arg(args, long);
2121
2122 /*
2123 * Unknown array size means pointer to an array. Unknown
2124 * varcharsize usually also means pointer. But if the type is
2125 * character and the array size is known, it is an array of
2126 * pointers to char, so use var->pointer as it is.
2127 */
2128 if (var->arrsize == 0 ||
2129 (var->varcharsize == 0 && ((var->type != ECPGt_char && var->type != ECPGt_unsigned_char) || (var->arrsize <= 1))))
2130 var->value = *((char **) (var->pointer));
2131 else
2132 var->value = var->pointer;
2133
2134 /*
2135 * negative values are used to indicate an array without given
2136 * bounds
2137 */
2138 /* reset to zero for us */
2139 if (var->arrsize < 0)
2140 var->arrsize = 0;
2141 if (var->varcharsize < 0)
2142 var->varcharsize = 0;
2143
2144 var->next = NULL;
2145
2146 var->ind_type = va_arg(args, enum ECPGttype);
2147 var->ind_pointer = va_arg(args, char *);
2148 var->ind_varcharsize = va_arg(args, long);
2149 var->ind_arrsize = va_arg(args, long);
2150 var->ind_offset = va_arg(args, long);
2151
2152 if (var->ind_type != ECPGt_NO_INDICATOR
2153 && (var->ind_arrsize == 0 || var->ind_varcharsize == 0))
2154 var->ind_value = *((char **) (var->ind_pointer));
2155 else
2156 var->ind_value = var->ind_pointer;
2157
2158 /*
2159 * negative values are used to indicate an array without given
2160 * bounds
2161 */
2162 /* reset to zero for us */
2163 if (var->ind_arrsize < 0)
2164 var->ind_arrsize = 0;
2165 if (var->ind_varcharsize < 0)
2166 var->ind_varcharsize = 0;
2167
2168 /* if variable is NULL, the statement hasn't been prepared */
2169 if (var->pointer == NULL)
2170 {
2171 ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
2172 ecpg_free(var);
2173 ecpg_do_epilogue(stmt);
2174 return false;
2175 }
2176
2177 for (ptr = *list; ptr && ptr->next; ptr = ptr->next)
2178 ;
2179
2180 if (ptr == NULL)
2181 *list = var;
2182 else
2183 ptr->next = var;
2184
2185 if (!is_prepared_name_set && stmt->statement_type == ECPGst_prepare)
2186 {
2187 stmt->name = ecpg_strdup(var->value, lineno);
2188 is_prepared_name_set = true;
2189 }
2190 }
2191
2192 type = va_arg(args, enum ECPGttype);
2193 }
2194
2195 /* are we connected? */
2196 if (con == NULL || con->connection == NULL)
2197 {
2198 ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
2199 ecpg_do_epilogue(stmt);
2200 return false;
2201 }
2202
2203 if (!is_prepared_name_set && stmt->statement_type == ECPGst_prepare)
2204 {
2205 ecpg_raise(lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
2206 ecpg_do_epilogue(stmt);
2207 return false;
2208 }
2209
2210 /* initialize auto_mem struct */
2211 ecpg_clear_auto_mem();
2212
2213 *stmt_out = stmt;
2214
2215 return true;
2216 }
2217
2218 /*
2219 * ecpg_do_epilogue
2220 * Restore the application locale and free the statement structure.
2221 */
2222 void
ecpg_do_epilogue(struct statement * stmt)2223 ecpg_do_epilogue(struct statement *stmt)
2224 {
2225 if (stmt == NULL)
2226 return;
2227
2228 #ifdef HAVE_USELOCALE
2229 if (stmt->oldlocale != (locale_t) 0)
2230 uselocale(stmt->oldlocale);
2231 #else
2232 if (stmt->oldlocale)
2233 setlocale(LC_NUMERIC, stmt->oldlocale);
2234 #ifdef HAVE__CONFIGTHREADLOCALE
2235
2236 /*
2237 * This is a bit trickier than it looks: if we failed partway through
2238 * statement initialization, oldthreadlocale could still be 0. But that's
2239 * okay because a call with 0 is defined to be a no-op.
2240 */
2241 if (stmt->oldthreadlocale != -1)
2242 (void) _configthreadlocale(stmt->oldthreadlocale);
2243 #endif
2244 #endif
2245
2246 free_statement(stmt);
2247 }
2248
2249 /*
2250 * Execute SQL statements in the backend.
2251 * The input/output parameters (variable argument list) are passed
2252 * in a va_list, so other functions can use this interface.
2253 */
2254 bool
ecpg_do(const int lineno,const int compat,const int force_indicator,const char * connection_name,const bool questionmarks,const int st,const char * query,va_list args)2255 ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)
2256 {
2257 struct statement *stmt = NULL;
2258
2259 if (!ecpg_do_prologue(lineno, compat, force_indicator, connection_name,
2260 questionmarks, (enum ECPG_statement_type) st,
2261 query, args, &stmt))
2262 goto fail;
2263
2264 if (!ecpg_build_params(stmt))
2265 goto fail;
2266
2267 if (!ecpg_autostart_transaction(stmt))
2268 goto fail;
2269
2270 if (!ecpg_execute(stmt))
2271 goto fail;
2272
2273 if (!ecpg_process_output(stmt, true))
2274 goto fail;
2275
2276 ecpg_do_epilogue(stmt);
2277 return true;
2278
2279 fail:
2280 ecpg_do_epilogue(stmt);
2281 return false;
2282 }
2283
2284 /*
2285 * Execute SQL statements in the backend.
2286 * The input/output parameters are passed as variable-length argument list.
2287 */
2288 bool
ECPGdo(const int lineno,const int compat,const int force_indicator,const char * connection_name,const bool questionmarks,const int st,const char * query,...)2289 ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)
2290 {
2291 va_list args;
2292 bool ret;
2293
2294 va_start(args, query);
2295 ret = ecpg_do(lineno, compat, force_indicator, connection_name,
2296 questionmarks, st, query, args);
2297 va_end(args);
2298
2299 return ret;
2300 }
2301
2302 /* old descriptor interface */
2303 bool
ECPGdo_descriptor(int line,const char * connection,const char * descriptor,const char * query)2304 ECPGdo_descriptor(int line, const char *connection,
2305 const char *descriptor, const char *query)
2306 {
2307 return ECPGdo(line, ECPG_COMPAT_PGSQL, true, connection, '\0', 0, query, ECPGt_EOIT,
2308 ECPGt_descriptor, descriptor, 0L, 0L, 0L,
2309 ECPGt_NO_INDICATOR, NULL, 0L, 0L, 0L, ECPGt_EORT);
2310 }
2311