3 #define POSTGRES_ECPG_INTERNAL
4 #include "postgres_fe.h"
11 #include "ecpgerrno.h"
14 #include "pgtypes_numeric.h"
15 #include "pgtypes_date.h"
16 #include "pgtypes_timestamp.h"
17 #include "pgtypes_interval.h"
20 garbage_left(enum ARRAY_TYPE isarray
, char *scan_length
, enum COMPAT_MODE compat
)
23 * INFORMIX allows for selecting a numeric into an int, the result is
26 if (isarray
== ECPG_ARRAY_NONE
&& INFORMIX_MODE(compat
) && *scan_length
== '.')
29 if (isarray
== ECPG_ARRAY_ARRAY
&& *scan_length
!= ',' && *scan_length
!= '}')
32 if (isarray
== ECPG_ARRAY_VECTOR
&& *scan_length
!= ' ' && *scan_length
!= '\0')
35 if (isarray
== ECPG_ARRAY_NONE
&& *scan_length
!= ' ' && *scan_length
!= '\0')
42 ecpg_get_data(const PGresult
*results
, int act_tuple
, int act_field
, int lineno
,
43 enum ECPGttype type
, enum ECPGttype ind_type
,
44 char *var
, char *ind
, long varcharsize
, long offset
,
45 long ind_offset
, enum ARRAY_TYPE isarray
, enum COMPAT_MODE compat
, bool force_indicator
)
47 struct sqlca_t
*sqlca
= ECPGget_sqlca();
48 char *pval
= (char *) PQgetvalue(results
, act_tuple
, act_field
);
49 int binary
= PQfformat(results
, act_field
);
50 int size
= PQgetlength(results
, act_tuple
, act_field
);
51 int value_for_indicator
= 0;
55 * If we are running in a regression test, do not log the offset variable,
56 * it depends on the machine's alignment.
58 if (ecpg_internal_regression_mode
)
63 ecpg_log("ecpg_get_data on line %d: RESULT: %s offset: %ld; array: %s\n", lineno
, pval
? (binary
? _("BINARY") : pval
) : _("EMPTY"), log_offset
, isarray
? _("yes") : _("no"));
65 /* We will have to decode the value */
68 * check for null value and set indicator accordingly, i.e. -1 if NULL and
71 if (PQgetisnull(results
, act_tuple
, act_field
))
72 value_for_indicator
= -1;
77 case ECPGt_unsigned_short
:
78 *((short *) (ind
+ ind_offset
* act_tuple
)) = value_for_indicator
;
81 case ECPGt_unsigned_int
:
82 *((int *) (ind
+ ind_offset
* act_tuple
)) = value_for_indicator
;
85 case ECPGt_unsigned_long
:
86 *((long *) (ind
+ ind_offset
* act_tuple
)) = value_for_indicator
;
88 #ifdef HAVE_LONG_LONG_INT_64
90 case ECPGt_unsigned_long_long
:
91 *((long long int *) (ind
+ ind_offset
* act_tuple
)) = value_for_indicator
;
93 #endif /* HAVE_LONG_LONG_INT_64 */
94 case ECPGt_NO_INDICATOR
:
95 if (value_for_indicator
== -1)
97 if (force_indicator
== false)
100 * Informix has an additional way to specify NULLs note
101 * that this uses special values to denote NULL
103 ECPGset_noind_null(type
, var
+ offset
* act_tuple
);
107 ecpg_raise(lineno
, ECPG_MISSING_INDICATOR
,
108 ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER
,
115 ecpg_raise(lineno
, ECPG_UNSUPPORTED
,
116 ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
,
117 ecpg_type_name(ind_type
));
122 if (value_for_indicator
== -1)
125 /* pval is a pointer to the value */
126 /* let's check if it really is an array if it should be one */
127 if (isarray
== ECPG_ARRAY_ARRAY
)
129 if (!pval
|| *pval
!= '{')
131 ecpg_raise(lineno
, ECPG_DATA_NOT_ARRAY
,
132 ECPG_SQLSTATE_DATATYPE_MISMATCH
, NULL
);
139 case ECPGt_unsigned_char
:
155 if (varcharsize
== 0 || varcharsize
* offset
>= size
)
156 memcpy((char *) ((long) var
+ offset
* act_tuple
),
160 memcpy((char *) ((long) var
+ offset
* act_tuple
),
161 pval
, varcharsize
* offset
);
163 if (varcharsize
* offset
< size
)
169 case ECPGt_unsigned_short
:
170 *((short *) (ind
+ ind_offset
* act_tuple
)) = size
;
173 case ECPGt_unsigned_int
:
174 *((int *) (ind
+ ind_offset
* act_tuple
)) = size
;
177 case ECPGt_unsigned_long
:
178 *((long *) (ind
+ ind_offset
* act_tuple
)) = size
;
180 #ifdef HAVE_LONG_LONG_INT_64
181 case ECPGt_long_long
:
182 case ECPGt_unsigned_long_long
:
183 *((long long int *) (ind
+ ind_offset
* act_tuple
)) = size
;
185 #endif /* HAVE_LONG_LONG_INT_64 */
189 sqlca
->sqlwarn
[0] = sqlca
->sqlwarn
[1] = 'W';
213 res
= strtol(pval
, &scan_length
, 10);
214 if (garbage_left(isarray
, scan_length
, compat
))
216 ecpg_raise(lineno
, ECPG_INT_FORMAT
,
217 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
228 *((short *) (var
+ offset
* act_tuple
)) = (short) res
;
231 *((int *) (var
+ offset
* act_tuple
)) = (int) res
;
234 *((long *) (var
+ offset
* act_tuple
)) = (long) res
;
242 case ECPGt_unsigned_short
:
243 case ECPGt_unsigned_int
:
244 case ECPGt_unsigned_long
:
247 ures
= strtoul(pval
, &scan_length
, 10);
248 if (garbage_left(isarray
, scan_length
, compat
))
250 ecpg_raise(lineno
, ECPG_UINT_FORMAT
,
251 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
261 case ECPGt_unsigned_short
:
262 *((unsigned short *) (var
+ offset
* act_tuple
)) = (unsigned short) ures
;
264 case ECPGt_unsigned_int
:
265 *((unsigned int *) (var
+ offset
* act_tuple
)) = (unsigned int) ures
;
267 case ECPGt_unsigned_long
:
268 *((unsigned long *) (var
+ offset
* act_tuple
)) = (unsigned long) ures
;
276 #ifdef HAVE_LONG_LONG_INT_64
278 case ECPGt_long_long
:
281 *((long long int *) (var
+ offset
* act_tuple
)) = strtoll(pval
, &scan_length
, 10);
282 if (garbage_left(isarray
, scan_length
, compat
))
284 ecpg_raise(lineno
, ECPG_INT_FORMAT
, ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
290 *((long long int *) (var
+ offset
* act_tuple
)) = (long long) 0;
293 #endif /* HAVE_STRTOLL */
295 case ECPGt_unsigned_long_long
:
298 *((unsigned long long int *) (var
+ offset
* act_tuple
)) = strtoull(pval
, &scan_length
, 10);
299 if ((isarray
&& *scan_length
!= ',' && *scan_length
!= '}')
300 || (!isarray
&& !(INFORMIX_MODE(compat
) && *scan_length
== '.') && *scan_length
!= '\0' && *scan_length
!= ' ')) /* Garbage left */
302 ecpg_raise(lineno
, ECPG_UINT_FORMAT
, ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
308 *((unsigned long long int *) (var
+ offset
* act_tuple
)) = (long long) 0;
311 #endif /* HAVE_STRTOULL */
312 #endif /* HAVE_LONG_LONG_INT_64 */
318 if (isarray
&& *pval
== '"')
319 dres
= strtod(pval
+ 1, &scan_length
);
321 dres
= strtod(pval
, &scan_length
);
323 if (isarray
&& *scan_length
== '"')
326 if (garbage_left(isarray
, scan_length
, compat
))
328 ecpg_raise(lineno
, ECPG_FLOAT_FORMAT
,
329 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
340 *((float *) (var
+ offset
* act_tuple
)) = dres
;
343 *((double *) (var
+ offset
* act_tuple
)) = dres
;
354 if (pval
[0] == 'f' && pval
[1] == '\0')
356 if (offset
== sizeof(char))
357 *((char *) (var
+ offset
* act_tuple
)) = false;
358 else if (offset
== sizeof(int))
359 *((int *) (var
+ offset
* act_tuple
)) = false;
361 ecpg_raise(lineno
, ECPG_CONVERT_BOOL
,
362 ECPG_SQLSTATE_DATATYPE_MISMATCH
,
363 _("different size"));
366 else if (pval
[0] == 't' && pval
[1] == '\0')
368 if (offset
== sizeof(char))
369 *((char *) (var
+ offset
* act_tuple
)) = true;
370 else if (offset
== sizeof(int))
371 *((int *) (var
+ offset
* act_tuple
)) = true;
373 ecpg_raise(lineno
, ECPG_CONVERT_BOOL
,
374 ECPG_SQLSTATE_DATATYPE_MISMATCH
,
375 _("different size"));
378 else if (pval
[0] == '\0' && PQgetisnull(results
, act_tuple
, act_field
))
385 ecpg_raise(lineno
, ECPG_CONVERT_BOOL
,
386 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
391 case ECPGt_unsigned_char
:
394 if (varcharsize
== 0 || varcharsize
> size
)
395 strncpy((char *) ((long) var
+ offset
* act_tuple
), pval
, size
+ 1);
398 strncpy((char *) ((long) var
+ offset
* act_tuple
), pval
, varcharsize
);
400 if (varcharsize
< size
)
406 case ECPGt_unsigned_short
:
407 *((short *) (ind
+ ind_offset
* act_tuple
)) = size
;
410 case ECPGt_unsigned_int
:
411 *((int *) (ind
+ ind_offset
* act_tuple
)) = size
;
414 case ECPGt_unsigned_long
:
415 *((long *) (ind
+ ind_offset
* act_tuple
)) = size
;
417 #ifdef HAVE_LONG_LONG_INT_64
418 case ECPGt_long_long
:
419 case ECPGt_unsigned_long_long
:
420 *((long long int *) (ind
+ ind_offset
* act_tuple
)) = size
;
422 #endif /* HAVE_LONG_LONG_INT_64 */
426 sqlca
->sqlwarn
[0] = sqlca
->sqlwarn
[1] = 'W';
436 struct ECPGgeneric_varchar
*variable
=
437 (struct ECPGgeneric_varchar
*) ((long) var
+ offset
* act_tuple
);
439 variable
->len
= size
;
440 if (varcharsize
== 0)
441 strncpy(variable
->arr
, pval
, variable
->len
);
444 strncpy(variable
->arr
, pval
, varcharsize
);
446 if (variable
->len
> varcharsize
)
452 case ECPGt_unsigned_short
:
453 *((short *) (ind
+ offset
* act_tuple
)) = variable
->len
;
456 case ECPGt_unsigned_int
:
457 *((int *) (ind
+ offset
* act_tuple
)) = variable
->len
;
460 case ECPGt_unsigned_long
:
461 *((long *) (ind
+ offset
* act_tuple
)) = variable
->len
;
463 #ifdef HAVE_LONG_LONG_INT_64
464 case ECPGt_long_long
:
465 case ECPGt_unsigned_long_long
:
466 *((long long int *) (ind
+ ind_offset
* act_tuple
)) = variable
->len
;
468 #endif /* HAVE_LONG_LONG_INT_64 */
472 sqlca
->sqlwarn
[0] = sqlca
->sqlwarn
[1] = 'W';
474 variable
->len
= varcharsize
;
485 if (isarray
&& *pval
== '"')
486 nres
= PGTYPESnumeric_from_asc(pval
+ 1, &scan_length
);
488 nres
= PGTYPESnumeric_from_asc(pval
, &scan_length
);
490 /* did we get an error? */
493 ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
494 lineno
, pval
? pval
: "", errno
);
496 if (INFORMIX_MODE(compat
))
499 * Informix wants its own NULL value here
500 * instead of an error
502 nres
= PGTYPESnumeric_new();
504 ECPGset_noind_null(ECPGt_numeric
, nres
);
507 ecpg_raise(lineno
, ECPG_OUT_OF_MEMORY
,
508 ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
, NULL
);
514 ecpg_raise(lineno
, ECPG_NUMERIC_FORMAT
,
515 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
521 if (isarray
&& *scan_length
== '"')
524 if (garbage_left(isarray
, scan_length
, compat
))
527 ecpg_raise(lineno
, ECPG_NUMERIC_FORMAT
,
528 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
535 nres
= PGTYPESnumeric_from_asc("0.0", &scan_length
);
537 if (type
== ECPGt_numeric
)
538 PGTYPESnumeric_copy(nres
, (numeric
*) (var
+ offset
* act_tuple
));
540 PGTYPESnumeric_to_decimal(nres
, (decimal
*) (var
+ offset
* act_tuple
));
548 if (isarray
&& *pval
== '"')
549 ires
= PGTYPESinterval_from_asc(pval
+ 1, &scan_length
);
551 ires
= PGTYPESinterval_from_asc(pval
, &scan_length
);
553 /* did we get an error? */
556 ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
557 lineno
, pval
? pval
: "", errno
);
559 if (INFORMIX_MODE(compat
))
562 * Informix wants its own NULL value here
563 * instead of an error
565 ires
= (interval
*) ecpg_alloc(sizeof(interval
), lineno
);
569 ECPGset_noind_null(ECPGt_interval
, ires
);
573 ecpg_raise(lineno
, ECPG_INTERVAL_FORMAT
,
574 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
580 if (isarray
&& *scan_length
== '"')
583 if (garbage_left(isarray
, scan_length
, compat
))
586 ecpg_raise(lineno
, ECPG_INTERVAL_FORMAT
,
587 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
594 ires
= PGTYPESinterval_from_asc("0 seconds", NULL
);
596 PGTYPESinterval_copy(ires
, (interval
*) (var
+ offset
* act_tuple
));
602 if (isarray
&& *pval
== '"')
603 ddres
= PGTYPESdate_from_asc(pval
+ 1, &scan_length
);
605 ddres
= PGTYPESdate_from_asc(pval
, &scan_length
);
607 /* did we get an error? */
610 ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
611 lineno
, pval
? pval
: "", errno
);
613 if (INFORMIX_MODE(compat
))
616 * Informix wants its own NULL value here
617 * instead of an error
619 ECPGset_noind_null(ECPGt_date
, &ddres
);
623 ecpg_raise(lineno
, ECPG_DATE_FORMAT
,
624 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
630 if (isarray
&& *scan_length
== '"')
633 if (garbage_left(isarray
, scan_length
, compat
))
635 ecpg_raise(lineno
, ECPG_DATE_FORMAT
,
636 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
641 *((date
*) (var
+ offset
* act_tuple
)) = ddres
;
646 case ECPGt_timestamp
:
649 if (isarray
&& *pval
== '"')
650 tres
= PGTYPEStimestamp_from_asc(pval
+ 1, &scan_length
);
652 tres
= PGTYPEStimestamp_from_asc(pval
, &scan_length
);
654 /* did we get an error? */
657 ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
658 lineno
, pval
? pval
: "", errno
);
660 if (INFORMIX_MODE(compat
))
663 * Informix wants its own NULL value here
664 * instead of an error
666 ECPGset_noind_null(ECPGt_timestamp
, &tres
);
670 ecpg_raise(lineno
, ECPG_TIMESTAMP_FORMAT
,
671 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
677 if (isarray
&& *scan_length
== '"')
680 if (garbage_left(isarray
, scan_length
, compat
))
682 ecpg_raise(lineno
, ECPG_TIMESTAMP_FORMAT
,
683 ECPG_SQLSTATE_DATATYPE_MISMATCH
, pval
);
688 *((timestamp
*) (var
+ offset
* act_tuple
)) = tres
;
694 ecpg_raise(lineno
, ECPG_UNSUPPORTED
,
695 ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
,
696 ecpg_type_name(type
));
700 if (isarray
== ECPG_ARRAY_ARRAY
)
704 /* set array to next entry */
707 /* set pval to the next entry */
708 for (; string
|| (*pval
!= ',' && *pval
!= '}' && *pval
!= '\0'); ++pval
)
710 string
= string
? false : true;
715 else if (isarray
== ECPG_ARRAY_VECTOR
)
719 /* set array to next entry */
722 /* set pval to the next entry */
723 for (; string
|| (*pval
!= ' ' && *pval
!= '\0'); ++pval
)
725 string
= string
? false : true;
731 } while (*pval
!= '\0' && ((isarray
== ECPG_ARRAY_ARRAY
&& *pval
!= '}') || isarray
== ECPG_ARRAY_VECTOR
));