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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16#define POSTGRES_ECPG_INTERNAL

18

19#include <math.h>

20

21#include "catalog/pg_type_d.h"

34

35

36

37

38

39static char *

41{

42 char *res;

43 size_t length;

44 size_t escaped_len;

45 size_t buffer_len;

46

47

48

49

50

51 if (!quote)

52 return arg;

53 else

54 {

55 length = strlen(arg);

56 buffer_len = 2 * length + 1;

57 res = (char *) ecpg_alloc(buffer_len + 3, lineno);

58 if (!res)

59 return res;

61 if (length == escaped_len)

62 {

63 res[0] = res[escaped_len + 1] = '\'';

64 res[escaped_len + 2] = '\0';

65 }

66 else

67 {

68

69

70

71

72 memmove(res + 2, res + 1, escaped_len);

74 res[1] = res[escaped_len + 2] = '\'';

75 res[escaped_len + 3] = '\0';

76 }

78 return res;

79 }

80}

81

82static void

84{

86

87 while (var)

88 {

89 var_next = var->next;

91 var = var_next;

92 }

93}

94

95static void

97{

98 if (stmt == NULL)

99 return;

104#ifndef HAVE_USELOCALE

106#endif

108}

109

110static int

112{

113 bool string = false;

114 int p = pos;

115

116 for (; text[p] != '\0'; p++)

117 {

118 if (string && !std_strings && text[p] == '\\')

119 p++;

120 else if (text[p] == '\'')

121 string = string ? false : true;

122 else if (!string)

123 {

124 if (text[p] == '$' && isdigit((unsigned char) text[p + 1]))

125 {

126

127 int i;

128

129 for (i = p + 1; isdigit((unsigned char) text[i]); i++)

130 ;

131 if (!isalpha((unsigned char) text[i]) &&

132 isascii((unsigned char) text[i]) && text[i] != '_')

133

134 return p;

135 }

137 {

138

139 return p;

140 }

141 }

142 }

143

144 return -1;

145}

146

147static bool

149{

152

153 if (new_entry == NULL)

154 return false;

155

156 new_entry->oid = oid;

158 new_entry->next = *cache;

159 *cache = new_entry;

160 return true;

161}

162

165{

166 char *array_query;

170

171 if ((stmt->connection->cache_head) == NULL)

172 {

173

174

175

176

177#define not_an_array_in_ecpg ECPG_ARRAY_NONE

178

179

258 }

259

260 for (cache_entry = (stmt->connection->cache_head); cache_entry != NULL; cache_entry = cache_entry->next)

261 {

262 if (cache_entry->oid == type)

263 return cache_entry->isarray;

264 }

265

266 array_query = (char *) ecpg_alloc(strlen("select typlen from pg_type where oid= and typelem<>0") + 11, stmt->lineno);

267 if (array_query == NULL)

269

270 sprintf(array_query, "select typlen from pg_type where oid=%d and typelem<>0", type);

271 query = PQexec(stmt->connection->connection, array_query);

276 {

279 else

280 {

284 {

285

286

287

289 }

290 }

292 }

293 else

295

299}

300

301

302bool

305{

307 int act_tuple,

309 bool status = true;

310

312 {

314 return false;

315 }

316

318 {

319

320

321

323 {

324 ecpg_log("ecpg_store_result on line %d: incorrect number of matches; %d don't fit into array of %ld\n",

327 return false;

328 }

329 }

330 else

331 {

332

333

334

336 {

338 return false;

339 }

340 }

341

342

343

344

346 {

347 int len = 0;

348

349 if (PQfformat(results, act_field))

350 {

351 switch (var->type)

352 {

357 {

358

359 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)

360 len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;

361 len *= var->offset;

362 len += (ntuples + 1) * sizeof(char *);

363 }

364 else

365 {

367

368 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)

369 {

370 int slen = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;

371

374 }

377 }

378 break;

381 break;

382 default:

384 break;

385 }

386 }

387 else

388 {

389 for (act_tuple = 0; act_tuple < ntuples; act_tuple++)

391 }

392

393 ecpg_log("ecpg_store_result on line %d: allocating memory for %d tuples\n", stmt->lineno, ntuples);

396 return false;

398 }

399

400

402 {

404

407 return false;

409 }

410

411

414 {

415

416

417

418 char **current_string = (char **) var->value;

419

420

421 char *current_data_location = (char *) &current_string[ntuples + 1];

422

423 for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)

424 {

425 int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;

426

428 var->type, var->ind_type, current_data_location,

430 status = false;

431 else

432 {

433 *current_string = current_data_location;

434 current_data_location += len;

435 current_string++;

436 }

437 }

438

439

440 *current_string = NULL;

441 }

442 else

443 {

444 for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)

445 {

449 status = false;

450 }

451 }

452 return status;

453}

454

455static void

457{

458 if (isnan(value))

459 sprintf(ptr, "%s%s", "NaN", delim);

460 else if (isinf(value))

461 {

463 sprintf(ptr, "%s%s", "-Infinity", delim);

464 else

465 sprintf(ptr, "%s%s", "Infinity", delim);

466 }

467 else

469}

470

471static void

