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

33#include "utils/fmgroids.h"

38

39

40

41

42

44

45

46

47

48#define ASSGN "="

49

50#define AARR_FREE_IF_COPY(array,n) \

51 do { \

52 if (!VARATT_IS_EXPANDED_HEADER(array)) \

53 PG_FREE_IF_COPY(array, n); \

54 } while (0)

55

56

57typedef enum

58{

66

67

69{

70

73 int nitems;

75 bool typbyval;

76 char typalign;

77

78

79 int slice_ndim;

80 int slice_len;

84 bool *slice_nulls;

85

86

87 char *data_ptr;

88 int current_item;

90

92 int *dim, int *lBound,

93 const char *origStr, Node *escontext);

95 const char *origStr, Node *escontext);

98 char typdelim,

99 int typlen, bool typbyval, char typalign,

100 int *ndim_p, int *dim,

101 int *nitems_p,

102 Datum **values_p, bool **nulls_p,

103 const char *origStr, Node *escontext);

105 const char *origStr, Node *escontext);

108 int typlen, bool typbyval, char typalign,

110 bool *hasnulls, int32 *nbytes);

112 int nSubscripts, int *indx,

113 int arraytyplen,

114 int elmlen, bool elmbyval, char elmalign,

115 bool *isNull);

117 int nSubscripts, int *indx,

118 Datum dataValue, bool isNull,

119 int arraytyplen,

120 int elmlen, bool elmbyval, char elmalign);

125 int typlen, bool typbyval, char typalign,

128 int typlen, bool typbyval, char typalign);

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

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

133 int typlen, bool typbyval, char typalign);

135 int ndim, int *dim, int *lb,

136 int *st, int *endp,

137 int typlen, bool typbyval, char typalign);

139 int ndim, int *dim, int *lb,

140 char *arraydataptr, bits8 *arraynullsptr,

141 int *st, int *endp,

142 int typlen, bool typbyval, char typalign);

145 int ndim, int *dim, int *lb,

146 int *st, int *endp,

147 int typlen, bool typbyval, char typalign);

150 Oid elmtype, int dataoffset);

155 Datum search, bool search_isnull,

156 Datum replace, bool replace_isnull,

157 bool remove, Oid collation,

162 Oid collation,

166 Oid collation,

168

169

170

171

172

173

174

175

176

177

180{

183

185 Node *escontext = fcinfo->context;

186 int typlen;

187 bool typbyval;

189 char typdelim;

190 Oid typioparam;

191 char *p;

194 bool *nulls;

195 bool hasnulls;

197 int32 dataoffset;

199 int ndim,

203

204

205

206

207

208

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

210 if (my_extra == NULL)

211 {

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

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

216 }

217

219 {

220

221

222

228 fcinfo->flinfo->fn_mcxt);

230 }

231 typlen = my_extra->typlen;

232 typbyval = my_extra->typbyval;

234 typdelim = my_extra->typdelim;

236

237

238

239

240

241

243 {

244 dim[i] = -1;

245 lBound[i] = 1;

246 }

247

248

249

250

251

252

253

256 return (Datum) 0;

257

258 if (ndim == 0)

259 {

260

261 if (*p != '{')

263 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

266 }

267 else

268 {

269

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

272 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

276 p += strlen(ASSGN);

277

279 p++;

280

281 if (*p != '{')

283 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

286 }

287

288

290 &my_extra->proc, typioparam, typmod,

291 typdelim,

293 &ndim,

294 dim,

297 string,

298 escontext))

299 return (Datum) 0;

300

301

302 while (*p)

303 {

306 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

309 }

310

311

314

315

316

317

318 hasnulls = false;

319 nbytes = 0;

321 {

322 if (nulls[i])

323 hasnulls = true;

324 else

325 {

326

327 if (typlen == -1)

331

334 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

335 errmsg("array size exceeds the maximum allowed (%d)",

337 }

338 }

339 if (hasnulls)

340 {

342 nbytes += dataoffset;

343 }

344 else

345 {

346 dataoffset = 0;

348 }

349

350

351

352

355 retval->ndim = ndim;

357

358

359

360

361

362

363 retval->elemtype = element_type;

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

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

366

370 true);

371

374

376}

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401static bool

403 const char *origStr, Node *escontext)

404{

405 char *p = *srcptr;

406 int ndim;

407

408

409

410

411

412 ndim = 0;

413 for (;;)

414 {

415 char *q;

416 int ub;

417 int i;

418

419

420

421

422

424 p++;

425 if (*p != '[')

426 break;

427 p++;

429 ereturn(escontext, false,

430 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

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

433

434 q = p;

436 return false;

437 if (p == q)

438 ereturn(escontext, false,

439 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

442

443 if (*p == ':')

444 {

445

446 lBound[ndim] = i;

447 p++;

448 q = p;

450 return false;

451 if (p == q)

452 ereturn(escontext, false,

453 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

456 }

457 else

458 {

459

460 lBound[ndim] = 1;

461 ub = i;

462 }

463 if (*p != ']')

464 ereturn(escontext, false,

465 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

468 "]")));

469 p++;

470

471

472

473

474

475

476

477

478 if (ub < lBound[ndim])

479 ereturn(escontext, false,

480 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

482

483

484 if (ub == INT_MAX)

485 ereturn(escontext, false,

486 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

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

488

489

492 ereturn(escontext, false,

493 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

494 errmsg("array size exceeds the maximum allowed (%d)",

496

497 dim[ndim] = ub;

498 ndim++;

499 }

500

501 *srcptr = p;

502 *ndim_p = ndim;

503 return true;

504}

505

506

507

508

509

510

511

512

513

514

515

516

517

518static bool

520 const char *origStr, Node *escontext)

521{

522 char *p = *srcptr;

523 long l;

524

525

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

527 {

528 *result = 0;

529 return true;

530 }

531

532 errno = 0;

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

534

536 ereturn(escontext, false,

537 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

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

539

540 *result = (int) l;

541 return true;

542}

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

578static bool

581 Oid typioparam,

583 char typdelim,

584 int typlen,

585 bool typbyval,

587 int *ndim_p,

588 int *dim,

589 int *nitems_p,

590 Datum **values_p,

591 bool **nulls_p,

592 const char *origStr,

593 Node *escontext)

594{

595 int ndim = *ndim_p;

596 bool dimensions_specified = (ndim != 0);

597 int maxitems;

599 bool *nulls;

601 int nest_level;

603 bool ndim_frozen;

604 bool expect_delim;

606

607

608 maxitems = 16;

611

612

614

615

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

617

618

619 nest_level = 0;

621 ndim_frozen = dimensions_specified;

622 expect_delim = false;

623 do

624 {

626

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

628

629 switch (tok)

630 {

632

633 if (expect_delim)

634 ereturn(escontext, false,

635 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

638

639

640 if (nest_level >= MAXDIM)

641 ereturn(escontext, false,

642 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

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

645

646 nelems[nest_level] = 0;

647 nest_level++;

648 if (nest_level > ndim)

649 {

650

651 if (ndim_frozen)

652 goto dimension_error;

653 ndim = nest_level;

654 }

655 break;

656

658

659 Assert(nest_level > 0);

660

661

662

663

664

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

666 ereturn(escontext, false,

667 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

670 '}')));

671 nest_level--;

672

673 if (nest_level > 0)

674 nelems[nest_level - 1]++;

675

676

677

678

679

680

681 if (dim[nest_level] < 0)

682 {

683

684 dim[nest_level] = nelems[nest_level];

685 }

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

687 {

688

689 goto dimension_error;

690 }

691

692

693

694

695

696 expect_delim = true;

697 break;

698

700 if (!expect_delim)

701 ereturn(escontext, false,

702 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

705 typdelim)));

706 expect_delim = false;

707 break;

708

711

712 Assert(nest_level > 0);

713

714

715 if (expect_delim)

716 ereturn(escontext, false,

717 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

720

721

722 if (nitems >= maxitems)

723 {

725 ereturn(escontext, false,

726 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

727 errmsg("array size exceeds the maximum allowed (%d)",

732 }

733

734

737 typioparam, typmod,

738 escontext,

740 return false;

743

744

745

746

747

748

749 ndim_frozen = true;

750 if (nest_level != ndim)

751 goto dimension_error;

752

753 nelems[nest_level - 1]++;

754

755

756 expect_delim = true;

757 break;

758

760 return false;

761 }

762 } while (nest_level > 0);

763

764

766

767 *ndim_p = ndim;

770 *nulls_p = nulls;

771 return true;

772

773dimension_error:

774 if (dimensions_specified)

775 ereturn(escontext, false,

776 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

779 else

780 ereturn(escontext, false,

781 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

784}

785

786

787

788

789

790

791

792

793

794

797 const char *origStr, Node *escontext)

798{

799 char *p = *srcptr;

800 int dstlen;

801 bool has_escapes;

802

804

805

806 for (;;)

807 {

808 switch (*p)

809 {

810 case '\0':

811 goto ending_error;

812 case '{':

813 *srcptr = p + 1;

815 case '}':

816 *srcptr = p + 1;

818 case '"':

819 p++;

820 goto quoted_element;

821 default:

822 if (*p == typdelim)

823 {

824 *srcptr = p + 1;

826 }

828 {

829 p++;

830 continue;

831 }

832 goto unquoted_element;

833 }

834 }

835

836quoted_element:

837 for (;;)

838 {

839 switch (*p)

840 {

841 case '\0':

842 goto ending_error;

843 case '\\':

844

845 p++;

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

847 goto ending_error;

849 break;

850 case '"':

851

852

853

854

855

856

857

858

859

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

861 {

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

863 {

864 *srcptr = p;

866 }

869 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

872 }

873 goto ending_error;

874 default:

876 break;

877 }

878 }

879

880unquoted_element:

881

882

883

884

885

886 dstlen = 0;

887 has_escapes = false;

888 for (;;)

889 {

890 switch (*p)

891 {

892 case '\0':

893 goto ending_error;

894 case '{':

896 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

899 '{')));

900 case '"':

901

903 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

906 case '\\':

907

908 p++;

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

910 goto ending_error;

912 dstlen = elembuf->len;

913 has_escapes = true;

914 break;

915 default:

916

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

918 {

919

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

921 elembuf->len = dstlen;

922 *srcptr = p;

923

927 else

929 }

932 dstlen = elembuf->len;

933 p++;

934 break;

935 }

936 }

937

938ending_error:

940 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

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

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

943}

944

945

946

947

948

949

950

951

952

953

954

955

956

957

958

959

960void

963 bool *nulls,

965 int typlen,

966 bool typbyval,

968 bool freedata)

969{

972 int bitval = 0;

973 int bitmask = 1;

974 int i;

975

976 if (typbyval)

977 freedata = false;

978

980 {

981 if (nulls && nulls[i])

982 {

983 if (!bitmap)

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

985

986 }

987 else

988 {

989 bitval |= bitmask;

991 if (freedata)

993 }

994 if (bitmap)

995 {

996 bitmask <<= 1;

997 if (bitmask == 0x100)

998 {

999 *bitmap++ = bitval;

1000 bitval = 0;

1001 bitmask = 1;

1002 }

1003 }

1004 }

1005

1006 if (bitmap && bitmask != 1)

1007 *bitmap = bitval;

1008}

1009

1010

1011

1012

1013

1014

1017{

1020 int typlen;

1021 bool typbyval;

1023 char typdelim;

1024 char *p,

1025 *tmp,

1026 *retval,

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

1029

1030

1031

1032

1033

1034

1035 bool *needquotes,

1036 needdims = false;

1037 size_t overall_length;

1039 i,

1040 j,

1041 k,

1043 int ndim,

1044 *dims,

1045 *lb;

1048

1049

1050

1051

1052

1053

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

1055 if (my_extra == NULL)

1056 {

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

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

1061 }

1062

1064 {

1065

1066

1067

1073 fcinfo->flinfo->fn_mcxt);

1075 }

1076 typlen = my_extra->typlen;

1077 typbyval = my_extra->typbyval;

1079 typdelim = my_extra->typdelim;

1080

1085

1087 {

1090 }

1091

1092

1093

1094

1095

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

1097 {

1098 if (lb[i] != 1)

1099 {

1100 needdims = true;

1101 break;

1102 }

1103 }

1104

1105

1106

1107

1108

1109

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

1112 overall_length = 0;

1113

1115

1117 {

1118 Datum itemvalue;

1119 bool isnull;

1120 bool needquote;

1121

1122

1124 typlen, typbyval, typalign);

1125

1126 if (isnull)

1127 {

1129 overall_length += 4;

1130 needquote = false;

1131 }

1132 else

1133 {

1135

1136

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

1138 needquote = true;

1140 needquote = true;

1141 else

1142 needquote = false;

1143

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

1145 {

1146 char ch = *tmp;

1147

1148 overall_length += 1;

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

1150 {

1151 needquote = true;

1152 overall_length += 1;

1153 }

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

1156 needquote = true;

1157 }

1158 }

1159

1160 needquotes[i] = needquote;

1161

1162

1163 if (needquote)

1164 overall_length += 2;

1165

1166 overall_length += 1;

1167 }

1168

1169

1170

1171

1172

1173

1174

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

1176 {

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

1178 }

1179 overall_length += 2 * j;

1180

1181

1182 dims_str[0] = '\0';

1183 if (needdims)

1184 {

1185 char *ptr = dims_str;

1186

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

1188 {

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

1190 ptr += strlen(ptr);

1191 }

1192 *ptr++ = *ASSGN;

1193 *ptr = '\0';

1194 overall_length += ptr - dims_str;

1195 }

1196

1197

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

1199 p = retval;

1200

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

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

1203

1204 if (needdims)

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

1208 indx[i] = 0;

1209 j = 0;

1210 k = 0;

1211 do

1212 {

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

1215

1216 if (needquotes[k])

1217 {

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

1220 {

1221 char ch = *tmp;

1222

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

1224 *p++ = '\\';

1225 *p++ = ch;

1226 }

1227 *p = '\0';

1229 }

1230 else

1233

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

1235 {

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

1237 {

1239 break;

1240 }

1241 else

1242 {

1243 indx[i] = 0;

1245 }

1246 }

1247 j = i;

1248 } while (j != -1);

1249

1250#undef APPENDSTR

1251#undef APPENDCHAR

1252

1253

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

1255

1257 pfree(needquotes);

1258

1260}

