210{
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
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 */
254 value_for_indicator = -1;
255
256 switch (ind_type)
257 {
260 *((
short *) (
ind + ind_offset * act_tuple)) = value_for_indicator;
261 break;
264 *((
int *) (
ind + ind_offset * act_tuple)) = value_for_indicator;
265 break;
268 *((
long *) (
ind + ind_offset * act_tuple)) = value_for_indicator;
269 break;
272 *((
long long int *) (
ind + ind_offset * act_tuple)) = value_for_indicator;
273 break;
275 if (value_for_indicator == -1)
276 {
278 {
279 /*
280 * Informix has an additional way to specify NULLs note
281 * that this uses special values to denote NULL
282 */
284 }
285 else
286 {
289 NULL);
290 return false;
291 }
292 }
293 break;
294 default:
298 return false;
299 break;
300 }
301
302 if (value_for_indicator == -1)
303 return true;
304
305 /* let's check if it really is an array if it should be one */
307 {
308 if (*pval != '{')
309 {
312 return false;
313 }
314
316 {
321 break;
322
323 default:
324 pval++;
325 break;
326 }
327 }
328
329 do
330 {
331 if (binary)
332 {
333 if (varcharsize == 0 || varcharsize * offset >= size)
334 memcpy(var + offset * act_tuple, pval, size);
335 else
336 {
337 memcpy(var + offset * act_tuple, pval, varcharsize * offset);
338
339 if (varcharsize * offset < size)
340 {
341 /* truncation */
342 switch (ind_type)
343 {
346 *((
short *) (
ind + ind_offset * act_tuple)) = size;
347 break;
350 *((
int *) (
ind + ind_offset * act_tuple)) = size;
351 break;
354 *((
long *) (
ind + ind_offset * act_tuple)) = size;
355 break;
358 *((
long long int *) (
ind + ind_offset * act_tuple)) = size;
359 break;
360 default:
361 break;
362 }
364 }
365 }
366 pval += size;
367 }
368 else
369 {
371 {
372 long res;
373 unsigned long ures;
374 double dres;
375 char *scan_length;
380 char *endptr,
381 endchar;
382
386 res = strtol(pval, &scan_length, 10);
388 {
391 return false;
392 }
393 pval = scan_length;
394
396 {
398 *((short *) (var + offset * act_tuple)) = (short) res;
399 break;
401 *((int *) (var + offset * act_tuple)) = (int) res;
402 break;
404 *((long *) (var + offset * act_tuple)) = (long) res;
405 break;
406 default:
407 /* Cannot happen */
408 break;
409 }
410 break;
411
415 ures = strtoul(pval, &scan_length, 10);
417 {
420 return false;
421 }
422 pval = scan_length;
423
425 {
427 *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
428 break;
430 *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
431 break;
433 *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
434 break;
435 default:
436 /* Cannot happen */
437 break;
438 }
439 break;
440
442 *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
444 {
446 return false;
447 }
448 pval = scan_length;
449
450 break;
451
453 *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
455 {
457 return false;
458 }
459 pval = scan_length;
460
461 break;
462
465 if (isarray && *pval == '"')
466 pval++;
467
469 dres = strtod(pval, &scan_length);
470
471 if (isarray && *scan_length == '"')
472 scan_length++;
473
474 /* no special INFORMIX treatment for floats */
476 {
479 return false;
480 }
481 pval = scan_length;
482
484 {
486 *((float *) (var + offset * act_tuple)) = dres;
487 break;
489 *((double *) (var + offset * act_tuple)) = dres;
490 break;
491 default:
492 /* Cannot happen */
493 break;
494 }
495 break;
496
498 if (pval[0] == 'f' && pval[1] == '0円')
499 {
500 *((bool *) (var + offset * act_tuple)) = false;
501 pval++;
502 break;
503 }
504 else if (pval[0] == 't' && pval[1] == '0円')
505 {
506 *((bool *) (var + offset * act_tuple)) = true;
507 pval++;
508 break;
509 }
510 else if (pval[0] ==
'0円' &&
PQgetisnull(results, act_tuple, act_field))
511 {
512 /* NULL is valid */
513 break;
514 }
515
518 return false;
519 break;
520
522 {
525 long dst_size,
526 src_size,
527 dec_size;
528
530 src_size = size - 2; /* exclude backslash + 'x' */
531 dec_size = src_size < dst_size ? src_size : dst_size;
533
534 if (dst_size < src_size)
535 {
537
538 /* truncation */
539 switch (ind_type)
540 {
543 *((
short *) (
ind + ind_offset * act_tuple)) = rcv_size;
544 break;
547 *((
int *) (
ind + ind_offset * act_tuple)) = rcv_size;
548 break;
551 *((
long *) (
ind + ind_offset * act_tuple)) = rcv_size;
552 break;
555 *((
long long int *) (
ind + ind_offset * act_tuple)) = rcv_size;
556 break;
557 default:
558 break;
559 }
561 }
562
563 pval += size;
564 }
565 break;
566
570 {
571 char *
str = (
char *) (var + offset * act_tuple);
572
573 /*
574 * If varcharsize is unknown and the offset is that of
575 * char *, then this variable represents the array of
576 * character pointers. So, use extra indirection.
577 */
578 if (varcharsize == 0 && offset == sizeof(char *))
580
581 if (varcharsize > size)
582 {
583 /*
584 * compatibility mode, blank pad and null
585 * terminate char array
586 */
588 {
589 memset(
str,
' ', varcharsize);
590 memcpy(
str, pval, size);
591 str[varcharsize - 1] =
'0円';
592
593 /*
594 * compatibility mode empty string gets -1
595 * indicator but no warning
596 */
597 if (size == 0)
598 {
599 /* truncation */
600 switch (ind_type)
601 {
604 *((
short *) (
ind + ind_offset * act_tuple)) = -1;
605 break;
608 *((
int *) (
ind + ind_offset * act_tuple)) = -1;
609 break;
612 *((
long *) (
ind + ind_offset * act_tuple)) = -1;
613 break;
616 *((
long long int *) (
ind + ind_offset * act_tuple)) = -1;
617 break;
618 default:
619 break;
620 }
621 }
622 }
623 else
624 {
625 strncpy(
str, pval, size + 1);
626 }
627 /* do the rtrim() */
629 {
630 char *last =
str + size;
631
632 while (last >
str && (*last ==
' ' || *last ==
'0円'))
633 {
634 *last = '0円';
635 last--;
636 }
637 }
638 }
639 else
640 {
641 int charsize = varcharsize;
642
643 /*
644 * assume that the caller provided storage exactly
645 * fit when varcharsize is zero.
646 */
647 if (varcharsize == 0)
648 charsize = size + 1;
649
650 strncpy(
str, pval, charsize);
651
652 /* compatibility mode, null terminate char array */
654 {
656 str[charsize - 1] =
'0円';
657 }
658
660 {
661 /* truncation */
662 switch (ind_type)
663 {
666 *((
short *) (
ind + ind_offset * act_tuple)) = size;
667 break;
670 *((
int *) (
ind + ind_offset * act_tuple)) = size;
671 break;
674 *((
long *) (
ind + ind_offset * act_tuple)) = size;
675 break;
678 *((
long long int *) (
ind + ind_offset * act_tuple)) = size;
679 break;
680 default:
681 break;
682 }
684 }
685 }
686 pval += size;
687 }
688 break;
689
691 {
694
696 if (varcharsize == 0)
698 else
699 {
700 strncpy(
variable->arr, pval, varcharsize);
701
703 {
704 /* truncation */
705 switch (ind_type)
706 {
709 *((
short *) (
ind + ind_offset * act_tuple)) =
variable->len;
710 break;
713 *((
int *) (
ind + ind_offset * act_tuple)) =
variable->len;
714 break;
717 *((
long *) (
ind + ind_offset * act_tuple)) =
variable->len;
718 break;
721 *((
long long int *) (
ind + ind_offset * act_tuple)) =
variable->len;
722 break;
723 default:
724 break;
725 }
727
729 }
730 }
731 pval += size;
732 }
733 break;
734
737 for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
738 endchar = *endptr;
739 *endptr = '0円';
741 *endptr = endchar;
742
743 /* did we get an error? */
744 if (nres == NULL)
745 {
746 ecpg_log(
"ecpg_get_data on line %d: RESULT %s; errno %d\n",
747 lineno, pval, errno);
748
750 {
751 /*
752 * Informix wants its own NULL value here instead
753 * of an error
754 */
756 if (nres)
758 else
759 {
762 return false;
763 }
764 }
765 else
766 {
769 return false;
770 }
771 }
772 else
773 {
775 {
779 return false;
780 }
781 }
782 pval = scan_length;
783
786 else
788
790 break;
791
793 if (*pval == '"')
794 pval++;
795
796 for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
797 endchar = *endptr;
798 *endptr = '0円';
800 *endptr = endchar;
801
802 /* did we get an error? */
803 if (ires == NULL)
804 {
805 ecpg_log(
"ecpg_get_data on line %d: RESULT %s; errno %d\n",
806 lineno, pval, errno);
807
809 {
810 /*
811 * Informix wants its own NULL value here instead
812 * of an error
813 */
815 if (!ires)
816 return false;
817
819 }
820 else
821 {
824 return false;
825 }
826 }
827 else
828 {
829 if (*scan_length == '"')
830 scan_length++;
831
833 {
837 return false;
838 }
839 }
840 pval = scan_length;
841
844 break;
845
847 if (*pval == '"')
848 pval++;
849
850 for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
851 endchar = *endptr;
852 *endptr = '0円';
854 *endptr = endchar;
855
856 /* did we get an error? */
857 if (errno != 0)
858 {
859 ecpg_log(
"ecpg_get_data on line %d: RESULT %s; errno %d\n",
860 lineno, pval, errno);
861
863 {
864 /*
865 * Informix wants its own NULL value here instead
866 * of an error
867 */
869 }
870 else
871 {
874 return false;
875 }
876 }
877 else
878 {
879 if (*scan_length == '"')
880 scan_length++;
881
883 {
886 return false;
887 }
888 }
889
890 *((
date *) (var + offset * act_tuple)) = ddres;
891 pval = scan_length;
892 break;
893
895 if (*pval == '"')
896 pval++;
897
898 for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
899 endchar = *endptr;
900 *endptr = '0円';
902 *endptr = endchar;
903
904 /* did we get an error? */
905 if (errno != 0)
906 {
907 ecpg_log(
"ecpg_get_data on line %d: RESULT %s; errno %d\n",
908 lineno, pval, errno);
909
911 {
912 /*
913 * Informix wants its own NULL value here instead
914 * of an error
915 */
917 }
918 else
919 {
922 return false;
923 }
924 }
925 else
926 {
927 if (*scan_length == '"')
928 scan_length++;
929
931 {
934 return false;
935 }
936 }
937
938 *((
timestamp *) (var + offset * act_tuple)) = tres;
939 pval = scan_length;
940 break;
941
942 default:
946 return false;
947 break;
948 }
950 {
951 bool string = false;
952
953 /* set array to next entry */
954 ++act_tuple;
955
956 /* set pval to the next entry */
957
958 /*
959 * *pval != '0円' should not be needed, but is used as a safety
960 * guard
961 */
963 if (*pval == '"')
964 string =
string ?
false :
true;
965
967 ++pval;
968 }
969 }
971
972 return true;
973}
unsigned ecpg_hex_enc_len(unsigned srclen)
static bool garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
unsigned ecpg_hex_dec_len(unsigned srclen)
static unsigned hex_decode(const char *src, unsigned len, char *dst)
static bool array_delimiter(enum ARRAY_TYPE isarray, char c)
static bool array_boundary(enum ARRAY_TYPE isarray, char c)
static bool check_special_value(char *ptr, double *retval, char **endptr)
#define ECPG_CONVERT_BOOL
#define ECPG_FLOAT_FORMAT
#define ECPG_MISSING_INDICATOR
#define ECPG_INTERVAL_FORMAT
#define ECPG_OUT_OF_MEMORY
#define ECPG_DATA_NOT_ARRAY
#define ECPG_NUMERIC_FORMAT
#define ECPG_TIMESTAMP_FORMAT
#define ECPG_SQLSTATE_NO_DATA
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY
char * ecpg_alloc(long size, int lineno)
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR
#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER
void ecpg_log(const char *format,...) pg_attribute_printf(1
const char * ecpg_type_name(enum ECPGttype typ)
#define ECPG_SQLSTATE_DATATYPE_MISMATCH
void ecpg_raise(int line, int code, const char *sqlstate, const char *str)
bool ecpg_internal_regression_mode
@ ECPGt_unsigned_long_long
int PQfformat(const PGresult *res, int field_num)
struct sqlca_t * ECPGget_sqlca(void)
void ECPGset_noind_null(enum ECPGttype type, void *ptr)
date PGTYPESdate_from_asc(char *str, char **endptr)
int PGTYPESinterval_copy(interval *intvlsrc, interval *intvldest)
interval * PGTYPESinterval_from_asc(char *str, char **endptr)
int PGTYPESnumeric_copy(numeric *src, numeric *dst)
numeric * PGTYPESnumeric_new(void)
int PGTYPESnumeric_to_decimal(numeric *src, decimal *dst)
void PGTYPESnumeric_free(numeric *var)
numeric * PGTYPESnumeric_from_asc(char *str, char **endptr)
timestamp PGTYPEStimestamp_from_asc(char *str, char **endptr)