473{

474 if (isnan(value))

475 sprintf(ptr, "%s%s", "NaN", delim);

476 else if (isinf(value))

477 {

479 sprintf(ptr, "%s%s", "-Infinity", delim);

480 else

481 sprintf(ptr, "%s%s", "Infinity", delim);

482 }

483 else

485}

486

487static char *

489{

490 char *to_data;

491 int to_len = ecpg_hex_enc_len(from_len) + 4 + 1;

492

493

494 to_data = ecpg_alloc(to_len, lineno);

495 if (!to_data)

496 return NULL;

497

498 strcpy(to_data, "'\\x");

501

502 return to_data;

503}

504

505bool

507 char **tobeinserted_p, bool quote)

508{

509 char *mallocedval = NULL;

510 char *newcopy = NULL;

511

512

513

514

515

516

517

518

519

520

521

522

523 *tobeinserted_p = "";

524

525

527 {

530 if (*(short *) var->ind_value < 0)

531 *tobeinserted_p = NULL;

532 break;

536 *tobeinserted_p = NULL;

537 break;

540 if (*(long *) var->ind_value < 0L)

541 *tobeinserted_p = NULL;

542 break;

545 if (*(long long int *) var->ind_value < (long long) 0)

546 *tobeinserted_p = NULL;

547 break;

550 {

552 *tobeinserted_p = NULL;

553 }

554 break;

555 default:

556 break;

557 }

558 if (*tobeinserted_p != NULL)

559 {

561

562 switch (var->type)

563 {

565

567 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))

568 return false;

569

570 if (asize > 1)

571 {

572 strcpy(mallocedval, "{");

573

575 sprintf(mallocedval + strlen(mallocedval), "%hd,", ((short *) var->value)[element]);

576

577 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

578 }

579 else

580 sprintf(mallocedval, "%hd", *((short *) var->value));

581

582 *tobeinserted_p = mallocedval;

583 break;

584

586 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))

587 return false;

588

589 if (asize > 1)

590 {

591 strcpy(mallocedval, "{");

592

594 sprintf(mallocedval + strlen(mallocedval), "%d,", ((int *) var->value)[element]);

595

596 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

597 }

598 else

599 sprintf(mallocedval, "%d", *((int *) var->value));

600

601 *tobeinserted_p = mallocedval;

602 break;

603

605 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))

606 return false;

607

608 if (asize > 1)

609 {

610 strcpy(mallocedval, "{");

611

613 sprintf(mallocedval + strlen(mallocedval), "%hu,", ((unsigned short *) var->value)[element]);

614

615 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

616 }

617 else

618 sprintf(mallocedval, "%hu", *((unsigned short *) var->value));

619

620 *tobeinserted_p = mallocedval;

621 break;

622

624 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))

625 return false;

626

627 if (asize > 1)

628 {

629 strcpy(mallocedval, "{");

630

632 sprintf(mallocedval + strlen(mallocedval), "%u,", ((unsigned int *) var->value)[element]);

633

634 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

635 }

636 else

637 sprintf(mallocedval, "%u", *((unsigned int *) var->value));

638

639 *tobeinserted_p = mallocedval;

640 break;

641

643 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))

644 return false;

645

646 if (asize > 1)

647 {

648 strcpy(mallocedval, "{");

649

651 sprintf(mallocedval + strlen(mallocedval), "%ld,", ((long *) var->value)[element]);

652

653 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

654 }

655 else

656 sprintf(mallocedval, "%ld", *((long *) var->value));

657

658 *tobeinserted_p = mallocedval;

659 break;

660

662 if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))

663 return false;

664

665 if (asize > 1)

666 {

667 strcpy(mallocedval, "{");

668

670 sprintf(mallocedval + strlen(mallocedval), "%lu,", ((unsigned long *) var->value)[element]);

671

672 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

673 }

674 else

675 sprintf(mallocedval, "%lu", *((unsigned long *) var->value));

676

677 *tobeinserted_p = mallocedval;

678 break;

679

681 if (!(mallocedval = ecpg_alloc(asize * 30, lineno)))

682 return false;

683

684 if (asize > 1)

685 {

686 strcpy(mallocedval, "{");

687

689 sprintf(mallocedval + strlen(mallocedval), "%lld,", ((long long int *) var->value)[element]);

690

691 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

692 }

693 else

694 sprintf(mallocedval, "%lld", *((long long int *) var->value));

695

696 *tobeinserted_p = mallocedval;

697 break;

698

700 if (!(mallocedval = ecpg_alloc(asize * 30, lineno)))

701 return false;

702

703 if (asize > 1)

704 {

705 strcpy(mallocedval, "{");

706

708 sprintf(mallocedval + strlen(mallocedval), "%llu,", ((unsigned long long int *) var->value)[element]);

709

710 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

711 }

712 else

713 sprintf(mallocedval, "%llu", *((unsigned long long int *) var->value));

714

715 *tobeinserted_p = mallocedval;

716 break;

717

719 if (!(mallocedval = ecpg_alloc(asize * 25, lineno)))

720 return false;

721

722 if (asize > 1)

723 {

724 strcpy(mallocedval, "{");

725

728

729 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

730 }

731 else

733

734 *tobeinserted_p = mallocedval;

735 break;

736

738 if (!(mallocedval = ecpg_alloc(asize * 25, lineno)))