1261

1262

1263

1264

1265

1266

1267

1268

1269

1272{

1274 Oid spec_element_type = PG_GETARG_OID(1);

1275

1277 Oid element_type;

1278 int typlen;

1279 bool typbyval;

1281 Oid typioparam;

1282 int i,

1285 bool *nullsPtr;

1286 bool hasnulls;

1288 int32 dataoffset;

1290 int ndim,

1291 flags,

1295

1296

1298 if (ndim < 0)

1300 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),

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

1304 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

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

1307

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

1311 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),

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

1313

1314

1316

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326

1327

1328 if (element_type != spec_element_type)

1329 {

1333 (errcode(ERRCODE_DATATYPE_MISMATCH),

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

1335 element_type,

1338 spec_element_type,

1341 element_type = spec_element_type;

1342 }

1343

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

1345 {

1348 }

1349

1350

1353

1354

1355

1356

1357

1358

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

1360 if (my_extra == NULL)

1361 {

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

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

1366 }

1367

1369 {

1370

1377 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

1381 fcinfo->flinfo->fn_mcxt);

1383 }

1384

1386 {

1387

1389 }

1390

1391 typlen = my_extra->typlen;

1392 typbyval = my_extra->typbyval;

1395

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

1399 &my_extra->proc, typioparam, typmod,

1401 dataPtr, nullsPtr,

1402 &hasnulls, &nbytes);

1403 if (hasnulls)

1404 {

1406 nbytes += dataoffset;

1407 }

1408 else

1409 {

1410 dataoffset = 0;

1412 }

1415 retval->ndim = ndim;

1417 retval->elemtype = element_type;

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

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

1420

1422 dataPtr, nullsPtr, nitems,

1424 true);

1425

1427 pfree(nullsPtr);

1428

1430}

1431

1432

1433

1434

1435

1436

1437

1438

1439

1440

1441

1442

1443

1444

1445

1446

1447

1448

1449

1450

1451

1452

1453static void

1457 Oid typioparam,

1459 int typlen,

1460 bool typbyval,

1463 bool *nulls,

1464 bool *hasnulls,

1466{

1467 int i;

1468 bool hasnull;

1470

1472 {

1473 int itemlen;

1475

1476

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

1480 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),

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

1482

1483 if (itemlen == -1)

1484 {

1485

1487 typioparam, typmod);

1488 nulls[i] = true;

1489 continue;

1490 }

1491

1492

1493

1494

1495

1497

1498 buf->cursor += itemlen;

1499

1500

1502 typioparam, typmod);

1503 nulls[i] = false;

1504

1505

1506 if (elem_buf.cursor != itemlen)

1508 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),

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

1510 i + 1)));

1511 }

1512

1513

1514

1515

1516 hasnull = false;

1517 totbytes = 0;

1519 {

1520 if (nulls[i])

1521 hasnull = true;

1522 else

1523 {

1524

1525 if (typlen == -1)

1529

1532 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

1533 errmsg("array size exceeds the maximum allowed (%d)",

1535 }

1536 }

1537 *hasnulls = hasnull;

1538 *nbytes = totbytes;

1539}

1540

1541

1542

1543

1544

1545

1546

1549{

1552 int typlen;

1553 bool typbyval;

1556 i;

1557 int ndim,

1558 *dim,

1559 *lb;

1563

1564

1565

1566

1567

1568

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

1570 if (my_extra == NULL)

1571 {

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

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

1576 }

1577

1579 {

1580

1587 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

1591 fcinfo->flinfo->fn_mcxt);

1593 }

1594 typlen = my_extra->typlen;

1595 typbyval = my_extra->typbyval;

1597

1602

1604

1605

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

1610 {

1613 }

1614

1615

1617

1619 {

1620 Datum itemvalue;

1621 bool isnull;

1622

1623

1625 typlen, typbyval, typalign);

1626

1627 if (isnull)

1628 {

1629

1631 }

1632 else

1633 {

1634 bytea *outputbytes;

1635

1640 pfree(outputbytes);

1641 }

1642 }

1643

1645}

1646

1647

1648

1649

1650

1653{

1655

1656

1659

1661}

1662

1663

1664

1665

1666

1669{

1671 char *p;

1672 int i;

1673 int *dimv,

1674 *lb;

1675

1676

1677

1678

1679

1680

1682

1683

1686

1689

1690 p = buf;

1692 {

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

1694 p += strlen(p);

1695 }

1696

1698}

1699

1700

1701

1702

1703

1704

1707{

1710 int *lb;

1711 int result;

1712

1713

1716

1717

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

1720

1722 result = lb[reqdim - 1];

1723

1725}

1726

1727

1728

1729

1730

1731

1734{

1737 int *dimv,

1738 *lb;

1739 int result;

1740

1741

1744

1745

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

1748

1751

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

1753

1755}

1756

1757

1758

1759

1760

1761

1764{

1767 int *dimv;

1768 int result;

1769

1770

1773

1774

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

1777

1779

1780 result = dimv[reqdim - 1];

1781

1783}

1784

1785

1786

1787

1788

1791{

1793

1795}

1796

1797

1798

1799

1800

1801

1802

1803

1804

1805

1806

1807

1808

1809

1810

1811

1812

1813

1814

1815

1816

1817

1818

1821 int nSubscripts,

1822 int *indx,

1823 int arraytyplen,

1824 int elmlen,

1825 bool elmbyval,

1826 char elmalign,

1827 bool *isNull)

