PostgreSQL Source Code  git master
data.c File Reference
#include "postgres_fe.h"
#include <math.h>
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
#include "ecpglib_extern.h"
#include "sqlca.h"
#include "pgtypes_numeric.h"
#include "pgtypes_date.h"
#include "pgtypes_timestamp.h"
#include "pgtypes_interval.h"
Include dependency graph for data.c:

Go to the source code of this file.

Macros

#define POSTGRES_ECPG_INTERNAL
 

Functions

static bool array_delimiter (enum ARRAY_TYPE isarray, char c)
 
static bool array_boundary (enum ARRAY_TYPE isarray, char c)
 
static bool garbage_left (enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
 
static double get_float8_infinity (void)
 
static double get_float8_nan (void)
 
static bool check_special_value (char *ptr, double *retval, char **endptr)
 
unsigned ecpg_hex_enc_len (unsigned srclen)
 
unsigned ecpg_hex_dec_len (unsigned srclen)
 
static char get_hex (char c)
 
static unsigned hex_decode (const char *src, unsigned len, char *dst)
 
unsigned ecpg_hex_encode (const char *src, unsigned len, char *dst)
 
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)
 

Macro Definition Documentation

◆ POSTGRES_ECPG_INTERNAL

#define POSTGRES_ECPG_INTERNAL

Definition at line 3 of file data.c.

Function Documentation

◆ array_boundary()

static bool array_boundary ( enum ARRAY_TYPE  isarray,
char  c 
)
static

Definition at line 33 of file data.c.

References ECPG_ARRAY_ARRAY, and ECPG_ARRAY_VECTOR.

Referenced by ecpg_get_data(), and garbage_left().

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 }
char * c

◆ array_delimiter()

static bool array_delimiter ( enum ARRAY_TYPE  isarray,
char  c 
)
static

Definition at line 20 of file data.c.

References ECPG_ARRAY_ARRAY, and ECPG_ARRAY_VECTOR.

Referenced by ecpg_get_data(), and garbage_left().

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 }
char * c

◆ check_special_value()

static bool check_special_value ( char *  ptr,
double *  retval,
char **  endptr 
)
static

Definition at line 101 of file data.c.

References get_float8_infinity(), get_float8_nan(), and pg_strncasecmp().

Referenced by ecpg_get_data().

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 }
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
static double get_float8_infinity(void)
Definition: data.c:80
static double get_float8_nan(void)
Definition: data.c:90

◆ ecpg_get_data()

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 at line 206 of file data.c.

References ECPGgeneric_varchar::arr, array_boundary(), array_delimiter(), check_special_value(), ecpg_alloc(), ECPG_ARRAY_ARRAY, ECPG_COMPAT_PGSQL, ECPG_CONVERT_BOOL, ECPG_DATA_NOT_ARRAY, ECPG_DATE_FORMAT, ECPG_FLOAT_FORMAT, ecpg_hex_dec_len(), ecpg_hex_enc_len(), ECPG_INT_FORMAT, ecpg_internal_regression_mode, ECPG_INTERVAL_FORMAT, ECPG_IS_ARRAY, ecpg_log(), ECPG_MISSING_INDICATOR, ECPG_NOT_FOUND, ECPG_NUMERIC_FORMAT, ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_DATATYPE_MISMATCH, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_NO_DATA, ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER, ECPG_TIMESTAMP_FORMAT, ecpg_type_name(), ECPG_UINT_FORMAT, ECPG_UNSUPPORTED, ECPGget_sqlca(), ECPGset_noind_null(), ECPGt_bool, ECPGt_bytea, ECPGt_char, ECPGt_date, ECPGt_decimal, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, ECPGt_NO_INDICATOR, ECPGt_numeric, ECPGt_short, ECPGt_string, ECPGt_timestamp, ECPGt_unsigned_char, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, ECPGt_varchar, false, free, garbage_left(), hex_decode(), INFORMIX_MODE, ECPGgeneric_varchar::len, ORACLE_MODE, PGTYPESdate_from_asc(), PGTYPESinterval_copy(), PGTYPESinterval_from_asc(), PGTYPESnumeric_copy(), PGTYPESnumeric_free(), PGTYPESnumeric_from_asc(), PGTYPESnumeric_new(), PGTYPESnumeric_to_decimal(), PGTYPEStimestamp_from_asc(), PQfformat(), PQgetisnull(), PQgetlength(), PQgetvalue(), sqlca, sqlca_t::sqlwarn, and generate_unaccent_rules::str.