739 return false;

740

741 if (asize > 1)

742 {

743 strcpy(mallocedval, "{");

744

747

748 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

749 }

750 else

752

753 *tobeinserted_p = mallocedval;

754 break;

755

757 if (!(mallocedval = ecpg_alloc(var->arrsize + sizeof("{}"), lineno)))

758 return false;

759

761 {

762 strcpy(mallocedval, "{");

763

765 sprintf(mallocedval + strlen(mallocedval), "%c,", (((bool *) var->value)[element]) ? 't' : 'f');

766

767 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

768 }

769 else

770 {

771 if (var->offset == sizeof(char))

772 sprintf(mallocedval, "%c", (*((char *) var->value)) ? 't' : 'f');

773 else if (var->offset == sizeof(int))

774 sprintf(mallocedval, "%c", (*((int *) var->value)) ? 't' : 'f');

775 else

777 }

778

779 *tobeinserted_p = mallocedval;

780 break;

781

785 {

786

788

789 if (!(newcopy = ecpg_alloc(slen + 1, lineno)))

790 return false;

791

792 strncpy(newcopy, (char *) var->value, slen);

793 newcopy[slen] = '\0';

794

795 mallocedval = quote_postgres(newcopy, quote, lineno);

796 if (!mallocedval)

797 {

799 return false;

800 }

801

802 *tobeinserted_p = mallocedval;

803 }

804 break;

807 {

808 int slen = strlen((char *) var->value);

809

810 if (!(mallocedval = ecpg_alloc(slen + 1, lineno)))

811 return false;

812

813 strncpy(mallocedval, (char *) var->value, slen);

814 mallocedval[slen] = '\0';

815

816 *tobeinserted_p = mallocedval;

817 }

818 break;

819

821 {

824

826 return false;

827

829 *tobeinserted_p = mallocedval;

830 }

831 break;

832

834 {

837

839 return false;

840

842 newcopy[variable->len] = '\0';

843

844 mallocedval = quote_postgres(newcopy, quote, lineno);

845 if (!mallocedval)

846 {

848 return false;

849 }

850

851 *tobeinserted_p = mallocedval;

852 }

853 break;

854

857 {

858 char *str = NULL;

859 int slen;

861

864 else

866

867 if (!mallocedval)

868 return false;

869

871 {

872 int result;

873

875 if (!nval)

876 {

878 return false;

879 }

880

883 else

885

886 if (result != 0)

887 {

890 return false;

891 }

892

894 slen = strlen(str);

896

897 if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))

898 {

901 return false;

902 }

903 mallocedval = newcopy;

904

905

906 memcpy(mallocedval + strlen(mallocedval), str, slen + 1);

908 strcpy(mallocedval + strlen(mallocedval), ",");

909

911 }

912

914 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

915

916 *tobeinserted_p = mallocedval;

917 }

918 break;

919

921 {

922 char *str = NULL;

923 int slen;

924

927 else

929

930 if (!mallocedval)

931 return false;

932

934 {

936 if (str)

937 {

939 return false;

940 }

941

942 slen = strlen(str);

943

944 if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))

945 {

948 return false;

949 }

950 mallocedval = newcopy;

951

952

953 memcpy(mallocedval + strlen(mallocedval), str, slen + 1);

955 strcpy(mallocedval + strlen(mallocedval), ",");

956

958 }

959

961 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

962

963 *tobeinserted_p = mallocedval;

964 }

965 break;

966

968 {

969 char *str = NULL;

970 int slen;

971

974 else

976

977 if (!mallocedval)

978 return false;

979

981 {

983 if (str)

984 {

986 return false;

987 }

988

989 slen = strlen(str);

990

991 if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))

992 {

995 return false;

996 }

997 mallocedval = newcopy;

998

999

1000 memcpy(mallocedval + strlen(mallocedval), str, slen + 1);

1002 strcpy(mallocedval + strlen(mallocedval), ",");

1003

1005 }

1006

1008 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

1009

1010 *tobeinserted_p = mallocedval;

1011 }

1012 break;

1013

1015 {

1016 char *str = NULL;

1017 int slen;

1018

1021 else

1023

1024 if (!mallocedval)

1025 return false;

1026

1028 {

1030 if (str)

1031 {

1033 return false;

1034 }

1035

1036 slen = strlen(str);

1037

1038 if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))

1039 {

1042 return false;

1043 }

1044 mallocedval = newcopy;

1045

1046

1047 memcpy(mallocedval + strlen(mallocedval), str, slen + 1);

1049 strcpy(mallocedval + strlen(mallocedval), ",");

1050

1052 }

1053

1055 strcpy(mallocedval + strlen(mallocedval) - 1, "}");

1056

1057 *tobeinserted_p = mallocedval;

1058 }

1059 break;

1060

1063 break;

1064

1065 default:

1066

1068 return false;

1069 break;

1070 }

1071 }

1072 return true;

1073}

1074

1075static void

1077{

1078 char *value_s;

1079 bool malloced = false;

1080

1081 if (value == NULL)

1082 value_s = "null";

1083 else if (!is_binary)

1084 value_s = value;

1085 else

1086 {

1088 if (value_s != NULL)

1089 {

1092 malloced = true;

1093 }

1094 else

1095 value_s = "no memory for logging of parameter";

1096 }

1097

1098 ecpg_log("ecpg_free_params on line %d: parameter %d = %s\n",

1099 lineno, nth, value_s);

1100

1101 if (malloced)

1103}

