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
19static void descriptor_free(struct descriptor *desc);
20
21/* We manage descriptors separately for each thread. */
23static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT;
24
25static void descriptor_deallocate_all(struct descriptor *list);
26
27static void
29{
31}
32
33static void
35{
36 pthread_key_create(&descriptor_key, descriptor_destructor);
37}
38
39static struct descriptor *
41{
44}
45
46static void
48{
50}
51
52/* old internal convenience function that might go away later */
53static PGresult *
54ecpg_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
63static 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
83bool
84ECPGget_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
107static bool
108get_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;
125 *(unsigned int *) var = (unsigned int) value;
126 break;
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
150static bool
151set_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;
168 *target = *(const unsigned int *) var;
169 break;
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
193static bool
194get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int varcharsize)
195{
196 switch (vartype)
197 {
198 case ECPGt_char:
200 case ECPGt_string:
201 strncpy((char *) var, value, varcharsize);
202 break;
203 case ECPGt_varchar:
204 {
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
233bool
234ECPGget_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
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
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 = 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 WIN32
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 WIN32
514 if (stmt.oldthreadlocale != -1)
515 _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 = 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
572bool
573ECPGset_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
583static void
584set_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 {
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
604bool
605ECPGset_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
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. */
727static 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
747bool
748ECPGdeallocate_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 */
779static void
781{
782 while (list)
783 {
784 struct descriptor *next = list->next;
785
787 list = next;
788 }
789}
790
791bool
792ECPGallocate_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. */
831struct descriptor *
832ecpg_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
846bool
847ECPGdescribe(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 {
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:219
#define VARHDRSZ
Definition: c.h:649
#define Assert(condition)
Definition: c.h:815
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:71
enum COMPAT_MODE compat
Definition: ecpg.c:26
#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
struct descriptor * ecpg_find_desc(int line, const char *name)
Definition: descriptor.c:832
static pthread_key_t descriptor_key
Definition: descriptor.c:22
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 PGresult * ecpg_result_by_descriptor(int line, const char *name)
Definition: descriptor.c:54
static void descriptor_destructor(void *arg)
Definition: descriptor.c:28
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
static struct descriptor * get_descriptors(void)
Definition: descriptor.c:40
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)
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
#define ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION
char * ecpg_alloc(long size, int lineno)
Definition: memory.c:19
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
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
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
struct sqlda_compat * ecpg_build_compat_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)
Definition: sqlda.c:205
#define ECPG_SQLSTATE_CARDINALITY_VIOLATION
#define ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME
#define INFORMIX_MODE(X)
#define ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX
struct prepared_statement * ecpg_find_prepared_statement(const char *name, struct connection *con, struct prepared_statement **prev_)
Definition: prepare.c:239
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
char * ecpg_strdup(const char *string, int lineno)
Definition: memory.c:47
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:3887
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:3719
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
Definition: fe-exec.c:2455
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:159
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3567
int PQfmod(const PGresult *res, int field_num)
Definition: fe-exec.c:3741
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3901
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3489
int PQfsize(const PGresult *res, int field_num)
Definition: fe-exec.c:3730
#define free(a)
Definition: header.h:65
#define stmt
Definition: indent_codes.h:59
FILE * input
static struct @162 value
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:108
va_end(args)
va_start(args, fmt)
void * arg
#define snprintf
Definition: port.h:238
unsigned int Oid
Definition: postgres_ext.h:32
void pthread_setspecific(pthread_key_t key, void *val)
Definition: pthread-win32.c:24
void * pthread_getspecific(pthread_key_t key)
Definition: pthread-win32.c:29
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:96
Definition: type.h:109
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:432
#define setlocale(a, b)
Definition: win32_port.h:475