PostgreSQL Source Code  git master
data.c File Reference
#include "postgres_fe.h"
#include <float.h>
#include <math.h>
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
#include "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)
 
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 34 of file data.c.

References ECPG_ARRAY_ARRAY, and ECPG_ARRAY_VECTOR.

Referenced by ecpg_get_data(), and garbage_left().

35 {
36  if (isarray == ECPG_ARRAY_ARRAY && c == '}')
37  return true;
38 
39  if (isarray == ECPG_ARRAY_VECTOR && c == '\0')
40  return true;
41 
42  return false;
43 }
char * c

◆ array_delimiter()

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

Definition at line 21 of file data.c.

References ECPG_ARRAY_ARRAY, and ECPG_ARRAY_VECTOR.

Referenced by ecpg_get_data(), and garbage_left().

22 {
23  if (isarray == ECPG_ARRAY_ARRAY && c == ',')
24  return true;
25 
26  if (isarray == ECPG_ARRAY_VECTOR && c == ' ')
27  return true;
28 
29  return false;
30 }
char * c

◆ check_special_value()

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

Definition at line 102 of file data.c.

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

Referenced by ecpg_get_data().

103 {
104  if (pg_strncasecmp(ptr, "NaN", 3) == 0)
105  {
106  *retval = get_float8_nan();
107  *endptr = ptr + 3;
108  return true;
109  }
110  else if (pg_strncasecmp(ptr, "Infinity", 8) == 0)
111  {
112  *retval = get_float8_infinity();
113  *endptr = ptr + 8;
114  return true;
115  }
116  else if (pg_strncasecmp(ptr, "-Infinity", 9) == 0)
117  {
118  *retval = -get_float8_infinity();
119  *endptr = ptr + 9;
120  return true;
121  }
122 
123  return false;
124 }
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:81
static double get_float8_nan(void)
Definition: data.c:91

◆ 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 127 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_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_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(), 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().