Referenced by ecpg_set_compat_sqlda(), ecpg_set_native_sqlda(), and ecpg_store_result().

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 #ifdef HAVE_LONG_LONG_INT
271  case ECPGt_long_long:
273  *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
274  break;
275 #endif /* HAVE_LONG_LONG_INT */
276  case ECPGt_NO_INDICATOR:
277  if (value_for_indicator == -1)
278  {
279  if (force_indicator == false)
280  {
281  /*
282  * Informix has an additional way to specify NULLs note
283  * that this uses special values to denote NULL
284  */
285  ECPGset_noind_null(type, var + offset * act_tuple);
286  }
287  else
288  {
291  NULL);
292  return false;
293  }
294  }
295  break;
296  default:
299  ecpg_type_name(ind_type));
300  return false;
301  break;
302  }
303 
304  if (value_for_indicator == -1)
305  return true;
306 
307  /* let's check if it really is an array if it should be one */
308  if (isarray == ECPG_ARRAY_ARRAY)
309  {
310  if (*pval != '{')
311  {
314  return false;
315  }
316 
317  switch (type)
318  {
319  case ECPGt_char:
320  case ECPGt_unsigned_char:
321  case ECPGt_varchar:
322  case ECPGt_string:
323  break;
324 
325  default:
326  pval++;
327  break;
328  }
329  }
330 
331  do
332  {
333  if (binary)
334  {
335  if (varcharsize == 0 || varcharsize * offset >= size)
336  memcpy(var + offset * act_tuple, pval, size);
337  else
338  {
339  memcpy(var + offset * act_tuple, pval, varcharsize * offset);
340 
341  if (varcharsize * offset < size)
342  {
343  /* truncation */
344  switch (ind_type)
345  {
346  case ECPGt_short:
348  *((short *) (ind + ind_offset * act_tuple)) = size;
349  break;
350  case ECPGt_int:
351  case ECPGt_unsigned_int:
352  *((int *) (ind + ind_offset * act_tuple)) = size;
353  break;
354  case ECPGt_long:
355  case ECPGt_unsigned_long:
356  *((long *) (ind + ind_offset * act_tuple)) = size;
357  break;
358 #ifdef HAVE_LONG_LONG_INT
359  case ECPGt_long_long:
361  *((long long int *) (ind + ind_offset * act_tuple)) = size;
362  break;
363 #endif /* HAVE_LONG_LONG_INT */
364  default:
365  break;
366  }
367  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
368  }
369  }
370  pval += size;
371  }
372  else
373  {
374  switch (type)
375  {
376  long res;
377  unsigned long ures;
378  double dres;
379  char *scan_length;
380  numeric *nres;
381  date ddres;
382  timestamp tres;
383  interval *ires;
384  char *endptr,
385  endchar;
386 
387  case ECPGt_short:
388  case ECPGt_int:
389  case ECPGt_long:
390  res = strtol(pval, &scan_length, 10);
391  if (garbage_left(isarray, &scan_length, compat))
392  {
393  ecpg_raise(lineno, ECPG_INT_FORMAT,
395  return false;
396  }
397  pval = scan_length;
398 
399  switch (type)
400  {
401  case ECPGt_short:
402  *((short *) (var + offset * act_tuple)) = (short) res;
403  break;
404  case ECPGt_int:
405  *((int *) (var + offset * act_tuple)) = (int) res;
406  break;
407  case ECPGt_long:
408  *((long *) (var + offset * act_tuple)) = (long) res;
409  break;
410  default:
411  /* Cannot happen */
412  break;
413  }
414  break;
415 
417  case ECPGt_unsigned_int:
418  case ECPGt_unsigned_long:
419  ures = strtoul(pval, &scan_length, 10);
420  if (garbage_left(isarray, &scan_length, compat))
421  {
424  return false;
425  }
426  pval = scan_length;
427 
428  switch (type)
429  {
431  *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
432  break;
433  case ECPGt_unsigned_int:
434  *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
435  break;
436  case ECPGt_unsigned_long:
437  *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
438  break;
439  default:
440  /* Cannot happen */
441  break;
442  }
443  break;
444 
445 #ifdef HAVE_LONG_LONG_INT
446 #ifdef HAVE_STRTOLL
447  case ECPGt_long_long:
448  *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
449  if (garbage_left(isarray, &scan_length, compat))
450  {
452  return false;
453  }
454  pval = scan_length;
455 
456  break;
457 #endif /* HAVE_STRTOLL */
458 #ifdef HAVE_STRTOULL
460  *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
461  if (garbage_left(isarray, &scan_length, compat))
462  {
464  return false;
465  }
466  pval = scan_length;
467 
468  break;
469 #endif /* HAVE_STRTOULL */
470 #endif /* HAVE_LONG_LONG_INT */
471 
472  case ECPGt_float:
473  case ECPGt_double:
474  if (isarray && *pval == '"')
475  pval++;
476 
477  if (!check_special_value(pval, &dres, &scan_length))
478  dres = strtod(pval, &scan_length);
479 
480  if (isarray && *scan_length == '"')
481  scan_length++;
482 
483  /* no special INFORMIX treatment for floats */
484  if (garbage_left(isarray, &scan_length, ECPG_COMPAT_PGSQL))
485  {
488  return false;
489  }
490  pval = scan_length;
491 
492  switch (type)
493  {
494  case ECPGt_float:
495  *((float *) (var + offset * act_tuple)) = dres;
496  break;
497  case ECPGt_double:
498  *((double *) (var + offset * act_tuple)) = dres;
499  break;
500  default:
501  /* Cannot happen */
502  break;
503  }
504  break;
505 
506  case ECPGt_bool:
507  if (pval[0] == 'f' && pval[1] == '\0')
508  {
509  *((bool *) (var + offset * act_tuple)) = false;
510  pval++;
511  break;
512  }
513  else if (pval[0] == 't' && pval[1] == '\0')
514  {
515  *((bool *) (var + offset * act_tuple)) = true;
516  pval++;
517  break;
518  }
519  else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
520  {
521  /* NULL is valid */
522  break;
523  }
524 
527  return false;
528  break;
529 
530  case ECPGt_bytea:
531  {
532  struct ECPGgeneric_varchar *variable =
533  (struct ECPGgeneric_varchar *) (var + offset * act_tuple);
534  long dst_size,
535  src_size,
536  dec_size;
537 
538  dst_size = ecpg_hex_enc_len(varcharsize);
539  src_size = size - 2; /* exclude backslash + 'x' */
540  dec_size = src_size < dst_size ? src_size : dst_size;
541  variable->len = hex_decode(pval + 2, dec_size, variable->arr);
542 
543  if (dst_size < src_size)
544  {
545  long rcv_size = ecpg_hex_dec_len(size - 2);
546 
547  /* truncation */
548  switch (ind_type)
549  {
550  case ECPGt_short:
552  *((short *) (ind + ind_offset * act_tuple)) = rcv_size;
553  break;
554  case ECPGt_int:
555  case ECPGt_unsigned_int:
556  *((int *) (ind + ind_offset * act_tuple)) = rcv_size;
557  break;
558  case ECPGt_long:
559  case ECPGt_unsigned_long:
560  *((long *) (ind + ind_offset * act_tuple)) = rcv_size;
561  break;
562 #ifdef HAVE_LONG_LONG_INT
563  case ECPGt_long_long:
565  *((long long int *) (ind + ind_offset * act_tuple)) = rcv_size;
566  break;
567 #endif /* HAVE_LONG_LONG_INT */
568  default:
569  break;
570  }
571  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
572  }
573 
574  pval += size;
575 
576  }
577  break;
578 
579  case ECPGt_char:
580  case ECPGt_unsigned_char:
581  case ECPGt_string:
582  {
583  char *str = (char *) (var + offset * act_tuple);
584 
585  /*
586  * If varcharsize is unknown and the offset is that of
587  * char *, then this variable represents the array of
588  * character pointers. So, use extra indirection.
589  */
590  if (varcharsize == 0 && offset == sizeof(char *))
591  str = *(char **) str;
592 
593  if (varcharsize == 0 || varcharsize > size)
594  {
595  /*
596  * compatibility mode, blank pad and null
597  * terminate char array
598  */
600  {
601  memset(str, ' ', varcharsize);
602  memcpy(str, pval, size);
603  str[varcharsize - 1] = '\0';
604 
605  /*
606  * compatibility mode empty string gets -1
607  * indicator but no warning
608  */
609  if (size == 0)
610  {
611  /* truncation */
612  switch (ind_type)
613  {
614  case ECPGt_short:
616  *((short *) (ind + ind_offset * act_tuple)) = -1;
617  break;
618  case ECPGt_int:
619  case ECPGt_unsigned_int:
620  *((int *) (ind + ind_offset * act_tuple)) = -1;
621  break;
622  case ECPGt_long:
623  case ECPGt_unsigned_long:
624  *((long *) (ind + ind_offset * act_tuple)) = -1;
625  break;
626 #ifdef HAVE_LONG_LONG_INT
627  case ECPGt_long_long:
629  *((long long int *) (ind + ind_offset * act_tuple)) = -1;
630  break;
631 #endif /* HAVE_LONG_LONG_INT */
632  default:
633  break;
634  }
635  }
636  }
637  else
638  {
639  strncpy(str, pval, size + 1);
640  }
641  /* do the rtrim() */
642  if (type == ECPGt_string)
643  {
644  char *last = str + size;
645 
646  while (last > str && (*last == ' ' || *last == '\0'))
647  {
648  *last = '\0';
649  last--;
650  }
651  }
652  }
653  else
654  {
655  strncpy(str, pval, varcharsize);
656 
657  /* compatibility mode, null terminate char array */
658  if (ORACLE_MODE(compat) && (varcharsize - 1) < size)
659  {
661  str[varcharsize - 1] = '\0';
662  }
663 
664  if (varcharsize < size || (ORACLE_MODE(compat) && (varcharsize - 1) < size))
665  {
666  /* truncation */
667  switch (ind_type)
668  {
669  case ECPGt_short:
671  *((short *) (ind + ind_offset * act_tuple)) = size;
672  break;
673  case ECPGt_int:
674  case ECPGt_unsigned_int:
675  *((int *) (ind + ind_offset * act_tuple)) = size;
676  break;
677  case ECPGt_long:
678  case ECPGt_unsigned_long:
679  *((long *) (ind + ind_offset * act_tuple)) = size;
680  break;
681 #ifdef HAVE_LONG_LONG_INT
682  case ECPGt_long_long:
684  *((long long int *) (ind + ind_offset * act_tuple)) = size;
685  break;
686 #endif /* HAVE_LONG_LONG_INT */
687  default:
688  break;
689  }
690  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
691  }
692  }
693  pval += size;
694  }
695  break;
696 
697  case ECPGt_varchar:
698  {
699  struct ECPGgeneric_varchar *variable =
700  (struct ECPGgeneric_varchar *) (var + offset * act_tuple);
701 
702  variable->len = size;
703  if (varcharsize == 0)
704  strncpy(variable->arr, pval, variable->len);
705  else
706  {
707  strncpy(variable->arr, pval, varcharsize);
708 
709  if (variable->len > varcharsize)
710  {
711  /* truncation */
712  switch (ind_type)
713  {
714  case ECPGt_short:
716  *((short *) (ind + ind_offset * act_tuple)) = variable->len;
717  break;
718  case ECPGt_int:
719  case ECPGt_unsigned_int:
720  *((int *) (ind + ind_offset * act_tuple)) = variable->len;
721  break;
722  case ECPGt_long:
723  case ECPGt_unsigned_long:
724  *((long *) (ind + ind_offset * act_tuple)) = variable->len;
725  break;
726 #ifdef HAVE_LONG_LONG_INT
727  case ECPGt_long_long:
729  *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
730  break;
731 #endif /* HAVE_LONG_LONG_INT */
732  default:
733  break;
734  }
735  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
736 
737  variable->len = varcharsize;
738  }
739  }
740  pval += size;
741  }
742  break;
743 
744  case ECPGt_decimal:
745  case ECPGt_numeric:
746  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
747  endchar = *endptr;
748  *endptr = '\0';
749  nres = PGTYPESnumeric_from_asc(pval, &scan_length);
750  *endptr = endchar;
751 
752  /* did we get an error? */
753  if (nres == NULL)
754  {
755  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
756  lineno, pval, errno);
757 
758  if (INFORMIX_MODE(compat))
759  {
760  /*
761  * Informix wants its own NULL value here instead
762  * of an error
763  */
764  nres = PGTYPESnumeric_new();
765  if (nres)
767  else
768  {
771  return false;
772  }
773  }
774  else
775  {
778  return false;
779  }
780  }
781  else
782  {
783  if (!isarray && garbage_left(isarray, &scan_length, compat))
784  {
785  free(nres);
788  return false;
789  }
790  }
791  pval = scan_length;
792 
793  if (type == ECPGt_numeric)
794  PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
795  else
796  PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
797 
798  PGTYPESnumeric_free(nres);
799  break;
800 
801  case ECPGt_interval:
802  if (*pval == '"')
803  pval++;
804 
805  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
806  endchar = *endptr;
807  *endptr = '\0';
808  ires = PGTYPESinterval_from_asc(pval, &scan_length);
809  *endptr = endchar;
810 
811  /* did we get an error? */
812  if (ires == NULL)
813  {
814  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
815  lineno, pval, errno);
816 
817  if (INFORMIX_MODE(compat))
818  {
819  /*
820  * Informix wants its own NULL value here instead
821  * of an error
822  */
823  ires = (interval *) ecpg_alloc(sizeof(interval), lineno);
824  if (!ires)
825  return false;
826 
828  }
829  else
830  {
833  return false;
834  }
835  }
836  else
837  {
838  if (*scan_length == '"')
839  scan_length++;
840 
841  if (!isarray && garbage_left(isarray, &scan_length, compat))
842  {
843  free(ires);
846  return false;
847  }
848  }
849  pval = scan_length;
850 
851  PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
852  free(ires);
853  break;
854 
855  case ECPGt_date:
856  if (*pval == '"')
857  pval++;
858 
859  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
860  endchar = *endptr;
861  *endptr = '\0';
862  ddres = PGTYPESdate_from_asc(pval, &scan_length);
863  *endptr = endchar;
864 
865  /* did we get an error? */
866  if (errno != 0)
867  {
868  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
869  lineno, pval, errno);
870 
871  if (INFORMIX_MODE(compat))
872  {
873  /*
874  * Informix wants its own NULL value here instead
875  * of an error
876  */
878  }
879  else
880  {
883  return false;
884  }
885  }
886  else
887  {
888  if (*scan_length == '"')
889  scan_length++;
890 
891  if (!isarray && garbage_left(isarray, &scan_length, compat))
892  {
895  return false;
896  }
897  }
898 
899  *((date *) (var + offset * act_tuple)) = ddres;
900  pval = scan_length;
901  break;
902 
903  case ECPGt_timestamp:
904  if (*pval == '"')
905  pval++;
906 
907  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
908  endchar = *endptr;
909  *endptr = '\0';
910  tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
911  *endptr = endchar;
912 
913  /* did we get an error? */
914  if (errno != 0)
915  {
916  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
917  lineno, pval, errno);
918 
919  if (INFORMIX_MODE(compat))
920  {
921  /*
922  * Informix wants its own NULL value here instead
923  * of an error
924  */
926  }
927  else
928  {
931  return false;
932  }
933  }
934  else
935  {
936  if (*scan_length == '"')
937  scan_length++;
938 
939  if (!isarray && garbage_left(isarray, &scan_length, compat))
940  {
943  return false;
944  }
945  }
946 
947  *((timestamp *) (var + offset * act_tuple)) = tres;
948  pval = scan_length;
949  break;
950 
951  default:
955  return false;
956  break;
957  }
958  if (ECPG_IS_ARRAY(isarray))
959  {
960  bool string = false;
961 
962  /* set array to next entry */
963  ++act_tuple;
964 
965  /* set pval to the next entry */
966 
967  /*
968  * *pval != '\0' should not be needed, but is used as a safety
969  * guard
970  */
971  for (; *pval != '\0' && (string || (!array_delimiter(isarray, *pval) && !array_boundary(isarray, *pval))); ++pval)
972  if (*pval == '"')
973  string = string ? false : true;
974 
975  if (array_delimiter(isarray, *pval))
976  ++pval;
977  }
978  }
979  } while (*pval != '\0' && !array_boundary(isarray, *pval));
980 
981  return true;
982 }
#define ECPG_DATA_NOT_ARRAY
Definition: ecpgerrno.h:33
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3175
date PGTYPESdate_from_asc(char *, char **)
Definition: datetime.c:47
int PGTYPESnumeric_copy(numeric *, numeric *)
Definition: numeric.c:1475
char arr[FLEXIBLE_ARRAY_MEMBER]
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3164
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
int PGTYPESinterval_copy(interval *, interval *)
Definition: interval.c:1086
#define ECPG_NUMERIC_FORMAT
Definition: ecpgerrno.h:25
#define sqlca
Definition: sqlca.h:59
int64 timestamp
#define ECPG_INTERVAL_FORMAT
Definition: ecpgerrno.h:26
unsigned ecpg_hex_enc_len(unsigned srclen)
Definition: data.c:128
#define ECPG_SQLSTATE_NO_DATA
char sqlwarn[8]
Definition: sqlca.h:39
#define INFORMIX_MODE(X)
static bool array_delimiter(enum ARRAY_TYPE isarray, char c)
Definition: data.c:20
#define ECPG_CONVERT_BOOL
Definition: ecpgerrno.h:29
int PGTYPESnumeric_to_decimal(numeric *, decimal *)
Definition: numeric.c:1629
static bool array_boundary(enum ARRAY_TYPE isarray, char c)
Definition: data.c:33
long date
Definition: pgtypes_date.h:9
#define false
Definition: c.h:316
#define ECPG_UINT_FORMAT
Definition: ecpgerrno.h:23
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
void PGTYPESnumeric_free(numeric *)
Definition: numeric.c:470
numeric * PGTYPESnumeric_new(void)
Definition: numeric.c:127
#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER
#define ECPG_OUT_OF_MEMORY
Definition: ecpgerrno.h:15
struct sqlca_t * ECPGget_sqlca(void)
Definition: misc.c:142
#define ECPG_DATE_FORMAT
Definition: ecpgerrno.h:27
Definition: sqlca.h:19
static unsigned hex_decode(const char *src, unsigned len, char *dst)
Definition: data.c:161
interval * PGTYPESinterval_from_asc(char *, char **)
Definition: interval.c:1007
#define ECPG_IS_ARRAY(X)
bool ecpg_internal_regression_mode
Definition: misc.c:30
#define ECPG_FLOAT_FORMAT
Definition: ecpgerrno.h:24
#define ECPG_UNSUPPORTED
Definition: ecpgerrno.h:18
void ecpg_log(const char *format,...) pg_attribute_printf(1
enum COMPAT_MODE compat
Definition: ecpg.c:25
char * ecpg_alloc(long, int)
Definition: memory.c:19
#define ECPG_MISSING_INDICATOR
Definition: ecpgerrno.h:31
const char * ecpg_type_name(enum ECPGttype)
Definition: typename.c:18
#define ECPG_NOT_FOUND
Definition: ecpgerrno.h:10
static bool check_special_value(char *ptr, double *retval, char **endptr)
Definition: data.c:101
numeric * PGTYPESnumeric_from_asc(char *, char **)
Definition: numeric.c:406
#define free(a)
Definition: header.h:65
unsigned ecpg_hex_dec_len(unsigned srclen)
Definition: data.c:134
void ECPGset_noind_null(enum ECPGttype type, void *ptr)
Definition: misc.c:320
#define ECPG_TIMESTAMP_FORMAT
Definition: ecpgerrno.h:28
#define ECPG_SQLSTATE_DATATYPE_MISMATCH
static bool garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
Definition: data.c:46
bool force_indicator
Definition: ecpg.c:18
#define ECPG_INT_FORMAT
Definition: ecpgerrno.h:22
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3189
int PQfformat(const PGresult *res, int field_num)
Definition: fe-exec.c:2997
timestamp PGTYPEStimestamp_from_asc(char *, char **)
Definition: timestamp.c:206
#define ORACLE_MODE(X)

◆ ecpg_hex_dec_len()

unsigned ecpg_hex_dec_len ( unsigned  srclen)

Definition at line 134 of file data.c.

Referenced by ecpg_get_data().

135 {
136  return srclen >> 1;
137 }

◆ ecpg_hex_enc_len()

unsigned ecpg_hex_enc_len ( unsigned  srclen)

Definition at line 128 of file data.c.

Referenced by convert_bytea_to_string(), ecpg_get_data(), and print_param_value().

129 {
130  return srclen << 1;
131 }

◆ ecpg_hex_encode()

unsigned ecpg_hex_encode ( const char *  src,
unsigned  len,
char *  dst 
)

Definition at line 191 of file data.c.

References hextbl.

Referenced by convert_bytea_to_string(), and print_param_value().

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 }
static const char hextbl[]
Definition: pgp-info.c:87

