Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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(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 bool alloc_failed = (sqlca == NULL);
244
245 if (alloc_failed)
246 {
249 return false;
250 }
251
252 va_start(args, index);
254 ECPGresult = ecpg_result_by_descriptor(lineno, desc_name);
255 if (!ECPGresult)
256 {
257 va_end(args);
258 return false;
259 }
260
261 ntuples = PQntuples(ECPGresult);
262
263 if (index < 1 || index > PQnfields(ECPGresult))
264 {
266 va_end(args);
267 return false;
268 }
269
270 ecpg_log("ECPGget_desc: reading items for tuple %d\n", index);
271 --index;
272
273 type = va_arg(args, enum ECPGdtype);
274
275 memset(&data_var, 0, sizeof data_var);
276 data_var.type = ECPGt_EORT;
277 data_var.ind_type = ECPGt_NO_INDICATOR;
278
279 while (type != ECPGd_EODT)
280 {
281 char type_str[20];
282 long varcharsize;
283 long offset;
284 long arrsize;
285 enum ECPGttype vartype;
286 void *var;
287
288 vartype = va_arg(args, enum ECPGttype);
289 var = va_arg(args, void *);
290 varcharsize = va_arg(args, long);
291 arrsize = va_arg(args, long);
292 offset = va_arg(args, long);
293
294 switch (type)
295 {
296 case (ECPGd_indicator):
298 data_var.ind_type = vartype;
299 data_var.ind_pointer = var;
300 data_var.ind_varcharsize = varcharsize;
301 data_var.ind_arrsize = arrsize;
302 data_var.ind_offset = offset;
303 if (data_var.ind_arrsize == 0 || data_var.ind_varcharsize == 0)
304 data_var.ind_value = *((void **) (data_var.ind_pointer));
305 else
306 data_var.ind_value = data_var.ind_pointer;
307 break;
308
309 case ECPGd_data:
311 data_var.type = vartype;
312 data_var.pointer = var;
313 data_var.varcharsize = varcharsize;
314 data_var.arrsize = arrsize;
315 data_var.offset = offset;
316 if (data_var.arrsize == 0 || data_var.varcharsize == 0)
317 data_var.value = *((void **) (data_var.pointer));
318 else
319 data_var.value = data_var.pointer;
320 break;
321
322 case ECPGd_name:
323 if (!get_char_item(lineno, var, vartype, PQfname(ECPGresult, index), varcharsize))
324 {
325 va_end(args);
326 return false;
327 }
328
329 ecpg_log("ECPGget_desc: NAME = %s\n", PQfname(ECPGresult, index));
330 break;
331
332 case ECPGd_nullable:
333 if (!get_int_item(lineno, var, vartype, 1))
334 {
335 va_end(args);
336 return false;
337 }
338
339 break;
340
341 case ECPGd_key_member:
342 if (!get_int_item(lineno, var, vartype, 0))
343 {
344 va_end(args);
345 return false;
346 }
347
348 break;
349
350 case ECPGd_scale:
351 if (!get_int_item(lineno, var, vartype, (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff))
352 {
353 va_end(args);
354 return false;
355 }
356
357 ecpg_log("ECPGget_desc: SCALE = %d\n", (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff);
358 break;
359
360 case ECPGd_precision:
361 if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) >> 16))
362 {
363 va_end(args);
364 return false;
365 }
366
367 ecpg_log("ECPGget_desc: PRECISION = %d\n", PQfmod(ECPGresult, index) >> 16);
368 break;
369
370 case ECPGd_octet:
371 if (!get_int_item(lineno, var, vartype, PQfsize(ECPGresult, index)))
372 {
373 va_end(args);
374 return false;
375 }
376
377 ecpg_log("ECPGget_desc: OCTET_LENGTH = %d\n", PQfsize(ECPGresult, index));
378 break;
379
380 case ECPGd_length:
381 if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) - VARHDRSZ))
382 {
383 va_end(args);
384 return false;
385 }
386
387 ecpg_log("ECPGget_desc: LENGTH = %d\n", PQfmod(ECPGresult, index) - VARHDRSZ);
388 break;
389
390 case ECPGd_type:
391 if (!get_int_item(lineno, var, vartype, ecpg_dynamic_type(PQftype(ECPGresult, index))))
392 {
393 va_end(args);
394 return false;
395 }
396
397 ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type(PQftype(ECPGresult, index)));
398 break;
399
400 case ECPGd_di_code:
401 if (!get_int_item(lineno, var, vartype, ecpg_dynamic_type_DDT(PQftype(ECPGresult, index))))
402 {
403 va_end(args);
404 return false;
405 }
406
407 ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type_DDT(PQftype(ECPGresult, index)));
408 break;
409
411 if (!get_int_item(lineno, var, vartype, PQntuples(ECPGresult)))
412 {
413 va_end(args);
414 return false;
415 }
416
417 ecpg_log("ECPGget_desc: CARDINALITY = %d\n", PQntuples(ECPGresult));
418 break;
419
420 case ECPGd_ret_length:
421 case ECPGd_ret_octet:
422
424
425 /*
426 * this is like ECPGstore_result
427 */
428 if (arrsize > 0 && ntuples > arrsize)
429 {
430 ecpg_log("ECPGget_desc on line %d: incorrect number of matches; %d don't fit into array of %ld\n",
431 lineno, ntuples, arrsize);
433 va_end(args);
434 return false;
435 }
436 /* allocate storage if needed */
437 if (arrsize == 0 && *(void **) var == NULL)
438 {
439 void *mem = ecpg_auto_alloc(offset * ntuples, lineno);
440
441 if (!mem)
442 {
443 va_end(args);
444 return false;
445 }
446 *(void **) var = mem;
447 var = mem;
448 }
449
450 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
451 {
452 if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, act_tuple, index)))
453 {
454 va_end(args);
455 return false;
456 }
457 var = (char *) var + offset;
458 ecpg_log("ECPGget_desc: RETURNED[%d] = %d\n", act_tuple, PQgetlength(ECPGresult, act_tuple, index));
459 }
460 break;
461
462 default:
463 snprintf(type_str, sizeof(type_str), "%d", type);
465 va_end(args);
466 return false;
467 }
468
469 type = va_arg(args, enum ECPGdtype);
470 }
471
472 if (data_var.type != ECPGt_EORT)
473 {
474 struct statement stmt;
475
476 memset(&stmt, 0, sizeof stmt);
477 stmt.lineno = lineno;
478
479 /* Make sure we do NOT honor the locale for numeric input */
480 /* since the database gives the standard decimal point */
481 /* (see comments in execute.c) */
482#ifdef HAVE_USELOCALE
483
484 /*
485 * To get here, the above PQnfields() test must have found nonzero
486 * fields. One needs a connection to create such a descriptor. (EXEC
487 * SQL SET DESCRIPTOR can populate the descriptor's "items", but it
488 * can't change the descriptor's PQnfields().) Any successful
489 * connection initializes ecpg_clocale.
490 */
491 Assert(ecpg_clocale);
492 stmt.oldlocale = uselocale(ecpg_clocale);
493#else
494#ifdef WIN32
495 stmt.oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
496#endif
497 stmt.oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL),
498 lineno, &alloc_failed);
499 if (alloc_failed)
500 {
501 va_end(args);
502 return false;
503 }
504
505 setlocale(LC_NUMERIC, "C");
506#endif
507
508 /* desperate try to guess something sensible */
509 stmt.connection = ecpg_get_connection(NULL);
510 ecpg_store_result(ECPGresult, index, &stmt, &data_var);
511
512#ifdef HAVE_USELOCALE
513 if (stmt.oldlocale != (locale_t) 0)
514 uselocale(stmt.oldlocale);
515#else
516 if (stmt.oldlocale)
517 {
518 setlocale(LC_NUMERIC, stmt.oldlocale);
519 ecpg_free(stmt.oldlocale);
520 }
521#ifdef WIN32
522 if (stmt.oldthreadlocale != -1)
523 _configthreadlocale(stmt.oldthreadlocale);
524#endif
525#endif
526 }
527 else if (data_var.ind_type != ECPGt_NO_INDICATOR && data_var.ind_pointer != NULL)
528
529 /*
530 * ind_type != NO_INDICATOR should always have ind_pointer != NULL but
531 * since this might be changed manually in the .c file let's play it
532 * safe
533 */
534 {
535 /*
536 * this is like ECPGstore_result but since we don't have a data
537 * variable at hand, we can't call it
538 */
539 if (data_var.ind_arrsize > 0 && ntuples > data_var.ind_arrsize)
540 {
541 ecpg_log("ECPGget_desc on line %d: incorrect number of matches (indicator); %d don't fit into array of %ld\n",
542 lineno, ntuples, data_var.ind_arrsize);
544 va_end(args);
545 return false;
546 }
547
548 /* allocate storage if needed */
549 if (data_var.ind_arrsize == 0 && data_var.ind_value == NULL)
550 {
551 void *mem = ecpg_auto_alloc(data_var.ind_offset * ntuples, lineno);
552
553 if (!mem)
554 {
555 va_end(args);
556 return false;
557 }
558 *(void **) data_var.ind_pointer = mem;
559 data_var.ind_value = mem;
560 }
561
562 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
563 {
564 if (!get_int_item(lineno, data_var.ind_value, data_var.ind_type, -PQgetisnull(ECPGresult, act_tuple, index)))
565 {
566 va_end(args);
567 return false;
568 }
569 data_var.ind_value = (char *) data_var.ind_value + data_var.ind_offset;
570 ecpg_log("ECPGget_desc: INDICATOR[%d] = %d\n", act_tuple, -PQgetisnull(ECPGresult, act_tuple, index));
571 }
572 }
573 sqlca->sqlerrd[2] = ntuples;
574 va_end(args);
575 return true;
576}
577
578#undef RETURN_IF_NO_DATA
579
580bool
581ECPGset_desc_header(int lineno, const char *desc_name, int count)
582{
583 struct descriptor *desc = ecpg_find_desc(lineno, desc_name);
584
585 if (desc == NULL)
586 return false;
587 desc->count = count;
588 return true;
589}
590
591static void
592set_desc_attr(struct descriptor_item *desc_item, struct variable *var,
593 char *tobeinserted)
594{
595 if (var->type != ECPGt_bytea)
596 desc_item->is_binary = false;
597
598 else
599 {
601 (struct ECPGgeneric_bytea *) (var->value);
602
603 desc_item->is_binary = true;
604 desc_item->data_len = variable->len;
605 }
606
607 ecpg_free(desc_item->data); /* free() takes care of a potential NULL value */
608 desc_item->data = tobeinserted;
609}
610
611
612bool
613ECPGset_desc(int lineno, const char *desc_name, int index,...)
614{
615 va_list args;
616 struct descriptor *desc;
617 struct descriptor_item *desc_item;
618 struct variable *var;
619
620 desc = ecpg_find_desc(lineno, desc_name);
621 if (desc == NULL)
622 return false;
623
624 for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
625 {
626 if (desc_item->num == index)
627 break;
628 }
629
630 if (desc_item == NULL)
631 {
632 desc_item = (struct descriptor_item *) ecpg_alloc(sizeof(*desc_item), lineno);
633 if (!desc_item)
634 return false;
635 desc_item->num = index;
636 if (desc->count < index)
637 desc->count = index;
638 desc_item->next = desc->items;
639 desc->items = desc_item;
640 }
641
642 if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
643 return false;
644
645 va_start(args, index);
646
647 for (;;)
648 {
649 enum ECPGdtype itemtype;
650 char *tobeinserted = NULL;
651
652 itemtype = va_arg(args, enum ECPGdtype);
653
654 if (itemtype == ECPGd_EODT)
655 break;
656
657 var->type = va_arg(args, enum ECPGttype);
658 var->pointer = va_arg(args, char *);
659
660 var->varcharsize = va_arg(args, long);
661 var->arrsize = va_arg(args, long);
662 var->offset = va_arg(args, long);
663
664 if (var->arrsize == 0 || var->varcharsize == 0)
665 var->value = *((char **) (var->pointer));
666 else
667 var->value = var->pointer;
668
669 /*
670 * negative values are used to indicate an array without given bounds
671 */
672 /* reset to zero for us */
673 if (var->arrsize < 0)
674 var->arrsize = 0;
675 if (var->varcharsize < 0)
676 var->varcharsize = 0;
677
678 var->next = NULL;
679
680 switch (itemtype)
681 {
682 case ECPGd_data:
683 {
684 if (!ecpg_store_input(lineno, true, var, &tobeinserted, false))
685 {
686 ecpg_free(var);
687 va_end(args);
688 return false;
689 }
690
691 set_desc_attr(desc_item, var, tobeinserted);
692 tobeinserted = NULL;
693 break;
694 }
695
696 case ECPGd_indicator:
697 set_int_item(lineno, &desc_item->indicator, var->pointer, var->type);
698 break;
699
700 case ECPGd_length:
701 set_int_item(lineno, &desc_item->length, var->pointer, var->type);
702 break;
703
704 case ECPGd_precision:
705 set_int_item(lineno, &desc_item->precision, var->pointer, var->type);
706 break;
707
708 case ECPGd_scale:
709 set_int_item(lineno, &desc_item->scale, var->pointer, var->type);
710 break;
711
712 case ECPGd_type:
713 set_int_item(lineno, &desc_item->type, var->pointer, var->type);
714 break;
715
716 default:
717 {
718 char type_str[20];
719
720 snprintf(type_str, sizeof(type_str), "%d", itemtype);
722 ecpg_free(var);
723 va_end(args);
724 return false;
725 }
726 }
727 }
728 ecpg_free(var);
729 va_end(args);
730
731 return true;
732}
733
734/* Free the descriptor and items in it. */
735static void
737{
738 struct descriptor_item *desc_item;
739
740 for (desc_item = desc->items; desc_item;)
741 {
742 struct descriptor_item *di;
743
744 ecpg_free(desc_item->data);
745 di = desc_item;
746 desc_item = desc_item->next;
747 ecpg_free(di);
748 }
749
750 ecpg_free(desc->name);
751 PQclear(desc->result);
752 ecpg_free(desc);
753}
754
755bool
756ECPGdeallocate_desc(int line, const char *name)
757{
758 struct descriptor *desc;
759 struct descriptor *prev;
760 struct sqlca_t *sqlca = ECPGget_sqlca();
761
762 if (sqlca == NULL)
763 {
766 return false;
767 }
768
770 for (desc = get_descriptors(), prev = NULL; desc; prev = desc, desc = desc->next)
771 {
772 if (strcmp(name, desc->name) == 0)
773 {
774 if (prev)
775 prev->next = desc->next;
776 else
777 set_descriptors(desc->next);
778 descriptor_free(desc);
779 return true;
780 }
781 }
783 return false;
784}
785
786/* Deallocate all descriptors in the list */
787static void
789{
790 while (list)
791 {
792 struct descriptor *next = list->next;
793
795 list = next;
796 }
797}
798
799bool
800ECPGallocate_desc(int line, const char *name)
801{
802 struct descriptor *new;
803 struct sqlca_t *sqlca = ECPGget_sqlca();
804
805 if (sqlca == NULL)
806 {
809 return false;
810 }
811
813 new = (struct descriptor *) ecpg_alloc(sizeof(struct descriptor), line);
814 if (!new)
815 return false;
816 new->next = get_descriptors();
817 new->name = ecpg_alloc(strlen(name) + 1, line);
818 if (!new->name)
819 {
820 ecpg_free(new);
821 return false;
822 }
823 new->count = -1;
824 new->items = NULL;
825 new->result = PQmakeEmptyPGresult(NULL, 0);
826 if (!new->result)
827 {
828 ecpg_free(new->name);
829 ecpg_free(new);
831 return false;
832 }
833 strcpy(new->name, name);
834 set_descriptors(new);
835 return true;
836}
837
838/* Find descriptor with name in the connection. */
839struct descriptor *
840ecpg_find_desc(int line, const char *name)
841{
842 struct descriptor *desc;
843
844 for (desc = get_descriptors(); desc; desc = desc->next)
845 {
846 if (strcmp(name, desc->name) == 0)
847 return desc;
848 }
849
851 return NULL; /* not found */
852}
853
854bool
855ECPGdescribe(int line, int compat, bool input, const char *connection_name, const char *stmt_name,...)
856{
857 bool ret = false;
858 struct connection *con;
859 struct prepared_statement *prep;
860 PGresult *res;
861 va_list args;
862
863 /* DESCRIBE INPUT is not yet supported */
864 if (input)
865 {
867 return ret;
868 }
869
870 con = ecpg_get_connection(connection_name);
871 if (!con)
872 {
874 connection_name ? connection_name : ecpg_gettext("NULL"));
875 return ret;
876 }
877 prep = ecpg_find_prepared_statement(stmt_name, con, NULL);
878 if (!prep)
879 {
881 return ret;
882 }
883
884 va_start(args, stmt_name);
885
886 for (;;)
887 {
888 enum ECPGttype type;
889 void *ptr;
890
891 /* variable type */
892 type = va_arg(args, enum ECPGttype);
893
894 if (type == ECPGt_EORT)
895 break;
896
897 /* rest of variable parameters */
898 ptr = va_arg(args, void *);
899 (void) va_arg(args, long); /* skip args */
900 (void) va_arg(args, long);
901 (void) va_arg(args, long);
902
903 /* variable indicator */
904 (void) va_arg(args, enum ECPGttype);
905 (void) va_arg(args, void *); /* skip args */
906 (void) va_arg(args, long);
907 (void) va_arg(args, long);
908 (void) va_arg(args, long);
909
910 switch (type)
911 {
912 case ECPGt_descriptor:
913 {
914 char *name = ptr;
915 struct descriptor *desc = ecpg_find_desc(line, name);
916
917 if (desc == NULL)
918 break;
919
920 res = PQdescribePrepared(con->connection, stmt_name);
921 if (!ecpg_check_PQresult(res, line, con->connection, compat))
922 break;
923
924 PQclear(desc->result);
925
926 desc->result = res;
927 ret = true;
928 break;
929 }
930 case ECPGt_sqlda:
931 {
933 {
934 struct sqlda_compat **_sqlda = ptr;
935 struct sqlda_compat *sqlda;
936
937 res = PQdescribePrepared(con->connection, stmt_name);
938 if (!ecpg_check_PQresult(res, line, con->connection, compat))
939 break;
940
941 sqlda = ecpg_build_compat_sqlda(line, res, -1, compat);
942 if (sqlda)
943 {
944 struct sqlda_compat *sqlda_old = *_sqlda;
945 struct sqlda_compat *sqlda_old1;
946
947 while (sqlda_old)
948 {
949 sqlda_old1 = sqlda_old->desc_next;
950 free(sqlda_old);
951 sqlda_old = sqlda_old1;
952 }
953
954 *_sqlda = sqlda;
955 ret = true;
956 }
957
958 PQclear(res);
959 }
960 else
961 {
962 struct sqlda_struct **_sqlda = ptr;
963 struct sqlda_struct *sqlda;
964
965 res = PQdescribePrepared(con->connection, stmt_name);
966 if (!ecpg_check_PQresult(res, line, con->connection, compat))
967 break;
968
969 sqlda = ecpg_build_native_sqlda(line, res, -1, compat);
970 if (sqlda)
971 {
972 struct sqlda_struct *sqlda_old = *_sqlda;
973 struct sqlda_struct *sqlda_old1;
974
975 while (sqlda_old)
976 {
977 sqlda_old1 = sqlda_old->desc_next;
978 free(sqlda_old);
979 sqlda_old = sqlda_old1;
980 }
981
982 *_sqlda = sqlda;
983 ret = true;
984 }
985
986 PQclear(res);
987 }
988 break;
989 }
990 default:
991 /* nothing else may come */
992 ;
993 }
994 }
995
996 va_end(args);
997
998 return ret;
999}
static int32 next
Definition: blutils.c:224
#define VARHDRSZ
Definition: c.h:698
struct connection * ecpg_get_connection(const char *connection_name)
Definition: connect.c:76
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:756
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:840
static pthread_key_t descriptor_key
Definition: descriptor.c:22
bool ECPGallocate_desc(int line, const char *name)
Definition: descriptor.c:800
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:581
static void descriptor_free(struct descriptor *desc)
Definition: descriptor.c:736
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:855
static struct descriptor * get_descriptors(void)
Definition: descriptor.c:40
bool ECPGset_desc(int lineno, const char *desc_name, int index,...)
Definition: descriptor.c:613
static void descriptor_deallocate_all(struct descriptor *list)
Definition: descriptor.c:788
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:592
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
char * ecpg_strdup(const char *string, int lineno, bool *alloc_failed)
Definition: memory.c:54
#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:110
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:265
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
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
Oid PQftype(const PGresult *res, int field_num)
Definition: fe-exec.c:3730
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
Definition: fe-exec.c:2466
PGresult * PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
Definition: fe-exec.c:159
int PQfmod(const PGresult *res, int field_num)
Definition: fe-exec.c:3752
int PQfsize(const PGresult *res, int field_num)
Definition: fe-exec.c:3741
Assert(PointerIsAligned(start, uint64))
#define free(a)
Definition: header.h:65
#define stmt
Definition: indent_codes.h:59
FILE * input
static struct @166 value
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:108
#define PQgetlength
Definition: libpq-be-fe.h:254
#define PQclear
Definition: libpq-be-fe.h:245
#define PQnfields
Definition: libpq-be-fe.h:252
#define PQgetisnull
Definition: libpq-be-fe.h:255
#define PQfname
Definition: libpq-be-fe.h:256
#define PQntuples
Definition: libpq-be-fe.h:251
void * arg
#define snprintf
Definition: port.h:239
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