131 {
132  struct sqlca_t *sqlca = ECPGget_sqlca();
133  char *pval = (char *) PQgetvalue(results, act_tuple, act_field);
134  int binary = PQfformat(results, act_field);
135  int size = PQgetlength(results, act_tuple, act_field);
136  int value_for_indicator = 0;
137  long log_offset;
138 
139  if (sqlca == NULL)
140  {
143  return false;
144  }
145 
146  /*
147  * If we are running in a regression test, do not log the offset variable,
148  * it depends on the machine's alignment.
149  */
151  log_offset = -1;
152  else
153  log_offset = offset;
154 
155  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");
156 
157  /* pval is a pointer to the value */
158  if (!pval)
159  {
160  /*
161  * This should never happen because we already checked that we found
162  * at least one tuple, but let's play it safe.
163  */
165  return false;
166  }
167 
168  /* We will have to decode the value */
169 
170  /*
171  * check for null value and set indicator accordingly, i.e. -1 if NULL and
172  * 0 if not
173  */
174  if (PQgetisnull(results, act_tuple, act_field))
175  value_for_indicator = -1;
176 
177  switch (ind_type)
178  {
179  case ECPGt_short:
181  *((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
182  break;
183  case ECPGt_int:
184  case ECPGt_unsigned_int:
185  *((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
186  break;
187  case ECPGt_long:
188  case ECPGt_unsigned_long:
189  *((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
190  break;
191 #ifdef HAVE_LONG_LONG_INT
192  case ECPGt_long_long:
194  *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
195  break;
196 #endif /* HAVE_LONG_LONG_INT */
197  case ECPGt_NO_INDICATOR:
198  if (value_for_indicator == -1)
199  {
200  if (force_indicator == false)
201  {
202  /*
203  * Informix has an additional way to specify NULLs note
204  * that this uses special values to denote NULL
205  */
206  ECPGset_noind_null(type, var + offset * act_tuple);
207  }
208  else
209  {
212  NULL);
213  return false;
214  }
215  }
216  break;
217  default:
220  ecpg_type_name(ind_type));
221  return false;
222  break;
223  }
224 
225  if (value_for_indicator == -1)
226  return true;
227 
228  /* let's check if it really is an array if it should be one */
229  if (isarray == ECPG_ARRAY_ARRAY)
230  {
231  if (*pval != '{')
232  {
235  return false;
236  }
237 
238  switch (type)
239  {
240  case ECPGt_char:
241  case ECPGt_unsigned_char:
242  case ECPGt_varchar:
243  case ECPGt_string:
244  break;
245 
246  default:
247  pval++;
248  break;
249  }
250  }
251 
252  do
253  {
254  if (binary)
255  {
256  if (varcharsize == 0 || varcharsize * offset >= size)
257  memcpy(var + offset * act_tuple, pval, size);
258  else
259  {
260  memcpy(var + offset * act_tuple, pval, varcharsize * offset);
261 
262  if (varcharsize * offset < size)
263  {
264  /* truncation */
265  switch (ind_type)
266  {
267  case ECPGt_short:
269  *((short *) (ind + ind_offset * act_tuple)) = size;
270  break;
271  case ECPGt_int:
272  case ECPGt_unsigned_int:
273  *((int *) (ind + ind_offset * act_tuple)) = size;
274  break;
275  case ECPGt_long:
276  case ECPGt_unsigned_long:
277  *((long *) (ind + ind_offset * act_tuple)) = size;
278  break;
279 #ifdef HAVE_LONG_LONG_INT
280  case ECPGt_long_long:
282  *((long long int *) (ind + ind_offset * act_tuple)) = size;
283  break;
284 #endif /* HAVE_LONG_LONG_INT */
285  default:
286  break;
287  }
288  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
289  }
290  }
291  pval += size;
292  }
293  else
294  {
295  switch (type)
296  {
297  long res;
298  unsigned long ures;
299  double dres;
300  char *scan_length;
301  numeric *nres;
302  date ddres;
303  timestamp tres;
304  interval *ires;
305  char *endptr,
306  endchar;
307 
308  case ECPGt_short:
309  case ECPGt_int:
310  case ECPGt_long:
311  res = strtol(pval, &scan_length, 10);
312  if (garbage_left(isarray, &scan_length, compat))
313  {
314  ecpg_raise(lineno, ECPG_INT_FORMAT,
316  return false;
317  }
318  pval = scan_length;
319 
320  switch (type)
321  {
322  case ECPGt_short:
323  *((short *) (var + offset * act_tuple)) = (short) res;
324  break;
325  case ECPGt_int:
326  *((int *) (var + offset * act_tuple)) = (int) res;
327  break;
328  case ECPGt_long:
329  *((long *) (var + offset * act_tuple)) = (long) res;
330  break;
331  default:
332  /* Cannot happen */
333  break;
334  }
335  break;
336 
338  case ECPGt_unsigned_int:
339  case ECPGt_unsigned_long:
340  ures = strtoul(pval, &scan_length, 10);
341  if (garbage_left(isarray, &scan_length, compat))
342  {
345  return false;
346  }
347  pval = scan_length;
348 
349  switch (type)
350  {
352  *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
353  break;
354  case ECPGt_unsigned_int:
355  *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
356  break;
357  case ECPGt_unsigned_long:
358  *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
359  break;
360  default:
361  /* Cannot happen */
362  break;
363  }
364  break;
365 
366 #ifdef HAVE_LONG_LONG_INT
367 #ifdef HAVE_STRTOLL
368  case ECPGt_long_long:
369  *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
370  if (garbage_left(isarray, &scan_length, compat))
371  {
373  return false;
374  }
375  pval = scan_length;
376 
377  break;
378 #endif /* HAVE_STRTOLL */
379 #ifdef HAVE_STRTOULL
381  *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
382  if (garbage_left(isarray, &scan_length, compat))
383  {
385  return false;
386  }
387  pval = scan_length;
388 
389  break;
390 #endif /* HAVE_STRTOULL */
391 #endif /* HAVE_LONG_LONG_INT */
392 
393  case ECPGt_float:
394  case ECPGt_double:
395  if (isarray && *pval == '"')
396  pval++;
397 
398  if (!check_special_value(pval, &dres, &scan_length))
399  dres = strtod(pval, &scan_length);
400 
401  if (isarray && *scan_length == '"')
402  scan_length++;
403 
404  /* no special INFORMIX treatment for floats */
405  if (garbage_left(isarray, &scan_length, ECPG_COMPAT_PGSQL))
406  {
409  return false;
410  }
411  pval = scan_length;
412 
413  switch (type)
414  {
415  case ECPGt_float:
416  *((float *) (var + offset * act_tuple)) = dres;
417  break;
418  case ECPGt_double:
419  *((double *) (var + offset * act_tuple)) = dres;
420  break;
421  default:
422  /* Cannot happen */
423  break;
424  }
425  break;
426 
427  case ECPGt_bool:
428  if (pval[0] == 'f' && pval[1] == '\0')
429  {
430  *((bool *) (var + offset * act_tuple)) = false;
431  pval++;
432  break;
433  }
434  else if (pval[0] == 't' && pval[1] == '\0')
435  {
436  *((bool *) (var + offset * act_tuple)) = true;
437  pval++;
438  break;
439  }
440  else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
441  {
442  /* NULL is valid */
443  break;
444  }
445 
448  return false;
449  break;
450 
451  case ECPGt_char:
452  case ECPGt_unsigned_char:
453  case ECPGt_string:
454  {
455  char *str = (char *) (var + offset * act_tuple);
456 
457  /*
458  * If varcharsize is unknown and the offset is that of
459  * char *, then this variable represents the array of
460  * character pointers. So, use extra indirection.
461  */
462  if (varcharsize == 0 && offset == sizeof(char *))
463  str = *(char **) str;
464 
465  if (varcharsize == 0 || varcharsize > size)
466  {
467  /*
468  * compatibility mode, blank pad and null
469  * terminate char array
470  */
472  {
473  memset(str, ' ', varcharsize);
474  memcpy(str, pval, size);
475  str[varcharsize - 1] = '\0';
476 
477  /*
478  * compatibility mode empty string gets -1
479  * indicator but no warning
480  */
481  if (size == 0)
482  {
483  /* truncation */
484  switch (ind_type)
485  {
486  case ECPGt_short:
488  *((short *) (ind + ind_offset * act_tuple)) = -1;
489  break;
490  case ECPGt_int:
491  case ECPGt_unsigned_int:
492  *((int *) (ind + ind_offset * act_tuple)) = -1;
493  break;
494  case ECPGt_long:
495  case ECPGt_unsigned_long:
496  *((long *) (ind + ind_offset * act_tuple)) = -1;
497  break;
498 #ifdef HAVE_LONG_LONG_INT
499  case ECPGt_long_long:
501  *((long long int *) (ind + ind_offset * act_tuple)) = -1;
502  break;
503 #endif /* HAVE_LONG_LONG_INT */
504  default:
505  break;
506  }
507  }
508  }
509  else
510  {
511  strncpy(str, pval, size + 1);
512  }
513  /* do the rtrim() */
514  if (type == ECPGt_string)
515  {
516  char *last = str + size;
517 
518  while (last > str && (*last == ' ' || *last == '\0'))
519  {
520  *last = '\0';
521  last--;
522  }
523  }
524  }
525  else
526  {
527  strncpy(str, pval, varcharsize);
528 
529  /* compatibility mode, null terminate char array */
530  if (ORACLE_MODE(compat) && (varcharsize - 1) < size)
531  {
533  str[varcharsize - 1] = '\0';
534  }
535 
536  if (varcharsize < size || (ORACLE_MODE(compat) && (varcharsize - 1) < size))
537  {
538  /* truncation */
539  switch (ind_type)
540  {
541  case ECPGt_short:
543  *((short *) (ind + ind_offset * act_tuple)) = size;
544  break;
545  case ECPGt_int:
546  case ECPGt_unsigned_int:
547  *((int *) (ind + ind_offset * act_tuple)) = size;
548  break;
549  case ECPGt_long:
550  case ECPGt_unsigned_long:
551  *((long *) (ind + ind_offset * act_tuple)) = size;
552  break;
553 #ifdef HAVE_LONG_LONG_INT
554  case ECPGt_long_long:
556  *((long long int *) (ind + ind_offset * act_tuple)) = size;
557  break;
558 #endif /* HAVE_LONG_LONG_INT */
559  default:
560  break;
561  }
562  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
563  }
564  }
565  pval += size;
566  }
567  break;
568 
569  case ECPGt_varchar:
570  {
571  struct ECPGgeneric_varchar *variable =
572  (struct ECPGgeneric_varchar *) (var + offset * act_tuple);
573 
574  variable->len = size;
575  if (varcharsize == 0)
576  strncpy(variable->arr, pval, variable->len);
577  else
578  {
579  strncpy(variable->arr, pval, varcharsize);
580 
581  if (variable->len > varcharsize)
582  {
583  /* truncation */
584  switch (ind_type)
585  {
586  case ECPGt_short:
588  *((short *) (ind + ind_offset * act_tuple)) = variable->len;
589  break;
590  case ECPGt_int:
591  case ECPGt_unsigned_int:
592  *((int *) (ind + ind_offset * act_tuple)) = variable->len;
593  break;
594  case ECPGt_long:
595  case ECPGt_unsigned_long:
596  *((long *) (ind + ind_offset * act_tuple)) = variable->len;
597  break;
598 #ifdef HAVE_LONG_LONG_INT
599  case ECPGt_long_long:
601  *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
602  break;
603 #endif /* HAVE_LONG_LONG_INT */
604  default:
605  break;
606  }
607  sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
608 
609  variable->len = varcharsize;
610  }
611  }
612  pval += size;
613  }
614  break;
615 
616  case ECPGt_decimal:
617  case ECPGt_numeric:
618  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
619  endchar = *endptr;
620  *endptr = '\0';
621  nres = PGTYPESnumeric_from_asc(pval, &scan_length);
622  *endptr = endchar;
623 
624  /* did we get an error? */
625  if (nres == NULL)
626  {
627  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
628  lineno, pval, errno);
629 
630  if (INFORMIX_MODE(compat))
631  {
632  /*
633  * Informix wants its own NULL value here instead
634  * of an error
635  */
636  nres = PGTYPESnumeric_new();
637  if (nres)
639  else
640  {
643  return false;
644  }
645  }
646  else
647  {
650  return false;
651  }
652  }
653  else
654  {
655  if (!isarray && garbage_left(isarray, &scan_length, compat))
656  {
657  free(nres);
660  return false;
661  }
662  }
663  pval = scan_length;
664 
665  if (type == ECPGt_numeric)
666  PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
667  else
668  PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
669 
670  PGTYPESnumeric_free(nres);
671  break;
672 
673  case ECPGt_interval:
674  if (*pval == '"')
675  pval++;
676 
677  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
678  endchar = *endptr;
679  *endptr = '\0';
680  ires = PGTYPESinterval_from_asc(pval, &scan_length);
681  *endptr = endchar;
682 
683  /* did we get an error? */
684  if (ires == NULL)
685  {
686  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
687  lineno, pval, errno);
688 
689  if (INFORMIX_MODE(compat))
690  {
691  /*
692  * Informix wants its own NULL value here instead
693  * of an error
694  */
695  ires = (interval *) ecpg_alloc(sizeof(interval), lineno);
696  if (!ires)
697  return false;
698 
700  }
701  else
702  {
705  return false;
706  }
707  }
708  else
709  {
710  if (*scan_length == '"')
711  scan_length++;
712 
713  if (!isarray && garbage_left(isarray, &scan_length, compat))
714  {
715  free(ires);
718  return false;
719  }
720  }
721  pval = scan_length;
722 
723  PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
724  free(ires);
725  break;
726 
727  case ECPGt_date:
728  if (*pval == '"')
729  pval++;
730 
731  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
732  endchar = *endptr;
733  *endptr = '\0';
734  ddres = PGTYPESdate_from_asc(pval, &scan_length);
735  *endptr = endchar;
736 
737  /* did we get an error? */
738  if (errno != 0)
739  {
740  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
741  lineno, pval, errno);
742 
743  if (INFORMIX_MODE(compat))
744  {
745  /*
746  * Informix wants its own NULL value here instead
747  * of an error
748  */
750  }
751  else
752  {
755  return false;
756  }
757  }
758  else
759  {
760  if (*scan_length == '"')
761  scan_length++;
762 
763  if (!isarray && garbage_left(isarray, &scan_length, compat))
764  {
767  return false;
768  }
769  }
770 
771  *((date *) (var + offset * act_tuple)) = ddres;
772  pval = scan_length;
773  break;
774 
775  case ECPGt_timestamp:
776  if (*pval == '"')
777  pval++;
778 
779  for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
780  endchar = *endptr;
781  *endptr = '\0';
782  tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
783  *endptr = endchar;
784 
785  /* did we get an error? */
786  if (errno != 0)
787  {
788  ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
789  lineno, pval, errno);
790 
791  if (INFORMIX_MODE(compat))
792  {
793  /*
794  * Informix wants its own NULL value here instead
795  * of an error
796  */
798  }
799  else
800  {
803  return false;
804  }
805  }
806  else
807  {
808  if (*scan_length == '"')
809  scan_length++;
810 
811  if (!isarray && garbage_left(isarray, &scan_length, compat))
812  {
815  return false;
816  }
817  }
818 
819  *((timestamp *) (var + offset * act_tuple)) = tres;
820  pval = scan_length;
821  break;
822 
823  default:
827  return false;
828  break;
829  }
830  if (ECPG_IS_ARRAY(isarray))
831  {
832  bool string = false;
833 
834  /* set array to next entry */
835  ++act_tuple;
836 
837  /* set pval to the next entry */
838 
839  /*
840  * *pval != '\0' should not be needed, but is used as a safety
841  * guard
842  */
843  for (; *pval != '\0' && (string || (!array_delimiter(isarray, *pval) && !array_boundary(isarray, *pval))); ++pval)
844  if (*pval == '"')
845  string = string ? false : true;
846 
847  if (array_delimiter(isarray, *pval))
848  ++pval;
849  }
850  }
851  } while (*pval != '\0' && !array_boundary(isarray, *pval));
852 
853  return true;
854 }
#define ECPG_DATA_NOT_ARRAY
Definition: ecpgerrno.h:33
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3129
date PGTYPESdate_from_asc(char *, char **)
Definition: datetime.c:48
#define ECPG_SQLSTATE_DATATYPE_MISMATCH
Definition: extern.h:217
#define ORACLE_MODE(X)
Definition: extern.h:24
int PGTYPESnumeric_copy(numeric *, numeric *)
Definition: numeric.c:1475
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
Definition: extern.h:221
char arr[FLEXIBLE_ARRAY_MEMBER]
Definition: extern.h:37
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3118
#define INFORMIX_MODE(X)
Definition: extern.h:23
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
char sqlwarn[8]
Definition: sqlca.h:39
static bool array_delimiter(enum ARRAY_TYPE isarray, char c)
Definition: data.c:21
#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:34
long date
Definition: pgtypes_date.h:8
#define false
Definition: c.h:283
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
Definition: extern.h:222
#define ECPG_UINT_FORMAT
Definition: ecpgerrno.h:23
#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER
Definition: extern.h:210
#define ECPG_SQLSTATE_NO_DATA
Definition: extern.h:201
void PGTYPESnumeric_free(numeric *)
Definition: numeric.c:470
numeric * PGTYPESnumeric_new(void)
Definition: numeric.c:127
void ecpg_log(const char *format,...) pg_attribute_printf(1
#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
const char * ecpg_type_name(enum ECPGttype)
Definition: typename.c:18
Definition: sqlca.h:19
interval * PGTYPESinterval_from_asc(char *, char **)
Definition: interval.c:1007
char * ecpg_alloc(long, int)
Definition: memory.c:19
#define ECPG_FLOAT_FORMAT
Definition: ecpgerrno.h:24
#define ECPG_UNSUPPORTED
Definition: ecpgerrno.h:18
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
Definition: error.c:13
enum COMPAT_MODE compat
Definition: ecpg.c:25
bool ecpg_internal_regression_mode
Definition: misc.c:30
#define ECPG_MISSING_INDICATOR
Definition: ecpgerrno.h:31
#define ECPG_NOT_FOUND
Definition: ecpgerrno.h:10
#define ECPG_IS_ARRAY(X)
Definition: extern.h:31
static bool check_special_value(char *ptr, double *retval, char **endptr)
Definition: data.c:102
numeric * PGTYPESnumeric_from_asc(char *, char **)
Definition: numeric.c:406
#define free(a)
Definition: header.h:65
void ECPGset_noind_null(enum ECPGttype type, void *ptr)
Definition: misc.c:320
#define ECPG_TIMESTAMP_FORMAT
Definition: ecpgerrno.h:28
static bool garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
Definition: data.c:47
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:3143
int PQfformat(const PGresult *res, int field_num)
Definition: fe-exec.c:2951
timestamp PGTYPEStimestamp_from_asc(char *, char **)
Definition: timestamp.c:207

◆ garbage_left()

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

Definition at line 47 of file data.c.

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

Referenced by ecpg_get_data().

48 {
49  /*
50  * INFORMIX allows for selecting a numeric into an int, the result is
51  * truncated
52  */
53  if (isarray == ECPG_ARRAY_NONE)
54  {
55  if (INFORMIX_MODE(compat) && **scan_length == '.')
56  {
57  /* skip invalid characters */
58  do
59  {
60  (*scan_length)++;
61  } while (isdigit((unsigned char) **scan_length));
62  }
63 
64  if (**scan_length != ' ' && **scan_length != '\0')
65  return true;
66  }
67  else if (ECPG_IS_ARRAY(isarray) && !array_delimiter(isarray, **scan_length) && !array_boundary(isarray, **scan_length))
68  return true;
69 
70  return false;
71 }
#define INFORMIX_MODE(X)
Definition: extern.h:23
static bool array_delimiter(enum ARRAY_TYPE isarray, char c)
Definition: data.c:21
static bool array_boundary(enum ARRAY_TYPE isarray, char c)
Definition: data.c:34
enum COMPAT_MODE compat
Definition: ecpg.c:25
#define ECPG_IS_ARRAY(X)
Definition: extern.h:31

◆ get_float8_infinity()

static double get_float8_infinity ( void  )
static

Definition at line 81 of file data.c.

Referenced by check_special_value().

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

◆ get_float8_nan()

static double get_float8_nan ( void  )
static

Definition at line 91 of file data.c.

Referenced by check_special_value().

92 {
93  /* (double) NAN doesn't work on some NetBSD/MIPS releases */
94 #if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__))
95  return (double) NAN;
96 #else
97  return (double) (0.0 / 0.0);
98 #endif
99 }