1 /* src/interfaces/ecpg/ecpglib/data.c */ 2 3 #define POSTGRES_ECPG_INTERNAL 4 #include "postgres_fe.h" 5 6 #include <math.h> 7 8 #include "ecpgtype.h" 9 #include "ecpglib.h" 10 #include "ecpgerrno.h" 11 #include "ecpglib_extern.h" 12 #include "sqlca.h" 13 #include "pgtypes_numeric.h" 14 #include "pgtypes_date.h" 15 #include "pgtypes_timestamp.h" 16 #include "pgtypes_interval.h" 17 18 /* returns true if character c is a delimiter for the given array type */ 19 static bool 20 array_delimiter(enum ARRAY_TYPE isarray, char c) 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 } 30 31 /* returns true if character c marks the boundary for the given array type */ 32 static bool 33 array_boundary(enum ARRAY_TYPE isarray, char c) 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 } 43 44 /* returns true if some garbage is found at the end of the scanned string */ 45 static bool 46 garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat) 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 } 71 72 /* stolen code from src/backend/utils/adt/float.c */ 73 #if defined(WIN32) && !defined(NAN) 74 static const uint32 nan[2] = {0xffffffff, 0x7fffffff}; 75 76 #define NAN (*(const double *) nan) 77 #endif 78 79 static double 80 get_float8_infinity(void) 81 { 82 #ifdef INFINITY 83 return (double) INFINITY; 84 #else 85 return (double) (HUGE_VAL * HUGE_VAL); 86 #endif 87 } 88 89 static double 90 get_float8_nan(void) 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 } 99 100 static bool 101 check_special_value(char *ptr, double *retval, char **endptr) 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 } 124 125 /* imported from src/backend/utils/adt/encode.c */ 126 127 unsigned 128 ecpg_hex_enc_len(unsigned srclen) 129 { 130 return srclen << 1; 131 } 132 133 unsigned 134 ecpg_hex_dec_len(unsigned srclen) 135 { 136 return srclen >> 1; 137 } 138 139 static inline char 140 get_hex(char c) 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 } 159 160 static unsigned 161 hex_decode(const char *src, unsigned len, char *dst) 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 } 189 190 unsigned 191 ecpg_hex_encode(const char *src, unsigned len, char *dst) 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 } 204 205 bool 206 ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, 207 enum ECPGttype type, enum ECPGttype ind_type, 208 char *var, char *ind, long varcharsize, long offset, 209 long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator) 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 { 220 ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, 221 ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL); 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 */ 229 if (ecpg_internal_regression_mode) 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 */ 243 ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL); 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: 259 case ECPGt_unsigned_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: 272 case ECPGt_unsigned_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 { 289 ecpg_raise(lineno, ECPG_MISSING_INDICATOR, 290 ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER, 291 NULL); 292 return false; 293 } 294 } 295 break; 296 default: 297 ecpg_raise(lineno, ECPG_UNSUPPORTED, 298 ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, 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 { 312 ecpg_raise(lineno, ECPG_DATA_NOT_ARRAY, 313 ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL); 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: 347 case ECPGt_unsigned_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: 360 case ECPGt_unsigned_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, 394 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 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 416 case ECPGt_unsigned_short: 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 { 422 ecpg_raise(lineno, ECPG_UINT_FORMAT, 423 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 424 return false; 425 } 426 pval = scan_length; 427 428 switch (type) 429 { 430 case ECPGt_unsigned_short: 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 { 451 ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 452 return false; 453 } 454 pval = scan_length; 455 456 break; 457 #endif /* HAVE_STRTOLL */ 458 #ifdef HAVE_STRTOULL 459 case ECPGt_unsigned_long_long: 460 *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10); 461 if (garbage_left(isarray, &scan_length, compat)) 462 { 463 ecpg_raise(lineno, ECPG_UINT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 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 { 486 ecpg_raise(lineno, ECPG_FLOAT_FORMAT, 487 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 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 525 ecpg_raise(lineno, ECPG_CONVERT_BOOL, 526 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 527 return false; 528 break; 529 530 case ECPGt_bytea: 531 { 532 struct ECPGgeneric_bytea *variable = 533 (struct ECPGgeneric_bytea *) (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: 551 case ECPGt_unsigned_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: 564 case ECPGt_unsigned_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 */ 599 if (ORACLE_MODE(compat) && (type == ECPGt_char || type == ECPGt_unsigned_char)) 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: 615 case ECPGt_unsigned_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: 628 case ECPGt_unsigned_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 { 660 if (type == ECPGt_char || type == ECPGt_unsigned_char) 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: 670 case ECPGt_unsigned_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: 683 case ECPGt_unsigned_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: 715 case ECPGt_unsigned_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: 728 case ECPGt_unsigned_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) 766 ECPGset_noind_null(ECPGt_numeric, nres); 767 else 768 { 769 ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, 770 ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL); 771 return false; 772 } 773 } 774 else 775 { 776 ecpg_raise(lineno, ECPG_NUMERIC_FORMAT, 777 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 778 return false; 779 } 780 } 781 else 782 { 783 if (!isarray && garbage_left(isarray, &scan_length, compat)) 784 { 785 free(nres); 786 ecpg_raise(lineno, ECPG_NUMERIC_FORMAT, 787 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 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 827 ECPGset_noind_null(ECPGt_interval, ires); 828 } 829 else 830 { 831 ecpg_raise(lineno, ECPG_INTERVAL_FORMAT, 832 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 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); 844 ecpg_raise(lineno, ECPG_INTERVAL_FORMAT, 845 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 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 */ 877 ECPGset_noind_null(ECPGt_date, &ddres); 878 } 879 else 880 { 881 ecpg_raise(lineno, ECPG_DATE_FORMAT, 882 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 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 { 893 ecpg_raise(lineno, ECPG_DATE_FORMAT, 894 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 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 */ 925 ECPGset_noind_null(ECPGt_timestamp, &tres); 926 } 927 else 928 { 929 ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT, 930 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 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 { 941 ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT, 942 ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); 943 return false; 944 } 945 } 946 947 *((timestamp *) (var + offset * act_tuple)) = tres; 948 pval = scan_length; 949 break; 950 951 default: 952 ecpg_raise(lineno, ECPG_UNSUPPORTED, 953 ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, 954 ecpg_type_name(type)); 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 } 983