PostgreSQL Source Code  git master
data.c
Go to the documentation of this file.
1 /* src/interfaces/ecpg/ecpglib/data.c */
2 
3 #define POSTGRES_ECPG_INTERNAL
4 #include "postgres_fe.h"
5 
6 #include <math.h>
7 
8 #include "ecpgerrno.h"
9 #include "ecpglib.h"
10 #include "ecpglib_extern.h"
11 #include "ecpgtype.h"
12 #include "pgtypes_date.h"
13 #include "pgtypes_interval.h"
14 #include "pgtypes_numeric.h"
15 #include "pgtypes_timestamp.h"
16 #include "sqlca.h"
17 
18 /* returns true if character c is a delimiter for the given array type */
19 static bool
20 array_delimiter(enum ARRAY_TYPE isarray, char c)
21 {
22  if (isarray == ECPG_ARRAY_ARRAY && c == ',')
23  return true;
24 
25  if (isarray == ECPG_ARRAY_VECTOR && c == ' ')
26  return true;
27 
28  return false;
29 }
30 
31 /* returns true if character c marks the boundary for the given array type */
32 static bool
33 array_boundary(enum ARRAY_TYPE isarray, char c)
34 {
35  if (isarray == ECPG_ARRAY_ARRAY && c == '}')
36  return true;
37 
38  if (isarray == ECPG_ARRAY_VECTOR && c == '\0')
39  return true;
40 
41  return false;
42 }
43 
44 /* returns true if some garbage is found at the end of the scanned string */
45 static bool
46 garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
47 {
48  /*
49  * INFORMIX allows for selecting a numeric into an int, the result is
50  * truncated
51  */
52  if (isarray == ECPG_ARRAY_NONE)
53  {
54  if (INFORMIX_MODE(compat) && **scan_length == '.')
55  {
56  /* skip invalid characters */
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  }
66  else if (ECPG_IS_ARRAY(isarray) && !array_delimiter(isarray, **scan_length) && !array_boundary(isarray, **scan_length))
67  return true;
68 
69  return false;
70 }
71 
72 /* stolen code from src/backend/utils/adt/float.c */
73 #if defined(WIN32) && !defined(NAN)
74 static const uint32 nan[2] = {0xffffffff, 0x7fffffff};
75 
76 #define NAN (*(const double *) nan)
77 #endif
78 
79 static double
81 {
82 #ifdef INFINITY
83  return (double) INFINITY;
84 #else
85  return (double) (HUGE_VAL * HUGE_VAL);
86 #endif
87 }
88 
89 static double
91 {
92  /* (double) NAN doesn't work on some NetBSD/MIPS releases */
93 #if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__))
94  return (double) NAN;
95 #else
96  return (double) (0.0 / 0.0);
97 #endif
98 }
99 
100 static bool
101 check_special_value(char *ptr, double *retval, char **endptr)
102 {
103  if (pg_strncasecmp(ptr, "NaN", 3) == 0)
104  {
105  *retval = get_float8_nan();
106  *endptr = ptr + 3;
107  return true;
108  }
109  else if (pg_strncasecmp(ptr, "Infinity", 8) == 0)
110  {
111  *retval = get_float8_infinity();
112  *endptr = ptr + 8;
113  return true;
114  }
115  else if (pg_strncasecmp(ptr, "-Infinity", 9) == 0)
116  {
117  *retval = -get_float8_infinity();
118  *endptr = ptr + 9;
119  return true;
120  }
121 
122  return false;
123 }
124 
125 /* imported from src/backend/utils/adt/encode.c */
126 
127 unsigned
128 ecpg_hex_enc_len(unsigned srclen)
129 {
130  return srclen << 1;
131 }
132 
133 unsigned
134 ecpg_hex_dec_len(unsigned srclen)
135 {
136  return srclen >> 1;
137 }
138 
139 static inline char
140 get_hex(char c)
141 {
142  static const int8 hexlookup[128] = {
143  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
144  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
145  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
146  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
147  -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
148  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
149  -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
150  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
151  };
152  int res = -1;
153 
154  if (c > 0 && c < 127)
155  res = hexlookup[(unsigned char) c];
156 
157  return (char) res;
158 }
159 
160 static unsigned
161 hex_decode(const char *src, unsigned len, char *dst)
162 {
163  const char *s,
164  *srcend;
165  char v1,
166  v2,
167  *p;
168 
169  srcend = src + len;
170  s = src;
171  p = dst;
172  while (s < srcend)
173  {
174  if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r')
175  {
176  s++;
177  continue;
178  }
179  v1 = get_hex(*s++) << 4;
180  if (s >= srcend)
181  return -1;
182 
183  v2 = get_hex(*s++);
184  *p++ = v1 | v2;
185  }
186 
187  return p - dst;
188 }
189 
190 unsigned
191 ecpg_hex_encode(const char *src, unsigned len, char *dst)
192 {
193  static const char hextbl[] = "0123456789abcdef";
194  const char *end = src + len;
195 
196  while (src < end)
197  {
198  *dst++ = hextbl[(*src >> 4) & 0xF];
199  *dst++ = hextbl[*src & 0xF];
200  src++;
201  }
202  return len * 2;
203 }
204 
205 bool
206 ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
207  enum ECPGttype type, enum ECPGttype ind_type,
208  char *var, char *ind, long varcharsize, long offset,
209  long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
210 {
211  struct sqlca_t *sqlca = ECPGget_sqlca();
212  char *pval = (char *) PQgetvalue(results, act_tuple, act_field);
213  int binary = PQfformat(results, act_field);
214  int size = PQgetlength(results, act_tuple, act_field);
215  int value_for_indicator = 0;
216  long log_offset;
217 
218  if (sqlca == NULL)
219  {
222  return false;
223  }
224 
225  /*
226  * If we are running in a regression test, do not log the offset variable,
227  * it depends on the machine's alignment.
228  */
230  log_offset = -1;
231  else
232  log_offset = offset;
233 
234  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");
235 
236  /* pval is a pointer to the value */
237  if (!pval)
238  {
239  /*
240  * This should never happen because we already checked that we found
241  * at least one tuple, but let's play it safe.
242  */
244  return false;
245  }
246 
247  /* We will have to decode the value */
248 
249  /*
250  * check for null value and set indicator accordingly, i.e. -1 if NULL and
251  * 0 if not
252  */
253  if (PQgetisnull(results, act_tuple, act_field))
254  value_for_indicator = -1;
255 
256  switch (ind_type)
257  {
258  case ECPGt_short:
260  *((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
261  break;
262  case ECPGt_int:
263  case ECPGt_unsigned_int:
264  *((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
265  break;
266  case ECPGt_long:
267  case ECPGt_unsigned_long:
268  *((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
269  break;
270  case ECPGt_long_long:
272  *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
273  break;
274  case ECPGt_NO_INDICATOR:
275  if (value_for_indicator == -1)
276  {
277  if (force_indicator == false)
278  {
279  /*
280  * Informix has an additional way to specify NULLs note
281  * that this uses special values to denote NULL
282  */
283  ECPGset_noind_null(type, var + offset * act_tuple);
284  }
285  else
286  {
289  NULL);
290  return false;
291  }
292  }
293  break;
294  default:
297  ecpg_type_name(ind_type));
298  return false;
299  break;
300  }
301 
302  if (value_for_indicator == -1)
303  return true;
304 
305  /* let's check if it really is an array if it should be one */
306  if (isarray == ECPG_ARRAY_ARRAY)
307  {
308  if (*pval != '{')
309  {
312  return false;
313  }
314 
315  switch (type)
316  {
317  case ECPGt_char:
318  case ECPGt_unsigned_char:
319  case ECPGt_varchar:
320  case ECPGt_string:
321  break;
322 
323  default:
324  pval++;
325  break;
326  }
327  }
328 
329  do
330  {
331  if (binary)
332  {
333  if (varcharsize == 0 || varcharsize * offset >= size)
334  memcpy(var + offset * act_tuple, pval, size);
335  else
336  {
337  memcpy(var + offset * act_tuple, pval, varcharsize * offset);
338 
339  if (varcharsize * offset < size)
340  {
341  /* truncation */
342  switch (ind_type)
343  {
344  case ECPGt_short:
346  *((short *) (ind + ind_offset * act_tuple)) = size;
347  break;
348  case ECPGt_int:
349  case ECPGt_unsigned_int:
350  *((int *) (ind + ind_offset * act_tuple)) = size;
351  break;
352  case ECPGt_long:
353  case ECPGt_unsigned_long:
354  *((long *) (ind + ind_offset * act_tuple)) = size;
355  break;
356  case ECPGt_long_long:
358  *((long long int *) (ind + ind_offset * act_tuple)) = size;
359  break;
360  default:
361  break;
362  }
363  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
364  }
365  }
366  pval += size;
367  }
368  else
369  {
370  switch (type)
371  {
372  long res;
373  unsigned long ures;
374  double dres;
375  char *scan_length;
376  numeric *nres;
377  date ddres;
378  timestamp tres;
379  interval *ires;
380  char *endptr,
381  endchar;
382 
383  case ECPGt_short:
384  case ECPGt_int:
385  case ECPGt_long:
386  res = strtol(pval, &scan_length, 10);
387  if (garbage_left(isarray, &scan_length, compat))
388  {
389  ecpg_raise(lineno, ECPG_INT_FORMAT,
391  return false;
392  }
393  pval = scan_length;
394 
395  switch (type)
396  {
397  case ECPGt_short:
398  *((short *) (var + offset * act_tuple)) = (short) res;
399  break;
400  case ECPGt_int:
401  *((int *) (var + offset * act_tuple)) = (int) res;
402  break;
403  case ECPGt_long:
404  *((long *) (var + offset * act_tuple)) = (long) res;
405  break;
406  default:
407  /* Cannot happen */
408  break;
409  }
410  break;
411 
413  case ECPGt_unsigned_int:
414  case ECPGt_unsigned_long:
415  ures = strtoul(pval, &scan_length, 10);
416  if (garbage_left(isarray, &scan_length, compat))
417  {
420  return false;
421  }
422  pval = scan_length;
423 
424  switch (type)
425  {
427  *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
428  break;
429  case ECPGt_unsigned_int:
430  *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
431  break;
432  case ECPGt_unsigned_long:
433  *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
434  break;
435  default:
436  /* Cannot happen */
437  break;
438  }
439  break;
440 
441  case ECPGt_long_long:
442  *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
443  if (garbage_left(isarray, &scan_length, compat))
444  {
446  return false;
447  }
448  pval = scan_length;
449 
450  break;
451 
453  *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
454  if (garbage_left(isarray, &scan_length, compat))
455  {
457  return false;
458  }
459  pval = scan_length;
460 
461  break;
462 
463  case ECPGt_float:
464  case ECPGt_double:
465  if (isarray && *pval == '"')
466  pval++;
467 
468  if (!check_special_value(pval, &dres, &scan_length))
469  dres = strtod(pval, &scan_length);
470 
471  if (isarray && *scan_length == '"')
472  scan_length++;
473 
474  /* no special INFORMIX treatment for floats */
475  if (garbage_left(isarray, &scan_length, ECPG_COMPAT_PGSQL))
476  {
479  return false;
480  }
481  pval = scan_length;
482 
483  switch (type)
484  {
485  case ECPGt_float:
486  *((float *) (var + offset * act_tuple)) = dres;
487  break;
488  case ECPGt_double:
489  *((double *) (var + offset * act_tuple)) = dres;
490  break;
491  default:
492  /* Cannot happen */
493  break;
494  }
495  break;
496 
497  case ECPGt_bool:
498  if (pval[0] == 'f' && pval[1] == '\0')
499  {
500  *((bool *) (var + offset * act_tuple)) = false;
501  pval++;
502  break;
503  }
504  else if (pval[0] == 't' && pval[1] == '\0')
505  {
506  *((bool *) (var + offset * act_tuple)) = true;
507  pval++;
508  break;
509  }
510  else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
511  {
512  /* NULL is valid */
513  break;
514  }
515 
518  return false;
519  break;
520 
521  case ECPGt_bytea:
522  {
523  struct ECPGgeneric_bytea *variable =
524  (struct ECPGgeneric_bytea *) (var + offset * act_tuple);
525  long dst_size,
526  src_size,
527  dec_size;
528 
529  dst_size = ecpg_hex_enc_len(varcharsize);
530  src_size = size - 2; /* exclude backslash + 'x' */
531  dec_size = src_size < dst_size ? src_size : dst_size;
532  variable->len = hex_decode(pval + 2, dec_size, variable->arr);
533 
534  if (dst_size < src_size)
535  {
536  long rcv_size = ecpg_hex_dec_len(size - 2);
537 
538  /* truncation */
539  switch (ind_type)
540  {
541  case ECPGt_short:
543  *((short *) (ind + ind_offset * act_tuple)) = rcv_size;
544  break;
545  case ECPGt_int:
546  case ECPGt_unsigned_int:
547  *((int *) (ind + ind_offset * act_tuple)) = rcv_size;
548  break;
549  case ECPGt_long:
550  case ECPGt_unsigned_long:
551  *((long *) (ind + ind_offset * act_tuple)) = rcv_size;
552  break;
553  case ECPGt_long_long:
555  *((long long int *) (ind + ind_offset * act_tuple)) = rcv_size;
556  break;
557  default:
558  break;
559  }
560  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
561  }
562 
563  pval += size;
564  }
565  break;
566 
567  case ECPGt_char:
568  case ECPGt_unsigned_char:
569  case ECPGt_string:
570  {
571  char *str = (char *) (var + offset * act_tuple);
572 
573  /*
574  * If varcharsize is unknown and the offset is that of
575  * char *, then this variable represents the array of
576  * character pointers. So, use extra indirection.
577  */
578  if (varcharsize == 0 && offset == sizeof(char *))
579  str = *(char **) str;
580 
581  if (varcharsize == 0 || varcharsize > size)
582  {
583  /*
584  * compatibility mode, blank pad and null
585  * terminate char array
586  */
588  {
589  memset(str, ' ', varcharsize);
590  memcpy(str, pval, size);
591  str[varcharsize - 1] = '\0';
592 
593  /*
594  * compatibility mode empty string gets -1
595  * indicator but no warning
596  */
597  if (size == 0)
598  {
599  /* truncation */
600  switch (ind_type)
601  {
602  case ECPGt_short:
604  *((short *) (ind + ind_offset * act_tuple)) = -1;
605  break;
606  case ECPGt_int:
607  case ECPGt_unsigned_int:
608  *((int *) (ind + ind_offset * act_tuple)) = -1;
609  break;
610  case ECPGt_long:
611  case ECPGt_unsigned_long:
612  *((long *) (ind + ind_offset * act_tuple)) = -1;
613  break;
614  case ECPGt_long_long:
616  *((long long int *) (ind + ind_offset * act_tuple)) = -1;
617  break;
618  default:
619  break;
620  }
621  }
622  }
623  else
624  {
625  strncpy(str, pval, size + 1);
626  }
627  /* do the rtrim() */
628  if (type == ECPGt_string)
629  {
630  char *last = str + size;
631 
632  while (last > str && (*last == ' ' || *last == '\0'))
633  {
634  *last = '\0';
635  last--;
636  }
637  }
638  }
639  else
640  {
641  strncpy(str, pval, varcharsize);
642 
643  /* compatibility mode, null terminate char array */
644  if (ORACLE_MODE(compat) && (varcharsize - 1) < size)
645  {
647  str[varcharsize - 1] = '\0';
648  }
649 
650  if (varcharsize < size || (ORACLE_MODE(compat) && (varcharsize - 1) < size))
651  {
652  /* truncation */
653  switch (ind_type)
654  {
655  case ECPGt_short:
657  *((short *) (ind + ind_offset * act_tuple)) = size;
658  break;
659  case ECPGt_int:
660  case ECPGt_unsigned_int:
661  *((int *) (ind + ind_offset * act_tuple)) = size;
662  break;
663  case ECPGt_long:
664  case ECPGt_unsigned_long:
665  *((long *) (ind + ind_offset * act_tuple)) = size;
666  break;
667  case ECPGt_long_long:
669  *((long long int *) (ind + ind_offset * act_tuple)) = size;
670  break;
671  default:
672  break;
673  }
674  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
675  }
676  }
677  pval += size;
678  }
679  break;
680 
681  case ECPGt_varchar:
682  {
683  struct ECPGgeneric_varchar *variable =
684  (struct ECPGgeneric_varchar *) (var + offset * act_tuple);
685 
686  variable->len = size;
687  if (varcharsize == 0)
688  strncpy(variable->arr, pval, variable->len);
689  else
690  {
691  strncpy(variable->arr, pval, varcharsize);
692 
693  if (variable->len > varcharsize)
694  {
695  /* truncation */
696  switch (ind_type)
697  {
698  case ECPGt_short:
700  *((short *) (ind + ind_offset * act_tuple)) = variable->len;
701  break;
702  case ECPGt_int:
703  case ECPGt_unsigned_int:
704  *((int *) (ind + ind_offset * act_tuple)) = variable->len;
705  break;
706  case ECPGt_long:
707  case ECPGt_unsigned_long:
708  *((long *) (ind + ind_offset * act_tuple)) = variable->len;
709  break;
710  case ECPGt_long_long:
712  *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
713  break;
714  default:
715  break;
716  }
717  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
718 
719  variable->len = varcharsize;
720  }
721  }
722  pval += size;
723  }
724  break;
725 
726  case ECPGt_decimal:
727  case ECPGt_numeric:
728  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
729  endchar = *endptr;
730  *endptr = '\0';
731  nres = PGTYPESnumeric_from_asc(pval, &scan_length);
732  *endptr = endchar;
733 
734  /* did we get an error? */
735  if (nres == NULL)
736  {
737  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
738  lineno, pval, errno);
739 
740  if (INFORMIX_MODE(compat))
741  {
742  /*
743  * Informix wants its own NULL value here instead
744  * of an error
745  */
746  nres = PGTYPESnumeric_new();
747  if (nres)
749  else
750  {
753  return false;
754  }
755  }
756  else
757  {
760  return false;
761  }
762  }
763  else
764  {
765  if (!isarray && garbage_left(isarray, &scan_length, compat))
766  {
767  free(nres);
770  return false;
771  }
772  }
773  pval = scan_length;
774 
775  if (type == ECPGt_numeric)
776  PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
777  else
778  PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
779 
780  PGTYPESnumeric_free(nres);
781  break;
782 
783  case ECPGt_interval:
784  if (*pval == '"')
785  pval++;
786 
787  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
788  endchar = *endptr;
789  *endptr = '\0';
790  ires = PGTYPESinterval_from_asc(pval, &scan_length);
791  *endptr = endchar;
792 
793  /* did we get an error? */
794  if (ires == NULL)
795  {
796  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
797  lineno, pval, errno);
798 
799  if (INFORMIX_MODE(compat))
800  {
801  /*
802  * Informix wants its own NULL value here instead
803  * of an error
804  */
805  ires = (interval *) ecpg_alloc(sizeof(interval), lineno);
806  if (!ires)
807  return false;
808 
810  }
811  else
812  {
815  return false;
816  }
817  }
818  else
819  {
820  if (*scan_length == '"')
821  scan_length++;
822 
823  if (!isarray && garbage_left(isarray, &scan_length, compat))
824  {
825  free(ires);
828  return false;
829  }
830  }
831  pval = scan_length;
832 
833  PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
834  free(ires);
835  break;
836 
837  case ECPGt_date:
838  if (*pval == '"')
839  pval++;
840 
841  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
842  endchar = *endptr;
843  *endptr = '\0';
844  ddres = PGTYPESdate_from_asc(pval, &scan_length);
845  *endptr = endchar;
846 
847  /* did we get an error? */
848  if (errno != 0)
849  {
850  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
851  lineno, pval, errno);
852 
853  if (INFORMIX_MODE(compat))
854  {
855  /*
856  * Informix wants its own NULL value here instead
857  * of an error
858  */
860  }
861  else
862  {
865  return false;
866  }
867  }
868  else
869  {
870  if (*scan_length == '"')
871  scan_length++;
872 
873  if (!isarray && garbage_left(isarray, &scan_length, compat))
874  {
877  return false;
878  }
879  }
880 
881  *((date *) (var + offset * act_tuple)) = ddres;
882  pval = scan_length;
883  break;
884 
885  case ECPGt_timestamp:
886  if (*pval == '"')
887  pval++;
888 
889  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
890  endchar = *endptr;
891  *endptr = '\0';
892  tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
893  *endptr = endchar;
894 
895  /* did we get an error? */
896  if (errno != 0)
897  {
898  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
899  lineno, pval, errno);
900 
901  if (INFORMIX_MODE(compat))
902  {
903  /*
904  * Informix wants its own NULL value here instead
905  * of an error
906  */
908  }
909  else
910  {
913  return false;
914  }
915  }
916  else
917  {
918  if (*scan_length == '"')
919  scan_length++;
920 
921  if (!isarray && garbage_left(isarray, &scan_length, compat))
922  {
925  return false;
926  }
927  }
928 
929  *((timestamp *) (var + offset * act_tuple)) = tres;
930  pval = scan_length;
931  break;
932 
933  default:
937  return false;
938  break;
939  }
940  if (ECPG_IS_ARRAY(isarray))
941  {
942  bool string = false;
943 
944  /* set array to next entry */
945  ++act_tuple;
946 
947  /* set pval to the next entry */
948 
949  /*
950  * *pval != '\0' should not be needed, but is used as a safety
951  * guard
952  */
953  for (; *pval != '\0' && (string || (!array_delimiter(isarray, *pval) && !array_boundary(isarray, *pval))); ++pval)
954  if (*pval == '"')
955  string = string ? false : true;
956 
957  if (array_delimiter(isarray, *pval))
958  ++pval;
959  }
960  }
961  } while (*pval != '\0' && !array_boundary(isarray, *pval));
962 
963  return true;
964 }
unsigned int uint32
Definition: c.h:442
signed char int8
Definition: c.h:428
unsigned ecpg_hex_enc_len(unsigned srclen)
Definition: data.c:128
static char get_hex(char c)
Definition: data.c:140
static bool garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
Definition: data.c:46
unsigned ecpg_hex_dec_len(unsigned srclen)
Definition: data.c:134
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)
Definition: data.c:206
static double get_float8_nan(void)
Definition: data.c:90
static unsigned hex_decode(const char *src, unsigned len, char *dst)
Definition: data.c:161
unsigned ecpg_hex_encode(const char *src, unsigned len, char *dst)
Definition: data.c:191
static bool array_delimiter(enum ARRAY_TYPE isarray, char c)
Definition: data.c:20
static double get_float8_infinity(void)
Definition: data.c:80
static bool array_boundary(enum ARRAY_TYPE isarray, char c)
Definition: data.c:33
static bool check_special_value(char *ptr, double *retval, char **endptr)
Definition: data.c:101
enum COMPAT_MODE compat
Definition: ecpg.c:25
bool force_indicator
Definition: ecpg.c:18
#define ECPG_CONVERT_BOOL
Definition: ecpgerrno.h:29
#define ECPG_UNSUPPORTED
Definition: ecpgerrno.h:18
#define ECPG_FLOAT_FORMAT
Definition: ecpgerrno.h:24
#define ECPG_INT_FORMAT
Definition: ecpgerrno.h:22
#define ECPG_MISSING_INDICATOR
Definition: ecpgerrno.h:31
#define ECPG_INTERVAL_FORMAT
Definition: ecpgerrno.h:26
#define ECPG_UINT_FORMAT
Definition: ecpgerrno.h:23
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
#define ECPG_NOT_FOUND
Definition: ecpgerrno.h:10
#define ECPG_DATA_NOT_ARRAY
Definition: ecpgerrno.h:33
#define ECPG_NUMERIC_FORMAT
Definition: ecpgerrno.h:25
#define ECPG_DATE_FORMAT
Definition: ecpgerrno.h:27
#define ECPG_TIMESTAMP_FORMAT
Definition: ecpgerrno.h:28
#define ECPG_SQLSTATE_NO_DATA
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
COMPAT_MODE
@ ECPG_COMPAT_PGSQL
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
const char * ecpg_type_name(enum ECPGttype typ)
Definition: typename.c:17
#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER
void ecpg_log(const char *format,...) pg_attribute_printf(1
char * ecpg_alloc(long size, int lineno)
Definition: memory.c:19
#define ORACLE_MODE(X)
#define INFORMIX_MODE(X)
#define ECPG_SQLSTATE_DATATYPE_MISMATCH
#define ECPG_IS_ARRAY(X)
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
bool ecpg_internal_regression_mode
Definition: misc.c:29
ARRAY_TYPE
@ ECPG_ARRAY_ARRAY
@ ECPG_ARRAY_VECTOR
@ ECPG_ARRAY_NONE
ECPGttype
Definition: ecpgtype.h:42
@ ECPGt_float
Definition: ecpgtype.h:47
@ ECPGt_long_long
Definition: ecpgtype.h:45
@ ECPGt_short
Definition: ecpgtype.h:43
@ ECPGt_decimal
Definition: ecpgtype.h:51
@ ECPGt_bytea
Definition: ecpgtype.h:67
@ ECPGt_numeric
Definition: ecpgtype.h:49
@ ECPGt_varchar
Definition: ecpgtype.h:48
@ ECPGt_timestamp
Definition: ecpgtype.h:54
@ 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_date
Definition: ecpgtype.h:53
@ ECPGt_interval
Definition: ecpgtype.h:55
@ ECPGt_unsigned_long
Definition: ecpgtype.h:44
@ ECPGt_bool
Definition: ecpgtype.h:46
@ ECPGt_unsigned_long_long
Definition: ecpgtype.h:45
@ ECPGt_unsigned_int
Definition: ecpgtype.h:44
@ ECPGt_char
Definition: ecpgtype.h:43
@ ECPGt_string
Definition: ecpgtype.h:65
static const int8 hexlookup[128]
Definition: encode.c:149
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3716
int PQfformat(const PGresult *res, int field_num)
Definition: fe-exec.c:3537
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3705
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3730
#define free(a)
Definition: header.h:65
void ECPGset_noind_null(enum ECPGttype type, void *ptr)
Definition: misc.c:318
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:141
return false
Definition: isn.c:131
const void size_t len
static const char hextbl[]
Definition: pgp-info.c:87
long date
Definition: pgtypes_date.h:9
date PGTYPESdate_from_asc(char *str, char **endptr)
Definition: datetime.c:47
int PGTYPESinterval_copy(interval *intvlsrc, interval *intvldest)
Definition: interval.c:1082
interval * PGTYPESinterval_from_asc(char *str, char **endptr)
Definition: interval.c:1003
int PGTYPESnumeric_copy(numeric *src, numeric *dst)
Definition: numeric.c:1388
int PGTYPESnumeric_to_decimal(numeric *src, decimal *dst)
Definition: numeric.c:1547
numeric * PGTYPESnumeric_new(void)
Definition: numeric.c:42
numeric * PGTYPESnumeric_from_asc(char *str, char **endptr)
Definition: numeric.c:321
void PGTYPESnumeric_free(numeric *var)
Definition: numeric.c:385
timestamp PGTYPEStimestamp_from_asc(char *str, char **endptr)
Definition: timestamp.c:206
int64 timestamp
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
char * c
#define sqlca
Definition: sqlca.h:59
Definition: sqlca.h:20