1828{

1829 int i,

1830 ndim,

1831 *dim,

1832 *lb,

1833 offset,

1834 fixedDim[1],

1835 fixedLb[1];

1836 char *arraydataptr,

1837 *retptr;

1838 bits8 *arraynullsptr;

1839

1840 if (arraytyplen > 0)

1841 {

1842

1843

1844

1845 ndim = 1;

1846 fixedDim[0] = arraytyplen / elmlen;

1847 fixedLb[0] = 0;

1848 dim = fixedDim;

1849 lb = fixedLb;

1851 arraynullsptr = NULL;

1852 }

1854 {

1855

1857 nSubscripts,

1858 indx,

1859 arraytyplen,

1860 elmlen,

1861 elmbyval,

1862 elmalign,

1863 isNull);

1864 }

1865 else

1866 {

1867

1869

1875 }

1876

1877

1878

1879

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

1881 {

1882 *isNull = true;

1883 return (Datum) 0;

1884 }

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

1886 {

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

1888 {

1889 *isNull = true;

1890 return (Datum) 0;

1891 }

1892 }

1893

1894

1895

1896

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

1898

1899

1900

1901

1903 {

1904 *isNull = true;

1905 return (Datum) 0;

1906 }

1907

1908

1909

1910

1911 *isNull = false;

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

1913 elmlen, elmbyval, elmalign);

1914 return ArrayCast(retptr, elmbyval, elmlen);

1915}

1916

1917

1918

1919

1922 int nSubscripts, int *indx,

1923 int arraytyplen,

1924 int elmlen, bool elmbyval, char elmalign,

1925 bool *isNull)

1926{

1928 int i,

1929 ndim,

1930 *dim,

1931 *lb,

1932 offset;

1934 bool *dnulls;

1935

1938

1939

1940 Assert(arraytyplen == -1);

1944

1945 ndim = eah->ndims;

1946 dim = eah->dims;

1948

1949

1950

1951

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

1953 {

1954 *isNull = true;

1955 return (Datum) 0;

1956 }

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

1958 {

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

1960 {

1961 *isNull = true;

1962 return (Datum) 0;

1963 }

1964 }

1965

1966

1967

1968

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

1970

1971

1972

1973

1974

1976

1978 dnulls = eah->dnulls;

1979

1980

1981

1982

1983 if (dnulls && dnulls[offset])

1984 {

1985 *isNull = true;

1986 return (Datum) 0;

1987 }

1988

1989

1990

1991

1992

1993

1994

1995 *isNull = false;

1996 return dvalues[offset];

1997}

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

2031 int nSubscripts,

2032 int *upperIndx,

2033 int *lowerIndx,

2034 bool *upperProvided,

2035 bool *lowerProvided,

2036 int arraytyplen,

2037 int elmlen,

2038 bool elmbyval,

2039 char elmalign)

2040{

2043 int i,

2044 ndim,

2045 *dim,

2046 *lb,

2047 *newlb;

2048 int fixedDim[1],

2049 fixedLb[1];

2050 Oid elemtype;

2051 char *arraydataptr;

2052 bits8 *arraynullsptr;

2053 int32 dataoffset;

2054 int bytes,

2056

2057 if (arraytyplen > 0)

2058 {

2059

2060

2061

2062

2063

2064

2066 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

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

2068

2069

2070

2071

2072

2073

2074 ndim = 1;

2075 fixedDim[0] = arraytyplen / elmlen;

2076 fixedLb[0] = 0;

2077 dim = fixedDim;

2078 lb = fixedLb;

2081 arraynullsptr = NULL;

2082 }

2083 else

2084 {

2085

2087

2094 }

2095

2096

2097

2098

2099

2100

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

2103

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

2105 {

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

2107 lowerIndx[i] = lb[i];

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

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

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

2112 }

2113

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

2115 {

2116 lowerIndx[i] = lb[i];

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

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

2120 }

2121

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

2123

2125 ndim, dim, lb,

2126 lowerIndx, upperIndx,

2127 elmlen, elmbyval, elmalign);

2128

2129

2130

2131

2132

2133 if (arraynullsptr)

2134 {

2136 bytes += dataoffset;

2137 }

2138 else

2139 {

2140 dataoffset = 0;

2142 }

2143

2146 newarray->ndim = ndim;

2148 newarray->elemtype = elemtype;

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

2150

2151

2152

2153

2154

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

2157 newlb[i] = 1;

2158

2160 ndim, dim, lb,

2161 arraydataptr, arraynullsptr,

2162 lowerIndx, upperIndx,

2163 elmlen, elmbyval, elmalign);

2164

2166}

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

2202 int nSubscripts,

2203 int *indx,

2204 Datum dataValue,

2205 bool isNull,

2206 int arraytyplen,

2207 int elmlen,

2208 bool elmbyval,

2209 char elmalign)

2210{

2213 int i,

2214 ndim,

2217 offset;

2218 char *elt_ptr;

2219 bool newhasnulls;

2220 bits8 *oldnullbitmap;

2221 int oldnitems,

2222 newnitems,

2223 olddatasize,

2224 newsize,

2225 olditemlen,

2226 newitemlen,

2227 overheadlen,

2228 oldoverheadlen,

2229 addedbefore,

2230 addedafter,

2231 lenbefore,

2232 lenafter;

2233

2234 if (arraytyplen > 0)

2235 {

2236

2237

2238

2239

2240 char *resultarray;

2241

2242 if (nSubscripts != 1)

2244 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

2246

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

2249 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

2251

2252 if (isNull)

2254 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

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

2256

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

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

2259 elt_ptr = (char *) resultarray + indx[0] * elmlen;

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

2262 }

2263

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

2266 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

2268

2269

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

2272

2274 {

2275

2277 nSubscripts,

2278 indx,

2279 dataValue,

2280 isNull,

2281 arraytyplen,

2282 elmlen,

2283 elmbyval,

2284 elmalign);

2285 }

2286

2287

2289

2291

2292

2293

2294

2295

2296

2297 if (ndim == 0)

2298 {

2300

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

2302 {

2303 dim[i] = 1;

2304 lb[i] = indx[i];

2305 }

2306

2308 nSubscripts, dim, lb,

2309 elmtype,

2310 elmlen, elmbyval, elmalign));

2311 }

2312

2313 if (ndim != nSubscripts)

2315 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

2317

2318

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

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

2321

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

2323 addedbefore = addedafter = 0;

2324

2325

2326

2327

2328

2329

2330

2331 if (ndim == 1)

2332 {

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

2334 {

2335

2336

2340 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2341 errmsg("array size exceeds the maximum allowed (%d)",

2343 lb[0] = indx[0];

2344 if (addedbefore > 1)

2345 newhasnulls = true;

2346 }

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

2348 {

2349

2350

2355 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2356 errmsg("array size exceeds the maximum allowed (%d)",

2358 if (addedafter > 1)

2359 newhasnulls = true;

2360 }

2361 }

2362 else

2363 {

2364

2365

2366

2367

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

2369 {

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

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

2373 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

2375 }

2376 }

2377

2378

2381

2382

2383

2384

2385 if (newhasnulls)

2387 else

2392 olddatasize = ARR_SIZE(array) - oldoverheadlen;

2393 if (addedbefore)

2394 {

2395 offset = 0;

2396 lenbefore = 0;

2397 olditemlen = 0;

2398 lenafter = olddatasize;

2399 }

2400 else if (addedafter)

2401 {

2402 offset = oldnitems;

2403 lenbefore = olddatasize;

2404 olditemlen = 0;

2405 lenafter = 0;

2406 }

2407 else

2408 {

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

2411 elmlen, elmbyval, elmalign);

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

2414 olditemlen = 0;

2415 else

2416 {

2419 }

2420 lenafter = (int) (olddatasize - lenbefore - olditemlen);

2421 }

2422

2423 if (isNull)

2424 newitemlen = 0;

2425 else

2426 {

2429 }

2430

2431 newsize = overheadlen + lenbefore + newitemlen + lenafter;

2432

2433

2434

2435

2438 newarray->ndim = ndim;

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

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

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

2443

2444

2445

2446

2447 memcpy((char *) newarray + overheadlen,

2448 (char *) array + oldoverheadlen,

2449 lenbefore);

2450 if (!isNull)

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

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

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

2455 lenafter);

2456

2457

2458

2459

2460

2461

2462

2463 if (newhasnulls)

2464 {

2466

2467

2468

2469 if (addedafter)

2471 else

2473

2474 if (addedbefore)

2476 oldnullbitmap, 0,

2477 oldnitems);

2478 else

2479 {

2481 oldnullbitmap, 0,

2482 offset);

2483 if (addedafter == 0)

2485 oldnullbitmap, offset + 1,

2486 oldnitems - offset - 1);

2487 }

2488 }

2489

2491}

2492

2493

2494

2495

2496

2497

2498

2499

2502 int nSubscripts, int *indx,

2503 Datum dataValue, bool isNull,

2504 int arraytyplen,

2505 int elmlen, bool elmbyval, char elmalign)

2506{

2509 bool *dnulls;

2510 int i,

2511 ndim,

2514 offset;

2515 bool dimschanged,

2516 newhasnulls;

2517 int addedbefore,

2518 addedafter;

2519 char *oldValue;

2520

2521

2523

2524

2525 Assert(arraytyplen == -1);

2529

2530

2531

2532

2533

2534

2535 ndim = eah->ndims;

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

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

2539 dimschanged = false;

2540

2541

2542

2543

2544

2545

2546 if (ndim == 0)

2547 {

2548

2549

2550

2551

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

2554 nSubscripts * sizeof(int));

2556 nSubscripts * sizeof(int));

2557

2558

2559 ndim = nSubscripts;

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

2561 {

2562 dim[i] = 0;

2563 lb[i] = indx[i];

2564 }

2565 dimschanged = true;

2566 }

2567 else if (ndim != nSubscripts)

2569 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

2571

2572

2573

2574

2575

2576

2577

2579

2580

2581

2582

2583

2584

2585

2586

2587

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

2589 {

2591

2594 }

2595

2597 dnulls = eah->dnulls;

2598

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

2600 addedbefore = addedafter = 0;

2601

2602

2603

2604

2605

2606

2607

2608 if (ndim == 1)

