PostgreSQL Source Code: src/interfaces/ecpg/ecpglib/data.c Source File (original) (raw)
1
2
3#define POSTGRES_ECPG_INTERNAL
5
6#include <math.h>
7
17
18
19static bool
21{
23 return true;
24
26 return true;
27
28 return false;
29}
30
31
32static bool
34{
36 return true;
37
39 return true;
40
41 return false;
42}
43
44
45static bool
47{
48
49
50
51
53 {
55 {
56
57 do
58 {
59 (*scan_length)++;
60 } while (isdigit((unsigned char) **scan_length));
61 }
62
63 if (**scan_length != ' ' && **scan_length != '\0')
64 return true;
65 }
67 return true;
68
69 return false;
70}
71
72
73
74
75
76static double
78{
79 return (double) INFINITY;
80}
81
82static double
84{
85 return (double) NAN;
86}
87
88
89static bool
91{
93 {
95 *endptr = ptr + 3;
96 return true;
97 }
99 {
101 *endptr = ptr + 8;
102 return true;
103 }
105 {
107 *endptr = ptr + 9;
108 return true;
109 }
110
111 return false;
112}
113
114
115
116unsigned
118{
119 return srclen << 1;
120}
121
122unsigned
124{
125 return srclen >> 1;
126}
127
128static inline char
130{
132 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
133 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
134 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
135 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
136 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
137 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
138 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
139 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
140 };
141 int res = -1;
142
145
146 return (char) res;
147}
148
149static unsigned
151{
152 const char *s,
153 *srcend;
154 char v1,
155 v2,
156 *p;
157
158 srcend = src + len;
159 s = src;
160 p = dst;
161 while (s < srcend)
162 {
163 if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r')
164 {
165 s++;
166 continue;
167 }
169 if (s >= srcend)
170 return -1;
171
173 *p++ = v1 | v2;
174 }
175
176 return p - dst;
177}
178
179unsigned
181{
182 static const char hextbl[] = "0123456789abcdef";
183 const char *end = src + len;
184
185 while (src < end)
186 {
187 *dst++ = hextbl[(*src >> 4) & 0xF];
188 *dst++ = hextbl[*src & 0xF];
189 src++;
190 }
191 return len * 2;
192}
193
194bool
197 char *var, char *ind, long varcharsize, long offset,
199{
201 char *pval = (char *) PQgetvalue(results, act_tuple, act_field);
202 int binary = PQfformat(results, act_field);
203 int size = PQgetlength(results, act_tuple, act_field);
204 int value_for_indicator = 0;
205 long log_offset;
206
207 if (sqlca == NULL)
208 {
211 return false;
212 }
213
214
215
216
217
219 log_offset = -1;
220 else
221 log_offset = offset;
222
223 ecpg_log("ecpg_get_data on line %d: RESULT: %s offset: %ld; array: %s\n", lineno, pval ? (binary ? "BINARY" : pval) : "EMPTY", log_offset, ECPG_IS_ARRAY(isarray) ? "yes" : "no");
224
225
226 if (!pval)
227 {
228
229
230
231
233 return false;
234 }
235
236
237
238
239
240
241
242 if (PQgetisnull(results, act_tuple, act_field))
243 value_for_indicator = -1;
244
245 switch (ind_type)
246 {
249 *((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
250 break;
253 *((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
254 break;
257 *((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
258 break;
261 *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
262 break;
264 if (value_for_indicator == -1)
265 {
267 {
268
269
270
271
273 }
274 else
275 {
278 NULL);
279 return false;
280 }
281 }
282 break;
283 default:
287 return false;
288 break;
289 }
290
291 if (value_for_indicator == -1)
292 return true;
293
294
296 {
297 if (*pval != '{')
298 {
301 return false;
302 }
303
304 switch (type)
305 {
310 break;
311
312 default:
313 pval++;
314 break;
315 }
316 }
317
318 do
319 {
320 if (binary)
321 {
322 if (varcharsize == 0 || varcharsize * offset >= size)
323 memcpy(var + offset * act_tuple, pval, size);
324 else
325 {
326 memcpy(var + offset * act_tuple, pval, varcharsize * offset);
327
328 if (varcharsize * offset < size)
329 {
330
331 switch (ind_type)
332 {
335 *((short *) (ind + ind_offset * act_tuple)) = size;
336 break;
339 *((int *) (ind + ind_offset * act_tuple)) = size;
340 break;
343 *((long *) (ind + ind_offset * act_tuple)) = size;
344 break;
347 *((long long int *) (ind + ind_offset * act_tuple)) = size;
348 break;
349 default:
350 break;
351 }
352 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
353 }
354 }
355 pval += size;
356 }
357 else
358 {
359 switch (type)
360 {
361 long res;
362 unsigned long ures;
363 double dres;
364 char *scan_length;
369 char *endptr,
370 endchar;
371
375 res = strtol(pval, &scan_length, 10);
377 {
380 return false;
381 }
382 pval = scan_length;
383
384 switch (type)
385 {
387 *((short *) (var + offset * act_tuple)) = (short) res;
388 break;
390 *((int *) (var + offset * act_tuple)) = (int) res;
391 break;
393 *((long *) (var + offset * act_tuple)) = (long) res;
394 break;
395 default:
396
397 break;
398 }
399 break;
400
404 ures = strtoul(pval, &scan_length, 10);
406 {
409 return false;
410 }
411 pval = scan_length;
412
413 switch (type)
414 {
416 *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
417 break;
419 *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
420 break;
422 *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
423 break;
424 default:
425
426 break;
427 }
428 break;
429
431 *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
433 {
435 return false;
436 }
437 pval = scan_length;
438
439 break;
440
442 *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
444 {
446 return false;
447 }
448 pval = scan_length;
449
450 break;
451
454 if (isarray && *pval == '"')
455 pval++;
456
458 dres = strtod(pval, &scan_length);
459
460 if (isarray && *scan_length == '"')
461 scan_length++;
462
463
465 {
468 return false;
469 }
470 pval = scan_length;
471
472 switch (type)
473 {
475 *((float *) (var + offset * act_tuple)) = dres;
476 break;
478 *((double *) (var + offset * act_tuple)) = dres;
479 break;
480 default:
481
482 break;
483 }
484 break;
485
487 if (pval[0] == 'f' && pval[1] == '\0')
488 {
489 *((bool *) (var + offset * act_tuple)) = false;
490 pval++;
491 break;
492 }
493 else if (pval[0] == 't' && pval[1] == '\0')
494 {
495 *((bool *) (var + offset * act_tuple)) = true;
496 pval++;
497 break;
498 }
499 else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
500 {
501
502 break;
503 }
504
507 return false;
508 break;
509
511 {
514 long dst_size,
515 src_size,
516 dec_size;
517
519 src_size = size - 2;
520 dec_size = src_size < dst_size ? src_size : dst_size;
522
523 if (dst_size < src_size)
524 {
526
527
528 switch (ind_type)
529 {
532 *((short *) (ind + ind_offset * act_tuple)) = rcv_size;
533 break;
536 *((int *) (ind + ind_offset * act_tuple)) = rcv_size;
537 break;
540 *((long *) (ind + ind_offset * act_tuple)) = rcv_size;
541 break;
544 *((long long int *) (ind + ind_offset * act_tuple)) = rcv_size;
545 break;
546 default:
547 break;
548 }
549 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
550 }
551
552 pval += size;
553 }
554 break;
555
559 {
560 char *str = (char *) (var + offset * act_tuple);
561
562
563
564
565
566
567 if (varcharsize == 0 && offset == sizeof(char *))
569
570 if (varcharsize > size)
571 {
572
573
574
575
577 {
578 memset(str, ' ', varcharsize);
579 memcpy(str, pval, size);
580 str[varcharsize - 1] = '\0';
581
582
583
584
585
586 if (size == 0)
587 {
588
589 switch (ind_type)
590 {
593 *((short *) (ind + ind_offset * act_tuple)) = -1;
594 break;
597 *((int *) (ind + ind_offset * act_tuple)) = -1;
598 break;
601 *((long *) (ind + ind_offset * act_tuple)) = -1;
602 break;
605 *((long long int *) (ind + ind_offset * act_tuple)) = -1;
606 break;
607 default:
608 break;
609 }
610 }
611 }
612 else
613 {
614 strncpy(str, pval, size + 1);
615 }
616
618 {
619 char *last = str + size;
620
621 while (last > str && (*last == ' ' || *last == '\0'))
622 {
623 *last = '\0';
624 last--;
625 }
626 }
627 }
628 else
629 {
630 int charsize = varcharsize;
631
632
633
634
635
636 if (varcharsize == 0)
637 charsize = size + 1;
638
639 strncpy(str, pval, charsize);
640
641
643 {
645 str[charsize - 1] = '\0';
646 }
647
648 if (charsize < size || (ORACLE_MODE(compat) && (charsize - 1) < size))
649 {
650
651 switch (ind_type)
652 {
655 *((short *) (ind + ind_offset * act_tuple)) = size;
656 break;
659 *((int *) (ind + ind_offset * act_tuple)) = size;
660 break;
663 *((long *) (ind + ind_offset * act_tuple)) = size;
664 break;
667 *((long long int *) (ind + ind_offset * act_tuple)) = size;
668 break;
669 default:
670 break;
671 }
672 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
673 }
674 }
675 pval += size;
676 }
677 break;
678
680 {
683
685 if (varcharsize == 0)
687 else
688 {
689 strncpy(variable->arr, pval, varcharsize);
690
691 if (variable->len > varcharsize)
692 {
693
694 switch (ind_type)
695 {
698 *((short *) (ind + ind_offset * act_tuple)) = variable->len;
699 break;
702 *((int *) (ind + ind_offset * act_tuple)) = variable->len;
703 break;
706 *((long *) (ind + ind_offset * act_tuple)) = variable->len;
707 break;
710 *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
711 break;
712 default:
713 break;
714 }
715 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
716
718 }
719 }
720 pval += size;
721 }
722 break;
723
726 for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
727 endchar = *endptr;
728 *endptr = '\0';
730 *endptr = endchar;
731
732
733 if (nres == NULL)
734 {
735 ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
736 lineno, pval, errno);
737
739 {
740
741
742
743
745 if (nres)
747 else
748 {
751 return false;
752 }
753 }
754 else
755 {
758 return false;
759 }
760 }
761 else
762 {
764 {
768 return false;
769 }
770 }
771 pval = scan_length;
772
775 else
777
779 break;
780
782 if (*pval == '"')
783 pval++;
784
785 for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
786 endchar = *endptr;
787 *endptr = '\0';
789 *endptr = endchar;
790
791
792 if (ires == NULL)
793 {
794 ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
795 lineno, pval, errno);
796
798 {
799
800
801
802
804 if (!ires)
805 return false;
806
808 }
809 else
810 {
813 return false;
814 }
815 }
816 else
817 {
818 if (*scan_length == '"')
819 scan_length++;
820
822 {
826 return false;
827 }
828 }
829 pval = scan_length;
830
833 break;
834
836 if (*pval == '"')
837 pval++;
838
839 for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
840 endchar = *endptr;
841 *endptr = '\0';
843 *endptr = endchar;
844
845
846 if (errno != 0)
847 {
848 ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
849 lineno, pval, errno);
850
852 {
853
854
855
856
858 }
859 else
860 {
863 return false;
864 }
865 }
866 else
867 {
868 if (*scan_length == '"')
869 scan_length++;
870
872 {
875 return false;
876 }
877 }
878
879 *((date *) (var + offset * act_tuple)) = ddres;
880 pval = scan_length;
881 break;
882
884 if (*pval == '"')
885 pval++;
886
887 for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
888 endchar = *endptr;
889 *endptr = '\0';
891 *endptr = endchar;
892
893
894 if (errno != 0)
895 {
896 ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
897 lineno, pval, errno);
898
900 {
901
902
903
904
906 }
907 else
908 {
911 return false;
912 }
913 }
914 else
915 {
916 if (*scan_length == '"')
917 scan_length++;
918
920 {
923 return false;
924 }
925 }
926
927 *((timestamp *) (var + offset * act_tuple)) = tres;
928 pval = scan_length;
929 break;
930
931 default:
935 return false;
936 break;
937 }
939 {
940 bool string = false;
941
942
943 ++act_tuple;
944
945
946
947
948
949
950
951 for (; *pval != '\0' && (string || ((isarray, *pval) &&
(isarray, *pval))); ++pval)
952 if (*pval == '"')
953 string = string ? false : true;
954
956 ++pval;
957 }
958 }
959 } while (*pval != '\0' && (isarray, *pval));
960
961 return true;
962}
unsigned ecpg_hex_enc_len(unsigned srclen)
static char get_hex(char c)
static bool garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
unsigned ecpg_hex_dec_len(unsigned srclen)
bool ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, enum ECPGttype type, enum ECPGttype ind_type, char *var, char *ind, long varcharsize, long offset, long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
static double get_float8_nan(void)
static unsigned hex_decode(const char *src, unsigned len, char *dst)
unsigned ecpg_hex_encode(const char *src, unsigned len, char *dst)
static bool array_delimiter(enum ARRAY_TYPE isarray, char c)
static double get_float8_infinity(void)
static bool array_boundary(enum ARRAY_TYPE isarray, char c)
static bool check_special_value(char *ptr, double *retval, char **endptr)
#define ECPG_CONVERT_BOOL
#define ECPG_FLOAT_FORMAT
#define ECPG_MISSING_INDICATOR
#define ECPG_INTERVAL_FORMAT
#define ECPG_OUT_OF_MEMORY
#define ECPG_DATA_NOT_ARRAY
#define ECPG_NUMERIC_FORMAT
#define ECPG_TIMESTAMP_FORMAT
#define ECPG_SQLSTATE_NO_DATA
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
char * ecpg_alloc(long size, int lineno)
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER
void ecpg_log(const char *format,...) pg_attribute_printf(1
const char * ecpg_type_name(enum ECPGttype typ)
#define ECPG_SQLSTATE_DATATYPE_MISMATCH
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
bool ecpg_internal_regression_mode
@ ECPGt_unsigned_long_long
static const int8 hexlookup[128]
int PQfformat(const PGresult *res, int field_num)
struct sqlca_t * ECPGget_sqlca(void)
void ECPGset_noind_null(enum ECPGttype type, void *ptr)
static const char hextbl[]
date PGTYPESdate_from_asc(char *str, char **endptr)
int PGTYPESinterval_copy(interval *intvlsrc, interval *intvldest)
interval * PGTYPESinterval_from_asc(char *str, char **endptr)
int PGTYPESnumeric_copy(numeric *src, numeric *dst)
numeric * PGTYPESnumeric_new(void)
int PGTYPESnumeric_to_decimal(numeric *src, decimal *dst)
void PGTYPESnumeric_free(numeric *var)
numeric * PGTYPESnumeric_from_asc(char *str, char **endptr)
timestamp PGTYPEStimestamp_from_asc(char *str, char **endptr)
int pg_strncasecmp(const char *s1, const char *s2, size_t n)