1104

1105void

1107{

1108 int n;

1109

1110 for (n = 0; n < stmt->nparams; n++)

1111 {

1114 stmt->paramformats[n], stmt->lineno, n + 1);

1116 }

1120 stmt->paramvalues = NULL;

1121 stmt->paramlengths = NULL;

1122 stmt->paramformats = NULL;

1123 stmt->nparams = 0;

1124}

1125

1126static bool

1128{

1129 char *newcopy;

1130

1131 if (!(newcopy = (char *) ecpg_alloc(strlen(stmt->command)

1132 + strlen(tobeinserted)

1133 + 1, stmt->lineno)))

1134 {

1136 return false;

1137 }

1138

1139 strcpy(newcopy, stmt->command);

1140 strcpy(newcopy + position - 1, tobeinserted);

1141

1142

1143

1144

1145

1146 strcat(newcopy,

1147 stmt->command

1148 + position

1149 + ph_len - 1);

1150

1152 stmt->command = newcopy;

1153

1155 return true;

1156}

1157

1158static bool

1160 char **tobeinserted)

1161{

1163

1164

1165

1166

1167

1168

1170 {

1172 return false;

1173 memcpy(*tobeinserted, desc_item->data, desc_item->data_len);

1174 return true;

1175 }

1176

1183

1185 {

1189 }

1190 else

1191 {

1197 }

1198

1200 return false;

1201

1202 return true;

1203}

1204

1205

1206

1207

1208

1209

1210

1211

1212bool

1214{

1216 int desc_counter = 0;

1217 int position = 0;

1218 const char *value;

1219 bool std_strings = false;

1220

1221

1223 if (value && strcmp(value, "on") == 0)

1224 std_strings = true;

1225

1226

1227

1228

1229

1230

1231 var = stmt->inlist;

1232 while (var)

1233 {

1234 char *tobeinserted;

1235 int counter = 1;

1236 bool binary_format;

1237 int binary_length;

1238

1239

1240 tobeinserted = NULL;

1241 binary_length = 0;

1242 binary_format = false;

1243

1244

1245

1246

1247

1249 {

1250

1251

1252

1253

1256

1258 if (desc == NULL)

1259 return false;

1260

1261 desc_counter++;

1262 for (desc_item = desc->items; desc_item; desc_item = desc_item->next)

1263 {

1264 if (desc_item->num != desc_counter)

1265 continue;

1266

1268 return false;

1269

1271 {

1272 binary_length = desc_item->data_len;

1273 binary_format = true;

1274 }

1275 break;

1276 }

1277 if (desc->count == desc_counter)

1278 desc_counter = 0;

1279 }

1281 {

1283 {

1285 struct variable desc_inlist;

1286 int i;

1287

1288 if (sqlda == NULL)

1289 return false;

1290

1291 desc_counter++;

1292 for (i = 0; i < sqlda->sqld; i++)

1293 {

1294 if (i + 1 == desc_counter)

1295 {

1299 switch (desc_inlist.type)

1300 {

1303 desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);

1304 break;

1305 default:

1306 desc_inlist.varcharsize = 0;

1307 break;

1308 }

1309 desc_inlist.arrsize = 1;

1310 desc_inlist.offset = 0;

1312 {

1314

1317 desc_inlist.ind_value = sqlda->sqlvar[i].sqlind;

1318 desc_inlist.ind_pointer = &(sqlda->sqlvar[i].sqlind);

1319 desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;

1320 desc_inlist.ind_offset = 0;

1321 }

1322 else

1323 {

1325 desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;

1326 desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;

1327 }

1328 if (ecpg\_store\_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))

1329 return false;

1330

1331 break;

1332 }

1333 }

1334 if (sqlda->sqld == desc_counter)

1335 desc_counter = 0;

1336 }

1337 else

1338 {

1340 struct variable desc_inlist;

1341 int i;

1342

1343 if (sqlda == NULL)

1344 return false;

1345

1346 desc_counter++;

1347 for (i = 0; i < sqlda->sqln; i++)

1348 {

1349 if (i + 1 == desc_counter)

1350 {

1354 switch (desc_inlist.type)

1355 {

1358 desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);

1359 break;

1360 default:

1361 desc_inlist.varcharsize = 0;

1362 break;

1363 }

1364 desc_inlist.arrsize = 1;

1365 desc_inlist.offset = 0;

1367 {

1369

1372 desc_inlist.ind_value = sqlda->sqlvar[i].sqlind;

1373 desc_inlist.ind_pointer = &(sqlda->sqlvar[i].sqlind);

1374 desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;

1375 desc_inlist.ind_offset = 0;

1376 }

1377 else

1378 {

1380 desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;

1381 desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;

1382 }

1383 if (ecpg\_store\_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))

1384 return false;

1385

1386 break;

1387 }

1388 }

1389 if (sqlda->sqln == desc_counter)

1390 desc_counter = 0;

1391 }

1392 }

1393 else