2609 {

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

2611 {

2612

2613

2617 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2618 errmsg("array size exceeds the maximum allowed (%d)",

2620 lb[0] = indx[0];

2621 dimschanged = true;

2622 if (addedbefore > 1)

2623 newhasnulls = true;

2624 }

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

2626 {

2627

2628

2633 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2634 errmsg("array size exceeds the maximum allowed (%d)",

2636 dimschanged = true;

2637 if (addedafter > 1)

2638 newhasnulls = true;

2639 }

2640 }

2641 else

2642 {

2643

2644

2645

2646

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

2648 {

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

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

2652 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

2654 }

2655 }

2656

2657

2658 if (dimschanged)

2659 {

2662 }

2663

2664

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

2666

2667

2669 {

2670

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

2672

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

2676 if (dnulls)

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

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

2680 }

2681

2682

2683

2684

2685

2686 if (newhasnulls && dnulls == NULL)

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

2690

2691

2692

2693

2694

2695

2696

2698

2700

2701

2702 if (dimschanged)

2703 {

2704 eah->ndims = ndim;

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

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

2707 }

2708

2709

2710 if (addedbefore > 0)

2711 {

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

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

2714 dvalues[i] = (Datum) 0;

2715 if (dnulls)

2716 {

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

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

2719 dnulls[i] = true;

2720 }

2721 eah->nelems += addedbefore;

2722 }

2723

2724

2725 if (addedafter > 0)

2726 {

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

2729 if (dnulls)

2730 {

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

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

2733 }

2734 eah->nelems += addedafter;

2735 }

2736

2737

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

2740 else

2741 oldValue = NULL;

2742

2743

2744 dvalues[offset] = dataValue;

2745 if (dnulls)

2746 dnulls[offset] = isNull;

2747

2748

2749

2750

2751

2752

2753 if (oldValue)

2754 {

2755

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

2757 pfree(oldValue);

2758 }

2759

2760

2762}

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

2807 int nSubscripts,

2808 int *upperIndx,

2809 int *lowerIndx,

2810 bool *upperProvided,

2811 bool *lowerProvided,

2812 Datum srcArrayDatum,

2813 bool isNull,

2814 int arraytyplen,

2815 int elmlen,

2816 bool elmbyval,

2817 char elmalign)

2818{

2822 int i,

2823 ndim,

2827 bool newhasnulls;

2829 nsrcitems,

2830 olddatasize,

2831 newsize,

2832 olditemsize,

2833 newitemsize,

2834 overheadlen,

2835 oldoverheadlen,

2836 addedbefore,

2837 addedafter,

2838 lenbefore,

2839 lenafter,

2840 itemsbefore,

2841 itemsafter,

2842 nolditems;

2843

2844

2845 if (isNull)

2846 return arraydatum;

2847

2848 if (arraytyplen > 0)

2849 {

2850

2851

2852

2854 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

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

2856 }

2857

2858

2861

2862

2863

2865

2866

2867

2868

2869

2870

2871 if (ndim == 0)

2872 {

2874 bool *dnulls;

2875 int nelems;

2877

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

2879 &dvalues, &dnulls, &nelems);

2880

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

2882 {

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

2885 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

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

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

2889

2890

2894 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2895 errmsg("array size exceeds the maximum allowed (%d)",

2897

2898 lb[i] = lowerIndx[i];

2899 }

2900

2901

2904 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

2906

2908 dim, lb, elmtype,

2909 elmlen, elmbyval, elmalign));

2910 }

2911

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

2914 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

2916

2917

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

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

2920

2922 addedbefore = addedafter = 0;

2923

2924

2925

2926

2927

2928

2929

2930 if (ndim == 1)

2931 {

2932 Assert(nSubscripts == 1);

2933 if (!lowerProvided[0])

2934 lowerIndx[0] = lb[0];

2935 if (!upperProvided[0])

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

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

2939 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

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

2942 {

2943

2944

2948 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2949 errmsg("array size exceeds the maximum allowed (%d)",

2951 lb[0] = lowerIndx[0];

2952 if (addedbefore > 1)

2953 newhasnulls = true;

2954 }

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

2956 {

2957

2958

2963 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

2964 errmsg("array size exceeds the maximum allowed (%d)",

2966 if (addedafter > 1)

2967 newhasnulls = true;

2968 }

2969 }

2970 else

2971 {

2972

2973

2974

2975

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

2977 {

2978 if (!lowerProvided[i])

2979 lowerIndx[i] = lb[i];

2980 if (!upperProvided[i])

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

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

2984 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

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

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

2989 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

2991 }

2992

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

2994 {

2995 lowerIndx[i] = lb[i];

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

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

2999 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

3001 }

3002 }

3003

3004

3007

3008

3009

3010

3011

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

3016 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

3018

3019

3020

3021

3022

3023 if (newhasnulls)

3025 else

3029 elmlen, elmbyval, elmalign);

3031 olddatasize = ARR_SIZE(array) - oldoverheadlen;

3032 if (ndim > 1)

3033 {

3034

3035

3036

3037

3040 ndim, dim, lb,

3041 lowerIndx, upperIndx,

3042 elmlen, elmbyval, elmalign);

3043 lenbefore = lenafter = 0;

3044 itemsbefore = itemsafter = nolditems = 0;

3045 }

3046 else

3047 {

3048

3049

3050

3051

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

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

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

3058

3059

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

3062 itemsbefore,

3063 elmlen, elmbyval, elmalign);

3064

3065 if (slicelb > sliceub)

3066 {

3067 nolditems = 0;

3068 olditemsize = 0;

3069 }

3070 else

3071 {

3072 nolditems = sliceub - slicelb + 1;

3074 itemsbefore, oldarraybitmap,

3075 nolditems,

3076 elmlen, elmbyval, elmalign);

3077 }

3078

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

3080 lenafter = olddatasize - lenbefore - olditemsize;

3081 }

3082

3083 newsize = overheadlen + olddatasize - olditemsize + newitemsize;

3084

3087 newarray->ndim = ndim;

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

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

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

3092

3093 if (ndim > 1)

3094 {

3095

3096

3097

3098

3100 ndim, dim, lb,

3101 lowerIndx, upperIndx,

3102 elmlen, elmbyval, elmalign);

3103 }

3104 else

3105 {

3106

3107 memcpy((char *) newarray + overheadlen,

3108 (char *) array + oldoverheadlen,

3109 lenbefore);

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

3112 newitemsize);

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

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

3115 lenafter);

3116

3117 if (newhasnulls)

3118 {

3121

3122

3124 oldnullbitmap, 0,

3125 itemsbefore);

3128 nsrcitems);

3129 array_bitmap_copy(newnullbitmap, addedbefore + itemsbefore + nolditems,

3130 oldnullbitmap, itemsbefore + nolditems,

3131 itemsafter);

3132 }

3133 }

3134

3136}

3137

3138

3139

3140

3141

3142

3143

3144

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

3148 bool *isNull)

3149{

3151 arraytyplen, elmlen, elmbyval, elmalign,

3152 isNull);

3153}

3154

3155

3156

3157

3158

3159

3160

3161

3164 Datum dataValue, bool isNull,

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

3166{

3168 nSubscripts, indx,

3169 dataValue, isNull,

3170 arraytyplen,

3171 elmlen, elmbyval, elmalign));

3172}

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

3204{

3208 bool *nulls;

3209 int *dim;

3210 int ndim;

3212 int i;

3213 int32 nbytes = 0;

3214 int32 dataoffset;

3215 bool hasnulls;

3216 Oid inpType;

3217 int inp_typlen;

3218 bool inp_typbyval;

3219 char inp_typalign;

3220 int typlen;

3221 bool typbyval;

3228

3233

3234

3236 {

3237

3239 }

3240

3241

3242

3243

3244

3245

3246 inp_extra = &amstate->inp_extra;

3247 ret_extra = &amstate->ret_extra;

3248

3250 {

3256 }

3257 inp_typlen = inp_extra->typlen;

3258 inp_typbyval = inp_extra->typbyval;

3259 inp_typalign = inp_extra->typalign;

3260

3262 {

3268 }

3269 typlen = ret_extra->typlen;

3270 typbyval = ret_extra->typbyval;

3272

3273

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

3276

3277

3279 hasnulls = false;

3280

3282 {

3283

3284 *transform_source =

3286 inp_typlen, inp_typbyval, inp_typalign);

3287

3288

3290

3291 if (nulls[i])

3292 hasnulls = true;

3293 else

3294 {

3295

3296 if (typlen == -1)

3298

3301

3304 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

3305 errmsg("array size exceeds the maximum allowed (%d)",

3307 }

3308 }

3309

3310

3311 if (hasnulls)

3312 {

3314 nbytes += dataoffset;

3315 }

3316 else

3317 {

3318 dataoffset = 0;

3320 }

3323 result->ndim = ndim;

3328

3332 false);

3333

3334

3335

3336

3339

3341}

3342

3343

3344

3345

3346

3347

3348

3349

3350

3351

3352

3353

3354

3355

3356

3357

3358

3359

3362 Oid elmtype,

3363 int elmlen, bool elmbyval, char elmalign)

3364{

3365 int dims[1];

3366 int lbs[1];

3367

3368 dims[0] = nelems;

3369 lbs[0] = 1;

3370

3372 elmtype, elmlen, elmbyval, elmalign);

3373}

3374

3375

3376

3377

3378

3379

