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