1394 {

1396 return false;

1397

1399 {

1401 binary_format = true;

1402 }

1403 }

1404

1405

1406

1407

1408

1409 if ((position = next_insert(stmt->command, position, stmt->questionmarks, std_strings) + 1) == 0)

1410 {

1411

1412

1413

1414

1417 NULL);

1420 return false;

1421 }

1422

1423

1424

1425

1426

1427

1429 {

1430 int ph_len = (stmt->command[position] == '?') ? strlen("?") : strlen("$1");

1431

1433 {

1435 return false;

1436 }

1437 tobeinserted = NULL;

1438 }

1439

1440

1441

1442

1443

1444

1445 else if (stmt->command[position] == '0')

1446 {

1449 {

1450

1451 char *str = ecpg_alloc(strlen(tobeinserted) + 2 + 1,

1452 stmt->lineno);

1453

1454 if (str)

1455 {

1458 return false;

1459 }

1460 sprintf(str, "\"%s\"", tobeinserted);

1462 tobeinserted = str;

1463 }

1464

1466 {

1468 return false;

1469 }

1470 tobeinserted = NULL;

1471 }

1473 {

1474 if (binary_format)

1475 {

1477 binary_length,

1478 stmt->lineno);

1479

1481 if (!p)

1482 {

1484 return false;

1485 }

1486 tobeinserted = p;

1487 }

1488

1490 {

1492 return false;

1493 }

1494 tobeinserted = NULL;

1495 }

1496 else

1497 {

1498 bool realloc_failed = false;

1499 char **newparamvalues;

1500 int *newparamlengths;

1501 int *newparamformats;

1502

1503

1504 if ((newparamvalues = (char **) ecpg_realloc(stmt->paramvalues, sizeof(char *) * (stmt->nparams + 1), stmt->lineno)))

1505 stmt->paramvalues = newparamvalues;

1506 else

1507 realloc_failed = true;

1508

1509 if ((newparamlengths = (int *) ecpg_realloc(stmt->paramlengths, sizeof(int) * (stmt->nparams + 1), stmt->lineno)))

1510 stmt->paramlengths = newparamlengths;

1511 else

1512 realloc_failed = true;

1513

1514 if ((newparamformats = (int *) ecpg_realloc(stmt->paramformats, sizeof(int) * (stmt->nparams + 1), stmt->lineno)))

1515 stmt->paramformats = newparamformats;

1516 else

1517 realloc_failed = true;

1518

1519 if (realloc_failed)

1520 {

1523 return false;

1524 }

1525

1526

1527 stmt->paramvalues[stmt->nparams] = tobeinserted;

1528 stmt->paramlengths[stmt->nparams] = binary_length;

1529 stmt->paramformats[stmt->nparams] = (binary_format ? 1 : 0);

1530 stmt->nparams++;

1531

1532

1533 if (stmt->command[position] == '?')

1534 {

1535

1536 int buffersize = sizeof(int) * CHAR_BIT * 10 / 3;

1537

1538

1539 if (!(tobeinserted = (char *) ecpg_alloc(buffersize, stmt->lineno)))

1540 {

1542 return false;

1543 }

1544

1545 snprintf(tobeinserted, buffersize, "$%d", counter++);

1546

1548 {

1550 return false;

1551 }

1552 tobeinserted = NULL;

1553 }

1554 }

1555

1556 if (desc_counter == 0)

1557 var = var->next;

1558 }

1559

1560

1561

1562

1563

1565 next_insert(stmt->command, position, stmt->questionmarks, std_strings) >= 0)

1566 {

1570 return false;

1571 }

1572

1573 return true;

1574}

1575

1576

1577

1578

1579

1580bool

1582{

1584 {

1585 stmt->results = PQexec(stmt->connection->connection, "begin transaction");

1587 {

1589 return false;

1590 }

1592 stmt->results = NULL;

1593 }

1594 return true;

1595}

1596

1597

1598

1599

1600

1601bool

1603{

1604 ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name);

1606 {

1609 stmt->nparams,

1610 (const char *const *) stmt->paramvalues,

1611 (const int *) stmt->paramlengths,

1612 (const int *) stmt->paramformats,

1613 0);

1614 ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command);

1615 }

1616 else

1617 {

1618 if (stmt->nparams == 0)

1619 {

1620 stmt->results = PQexec(stmt->connection->connection, stmt->command);

1621 ecpg_log("ecpg_execute on line %d: using PQexec\n", stmt->lineno);

1622 }

1623 else

1624 {

1626 stmt->command, stmt->nparams, NULL,

1627 (const char *const *) stmt->paramvalues,

1628 (const int *) stmt->paramlengths,

1629 (const int *) stmt->paramformats,

1630 0);

1631

1632 ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);

1633 }

1634

1636 {

1638 {

1640 return false;

1641 }

1642 }

1643 }

1644

1646

1648 return false;

1649

1650 return true;

1651}

1652

1653

1654

1655

1656

1657

1658

1659

1660

1661

1662

1663

1664

1665

1666

1667

1668

1669

1670bool