3382{

3383 int elmlen;

3384 bool elmbyval;

3385 char elmalign;

3386

3387 switch (elmtype)

3388 {

3389 case CHAROID:

3390 elmlen = 1;

3391 elmbyval = true;

3392 elmalign = TYPALIGN_CHAR;

3393 break;

3394

3395 case CSTRINGOID:

3396 elmlen = -2;

3397 elmbyval = false;

3398 elmalign = TYPALIGN_CHAR;

3399 break;

3400

3401 case FLOAT4OID:

3402 elmlen = sizeof(float4);

3403 elmbyval = true;

3404 elmalign = TYPALIGN_INT;

3405 break;

3406

3407 case FLOAT8OID:

3408 elmlen = sizeof(float8);

3410 elmalign = TYPALIGN_DOUBLE;

3411 break;

3412

3413 case INT2OID:

3414 elmlen = sizeof(int16);

3415 elmbyval = true;

3416 elmalign = TYPALIGN_SHORT;

3417 break;

3418

3419 case INT4OID:

3420 elmlen = sizeof(int32);

3421 elmbyval = true;

3422 elmalign = TYPALIGN_INT;

3423 break;

3424

3425 case INT8OID:

3426 elmlen = sizeof(int64);

3428 elmalign = TYPALIGN_DOUBLE;

3429 break;

3430

3431 case NAMEOID:

3433 elmbyval = false;

3434 elmalign = TYPALIGN_CHAR;

3435 break;

3436

3437 case OIDOID:

3438 case REGTYPEOID:

3439 elmlen = sizeof(Oid);

3440 elmbyval = true;

3441 elmalign = TYPALIGN_INT;

3442 break;

3443

3444 case TEXTOID:

3445 elmlen = -1;

3446 elmbyval = false;

3447 elmalign = TYPALIGN_INT;

3448 break;

3449

3450 case TIDOID:

3452 elmbyval = false;

3453 elmalign = TYPALIGN_SHORT;

3454 break;

3455

3456 case XIDOID:

3458 elmbyval = true;

3459 elmalign = TYPALIGN_INT;

3460 break;

3461

3462 default:

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

3464

3465 elmlen = 0;

3466 elmbyval = false;

3467 elmalign = 0;

3468 }

3469

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

3471}

3472

3473

3474

3475

3476

3477

3478

3479

3480

3481

3482

3483

3484

3485

3486

3487

3488

3489

3490

3491

3492

3495 bool *nulls,

3496 int ndims,

3497 int *dims,

3498 int *lbs,

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

3500{

3502 bool hasnulls;

3504 int32 dataoffset;

3505 int i;

3506 int nelems;

3507

3508 if (ndims < 0)

3510 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

3514 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

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

3517

3518

3521

3522

3523 if (nelems <= 0)

3525

3526

3527 nbytes = 0;

3528 hasnulls = false;

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

3530 {

3531 if (nulls && nulls[i])

3532 {

3533 hasnulls = true;

3534 continue;

3535 }

3536

3537 if (elmlen == -1)

3541

3544 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

3545 errmsg("array size exceeds the maximum allowed (%d)",

3547 }

3548

3549

3550 if (hasnulls)

3551 {

3553 nbytes += dataoffset;

3554 }

3555 else

3556 {

3557 dataoffset = 0;

3559 }

3562 result->ndim = ndims;

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

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

3567

3569 elems, nulls, nelems,

3570 elmlen, elmbyval, elmalign,

3571 false);

3572

3573 return result;

3574}

3575

3576

3577

3578

3581{

3583

3586 result->ndim = 0;

3589 return result;

3590}

3591

3592

3593

3594

3595

3600{

3603

3607}

3608

3609

3610

3611

3612

3613

3614

3615

3616

3617

3618

3619

3620

3621

3622

3623

3624

3625

3626

3627

3628

3629

3630void

3632 Oid elmtype,

3633 int elmlen, bool elmbyval, char elmalign,

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

3635{

3637 bool *nulls;

3638 int nelems;

3639 char *p;

3641 int bitmask;

3642 int i;

3643

3645

3648 if (nullsp)

3649 *nullsp = nulls = (bool *) palloc0(nelems * sizeof(bool));

3650 else

3651 nulls = NULL;

3652 *nelemsp = nelems;

3653

3656 bitmask = 1;

3657

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

3659 {

3660

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

3662 {

3663 elems[i] = (Datum) 0;

3664 if (nulls)

3665 nulls[i] = true;

3666 else

3668 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

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

3670 }

3671 else

3672 {

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

3676 }

3677

3678

3679 if (bitmap)

3680 {

3681 bitmask <<= 1;

3682 if (bitmask == 0x100)

3683 {

3684 bitmap++;

3685 bitmask = 1;

3686 }

3687 }

3688 }

3689}

3690

3691

3692

3693

3694

3695

3696void

3698 Oid elmtype,

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

3700{

3701 int elmlen;

3702 bool elmbyval;

3703 char elmalign;

3704

3705 switch (elmtype)

3706 {

3707 case CHAROID:

3708 elmlen = 1;

3709 elmbyval = true;

3710 elmalign = TYPALIGN_CHAR;

3711 break;

3712

3713 case CSTRINGOID:

3714 elmlen = -2;

3715 elmbyval = false;

3716 elmalign = TYPALIGN_CHAR;

3717 break;

3718

3719 case FLOAT8OID:

3720 elmlen = sizeof(float8);

3722 elmalign = TYPALIGN_DOUBLE;

3723 break;

3724

3725 case INT2OID:

3726 elmlen = sizeof(int16);

3727 elmbyval = true;

3728 elmalign = TYPALIGN_SHORT;

3729 break;

3730

3731 case OIDOID:

3732 elmlen = sizeof(Oid);

3733 elmbyval = true;

3734 elmalign = TYPALIGN_INT;

3735 break;

3736

3737 case TEXTOID:

3738 elmlen = -1;

3739 elmbyval = false;

3740 elmalign = TYPALIGN_INT;

3741 break;

3742

3743 case TIDOID:

3745 elmbyval = false;

3746 elmalign = TYPALIGN_SHORT;

3747 break;

3748

3749 default:

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

3751

3752 elmlen = 0;

3753 elmbyval = false;

3754 elmalign = 0;

3755 }

3756

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

3758}

3759

3760

3761

3762

3763

3764

3765

3766bool

3768{

3769 int nelems;

3771 int bitmask;

3772

3773

3775 return false;

3776

3778

3780

3781

3782 while (nelems >= 8)

3783 {

3784 if (*bitmap != 0xFF)

3785 return true;

3786 bitmap++;

3787 nelems -= 8;

3788 }

3789

3790

3791 bitmask = 1;

3792 while (nelems > 0)

3793 {

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

3795 return true;

3796 bitmask <<= 1;

3797 nelems--;

3798 }

3799

3800 return false;

3801}

3802

3803

3804

3805

3806

3807

3808

3809

3810

3811

3812

3815{

3827 bool result = true;

3830 int typlen;

3831 bool typbyval;

3835 int i;

3836

3839 (errcode(ERRCODE_DATATYPE_MISMATCH),

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

3841

3842

3843 if (ndims1 != ndims2 ||

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

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

3846 result = false;

3847 else

3848 {

3849

3850

3851

3852

3853

3854

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

3856 if (typentry == NULL ||

3857 typentry->type_id != element_type)

3858 {

3863 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

3866 fcinfo->flinfo->fn_extra = typentry;

3867 }

3868 typlen = typentry->typlen;

3869 typbyval = typentry->typbyval;

3871

3872

3873

3874

3876 collation, NULL, NULL);

3877

3878

3882

3884 {

3887 bool isnull1;

3888 bool isnull2;

3889 bool oprresult;

3890

3891

3893 typlen, typbyval, typalign);

3895 typlen, typbyval, typalign);

3896

3897

3898

3899

3900 if (isnull1 && isnull2)

3901 continue;

3902 if (isnull1 || isnull2)

3903 {

3904 result = false;

3905 break;

3906 }

3907

3908

3909

3910

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

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

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

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

3915 locfcinfo->isnull = false;

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

3918 {

3919 result = false;

3920 break;

3921 }

3922 }

3923 }

3924

3925

3928

3930}

3931

3932

3933

3934

3935

3936

3937

3938

3939

3940

3941

3944{

3946}

3947

3950{

3952}

3953

3956{

3958}

3959

3962{

3964}

3965

3968{

3970}

3971

3974{

3976}

3977

3978

3979

3980

3981

3982

3983

3984static int

3986{

3998 int result = 0;

4000 int typlen;

4001 bool typbyval;

4003 int min_nitems;

4006 int i;

4007

4010 (errcode(ERRCODE_DATATYPE_MISMATCH),

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

4012

4013

4014

4015

4016

4017

4018

4020 if (typentry == NULL ||

4021 typentry->type_id != element_type)

4022 {

4027 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

4031 }

4032 typlen = typentry->typlen;

4033 typbyval = typentry->typbyval;

4035

4036

4037

4038

4040 collation, NULL, NULL);

4041

4042

4043 min_nitems = Min(nitems1, nitems2);

4046

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

4048 {

4051 bool isnull1;

4052 bool isnull2;

4053 int32 cmpresult;

4054

4055

4058

4059

4060

4061

4062 if (isnull1 && isnull2)

4063 continue;

4064 if (isnull1)

4065 {

4066

4067 result = 1;

4068 break;

4069 }

4070 if (isnull2)

4071 {

4072

4073 result = -1;

4074 break;

4075 }

4076

4077

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

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

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

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

4083

4084

4085 Assert(!locfcinfo->isnull);

4086

4087 if (cmpresult == 0)

4088 continue;

4089

4090 if (cmpresult < 0)

4091 {

4092

4093 result = -1;

4094 break;

4095 }

4096 else

4097 {

4098

4099 result = 1;

4100 break;

4101 }

4102 }

4103

4104

4105

4106

4107

4108

4109

4110 if (result == 0)

4111 {

4112 if (nitems1 != nitems2)

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

4114 else if (ndims1 != ndims2)

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

4116 else

4117 {

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

4119 {

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

4121 {

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

4123 break;

4124 }

4125 }

4126 if (result == 0)

4127 {

4130

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

4132 {

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

4134 {

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

4136 break;

4137 }

4138 }

4139 }

4140 }

4141 }

4142

4143

4146

4147 return result;

4148}

4149

4150

4151

4152

4153

4154

4155

4156

