PostgreSQL Source Code: src/backend/utils/adt/arrayfuncs.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

17#include <ctype.h>

18#include <math.h>

19

34#include "utils/fmgroids.h"

39

40

41

42

43

45

46

47

48

49#define ASSGN "="

50

51#define AARR_FREE_IF_COPY(array,n) \

52 do { \

53 if (!VARATT_IS_EXPANDED_HEADER(array)) \

54 PG_FREE_IF_COPY(array, n); \

55 } while (0)

56

57

58typedef enum

59{

67

68

70{

71

74 int nitems;

76 bool typbyval;

77 char typalign;

78

79

80 int slice_ndim;

81 int slice_len;

85 bool *slice_nulls;

86

87

88 char *data_ptr;

89 int current_item;

91

93 int *dim, int *lBound,

94 const char *origStr, Node *escontext);

96 const char *origStr, Node *escontext);

99 char typdelim,

100 int typlen, bool typbyval, char typalign,

101 int *ndim_p, int *dim,

102 int *nitems_p,

103 Datum **values_p, bool **nulls_p,

104 const char *origStr, Node *escontext);

106 const char *origStr, Node *escontext);

109 int typlen, bool typbyval, char typalign,

111 bool *hasnulls, int32 *nbytes);

113 int nSubscripts, int *indx,

114 int arraytyplen,

115 int elmlen, bool elmbyval, char elmalign,

116 bool *isNull);

118 int nSubscripts, int *indx,

119 Datum dataValue, bool isNull,

120 int arraytyplen,

121 int elmlen, bool elmbyval, char elmalign);

126 int typlen, bool typbyval, char typalign,

129 int typlen, bool typbyval, char typalign);

131 int nitems, int typlen, bool typbyval, char typalign);

133 char *srcptr, int offset, bits8 *nullbitmap,

134 int typlen, bool typbyval, char typalign);

136 int ndim, int *dim, int *lb,

137 int *st, int *endp,

138 int typlen, bool typbyval, char typalign);

140 int ndim, int *dim, int *lb,

141 char *arraydataptr, bits8 *arraynullsptr,

142 int *st, int *endp,

143 int typlen, bool typbyval, char typalign);

146 int ndim, int *dim, int *lb,

147 int *st, int *endp,

148 int typlen, bool typbyval, char typalign);

151 Oid elmtype, int dataoffset);

156 Datum search, bool search_isnull,

157 Datum replace, bool replace_isnull,

158 bool remove, Oid collation,

163 Oid collation,

167 Oid collation,

169

170

171

172

173

174

175

176

177

178

181{

184

186 Node *escontext = fcinfo->context;

187 int typlen;

188 bool typbyval;

190 char typdelim;

191 Oid typioparam;

192 char *p;

195 bool *nulls;

196 bool hasnulls;

198 int32 dataoffset;

200 int ndim,

204

205

206

207

208

209

210 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

211 if (my_extra == NULL)

212 {

213 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,

215 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

217 }

218

220 {

221

222

223

229 fcinfo->flinfo->fn_mcxt);

231 }

232 typlen = my_extra->typlen;

233 typbyval = my_extra->typbyval;

235 typdelim = my_extra->typdelim;

237

238

239

240

241

242

244 {

245 dim[i] = -1;

246 lBound[i] = 1;

247 }

248

249

250

251

252

253

254

257 return (Datum) 0;

258

259 if (ndim == 0)

260 {

261

262 if (*p != '{')

264 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

265 errmsg("malformed array literal: \"%s\"", string),

266 errdetail("Array value must start with \"{\" or dimension information.")));

267 }

268 else

269 {

270

271 if (strncmp(p, ASSGN, strlen(ASSGN)) != 0)

273 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

274 errmsg("malformed array literal: \"%s\"", string),

275 errdetail("Missing \"%s\" after array dimensions.",

277 p += strlen(ASSGN);

278

280 p++;

281

282 if (*p != '{')

284 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

285 errmsg("malformed array literal: \"%s\"", string),

286 errdetail("Array contents must start with \"{\".")));

287 }

288

289

291 &my_extra->proc, typioparam, typmod,

292 typdelim,

294 &ndim,

295 dim,

298 string,

299 escontext))

300 return (Datum) 0;

301

302

303 while (*p)

304 {

307 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

308 errmsg("malformed array literal: \"%s\"", string),

309 errdetail("Junk after closing right brace.")));

310 }

311

312

315

316

317

318

319 hasnulls = false;

320 nbytes = 0;

322 {

323 if (nulls[i])

324 hasnulls = true;

325 else

326 {

327

328 if (typlen == -1)

332

335 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

336 errmsg("array size exceeds the maximum allowed (%zu)",

338 }

339 }

340 if (hasnulls)

341 {

343 nbytes += dataoffset;

344 }

345 else

346 {

347 dataoffset = 0;

349 }

350

351

352

353

356 retval->ndim = ndim;

358

359

360

361

362

363

364 retval->elemtype = element_type;

365 memcpy(ARR_DIMS(retval), dim, ndim * sizeof(int));

366 memcpy(ARR_LBOUND(retval), lBound, ndim * sizeof(int));

367

371 true);

372

375

377}

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402static bool

404 const char *origStr, Node *escontext)

405{

406 char *p = *srcptr;

407 int ndim;

408

409

410

411

412

413 ndim = 0;

414 for (;;)

415 {

416 char *q;

417 int ub;

418 int i;

419

420

421

422

423

425 p++;

426 if (*p != '[')

427 break;

428 p++;

430 ereturn(escontext, false,

431 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

432 errmsg("number of array dimensions exceeds the maximum allowed (%d)",

434

435 q = p;

437 return false;

438 if (p == q)

439 ereturn(escontext, false,

440 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

441 errmsg("malformed array literal: \"%s\"", origStr),

442 errdetail("\"[\" must introduce explicitly-specified array dimensions.")));

443

444 if (*p == ':')

445 {

446

447 lBound[ndim] = i;

448 p++;

449 q = p;

451 return false;

452 if (p == q)

453 ereturn(escontext, false,

454 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

455 errmsg("malformed array literal: \"%s\"", origStr),

456 errdetail("Missing array dimension value.")));

457 }

458 else

459 {

460

461 lBound[ndim] = 1;

462 ub = i;

463 }

464 if (*p != ']')

465 ereturn(escontext, false,

466 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

467 errmsg("malformed array literal: \"%s\"", origStr),

468 errdetail("Missing \"%s\" after array dimensions.",

469 "]")));

470 p++;

471

472

473

474

475

476

477

478

479 if (ub < lBound[ndim])

480 ereturn(escontext, false,

481 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

482 errmsg("upper bound cannot be less than lower bound")));

483

484

485 if (ub == INT_MAX)

486 ereturn(escontext, false,

487 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

488 errmsg("array upper bound is too large: %d", ub)));

489

490

493 ereturn(escontext, false,

494 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

495 errmsg("array size exceeds the maximum allowed (%zu)",

497

498 dim[ndim] = ub;

499 ndim++;

500 }

501

502 *srcptr = p;

503 *ndim_p = ndim;

504 return true;

505}

506

507

508

509

510

511

512

513

514

515

516

517

518

519static bool

521 const char *origStr, Node *escontext)

522{

523 char *p = *srcptr;

524 long l;

525

526

527 if (!isdigit((unsigned char) *p) && *p != '-' && *p != '+')

528 {

529 *result = 0;

530 return true;

531 }

532

533 errno = 0;

534 l = strtol(p, srcptr, 10);

535

537 ereturn(escontext, false,

538 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

539 errmsg("array bound is out of integer range")));

540

541 *result = (int) l;

542 return true;

543}

544

545

546

547

548

549

550

551

552

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577

578

579static bool

582 Oid typioparam,

584 char typdelim,

585 int typlen,

586 bool typbyval,

588 int *ndim_p,

589 int *dim,

590 int *nitems_p,

591 Datum **values_p,

592 bool **nulls_p,

593 const char *origStr,

594 Node *escontext)

595{

596 int ndim = *ndim_p;

597 bool dimensions_specified = (ndim != 0);

598 int maxitems;

600 bool *nulls;

602 int nest_level;

604 bool ndim_frozen;

605 bool expect_delim;

607

608

609 maxitems = 16;

612

613

615

616

617 Assert(**srcptr == '{');

618

619

620 nest_level = 0;

622 ndim_frozen = dimensions_specified;

623 expect_delim = false;

624 do

625 {

627

628 tok = ReadArrayToken(srcptr, &elembuf, typdelim, origStr, escontext);

629

630 switch (tok)

631 {

633

634 if (expect_delim)

635 ereturn(escontext, false,

636 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

637 errmsg("malformed array literal: \"%s\"", origStr),

638 errdetail("Unexpected \"%c\" character.", '{')));

639

640

641 if (nest_level >= MAXDIM)

642 ereturn(escontext, false,

643 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

644 errmsg("number of array dimensions exceeds the maximum allowed (%d)",

646

647 nelems[nest_level] = 0;

648 nest_level++;

649 if (nest_level > ndim)

650 {

651

652 if (ndim_frozen)

653 goto dimension_error;

654 ndim = nest_level;

655 }

656 break;

657

659

660 Assert(nest_level > 0);

661

662

663

664

665

666 if (nelems[nest_level - 1] > 0 && !expect_delim)

667 ereturn(escontext, false,

668 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

669 errmsg("malformed array literal: \"%s\"", origStr),

670 errdetail("Unexpected \"%c\" character.",

671 '}')));

672 nest_level--;

673

674 if (nest_level > 0)

675 nelems[nest_level - 1]++;

676

677

678

679

680

681

682 if (dim[nest_level] < 0)

683 {

684

685 dim[nest_level] = nelems[nest_level];

686 }

687 else if (nelems[nest_level] != dim[nest_level])

688 {

689

690 goto dimension_error;

691 }

692

693

694

695

696

697 expect_delim = true;

698 break;

699

701 if (!expect_delim)

702 ereturn(escontext, false,

703 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

704 errmsg("malformed array literal: \"%s\"", origStr),

705 errdetail("Unexpected \"%c\" character.",

706 typdelim)));

707 expect_delim = false;

708 break;

709

712

713 Assert(nest_level > 0);

714

715

716 if (expect_delim)

717 ereturn(escontext, false,

718 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

719 errmsg("malformed array literal: \"%s\"", origStr),

720 errdetail("Unexpected array element.")));

721

722

723 if (nitems >= maxitems)

724 {

726 ereturn(escontext, false,

727 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

728 errmsg("array size exceeds the maximum allowed (%zu)",

733 }

734

735

738 typioparam, typmod,

739 escontext,

741 return false;

744

745

746

747

748

749

750 ndim_frozen = true;

751 if (nest_level != ndim)

752 goto dimension_error;

753

754 nelems[nest_level - 1]++;

755

756

757 expect_delim = true;

758 break;

759

761 return false;

762 }

763 } while (nest_level > 0);

764

765

767

768 *ndim_p = ndim;

771 *nulls_p = nulls;

772 return true;

773

774dimension_error:

775 if (dimensions_specified)

776 ereturn(escontext, false,

777 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

778 errmsg("malformed array literal: \"%s\"", origStr),

779 errdetail("Specified array dimensions do not match array contents.")));

780 else

781 ereturn(escontext, false,

782 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

783 errmsg("malformed array literal: \"%s\"", origStr),

784 errdetail("Multidimensional arrays must have sub-arrays with matching dimensions.")));

785}

786

787

788

789

790

791

792

793

794

795

798 const char *origStr, Node *escontext)

799{

800 char *p = *srcptr;

801 int dstlen;

802 bool has_escapes;

803

805

806

807 for (;;)

808 {

809 switch (*p)

810 {

811 case '\0':

812 goto ending_error;

813 case '{':

814 *srcptr = p + 1;

816 case '}':

817 *srcptr = p + 1;

819 case '"':

820 p++;

821 goto quoted_element;

822 default:

823 if (*p == typdelim)

824 {

825 *srcptr = p + 1;

827 }

829 {

830 p++;

831 continue;

832 }

833 goto unquoted_element;

834 }

835 }

836

837quoted_element:

838 for (;;)

839 {

840 switch (*p)

841 {

842 case '\0':

843 goto ending_error;

844 case '\\':

845

846 p++;

847 if (*p == '\0')

848 goto ending_error;

850 break;

851 case '"':

852

853

854

855

856

857

858

859

860

861 while (*(++p) != '\0')

862 {

863 if (*p == typdelim || *p == '}' || *p == '{')

864 {

865 *srcptr = p;

867 }

870 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

871 errmsg("malformed array literal: \"%s\"", origStr),

872 errdetail("Incorrectly quoted array element.")));

873 }

874 goto ending_error;

875 default:

877 break;

878 }

879 }

880

881unquoted_element:

882

883

884

885

886

887 dstlen = 0;

888 has_escapes = false;

889 for (;;)

890 {

891 switch (*p)

892 {

893 case '\0':

894 goto ending_error;

895 case '{':

897 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

898 errmsg("malformed array literal: \"%s\"", origStr),

899 errdetail("Unexpected \"%c\" character.",

900 '{')));

901 case '"':

902

904 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

905 errmsg("malformed array literal: \"%s\"", origStr),

906 errdetail("Incorrectly quoted array element.")));

907 case '\\':

908

909 p++;

910 if (*p == '\0')

911 goto ending_error;

913 dstlen = elembuf->len;

914 has_escapes = true;

915 break;

916 default:

917

918 if (*p == typdelim || *p == '}')

919 {

920

921 elembuf->data[dstlen] = '\0';

922 elembuf->len = dstlen;

923 *srcptr = p;

924

928 else

930 }

933 dstlen = elembuf->len;

934 p++;

935 break;

936 }

937 }

938

939ending_error:

941 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

942 errmsg("malformed array literal: \"%s\"", origStr),

943 errdetail("Unexpected end of input.")));

944}

945

946

947

948

949

950

951

952

953

954

955

956

957

958

959

960

961void

964 const bool *nulls,

966 int typlen,

967 bool typbyval,

969 bool freedata)

970{

973 int bitval = 0;

974 int bitmask = 1;

975 int i;

976

977 if (typbyval)

978 freedata = false;

979

981 {

982 if (nulls && nulls[i])

983 {

984 if (!bitmap)

985 elog(ERROR, "null array element where not supported");

986

987 }

988 else

989 {

990 bitval |= bitmask;

992 if (freedata)

994 }

995 if (bitmap)

996 {

997 bitmask <<= 1;

998 if (bitmask == 0x100)

999 {

1000 *bitmap++ = bitval;

1001 bitval = 0;

1002 bitmask = 1;

1003 }

1004 }

1005 }

1006

1007 if (bitmap && bitmask != 1)

1008 *bitmap = bitval;

1009}