1672{

1674 bool status = false;

1675 char *cmdstat;

1678 int nfields,

1679 ntuples,

1680 act_field;

1681

1682 if (sqlca == NULL)

1683 {

1686 return false;

1687 }

1688

1689 var = stmt->outlist;

1691 {

1695

1696 ecpg_log("ecpg_process_output on line %d: correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);

1697 status = true;

1698

1699 if (ntuples < 1)

1700 {

1701 if (ntuples)

1702 ecpg_log("ecpg_process_output on line %d: incorrect number of matches (%d)\n",

1703 stmt->lineno, ntuples);

1705 status = false;

1706 break;

1707 }

1708

1710 {

1712

1713 if (desc == NULL)

1714 status = false;

1715 else

1716 {

1719 clear_result = false;

1720 ecpg_log("ecpg_process_output on line %d: putting result (%d tuples) into descriptor %s\n",

1722 }

1723 var = var->next;

1724 }

1726 {

1728 {

1732 int i;

1733

1734

1735

1736

1737

1739 {

1740 sqlda_new = sqlda->desc_next;

1741 free(sqlda);

1742 sqlda = sqlda_new;

1743 }

1744 *_sqlda = sqlda = sqlda_new = NULL;

1745 for (i = ntuples - 1; i >= 0; i--)

1746 {

1747

1748

1749

1750

1752

1753 if (!sqlda_new)

1754 {

1755

1756 while (sqlda)

1757 {

1758 sqlda_new = sqlda->desc_next;

1759 free(sqlda);

1760 sqlda = sqlda_new;

1761 }

1762 *_sqlda = NULL;

1763

1764 ecpg_log("ecpg_process_output on line %d: out of memory allocating a new sqlda\n", stmt->lineno);

1765 status = false;

1766 break;

1767 }

1768 else

1769 {

1770 ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);

1771

1772 *_sqlda = sqlda_new;

1773

1775 ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",

1777

1778 sqlda_new->desc_next = sqlda;

1779 sqlda = sqlda_new;

1780 }

1781 }

1782 }

1783 else

1784 {

1788 int i;

1789

1790

1791

1792

1793

1795 {

1796 sqlda_new = sqlda->desc_next;

1797 free(sqlda);

1798 sqlda = sqlda_new;

1799 }

1800 *_sqlda = sqlda = sqlda_new = NULL;

1801 for (i = ntuples - 1; i >= 0; i--)

1802 {

1803

1804

1805

1806

1808

1809 if (!sqlda_new)

1810 {

1811

1812 while (sqlda)

1813 {

1814 sqlda_new = sqlda->desc_next;

1815 free(sqlda);

1816 sqlda = sqlda_new;

1817 }

1818 *_sqlda = NULL;

1819

1820 ecpg_log("ecpg_process_output on line %d: out of memory allocating a new sqlda\n", stmt->lineno);

1821 status = false;

1822 break;

1823 }

1824 else

1825 {

1826 ecpg_log("ecpg_process_output on line %d: new sqlda was built\n", stmt->lineno);

1827

1828 *_sqlda = sqlda_new;

1829

1831 ecpg_log("ecpg_process_output on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n",

1833

1834 sqlda_new->desc_next = sqlda;

1835 sqlda = sqlda_new;

1836 }

1837 }

1838 }

1839

1840 var = var->next;

1841 }

1842 else

1843 for (act_field = 0; act_field < nfields && status; act_field++)

1844 {

1845 if (var != NULL)

1846 {

1848 var = var->next;

1849 }

1851 {

1853 return false;

1854 }

1855 }

1856

1857 if (status && var != NULL)

1858 {

1860 status = false;

1861 }

1862

1863 break;

1865 status = true;

1869 ecpg_log("ecpg_process_output on line %d: OK: %s\n", stmt->lineno, cmdstat);

1871 sqlca->sqlerrd[2] &&

1872 (strncmp(cmdstat, "UPDATE", 6) == 0

1873 || strncmp(cmdstat, "INSERT", 6) == 0

1874 || strncmp(cmdstat, "DELETE", 6) == 0))

1876 break;

1878 {

1879 char *buffer;

1880 int res;

1881

1882 ecpg_log("ecpg_process_output on line %d: COPY OUT data transfer in progress\n", stmt->lineno);

1884 &buffer, 0)) > 0)

1885 {

1886 printf("%s", buffer);

1888 }

1889 if (res == -1)

1890 {

1891

1895 ecpg_log("ecpg_process_output on line %d: got PGRES_COMMAND_OK after PGRES_COPY_OUT\n", stmt->lineno);

1896 else

1898 }

1899 break;

1900 }

1901 default:

1902

1903

1904

1905

1906

1907 ecpg_log("ecpg_process_output on line %d: unknown execution status type\n",

1908 stmt->lineno);

1910 status = false;

1911 break;

1912 }

1913

1914 if (clear_result)

1915 {

1917 stmt->results = NULL;

1918 }

1919

1920

1922 while ((notify = PQnotifies(stmt->connection->connection)) != NULL)

1923 {

1924 ecpg_log("ecpg_process_output on line %d: asynchronous notification of \"%s\" from backend PID %d received\n",

1928 }

1929

1930 return status;

1931}

1932

1933

1934

1935

1936

1937

1938

1939

1940

1941

1942

1943bool

1945 const char *connection_name, const bool questionmarks,