4159{

4168 int typlen;

4169 bool typbyval;

4171 int i;

4173

4174

4175

4176

4177

4178

4179

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

4181 if (typentry == NULL ||

4182 typentry->type_id != element_type)

4183 {

4188 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

4191

4192

4193

4194

4195

4196

4197

4198

4199 if (element_type == RECORDOID)

4200 {

4203

4205

4206

4207

4208

4209

4210

4211 record_typentry = palloc0(sizeof(*record_typentry));

4212 record_typentry->type_id = element_type;

4213

4214

4219

4221

4222 typentry = record_typentry;

4223 }

4224

4225 fcinfo->flinfo->fn_extra = typentry;

4226 }

4227

4228 typlen = typentry->typlen;

4229 typbyval = typentry->typbyval;

4231

4232

4233

4234

4237

4238

4241

4243 {

4245 bool isnull;

4247

4248

4250

4251 if (isnull)

4252 {

4253

4254 elthash = 0;

4255 }

4256 else

4257 {

4258

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

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

4262

4263 Assert(!locfcinfo->isnull);

4264 }

4265

4266

4267

4268

4269

4270

4271

4272

4273

4274

4275

4276

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

4278 }

4279

4280

4282

4284}

4285

4286

4287

4288

4289

4292{

4302 int typlen;

4303 bool typbyval;

4305 int i;

4307

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

4309 if (typentry == NULL ||

4310 typentry->type_id != element_type)

4311 {

4316 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

4319 fcinfo->flinfo->fn_extra = typentry;

4320 }

4321 typlen = typentry->typlen;

4322 typbyval = typentry->typbyval;

4324

4327

4328

4331

4333 {

4335 bool isnull;

4337

4338

4340

4341 if (isnull)

4342 {

4343 elthash = 0;

4344 }

4345 else

4346 {

4347

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

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

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

4353

4354 Assert(!locfcinfo->isnull);

4355 }

4356

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

4358 }

4359

4361

4363}

4364

4365

4366

4367

4368

4369

4370

4371

4372

4373

4374

4375

4376

4377

4378

4379

4380static bool

4382 bool matchall, void **fn_extra)

4383{

4385 bool result = matchall;

4388 int nelems1;

4390 bool *nulls2;

4391 int nelems2;

4392 int typlen;

4393 bool typbyval;

4395 int i;

4396 int j;

4398

4401 (errcode(ERRCODE_DATATYPE_MISMATCH),

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

4403

4404

4405

4406

4407

4408

4409

4411 if (typentry == NULL ||

4412 typentry->type_id != element_type)

4413 {

4418 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

4421 *fn_extra = typentry;

4422 }

4423 typlen = typentry->typlen;

4424 typbyval = typentry->typbyval;

4426

4427

4428

4429

4430

4431

4433 {

4434

4439 }

4440 else

4442 element_type, typlen, typbyval, typalign,

4443 &values2, &nulls2, &nelems2);

4444

4445

4446

4447

4449 collation, NULL, NULL);

4450

4451

4454

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

4456 {

4458 bool isnull1;

4459

4460

4462

4463

4464

4465

4466

4467

4468 if (isnull1)

4469 {

4470 if (matchall)

4471 {

4472 result = false;

4473 break;

4474 }

4475 continue;

4476 }

4477

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

4479 {

4480 Datum elt2 = values2[j];

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

4482 bool oprresult;

4483

4484 if (isnull2)

4485 continue;

4486

4487

4488

4489

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

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

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

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

4494 locfcinfo->isnull = false;

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

4497 break;

4498 }

4499

4500 if (j < nelems2)

4501 {

4502

4503 if (!matchall)

4504 {

4505 result = true;

4506 break;

4507 }

4508 }

4509 else

4510 {

4511

4512 if (matchall)

4513 {

4514 result = false;

4515 break;

4516 }

4517 }

4518 }

4519

4520 return result;

4521}

4522

4525{

4529 bool result;

4530

4532 &fcinfo->flinfo->fn_extra);

4533

4534

4537

4539}

4540

4543{

4547 bool result;

4548

4550 &fcinfo->flinfo->fn_extra);

4551

4552

4555

4557}

4558

4561{

4565 bool result;

4566

4568 &fcinfo->flinfo->fn_extra);

4569

4570

4573

4575}

4576

4577

4578

4579

4580

4581

4582

4583

4584

4585

4586

4587

4588

4589

4590

4591

4592

4593

4594

4595

4598{

4600

4601

4602

4603

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

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

4607

4608

4609

4610

4611 iterator->arr = arr;

4614

4615 if (mstate != NULL)

4616 {

4618

4622 }

4623 else

4628

4629

4630

4631

4633

4634 if (slice_ndim > 0)

4635 {

4636

4637

4638

4639

4640

4643

4644

4645

4646

4649

4650

4651

4652

4657 }

4658

4659

4660

4661

4662

4665

4666 return iterator;

4667}

4668

4669

4670

4671

4672

4673

4674

4675bool

4677{

4678

4680 return false;

4681

4683 {

4684

4685

4686

4688 {

4689 *isnull = true;

4691 }

4692 else

4693 {

4694

4695 char *p = iterator->data_ptr;

4696

4697 *isnull = false;

4699

4700

4704 }

4705 }

4706 else

4707 {

4708

4709

4710

4714 char *p = iterator->data_ptr;

4715 int i;

4716

4718 {

4721 {

4722 nulls[i] = true;

4724 }

4725 else

4726 {

4727 nulls[i] = false;

4729

4730

4733 }

4734 }

4735

4737

4739 nulls,

4747

4748 *isnull = false;

4750 }

4751

4752 return true;

4753}

4754

4755

4756

4757

4758void

4760{

4762 {

4765 }

4766 pfree(iterator);

4767}

4768

4769

4770

4771

4772

4773

4774

4775

4776

4777

4778

4779

4780static bool

4782{

4783 if (nullbitmap == NULL)

4784 return false;

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

4786 return false;

4787 return true;

4788}

4789

4790

4791

4792

4793

4794

4795

4796

4797static void

4799{

4800 int bitmask;

4801

4802 nullbitmap += offset / 8;

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

4804 if (isNull)

4805 *nullbitmap &= ~bitmask;

4806 else

4807 *nullbitmap |= bitmask;

4808}

4809

4810

4811

4812

4813

4814

4817{

4819}

4820

4821

4822

4823

4824

4825

4826static int

4828 int typlen,

4829 bool typbyval,

4832{

4833 int inc;

4834

4835 if (typlen > 0)

4836 {

4837 if (typbyval)

4839 else

4842 }

4843 else

4844 {

4849 }

4850

4851 return inc;

4852}

4853

4854

4855

4856

4857

4858

4859

4860

4861

4862

4863

4864

4865static char *

4867 int typlen, bool typbyval, char typalign)

4868{

4869 int bitmask;

4870 int i;

4871

4872

4873 if (typlen > 0 && !nullbitmap)

4875

4876

4877 if (nullbitmap)

4878 {

4879 nullbitmap += offset / 8;

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

4881

4883 {

4884 if (*nullbitmap & bitmask)

4885 {

4888 }

4889 bitmask <<= 1;

4890 if (bitmask == 0x100)

4891 {

4892 nullbitmap++;

4893 bitmask = 1;

4894 }

4895 }

4896 }

4897 else

4898 {

4900 {

4903 }

4904 }

4905 return ptr;

4906}

4907

4908

4909

4910

4911

4912

4913static int

4915 int typlen, bool typbyval, char typalign)

4916{

4918 typlen, typbyval, typalign) - ptr;

4919}

4920

4921

4922

4923

4924

4925

4926

4927

4928

4929

4930

4931

4932

4933

4934

4935static int

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

4938 int typlen, bool typbyval, char typalign)

4939{

4940 int numbytes;

4941

4943 typlen, typbyval, typalign);

4944 memcpy(destptr, srcptr, numbytes);

4945 return numbytes;

4946}

4947

4948

4949

4950

4951

4952

4953

4954

4955

4956

4957

4958

4959

4960

4961

4962

4963

4964

4965void

4967 const bits8 *srcbitmap, int srcoffset,

4969{

4970 int destbitmask,

4971 destbitval,

4972 srcbitmask,

4973 srcbitval;

4974

4977 return;

4978 destbitmap += destoffset / 8;

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

4980 destbitval = *destbitmap;

4981 if (srcbitmap)

4982 {

4983 srcbitmap += srcoffset / 8;

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

4985 srcbitval = *srcbitmap;

4986 while (nitems-- > 0)

4987 {

4988 if (srcbitval & srcbitmask)

4989 destbitval |= destbitmask;

4990 else

4991 destbitval &= ~destbitmask;

4992 destbitmask <<= 1;

4993 if (destbitmask == 0x100)

4994 {

4995 *destbitmap++ = destbitval;

4996 destbitmask = 1;

4998 destbitval = *destbitmap;

4999 }

5000 srcbitmask <<= 1;

5001 if (srcbitmask == 0x100)

5002 {

5003 srcbitmap++;

5004 srcbitmask = 1;

5006 srcbitval = *srcbitmap;

5007 }

5008 }

5009 if (destbitmask != 1)

5010 *destbitmap = destbitval;

5011 }

5012 else

5013 {

5014 while (nitems-- > 0)

5015 {

5016 destbitval |= destbitmask;

5017 destbitmask <<= 1;

5018 if (destbitmask == 0x100)

5019 {

5020 *destbitmap++ = destbitval;

5021 destbitmask = 1;

5023 destbitval = *destbitmap;

5024 }

5025 }

5026 if (destbitmask != 1)

5027 *destbitmap = destbitval;

5028 }

5029}

5030

5031

5032

5033

5034

5035

5036static int

5038 int ndim, int *dim, int *lb,

5039 int *st, int *endp,

5040 int typlen, bool typbyval, char typalign)

5041{

5042 int src_offset,

5047 char *ptr;

5048 int i,

5049 j,

5050 inc;

5051 int count = 0;

5052

5054

5055

5056 if (typlen > 0 && !arraynullsptr)

5058

5059

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

5062 typlen, typbyval, typalign);

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

5066 indx[i] = 0;

5067 j = ndim - 1;

5068 do

5069 {

5070 if (dist[j])

5071 {

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

5073 typlen, typbyval, typalign);

5074 src_offset += dist[j];

5075 }

5077 {

5080 ptr += inc;

5081 count += inc;

5082 }

5083 src_offset++;

5085 return count;

5086}

5087

5088

5089

5090

5091

5092

5093

5094

5095

5096static void

5098 int ndim,

5099 int *dim,

5100 int *lb,

5101 char *arraydataptr,

5102 bits8 *arraynullsptr,

5103 int *st,