1010

1011

1012

1013

1014

1015

1018{

1021 int typlen;

1022 bool typbyval;

1024 char typdelim;

1025 char *p,

1026 *tmp,

1027 *retval,

1029 dims_str[(MAXDIM * 33) + 2];

1030

1031

1032

1033

1034

1035

1036 bool *needquotes,

1037 needdims = false;

1038 size_t overall_length;

1040 i,

1041 j,

1042 k,

1044 int ndim,

1045 *dims,

1046 *lb;

1049

1050

1051

1052

1053

1054

1055 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

1056 if (my_extra == NULL)

1057 {

1058 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,

1060 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

1062 }

1063

1065 {

1066

1067

1068

1074 fcinfo->flinfo->fn_mcxt);

1076 }

1077 typlen = my_extra->typlen;

1078 typbyval = my_extra->typbyval;

1080 typdelim = my_extra->typdelim;

1081

1086

1088 {

1091 }

1092

1093

1094

1095

1096

1097 for (i = 0; i < ndim; i++)

1098 {

1099 if (lb[i] != 1)

1100 {

1101 needdims = true;

1102 break;

1103 }

1104 }

1105

1106

1107

1108

1109

1110

1112 needquotes = (bool *) palloc(nitems * sizeof(bool));

1113 overall_length = 0;

1114

1116

1118 {

1119 Datum itemvalue;

1120 bool isnull;

1121 bool needquote;

1122

1123

1125 typlen, typbyval, typalign);

1126

1127 if (isnull)

1128 {

1130 overall_length += 4;

1131 needquote = false;

1132 }

1133 else

1134 {

1136

1137

1138 if (values[i][0] == '\0')

1139 needquote = true;

1141 needquote = true;

1142 else

1143 needquote = false;

1144

1145 for (tmp = values[i]; *tmp != '\0'; tmp++)

1146 {

1147 char ch = *tmp;

1148

1149 overall_length += 1;

1150 if (ch == '"' || ch == '\\')

1151 {

1152 needquote = true;

1153 overall_length += 1;

1154 }

1155 else if (ch == '{' || ch == '}' || ch == typdelim ||

1157 needquote = true;

1158 }

1159 }

1160

1161 needquotes[i] = needquote;

1162

1163

1164 if (needquote)

1165 overall_length += 2;

1166

1167 overall_length += 1;

1168 }

1169

1170

1171

1172

1173

1174

1175

1176 for (i = j = 0, k = 1; i < ndim; i++)

1177 {

1178 j += k, k *= dims[i];

1179 }

1180 overall_length += 2 * j;

1181

1182

1183 dims_str[0] = '\0';

1184 if (needdims)

1185 {

1186 char *ptr = dims_str;

1187

1188 for (i = 0; i < ndim; i++)

1189 {

1190 sprintf(ptr, "[%d:%d]", lb[i], lb[i] + dims[i] - 1);

1191 ptr += strlen(ptr);

1192 }

1193 *ptr++ = *ASSGN;

1194 *ptr = '\0';

1195 overall_length += ptr - dims_str;

1196 }

1197

1198

1199 retval = (char *) palloc(overall_length);

1200 p = retval;

1201

1202#define APPENDSTR(str) (strcpy(p, (str)), p += strlen(p))

1203#define APPENDCHAR(ch) (*p++ = (ch), *p = '\0')

1204

1205 if (needdims)

1208 for (i = 0; i < ndim; i++)

1209 indx[i] = 0;

1210 j = 0;

1211 k = 0;

1212 do

1213 {

1214 for (i = j; i < ndim - 1; i++)

1216

1217 if (needquotes[k])

1218 {

1220 for (tmp = values[k]; *tmp; tmp++)

1221 {

1222 char ch = *tmp;

1223

1224 if (ch == '"' || ch == '\\')

1225 *p++ = '\\';

1226 *p++ = ch;

1227 }

1228 *p = '\0';

1230 }

1231 else

1234

1235 for (i = ndim - 1; i >= 0; i--)

1236 {

1237 if (++(indx[i]) < dims[i])

1238 {

1240 break;

1241 }

1242 else

1243 {

1244 indx[i] = 0;

1246 }

1247 }

1248 j = i;

1249 } while (j != -1);

1250

1251#undef APPENDSTR

1252#undef APPENDCHAR

1253

1254

1255 Assert(overall_length == (p - retval + 1));

1256

1258 pfree(needquotes);

1259

1261}

1262

1263

1264

1265

1266

1267

1268

1269

1270

1273{

1275 Oid spec_element_type = PG_GETARG_OID(1);

1276

1278 Oid element_type;

1279 int typlen;

1280 bool typbyval;

1282 Oid typioparam;

1283 int i,

1286 bool *nullsPtr;

1287 bool hasnulls;

1289 int32 dataoffset;

1291 int ndim,

1292 flags,

1296

1297

1299 if (ndim < 0)

1301 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),

1302 errmsg("invalid number of dimensions: %d", ndim)));

1305 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

1306 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",

1308

1310 if (flags != 0 && flags != 1)

1312 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),

1313 errmsg("invalid array flags")));

1314

1315

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326

1327

1328

1329 if (element_type != spec_element_type)

1330 {

1334 (errcode(ERRCODE_DATATYPE_MISMATCH),

1335 errmsg("binary data has array element type %u (%s) instead of expected %u (%s)",

1336 element_type,

1339 spec_element_type,

1342 element_type = spec_element_type;

1343 }

1344

1345 for (i = 0; i < ndim; i++)

1346 {

1349 }

1350

1351

1354

1355

1356

1357

1358

1359

1360 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

1361 if (my_extra == NULL)

1362 {

1363 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,

1365 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

1367 }

1368

1370 {

1371

1378 (errcode(ERRCODE_UNDEFINED_FUNCTION),

1379 errmsg("no binary input function available for type %s",

1382 fcinfo->flinfo->fn_mcxt);

1384 }

1385

1387 {

1388

1390 }

1391

1392 typlen = my_extra->typlen;

1393 typbyval = my_extra->typbyval;

1396

1398 nullsPtr = (bool *) palloc(nitems * sizeof(bool));

1400 &my_extra->proc, typioparam, typmod,

1402 dataPtr, nullsPtr,

1403 &hasnulls, &nbytes);

1404 if (hasnulls)

1405 {

1407 nbytes += dataoffset;

1408 }

1409 else

1410 {

1411 dataoffset = 0;

1413 }

1416 retval->ndim = ndim;

1418 retval->elemtype = element_type;

1419 memcpy(ARR_DIMS(retval), dim, ndim * sizeof(int));

1420 memcpy(ARR_LBOUND(retval), lBound, ndim * sizeof(int));

1421

1423 dataPtr, nullsPtr, nitems,

1425 true);

1426

1428 pfree(nullsPtr);

1429

1431}

1432

1433

1434

1435

1436

1437

1438

1439

1440

1441

1442

1443

1444

1445

1446

1447

1448

1449

1450

1451

1452

1453

1454static void

1458 Oid typioparam,

1460 int typlen,

1461 bool typbyval,

1464 bool *nulls,

1465 bool *hasnulls,

1467{

1468 int i;

1469 bool hasnull;

1471

1473 {

1474 int itemlen;

1476

1477

1479 if (itemlen < -1 || itemlen > (buf->len - buf->cursor))

1481 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),

1482 errmsg("insufficient data left in message")));

1483

1484 if (itemlen == -1)

1485 {

1486

1488 typioparam, typmod);

1489 nulls[i] = true;

1490 continue;

1491 }

1492

1493

1494

1495

1496

1498

1499 buf->cursor += itemlen;

1500

1501

1503 typioparam, typmod);

1504 nulls[i] = false;

1505

1506

1507 if (elem_buf.cursor != itemlen)

1509 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),

1510 errmsg("improper binary format in array element %d",

1511 i + 1)));

1512 }

1513

1514

1515

1516

1517 hasnull = false;

1518 totbytes = 0;

1520 {

1521 if (nulls[i])

1522 hasnull = true;

1523 else

1524 {

1525

1526 if (typlen == -1)

1530

1533 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

1534 errmsg("array size exceeds the maximum allowed (%zu)",

1536 }

1537 }

1538 *hasnulls = hasnull;

1539 *nbytes = totbytes;

1540}

1541

1542

1543

1544

1545

1546

1547

1550{

1553 int typlen;

1554 bool typbyval;

1557 i;

1558 int ndim,

1559 *dim,

1560 *lb;

1564

1565

1566

1567

1568

1569

1570 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

1571 if (my_extra == NULL)

1572 {

1573 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,

1575 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

1577 }

1578

1580 {

1581

1588 (errcode(ERRCODE_UNDEFINED_FUNCTION),

1589 errmsg("no binary output function available for type %s",

1592 fcinfo->flinfo->fn_mcxt);

1594 }

1595 typlen = my_extra->typlen;

1596 typbyval = my_extra->typbyval;

1598

1603

1605

1606

1610 for (i = 0; i < ndim; i++)

1611 {

1614 }

1615

1616

1618

1620 {

1621 Datum itemvalue;

1622 bool isnull;

1623

1624

1626 typlen, typbyval, typalign);

1627

1628 if (isnull)

1629 {

1630

1632 }

1633 else

1634 {

1635 bytea *outputbytes;

1636

1641 pfree(outputbytes);

1642 }

1643 }

1644

1646}

1647

1648

1649

1650

1651

1654{

1656

1657

1660

1662}

1663

1664

1665

1666

1667

1670{

1672 char *p;

1673 int i;

1674 int *dimv,

1675 *lb;

1676

1677

1678

1679

1680

1681

1683

1684

1687

1690

1691 p = buf;

1693 {

1694 sprintf(p, "[%d:%d]", lb[i], dimv[i] + lb[i] - 1);

1695 p += strlen(p);

1696 }

1697

1699}

1700

1701

1702

1703

1704

1705

1708{

1711 int *lb;

1712 int result;

1713

1714

1717

1718

1719 if (reqdim <= 0 || reqdim > AARR_NDIM(v))

1721

1723 result = lb[reqdim - 1];

1724

1726}

1727

1728

1729

1730

1731

1732

1735{

1738 int *dimv,

1739 *lb;

1740 int result;

1741

1742

1745

1746

1747 if (reqdim <= 0 || reqdim > AARR_NDIM(v))

1749

1752

1753 result = dimv[reqdim - 1] + lb[reqdim - 1] - 1;

1754

1756}

1757

1758

1759

1760

1761

1762

1765{

1768 int *dimv;

1769 int result;

1770

1771

1774

1775

1776 if (reqdim <= 0 || reqdim > AARR_NDIM(v))

1778

1780

1781 result = dimv[reqdim - 1];

1782

1784}

1785

1786

1787

1788

1789

1792{

1794

1796}

1797

1798

1799

1800

1801

1802

1803

1804

1805

1806

1807

1808

1809

1810

1811

1812

1813

1814

1815

1816

1817

1818

1819

1822 int nSubscripts,

1823 int *indx,

1824 int arraytyplen,

1825 int elmlen,

1826 bool elmbyval,

1827 char elmalign,

1828 bool *isNull)

1829{

1830 int i,

1831 ndim,

1832 *dim,

1833 *lb,

1834 offset,

1835 fixedDim[1],

1836 fixedLb[1];

1837 char *arraydataptr,

1838 *retptr;

1839 bits8 *arraynullsptr;

1840

1841 if (arraytyplen > 0)

1842 {

1843

1844

1845

1846 ndim = 1;

1847 fixedDim[0] = arraytyplen / elmlen;

1848 fixedLb[0] = 0;

1849 dim = fixedDim;

1850 lb = fixedLb;

1852 arraynullsptr = NULL;

1853 }

1855 {

1856

1858 nSubscripts,

1859 indx,

1860 arraytyplen,

1861 elmlen,

1862 elmbyval,

1863 elmalign,

1864 isNull);

1865 }

1866 else

1867 {

1868

1870

1876 }

1877

1878

1879

1880

1881 if (ndim != nSubscripts || ndim <= 0 || ndim > MAXDIM)

1882 {

1883 *isNull = true;

1884 return (Datum) 0;

1885 }

1886 for (i = 0; i < ndim; i++)

1887 {

1888 if (indx[i] < lb[i] || indx[i] >= (dim[i] + lb[i]))

1889 {

1890 *isNull = true;

1891 return (Datum) 0;

1892 }

1893 }

1894

1895

1896

1897

1898 offset = ArrayGetOffset(nSubscripts, dim, lb, indx);

1899

1900

1901

1902

1904 {

1905 *isNull = true;

1906 return (Datum) 0;

1907 }

1908

1909

1910

1911

1912 *isNull = false;

1913 retptr = array_seek(arraydataptr, 0, arraynullsptr, offset,

1914 elmlen, elmbyval, elmalign);

1915 return ArrayCast(retptr, elmbyval, elmlen);

1916}

1917

1918

1919

1920

1923 int nSubscripts, int *indx,

1924 int arraytyplen,

1925 int elmlen, bool elmbyval, char elmalign,

1926 bool *isNull)

1927{

1929 int i,

1930 ndim,

1931 *dim,

1932 *lb,

1933 offset;

1935 bool *dnulls;

1936

1939

1940

1941 Assert(arraytyplen == -1);

1945

1946 ndim = eah->ndims;

1947 dim = eah->dims;

1949

1950

1951

1952

1953 if (ndim != nSubscripts || ndim <= 0 || ndim > MAXDIM)

1954 {

1955 *isNull = true;

1956 return (Datum) 0;

1957 }

1958 for (i = 0; i < ndim; i++)

1959 {

1960 if (indx[i] < lb[i] || indx[i] >= (dim[i] + lb[i]))

1961 {

1962 *isNull = true;

1963 return (Datum) 0;

1964 }

1965 }

1966

1967

1968

1969

1970 offset = ArrayGetOffset(nSubscripts, dim, lb, indx);

1971

1972

1973

1974

1975

1977

1979 dnulls = eah->dnulls;

1980

1981

1982

1983

1984 if (dnulls && dnulls[offset])

1985 {

1986 *isNull = true;

1987 return (Datum) 0;

1988 }

1989

1990

1991

1992

1993

1994

1995

1996 *isNull = false;

1997 return dvalues[offset];

1998}

1999

2000

2001

2002

2003

2004

2005

2006

2007

2008

2009

2010

2011

2012

2013

2014

2015

2016

2017

2018

2019

2020

2021

2022

2023

2024

2025

2026

2027

2028

2029

2032 int nSubscripts,

