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