1948{

1953 char *prepname;

1954 bool is_prepared_name_set;

1955

1956 *stmt_out = NULL;

1957

1958 if (!query)

1959 {

1961 return false;

1962 }

1963

1965

1967

1968 if (ecpg\_init(con, connection_name, lineno))

1969 return false;

1970

1972

1973 if (stmt == NULL)

1974 return false;

1975

1976

1977

1978

1979

1980

1981

1982#ifdef HAVE_USELOCALE

1983

1984

1985

1986

1987

1988 Assert(ecpg_clocale);

1989 stmt->oldlocale = uselocale(ecpg_clocale);

1991 {

1993 return false;

1994 }

1995#else

1996#ifdef WIN32

1997 stmt->oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);

1998 if (stmt->oldthreadlocale == -1)

1999 {

2001 return false;

2002 }

2003#endif

2005 if (stmt->oldlocale == NULL)

2006 {

2008 return false;

2009 }

2011#endif

2012

2013

2014

2015

2016

2018 {

2020 {

2022 return false;

2023 }

2024

2025

2026

2027

2028

2029 stmt->command = prepname;

2031 }

2032 else

2034

2035 stmt->name = NULL;

2036

2038 {

2039

2041

2043 {

2046 }

2047 else

2048 {

2051 return false;

2052 }

2053 }

2054

2055

2056 stmt->connection = con;

2062

2063

2064

2065

2066

2067

2068

2069

2070

2071

2072

2073

2074

2075

2076

2077

2078

2079

2080

2081

2082

2083

2084

2085 is_prepared_name_set = false;

2086

2088

2090

2092 {

2095 else

2096 {

2098 *ptr;

2099

2101 {

2103 return false;

2104 }

2105

2108

2112

2113

2114

2115

2116

2117

2118

2119 if (var->arrsize == 0 ||

2122 else

2124

2125

2126

2127

2128

2129

2134

2135 var->next = NULL;

2136

2142

2146 else

2148

2149

2150

2151

2152

2153

2158

2159

2160 if (var->pointer == NULL)

2161 {

2165 return false;

2166 }

2167

2168 for (ptr = *list; ptr && ptr->next; ptr = ptr->next)

2169 ;

2170

2171 if (ptr == NULL)

2172 *list = var;

2173 else

2174 ptr->next = var;

2175

2176 if (!is_prepared_name_set && stmt->statement_type == ECPGst_prepare)

2177 {

2179 is_prepared_name_set = true;

2180 }

2181 }

2182

2184 }

2185

2186

2187 if (con == NULL || con->connection == NULL)

2188 {

2191 return false;

2192 }

2193

2194 if (!is_prepared_name_set && stmt->statement_type == ECPGst_prepare)

2195 {

2198 return false;

2199 }

2200

2201

2203

2204 *stmt_out = stmt;

2205

2206 return true;

2207}

2208

2209

2210

2211

2212

2213void

2215{

2216 if (stmt == NULL)

2217 return;

2218

2219#ifdef HAVE_USELOCALE

2221 uselocale(stmt->oldlocale);

2222#else

2223 if (stmt->oldlocale)

2224 {

2226#ifdef WIN32

2227 _configthreadlocale(stmt->oldthreadlocale);

2228#endif

2229 }

2230#endif

2231

2233}

2234

2235

2236

2237

2238

2239

2240bool

2242{

2244

2248 goto fail;

2249

2251 goto fail;

2252

2254 goto fail;

2255

2257 goto fail;

2258

2260 goto fail;

2261

2263 return true;

2264

2265fail:

2267 return false;

2268}

2269

2270

2271

2272

2273

2274bool

2276{

2277 va_list args;

2278 bool ret;

2279

2280 va_start(args, query);

2283 va_end(args);

2284

2285 return ret;

2286}

2287

2288

2289bool

2291 const char *descriptor, const char *query)

2292{

2296}

void print(const void *obj)

#define ESCAPE_STRING_SYNTAX

void ecpg_pthreads_init(void)

struct connection * ecpg_get_connection(const char *connection_name)

unsigned ecpg_hex_enc_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)

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

#define ECPG_CONVERT_BOOL

#define ECPG_TOO_MANY_ARGUMENTS

#define ECPG_TOO_FEW_ARGUMENTS

#define ECPG_INVALID_STMT

#define ECPG_INFORMIX_SUBSELECT_NOT_ONE

#define ECPG_TOO_MANY_MATCHES

#define ECPG_OUT_OF_MEMORY

struct descriptor * ecpg_find_desc(int line, const char *name)

bool ecpg_check_PQresult(PGresult *results, int lineno, PGconn *connection, enum COMPAT_MODE compat)

#define ECPG_SQLSTATE_NO_DATA

#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY

@ ECPG_COMPAT_INFORMIX_SE

char * ecpg_alloc(long size, int lineno)

#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR

struct sqlda_struct * ecpg_build_native_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)

char * ecpg_auto_alloc(long size, int lineno)

bool ecpg_register_prepared_stmt(struct statement *stmt)

void ecpg_log(const char *format,...) pg_attribute_printf(1

void bool ecpg_auto_prepare(int lineno, const char *connection_name, const int compat, char **name, const char *query)

void ecpg_clear_auto_mem(void)

bool ecpg_init(const struct connection *con, const char *connection_name, const int lineno)

#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS

struct sqlda_compat * ecpg_build_compat_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)