2033 int *upperIndx,

2034 int *lowerIndx,

2035 bool *upperProvided,

2036 bool *lowerProvided,

2037 int arraytyplen,

2038 int elmlen,

2039 bool elmbyval,

2040 char elmalign)

2041{

2044 int i,

2045 ndim,

2046 *dim,

2047 *lb,

2048 *newlb;

2049 int fixedDim[1],

2050 fixedLb[1];

2051 Oid elemtype;

2052 char *arraydataptr;

2053 bits8 *arraynullsptr;

2054 int32 dataoffset;

2055 int bytes,

2057

2058 if (arraytyplen > 0)

2059 {

2060

2061

2062

2063

2064

2065

2067 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

2068 errmsg("slices of fixed-length arrays not implemented")));

2069

2070

2071

2072

2073

2074

2075 ndim = 1;

2076 fixedDim[0] = arraytyplen / elmlen;

2077 fixedLb[0] = 0;

2078 dim = fixedDim;

2079 lb = fixedLb;

2082 arraynullsptr = NULL;

2083 }

2084 else

2085 {

2086

2088

2095 }

2096

2097

2098

2099

2100

2101

2102 if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)

2104

2105 for (i = 0; i < nSubscripts; i++)

2106 {

2107 if (!lowerProvided[i] || lowerIndx[i] < lb[i])

2108 lowerIndx[i] = lb[i];

2109 if (!upperProvided[i] || upperIndx[i] >= (dim[i] + lb[i]))

2110 upperIndx[i] = dim[i] + lb[i] - 1;

2111 if (lowerIndx[i] > upperIndx[i])

2113 }

2114

2115 for (; i < ndim; i++)

2116 {

2117 lowerIndx[i] = lb[i];

2118 upperIndx[i] = dim[i] + lb[i] - 1;

2119 if (lowerIndx[i] > upperIndx[i])

2121 }

2122

2123 mda_get_range(ndim, span, lowerIndx, upperIndx);

2124

2126 ndim, dim, lb,

2127 lowerIndx, upperIndx,

2128 elmlen, elmbyval, elmalign);

2129

2130

2131

2132

2133

2134 if (arraynullsptr)

2135 {

2137 bytes += dataoffset;

2138 }

2139 else

2140 {

2141 dataoffset = 0;

2143 }

2144

2147 newarray->ndim = ndim;

2149 newarray->elemtype = elemtype;

2150 memcpy(ARR_DIMS(newarray), span, ndim * sizeof(int));

2151

2152

2153

2154

2155

2157 for (i = 0; i < ndim; i++)

2158 newlb[i] = 1;

2159

2161 ndim, dim, lb,

2162 arraydataptr, arraynullsptr,

2163 lowerIndx, upperIndx,

2164 elmlen, elmbyval, elmalign);

2165

2167}

2168

2169

2170

2171

2172

2173

2174

2175

2176

2177

2178

2179

2180

2181

2182

2183

2184

2185

2186

2187

2188

2189

2190

2191

2192

2193

2194

2195

2196

2197

2198

2199

2200

2203 int nSubscripts,

2204 int *indx,

2205 Datum dataValue,

2206 bool isNull,

2207 int arraytyplen,

2208 int elmlen,

2209 bool elmbyval,

2210 char elmalign)

2211{

2214 int i,

2215 ndim,

2218 offset;

2219 char *elt_ptr;

2220 bool newhasnulls;

2221 bits8 *oldnullbitmap;

2222 int oldnitems,

2223 newnitems,

2224 olddatasize,

2225 newsize,

2226 olditemlen,

2227 newitemlen,

2228 overheadlen,

2229 oldoverheadlen,

2230 addedbefore,

2231 addedafter,

2232 lenbefore,

2233 lenafter;

2234

2235 if (arraytyplen > 0)

2236 {

2237

2238

2239

2240

2241 char *resultarray;

2242

2243 if (nSubscripts != 1)

2245 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2246 errmsg("wrong number of array subscripts")));

2247

2248 if (indx[0] < 0 || indx[0] >= arraytyplen / elmlen)

2250 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2251 errmsg("array subscript out of range")));

2252

2253 if (isNull)

2255 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

2256 errmsg("cannot assign null value to an element of a fixed-length array")));

2257

2258 resultarray = (char *) palloc(arraytyplen);

2259 memcpy(resultarray, DatumGetPointer(arraydatum), arraytyplen);

2260 elt_ptr = resultarray + indx[0] * elmlen;

2261 ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elt_ptr);

2263 }

2264

2265 if (nSubscripts <= 0 || nSubscripts > MAXDIM)

2267 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2268 errmsg("wrong number of array subscripts")));

2269

2270

2271 if (elmlen == -1 && !isNull)

2273

2275 {

2276

2278 nSubscripts,

2279 indx,

2280 dataValue,

2281 isNull,

2282 arraytyplen,

2283 elmlen,

2284 elmbyval,

2285 elmalign);

2286 }

2287

2288

2290

2292

2293

2294

2295

2296

2297

2298 if (ndim == 0)

2299 {

2301

2302 for (i = 0; i < nSubscripts; i++)

2303 {

2304 dim[i] = 1;

2305 lb[i] = indx[i];

2306 }

2307

2309 nSubscripts, dim, lb,

2310 elmtype,

2311 elmlen, elmbyval, elmalign));

2312 }

2313

2314 if (ndim != nSubscripts)

2316 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2317 errmsg("wrong number of array subscripts")));

2318

2319

2320 memcpy(dim, ARR_DIMS(array), ndim * sizeof(int));

2321 memcpy(lb, ARR_LBOUND(array), ndim * sizeof(int));

2322

2323 newhasnulls = (ARR_HASNULL(array) || isNull);

2324 addedbefore = addedafter = 0;

2325

2326

2327

2328

2329

2330

2331

2332 if (ndim == 1)

2333 {

2334 if (indx[0] < lb[0])

2335 {

2336

2337

2341 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2342 errmsg("array size exceeds the maximum allowed (%zu)",

2344 lb[0] = indx[0];

2345 if (addedbefore > 1)

2346 newhasnulls = true;

2347 }

2348 if (indx[0] >= (dim[0] + lb[0]))

2349 {

2350

2351

2356 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2357 errmsg("array size exceeds the maximum allowed (%zu)",

2359 if (addedafter > 1)

2360 newhasnulls = true;

2361 }

2362 }

2363 else

2364 {

2365

2366

2367

2368

2369 for (i = 0; i < ndim; i++)

2370 {

2371 if (indx[i] < lb[i] ||

2372 indx[i] >= (dim[i] + lb[i]))

2374 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2375 errmsg("array subscript out of range")));

2376 }

2377 }

2378

2379

2382

2383

2384

2385

2386 if (newhasnulls)

2388 else

2393 olddatasize = ARR_SIZE(array) - oldoverheadlen;

2394 if (addedbefore)

2395 {

2396 offset = 0;

2397 lenbefore = 0;

2398 olditemlen = 0;

2399 lenafter = olddatasize;

2400 }

2401 else if (addedafter)

2402 {

2403 offset = oldnitems;

2404 lenbefore = olddatasize;

2405 olditemlen = 0;

2406 lenafter = 0;

2407 }

2408 else

2409 {

2410 offset = ArrayGetOffset(nSubscripts, dim, lb, indx);

2412 elmlen, elmbyval, elmalign);

2413 lenbefore = (int) (elt_ptr - ARR_DATA_PTR(array));

2415 olditemlen = 0;

2416 else

2417 {

2420 }

2421 lenafter = olddatasize - lenbefore - olditemlen;

2422 }

2423

2424 if (isNull)

2425 newitemlen = 0;

2426 else

2427 {

2430 }

2431

2432 newsize = overheadlen + lenbefore + newitemlen + lenafter;

2433

2434

2435

2436

2439 newarray->ndim = ndim;

2440 newarray->dataoffset = newhasnulls ? overheadlen : 0;

2442 memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));

2443 memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));

2444

2445

2446

2447

2448 memcpy((char *) newarray + overheadlen,

2449 (char *) array + oldoverheadlen,

2450 lenbefore);

2451 if (!isNull)

2453 (char *) newarray + overheadlen + lenbefore);

2454 memcpy((char *) newarray + overheadlen + lenbefore + newitemlen,

2455 (char *) array + oldoverheadlen + lenbefore + olditemlen,

2456 lenafter);

2457

2458

2459

2460

2461

2462

2463

2464 if (newhasnulls)

2465 {

2467

2468

2469

2470 if (addedafter)

2472 else

2474

2475 if (addedbefore)

2477 oldnullbitmap, 0,

2478 oldnitems);

2479 else

2480 {

2482 oldnullbitmap, 0,

2483 offset);

2484 if (addedafter == 0)

2486 oldnullbitmap, offset + 1,

2487 oldnitems - offset - 1);

2488 }

2489 }

2490

2492}

2493

2494

2495

2496

2497

2498

2499

2500

2503 int nSubscripts, int *indx,

2504 Datum dataValue, bool isNull,

2505 int arraytyplen,

2506 int elmlen, bool elmbyval, char elmalign)

2507{

2510 bool *dnulls;

2511 int i,

2512 ndim,

2515 offset;

2516 bool dimschanged,

2517 newhasnulls;

2518 int addedbefore,

2519 addedafter;

2520 char *oldValue;

2521

2522

2524

2525

2526 Assert(arraytyplen == -1);

2530

2531

2532

2533

2534

2535

2536 ndim = eah->ndims;

2538 memcpy(dim, eah->dims, ndim * sizeof(int));

2539 memcpy(lb, eah->lbound, ndim * sizeof(int));

2540 dimschanged = false;

2541

2542

2543

2544

2545

2546

2547 if (ndim == 0)

2548 {

2549

2550

2551

2552

2553 Assert(nSubscripts > 0 && nSubscripts <= MAXDIM);

2555 nSubscripts * sizeof(int));

2557 nSubscripts * sizeof(int));

2558

2559

2560 ndim = nSubscripts;

2561 for (i = 0; i < nSubscripts; i++)

2562 {

2563 dim[i] = 0;

2564 lb[i] = indx[i];

2565 }

2566 dimschanged = true;

2567 }

2568 else if (ndim != nSubscripts)

2570 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2571 errmsg("wrong number of array subscripts")));

2572

2573

2574

2575

2576

2577

2578

2580

2581

2582

2583

2584

2585

2586

2587

2588

2589 if (!eah->typbyval && !isNull)

2590 {

2592

2595 }

2596

2598 dnulls = eah->dnulls;

2599

2600 newhasnulls = ((dnulls != NULL) || isNull);

2601 addedbefore = addedafter = 0;

2602

2603

2604

2605

2606

2607

2608

2609 if (ndim == 1)

2610 {

2611 if (indx[0] < lb[0])

2612 {

2613

2614

2618 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2619 errmsg("array size exceeds the maximum allowed (%zu)",

2621 lb[0] = indx[0];

2622 dimschanged = true;

2623 if (addedbefore > 1)

2624 newhasnulls = true;

2625 }

2626 if (indx[0] >= (dim[0] + lb[0]))

2627 {

2628

2629

2634 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2635 errmsg("array size exceeds the maximum allowed (%zu)",

2637 dimschanged = true;

2638 if (addedafter > 1)

2639 newhasnulls = true;

2640 }

2641 }

2642 else

2643 {

2644

2645

2646

2647

2648 for (i = 0; i < ndim; i++)

2649 {

2650 if (indx[i] < lb[i] ||

2651 indx[i] >= (dim[i] + lb[i]))

2653 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2654 errmsg("array subscript out of range")));

2655 }

2656 }

2657

2658

2659 if (dimschanged)

2660 {

2663 }

2664

2665

2666 offset = ArrayGetOffset(nSubscripts, dim, lb, indx);

2667

2668

2670 {

2671

2672 int newlen = dim[0] + dim[0] / 8;

2673

2674 newlen = Max(newlen, dim[0]);

2677 if (dnulls)

2678 eah->dnulls = dnulls = (bool *)

2679 repalloc(dnulls, newlen * sizeof(bool));

2681 }

2682

2683

2684

2685

2686

2687 if (newhasnulls && dnulls == NULL)

2688 eah->dnulls = dnulls = (bool *)

2691

2692

2693

2694

2695

2696

2697

2699

2701

2702

2703 if (dimschanged)

2704 {

2705 eah->ndims = ndim;

2706 memcpy(eah->dims, dim, ndim * sizeof(int));

2707 memcpy(eah->lbound, lb, ndim * sizeof(int));

2708 }

2709

2710

2711 if (addedbefore > 0)

2712 {

2713 memmove(dvalues + addedbefore, dvalues, eah->nelems * sizeof(Datum));

2714 for (i = 0; i < addedbefore; i++)

2715 dvalues[i] = (Datum) 0;

2716 if (dnulls)

2717 {

2718 memmove(dnulls + addedbefore, dnulls, eah->nelems * sizeof(bool));

2719 for (i = 0; i < addedbefore; i++)

2720 dnulls[i] = true;

2721 }

2722 eah->nelems += addedbefore;

2723 }

2724

2725

2726 if (addedafter > 0)

2727 {

2728 for (i = 0; i < addedafter; i++)

2730 if (dnulls)

2731 {

2732 for (i = 0; i < addedafter; i++)

2733 dnulls[eah->nelems + i] = true;

2734 }

2735 eah->nelems += addedafter;

2736 }

2737

2738

2739 if (!eah->typbyval && (dnulls == NULL || !dnulls[offset]))

2741 else

2742 oldValue = NULL;

2743

2744

2745 dvalues[offset] = dataValue;

2746 if (dnulls)

2747 dnulls[offset] = isNull;

2748

2749

2750

2751

2752

2753

2754 if (oldValue)

2755 {

2756

2757 if (oldValue < eah->fstartptr || oldValue >= eah->fendptr)

2758 pfree(oldValue);

2759 }

2760

2761

2763}

2764

2765

2766

2767

2768

2769

2770

2771

2772

2773

2774

2775

2776

2777

2778

2779

2780

2781

2782

2783

2784

2785

2786

2787

2788

2789

2790

2791

2792

2793

2794

2795

2796

2797

2798

2799

2800

2801

2802

2803

2804

2805

2808 int nSubscripts,

2809 int *upperIndx,

2810 int *lowerIndx,

2811 bool *upperProvided,

2812 bool *lowerProvided,

2813 Datum srcArrayDatum,

2814 bool isNull,

2815 int arraytyplen,

2816 int elmlen,

2817 bool elmbyval,

2818 char elmalign)

