YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/postgres/src/interfaces/ecpg/ecpglib/data.c
Line
Count
Source (jump to first uncovered line)
1
/* src/interfaces/ecpg/ecpglib/data.c */
2
3
#define POSTGRES_ECPG_INTERNAL
4
#include "postgres_fe.h"
5
6
#include <float.h>
7
#include <math.h>
8
9
#include "ecpgtype.h"
10
#include "ecpglib.h"
11
#include "ecpgerrno.h"
12
#include "extern.h"
13
#include "sqlca.h"
14
#include "pgtypes_numeric.h"
15
#include "pgtypes_date.h"
16
#include "pgtypes_timestamp.h"
17
#include "pgtypes_interval.h"
18
19
/* returns true if character c is a delimiter for the given array type */
20
static bool
21
array_delimiter(enum ARRAY_TYPE isarray, char c)
22
0
{
23
0
  if (isarray == ECPG_ARRAY_ARRAY && c == ',')
24
0
    return true;
25
26
0
  if (isarray == ECPG_ARRAY_VECTOR && c == ' ')
27
0
    return true;
28
29
0
  return false;
30
0
}
31
32
/* returns true if character c marks the boundary for the given array type */
33
static bool
34
array_boundary(enum ARRAY_TYPE isarray, char c)
35
0
{
36
0
  if (isarray == ECPG_ARRAY_ARRAY && c == '}')
37
0
    return true;
38
39
0
  if (isarray == ECPG_ARRAY_VECTOR && c == '\0')
40
0
    return true;
41
42
0
  return false;
43
0
}
44
45
/* returns true if some garbage is found at the end of the scanned string */
46
static bool
47
garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
48
0
{
49
  /*
50
   * INFORMIX allows for selecting a numeric into an int, the result is
51
   * truncated
52
   */
53
0
  if (isarray == ECPG_ARRAY_NONE)
54
0
  {
55
0
    if (INFORMIX_MODE(compat) && **scan_length == '.')
56
0
    {
57
      /* skip invalid characters */
58
0
      do
59
0
      {
60
0
        (*scan_length)++;
61
0
      } while (isdigit((unsigned char) **scan_length));
62
0
    }
63
64
0
    if (**scan_length != ' ' && **scan_length != '\0')
65
0
      return true;
66
0
  }
67
0
  else if (ECPG_IS_ARRAY(isarray) && !array_delimiter(isarray, **scan_length) && !array_boundary(isarray, **scan_length))
68
0
    return true;
69
70
0
  return false;
71
0
}
72
73
/* stolen code from src/backend/utils/adt/float.c */
74
#if defined(WIN32) && !defined(NAN)
75
static const uint32 nan[2] = {0xffffffff, 0x7fffffff};
76
77
#define NAN (*(const double *) nan)
78
#endif
79
80
static double
81
get_float8_infinity(void)
82
0
{
83
0
#ifdef INFINITY
84
0
  return (double) INFINITY;
85
#else
86
  return (double) (HUGE_VAL * HUGE_VAL);
87
#endif
88
0
}
89
90
static double
91
get_float8_nan(void)
92
0
{
93
  /* (double) NAN doesn't work on some NetBSD/MIPS releases */
94
0
#if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__))
95
0
  return (double) NAN;
96
#else
97
  return (double) (0.0 / 0.0);
98
#endif
99
0
}
100
101
static bool
102
check_special_value(char *ptr, double *retval, char **endptr)
103
0
{
104
0
  if (pg_strncasecmp(ptr, "NaN", 3) == 0)
105
0
  {
106
0
    *retval = get_float8_nan();
107
0
    *endptr = ptr + 3;
108
0
    return true;
109
0
  }
110
0
  else if (pg_strncasecmp(ptr, "Infinity", 8) == 0)
111
0
  {
112
0
    *retval = get_float8_infinity();
113
0
    *endptr = ptr + 8;
114
0
    return true;
115
0
  }
116
0
  else if (pg_strncasecmp(ptr, "-Infinity", 9) == 0)
117
0
  {
118
0
    *retval = -get_float8_infinity();
119
0
    *endptr = ptr + 9;
120
0
    return true;
121
0
  }
122
123
0
  return false;
124
0
}
125
126
bool
127
ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
128
        enum ECPGttype type, enum ECPGttype ind_type,