#define ECPG_SQLSTATE_CARDINALITY_VIOLATION

char * ecpg_prepared(const char *name, struct connection *con)

void ecpg_set_compat_sqlda(int lineno, struct sqlda_compat **_sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)

char * ecpg_realloc(void *ptr, long size, int lineno)

#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS

const char * ecpg_type_name(enum ECPGttype typ)

#define ECPG_SQLSTATE_DATATYPE_MISMATCH

void ecpg_set_native_sqlda(int lineno, struct sqlda_struct **_sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)

int ecpg_dynamic_type(Oid type)

void ecpg_raise(int line, int code, const char *sqlstate, const char *str)

char * ecpg_strdup(const char *string, int lineno)

void ecpg_free(void *ptr)

void ecpg_raise_backend(int line, PGresult *result, PGconn *conn, int compat)

#define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME

@ ECPGst_exec_with_exprlist

@ ECPGt_unsigned_long_long

static bool ecpg_type_infocache_push(struct ECPGtype_information_cache **cache, int oid, enum ARRAY_TYPE isarray, int lineno)

bool ecpg_build_params(struct statement *stmt)

bool ecpg_store_result(const PGresult *results, int act_field, const struct statement *stmt, struct variable *var)

static void sprintf_double_value(char *ptr, double value, const char *delim)

static void print_param_value(char *value, int len, int is_binary, int lineno, int nth)

static bool insert_tobeinserted(int position, int ph_len, struct statement *stmt, char *tobeinserted)

bool ecpg_execute(struct statement *stmt)

static char * quote_postgres(char *arg, bool quote, int lineno)

void ecpg_free_params(struct statement *stmt, bool print)

static char * convert_bytea_to_string(char *from_data, int from_len, int lineno)

static enum ARRAY_TYPE ecpg_is_type_an_array(int type, const struct statement *stmt, const struct variable *var)

bool ecpg_store_input(const int lineno, const bool force_indicator, const struct variable *var, char **tobeinserted_p, bool quote)

static bool store_input_from_desc(struct statement *stmt, struct descriptor_item *desc_item, char **tobeinserted)

static void sprintf_float_value(char *ptr, float value, const char *delim)

void ecpg_do_epilogue(struct statement *stmt)

bool ecpg_do(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query, va_list args)

static void free_variable(struct variable *var)

bool ecpg_do_prologue(int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, enum ECPG_statement_type statement_type, const char *query, va_list args, struct statement **stmt_out)

bool ecpg_process_output(struct statement *stmt, bool clear_result)

bool ecpg_autostart_transaction(struct statement *stmt)

bool ECPGdo_descriptor(int line, const char *connection, const char *descriptor, const char *query)

static void free_statement(struct statement *stmt)

#define not_an_array_in_ecpg

static int next_insert(char *text, int pos, bool questionmarks, bool std_strings)

bool ECPGdo(const int lineno, const int compat, const int force_indicator, const char *connection_name, const bool questionmarks, const int st, const char *query,...)

PGTransactionStatusType PQtransactionStatus(const PGconn *conn)

const char * PQparameterStatus(const PGconn *conn, const char *paramName)

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

void PQfreemem(void *ptr)

Oid PQftype(const PGresult *res, int field_num)

PGresult * PQexecParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)

PGresult * PQexecPrepared(PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)

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

PGresult * PQgetResult(PGconn *conn)

ExecStatusType PQresultStatus(const PGresult *res)

void PQclear(PGresult *res)

char * PQcmdTuples(PGresult *res)

int PQfformat(const PGresult *res, int field_num)

int PQntuples(const PGresult *res)

char * PQresultErrorMessage(const PGresult *res)

size_t PQescapeString(char *to, const char *from, size_t length)

int PQconsumeInput(PGconn *conn)

char * PQcmdStatus(PGresult *res)

PGresult * PQexec(PGconn *conn, const char *query)

Oid PQoidValue(const PGresult *res)

int PQnfields(const PGresult *res)

PGnotify * PQnotifies(PGconn *conn)

int PQgetCopyData(PGconn *conn, char **buffer, int async)

Assert(PointerIsAligned(start, uint64))

struct sqlca_t * ECPGget_sqlca(void)

bool ECPGis_noind_null(enum ECPGttype type, const void *ptr)

if(TABLE==NULL||TABLE_index==NULL)

char * PGTYPESdate_to_asc(date dDate)

char * PGTYPESinterval_to_asc(interval *span)

int PGTYPESnumeric_copy(numeric *src, numeric *dst)

int PGTYPESnumeric_from_decimal(decimal *src, numeric *dst)

numeric * PGTYPESnumeric_new(void)

char * PGTYPESnumeric_to_asc(numeric *num, int dscale)

void PGTYPESnumeric_free(numeric *var)

char * PGTYPEStimestamp_to_asc(timestamp tstamp)

static chr element(struct vars *v, const chr *startp, const chr *endp)

struct ECPGtype_information_cache * next

struct descriptor_item * next

struct descriptor_item * items

struct sqlvar_compat * sqlvar

struct sqlvar_struct sqlvar[1]

enum ECPG_statement_type statement_type