2819{

2823 int i,

2824 ndim,

2828 bool newhasnulls;

2830 nsrcitems,

2831 olddatasize,

2832 newsize,

2833 olditemsize,

2834 newitemsize,

2835 overheadlen,

2836 oldoverheadlen,

2837 addedbefore,

2838 addedafter,

2839 lenbefore,

2840 lenafter,

2841 itemsbefore,

2842 itemsafter,

2843 nolditems;

2844

2845

2846 if (isNull)

2847 return arraydatum;

2848

2849 if (arraytyplen > 0)

2850 {

2851

2852

2853

2855 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

2856 errmsg("updates on slices of fixed-length arrays not implemented")));

2857 }

2858

2859

2862

2863

2864

2866

2867

2868

2869

2870

2871

2872 if (ndim == 0)

2873 {

2875 bool *dnulls;

2876 int nelems;

2878

2879 deconstruct_array(srcArray, elmtype, elmlen, elmbyval, elmalign,

2880 &dvalues, &dnulls, &nelems);

2881

2882 for (i = 0; i < nSubscripts; i++)

2883 {

2884 if (!upperProvided[i] || !lowerProvided[i])

2886 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2887 errmsg("array slice subscript must provide both boundaries"),

2888 errdetail("When assigning to a slice of an empty array value,"

2889 " slice boundaries must be fully specified.")));

2890

2891

2895 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2896 errmsg("array size exceeds the maximum allowed (%zu)",

2898

2899 lb[i] = lowerIndx[i];

2900 }

2901

2902

2905 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2906 errmsg("source array too small")));

2907

2909 dim, lb, elmtype,

2910 elmlen, elmbyval, elmalign));

2911 }

2912

2913 if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)

2915 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2916 errmsg("wrong number of array subscripts")));

2917

2918

2919 memcpy(dim, ARR_DIMS(array), ndim * sizeof(int));

2920 memcpy(lb, ARR_LBOUND(array), ndim * sizeof(int));

2921

2923 addedbefore = addedafter = 0;

2924

2925

2926

2927

2928

2929

2930

2931 if (ndim == 1)

2932 {

2933 Assert(nSubscripts == 1);

2934 if (!lowerProvided[0])

2935 lowerIndx[0] = lb[0];

2936 if (!upperProvided[0])

2937 upperIndx[0] = dim[0] + lb[0] - 1;

2938 if (lowerIndx[0] > upperIndx[0])

2940 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2941 errmsg("upper bound cannot be less than lower bound")));

2942 if (lowerIndx[0] < lb[0])

2943 {

2944

2945

2949 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2950 errmsg("array size exceeds the maximum allowed (%zu)",

2952 lb[0] = lowerIndx[0];

2953 if (addedbefore > 1)

2954 newhasnulls = true;

2955 }

2956 if (upperIndx[0] >= (dim[0] + lb[0]))

2957 {

2958

2959

2964 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2965 errmsg("array size exceeds the maximum allowed (%zu)",

2967 if (addedafter > 1)

2968 newhasnulls = true;

2969 }

2970 }

2971 else

2972 {

2973

2974

2975

2976

2977 for (i = 0; i < nSubscripts; i++)

2978 {

2979 if (!lowerProvided[i])

2980 lowerIndx[i] = lb[i];

2981 if (!upperProvided[i])

2982 upperIndx[i] = dim[i] + lb[i] - 1;

2983 if (lowerIndx[i] > upperIndx[i])

2985 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2986 errmsg("upper bound cannot be less than lower bound")));

2987 if (lowerIndx[i] < lb[i] ||

2988 upperIndx[i] >= (dim[i] + lb[i]))

2990 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

2991 errmsg("array subscript out of range")));

2992 }

2993

2994 for (; i < ndim; i++)

2995 {

2996 lowerIndx[i] = lb[i];

2997 upperIndx[i] = dim[i] + lb[i] - 1;

2998 if (lowerIndx[i] > upperIndx[i])

3000 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

3001 errmsg("upper bound cannot be less than lower bound")));

3002 }

3003 }

3004

3005

3008

3009

3010

3011

3012

3013 mda_get_range(ndim, span, lowerIndx, upperIndx);

3017 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

3018 errmsg("source array too small")));

3019

3020

3021

3022

3023

3024 if (newhasnulls)

3026 else

3030 elmlen, elmbyval, elmalign);

3032 olddatasize = ARR_SIZE(array) - oldoverheadlen;

3033 if (ndim > 1)

3034 {

3035

3036

3037

3038

3041 ndim, dim, lb,

3042 lowerIndx, upperIndx,

3043 elmlen, elmbyval, elmalign);

3044 lenbefore = lenafter = 0;

3045 itemsbefore = itemsafter = nolditems = 0;

3046 }

3047 else

3048 {

3049

3050

3051

3052

3054 int oldub = oldlb + ARR_DIMS(array)[0] - 1;

3055 int slicelb = Max(oldlb, lowerIndx[0]);

3056 int sliceub = Min(oldub, upperIndx[0]);

3059

3060

3061 itemsbefore = Min(slicelb, oldub + 1) - oldlb;

3063 itemsbefore,

3064 elmlen, elmbyval, elmalign);

3065

3066 if (slicelb > sliceub)

3067 {

3068 nolditems = 0;

3069 olditemsize = 0;

3070 }

3071 else

3072 {

3073 nolditems = sliceub - slicelb + 1;

3075 itemsbefore, oldarraybitmap,

3076 nolditems,

3077 elmlen, elmbyval, elmalign);

3078 }

3079

3080 itemsafter = oldub + 1 - Max(sliceub + 1, oldlb);

3081 lenafter = olddatasize - lenbefore - olditemsize;

3082 }

3083

3084 newsize = overheadlen + olddatasize - olditemsize + newitemsize;

3085

3088 newarray->ndim = ndim;

3089 newarray->dataoffset = newhasnulls ? overheadlen : 0;

3091 memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));

3092 memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));

3093

3094 if (ndim > 1)

3095 {

3096

3097

3098

3099

3101 ndim, dim, lb,

3102 lowerIndx, upperIndx,

3103 elmlen, elmbyval, elmalign);

3104 }

3105 else

3106 {

3107

3108 memcpy((char *) newarray + overheadlen,

3109 (char *) array + oldoverheadlen,

3110 lenbefore);

3111 memcpy((char *) newarray + overheadlen + lenbefore,

3113 newitemsize);

3114 memcpy((char *) newarray + overheadlen + lenbefore + newitemsize,

3115 (char *) array + oldoverheadlen + lenbefore + olditemsize,

3116 lenafter);

3117

3118 if (newhasnulls)

3119 {

3122

3123

3125 oldnullbitmap, 0,

3126 itemsbefore);

3129 nsrcitems);

3130 array_bitmap_copy(newnullbitmap, addedbefore + itemsbefore + nolditems,

3131 oldnullbitmap, itemsbefore + nolditems,

3132 itemsafter);

3133 }

3134 }

3135

3137}

3138

3139

3140

3141

3142

3143

3144

3145

3148 int arraytyplen, int elmlen, bool elmbyval, char elmalign,

3149 bool *isNull)

3150{

3152 arraytyplen, elmlen, elmbyval, elmalign,

3153 isNull);

3154}

3155

3156

3157

3158

3159

3160

3161

3162

3165 Datum dataValue, bool isNull,

3166 int arraytyplen, int elmlen, bool elmbyval, char elmalign)

3167{

3169 nSubscripts, indx,

3170 dataValue, isNull,

3171 arraytyplen,

3172 elmlen, elmbyval, elmalign));

3173}

3174

3175

3176

3177

3178

3179

3180

3181

3182

3183

3184

3185

3186

3187

3188

3189

3190

3191

3192

3193

3194

3195

3196

3197

3198

3199

3200

3205{

3209 bool *nulls;

3210 int *dim;

3211 int ndim;

3213 int i;

3214 int32 nbytes = 0;

3215 int32 dataoffset;

3216 bool hasnulls;

3217 Oid inpType;

3218 int inp_typlen;

3219 bool inp_typbyval;

3220 char inp_typalign;

3221 int typlen;

3222 bool typbyval;

3229

3234

3235

3237 {

3238

3240 }

3241

3242

3243

3244

3245

3246

3247 inp_extra = &amstate->inp_extra;

3248 ret_extra = &amstate->ret_extra;

3249

3251 {

3257 }

3258 inp_typlen = inp_extra->typlen;

3259 inp_typbyval = inp_extra->typbyval;

3260 inp_typalign = inp_extra->typalign;

3261

3263 {

3269 }

3270 typlen = ret_extra->typlen;

3271 typbyval = ret_extra->typbyval;

3273

3274

3276 nulls = (bool *) palloc(nitems * sizeof(bool));

3277

3278

3280 hasnulls = false;

3281

3283 {

3284

3285 *transform_source =

3287 inp_typlen, inp_typbyval, inp_typalign);

3288

3289

3291

3292 if (nulls[i])

3293 hasnulls = true;

3294 else

3295 {

3296

3297 if (typlen == -1)

3299

3302

3305 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

3306 errmsg("array size exceeds the maximum allowed (%zu)",

3308 }

3309 }

3310

3311

3312 if (hasnulls)

3313 {

3315 nbytes += dataoffset;

3316 }

3317 else

3318 {

3319 dataoffset = 0;

3321 }

3324 result->ndim = ndim;

3329

3333 false);

3334

3335

3336

3337

3340

3342}

3343

3344

3345

3346

3347

3348

3349

3350

3351

3352

3353

3354

3355

3356

3357

3358

3359

3360

3363 Oid elmtype,

3364 int elmlen, bool elmbyval, char elmalign)

3365{

3366 int dims[1];

3367 int lbs[1];

3368

3369 dims[0] = nelems;

3370 lbs[0] = 1;

3371

3373 elmtype, elmlen, elmbyval, elmalign);

3374}

3375

3376

3377

3378

3379

3380

3383{

3384 int elmlen;

3385 bool elmbyval;

3386 char elmalign;

3387

3388 switch (elmtype)

3389 {

3390 case CHAROID:

3391 elmlen = 1;

3392 elmbyval = true;

3393 elmalign = TYPALIGN_CHAR;

3394 break;

3395

3396 case CSTRINGOID:

3397 elmlen = -2;

3398 elmbyval = false;

3399 elmalign = TYPALIGN_CHAR;

3400 break;

3401

3402 case FLOAT4OID:

3403 elmlen = sizeof(float4);

3404 elmbyval = true;

3405 elmalign = TYPALIGN_INT;

3406 break;

3407

3408 case FLOAT8OID:

3409 elmlen = sizeof(float8);

3410 elmbyval = true;

3411 elmalign = TYPALIGN_DOUBLE;

3412 break;

3413

3414 case INT2OID:

3415 elmlen = sizeof(int16);

3416 elmbyval = true;

3417 elmalign = TYPALIGN_SHORT;

3418 break;

3419

3420 case INT4OID:

3421 elmlen = sizeof(int32);

3422 elmbyval = true;

3423 elmalign = TYPALIGN_INT;

3424 break;

3425

3426 case INT8OID:

3427 elmlen = sizeof(int64);

3428 elmbyval = true;

3429 elmalign = TYPALIGN_DOUBLE;

3430 break;

3431

3432 case NAMEOID:

3434 elmbyval = false;

3435 elmalign = TYPALIGN_CHAR;

3436 break;

3437

3438 case OIDOID:

3439 case REGTYPEOID:

3440 elmlen = sizeof(Oid);

3441 elmbyval = true;

3442 elmalign = TYPALIGN_INT;

3443 break;

3444

3445 case TEXTOID:

3446 elmlen = -1;

3447 elmbyval = false;

3448 elmalign = TYPALIGN_INT;

3449 break;

3450

3451 case TIDOID:

3453 elmbyval = false;

3454 elmalign = TYPALIGN_SHORT;

3455 break;

3456

3457 case XIDOID:

3459 elmbyval = true;

3460 elmalign = TYPALIGN_INT;

3461 break;

3462

3463 default:

3464 elog(ERROR, "type %u not supported by construct_array_builtin()", elmtype);

3465

3466 elmlen = 0;

3467 elmbyval = false;

3468 elmalign = 0;

3469 }

3470

3471 return construct_array(elems, nelems, elmtype, elmlen, elmbyval, elmalign);

3472}

3473

3474

3475

3476

3477

3478

3479

3480

3481

3482

3483

3484

3485

3486

3487

3488

3489

3490

3491

3492

3493

3496 bool *nulls,

3497 int ndims,

3498 int *dims,

3499 int *lbs,

3500 Oid elmtype, int elmlen, bool elmbyval, char elmalign)

3501{

3503 bool hasnulls;

3505 int32 dataoffset;

3506 int i;

3507 int nelems;

3508

3509 if (ndims < 0)

3511 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

3512 errmsg("invalid number of dimensions: %d", ndims)));

3515 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

3516 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",

3518

3519

3522

3523

3524 if (nelems <= 0)

3526

3527

3528 nbytes = 0;

3529 hasnulls = false;

3530 for (i = 0; i < nelems; i++)

3531 {

3532 if (nulls && nulls[i])

3533 {

3534 hasnulls = true;

3535 continue;

3536 }

3537

3538 if (elmlen == -1)

3542

3545 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

3546 errmsg("array size exceeds the maximum allowed (%zu)",

3548 }

3549

3550

3551 if (hasnulls)

3552 {

3554 nbytes += dataoffset;

3555 }

3556 else

3557 {

3558 dataoffset = 0;

3560 }

3563 result->ndim = ndims;

3566 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));

3567 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));

3568

3570 elems, nulls, nelems,

3571 elmlen, elmbyval, elmalign,

3572 false);

3573

3574 return result;

3575}

3576

3577

3578

3579

3582{

3584

3587 result->ndim = 0;

3590 return result;

3591}

3592

3593

3594

3595

3596

3601{

3604

3608}

3609

3610

3611

3612

3613

3614

3615

3616

3617

3618

3619

3620

3621

3622

3623

3624

3625

3626

3627

3628

3629

3630

3631void

3633 Oid elmtype,

3634 int elmlen, bool elmbyval, char elmalign,

3635 Datum **elemsp, bool **nullsp, int *nelemsp)

3636{

3638 bool *nulls;

3639 int nelems;

3640 char *p;

3642 int bitmask;

3643 int i;

3644

3646

3649 if (nullsp)

3651 else

3652 nulls = NULL;

3653 *nelemsp = nelems;

3654

3657 bitmask = 1;

3658

3659 for (i = 0; i < nelems; i++)

3660 {

3661

3662 if (bitmap && (*bitmap & bitmask) == 0)

3663 {

3664 elems[i] = (Datum) 0;

3665 if (nulls)

3666 nulls[i] = true;

3667 else

3669 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

3670 errmsg("null array element not allowed in this context")));

3671 }