129
        char *var, char *ind, long varcharsize, long offset,
130
        long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
131
0
{
132
0
  struct sqlca_t *sqlca = ECPGget_sqlca();
133
0
  char     *pval = (char *) PQgetvalue(results, act_tuple, act_field);
134
0
  int     binary = PQfformat(results, act_field);
135
0
  int     size = PQgetlength(results, act_tuple, act_field);
136
0
  int     value_for_indicator = 0;
137
0
  long    log_offset;
138
139
0
  if (sqlca == NULL)
140
0
  {
141
0
    ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
142
0
           ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
143
0
    return false;
144
0
  }
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
   */
150
0
  if (ecpg_internal_regression_mode)
151
0
    log_offset = -1;
152
0
  else
153
0
    log_offset = offset;
154
155
0
  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
0
  if (!pval)
159
0
  {
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
     */
164
0
    ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
165
0
    return false;
166
0
  }
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
0
  if (PQgetisnull(results, act_tuple, act_field))
175
0
    value_for_indicator = -1;
176
177
0
  switch (ind_type)
178
0
  {
179
0
    case ECPGt_short:
180
0
    case ECPGt_unsigned_short:
181
0
      *((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
182
0
      break;
183
0
    case ECPGt_int:
184
0
    case ECPGt_unsigned_int:
185
0
      *((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
186
0
      break;
187
0
    case ECPGt_long:
188
0
    case ECPGt_unsigned_long:
189
0
      *((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
190
0
      break;
191
0
#ifdef HAVE_LONG_LONG_INT
192
0
    case ECPGt_long_long:
193
0
    case ECPGt_unsigned_long_long:
194
0
      *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
195
0
      break;
196
0
#endif              /* HAVE_LONG_LONG_INT */
197
0
    case ECPGt_NO_INDICATOR:
198
0
      if (value_for_indicator == -1)
199
0
      {
200
0
        if (force_indicator == false)
201
0
        {
202
          /*
203
           * Informix has an additional way to specify NULLs note
204
           * that this uses special values to denote NULL
205
           */
206
0
          ECPGset_noind_null(type, var + offset * act_tuple);
207
0
        }
208
0
        else
209
0
        {
210
0
          ecpg_raise(lineno, ECPG_MISSING_INDICATOR,
211
0
                 ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER,
212
0
                 NULL);
213
0
          return false;
214
0
        }
215
0
      }
216
0
      break;
217
0
    default:
218
0
      ecpg_raise(lineno, ECPG_UNSUPPORTED,
219
0
             ECPG_SQLSTATE_ECPG_INTERNAL_ERROR,
220
0
             ecpg_type_name(ind_type));
221
0
      return false;
222
0
      break;
223
0
  }
224
225
0
  if (value_for_indicator == -1)
226
0
    return true;
227
228
  /* let's check if it really is an array if it should be one */
229
0
  if (isarray == ECPG_ARRAY_ARRAY)
230
0
  {
231
0
    if (*pval != '{')
232
0
    {
233
0
      ecpg_raise(lineno, ECPG_DATA_NOT_ARRAY,
234
0
             ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
235
0
      return false;
236
0
    }
237
238
0
    switch (type)
239
0
    {
240
0
      case ECPGt_char:
241
0
      case ECPGt_unsigned_char:
242
0
      case ECPGt_varchar:
243
0
      case ECPGt_string:
244
0
        break;
245
246
0
      default:
247
0
        pval++;
248
0
        break;
249
0
    }
250
0
  }
251
252
0
  do
253
0
  {
254
0
    if (binary)
255
0
    {
256
0
      if (varcharsize == 0 || varcharsize * offset >= size)
257
0
        memcpy(var + offset * act_tuple, pval, size);
258
0
      else
259
0
      {
260
0
        memcpy(var + offset * act_tuple, pval, varcharsize * offset);
261
262
0
        if (varcharsize * offset < size)
263
0
        {
264
          /* truncation */
265
0
          switch (ind_type)
266
0
          {
267
0
            case ECPGt_short:
268
0
            case ECPGt_unsigned_short:
269
0
              *((short *) (ind + ind_offset * act_tuple)) = size;
270
0
              break;
271
0
            case ECPGt_int:
272
0
            case ECPGt_unsigned_int:
273
0
              *((int *) (ind + ind_offset * act_tuple)) = size;
274
0
              break;
275
0
            case ECPGt_long:
276
0
            case ECPGt_unsigned_long:
277
0
              *((long *) (ind + ind_offset * act_tuple)) = size;
278
0
              break;
279
0
#ifdef HAVE_LONG_LONG_INT
280
0
            case ECPGt_long_long:
281
0
            case ECPGt_unsigned_long_long:
282
0
              *((long long int *) (ind + ind_offset * act_tuple)) = size;
283
0
              break;
284
0
#endif              /* HAVE_LONG_LONG_INT */
285
0
            default:
286
0
              break;
287
0
          }
288
0
          sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
289
0
        }
290
0
      }
291
0
      pval += size;
292
0
    }
293
0
    else
294
0
    {
295
0
      switch (type)
296
0
      {
297
0
          long    res;
298
0
          unsigned long ures;
299
0
          double    dres;
300
0
          char     *scan_length;
301
0
          numeric    *nres;
302
0
          date    ddres;
303
0
          timestamp tres;
304
0
          interval   *ires;
305
0
          char     *endptr,
306
0
                endchar;
307
308
0
        case ECPGt_short:
309
0
        case ECPGt_int:
310
0
        case ECPGt_long:
311
0
          res = strtol(pval, &scan_length, 10);
312
0
          if (garbage_left(isarray, &scan_length, compat))
313
0
          {
314
0
            ecpg_raise(lineno, ECPG_INT_FORMAT,
315
0
                   ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
316
0
            return false;
317
0
          }
318
0
          pval = scan_length;
319
320
0
          switch (type)
321
0
          {
322
0
            case ECPGt_short:
323
0
              *((short *) (var + offset * act_tuple)) = (short) res;
324
0
              break;
325
0
            case ECPGt_int:
326
0
              *((int *) (var + offset * act_tuple)) = (int) res;
327
0
              break;
328
0
            case ECPGt_long:
329
0
              *((long *) (var + offset * act_tuple)) = (long) res;
330
0
              break;
331
0
            default:
332
              /* Cannot happen */
333
0
              break;
334
0
          }
335
0
          break;
336
337
0
        case ECPGt_unsigned_short:
338
0
        case ECPGt_unsigned_int:
339
0
        case ECPGt_unsigned_long:
340
0
          ures = strtoul(pval, &scan_length, 10);
341
0
          if (garbage_left(isarray, &scan_length, compat))
342
0
          {
343
0
            ecpg_raise(lineno, ECPG_UINT_FORMAT,
344
0
                   ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
345
0
            return false;
346
0
          }
347
0
          pval = scan_length;
348
349
0
          switch (type)
350
0
          {
351
0
            case ECPGt_unsigned_short:
352
0
              *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
353
0
              break;
354
0
            case ECPGt_unsigned_int:
355
0
              *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
356
0
              break;
357
0
            case ECPGt_unsigned_long:
358
0
              *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
359
0
              break;
360
0
            default:
361
              /* Cannot happen */
362
0
              break;
363
0
          }
364
0
          break;
365
366
0
#ifdef HAVE_LONG_LONG_INT
367
0
#ifdef HAVE_STRTOLL
368
0
        case ECPGt_long_long:
369
0
          *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
370
0
          if (garbage_left(isarray, &scan_length, compat))
371
0
          {
372
0
            ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
373
0
            return false;
374
0
          }
375
0
          pval = scan_length;
376
377
0
          break;
378
0
#endif              /* HAVE_STRTOLL */
379
0
#ifdef HAVE_STRTOULL
380
0
        case ECPGt_unsigned_long_long:
381
0
          *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
382
0
          if (garbage_left(isarray, &scan_length, compat))
383
0
          {
384
0
            ecpg_raise(lineno, ECPG_UINT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
385
0
            return false;
386
0
          }
387
0
          pval = scan_length;
388
389
0
          break;
390
0
#endif              /* HAVE_STRTOULL */
391
0
#endif              /* HAVE_LONG_LONG_INT */
392
393
0
        case ECPGt_float:
394
0
        case ECPGt_double:
395
0
          if (isarray && *pval == '"')
396
0
            pval++;
397
398
0
          if (!check_special_value(pval, &dres, &scan_length))
399
0
            dres = strtod(pval, &scan_length);
400
401
0
          if (isarray && *scan_length == '"')
402
0
            scan_length++;
403
404
          /* no special INFORMIX treatment for floats */
405
0
          if (garbage_left(isarray, &scan_length, ECPG_COMPAT_PGSQL))
406
0
          {
407
0
            ecpg_raise(lineno, ECPG_FLOAT_FORMAT,
408
0
                   ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
409
0
            return false;
410
0
          }
411
0
          pval = scan_length;
412
413
0
          switch (type)
414
0
          {
415
0
            case ECPGt_float:
416
0
              *((float *) (var + offset * act_tuple)) = dres;
417
0
              break;
418
0
            case ECPGt_double:
419
0
              *((double *) (var + offset * act_tuple)) = dres;
420
0
              break;
421
0
            default:
422
              /* Cannot happen */
423
0
              break;
424
0
          }
425
0
          break;
426
427
0
        case ECPGt_bool:
428
0
          if (pval[0] == 'f' && pval[1] == '\0')
429
0
          {
430
0
            *((bool *) (var + offset * act_tuple)) = false;
431
0
            pval++;
432
0
            break;
433
0
          }
434
0
          else if (pval[0] == 't' && pval[1] == '\0')
435
0
          {
436
0
            *((bool *) (var + offset * act_tuple)) = true;
437
0
            pval++;
438
0
            break;
439
0
          }
440
0
          else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
441
0
          {
442
            /* NULL is valid */
443
0
            break;
444
0
          }
445
446
0
          ecpg_raise(lineno, ECPG_CONVERT_BOOL,
447
0
                 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
448
0
          return false;
449
0
          break;
450
451
0
        case ECPGt_char:
452
0
        case ECPGt_unsigned_char:
453
0
        case ECPGt_string:
454
0
          {
455
0
            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
0
            if (varcharsize == 0 && offset == sizeof(char *))
463
0
              str = *(char **) str;
464
465
0
            if (varcharsize == 0 || varcharsize > size)
466
0
            {
467
              /*
468
               * compatibility mode, blank pad and null
469
               * terminate char array
470
               */
471
0
              if (ORACLE_MODE(compat) && (type == ECPGt_char || type == ECPGt_unsigned_char))
472
0
              {
473
0
                memset(str, ' ', varcharsize);
474
0
                memcpy(str, pval, size);
475
0
                str[varcharsize - 1] = '\0';
476
477
                /*
478
                 * compatibility mode empty string gets -1
479
                 * indicator but no warning
480
                 */
481
0
                if (size == 0)
482
0
                {
483
                  /* truncation */
484
0
                  switch (ind_type)
485
0
                  {
486
0
                    case ECPGt_short:
487
0
                    case ECPGt_unsigned_short:
488
0
                      *((short *) (ind + ind_offset * act_tuple)) = -1;
489
0
                      break;
490
0
                    case ECPGt_int:
491
0
                    case ECPGt_unsigned_int:
492
0
                      *((int *) (ind + ind_offset * act_tuple)) = -1;
493
0
                      break;
494
0
                    case ECPGt_long:
495
0
                    case ECPGt_unsigned_long:
496
0
                      *((long *) (ind + ind_offset * act_tuple)) = -1;
497
0
                      break;
498
0
#ifdef HAVE_LONG_LONG_INT
499
0
                    case ECPGt_long_long:
500
0
                    case ECPGt_unsigned_long_long:
501
0
                      *((long long int *) (ind + ind_offset * act_tuple)) = -1;
502
0
                      break;
503
0
#endif              /* HAVE_LONG_LONG_INT */
504
0
                    default:
505
0
                      break;
506
0
                  }
507
0
                }
508
0
              }
509
0
              else
510
0
              {
511
0
                strncpy(str, pval, size + 1);
512
0
              }
513
              /* do the rtrim() */
514
0
              if (type == ECPGt_string)
515
0
              {
516
0
                char     *last = str + size;
517
518
0
                while (last > str && (*last == ' ' || *last == '\0'))
519
0
                {
520
0
                  *last = '\0';
521
0
                  last--;
522
0
                }
523
0
              }
524
0
            }
525
0
            else
526
0
            {
527
0
              strncpy(str, pval, varcharsize);
528
529
              /* compatibility mode, null terminate char array */
530
0
              if (ORACLE_MODE(compat) && (varcharsize - 1) < size)
531
0
              {
532
0
                if (type == ECPGt_char || type == ECPGt_unsigned_char)
533
0
                  str[varcharsize - 1] = '\0';
534
0
              }
535
536
0
              if (varcharsize < size || (ORACLE_MODE(compat) && (varcharsize - 1) < size))
537
0
              {
538
                /* truncation */
539
0
                switch (ind_type)
540
0
                {
541
0
                  case ECPGt_short:
542
0
                  case ECPGt_unsigned_short:
543
0
                    *((short *) (ind + ind_offset * act_tuple)) = size;
544
0
                    break;
545
0
                  case ECPGt_int:
546
0
                  case ECPGt_unsigned_int:
547
0
                    *((int *) (ind + ind_offset * act_tuple)) = size;
548
0
                    break;
549
0
                  case ECPGt_long:
550
0
                  case ECPGt_unsigned_long:
551
0
                    *((long *) (ind + ind_offset * act_tuple)) = size;
552
0
                    break;
553
0
#ifdef HAVE_LONG_LONG_INT
554
0
                  case ECPGt_long_long:
555
0
                  case ECPGt_unsigned_long_long:
556
0
                    *((long long int *) (ind + ind_offset * act_tuple)) = size;
557
0
                    break;
558
0
#endif              /* HAVE_LONG_LONG_INT */
559
0
                  default:
560
0
                    break;
561
0
                }
562
0
                sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
563
0
              }
564
0
            }
565
0
            pval += size;
566
0
          }
567
0
          break;
568
569
0
        case ECPGt_varchar:
570
0
          {
571
0
            struct ECPGgeneric_varchar *variable =
572
0
            (struct ECPGgeneric_varchar *) (var + offset * act_tuple);
573
574
0
            variable->len = size;
575
0
            if (varcharsize == 0)
576
0
              strncpy(variable->arr, pval, variable->len);
577
0
            else
578
0
            {
579
0
              strncpy(variable->arr, pval, varcharsize);
580
581
0
              if (variable->len > varcharsize)
582
0
              {
583
                /* truncation */
584
0
                switch (ind_type)
585
0
                {
586
0
                  case ECPGt_short:
587
0
                  case ECPGt_unsigned_short:
588
0
                    *((short *) (ind + ind_offset * act_tuple)) = variable->len;
589
0
                    break;
590
0
                  case ECPGt_int:
591
0
                  case ECPGt_unsigned_int:
592
0
                    *((int *) (ind + ind_offset * act_tuple)) = variable->len;
593
0
                    break;
594
0
                  case ECPGt_long:
595
0
                  case ECPGt_unsigned_long:
596
0
                    *((long *) (ind + ind_offset * act_tuple)) = variable->len;
597
0
                    break;
598
0
#ifdef HAVE_LONG_LONG_INT
599
0
                  case ECPGt_long_long:
600
0
                  case ECPGt_unsigned_long_long:
601
0
                    *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
602
0
                    break;
603
0
#endif              /* HAVE_LONG_LONG_INT */
604
0
                  default:
605
0
                    break;
606
0
                }
607
0
                sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
608
609
0
                variable->len = varcharsize;
610
0
              }
611
0
            }
612
0
            pval += size;
613
0
          }
614
0
          break;
615
616
0
        case ECPGt_decimal:
617
0
        case ECPGt_numeric:
618
0
          for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
619
0
          endchar = *endptr;
620
0
          *endptr = '\0';
621
0
          nres = PGTYPESnumeric_from_asc(pval, &scan_length);
622
0
          *endptr = endchar;
623
624
          /* did we get an error? */
625
0
          if (nres == NULL)
626
0
          {
627
0
            ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
628
0
                 lineno, pval, errno);
629
630
0
            if (INFORMIX_MODE(compat))
631
0
            {
632
              /*
633
               * Informix wants its own NULL value here instead
634
               * of an error
635
               */
636
0
              nres = PGTYPESnumeric_new();
637
0
              if (nres)
638
0
                ECPGset_noind_null(ECPGt_numeric, nres);
639
0
              else
640
0
              {
641
0
                ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
642
0
                       ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
643
0
                return false;
644
0
              }
645
0
            }
646
0
            else
647
0
            {
648
0
              ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
649
0
                     ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
650
0
              return false;
651
0
            }
652
0
          }
653
0
          else
654
0
          {
655
0
            if (!isarray && garbage_left(isarray, &scan_length, compat))
656
0
            {
657
0
              free(nres);
658
0
              ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
659
0
                     ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
660
0
              return false;
661
0
            }
662
0
          }
663
0
          pval = scan_length;
664
665
0
          if (type == ECPGt_numeric)
666
0
            PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
667
0
          else
668
0
            PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
669
670
0
          PGTYPESnumeric_free(nres);
671
0
          break;
672
673
0
        case ECPGt_interval:
674
0
          if (*pval == '"')
675
0
            pval++;
676
677
0
          for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
678
0
          endchar = *endptr;
679
0
          *endptr = '\0';
680
0
          ires = PGTYPESinterval_from_asc(pval, &scan_length);
681
0
          *endptr = endchar;
682
683
          /* did we get an error? */
684
0
          if (ires == NULL)
685
0
          {
686
0
            ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
687
0
                 lineno, pval, errno);
688
689
0
            if (INFORMIX_MODE(compat))
690
0
            {
691
              /*
692
               * Informix wants its own NULL value here instead
693
               * of an error
694
               */
695
0
              ires = (interval *) ecpg_alloc(sizeof(interval), lineno);
696
0
              if (!ires)
697
0
                return false;
698
699
0
              ECPGset_noind_null(ECPGt_interval, ires);
700
0
            }
701
0
            else
702
0
            {
703
0
              ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
704
0
                     ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
705
0
              return false;
706
0
            }
707
0
          }
708
0
          else
709
0
          {
710
0
            if (*scan_length == '"')
711
0
              scan_length++;
712
713
0
            if (!isarray && garbage_left(isarray, &scan_length, compat))
714
0
            {
715
0
              free(ires);
716
0
              ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
717
0
                     ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
718
0
              return false;
719
0
            }
720
0
          }
721
0
          pval = scan_length;
722
723
0
          PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
724
0
          free(ires);
725
0
          break;
726
727
0
        case ECPGt_date:
728
0
          if (*pval == '"')
729
0
            pval++;
730
731
0
          for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
732
0
          endchar = *endptr;
733
0
          *endptr = '\0';
734
0
          ddres = PGTYPESdate_from_asc(pval, &scan_length);
735
0
          *endptr = endchar;
736
737
          /* did we get an error? */
738
0
          if (errno != 0)
739
0
          {
740
0
            ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
741
0
                 lineno, pval, errno);
742
743
0
            if (INFORMIX_MODE(compat))
744
0
            {
745
              /*
746
               * Informix wants its own NULL value here instead
747
               * of an error
748
               */
749
0
              ECPGset_noind_null(ECPGt_date, &ddres);
750
0
            }
751
0
            else
752
0
            {
753
0
              ecpg_raise(lineno, ECPG_DATE_FORMAT,
754
0
                     ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
755
0
              return false;
756
0
            }
757
0
          }
758
0
          else
759
0
          {
760
0
            if (*scan_length == '"')
761
0
              scan_length++;
762
763
0
            if (!isarray && garbage_left(isarray, &scan_length, compat))
764
0
            {
765
0
              ecpg_raise(lineno, ECPG_DATE_FORMAT,
766
0
                     ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
767
0
              return false;
768
0
            }
769
0
          }
770
771
0
          *((date *) (var + offset * act_tuple)) = ddres;
772
0
          pval = scan_length;
773
0
          break;
774
775
0
        case ECPGt_timestamp:
776
0
          if (*pval == '"')
777
0
            pval++;
778
779
0
          for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
780
0
          endchar = *endptr;
781
0
          *endptr = '\0';
782
0
          tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
783
0
          *endptr = endchar;
784
785
          /* did we get an error? */
786
0
          if (errno != 0)
787
0
          {
788
0
            ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
789
0
                 lineno, pval, errno);
790
791
0
            if (INFORMIX_MODE(compat))
792
0
            {
793
              /*
794
               * Informix wants its own NULL value here instead
795
               * of an error
796
               */
797
0
              ECPGset_noind_null(ECPGt_timestamp, &tres);
798
0
            }
799
0
            else
800
0
            {
801
0
              ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
802
0
                     ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
803
0
              return false;
804
0
            }
805
0
          }
806
0
          else
807
0
          {
808
0
            if (*scan_length == '"')
809
0
              scan_length++;
810
811
0
            if (!isarray && garbage_left(isarray, &scan_length, compat))
812
0
            {
813
0
              ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
814
0
                     ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
815
0
              return false;
816
0
            }
817
0
          }
818
819
0
          *((timestamp *) (var + offset * act_tuple)) = tres;
820
0
          pval = scan_length;
821
0
          break;
822
823
0
        default:
824
0
          ecpg_raise(lineno, ECPG_UNSUPPORTED,
825
0
                 ECPG_SQLSTATE_ECPG_INTERNAL_ERROR,
826
0
                 ecpg_type_name(type));
827
0
          return false;
828
0
          break;
829
0
      }
830
0
      if (ECPG_IS_ARRAY(isarray))
831
0
      {
832
0
        bool    string = false;
833
834
        /* set array to next entry */
835
0
        ++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
0
        for (; *pval != '\0' && (string || (!array_delimiter(isarray, *pval) && !array_boundary(isarray, *pval))); ++pval)
844
0
          if (*pval == '"')
845
0
            string = string ? false : true;
846
847
0
        if (array_delimiter(isarray, *pval))
848
0
          ++pval;
849
0
      }
850
0
    }
851
0
  } while (*pval != '\0' && !array_boundary(isarray, *pval));
852
853
0
  return true;
854
0
}