5104 int *endp,

5105 int typlen,

5106 bool typbyval,

5108{

5111 char *srcdataptr;

5112 int src_offset,

5113 dest_offset,

5118 int i,

5119 j,

5120 inc;

5121

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

5124 typlen, typbyval, typalign);

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

5129 indx[i] = 0;

5130 dest_offset = 0;

5131 j = ndim - 1;

5132 do

5133 {

5134 if (dist[j])

5135 {

5136

5137 srcdataptr = array_seek(srcdataptr, src_offset, arraynullsptr,

5138 dist[j],

5139 typlen, typbyval, typalign);

5140 src_offset += dist[j];

5141 }

5143 srcdataptr, src_offset, arraynullsptr,

5144 typlen, typbyval, typalign);

5145 if (destnullsptr)

5147 arraynullsptr, src_offset,

5148 1);

5149 destdataptr += inc;

5150 srcdataptr += inc;

5151 src_offset++;

5152 dest_offset++;

5154}

5155

5156

5157

5158

5159

5160

5161

5162

5163

5164

5165

5166

5167

5168

5169static void

5173 int ndim,

5174 int *dim,

5175 int *lb,

5176 int *st,

5177 int *endp,

5178 int typlen,

5179 bool typbyval,

5181{

5190 int dest_offset,

5191 orig_offset,

5192 src_offset,

5197 int i,

5198 j,

5199 inc;

5200

5202

5203 inc = array_copy(destPtr, dest_offset,

5204 origPtr, 0, origBitmap,

5205 typlen, typbyval, typalign);

5206 destPtr += inc;

5207 origPtr += inc;

5208 if (destBitmap)

5210 orig_offset = dest_offset;

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

5215 indx[i] = 0;

5216 src_offset = 0;

5217 j = ndim - 1;

5218 do

5219 {

5220

5221 if (dist[j])

5222 {

5224 origPtr, orig_offset, origBitmap,

5225 typlen, typbyval, typalign);

5226 destPtr += inc;

5227 origPtr += inc;

5228 if (destBitmap)

5230 origBitmap, orig_offset,

5231 dist[j]);

5232 dest_offset += dist[j];

5233 orig_offset += dist[j];

5234 }

5235

5237 srcPtr, src_offset, srcBitmap,

5238 typlen, typbyval, typalign);

5239 if (destBitmap)

5241 srcBitmap, src_offset,

5242 1);

5243 destPtr += inc;

5244 srcPtr += inc;

5245 dest_offset++;

5246 src_offset++;

5247

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

5249 typlen, typbyval, typalign);

5250 orig_offset++;

5252

5253

5254 array_copy(destPtr, orignitems - orig_offset,

5255 origPtr, orig_offset, origBitmap,

5256 typlen, typbyval, typalign);

5257 if (destBitmap)

5259 origBitmap, orig_offset,

5260 orignitems - orig_offset);

5261}

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

5294{

5295

5296

5297

5298

5299

5301 subcontext ? 64 : 8);

5302}

5303

5304

5305

5306

5307

5308

5311 bool subcontext, int initsize)

5312{

5315

5316

5317 if (subcontext)

5319 "accumArrayResult",

5321

5324 astate->mcontext = arr_context;

5326 astate->alen = initsize;

5329 astate->dnulls = (bool *)

5337

5338 return astate;

5339}

5340

5341

5342

5343

5344

5345

5346

5347

5348

5351 Datum dvalue, bool disnull,

5352 Oid element_type,

5354{

5356

5357 if (astate == NULL)

5358 {

5359

5361 }

5362 else

5363 {

5365 }

5366

5368

5369

5371 {

5372 astate->alen *= 2;

5373

5376 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

5377 errmsg("array size exceeds the maximum allowed (%d)",

5381 astate->dnulls = (bool *)

5383 }

5384

5385

5386

5387

5388

5389

5390

5391

5392

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

5394 {

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

5397 else

5399 }

5400

5404

5406

5407 return astate;

5408}

5409

5410

5411

5412

5413

5414

5415

5416

5417

5418

5422{

5423 int ndims;

5424 int dims[1];

5425 int lbs[1];

5426

5427

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

5429 dims[0] = astate->nelems;

5430 lbs[0] = 1;

5431

5434}

5435

5436

5437

5438

5439

5440

5441

5442

5443

5444

5445

5446

5447

5448

5449

5450

5453 int ndims,

5454 int *dims,

5455 int *lbs,

5457 bool release)

5458{

5461

5462

5464

5467 ndims,

5468 dims,

5469 lbs,

5474

5476

5477

5478 if (release)

5479 {

5482 }

5483

5485}

5486

5487

5488

5489

5490

5491

5492

5493

5494

5495

5496

5497

5498

5499

5500

5501

5502

5505 bool subcontext)

5506{

5508 MemoryContext arr_context = rcontext;

5509

5510

5512 {

5514

5517 (errcode(ERRCODE_DATATYPE_MISMATCH),

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

5520 }

5521

5522

5523 if (subcontext)

5525 "accumArrayResultArr",

5527

5528

5531 astate->mcontext = arr_context;

5533

5534

5537

5538 return astate;

5539}

5540

5541

5542

5543

5544

5545

5546

5547

5548

5551 Datum dvalue, bool disnull,

5552 Oid array_type,

5554{

5557 int *dims,

5558 *lbs,

5559 ndims,

5561 ndatabytes;

5563 int i;

5564

5565

5566

5567

5568

5569

5570 if (disnull)

5572 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

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

5574

5575

5577

5578 if (astate == NULL)

5580 else

5582

5584

5585

5592

5593 if (astate->ndims == 0)

5594 {

5595

5596

5597

5598 if (ndims == 0)

5600 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

5602 if (ndims + 1 > MAXDIM)

5604 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

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

5606 ndims + 1, MAXDIM)));

5607

5608

5609

5610

5611

5612 astate->ndims = ndims + 1;

5613 astate->dims[0] = 0;

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

5615 astate->lbs[0] = 1;

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

5617

5618

5621 }

5622 else

5623 {

5624

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

5627 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

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

5630 {

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

5633 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

5635 }

5636

5637

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

5639 {

5641 astate->nbytes + ndatabytes);

5643 }

5644 }

5645

5646

5647

5648

5649

5650

5651

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

5653 astate->nbytes += ndatabytes;

5654

5655

5657 {

5659

5661 {

5662

5663

5664

5665

5669 NULL, 0,

5671 }

5672 else if (newnitems > astate->aitems)

5673 {

5677 }

5681 }

5682

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

5685

5687

5688

5691

5692 return astate;

5693}

5694

5695

5696

5697

5698

5699

5700

5701

5705 bool release)

5706{

5709

5710

5712

5713 if (astate->ndims == 0)

5714 {

5715

5717 }

5718 else

5719 {

5720 int dataoffset,

5721 nbytes;

5722

5723

5726

5727

5728 nbytes = astate->nbytes;

5730 {

5732 nbytes += dataoffset;

5733 }

5734 else

5735 {

5736 dataoffset = 0;

5738 }

5739

5745

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

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

5749

5754 }

5755

5757

5758

5759 if (release)

5760 {

5763 }

5764

5766}

5767

5768

5769

5770

5771

5772

5773

5774

5775

5776

5777

5778

5779

5780

5783{

5785

5786

5787

5788

5789

5790

5791

5793 {

5794

5796

5803 }

5804 else

5805 {

5806

5808

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

5815 }

5816

5817 return astate;

5818}

5819

5820

5821

5822

5823

5824

5825

5826

5827

5830 Datum dvalue, bool disnull,

5831 Oid input_type,

5833{

5834 if (astate == NULL)

5836

5839 dvalue, disnull,

5840 input_type, rcontext);

5841 else

5843 dvalue, disnull,

5844 input_type, rcontext);

5845

5846 return astate;

5847}

5848

5849

5850

5851

5852

5853

5854

5855

5859{

5861

5863 {

5864

5865 int ndims;

5866 int dims[1];

5867 int lbs[1];

5868

5869

5872 lbs[0] = 1;

5873

5875 rcontext, release);

5876 }

5877 else

5878 {

5880 rcontext, release);

5881 }

5882 return result;

5883}

5884

5885

5888{

5891 else

5893}

5894

5897{

5900 else

5902}

5903

5904

5906{

5911

5912

5913

5914

5915

5918{

5922

5923

5925 {

5928 int *lb,

5929 *dimv;

5930

5931

5933

5934

5937

5938

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

5941

5942

5943

5944

5947

5950

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

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

5954

5956

5958 }

5959

5961

5963

5965 {

5968 else

5970 }

5971 else

5972

5974}

5975

5976

5977

5978

5979

5982{

5983

5985}

5986

5987

5988

5989

5990

5993{

5997 Oid elmtype;

5999 bool isnull;

6000

6003 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

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

6005

6008

6010 {

6012 isnull = false;

6013 }

6014 else

6015 {

6017 isnull = true;

6018 }

6019

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

6023

6026}

6027

6028

6029

6030

6031

6034{

6037 Oid elmtype;

6039 bool isnull;

6040

6043 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

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

6045

6047

6049 {

6051 isnull = false;

6052 }

6053 else

6054 {

6056 isnull = true;

6057 }

6058

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

6062

6065}

6066

6069 Oid elmtype, int dataoffset)

6070{

6072

6075 result->ndim = ndims;

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

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

6080

6081 return result;

6082}

6083