3672 else

3673 {

3674 elems[i] = fetch_att(p, elmbyval, elmlen);

3677 }

3678

3679

3680 if (bitmap)

3681 {

3682 bitmask <<= 1;

3683 if (bitmask == 0x100)

3684 {

3685 bitmap++;

3686 bitmask = 1;

3687 }

3688 }

3689 }

3690}

3691

3692

3693

3694

3695

3696

3697void

3699 Oid elmtype,

3700 Datum **elemsp, bool **nullsp, int *nelemsp)

3701{

3702 int elmlen;

3703 bool elmbyval;

3704 char elmalign;

3705

3706 switch (elmtype)

3707 {

3708 case CHAROID:

3709 elmlen = 1;

3710 elmbyval = true;

3711 elmalign = TYPALIGN_CHAR;

3712 break;

3713

3714 case CSTRINGOID:

3715 elmlen = -2;

3716 elmbyval = false;

3717 elmalign = TYPALIGN_CHAR;

3718 break;

3719

3720 case FLOAT8OID:

3721 elmlen = sizeof(float8);

3722 elmbyval = true;

3723 elmalign = TYPALIGN_DOUBLE;

3724 break;

3725

3726 case INT2OID:

3727 elmlen = sizeof(int16);

3728 elmbyval = true;

3729 elmalign = TYPALIGN_SHORT;

3730 break;

3731

3732 case OIDOID:

3733 elmlen = sizeof(Oid);

3734 elmbyval = true;

3735 elmalign = TYPALIGN_INT;

3736 break;

3737

3738 case TEXTOID:

3739 elmlen = -1;

3740 elmbyval = false;

3741 elmalign = TYPALIGN_INT;

3742 break;

3743

3744 case TIDOID:

3746 elmbyval = false;

3747 elmalign = TYPALIGN_SHORT;

3748 break;

3749

3750 default:

3751 elog(ERROR, "type %u not supported by deconstruct_array_builtin()", elmtype);

3752

3753 elmlen = 0;

3754 elmbyval = false;

3755 elmalign = 0;

3756 }

3757

3758 deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, elemsp, nullsp, nelemsp);

3759}

3760

3761

3762

3763

3764

3765

3766

3767bool

3769{

3770 int nelems;

3772 int bitmask;

3773

3774

3776 return false;

3777

3779

3781

3782

3783 while (nelems >= 8)

3784 {

3785 if (*bitmap != 0xFF)

3786 return true;

3787 bitmap++;

3788 nelems -= 8;

3789 }

3790

3791

3792 bitmask = 1;

3793 while (nelems > 0)

3794 {

3795 if ((*bitmap & bitmask) == 0)

3796 return true;

3797 bitmask <<= 1;

3798 nelems--;

3799 }

3800

3801 return false;

3802}

3803

3804

3805

3806

3807

3808

3809

3810

3811

3812

3813

3816{

3828 bool result = true;

3831 int typlen;

3832 bool typbyval;

3836 int i;

3837

3840 (errcode(ERRCODE_DATATYPE_MISMATCH),

3841 errmsg("cannot compare arrays of different element types")));

3842

3843

3844 if (ndims1 != ndims2 ||

3845 memcmp(dims1, dims2, ndims1 * sizeof(int)) != 0 ||

3846 memcmp(lbs1, lbs2, ndims1 * sizeof(int)) != 0)

3847 result = false;

3848 else

3849 {

3850

3851

3852

3853

3854

3855

3856 typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;

3857 if (typentry == NULL ||

3858 typentry->type_id != element_type)

3859 {

3864 (errcode(ERRCODE_UNDEFINED_FUNCTION),

3865 errmsg("could not identify an equality operator for type %s",

3867 fcinfo->flinfo->fn_extra = typentry;

3868 }

3869 typlen = typentry->typlen;

3870 typbyval = typentry->typbyval;

3872

3873

3874

3875

3877 collation, NULL, NULL);

3878

3879

3883

3885 {

3888 bool isnull1;

3889 bool isnull2;

3890 bool oprresult;

3891

3892

3894 typlen, typbyval, typalign);

3896 typlen, typbyval, typalign);

3897

3898

3899

3900

3901 if (isnull1 && isnull2)

3902 continue;

3903 if (isnull1 || isnull2)

3904 {

3905 result = false;

3906 break;

3907 }

3908

3909

3910

3911

3912 locfcinfo->args[0].value = elt1;

3913 locfcinfo->args[0].isnull = false;

3914 locfcinfo->args[1].value = elt2;

3915 locfcinfo->args[1].isnull = false;

3916 locfcinfo->isnull = false;

3918 if (locfcinfo->isnull || !oprresult)

3919 {

3920 result = false;

3921 break;

3922 }

3923 }

3924 }

3925

3926

3929

3931}

3932

3933

3934

3935

3936

3937

3938

3939

3940

3941

3942

3945{

3947}

3948

3951{

3953}

3954

3957{

3959}

3960

3963{

3965}

3966

3969{

3971}

3972

3975{

3977}

3978

3979

3980

3981

3982

3983

3984

3985static int

3987{

3999 int result = 0;

4001 int typlen;

4002 bool typbyval;

4004 int min_nitems;

4007 int i;

4008

4011 (errcode(ERRCODE_DATATYPE_MISMATCH),

4012 errmsg("cannot compare arrays of different element types")));

4013

4014

4015

4016

4017

4018

4019

4021 if (typentry == NULL ||

4022 typentry->type_id != element_type)

4023 {

4028 (errcode(ERRCODE_UNDEFINED_FUNCTION),

4029 errmsg("could not identify a comparison function for type %s",

4032 }

4033 typlen = typentry->typlen;

4034 typbyval = typentry->typbyval;

4036

4037

4038

4039

4041 collation, NULL, NULL);

4042

4043

4044 min_nitems = Min(nitems1, nitems2);

4047

4048 for (i = 0; i < min_nitems; i++)

4049 {

4052 bool isnull1;

4053 bool isnull2;

4054 int32 cmpresult;

4055

4056

4059

4060

4061

4062

4063 if (isnull1 && isnull2)

4064 continue;

4065 if (isnull1)

4066 {

4067

4068 result = 1;

4069 break;

4070 }

4071 if (isnull2)

4072 {

4073

4074 result = -1;

4075 break;

4076 }

4077

4078

4079 locfcinfo->args[0].value = elt1;

4080 locfcinfo->args[0].isnull = false;

4081 locfcinfo->args[1].value = elt2;

4082 locfcinfo->args[1].isnull = false;

4084

4085

4086 Assert(!locfcinfo->isnull);

4087

4088 if (cmpresult == 0)

4089 continue;

4090

4091 if (cmpresult < 0)

4092 {

4093

4094 result = -1;

4095 break;

4096 }

4097 else

4098 {

4099

4100 result = 1;

4101 break;

4102 }

4103 }

4104

4105

4106

4107

4108

4109

4110

4111 if (result == 0)

4112 {

4113 if (nitems1 != nitems2)

4114 result = (nitems1 < nitems2) ? -1 : 1;

4115 else if (ndims1 != ndims2)

4116 result = (ndims1 < ndims2) ? -1 : 1;

4117 else

4118 {

4119 for (i = 0; i < ndims1; i++)

4120 {

4121 if (dims1[i] != dims2[i])

4122 {

4123 result = (dims1[i] < dims2[i]) ? -1 : 1;

4124 break;

4125 }

4126 }

4127 if (result == 0)

4128 {

4131

4132 for (i = 0; i < ndims1; i++)

4133 {

4134 if (lbound1[i] != lbound2[i])

4135 {

4136 result = (lbound1[i] < lbound2[i]) ? -1 : 1;

4137 break;

4138 }

4139 }

4140 }

4141 }

4142 }

4143

4144

4147

4148 return result;

4149}

4150

4151

4152

4153

4154

4155

4156

4157

4160{

4169 int typlen;

4170 bool typbyval;

4172 int i;

4174

4175

4176

4177

4178

4179

4180

4181 typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;

4182 if (typentry == NULL ||

4183 typentry->type_id != element_type)

4184 {

4189 (errcode(ERRCODE_UNDEFINED_FUNCTION),

4190 errmsg("could not identify a hash function for type %s",

4192

4193

4194

4195

4196

4197

4198

4199

4200 if (element_type == RECORDOID)

4201 {

4204

4206

4207

4208

4209

4210

4211

4213 record_typentry->type_id = element_type;

4214

4215

4220

4222

4223 typentry = record_typentry;

4224 }

4225

4226 fcinfo->flinfo->fn_extra = typentry;

4227 }

4228

4229 typlen = typentry->typlen;

4230 typbyval = typentry->typbyval;

4232

4233

4234

4235

4238

4239

4242

4244 {

4246 bool isnull;

4248

4249

4251

4252 if (isnull)

4253 {

4254

4255 elthash = 0;

4256 }

4257 else

4258 {

4259

4260 locfcinfo->args[0].value = elt;

4261 locfcinfo->args[0].isnull = false;

4263

4264 Assert(!locfcinfo->isnull);

4265 }

4266

4267

4268

4269

4270

4271

4272

4273

4274

4275

4276

4277

4278 result = (result << 5) - result + elthash;

4279 }

4280

4281

4283

4285}

4286

4287

4288

4289

4290

4293{

4303 int typlen;

4304 bool typbyval;

4306 int i;

4308

4309 typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;

4310 if (typentry == NULL ||

4311 typentry->type_id != element_type)

4312 {

4317 (errcode(ERRCODE_UNDEFINED_FUNCTION),

4318 errmsg("could not identify an extended hash function for type %s",

4320 fcinfo->flinfo->fn_extra = typentry;

4321 }

4322 typlen = typentry->typlen;

4323 typbyval = typentry->typbyval;

4325

4328

4329

4332

4334 {

4336 bool isnull;

4338

4339

4341

4342 if (isnull)

4343 {

4344 elthash = 0;

4345 }

4346 else

4347 {

4348

4349 locfcinfo->args[0].value = elt;

4350 locfcinfo->args[0].isnull = false;

4352 locfcinfo->args[1].isnull = false;

4354

4355 Assert(!locfcinfo->isnull);

4356 }

4357

4358 result = (result << 5) - result + elthash;

4359 }

4360

4362

4364}

4365

4366

4367

4368

4369

4370

4371

4372

4373

4374

4375

4376

4377

4378

4379

4380

4381static bool

4383 bool matchall, void **fn_extra)

4384{

4386 bool result = matchall;

4389 int nelems1;

4391 bool *nulls2;

4392 int nelems2;

4393 int typlen;

4394 bool typbyval;

4396 int i;

4397 int j;

4399

4402 (errcode(ERRCODE_DATATYPE_MISMATCH),

4403 errmsg("cannot compare arrays of different element types")));

4404

4405

4406

4407

4408

4409

4410

4412 if (typentry == NULL ||

4413 typentry->type_id != element_type)

4414 {

4419 (errcode(ERRCODE_UNDEFINED_FUNCTION),

4420 errmsg("could not identify an equality operator for type %s",

4422 *fn_extra = typentry;

4423 }

4424 typlen = typentry->typlen;

4425 typbyval = typentry->typbyval;

4427

4428

4429

4430

4431

4432

4434 {

4435

4440 }

4441 else

4443 element_type, typlen, typbyval, typalign,

4444 &values2, &nulls2, &nelems2);

4445

4446

4447

4448

4450 collation, NULL, NULL);

4451

4452

4455

4456 for (i = 0; i < nelems1; i++)

4457 {

4459 bool isnull1;

4460

4461

4463

4464

4465

4466

4467

4468

4469 if (isnull1)

4470 {

4471 if (matchall)

4472 {

4473 result = false;

4474 break;

4475 }

4476 continue;

4477 }

4478

4479 for (j = 0; j < nelems2; j++)

4480 {

4481 Datum elt2 = values2[j];

4482 bool isnull2 = nulls2 ? nulls2[j] : false;

4483 bool oprresult;

4484

4485 if (isnull2)

4486 continue;

4487

4488

4489

4490

4491 locfcinfo->args[0].value = elt1;

4492 locfcinfo->args[0].isnull = false;

4493 locfcinfo->args[1].value = elt2;

4494 locfcinfo->args[1].isnull = false;

4495 locfcinfo->isnull = false;

4497 if (!locfcinfo->isnull && oprresult)

4498 break;

4499 }

4500

4501 if (j < nelems2)

4502 {

4503

4504 if (!matchall)

4505 {

4506 result = true;

4507 break;

4508 }

4509 }

4510 else

4511 {

4512

4513 if (matchall)

4514 {

4515 result = false;

4516 break;

4517 }

4518 }

4519 }

4520

4521 return result;

4522}

4523

4526{

4530 bool result;

4531

4533 &fcinfo->flinfo->fn_extra);

4534

4535

4538

4540}

4541

4544{

4548 bool result;

4549

4551 &fcinfo->flinfo->fn_extra);

4552

4553

4556

4558}

4559

4562{

4566 bool result;

4567

4569 &fcinfo->flinfo->fn_extra);

4570

4571

4574

4576}

4577

4578

4579

4580

4581

4582

4583

4584

4585

4586

4587

4588

4589

4590

4591

4592

4593

4594

4595

4596

4599{

4601

4602

4603

4604

4606 if (slice_ndim < 0 || slice_ndim > ARR_NDIM(arr))

4607 elog(ERROR, "invalid arguments to array_create_iterator");

4608

4609

4610

4611

4612 iterator->arr = arr;

4615

4616 if (mstate != NULL)

4617 {

4619

4623 }

4624 else

4629

4630

4631

4632

4634

4635 if (slice_ndim > 0)

4636 {

4637

4638

4639

4640

4641

4644

4645

4646

4647

4650

4651

4652

4653

4658 }

4659

4660

4661

4662

4663

4666

4667 return iterator;

4668}

4669

4670

4671

4672

4673

4674

4675

4676bool

4678{

4679

4681 return false;

4682

4684 {

4685

4686

4687

4689 {

4690 *isnull = true;

4692 }

4693 else

4694 {

4695

4696 char *p = iterator->data_ptr;

4697

4698 *isnull = false;

4700

4701

4705 }

4706 }

4707 else

4708 {

4709

4710

4711

4715 char *p = iterator->data_ptr;

4716 int i;

4717

4719 {

4722 {

4723 nulls[i] = true;

4725 }

4726 else

4727 {

4728 nulls[i] = false;

4730

4731

4734 }

4735 }

4736

4738

4740 nulls,

4748

4749 *isnull = false;

4751 }

4752

4753 return true;

4754}