◆ garbage_left()

static bool garbage_left ( enum ARRAY_TYPE  isarray,
char **  scan_length,
enum COMPAT_MODE  compat 
)
static

Definition at line 46 of file data.c.

References array_boundary(), array_delimiter(), ECPG_ARRAY_NONE, ECPG_IS_ARRAY, and INFORMIX_MODE.

Referenced by ecpg_get_data().

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 }
#define INFORMIX_MODE(X)
static bool array_delimiter(enum ARRAY_TYPE isarray, char c)
Definition: data.c:20
static bool array_boundary(enum ARRAY_TYPE isarray, char c)
Definition: data.c:33
#define ECPG_IS_ARRAY(X)
enum COMPAT_MODE compat
Definition: ecpg.c:25

◆ get_float8_infinity()

static double get_float8_infinity ( void  )
static

Definition at line 80 of file data.c.

Referenced by check_special_value().

81 {
82 #ifdef INFINITY
83  return (double) INFINITY;
84 #else
85  return (double) (HUGE_VAL * HUGE_VAL);
86 #endif
87 }

◆ get_float8_nan()

static double get_float8_nan ( void  )
static

Definition at line 90 of file data.c.

Referenced by check_special_value().

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 }

◆ get_hex()

static char get_hex ( char  c)
inlinestatic

Definition at line 140 of file data.c.

References hexlookup.

Referenced by hex_decode().

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 }
static const int8 hexlookup[128]
Definition: encode.c:114
char * c
signed char int8
Definition: c.h:344

◆ hex_decode()

static unsigned hex_decode ( const char *  src,
unsigned  len,
char *  dst 
)
static

Definition at line 161 of file data.c.

References get_hex().

Referenced by ecpg_get_data().

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 }
static char get_hex(char c)
Definition: data.c:140