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