4755

4756

4757

4758

4759void

4761{

4763 {

4766 }

4767 pfree(iterator);

4768}

4769

4770

4771

4772

4773

4774

4775

4776

4777

4778

4779

4780

4781static bool

4783{

4784 if (nullbitmap == NULL)

4785 return false;

4786 if (nullbitmap[offset / 8] & (1 << (offset % 8)))

4787 return false;

4788 return true;

4789}

4790

4791

4792

4793

4794

4795

4796

4797

4798static void

4800{

4801 int bitmask;

4802

4803 nullbitmap += offset / 8;

4804 bitmask = 1 << (offset % 8);

4805 if (isNull)

4806 *nullbitmap &= ~bitmask;

4807 else

4808 *nullbitmap |= bitmask;

4809}

4810

4811

4812

4813

4814

4815

4818{

4820}

4821

4822

4823

4824

4825

4826

4827static int

4829 int typlen,

4830 bool typbyval,

4833{

4834 int inc;

4835

4836 if (typlen > 0)

4837 {

4838 if (typbyval)

4840 else

4843 }

4844 else

4845 {

4850 }

4851

4852 return inc;

4853}

4854

4855

4856

4857

4858

4859

4860

4861

4862

4863

4864

4865

4866static char *

4868 int typlen, bool typbyval, char typalign)

4869{

4870 int bitmask;

4871 int i;

4872

4873

4874 if (typlen > 0 && !nullbitmap)

4876

4877

4878 if (nullbitmap)

4879 {

4880 nullbitmap += offset / 8;

4881 bitmask = 1 << (offset % 8);

4882

4884 {

4885 if (*nullbitmap & bitmask)

4886 {

4889 }

4890 bitmask <<= 1;

4891 if (bitmask == 0x100)

4892 {

4893 nullbitmap++;

4894 bitmask = 1;

4895 }

4896 }

4897 }

4898 else

4899 {

4901 {

4904 }

4905 }

4906 return ptr;

4907}

4908

4909

4910

4911

4912

4913

4914static int

4916 int typlen, bool typbyval, char typalign)

4917{

4919 typlen, typbyval, typalign) - ptr;

4920}

4921

4922

4923

4924

4925

4926

4927

4928

4929

4930

4931

4932

4933

4934

4935

4936static int

4938 char *srcptr, int offset, bits8 *nullbitmap,

4939 int typlen, bool typbyval, char typalign)

4940{

4941 int numbytes;

4942

4944 typlen, typbyval, typalign);

4945 memcpy(destptr, srcptr, numbytes);

4946 return numbytes;

4947}

4948

4949

4950

4951

4952

4953

4954

4955

4956

4957

4958

4959

4960

4961

4962

4963

4964

4965

4966void

4968 const bits8 *srcbitmap, int srcoffset,

4970{

4971 int destbitmask,

4972 destbitval,

4973 srcbitmask,

4974 srcbitval;

4975

4978 return;

4979 destbitmap += destoffset / 8;

4980 destbitmask = 1 << (destoffset % 8);

4981 destbitval = *destbitmap;

4982 if (srcbitmap)

4983 {

4984 srcbitmap += srcoffset / 8;

4985 srcbitmask = 1 << (srcoffset % 8);

4986 srcbitval = *srcbitmap;

4987 while (nitems-- > 0)

4988 {

4989 if (srcbitval & srcbitmask)

4990 destbitval |= destbitmask;

4991 else

4992 destbitval &= ~destbitmask;

4993 destbitmask <<= 1;

4994 if (destbitmask == 0x100)

4995 {

4996 *destbitmap++ = destbitval;

4997 destbitmask = 1;

4999 destbitval = *destbitmap;

5000 }

5001 srcbitmask <<= 1;

5002 if (srcbitmask == 0x100)

5003 {

5004 srcbitmap++;

5005 srcbitmask = 1;

5007 srcbitval = *srcbitmap;

5008 }

5009 }

5010 if (destbitmask != 1)

5011 *destbitmap = destbitval;

5012 }

5013 else

5014 {

5015 while (nitems-- > 0)

5016 {

5017 destbitval |= destbitmask;

5018 destbitmask <<= 1;

5019 if (destbitmask == 0x100)

5020 {

5021 *destbitmap++ = destbitval;

5022 destbitmask = 1;

5024 destbitval = *destbitmap;

5025 }

5026 }

5027 if (destbitmask != 1)

5028 *destbitmap = destbitval;

5029 }

5030}

5031

5032

5033

5034

5035

5036

5037static int

5039 int ndim, int *dim, int *lb,

5040 int *st, int *endp,

5041 int typlen, bool typbyval, char typalign)

5042{

5043 int src_offset,

5048 char *ptr;

5049 int i,

5050 j,

5051 inc;

5052 int count = 0;

5053

5055

5056

5057 if (typlen > 0 && !arraynullsptr)

5059

5060

5062 ptr = array_seek(arraydataptr, 0, arraynullsptr, src_offset,

5063 typlen, typbyval, typalign);

5066 for (i = 0; i < ndim; i++)

5067 indx[i] = 0;

5068 j = ndim - 1;

5069 do

5070 {

5071 if (dist[j])

5072 {

5073 ptr = array_seek(ptr, src_offset, arraynullsptr, dist[j],

5074 typlen, typbyval, typalign);

5075 src_offset += dist[j];

5076 }

5078 {

5081 ptr += inc;

5082 count += inc;

5083 }

5084 src_offset++;

5086 return count;

5087}

5088

5089

5090

5091

5092

5093

5094

5095

5096

5097static void

5099 int ndim,

5100 int *dim,

5101 int *lb,

5102 char *arraydataptr,

5103 bits8 *arraynullsptr,

5104 int *st,

5105 int *endp,

5106 int typlen,

5107 bool typbyval,

5109{

5112 char *srcdataptr;

5113 int src_offset,

5114 dest_offset,

5119 int i,

5120 j,

5121 inc;

5122

5124 srcdataptr = array_seek(arraydataptr, 0, arraynullsptr, src_offset,

5125 typlen, typbyval, typalign);

5129 for (i = 0; i < ndim; i++)

5130 indx[i] = 0;

5131 dest_offset = 0;

5132 j = ndim - 1;

5133 do

5134 {

5135 if (dist[j])

5136 {

5137

5138 srcdataptr = array_seek(srcdataptr, src_offset, arraynullsptr,

5139 dist[j],

5140 typlen, typbyval, typalign);

5141 src_offset += dist[j];

5142 }

5144 srcdataptr, src_offset, arraynullsptr,

5145 typlen, typbyval, typalign);

5146 if (destnullsptr)

5148 arraynullsptr, src_offset,

5149 1);

5150 destdataptr += inc;

5151 srcdataptr += inc;

5152 src_offset++;

5153 dest_offset++;

5155}

5156

5157

5158

5159

5160

5161

5162

5163

5164

5165

5166

5167

5168

5169

5170static void

5174 int ndim,

5175 int *dim,

5176 int *lb,

5177 int *st,

5178 int *endp,

5179 int typlen,

5180 bool typbyval,

5182{

5191 int dest_offset,

5192 orig_offset,

5193 src_offset,

5198 int i,

5199 j,

5200 inc;

5201

5203

5204 inc = array_copy(destPtr, dest_offset,

5205 origPtr, 0, origBitmap,

5206 typlen, typbyval, typalign);

5207 destPtr += inc;

5208 origPtr += inc;

5209 if (destBitmap)

5211 orig_offset = dest_offset;

5215 for (i = 0; i < ndim; i++)

5216 indx[i] = 0;

5217 src_offset = 0;

5218 j = ndim - 1;

5219 do

5220 {

5221

5222 if (dist[j])

5223 {

5225 origPtr, orig_offset, origBitmap,

5226 typlen, typbyval, typalign);

5227 destPtr += inc;

5228 origPtr += inc;

5229 if (destBitmap)

5231 origBitmap, orig_offset,

5232 dist[j]);

5233 dest_offset += dist[j];

5234 orig_offset += dist[j];

5235 }

5236

5238 srcPtr, src_offset, srcBitmap,

5239 typlen, typbyval, typalign);

5240 if (destBitmap)

5242 srcBitmap, src_offset,

5243 1);

5244 destPtr += inc;

5245 srcPtr += inc;

5246 dest_offset++;

5247 src_offset++;

5248

5249 origPtr = array_seek(origPtr, orig_offset, origBitmap, 1,

5250 typlen, typbyval, typalign);

5251 orig_offset++;

5253

5254

5255 array_copy(destPtr, orignitems - orig_offset,

5256 origPtr, orig_offset, origBitmap,

5257 typlen, typbyval, typalign);

5258 if (destBitmap)

5260 origBitmap, orig_offset,

5261 orignitems - orig_offset);

5262}

5263

5264

5265

5266

5267

5268

5269

5270

5271

5272

5273

5274

5275

5276

5277

5278

5279

5280

5281

5282

5283

5284

5285

5286

5287

5288

5289

5290

5291

5292

5295{

5296

5297

5298

5299

5300

5302 subcontext ? 64 : 8);

5303}

5304

5305

5306

5307

5308

5309

5312 bool subcontext, int initsize)

5313{

5316

5317

5318 if (subcontext)

5320 "accumArrayResult",

5322

5325 astate->mcontext = arr_context;

5327 astate->alen = initsize;

5330 astate->dnulls = (bool *)

5338

5339 return astate;

5340}

5341

5342

5343

5344

5345

5346

5347

5348

5349

5352 Datum dvalue, bool disnull,

5353 Oid element_type,

5355{

5357

5358 if (astate == NULL)

5359 {

5360

5362 }

5363 else

5364 {

5366 }

5367

5369

5370

5372 {

5373 astate->alen *= 2;

5374

5377 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

5378 errmsg("array size exceeds the maximum allowed (%zu)",

5382 astate->dnulls = (bool *)

5384 }

5385

5386

5387

5388

5389

5390

5391

5392

5393

5394 if (!disnull && !astate->typbyval)

5395 {

5396 if (astate->typlen == -1)

5398 else

5400 }

5401

5405

5407

5408 return astate;

5409}

5410

5411

5412

5413

5414

5415

5416

5417

5418

5419

5423{

5424 int ndims;

5425 int dims[1];

5426 int lbs[1];

5427

5428

5429 ndims = (astate->nelems > 0) ? 1 : 0;

5430 dims[0] = astate->nelems;

5431 lbs[0] = 1;

5432

5435}

5436

5437

5438

5439

5440

5441

5442

5443

5444

5445

5446

5447

5448

5449

5450

5451

5454 int ndims,

5455 int *dims,

5456 int *lbs,

5458 bool release)

5459{

5462

5463

5465

5468 ndims,

5469 dims,

5470 lbs,

5475

5477

5478

5479 if (release)

5480 {

5483 }

5484

5486}

5487

5488

5489

5490

5491

5492

5493

5494

5495

5496

5497

5498

5499

5500

5501

5502

5503

5506 bool subcontext)

5507{

5509 MemoryContext arr_context = rcontext;

5510

5511

5513 {

5515

5518 (errcode(ERRCODE_DATATYPE_MISMATCH),

5519 errmsg("data type %s is not an array type",

5521 }

5522

5523

5524 if (subcontext)

5526 "accumArrayResultArr",

5528

5529

5532 astate->mcontext = arr_context;

5534

5535

5538

5539 return astate;

5540}

5541

5542

5543

5544

5545

5546

5547

5548

5549

5552 Datum dvalue, bool disnull,

5553 Oid array_type,

5555{

5558 int *dims,

5559 *lbs,

5560 ndims,

5562 ndatabytes;

5564 int i;

5565

5566

5567

5568

5569

5570

5571 if (disnull)

5573 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

5574 errmsg("cannot accumulate null arrays")));

5575

5576

5578

5579 if (astate == NULL)

5581 else

5583

5585

5586

5593

5594 if (astate->ndims == 0)

5595 {

5596

5597

5598

5599 if (ndims == 0)

5601 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

5602 errmsg("cannot accumulate empty arrays")));

5603 if (ndims + 1 > MAXDIM)

5605 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

5606 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",

5607 ndims + 1, MAXDIM)));

5608

5609

5610

5611

5612

5613 astate->ndims = ndims + 1;

5614 astate->dims[0] = 0;

5615 memcpy(&astate->dims[1], dims, ndims * sizeof(int));

5616 astate->lbs[0] = 1;

5617 memcpy(&astate->lbs[1], lbs, ndims * sizeof(int));

5618

5619

5622 }

5623 else

5624 {

5625

5626 if (astate->ndims != ndims + 1)

5628 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

5629 errmsg("cannot accumulate arrays of different dimensionality")));

5630 for (i = 0; i < ndims; i++)

5631 {

5632 if (astate->dims[i + 1] != dims[i] || astate->lbs[i + 1] != lbs[i])

5634 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

5635 errmsg("cannot accumulate arrays of different dimensionality")));

5636 }

5637

5638

5639 if (astate->nbytes + ndatabytes > astate->abytes)

5640 {

5642 astate->nbytes + ndatabytes);

5644 }

5645 }

5646

5647

5648

5649

5650

5651

5652

5653 memcpy(astate->data + astate->nbytes, data, ndatabytes);

5654 astate->nbytes += ndatabytes;

5655

5656

5658 {

5660

5662 {

5663

5664

5665

5666

5670 NULL, 0,

5672 }

5673 else if (newnitems > astate->aitems)

5674 {

5678 }

5682 }

5683

5685 astate->dims[0] += 1;

5686

5688

5689

5692

5693 return astate;

5694}

5695

5696

5697

5698

5699

5700

5701

5702

5706 bool release)

5707{

5710

5711

5713

5714 if (astate->ndims == 0)

5715 {

5716

5718 }

5719 else

5720 {

5721 int dataoffset,

5722 nbytes;

5723

5724

5727

5728

5729 nbytes = astate->nbytes;

5731 {

5733 nbytes += dataoffset;

5734 }

5735 else

5736 {

5737 dataoffset = 0;

5739 }

5740

5746

5747 memcpy(ARR_DIMS(result), astate->dims, astate->ndims * sizeof(int));

5748 memcpy(ARR_LBOUND(result), astate->lbs, astate->ndims * sizeof(int));

5750

5755 }

5756

5758

5759

5760 if (release)

5761 {

5764 }

5765

5767}

5768

5769

5770

5771

5772

5773

5774

5775

5776

5777

5778

5779

5780

5781

5784{

5786

5787

5788

5789

5790

5791

5792

5794 {

5795

5797

5804 }

5805 else

5806 {

5807

5809

5810 scalarstate = initArrayResult(input_type, rcontext, subcontext);

5816 }

5817

5818 return astate;

5819}

