PostgreSQL Source Code  git master
descriptor.c
Go to the documentation of this file.
1 /* dynamic SQL support routines
2  *
3  * src/interfaces/ecpg/ecpglib/descriptor.c
4  */
5 
6 #define POSTGRES_ECPG_INTERNAL
7 #include "postgres_fe.h"
8 
9 #include "catalog/pg_type_d.h"
10 #include "ecpg-pthread-win32.h"
11 #include "ecpgerrno.h"
12 #include "ecpglib.h"
13 #include "ecpglib_extern.h"
14 #include "ecpgtype.h"
15 #include "sqlca.h"
16 #include "sqlda.h"
17 #include "sql3types.h"
18 
19 static void descriptor_free(struct descriptor *desc);
20 
21 /* We manage descriptors separately for each thread. */
22 #ifdef ENABLE_THREAD_SAFETY
23 static pthread_key_t descriptor_key;
24 static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT;
25 
26 static void descriptor_deallocate_all(struct descriptor *list);
27 
28 static void
29 descriptor_destructor(void *arg)
30 {
31  descriptor_deallocate_all(arg);
32 }
33 
34 static void
35 descriptor_key_init(void)
36 {
37  pthread_key_create(&descriptor_key, descriptor_destructor);
38 }
39 
40 static struct descriptor *
41 get_descriptors(void)
42 {
43  pthread_once(&descriptor_once, descriptor_key_init);
44  return (struct descriptor *) pthread_getspecific(descriptor_key);
45 }
46 
47 static void
49 {
50  pthread_setspecific(descriptor_key, value);
51 }
52 #else
53 static struct descriptor *all_descriptors = NULL;
54 
55 #define get_descriptors() (all_descriptors)
56 #define set_descriptors(value) do { all_descriptors = (value); } while(0)
57 #endif
58 
59 /* old internal convenience function that might go away later */
60 static PGresult *
61 ecpg_result_by_descriptor(int line, const char *name)
62 {
63  struct descriptor *desc = ecpg_find_desc(line, name);
64 
65  if (desc == NULL)
66  return NULL;
67  return desc->result;
68 }
69 
70 static unsigned int
72 {
73  switch (type)
74  {
75  case DATEOID:
76  return SQL3_DDT_DATE;
77  case TIMEOID:
78  return SQL3_DDT_TIME;
79  case TIMESTAMPOID:
80  return SQL3_DDT_TIMESTAMP;
81  case TIMESTAMPTZOID:
83  case TIMETZOID:
85  default:
86  return SQL3_DDT_ILLEGAL;
87  }
88 }
89 
90 bool
91 ECPGget_desc_header(int lineno, const char *desc_name, int *count)
92 {
93  PGresult *ECPGresult;
94  struct sqlca_t *sqlca = ECPGget_sqlca();
95 
96  if (sqlca == NULL)
97  {
100  return false;
101  }
102 
103  ecpg_init_sqlca(sqlca);
104  ECPGresult = ecpg_result_by_descriptor(lineno, desc_name);
105  if (!ECPGresult)
106  return false;
107 
108  *count = PQnfields(ECPGresult);
109  sqlca->sqlerrd[2] = 1;
110  ecpg_log("ECPGget_desc_header: found %d attributes\n", *count);
111  return true;
112 }
113 
114 static bool
115 get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
116 {
117  switch (vartype)
118  {
119  case ECPGt_short:
120  *(short *) var = (short) value;
121  break;
122  case ECPGt_int:
123  *(int *) var = (int) value;
124  break;
125  case ECPGt_long:
126  *(long *) var = (long) value;
127  break;
129  *(unsigned short *) var = (unsigned short) value;
130  break;
131  case ECPGt_unsigned_int:
132  *(unsigned int *) var = (unsigned int) value;
133  break;
134  case ECPGt_unsigned_long:
135  *(unsigned long *) var = (unsigned long) value;
136  break;
137  case ECPGt_long_long:
138  *(long long int *) var = (long long int) value;
139  break;
141  *(unsigned long long int *) var = (unsigned long long int) value;
142  break;
143  case ECPGt_float:
144  *(float *) var = (float) value;
145  break;
146  case ECPGt_double:
147  *(double *) var = (double) value;
148  break;
149  default:
151  return false;
152  }
153 
154  return true;
155 }
156 
157 static bool
158 set_int_item(int lineno, int *target, const void *var, enum ECPGttype vartype)
159 {
160  switch (vartype)
161  {
162  case ECPGt_short:
163  *target = *(const short *) var;
164  break;
165  case ECPGt_int:
166  *target = *(const int *) var;
167  break;
168  case ECPGt_long:
169  *target = *(const long *) var;
170  break;
172  *target = *(const unsigned short *) var;
173  break;
174  case ECPGt_unsigned_int:
175  *target = *(const unsigned int *) var;
176  break;
177  case ECPGt_unsigned_long:
178  *target = *(const unsigned long *) var;
179  break;
180  case ECPGt_long_long:
181  *target = *(const long long int *) var;
182  break;
184  *target = *(const unsigned long long int *) var;
185  break;
186  case ECPGt_float:
187  *target = *(const float *) var;
188  break;
189  case ECPGt_double:
190  *target = *(const double *) var;
191  break;
192  default:
194  return false;
195  }
196 
197  return true;
198 }
199 
200 static bool
201 get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int varcharsize)
202 {
203  switch (vartype)
204  {
205  case ECPGt_char:
206  case ECPGt_unsigned_char:
207  case ECPGt_string:
208  strncpy((char *) var, value, varcharsize);
209  break;
210  case ECPGt_varchar:
211  {
212  struct ECPGgeneric_varchar *variable =
213  (struct ECPGgeneric_varchar *) var;
214 
215  if (varcharsize == 0)
216  memcpy(variable->arr, value, strlen(value));
217  else
218  strncpy(variable->arr, value, varcharsize);
219 
220  variable->len = strlen(value);
221  if (varcharsize > 0 && variable->len > varcharsize)
222  variable->len = varcharsize;
223  }
224  break;
225  default:
227  return false;
228  }
229 
230  return true;
231 }
232 
233 #define RETURN_IF_NO_DATA if (ntuples < 1) \
234  { \
235  va_end(args); \
236  ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL); \
237  return false; \
238  }
239 
240 bool
241 ECPGget_desc(int lineno, const char *desc_name, int index,...)
242 {
243  va_list args;
244  PGresult *ECPGresult;
245  enum ECPGdtype type;
246  int ntuples,
247  act_tuple;
248  struct variable data_var;
249  struct sqlca_t *sqlca = ECPGget_sqlca();
250 
251  if (sqlca == NULL)
252  {
255  return false;
256  }
257 
258  va_start(args, index);
259  ecpg_init_sqlca(sqlca);
260  ECPGresult = ecpg_result_by_descriptor(lineno, desc_name);
261  if (!ECPGresult)
262  {
263  va_end(args);
264  return false;
265  }
266 
267  ntuples = PQntuples(ECPGresult);
268 
269  if (index < 1 || index > PQnfields(ECPGresult))
270  {
272  va_end(args);
273  return false;
274  }
275 
276  ecpg_log("ECPGget_desc: reading items for tuple %d\n", index);
277  --index;
278 
279  type = va_arg(args, enum ECPGdtype);
280 
281  memset(&data_var, 0, sizeof data_var);
282  data_var.type = ECPGt_EORT;
283  data_var.ind_type = ECPGt_NO_INDICATOR;
284 
285  while (type != ECPGd_EODT)
286  {
287  char type_str[20];
288  long varcharsize;
289  long offset;
290  long arrsize;
291  enum ECPGttype vartype;
292  void *var;
293 
294  vartype = va_arg(args, enum ECPGttype);
295  var = va_arg(args, void *);
296  varcharsize = va_arg(args, long);
297  arrsize = va_arg(args, long);
298  offset = va_arg(args, long);
299 
300  switch (type)
301  {
302  case (ECPGd_indicator):
304  data_var.ind_type = vartype;
305  data_var.ind_pointer = var;
306  data_var.ind_varcharsize = varcharsize;
307  data_var.ind_arrsize = arrsize;
308  data_var.ind_offset = offset;
309  if (data_var.ind_arrsize == 0 || data_var.ind_varcharsize == 0)
310  data_var.ind_value = *((void **) (data_var.ind_pointer));
311  else
312  data_var.ind_value = data_var.ind_pointer;
313  break;
314 
315  case ECPGd_data:
317  data_var.type = vartype;
318  data_var.pointer = var;
319  data_var.varcharsize = varcharsize;
320  data_var.arrsize = arrsize;
321  data_var.offset = offset;
322  if (data_var.arrsize == 0 || data_var.varcharsize == 0)
323  data_var.value = *((void **) (data_var.pointer));
324  else
325  data_var.value = data_var.pointer;
326  break;
327 
328  case ECPGd_name:
329  if (!get_char_item(lineno, var, vartype, PQfname(ECPGresult, index), varcharsize))
330  {
331  va_end(args);
332  return false;
333  }
334 
335  ecpg_log("ECPGget_desc: NAME = %s\n", PQfname(ECPGresult, index));
336  break;
337 
338  case ECPGd_nullable:
339  if (!get_int_item(lineno, var, vartype, 1))
340  {
341  va_end(args);
342  return false;
343  }
344 
345  break;
346 
347  case ECPGd_key_member:
348  if (!get_int_item(lineno, var, vartype, 0))
349  {
350  va_end(args);
351  return false;
352  }
353 
354  break;
355 
356  case ECPGd_scale:
357  if (!get_int_item(lineno, var, vartype, (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff))
358  {
359  va_end(args);
360  return false;
361  }
362 
363  ecpg_log("ECPGget_desc: SCALE = %d\n", (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff);
364  break;
365 
366  case ECPGd_precision:
367  if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) >> 16))
368  {
369  va_end(args);
370  return false;
371  }
372 
373  ecpg_log("ECPGget_desc: PRECISION = %d\n", PQfmod(ECPGresult, index) >> 16);
374  break;
375 
376  case ECPGd_octet:
377  if (!get_int_item(lineno, var, vartype, PQfsize(ECPGresult, index)))
378  {
379  va_end(args);
380  return false;
381  }
382 
383  ecpg_log("ECPGget_desc: OCTET_LENGTH = %d\n", PQfsize(ECPGresult, index));
384  break;
385 
386  case ECPGd_length:
387  if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) - VARHDRSZ))
388  {
389  va_end(args);
390  return false;
391  }
392 
393  ecpg_log("ECPGget_desc: LENGTH = %d\n", PQfmod(ECPGresult, index) - VARHDRSZ);
394  break;
395 
396  case ECPGd_type:
397  if (!get_int_item(lineno, var, vartype, ecpg_dynamic_type(PQftype(ECPGresult, index))))
398  {
399  va_end(args);
400  return false;
401  }
402 
403  ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type(PQftype(ECPGresult, index)));
404  break;
405 
406  case ECPGd_di_code:
407  if (!get_int_item(lineno, var, vartype, ecpg_dynamic_type_DDT(PQftype(ECPGresult, index))))
408  {
409  va_end(args);
410  return false;
411  }
412 
413  ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type_DDT(PQftype(ECPGresult, index)));
414  break;
415 
416  case ECPGd_cardinality:
417  if (!get_int_item(lineno, var, vartype, PQntuples(ECPGresult)))
418  {
419  va_end(args);
420  return false;
421  }
422 
423  ecpg_log("ECPGget_desc: CARDINALITY = %d\n", PQntuples(ECPGresult));
424  break;
425 
426  case ECPGd_ret_length:
427  case ECPGd_ret_octet:
428 
430 
431  /*
432  * this is like ECPGstore_result
433  */
434  if (arrsize > 0 && ntuples > arrsize)
435  {
436  ecpg_log("ECPGget_desc on line %d: incorrect number of matches; %d don't fit into array of %ld\n",
437  lineno, ntuples, arrsize);
439  va_end(args);
440  return false;
441  }
442  /* allocate storage if needed */
443  if (arrsize == 0 && *(void **) var == NULL)
444  {
445  void *mem = (void *) ecpg_auto_alloc(offset * ntuples, lineno);
446 
447  if (!mem)
448  {
449  va_end(args);
450  return false;
451  }
452  *(void **) var = mem;
453  var = mem;
454  }
455 
456  for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
457  {
458  if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, act_tuple, index)))
459  {
460  va_end(args);
461  return false;
462  }
463  var = (char *) var + offset;
464  ecpg_log("ECPGget_desc: RETURNED[%d] = %d\n", act_tuple, PQgetlength(ECPGresult, act_tuple, index));
465  }
466  break;
467 
468  default:
469  snprintf(type_str, sizeof(type_str), "%d", type);
471  va_end(args);
472  return false;
473  }
474 
475  type = va_arg(args, enum ECPGdtype);
476  }
477 
478  if (data_var.type != ECPGt_EORT)
479  {
480  struct statement stmt;
481 
482  memset(&stmt, 0, sizeof stmt);
483  stmt.lineno = lineno;
484 
485  /* Make sure we do NOT honor the locale for numeric input */
486  /* since the database gives the standard decimal point */
487  /* (see comments in execute.c) */
488 #ifdef HAVE_USELOCALE
489  stmt.clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
490  if (stmt.clocale != (locale_t) 0)
491  stmt.oldlocale = uselocale(stmt.clocale);
492 #else
493 #ifdef HAVE__CONFIGTHREADLOCALE
494  stmt.oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
495 #endif
496  stmt.oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
497  setlocale(LC_NUMERIC, "C");
498 #endif
499 
500  /* desperate try to guess something sensible */
501  stmt.connection = ecpg_get_connection(NULL);
502  ecpg_store_result(ECPGresult, index, &stmt, &data_var);
503 
504 #ifdef HAVE_USELOCALE
505  if (stmt.oldlocale != (locale_t) 0)
506  uselocale(stmt.oldlocale);
507  if (stmt.clocale)
508  freelocale(stmt.clocale);
509 #else
510  if (stmt.oldlocale)
511  {
512  setlocale(LC_NUMERIC, stmt.oldlocale);
513  ecpg_free(stmt.oldlocale);
514  }
515 #ifdef HAVE__CONFIGTHREADLOCALE
516  if (stmt.oldthreadlocale != -1)
517  (void) _configthreadlocale(stmt.oldthreadlocale);
518 #endif
519 #endif
520  }
521  else if (data_var.ind_type != ECPGt_NO_INDICATOR && data_var.ind_pointer != NULL)
522 
523  /*
524  * ind_type != NO_INDICATOR should always have ind_pointer != NULL but
525  * since this might be changed manually in the .c file let's play it
526  * safe
527  */
528  {
529  /*
530  * this is like ECPGstore_result but since we don't have a data
531  * variable at hand, we can't call it
532  */
533  if (data_var.ind_arrsize > 0 && ntuples > data_var.ind_arrsize)
534  {
535  ecpg_log("ECPGget_desc on line %d: incorrect number of matches (indicator); %d don't fit into array of %ld\n",
536  lineno, ntuples, data_var.ind_arrsize);
538  va_end(args);
539  return false;
540  }
541 
542  /* allocate storage if needed */
543  if (data_var.ind_arrsize == 0 && data_var.ind_value == NULL)
544  {
545  void *mem = (void *) ecpg_auto_alloc(data_var.ind_offset * ntuples, lineno);
546 
547  if (!mem)
548  {
549  va_end(args);
550  return false;
551  }
552  *(void **) data_var.ind_pointer = mem;
553  data_var.ind_value = mem;
554  }
555 
556  for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
557  {
558  if (!get_int_item(lineno, data_var.ind_value, data_var.ind_type, -PQgetisnull(ECPGresult, act_tuple, index)))
559  {
560  va_end(args);
561  return false;
562  }
563  data_var.ind_value = (char *) data_var.ind_value + data_var.ind_offset;
564  ecpg_log("ECPGget_desc: INDICATOR[%d] = %d\n", act_tuple, -PQgetisnull(ECPGresult, act_tuple, index));
565  }
566  }
567  sqlca->sqlerrd[2] = ntuples;
568  va_end(args);
569  return true;
570 }
571 
572 #undef RETURN_IF_NO_DATA
573 
574 bool
575 ECPGset_desc_header(int lineno, const char *desc_name, int count)
576 {
577  struct descriptor *desc = ecpg_find_desc(lineno, desc_name);
578 
579  if (desc == NULL)
580  return false;
581  desc->count = count;
582  return true;
583 }
584 
585 static void
586 set_desc_attr(struct descriptor_item *desc_item, struct variable *var,
587  char *tobeinserted)
588 {
589  if (var->type != ECPGt_bytea)
590  desc_item->is_binary = false;
591 
592  else
593  {
594  struct ECPGgeneric_varchar *variable =
595  (struct ECPGgeneric_varchar *) (var->value);
596 
597  desc_item->is_binary = true;
598  desc_item->data_len = variable->len;
599  }
600 
601  ecpg_free(desc_item->data); /* free() takes care of a potential NULL value */
602  desc_item->data = (char *) tobeinserted;
603 }
604 
605 
606 bool
607 ECPGset_desc(int lineno, const char *desc_name, int index,...)
608 {
609  va_list args;
610  struct descriptor *desc;
611  struct descriptor_item *desc_item;
612  struct variable *var;
613 
614  desc = ecpg_find_desc(lineno, desc_name);
615  if (desc == NULL)
616  return false;
617 
618  for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
619  {
620  if (desc_item->num == index)
621  break;
622  }
623 
624  if (desc_item == NULL)
625  {
626  desc_item = (struct descriptor_item *) ecpg_alloc(sizeof(*desc_item), lineno);
627  if (!desc_item)
628  return false;
629  desc_item->num = index;
630  if (desc->count < index)
631  desc->count = index;
632  desc_item->next = desc->items;
633  desc->items = desc_item;
634  }
635 
636  if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
637  return false;
638 
639  va_start(args, index);
640 
641  for (;;)
642  {
643  enum ECPGdtype itemtype;
644  char *tobeinserted = NULL;
645 
646  itemtype = va_arg(args, enum ECPGdtype);
647 
648  if (itemtype == ECPGd_EODT)
649  break;
650 
651  var->type = va_arg(args, enum ECPGttype);
652  var->pointer = va_arg(args, char *);
653 
654  var->varcharsize = va_arg(args, long);
655  var->arrsize = va_arg(args, long);
656  var->offset = va_arg(args, long);
657 
658  if (var->arrsize == 0 || var->varcharsize == 0)
659  var->value = *((char **) (var->pointer));
660  else
661  var->value = var->pointer;
662 
663  /*
664  * negative values are used to indicate an array without given bounds
665  */
666  /* reset to zero for us */
667  if (var->arrsize < 0)
668  var->arrsize = 0;
669  if (var->varcharsize < 0)
670  var->varcharsize = 0;
671 
672  var->next = NULL;
673 
674  switch (itemtype)
675  {
676  case ECPGd_data:
677  {
678  if (!ecpg_store_input(lineno, true, var, &tobeinserted, false))
679  {
680  ecpg_free(var);
681  va_end(args);
682  return false;
683  }
684 
685  set_desc_attr(desc_item, var, tobeinserted);
686  tobeinserted = NULL;
687  break;
688  }
689 
690  case ECPGd_indicator:
691  set_int_item(lineno, &desc_item->indicator, var->pointer, var->type);
692  break;
693 
694  case ECPGd_length:
695  set_int_item(lineno, &desc_item->length, var->pointer, var->type);
696  break;
697 
698  case ECPGd_precision:
699  set_int_item(lineno, &desc_item->precision, var->pointer, var->type);
700  break;
701 
702  case ECPGd_scale:
703  set_int_item(lineno, &desc_item->scale, var->pointer, var->type);
704  break;
705 
706  case ECPGd_type:
707  set_int_item(lineno, &desc_item->type, var->pointer, var->type);
708  break;
709 
710  default:
711  {
712  char type_str[20];
713 
714  snprintf(type_str, sizeof(type_str), "%d", itemtype);
716  ecpg_free(var);
717  va_end(args);
718  return false;
719  }
720  }
721  }
722  ecpg_free(var);
723  va_end(args);
724 
725  return true;
726 }
727 
728 /* Free the descriptor and items in it. */
729 static void
731 {
732  struct descriptor_item *desc_item;
733 
734  for (desc_item = desc->items; desc_item;)
735  {
736  struct descriptor_item *di;
737 
738  ecpg_free(desc_item->data);
739  di = desc_item;
740  desc_item = desc_item->next;
741  ecpg_free(di);
742  }
743 
744  ecpg_free(desc->name);
745  PQclear(desc->result);
746  ecpg_free(desc);
747 }
748 
749 bool
750 ECPGdeallocate_desc(int line, const char *name)
751 {
752  struct descriptor *desc;
753  struct descriptor *prev;
754  struct sqlca_t *sqlca = ECPGget_sqlca();
755 
756  if (sqlca == NULL)
757  {
760  return false;
761  }
762 
763  ecpg_init_sqlca(sqlca);
764  for (desc = get_descriptors(), prev = NULL; desc; prev = desc, desc = desc->next)
765  {
766  if (strcmp(name, desc->name) == 0)
767  {
768  if (prev)
769  prev->next = desc->next;
770  else
771  set_descriptors(desc->next);
772  descriptor_free(desc);
773  return true;
774  }
775  }
777  return false;
778 }
779 
780 #ifdef ENABLE_THREAD_SAFETY
781 
782 /* Deallocate all descriptors in the list */
783 static void
784 descriptor_deallocate_all(struct descriptor *list)
785 {
786  while (list)
787  {
788  struct descriptor *next = list->next;
789 
790  descriptor_free(list);
791  list = next;
792  }
793 }
794 #endif /* ENABLE_THREAD_SAFETY */
795 
796 bool
797 ECPGallocate_desc(int line, const char *name)
798 {
799  struct descriptor *new;
800  struct sqlca_t *sqlca = ECPGget_sqlca();
801 
802  if (sqlca == NULL)
803  {
806  return false;
807  }
808 
809  ecpg_init_sqlca(sqlca);
810  new = (struct descriptor *) ecpg_alloc(sizeof(struct descriptor), line);
811  if (!new)
812  return false;
813  new->next = get_descriptors();
814  new->name = ecpg_alloc(strlen(name) + 1, line);
815  if (!new->name)
816  {
817  ecpg_free(new);
818  return false;
819  }
820  new->count = -1;
821  new->items = NULL;
822  new->result = PQmakeEmptyPGresult(NULL, 0);
823  if (!new->result)
824  {
825  ecpg_free(new->name);
826  ecpg_free(new);
828  return false;
829  }
830  strcpy(new->name, name);
831  set_descriptors(new);
832  return true;
833 }
834 
835 /* Find descriptor with name in the connection. */
836 struct descriptor *
837 ecpg_find_desc(int line, const char *name)
838 {
839  struct descriptor *desc;
840 
841  for (desc = get_descriptors(); desc; desc = desc->next)
842  {
843  if (strcmp(name, desc->name) == 0)
844  return desc;
845  }
846 
848  return NULL; /* not found */
849 }
850 
851 bool
852 ECPGdescribe(int line, int compat, bool input, const char *connection_name, const char *stmt_name,...)
853 {
854  bool ret = false;
855  struct connection *con;
856  struct prepared_statement *prep;
857  PGresult *res;
858  va_list args;
859 
860  /* DESCRIBE INPUT is not yet supported */
861  if (input)
862  {
864  return ret;
865  }
866 
867  con = ecpg_get_connection(connection_name);
868  if (!con)
869  {
871  connection_name ? connection_name : ecpg_gettext("NULL"));
872  return ret;
873  }
874  prep = ecpg_find_prepared_statement(stmt_name, con, NULL);
875  if (!prep)
876  {
878  return ret;
879  }
880 
881  va_start(args, stmt_name);
882 
883  for (;;)
884  {
885  enum ECPGttype type;
886  void *ptr;
887 
888  /* variable type */
889  type = va_arg(args, enum ECPGttype);
890 
891  if (type == ECPGt_EORT)
892  break;
893 
894  /* rest of variable parameters */
895  ptr = va_arg(args, void *);
896  (void) va_arg(args, long); /* skip args */
897  (void) va_arg(args, long);
898  (void) va_arg(args, long);
899 
900  /* variable indicator */
901  (void) va_arg(args, enum ECPGttype);
902  (void) va_arg(args, void *); /* skip args */
903  (void) va_arg(args, long);
904  (void) va_arg(args, long);
905  (void) va_arg(args, long);
906 
907  switch (type)
908  {
909  case ECPGt_descriptor:
910  {
911  char *name = ptr;
912  struct descriptor *desc = ecpg_find_desc(line, name);
913 
914  if (desc == NULL)
915  break;
916 
917  res = PQdescribePrepared(con->connection, stmt_name);
918  if (!ecpg_check_PQresult(res, line, con->connection, compat))
919  break;
920 
921  if (desc->result != NULL)
922  PQclear(desc->result);
923 
924  desc->result = res;
925  ret = true;
926  break;
927  }
928  case ECPGt_sqlda:
929  {
930  if (INFORMIX_MODE(compat))
931  {
932  struct sqlda_compat **_sqlda = ptr;
933  struct sqlda_compat *sqlda;
934 
935  res = PQdescribePrepared(con->connection, stmt_name);
936  if (!ecpg_check_PQresult(res, line, con->connection, compat))
937  break;
938 
939  sqlda = ecpg_build_compat_sqlda(line, res, -1, compat);
940  if (sqlda)
941  {
942  struct sqlda_compat *sqlda_old = *_sqlda;
943  struct sqlda_compat *sqlda_old1;
944 
945  while (sqlda_old)
946  {
947  sqlda_old1 = sqlda_old->desc_next;
948  free(sqlda_old);
949  sqlda_old = sqlda_old1;
950  }
951 
952  *_sqlda = sqlda;
953  ret = true;
954  }
955 
956  PQclear(res);
957  }
958  else
959  {
960  struct sqlda_struct **_sqlda = ptr;
961  struct sqlda_struct *sqlda;
962 
963  res = PQdescribePrepared(con->connection, stmt_name);
964  if (!ecpg_check_PQresult(res, line, con->connection, compat))
965  break;
966 
967  sqlda = ecpg_build_native_sqlda(line, res, -1, compat);
968  if (sqlda)
969  {
970  struct sqlda_struct *sqlda_old = *_sqlda;
971  struct sqlda_struct *sqlda_old1;
972 
973  while (sqlda_old)
974  {
975  sqlda_old1 = sqlda_old->desc_next;
976  free(sqlda_old);
977  sqlda_old = sqlda_old1;
978  }
979 
980  *_sqlda = sqlda;
981  ret = true;
982  }
983 
984  PQclear(res);
985  }
986  break;
987  }
988  default:
989  /* nothing else may come */
990  ;
991  }
992  }
993 
994  va_end(args);
995 
996  return ret;
997 }
long ind_arrsize
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3174
static bool get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int varcharsize)
Definition: descriptor.c:201
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2777
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
Definition: fe-exec.c:2156
bool ecpg_store_input(const int, const bool, const struct variable *, char **, bool)
Definition: execute.c:509
char arr[FLEXIBLE_ARRAY_MEMBER]
bool ECPGallocate_desc(int line, const char *name)
Definition: descriptor.c:797
static int32 next
Definition: blutils.c:213
static bool set_int_item(int lineno, int *target, const void *var, enum ECPGttype vartype)
Definition: descriptor.c:158
#define setlocale(a, b)
Definition: win32_port.h:408
int PQfsize(const PGresult *res, int field_num)
Definition: fe-exec.c:3018
struct sqlda_struct * desc_next
Definition: sqlda-native.h:39
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:2855
static bool get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
Definition: descriptor.c:115
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
int ecpg_dynamic_type(Oid)
Definition: typename.c:73
#define sqlca
Definition: sqlca.h:59
#define set_descriptors(value)
Definition: descriptor.c:56
ULONG pthread_key_t
Definition: pthread-win32.h:7
#define VARHDRSZ
Definition: c.h:556
void ecpg_free(void *)
Definition: memory.c:13
#define ECPG_INVALID_STMT
Definition: ecpgerrno.h:39
Definition: type.h:102
char * ecpg_strdup(const char *, int)
Definition: memory.c:47
#define ECPG_VAR_NOT_CHAR
Definition: ecpgerrno.h:46
#define INFORMIX_MODE(X)
void * pointer
#define ECPG_INVALID_DESCRIPTOR_INDEX
Definition: ecpgerrno.h:43
static struct @145 value
#define ECPG_UNKNOWN_DESCRIPTOR_ITEM
Definition: ecpgerrno.h:44
enum ECPGttype type
#define ECPG_SQLSTATE_CARDINALITY_VIOLATION
struct variable * next
unsigned int Oid
Definition: postgres_ext.h:31
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#define ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME
char * oldlocale
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
Definition: type.h:89
#define ecpg_gettext(x)
#define ECPG_TOO_MANY_MATCHES
Definition: ecpgerrno.h:21
bool ECPGdescribe(int line, int compat, bool input, const char *connection_name, const char *stmt_name,...)
Definition: descriptor.c:852
char * ecpg_auto_alloc(long, int)
Definition: memory.c:108
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
struct descriptor * next
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:141
static PGresult * ecpg_result_by_descriptor(int line, const char *name)
Definition: descriptor.c:61
struct connection * connection
Definition: sqlca.h:19
struct sqlda_compat * desc_next
Definition: sqlda-compat.h:43
#define ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:3007
struct descriptor * ecpg_find_desc(int line, const char *name)
Definition: descriptor.c:837
#define ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX
struct sqlda_struct * ecpg_build_native_sqlda(int, PGresult *, int, enum COMPAT_MODE)
Definition: sqlda.c:412
void * value
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:141
PGresult * result
long sqlerrd[6]
Definition: sqlca.h:30
#define ECPG_UNSUPPORTED
Definition: ecpgerrno.h:18
#define locale_t
Definition: win32_port.h:363
void ecpg_log(const char *format,...) pg_attribute_printf(1
struct sqlda_compat * ecpg_build_compat_sqlda(int, PGresult *, int, enum COMPAT_MODE)
Definition: sqlda.c:205
enum COMPAT_MODE compat
Definition: ecpg.c:25
char * ecpg_alloc(long, int)
Definition: memory.c:19
void ecpg_init_sqlca(struct sqlca_t *sqlca)
Definition: misc.c:98
bool ECPGget_desc(int lineno, const char *desc_name, int index,...)
Definition: descriptor.c:241
#define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME
struct prepared_statement * ecpg_find_prepared_statement(const char *, struct connection *, struct prepared_statement **)
Definition: prepare.c:239
void * ind_pointer
#define ECPG_VAR_NOT_NUMERIC
Definition: ecpgerrno.h:45
ECPGdtype
Definition: ecpgtype.h:71
#define ECPG_UNKNOWN_DESCRIPTOR
Definition: ecpgerrno.h:42
bool ECPGget_desc_header(int lineno, const char *desc_name, int *count)
Definition: descriptor.c:91
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define free(a)
Definition: header.h:65
bool ecpg_store_result(const PGresult *results, int act_field, const struct statement *stmt, struct variable *var)
Definition: execute.c:306
bool ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE)
Definition: error.c:283
PGconn * connection
#define ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION
long ind_varcharsize
int pthread_once_t
Definition: pthread-win32.h:9
int PQfmod(const PGresult *res, int field_num)
Definition: fe-exec.c:3029
enum ECPGttype ind_type
void * pthread_getspecific(pthread_key_t key)
Definition: pthread-win32.c:29
bool ECPGdeallocate_desc(int line, const char *name)
Definition: descriptor.c:750
static void descriptor_free(struct descriptor *desc)
Definition: descriptor.c:730
bool ECPGset_desc(int lineno, const char *desc_name, int index,...)
Definition: descriptor.c:607
struct descriptor_item * items
const char * name
Definition: encode.c:521
long ind_offset
struct descriptor_item * next
static void set_desc_attr(struct descriptor_item *desc_item, struct variable *var, char *tobeinserted)
Definition: descriptor.c:586
void pthread_setspecific(pthread_key_t key, void *val)
Definition: pthread-win32.c:24
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:74
void * ind_value
void * arg
static unsigned int ecpg_dynamic_type_DDT(Oid type)
Definition: descriptor.c:71
static struct descriptor * all_descriptors
Definition: descriptor.c:53
#define get_descriptors()
Definition: descriptor.c:55
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3188
#define RETURN_IF_NO_DATA
Definition: descriptor.c:233
#define ECPG_NO_CONN
Definition: ecpgerrno.h:36
#define snprintf
Definition: port.h:192
long varcharsize
bool ECPGset_desc_header(int lineno, const char *desc_name, int count)
Definition: descriptor.c:575
ECPGttype
Definition: ecpgtype.h:41