PostgreSQL Source Code: src/interfaces/ecpg/ecpglib/data.c Source File (original) (raw)

1

2

3#define POSTGRES_ECPG_INTERNAL

5

6#include <math.h>

7

17

18

19static bool

21{

23 return true;

24

26 return true;

27

28 return false;

29}

30

31

32static bool

34{

36 return true;

37

39 return true;

40

41 return false;

42}

43

44

45static bool

47{

48

49

50

51

53 {

55 {

56

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 }

67 return true;

68

69 return false;

70}

71

72

73#if defined(WIN32) && !defined(NAN)

74static const uint32 nan[2] = {0xffffffff, 0x7fffffff};

75

76#define NAN (*(const double *) nan)

77#endif

78

79static double

81{

82#ifdef INFINITY

83 return (double) INFINITY;

84#else

85 return (double) (HUGE_VAL * HUGE_VAL);

86#endif

87}

88

89static double

91{

92

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

100static bool

102{

104 {

106 *endptr = ptr + 3;

107 return true;

108 }

110 {

112 *endptr = ptr + 8;

113 return true;

114 }

116 {

118 *endptr = ptr + 9;

119 return true;

120 }

121

122 return false;

123}

124

125

126

127unsigned

129{

130 return srclen << 1;

131}

132

133unsigned

135{

136 return srclen >> 1;

137}

138

139static inline char

141{

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)

156

157 return (char) res;

158}

159

160static unsigned

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 }

180 if (s >= srcend)

181 return -1;

182

184 *p++ = v1 | v2;

185 }

186

187 return p - dst;

188}

189

190unsigned

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

205bool

208 char *var, char *ind, long varcharsize, long offset,

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

218 if (sqlca == NULL)

219 {

222 return false;

223 }

224

225

226

227

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

237 if (!pval)

238 {

239

240

241

242

244 return false;

245 }

246

247

248

249

250

251

252

253 if (PQgetisnull(results, act_tuple, act_field))

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

281

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

307 {

308 if (*pval != '{')

309 {

312 return false;

313 }

314

315 switch (type)

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

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 }

363 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';

364 }

365 }

366 pval += size;

367 }

368 else

369 {

370 switch (type)

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

395 switch (type)

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

408 break;

409 }

410 break;

411

415 ures = strtoul(pval, &scan_length, 10);

417 {

420 return false;

421 }

422 pval = scan_length;

423

424 switch (type)

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

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

476 {

479 return false;

480 }

481 pval = scan_length;

482

483 switch (type)

484 {

486 *((float *) (var + offset * act_tuple)) = dres;

487 break;

489 *((double *) (var + offset * act_tuple)) = dres;

490 break;

491 default:

492

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

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;

531 dec_size = src_size < dst_size ? src_size : dst_size;

533

534 if (dst_size < src_size)

535 {

537

538

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 }

560 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';

561 }

562

563 pval += size;

564 }

565 break;

566

570 {

571 char *str = (char *) (var + offset * act_tuple);

572

573

574

575

576

577

578 if (varcharsize == 0 && offset == sizeof(char *))

579 str = *(char **) str;

580

581 if (varcharsize > size)

582 {

583

584

585

586

588 {

589 memset(str, ' ', varcharsize);

590 memcpy(str, pval, size);

591 str[varcharsize - 1] = '\0';

592

593

594

595

596

597 if (size == 0)

598 {

599

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

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

645

646

647 if (varcharsize == 0)

648 charsize = size + 1;

649

650 strncpy(str, pval, charsize);

651

652

654 {

656 str[charsize - 1] = '\0';

657 }

658

659 if (charsize < size || (ORACLE_MODE(compat) && (charsize - 1) < size))

660 {

661

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 }

683 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';

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

702 if (variable->len > varcharsize)

703 {

704

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 }

726 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';

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

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

753

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

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

812

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

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

866

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

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

914

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

954 ++act_tuple;

955

956

957

958

959

960

961

962 for (; *pval != '\0' && (string || (array\_delimiter(isarray, *pval) && array\_boundary(isarray, *pval))); ++pval)

963 if (*pval == '"')

964 string = string ? false : true;

965

967 ++pval;

968 }

969 }

970 } while (*pval != '\0' && array\_boundary(isarray, *pval));

971

972 return true;

973}

unsigned ecpg_hex_enc_len(unsigned srclen)

static char get_hex(char c)

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

unsigned ecpg_hex_dec_len(unsigned srclen)

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)

static double get_float8_nan(void)

static unsigned hex_decode(const char *src, unsigned len, char *dst)

unsigned ecpg_hex_encode(const char *src, unsigned len, char *dst)

static bool array_delimiter(enum ARRAY_TYPE isarray, char c)

static double get_float8_infinity(void)

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

static const int8 hexlookup[128]

int PQgetlength(const PGresult *res, int tup_num, int field_num)

char * PQgetvalue(const PGresult *res, int tup_num, int field_num)

int PQfformat(const PGresult *res, int field_num)

int PQgetisnull(const PGresult *res, int tup_num, int field_num)

struct sqlca_t * ECPGget_sqlca(void)

void ECPGset_noind_null(enum ECPGttype type, void *ptr)

static const char hextbl[]

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)

int pg_strncasecmp(const char *s1, const char *s2, size_t n)