5820

5821

5822

5823

5824

5825

5826

5827

5828

5831 Datum dvalue, bool disnull,

5832 Oid input_type,

5834{

5835 if (astate == NULL)

5837

5840 dvalue, disnull,

5841 input_type, rcontext);

5842 else

5844 dvalue, disnull,

5845 input_type, rcontext);

5846

5847 return astate;

5848}

5849

5850

5851

5852

5853

5854

5855

5856

5860{

5862

5864 {

5865

5866 int ndims;

5867 int dims[1];

5868 int lbs[1];

5869

5870

5873 lbs[0] = 1;

5874

5876 rcontext, release);

5877 }

5878 else

5879 {

5881 rcontext, release);

5882 }

5883 return result;

5884}

5885

5886

5889{

5892 else

5894}

5895

5898{

5901 else

5903}

5904

5905

5907{

5912

5913

5914

5915

5916

5919{

5923

5924

5926 {

5929 int *lb,

5930 *dimv;

5931

5932

5934

5935

5938

5939

5940 if (reqdim <= 0 || reqdim > AARR_NDIM(v))

5942

5943

5944

5945

5948

5951

5952 fctx->lower = lb[reqdim - 1];

5953 fctx->upper = dimv[reqdim - 1] + lb[reqdim - 1] - 1;

5955

5957

5959 }

5960

5962

5964

5966 {

5969 else

5971 }

5972 else

5973

5975}

5976

5977

5978

5979

5980

5983{

5984

5986}

5987

5988

5989

5990

5991

5994{

5998 Oid elmtype;

6000 bool isnull;

6001

6004 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

6005 errmsg("dimension array or low bound array cannot be null")));

6006

6009

6011 {

6013 isnull = false;

6014 }

6015 else

6016 {

6018 isnull = true;

6019 }

6020

6023 elog(ERROR, "could not determine data type of input");

6024

6027}

6028

6029

6030

6031

6032

6035{

6038 Oid elmtype;

6040 bool isnull;

6041

6044 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

6045 errmsg("dimension array or low bound array cannot be null")));

6046

6048

6050 {

6052 isnull = false;

6053 }

6054 else

6055 {

6057 isnull = true;

6058 }

6059

6062 elog(ERROR, "could not determine data type of input");

6063

6066}

6067

6070 Oid elmtype, int dataoffset)

6071{

6073

6076 result->ndim = ndims;

6079 memcpy(ARR_DIMS(result), dimv, ndims * sizeof(int));

6080 memcpy(ARR_LBOUND(result), lbsv, ndims * sizeof(int));

6081

6082 return result;

6083}

6084

6089{

6091 int *dimv;

6092 int *lbsv;

6093 int ndims;

6097 bool elmbyval;

6098 char elmalign;

6100

6101

6102

6103

6106 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

6107 errmsg("wrong number of array subscripts"),

6108 errdetail("Dimension array must be one dimensional.")));

6109

6112 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

6113 errmsg("dimension values cannot be null")));

6114

6117

6118 if (ndims < 0)

6120 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

6121 errmsg("invalid number of dimensions: %d", ndims)));

6124 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

6125 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",

6127

6128 if (lbs != NULL)

6129 {

6132 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

6133 errmsg("wrong number of array subscripts"),

6134 errdetail("Dimension array must be one dimensional.")));

6135

6138 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

6139 errmsg("dimension values cannot be null")));

6140

6143 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

6144 errmsg("wrong number of array subscripts"),

6145 errdetail("Low bound array has different size than dimensions array.")));

6146

6148 }

6149 else

6150 {

6151 int i;

6152

6154 deflbs[i] = 1;

6155

6156 lbsv = deflbs;

6157 }

6158

6159

6162

6163

6166

6167

6168

6169

6170

6172 if (my_extra == NULL)

6173 {

6178 }

6179

6181 {

6182

6188 }

6189

6190 elmlen = my_extra->typlen;

6191 elmbyval = my_extra->typbyval;

6192 elmalign = my_extra->typalign;

6193

6194

6195 if (!isnull)

6196 {

6197 int i;

6198 char *p;

6199 int nbytes;

6200 int totbytes;

6201

6202

6203 if (elmlen == -1)

6205

6209

6210 totbytes = nbytes * nitems;

6211

6212

6213 if (totbytes / nbytes != nitems ||

6216 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

6217 errmsg("array size exceeds the maximum allowed (%zu)",

6219

6220

6221

6222

6223

6225

6227 elmtype, 0);

6228

6232 }

6233 else

6234 {

6235 int nbytes;

6236 int dataoffset;

6237

6239 nbytes = dataoffset;

6240

6242 elmtype, dataoffset);

6243

6244

6245 }

6246

6247 return result;

6248}

6249

6250

6251

6252

6253

6256{

6257 typedef struct

6258 {

6260 int nextelem;

6261 int numelems;

6263 bool elmbyval;

6264 char elmalign;

6265 } array_unnest_fctx;

6266

6268 array_unnest_fctx *fctx;

6270

6271

6273 {

6275

6276

6278

6279

6280

6281

6283

6284

6285

6286

6287

6288

6289

6290

6292

6293

6295

6296

6298 fctx->nextelem = 0;

6300

6302 {

6303

6307 }

6308 else

6310 &fctx->elmlen,

6311 &fctx->elmbyval,

6312 &fctx->elmalign);

6313

6316 }

6317

6318

6321

6322 if (fctx->nextelem < fctx->numelems)

6323 {

6324 int offset = fctx->nextelem++;

6326

6327 elem = array_iter_next(&fctx->iter, &fcinfo->isnull, offset,

6328 fctx->elmlen, fctx->elmbyval, fctx->elmalign);

6329

6331 }

6332 else

6333 {

6334

6336 }

6337}

6338

6339

6340

6341

6342

6343

6344

6347{

6349 Node *ret = NULL;

6350

6352 {

6353

6355

6357 {

6360

6361

6363

6365 ret = (Node *) req;

6366 }

6367 }

6368

6370}

6371

6372

6373

6374

6375

6376

6377

6378

6379

6380

6383 Datum search, bool search_isnull,

6384 Datum replace, bool replace_isnull,

6385 bool remove, Oid collation,

6387{

6390 Oid element_type;

6392 bool *nulls;

6393 int *dim;

6394 int ndim;

6396 nresult;

6397 int i;

6398 int32 nbytes = 0;

6399 int32 dataoffset;

6400 bool hasnulls;

6401 int typlen;

6402 bool typbyval;

6404 char *arraydataptr;

6406 int bitmask;

6407 bool changed = false;

6409

6414

6415

6417 return array;

6418

6419

6420

6421

6422

6423 if (remove && ndim > 1)

6425 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

6426 errmsg("removing elements from multidimensional arrays is not supported")));

6427

6428

6429

6430

6431

6433 if (typentry == NULL ||

6434 typentry->type_id != element_type)

6435 {

6440 (errcode(ERRCODE_UNDEFINED_FUNCTION),

6441 errmsg("could not identify an equality operator for type %s",

6444 }

6445 typlen = typentry->typlen;

6446 typbyval = typentry->typbyval;

6448

6449

6450

6451

6452

6453

6454 if (typlen == -1)

6455 {

6456 if (!search_isnull)

6458 if (!replace_isnull)

6460 }

6461

6462

6464 collation, NULL, NULL);

6465

6466

6468 nulls = (bool *) palloc(nitems * sizeof(bool));

6469

6470

6473 bitmask = 1;

6474 hasnulls = false;

6475 nresult = 0;

6476

6478 {

6480 bool isNull;

6481 bool oprresult;

6482 bool skip = false;

6483

6484

6485 if (bitmap && (*bitmap & bitmask) == 0)

6486 {

6487 isNull = true;

6488

6489 if (search_isnull)

6490 {

6491 if (remove)

6492 {

6493 skip = true;

6494 changed = true;

6495 }

6496 else if (!replace_isnull)

6497 {

6498 values[nresult] = replace;

6499 isNull = false;

6500 changed = true;

6501 }

6502 }

6503 }

6504 else

6505 {

6506 isNull = false;

6507 elt = fetch_att(arraydataptr, typbyval, typlen);

6510

6511 if (search_isnull)

6512 {

6513

6514 values[nresult] = elt;

6515 }

6516 else

6517 {

6518

6519

6520

6521 locfcinfo->args[0].value = elt;

6522 locfcinfo->args[0].isnull = false;

6523 locfcinfo->args[1].value = search;

6524 locfcinfo->args[1].isnull = false;

6525 locfcinfo->isnull = false;

6527 if (locfcinfo->isnull || !oprresult)

6528 {

6529

6530 values[nresult] = elt;

6531 }

6532 else

6533 {

6534

6535 changed = true;

6536 if (remove)

6537 skip = true;

6538 else

6539 {

6540 values[nresult] = replace;

6541 isNull = replace_isnull;

6542 }

6543 }

6544 }

6545 }

6546

6548 {

6549 nulls[nresult] = isNull;

6550 if (isNull)

6551 hasnulls = true;

6552 else

6553 {

6554

6557

6560 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

6561 errmsg("array size exceeds the maximum allowed (%zu)",

6563 }

6564 nresult++;

6565 }

6566

6567

6568 if (bitmap)

6569 {

6570 bitmask <<= 1;

6571 if (bitmask == 0x100)

6572 {

6573 bitmap++;

6574 bitmask = 1;

6575 }

6576 }

6577 }

6578

6579

6580

6581

6582 if (!changed)

6583 {

6586 return array;

6587 }

6588

6589

6590 if (nresult == 0)

6591 {

6595 }

6596

6597

6598 if (hasnulls)

6599 {

6601 nbytes += dataoffset;

6602 }

6603 else

6604 {

6605 dataoffset = 0;

6607 }

6610 result->ndim = ndim;

6612 result->elemtype = element_type;

6613 memcpy(ARR_DIMS(result), ARR_DIMS(array), ndim * sizeof(int));

6615

6616 if (remove)

6617 {

6618

6619 ARR_DIMS(result)[0] = nresult;

6620 }

6621

6622

6624 values, nulls, nresult,

6626 false);

6627

6630

6631 return result;

6632}

6633

6634

6635

6636

6637

6638

6641{

6645

6649

6651 search, search_isnull,

6652 (Datum) 0, true,

6654 fcinfo);

6656}

6657

6658

6659

6660

6663{

6669

6673

6675 search, search_isnull,

6676 replace, replace_isnull,

6678 fcinfo);

6680}

6681

6682

6683

6684

6685

6686

6687

6688

6689

6692{

6697 int result;

6698

6699

6700 if (ARR_NDIM(thresholds) > 1)

6702 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

6703 errmsg("thresholds must be one-dimensional array")));

6704

6707 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

6708 errmsg("thresholds array must not contain NULLs")));

6709

6710

6711 if (element_type == FLOAT8OID)

6713 else

6714 {

6716

6717

6718 typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;

6719 if (typentry == NULL ||

6720 typentry->type_id != element_type)

6721 {

6726 (errcode(ERRCODE_UNDEFINED_FUNCTION),

6727 errmsg("could not identify a comparison function for type %s",

6729 fcinfo->flinfo->fn_extra = typentry;

6730 }

6731

6732

6733

6734

6735

6736 if (typentry->typlen > 0)

6738 collation, typentry);

6739 else

6741 collation, typentry);

6742 }

6743

6744

6746

6748}

6749

6750

6751

6752

6753static int

6755{

6757 float8 *thresholds_data;

6758 int left;

6759 int right;

6760

6761

6762

6763

6764

6766

6767 left = 0;

6769

6770

6771

6772

6773

6774

6775

6776

6777 if (isnan(op))

6778 return right;

6779

6780

6781 while (left < right)

6782 {

6783 int mid = (left + right) / 2;

6784

6785 if (isnan(thresholds_data[mid]) || op < thresholds_data[mid])

6786 right = mid;

6787 else

6788 left = mid + 1;

6789 }

6790

6791 return left;

6792}

6793

6794

6795

6796

6797static int

6800 Oid collation,

6802{

6804 char *thresholds_data;

6805 int typlen = typentry->typlen;

6806 bool typbyval = typentry->typbyval;

6807 int left;

6808 int right;

6809

6810

6811

6812

6813

6814 thresholds_data = (char *) ARR_DATA_PTR(thresholds);

6815

6817 collation, NULL, NULL);

6818

6819

6820 left = 0;

6822 while (left < right)

6823 {

6824 int mid = (left + right) / 2;

6825 char *ptr;

6826 int32 cmpresult;

6827

6828 ptr = thresholds_data + mid * typlen;

6829

6830 locfcinfo->args[0].value = operand;

6831 locfcinfo->args[0].isnull = false;

6832 locfcinfo->args[1].value = fetch_att(ptr, typbyval, typlen);

6833 locfcinfo->args[1].isnull = false;

6834

6836

6837

6838 Assert(!locfcinfo->isnull);

6839

6840 if (cmpresult < 0)

6841 right = mid;

6842 else

6843 left = mid + 1;

6844 }

6845

6846 return left;

6847}

6848

6849

6850

6851

6852static int

6855 Oid collation,

6857{

6859 char *thresholds_data;

6860 int typlen = typentry->typlen;

6861 bool typbyval = typentry->typbyval;

6863 int left;

6864 int right;

6865

6866 thresholds_data = (char *) ARR_DATA_PTR(thresholds);

6867

6869 collation, NULL, NULL);

6870

6871

6872 left = 0;

6874 while (left < right)

6875 {

6876 int mid = (left + right) / 2;

6877 char *ptr;

6878 int i;

6879 int32 cmpresult;

6880

6881

6882 ptr = thresholds_data;

6883 for (i = left; i < mid; i++)

6884 {

6887 }

6888

6889 locfcinfo->args[0].value = operand;

6890 locfcinfo->args[0].isnull = false;

6891 locfcinfo->args[1].value = fetch_att(ptr, typbyval, typlen);

6892 locfcinfo->args[1].isnull = false;

6893

6895

6896

6897 Assert(!locfcinfo->isnull);

6898

6899 if (cmpresult < 0)

6900 right = mid;

6901 else

6902 {

6903 left = mid + 1;

6904

6905

6906

6907

6908

6909

6912 }

6913 }

6914

6915 return left;

6916}

6917

6918

6919

6920

6921

6924{

6929 bool elmbyval;

6930 char elmalign;

6933 bool lowerProvided[MAXDIM];

6934 bool upperProvided[MAXDIM];

6936

6937

6940 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),