6088{

6090 int *dimv;

6091 int *lbsv;

6092 int ndims;

6096 bool elmbyval;

6097 char elmalign;

6099

6100

6101

6102

6105 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

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

6108

6111 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

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

6113

6116

6117 if (ndims < 0)

6119 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

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

6123 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

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

6126

6127 if (lbs != NULL)

6128 {

6131 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

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

6134

6137 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

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

6139

6142 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

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

6145

6147 }

6148 else

6149 {

6150 int i;

6151

6153 deflbs[i] = 1;

6154

6155 lbsv = deflbs;

6156 }

6157

6158

6161

6162

6165

6166

6167

6168

6169

6171 if (my_extra == NULL)

6172 {

6177 }

6178

6180 {

6181

6187 }

6188

6189 elmlen = my_extra->typlen;

6190 elmbyval = my_extra->typbyval;

6191 elmalign = my_extra->typalign;

6192

6193

6194 if (!isnull)

6195 {

6196 int i;

6197 char *p;

6198 int nbytes;

6199 int totbytes;

6200

6201

6202 if (elmlen == -1)

6204

6208

6209 totbytes = nbytes * nitems;

6210

6211

6212 if (totbytes / nbytes != nitems ||

6215 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

6216 errmsg("array size exceeds the maximum allowed (%d)",

6218

6219

6220

6221

6222

6224

6226 elmtype, 0);

6227

6231 }

6232 else

6233 {

6234 int nbytes;

6235 int dataoffset;

6236

6238 nbytes = dataoffset;

6239

6241 elmtype, dataoffset);

6242

6243

6244 }

6245

6246 return result;

6247}

6248

6249

6250

6251

6252

6255{

6256 typedef struct

6257 {

6259 int nextelem;

6260 int numelems;

6262 bool elmbyval;

6263 char elmalign;

6264 } array_unnest_fctx;

6265

6267 array_unnest_fctx *fctx;

6269

6270

6272 {

6274

6275

6277

6278

6279

6280

6282

6283

6284

6285

6286

6287

6288

6289

6291

6292

6293 fctx = (array_unnest_fctx *) palloc(sizeof(array_unnest_fctx));

6294

6295

6297 fctx->nextelem = 0;

6299

6301 {

6302

6306 }

6307 else

6309 &fctx->elmlen,

6310 &fctx->elmbyval,

6311 &fctx->elmalign);

6312

6315 }

6316

6317

6320

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

6322 {

6323 int offset = fctx->nextelem++;

6325

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

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

6328

6330 }

6331 else

6332 {

6333

6335 }

6336}

6337

6338

6339

6340

6341

6342

6343

6346{

6348 Node *ret = NULL;

6349

6351 {

6352

6354

6356 {

6359

6360

6362

6364 ret = (Node *) req;

6365 }

6366 }

6367

6369}

6370

6371

6372

6373

6374

6375

6376

6377

6378

6379

6382 Datum search, bool search_isnull,

6383 Datum replace, bool replace_isnull,

6384 bool remove, Oid collation,

6386{

6389 Oid element_type;

6391 bool *nulls;

6392 int *dim;

6393 int ndim;

6395 nresult;

6396 int i;

6397 int32 nbytes = 0;

6398 int32 dataoffset;

6399 bool hasnulls;

6400 int typlen;

6401 bool typbyval;

6403 char *arraydataptr;

6405 int bitmask;

6406 bool changed = false;

6408

6413

6414

6416 return array;

6417

6418

6419

6420

6421

6422 if (remove && ndim > 1)

6424 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

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

6426

6427

6428

6429

6430

6432 if (typentry == NULL ||

6433 typentry->type_id != element_type)

6434 {

6439 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

6443 }

6444 typlen = typentry->typlen;

6445 typbyval = typentry->typbyval;

6447

6448

6449

6450

6451

6452

6453 if (typlen == -1)

6454 {

6455 if (!search_isnull)

6457 if (!replace_isnull)

6459 }

6460

6461

6463 collation, NULL, NULL);

6464

6465

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

6468

6469

6472 bitmask = 1;

6473 hasnulls = false;

6474 nresult = 0;

6475

6477 {

6479 bool isNull;

6480 bool oprresult;

6481 bool skip = false;

6482

6483

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

6485 {

6486 isNull = true;

6487

6488 if (search_isnull)

6489 {

6490 if (remove)

6491 {

6492 skip = true;

6493 changed = true;

6494 }

6495 else if (!replace_isnull)

6496 {

6497 values[nresult] = replace;

6498 isNull = false;

6499 changed = true;

6500 }

6501 }

6502 }

6503 else

6504 {

6505 isNull = false;

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

6509

6510 if (search_isnull)

6511 {

6512

6513 values[nresult] = elt;

6514 }

6515 else

6516 {

6517

6518

6519

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

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

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

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

6524 locfcinfo->isnull = false;

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

6527 {

6528

6529 values[nresult] = elt;

6530 }

6531 else

6532 {

6533

6534 changed = true;

6535 if (remove)

6536 skip = true;

6537 else

6538 {

6539 values[nresult] = replace;

6540 isNull = replace_isnull;

6541 }

6542 }

6543 }

6544 }

6545

6547 {

6548 nulls[nresult] = isNull;

6549 if (isNull)

6550 hasnulls = true;

6551 else

6552 {

6553

6556

6559 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

6560 errmsg("array size exceeds the maximum allowed (%d)",

6562 }

6563 nresult++;

6564 }

6565

6566

6567 if (bitmap)

6568 {

6569 bitmask <<= 1;

6570 if (bitmask == 0x100)

6571 {

6572 bitmap++;

6573 bitmask = 1;

6574 }

6575 }

6576 }

6577

6578

6579

6580

6581 if (!changed)

6582 {

6585 return array;

6586 }

6587

6588

6589 if (nresult == 0)

6590 {

6594 }

6595

6596

6597 if (hasnulls)

6598 {

6600 nbytes += dataoffset;

6601 }

6602 else

6603 {

6604 dataoffset = 0;

6606 }

6609 result->ndim = ndim;

6611 result->elemtype = element_type;

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

6614

6615 if (remove)

6616 {

6617

6618 ARR_DIMS(result)[0] = nresult;

6619 }

6620

6621

6623 values, nulls, nresult,

6625 false);

6626

6629

6630 return result;

6631}

6632

6633

6634

6635

6636

6637

6640{

6644

6648

6650 search, search_isnull,

6651 (Datum) 0, true,

6653 fcinfo);

6655}

6656

6657

6658

6659

6662{

6668

6672

6674 search, search_isnull,

6675 replace, replace_isnull,

6677 fcinfo);

6679}

6680

6681

6682

6683

6684

6685

6686

6687

6688

6691{

6696 int result;

6697

6698

6699 if (ARR_NDIM(thresholds) > 1)

6701 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

6703

6706 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

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

6708

6709

6710 if (element_type == FLOAT8OID)

6712 else

6713 {

6715

6716

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

6718 if (typentry == NULL ||

6719 typentry->type_id != element_type)

6720 {

6725 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

6728 fcinfo->flinfo->fn_extra = typentry;

6729 }

6730

6731

6732

6733

6734

6735 if (typentry->typlen > 0)

6737 collation, typentry);

6738 else

6740 collation, typentry);

6741 }

6742

6743

6745

6747}

6748

6749

6750

6751

6752static int

6754{

6756 float8 *thresholds_data;

6757 int left;

6758 int right;

6759

6760

6761

6762

6763

6765

6766 left = 0;

6768

6769

6770

6771

6772

6773

6774

6775

6776 if (isnan(op))

6777 return right;

6778

6779

6780 while (left < right)

6781 {

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

6783

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

6785 right = mid;

6786 else

6787 left = mid + 1;

6788 }

6789

6790 return left;

6791}

6792

6793

6794

6795

6796static int

6799 Oid collation,

6801{

6803 char *thresholds_data;

6804 int typlen = typentry->typlen;

6805 bool typbyval = typentry->typbyval;

6806 int left;

6807 int right;

6808

6809

6810

6811

6812

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

6814

6816 collation, NULL, NULL);

6817

6818

6819 left = 0;

6821 while (left < right)

6822 {

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

6824 char *ptr;

6825 int32 cmpresult;

6826

6827 ptr = thresholds_data + mid * typlen;

6828

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

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

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

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

6833

6835

6836

6837 Assert(!locfcinfo->isnull);

6838

6839 if (cmpresult < 0)

6840 right = mid;

6841 else

6842 left = mid + 1;

6843 }

6844

6845 return left;

6846}

6847

6848

6849

6850

6851static int

6854 Oid collation,

6856{

6858 char *thresholds_data;

6859 int typlen = typentry->typlen;

6860 bool typbyval = typentry->typbyval;

6862 int left;

6863 int right;

6864

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

6866

6868 collation, NULL, NULL);

6869

6870

6871 left = 0;

6873 while (left < right)

6874 {

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

6876 char *ptr;

6877 int i;

6878 int32 cmpresult;

6879

6880

6881 ptr = thresholds_data;

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

6883 {

6886 }

6887

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

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

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

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

6892

6894

6895

6896 Assert(!locfcinfo->isnull);

6897

6898 if (cmpresult < 0)

6899 right = mid;

6900 else

6901 {

6902 left = mid + 1;

6903

6904

6905

6906

6907

6908

6911 }

6912 }

6913

6914 return left;

6915}

6916

6917

6918

6919

6920

6923{

6928 bool elmbyval;

6929 char elmalign;

6932 bool lowerProvided[MAXDIM];

6933 bool upperProvided[MAXDIM];

6935

6936

6939 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),

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

6942

6943

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

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

6947 {

6949 upperProvided[0] = true;

6950 }

6951

6952

6954

6955

6957 upper, lower, upperProvided, lowerProvided,

6958 -1, elmlen, elmbyval, elmalign);

6959

6961}

#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)

bool array_contains_nulls(ArrayType *array)

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)

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

Datum array_dims(PG_FUNCTION_ARGS)

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)

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

Datum hash_array_extended(PG_FUNCTION_ARGS)

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

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)

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

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 PointerIsValid(pointer)

#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 repalloc_array(pointer, type, count)

#define palloc_array(type, count)

void fmgr_info(Oid functionId, FmgrInfo *finfo)

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

Datum Int64GetDatum(int64 X)

bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)

bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod, fmNodePtr 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[]

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

static uint32 DatumGetUInt32(Datum 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)

void resetStringInfo(StringInfo str)

void appendStringInfoChar(StringInfo str, char ch)

void initStringInfo(StringInfo str)

StringInfoData * StringInfo

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

struct PlannerInfo * root

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

#define VARATT_IS_EXTERNAL_EXPANDED(PTR)

#define SET_VARSIZE(PTR, len)

text * cstring_to_text(const char *s)