6941 errmsg("number of elements to trim must be between 0 and %d",

6943

6944

6945 memset(lowerProvided, false, sizeof(lowerProvided));

6946 memset(upperProvided, false, sizeof(upperProvided));

6948 {

6950 upperProvided[0] = true;

6951 }

6952

6953

6955

6956

6958 upper, lower, upperProvided, lowerProvided,

6959 -1, elmlen, elmbyval, elmalign);

6960

6962}

#define PG_GETARG_ANY_ARRAY_P(n)

#define PG_GETARG_ARRAYTYPE_P(n)

#define ARR_NULLBITMAP(a)

#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)

#define DatumGetArrayTypeP(X)

#define PG_RETURN_ARRAYTYPE_P(x)

#define ARR_OVERHEAD_NONULLS(ndims)

#define ARR_DATA_OFFSET(a)

Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)

void deconstruct_expanded_array(ExpandedArrayHeader *eah)

ExpandedArrayHeader * DatumGetExpandedArray(Datum d)

AnyArrayType * DatumGetAnyArrayP(Datum d)

static Datum array_iter_next(array_iter *it, bool *isnull, int i, int elmlen, bool elmbyval, char elmalign)

static void array_iter_setup(array_iter *it, AnyArrayType *a)

Datum array_eq(PG_FUNCTION_ARGS)

Datum arraycontained(PG_FUNCTION_ARGS)

Datum array_lt(PG_FUNCTION_ARGS)

ArrayType * array_set(ArrayType *array, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)

static bool ReadArrayStr(char **srcptr, FmgrInfo *inputproc, Oid typioparam, int32 typmod, char typdelim, int typlen, bool typbyval, char typalign, int *ndim_p, int *dim, int *nitems_p, Datum **values_p, bool **nulls_p, const char *origStr, Node *escontext)

Datum array_fill(PG_FUNCTION_ARGS)

Datum array_replace(PG_FUNCTION_ARGS)

static ArrayType * array_replace_internal(ArrayType *array, Datum search, bool search_isnull, Datum replace, bool replace_isnull, bool remove, Oid collation, FunctionCallInfo fcinfo)

Datum array_smaller(PG_FUNCTION_ARGS)

ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)

static bool ReadArrayDimensions(char **srcptr, int *ndim_p, int *dim, int *lBound, const char *origStr, Node *escontext)

Datum array_cardinality(PG_FUNCTION_ARGS)

ExpandedArrayHeader * construct_empty_expanded_array(Oid element_type, MemoryContext parentcontext, ArrayMetaState *metacache)

bool array_iterate(ArrayIterator iterator, Datum *value, bool *isnull)

static Datum array_set_element_expanded(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)

void array_free_iterator(ArrayIterator iterator)

Datum array_recv(PG_FUNCTION_ARGS)

Datum generate_subscripts_nodir(PG_FUNCTION_ARGS)

Datum hash_array(PG_FUNCTION_ARGS)

static int width_bucket_array_float8(Datum operand, ArrayType *thresholds)

ArrayBuildStateAny * initArrayResultAny(Oid input_type, MemoryContext rcontext, bool subcontext)

ArrayBuildStateAny * accumArrayResultAny(ArrayBuildStateAny *astate, Datum dvalue, bool disnull, Oid input_type, MemoryContext rcontext)

ArrayType * construct_empty_array(Oid elmtype)

Datum array_dims(PG_FUNCTION_ARGS)

bool array_contains_nulls(const ArrayType *array)

static ArrayToken ReadArrayToken(char **srcptr, StringInfo elembuf, char typdelim, const char *origStr, Node *escontext)

Datum arraycontains(PG_FUNCTION_ARGS)

static int array_slice_size(char *arraydataptr, bits8 *arraynullsptr, int ndim, int *dim, int *lb, int *st, int *endp, int typlen, bool typbyval, char typalign)

static bool array_get_isnull(const bits8 *nullbitmap, int offset)

Datum makeArrayResultArr(ArrayBuildStateArr *astate, MemoryContext rcontext, bool release)

#define AARR_FREE_IF_COPY(array, n)

Datum array_upper(PG_FUNCTION_ARGS)

Datum makeArrayResultAny(ArrayBuildStateAny *astate, MemoryContext rcontext, bool release)

static ArrayType * array_fill_internal(ArrayType *dims, ArrayType *lbs, Datum value, bool isnull, Oid elmtype, FunctionCallInfo fcinfo)

ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)

Datum array_map(Datum arrayd, ExprState *exprstate, ExprContext *econtext, Oid retType, ArrayMapState *amstate)

Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)

Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)

struct ArrayIteratorData ArrayIteratorData

static bool ReadDimensionInt(char **srcptr, int *result, const char *origStr, Node *escontext)

ArrayBuildStateArr * initArrayResultArr(Oid array_type, Oid element_type, MemoryContext rcontext, bool subcontext)

static bool array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation, bool matchall, void **fn_extra)

Datum array_lower(PG_FUNCTION_ARGS)

static int width_bucket_array_fixed(Datum operand, ArrayType *thresholds, Oid collation, TypeCacheEntry *typentry)

ArrayBuildStateArr * accumArrayResultArr(ArrayBuildStateArr *astate, Datum dvalue, bool disnull, Oid array_type, MemoryContext rcontext)

static int array_cmp(FunctionCallInfo fcinfo)

ArrayIterator array_create_iterator(ArrayType *arr, int slice_ndim, ArrayMetaState *mstate)

Datum btarraycmp(PG_FUNCTION_ARGS)

Datum array_ref(ArrayType *array, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)

static void ReadArrayBinary(StringInfo buf, int nitems, FmgrInfo *receiveproc, Oid typioparam, int32 typmod, int typlen, bool typbyval, char typalign, Datum *values, bool *nulls, bool *hasnulls, int32 *nbytes)

static Datum array_get_element_expanded(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)

ArrayBuildState * initArrayResultWithSize(Oid element_type, MemoryContext rcontext, bool subcontext, int initsize)

Datum hash_array_extended(PG_FUNCTION_ARGS)

Datum generate_subscripts(PG_FUNCTION_ARGS)

static void array_insert_slice(ArrayType *destArray, ArrayType *origArray, ArrayType *srcArray, int ndim, int *dim, int *lb, int *st, int *endp, int typlen, bool typbyval, char typalign)

Datum array_send(PG_FUNCTION_ARGS)

Datum array_le(PG_FUNCTION_ARGS)

ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)

static int array_copy(char *destptr, int nitems, char *srcptr, int offset, bits8 *nullbitmap, int typlen, bool typbyval, char typalign)

ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)

Datum array_gt(PG_FUNCTION_ARGS)

Datum array_unnest(PG_FUNCTION_ARGS)

static ArrayType * create_array_envelope(int ndims, int *dimv, int *lbsv, int nbytes, Oid elmtype, int dataoffset)

Datum array_remove(PG_FUNCTION_ARGS)

Datum array_ne(PG_FUNCTION_ARGS)

Datum array_larger(PG_FUNCTION_ARGS)

Datum array_in(PG_FUNCTION_ARGS)

static void array_extract_slice(ArrayType *newarray, int ndim, int *dim, int *lb, char *arraydataptr, bits8 *arraynullsptr, int *st, int *endp, int typlen, bool typbyval, char typalign)

ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)

static int width_bucket_array_variable(Datum operand, ArrayType *thresholds, Oid collation, TypeCacheEntry *typentry)

Datum array_length(PG_FUNCTION_ARGS)

void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)

Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)

static int array_nelems_size(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)

static void array_set_isnull(bits8 *nullbitmap, int offset, bool isNull)

void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)

void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)

static int ArrayCastAndSet(Datum src, int typlen, bool typbyval, char typalign, char *dest)

static Datum ArrayCast(char *value, bool byval, int len)

Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)

Datum array_out(PG_FUNCTION_ARGS)

Datum array_fill_with_lower_bounds(PG_FUNCTION_ARGS)

Datum array_ndims(PG_FUNCTION_ARGS)

static char * array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)

Datum array_get_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, int arraytyplen, int elmlen, bool elmbyval, char elmalign)

Datum array_ge(PG_FUNCTION_ARGS)

Datum width_bucket_array(PG_FUNCTION_ARGS)

Datum arrayoverlap(PG_FUNCTION_ARGS)

Datum array_set_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, Datum srcArrayDatum, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)

void CopyArrayEls(ArrayType *array, const Datum *values, const bool *nulls, int nitems, int typlen, bool typbyval, char typalign, bool freedata)

Datum trim_array(PG_FUNCTION_ARGS)

Datum array_unnest_support(PG_FUNCTION_ARGS)

struct generate_subscripts_fctx generate_subscripts_fctx

void mda_get_offset_values(int n, int *dist, const int *prod, const int *span)

int ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx)

void mda_get_range(int n, int *span, const int *st, const int *endp)

int ArrayGetNItems(int ndim, const int *dims)

void mda_get_prod(int n, const int *range, int *prod)

void ArrayCheckBounds(int ndim, const int *dims, const int *lb)

int mda_next_tuple(int n, int *curr, const int *span)

static Datum values[MAXATTR]

#define FORMAT_TYPE_ALLOW_INVALID

#define OidIsValid(objectId)

Node * estimate_expression_value(PlannerInfo *root, Node *node)

Datum datumCopy(Datum value, bool typByVal, int typLen)

int errdetail(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereturn(context, dummy_value,...)

#define ereport(elevel,...)

static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)

ExpandedObjectHeader * DatumGetEOHP(Datum d)

#define VARATT_IS_EXPANDED_HEADER(PTR)

static Datum EOHPGetRWDatum(const struct ExpandedObjectHeader *eohptr)

#define palloc_object(type)

#define repalloc_array(pointer, type, count)

#define palloc_array(type, count)

#define palloc0_array(type, count)

#define palloc0_object(type)

void fmgr_info(Oid functionId, FmgrInfo *finfo)

void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)

bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)

bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod, Node *escontext, Datum *result)

char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)

Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)

Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf, Oid typioparam, int32 typmod)

#define PG_FREE_IF_COPY(ptr, n)

#define PG_RETURN_UINT32(x)

#define PG_RETURN_BYTEA_P(x)

#define PG_DETOAST_DATUM_COPY(datum)

#define PG_GETARG_POINTER(n)

#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)

#define PG_RETURN_CSTRING(x)

#define PG_GETARG_DATUM(n)

#define LOCAL_FCINFO(name, nargs)

#define PG_GETARG_CSTRING(n)

#define PG_GETARG_INT64(n)

#define PG_RETURN_UINT64(x)

#define PG_DETOAST_DATUM(datum)

#define FunctionCallInvoke(fcinfo)

#define PG_RETURN_TEXT_P(x)

#define PG_RETURN_INT32(x)

#define PG_GETARG_INT32(n)

#define PG_GETARG_BOOL(n)

#define PG_RETURN_DATUM(x)

#define PG_RETURN_POINTER(x)

#define PG_GET_COLLATION()

#define PG_RETURN_BOOL(x)

char * format_type_extended(Oid type_oid, int32 typemod, bits16 flags)

char * format_type_be(Oid type_oid)

#define SRF_IS_FIRSTCALL()

#define SRF_PERCALL_SETUP()

#define SRF_RETURN_NEXT(_funcctx, _result)

#define SRF_FIRSTCALL_INIT()

#define SRF_RETURN_DONE(_funcctx)

Assert(PointerIsAligned(start, uint64))

static bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result)

static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)

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

struct ItemPointerData ItemPointerData

Oid get_element_type(Oid typid)

void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)

void get_type_io_data(Oid typid, IOFuncSelector which_func, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *func)

Oid get_array_type(Oid typid)

void * MemoryContextAlloc(MemoryContext context, Size size)

void * MemoryContextAllocZero(MemoryContext context, Size size)

char * pstrdup(const char *in)

void * repalloc(void *pointer, Size size)

void pfree(void *pointer)

void * palloc0(Size size)

void MemoryContextDelete(MemoryContext context)

#define AllocSetContextCreate

#define ALLOCSET_DEFAULT_SIZES

#define AllocSizeIsValid(size)

static bool is_funcclause(const void *clause)

#define IsA(nodeptr, _type_)

Datum lower(PG_FUNCTION_ARGS)

Datum upper(PG_FUNCTION_ARGS)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

static uint32 pg_nextpower2_32(uint32 num)

static const struct exclude_list_item skip[]

static char buf[DEFAULT_XLOG_SEG_SIZE]

int pg_strcasecmp(const char *s1, const char *s2)

static uint32 DatumGetUInt32(Datum X)

static Datum Int64GetDatum(int64 X)

static uint64 DatumGetUInt64(Datum X)

static bool DatumGetBool(Datum X)

static Datum PointerGetDatum(const void *X)

static float8 DatumGetFloat8(Datum X)

static Pointer DatumGetPointer(Datum X)

static Datum Int32GetDatum(int32 X)

static int32 DatumGetInt32(Datum X)

unsigned int pq_getmsgint(StringInfo msg, int b)

void pq_sendbytes(StringInfo buf, const void *data, int datalen)

void pq_begintypsend(StringInfo buf)

bytea * pq_endtypsend(StringInfo buf)

static void pq_sendint32(StringInfo buf, uint32 i)

bool scanner_isspace(char ch)

double estimate_array_length(PlannerInfo *root, Node *arrayexpr)

struct StringInfoData * StringInfo

void resetStringInfo(StringInfo str)

void appendStringInfoChar(StringInfo str, char ch)

void initStringInfo(StringInfo str)

static void initReadOnlyStringInfo(StringInfo str, char *data, int len)

ArrayBuildStateArr * arraystate

ArrayBuildState * scalarstate

MemoryContext eoh_context

bool * innermost_casenull

Datum * innermost_caseval

MemoryContext multi_call_memory_ctx

FmgrInfo hash_extended_proc_finfo

#define FirstGenbkiObjectId

#define att_align_nominal(cur_offset, attalign)

#define att_addlength_pointer(cur_offset, attlen, attptr)

static Datum fetch_att(const void *T, bool attbyval, int attlen)

#define att_addlength_datum(cur_offset, attlen, attdatum)

static void store_att_byval(void *T, Datum newdatum, int attlen)

TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)

#define TYPECACHE_HASH_PROC_FINFO

#define TYPECACHE_EQ_OPR_FINFO

#define TYPECACHE_HASH_EXTENDED_PROC_FINFO

#define TYPECACHE_CMP_PROC_FINFO

static Size VARSIZE(const void *PTR)

static char * VARDATA(const void *PTR)

static bool VARATT_IS_EXTERNAL_EXPANDED(const void *PTR)

static void SET_VARSIZE(void *PTR, Size len)

text * cstring_to_text(const char *s)