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

1

2

3

4

5

6

7

8

9

10

11

12

14

15#include "catalog/pg_operator_d.h"

29

30

31

32

33

35{

38

39

40

41

42

44{

48

49

50

51

52

54{

60

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

81{

83 Oid element_type;

86

87

89 if (my_extra == NULL)

90 {

96 }

97

98

101

102

104 {

106

109 }

110 else

111 {

112

114

117 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

118 errmsg("could not determine input data type")));

122 (errcode(ERRCODE_DATATYPE_MISMATCH),

123 errmsg("input data type is not an array")));

124

126 resultcxt,

127 my_extra);

128 }

129

130 return eah;

131}

132

133

134

135

136

137

140{

143 bool isNull;

145 int *dimv,

146 *lb;

147 int indx;

149

152 if (isNull)

153 newelem = (Datum) 0;

154 else

156

157 if (eah->ndims == 1)

158 {

159

161 dimv = eah->dims;

162

163

166 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),

167 errmsg("integer out of range")));

168 }

169 else if (eah->ndims == 0)

170 indx = 1;

171 else

173 (errcode(ERRCODE_DATA_EXCEPTION),

174 errmsg("argument must be empty or one-dimensional array")));

175

176

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

178

180 1, &indx, newelem, isNull,

182

184}

185

186

187

188

189

190

193{

195 Node *ret = NULL;

196

198 {

199

200

201

202

203

206

211 }

212

214}

215

216

217

218

219

220

223{

226 bool isNull;

228 int *lb;

229 int indx;

230 int lb0;

232

234 if (isNull)

235 newelem = (Datum) 0;

236 else

239

240 if (eah->ndims == 1)

241 {

242

244 lb0 = lb[0];

245

248 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),

249 errmsg("integer out of range")));

250 }

251 else if (eah->ndims == 0)

252 {

253 indx = 1;

254 lb0 = 1;

255 }

256 else

258 (errcode(ERRCODE_DATA_EXCEPTION),

259 errmsg("argument must be empty or one-dimensional array")));

260

261

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

263

265 1, &indx, newelem, isNull,

267

268

270 if (eah->ndims == 1)

271 {

272

273 eah->lbound[0] = lb0;

274 }

275

277}

278

279

280

281

282

283

286{

288 Node *ret = NULL;

289

291 {

292

293

294

295

296

299

304 }

305

307}

308

309

310

311

312

313

314

317{

319 *v2;

321 int *dims,

322 *lbs,

323 ndims,

325 ndatabytes,

326 nbytes;

327 int *dims1,

328 *lbs1,

329 ndims1,

330 nitems1,

331 ndatabytes1;

332 int *dims2,

333 *lbs2,

334 ndims2,

335 nitems2,

336 ndatabytes2;

337 int i;

338 char *dat1,

339 *dat2;

341 *bitmap2;

342 Oid element_type;

343 Oid element_type1;

344 Oid element_type2;

345 int32 dataoffset;

346

347

349 {

354 }

356 {

359 }

360

363

366

367

368 if (element_type1 != element_type2)

370 (errcode(ERRCODE_DATATYPE_MISMATCH),

371 errmsg("cannot concatenate incompatible arrays"),

372 errdetail("Arrays with element types %s and %s are not "

373 "compatible for concatenation.",

376

377

378 element_type = element_type1;

379

380

381

382

383

384

385

386

387

388

391

392

393

394

395

396

397

398 if (ndims1 == 0 && ndims2 > 0)

400

401 if (ndims2 == 0)

403

404

405 if (ndims1 != ndims2 &&

406 ndims1 != ndims2 - 1 &&

407 ndims1 != ndims2 + 1)

409 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

410 errmsg("cannot concatenate incompatible arrays"),

411 errdetail("Arrays of %d and %d dimensions are not "

412 "compatible for concatenation.",

413 ndims1, ndims2)));

414

415

428

429 if (ndims1 == ndims2)

430 {

431

432

433

434

435 ndims = ndims1;

436 dims = (int *) palloc(ndims * sizeof(int));

437 lbs = (int *) palloc(ndims * sizeof(int));

438

439 dims[0] = dims1[0] + dims2[0];

440 lbs[0] = lbs1[0];

441

442 for (i = 1; i < ndims; i++)

443 {

444 if (dims1[i] != dims2[i] || lbs1[i] != lbs2[i])

446 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

447 errmsg("cannot concatenate incompatible arrays"),

448 errdetail("Arrays with differing element dimensions are "

449 "not compatible for concatenation.")));

450

451 dims[i] = dims1[i];

452 lbs[i] = lbs1[i];

453 }

454 }

455 else if (ndims1 == ndims2 - 1)

456 {

457

458

459

460

461 ndims = ndims2;

462 dims = (int *) palloc(ndims * sizeof(int));

463 lbs = (int *) palloc(ndims * sizeof(int));

464 memcpy(dims, dims2, ndims * sizeof(int));

465 memcpy(lbs, lbs2, ndims * sizeof(int));

466

467

468 dims[0] += 1;

469

470

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

472 {

473 if (dims1[i] != dims[i + 1] || lbs1[i] != lbs[i + 1])

475 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

476 errmsg("cannot concatenate incompatible arrays"),

477 errdetail("Arrays with differing dimensions are not "

478 "compatible for concatenation.")));

479 }

480 }

481 else

482 {

483

484

485

486

487

488

489 ndims = ndims1;

490 dims = (int *) palloc(ndims * sizeof(int));

491 lbs = (int *) palloc(ndims * sizeof(int));

492 memcpy(dims, dims1, ndims * sizeof(int));

493 memcpy(lbs, lbs1, ndims * sizeof(int));

494

495

496 dims[0] += 1;

497

498

499 for (i = 0; i < ndims2; i++)

500 {

501 if (dims2[i] != dims[i + 1] || lbs2[i] != lbs[i + 1])

503 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

504 errmsg("cannot concatenate incompatible arrays"),

505 errdetail("Arrays with differing dimensions are not "

506 "compatible for concatenation.")));

507 }

508 }

509

510

513

514

515 ndatabytes = ndatabytes1 + ndatabytes2;

517 {

519 nbytes = ndatabytes + dataoffset;

520 }

521 else

522 {

523 dataoffset = 0;

525 }

528 result->ndim = ndims;

530 result->elemtype = element_type;

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

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

533

534 memcpy(ARR_DATA_PTR(result), dat1, ndatabytes1);

535 memcpy(ARR_DATA_PTR(result) + ndatabytes1, dat2, ndatabytes2);

536

538 {

540 bitmap1, 0,

541 nitems1);

543 bitmap2, 0,

544 nitems2);

545 }

546

548}

549

550

551

552

553

556{

561

564 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

565 errmsg("could not determine input data type")));

566

567

568

569

570

571

572

574 {

575

576 elog(ERROR, "array_agg_transfn called in non-aggregate context");

577 }

578

581 else

583

585

587 elem,

589 arg1_typeid,

590 aggcontext);

591

592

593

594

595

596

598}

599

602{

607

609 elog(ERROR, "aggregate function called in non-aggregate context");

610

613

614 if (state2 == NULL)

615 {

616

617

618

619

620 if (state1 == NULL)

623 }

624

625 if (state1 == NULL)

626 {

627

629 false, state2->alen);

630

632

633 for (int i = 0; i < state2->nelems; i++)

634 {

639 else

641 }

642

644

645 memcpy(state1->dnulls, state2->dnulls, sizeof(bool) * state2->nelems);

646

648

650 }

651 else if (state2->nelems > 0)

652 {

653

654 int reqsize = state1->nelems + state2->nelems;

656

658

659

660 if (state1->alen < reqsize)

661 {

662

667 state1->alen * sizeof(bool));

668 }

669

670

671 for (int i = 0; i < state2->nelems; i++)

672 {

678 else

680 }

681

683 sizeof(bool) * state2->nelems);

684

685 state1->nelems = reqsize;

686

688 }

689

691}

692

693

694

695

696

699{

703

704

706

708

710

711

712

713

715

716

717

718

719

721

722

723

724

726

727

729

730

732

733

735

736

737

738

739

740

741

742

743 if (state->typbyval)

745 else

746 {

748 int i;

749

750

751 iodata = (SerialIOData *) fcinfo->flinfo->fn_extra;

752 if (iodata == NULL)

753 {

754 Oid typsend;

755 bool typisvarlena;

756

761 &typisvarlena);

763 fcinfo->flinfo->fn_mcxt);

764 fcinfo->flinfo->fn_extra = iodata;

765 }

766

767 for (i = 0; i < state->nelems; i++)

768 {

769 bytea *outputbytes;

770

771 if (state->dnulls[i])

772 continue;

778 }

779 }

780

782

784}

785

788{

792 Oid element_type;

794 const char *temp;

795

797 elog(ERROR, "aggregate function called in non-aggregate context");

798

800

801

802

803

804

807

808

810

811

813

814

816 false, nelems);

817 result->nelems = nelems;

818

819

821

822

824

825

827

828

830 memcpy(result->dnulls, temp, sizeof(bool) * nelems);

831

832

834 {

836 memcpy(result->dvalues, temp, sizeof(Datum) * nelems);

837 }

838 else

839 {

841

842

843 iodata = (DeserialIOData *) fcinfo->flinfo->fn_extra;

844 if (iodata == NULL)

845 {

846 Oid typreceive;

847

854 fcinfo->flinfo->fn_mcxt);

855 fcinfo->flinfo->fn_extra = iodata;

856 }

857

858 for (int i = 0; i < nelems; i++)

859 {

860 int itemlen;

862

864 {

866 continue;

867 }

868

870 if (itemlen < 0 || itemlen > (buf.len - buf.cursor))

872 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),

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

874

875

876

877

878

879

881

882 buf.cursor += itemlen;

883

884

886 &elem_buf,

888 -1);

889 }

890 }

891

893

895}

896

899{

902 int dims[1];

903 int lbs[1];

904

905

907

909

910 if (state == NULL)

911 PG_RETURN_NULL();

912

913 dims[0] = state->nelems;

914 lbs[0] = 1;

915

916

917

918

919

920

921

924 false);

925

927}

928

929

930

931

934{

938

941 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

942 errmsg("could not determine input data type")));

943

944

945

946

947

948

949

951 {

952

953 elog(ERROR, "array_agg_array_transfn called in non-aggregate context");

954 }

955

956

959 else

961

965 arg1_typeid,

966 aggcontext);

967

968

969

970

971

972

974}

975

978{

983

985 elog(ERROR, "aggregate function called in non-aggregate context");

986

989

990 if (state2 == NULL)

991 {

992

993

994

995

996 if (state1 == NULL)

999 }

1000

1001 if (state1 == NULL)

1002 {

1003

1005

1007 agg_context, false);

1008

1011

1013 {

1014 int size = (state2->aitems + 7) / 8;

1015

1018 }

1019

1025 memcpy(state1->dims, state2->dims, sizeof(state2->dims));

1026 memcpy(state1->lbs, state2->lbs, sizeof(state2->lbs));

1029

1031

1033 }

1034

1035

1036 else if (state2->nitems > 0)

1037 {

1039 int reqsize = state1->nbytes + state2->nbytes;

1040 int i;

1041

1042

1043

1044

1045

1046

1047

1050 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

1052

1053

1054 for (i = 1; i < state1->ndims; i++)

1055 {

1056 if (state1->dims[i] != state2->dims[i] || state1->lbs[i] != state2->lbs[i])

1058 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),

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

1060 }

1061

1062

1064

1065

1066

1067

1068

1069 if (state1->abytes < reqsize)

1070 {

1071

1074 }

1075

1077 {

1078 int newnitems = state1->nitems + state2->nitems;

1079

1081 {

1082

1083

1084

1085

1089 NULL, 0,

1091 }

1092 else if (newnitems > state1->aitems)

1093 {

1094 int newaitems = state1->aitems + state2->aitems;

1095

1099 }

1103 }

1104

1108

1109 state1->dims[0] += state2->dims[0];

1110

1111

1114

1116 }

1117

1119}

1120

1121

1122

1123

1124

1127{

1131

1132

1134

1136

1138

1139

1140

1141

1142

1144

1145

1147

1148

1150

1151

1153

1154

1156

1157

1159

1160

1161 if (state->nullbitmap)

1162 {

1165 }

1166

1167

1169

1170

1172

1173

1175

1176

1178

1180

1182}

1183

1186{

1190 Oid element_type;

1191 Oid array_type;

1192 int nbytes;

1193 const char *temp;

1194

1195

1197

1199

1200

1201

1202

1203

1206

1207

1209

1210

1212

1213

1215

1218

1219 result->abytes = 1024;

1220 while (result->abytes < nbytes)

1221 result->abytes *= 2;

1222

1224

1225

1227 memcpy(result->data, temp, nbytes);

1228 result->nbytes = nbytes;

1229

1230

1232

1233

1235

1236

1237 if (result->aitems > 0)

1238 {

1239 int size = (result->aitems + 7) / 8;

1240

1243 memcpy(result->nullbitmap, temp, size);

1244 }

1245 else

1247

1248

1250

1251

1253

1254

1256 memcpy(result->dims, temp, sizeof(result->dims));

1257

1258

1260 memcpy(result->lbs, temp, sizeof(result->lbs));

1261

1263

1265}

1266

1269{

1272

1273

1275

1277

1278 if (state == NULL)

1279 PG_RETURN_NULL();

1280

1281

1282

1283

1284

1285

1286

1288

1290}

1291

1292

1293

1294

1295

1296

1297

1298

1299

1302{

1304}

1305

1308{

1310}

1311

1312

1313

1314

1315

1316

1317

1318

1321{

1324 Oid element_type;

1325 Datum searched_element,

1327 bool isnull;

1328 int position,

1329 position_min;

1330 bool found = false;

1333 bool null_search;

1335

1338

1340

1341

1342

1343

1344

1347 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

1348 errmsg("searching for elements in multidimensional arrays is not supported")));

1349

1350

1353

1355 {

1356

1359 searched_element = (Datum) 0;

1360 null_search = true;

1361 }

1362 else

1363 {

1365 null_search = false;

1366 }

1367

1369 position = (ARR_LBOUND(array))[0] - 1;

1370

1371

1373 {

1376 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

1377 errmsg("initial position must not be null")));

1378

1380 }

1381 else

1382 position_min = (ARR_LBOUND(array))[0];

1383

1384

1385

1386

1387

1388

1390 if (my_extra == NULL)

1391 {

1396 }

1397

1399 {

1404

1406

1409 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

1412

1416 }

1417

1418

1421 {

1422 position++;

1423

1424

1425 if (position < position_min)

1426 continue;

1427

1428

1429

1430

1431

1432 if (isnull || null_search)

1433 {

1434 if (isnull && null_search)

1435 {

1436 found = true;

1437 break;

1438 }

1439 else

1440 continue;

1441 }

1442

1443

1445 searched_element, value)))

1446 {

1447 found = true;

1448 break;

1449 }

1450 }

1451

1453

1454

1456

1457 if (!found)

1459

1461}

1462

1463

1464

1465

1466

1467

1468

1469

1470

1471

1472

1473

1476{

1479 Oid element_type;

1480 Datum searched_element,

1482 bool isnull;

1483 int position;

1486 bool null_search;

1489

1492

1494

1495

1496

1497

1498

1501 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

1502 errmsg("searching for elements in multidimensional arrays is not supported")));

1503

1505

1506

1509

1511 {

1512

1515 searched_element = (Datum) 0;

1516 null_search = true;

1517 }

1518 else

1519 {

1521 null_search = false;

1522 }

1523

1525 position = (ARR_LBOUND(array))[0] - 1;

1526

1527

1528

1529

1530

1531

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

1533 if (my_extra == NULL)

1534 {

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

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

1539 }

1540

1542 {

1547

1549

1552 (errcode(ERRCODE_UNDEFINED_FUNCTION),

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

1555

1558 fcinfo->flinfo->fn_mcxt);

1559 }

1560

1561

1562

1563

1564

1567 {

1568 position += 1;

1569

1570

1571

1572

1573

1574 if (isnull || null_search)

1575 {

1576 if (isnull && null_search)

1577 astate =

1580

1581 continue;

1582 }

1583

1584

1586 searched_element, value)))

1587 astate =

1590 }

1591

1593

1594

1596

1598}

1599

1600

1601

1602

1603

1604

1605

1606

1607

1608

1609

1610

1611

1615{

1617 int ndim,

1618 *dims,

1619 *lbs,

1620 nelm,

1621 nitem,

1625 bool elmbyval;

1626 char elmalign;

1628 *ielms;

1629 bool *nuls,

1630 *inuls;

1631

1635

1636 elmlen = typentry->typlen;

1637 elmbyval = typentry->typbyval;

1638 elmalign = typentry->typalign;

1639

1640

1641 if (ndim < 1 || dims[0] < 1 || n < 1)

1643

1645 &elms, &nuls, &nelm);

1646

1647 nitem = dims[0];

1648 nelm /= nitem;

1649

1650 Assert(n <= nitem);

1651

1652

1653

1654

1655

1656

1657

1658 ielms = elms;

1659 inuls = nuls;

1660 for (int i = 0; i < n; i++)

1661 {

1663 Datum *jelms = elms + j;

1664 bool *jnuls = nuls + j;

1665

1666

1667 for (int k = 0; k < nelm; k++)

1668 {

1669 Datum elm = *ielms;

1670 bool nul = *inuls;

1671

1672 *ielms++ = *jelms;

1673 *inuls++ = *jnuls;

1674 *jelms++ = elm;

1675 *jnuls++ = nul;

1676 }

1677 }

1678

1679

1680 memcpy(rdims, dims, ndim * sizeof(int));

1681 memcpy(rlbs, lbs, ndim * sizeof(int));

1682 rdims[0] = n;

1683 if (!keep_lb)

1684 rlbs[0] = 1;

1685

1687 elmtyp, elmlen, elmbyval, elmalign);

1688

1691

1692 return result;

1693}

1694

1695

1696

1697

1698

1699

1700

1703{

1706 Oid elmtyp;

1708

1709

1710

1711

1712

1715

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

1718 if (typentry == NULL || typentry->type_id != elmtyp)

1719 {

1721 fcinfo->flinfo->fn_extra = typentry;

1722 }

1723

1725

1727}

1728

1729

1730

1731

1732

1733

1734

1737{

1741 Oid elmtyp;

1743 int nitem;

1744

1746

1747 if (n < 0 || n > nitem)

1749 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1750 errmsg("sample size must be between 0 and %d", nitem)));

1751

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

1754 if (typentry == NULL || typentry->type_id != elmtyp)

1755 {

1757 fcinfo->flinfo->fn_extra = typentry;

1758 }

1759

1760 result = array_shuffle_n(array, n, false, elmtyp, typentry);

1761

1763}

1764

1765

1766

1767

1768

1769

1770

1771

1772

1773

1776{

1778 int ndim,

1779 *dims,

1780 *lbs,

1781 nelm,

1782 nitem,

1786 bool elmbyval;

1787 char elmalign;

1789 *ielms;

1790 bool *nuls,

1791 *inuls;

1792

1796

1797 elmlen = typentry->typlen;

1798 elmbyval = typentry->typbyval;

1799 elmalign = typentry->typalign;

1800

1802 &elms, &nuls, &nelm);

1803

1804 nitem = dims[0];

1805 nelm /= nitem;

1806

1807

1808 ielms = elms;

1809 inuls = nuls;

1810 for (int i = 0; i < nitem / 2; i++)

1811 {

1812 int j = (nitem - i - 1) * nelm;

1813 Datum *jelms = elms + j;

1814 bool *jnuls = nuls + j;

1815

1816

1817 for (int k = 0; k < nelm; k++)

1818 {

1819 Datum elm = *ielms;

1820 bool nul = *inuls;

1821

1822 *ielms++ = *jelms;

1823 *inuls++ = *jnuls;

1824 *jelms++ = elm;

1825 *jnuls++ = nul;

1826 }

1827 }

1828

1829

1830 memcpy(rdims, dims, ndim * sizeof(int));

1831 memcpy(rlbs, lbs, ndim * sizeof(int));

1832 rdims[0] = nitem;

1833

1835 elmtyp, elmlen, elmbyval, elmalign);

1836

1839

1840 return result;

1841}

1842

1843

1844

1845

1846

1847

1848

1851{

1854 Oid elmtyp;

1856

1857

1858

1859

1860

1863

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

1866 if (typentry == NULL || typentry->type_id != elmtyp)

1867 {

1869 fcinfo->flinfo->fn_extra = (void *) typentry;

1870 }

1871

1873

1875}

1876

1877

1878

1879

1880

1881

1885{

1888 int ndim,

1889 *dims,

1890 *lbs;

1892 Oid elmtyp;

1893 Oid sort_typ;

1894 Oid sort_opr;

1898 bool isnull;

1900

1904

1905

1906 if (ndim < 1 || dims[0] < 2)

1907 return array;

1908

1909

1911 if (cache_info == NULL)

1912 {

1917 }

1918

1919

1922 {

1924

1934 }

1935

1936

1937 if (ndim == 1)

1938 {

1939

1940 sort_typ = elmtyp;

1942 }

1943 else

1944 {

1945

1949 (errcode(ERRCODE_UNDEFINED_OBJECT),

1950 errmsg("could not find array type for data type %s",

1952

1953 sort_opr = (descending ? ARRAY_GT_OP : ARRAY_LT_OP);

1954 }

1955

1956

1957

1958

1959

1962 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

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

1965

1966

1968 sort_opr,

1969 collation,

1970 nulls_first,

1972 NULL,

1974

1978 {

1980 }

1982

1983

1985

1986

1988 {

1991 }

1993

1996 true));

1997

1998

2000

2001 return newarray;

2002}

2003

2006{

2008

2010 false,

2011 false,

2012 fcinfo));

2013}

2014

2017{

2020

2022 descending,

2023 descending,

2024 fcinfo));

2025}

2026

2029{

2033

2035 descending,

2036 nulls_first,

2037 fcinfo));

2038}

static bool array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree **found)

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

#define PG_GETARG_EXPANDED_ARRAYX(n, metacache)

Datum array_sample(PG_FUNCTION_ARGS)

struct DeserialIOData DeserialIOData

Datum array_prepend(PG_FUNCTION_ARGS)

Datum array_agg_deserialize(PG_FUNCTION_ARGS)

Datum array_positions(PG_FUNCTION_ARGS)

static Datum array_position_common(FunctionCallInfo fcinfo)

Datum array_position(PG_FUNCTION_ARGS)

static ExpandedArrayHeader * fetch_array_arg_replace_nulls(FunctionCallInfo fcinfo, int argno)

struct SerialIOData SerialIOData

struct ArraySortCachedInfo ArraySortCachedInfo

Datum array_agg_combine(PG_FUNCTION_ARGS)

Datum array_sort(PG_FUNCTION_ARGS)

Datum array_reverse(PG_FUNCTION_ARGS)

Datum array_append(PG_FUNCTION_ARGS)

Datum array_agg_array_combine(PG_FUNCTION_ARGS)

Datum array_agg_serialize(PG_FUNCTION_ARGS)

Datum array_agg_array_deserialize(PG_FUNCTION_ARGS)

Datum array_append_support(PG_FUNCTION_ARGS)

Datum array_agg_finalfn(PG_FUNCTION_ARGS)

Datum array_agg_array_transfn(PG_FUNCTION_ARGS)

Datum array_position_start(PG_FUNCTION_ARGS)

static ArrayType * array_sort_internal(ArrayType *array, bool descending, bool nulls_first, FunctionCallInfo fcinfo)

Datum array_shuffle(PG_FUNCTION_ARGS)

Datum array_cat(PG_FUNCTION_ARGS)

static ArrayType * array_reverse_n(ArrayType *array, Oid elmtyp, TypeCacheEntry *typentry)

Datum array_sort_order(PG_FUNCTION_ARGS)

static ArrayType * array_shuffle_n(ArrayType *array, int n, bool keep_lb, Oid elmtyp, TypeCacheEntry *typentry)

Datum array_sort_order_nulls_first(PG_FUNCTION_ARGS)

Datum array_agg_transfn(PG_FUNCTION_ARGS)

Datum array_agg_array_finalfn(PG_FUNCTION_ARGS)

Datum array_agg_array_serialize(PG_FUNCTION_ARGS)

Datum array_prepend_support(PG_FUNCTION_ARGS)

bool array_contains_nulls(ArrayType *array)

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

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

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

void array_free_iterator(ArrayIterator iterator)

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

ArrayType * construct_empty_array(Oid elmtype)

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

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

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)

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

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

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

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)

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

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

Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)

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

int ArrayGetNItems(int ndim, const int *dims)

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

#define OidIsValid(objectId)

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

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

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

static Datum EOHPGetRWDatum(const struct ExpandedObjectHeader *eohptr)

Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)

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

bytea * SendFunctionCall(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_GETARG_BYTEA_PP(n)

#define PG_RETURN_BYTEA_P(x)

#define PG_GETARG_POINTER(n)

#define PG_GETARG_DATUM(n)

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

char * format_type_be(Oid type_oid)

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)

void getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)

Oid get_element_type(Oid typid)

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

void getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)

void * MemoryContextAlloc(MemoryContext context, Size size)

void * MemoryContextAllocZero(MemoryContext context, Size size)

void * repalloc(void *pointer, Size size)

void pfree(void *pointer)

void * palloc0(Size size)

MemoryContext CurrentMemoryContext

int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)

#define IsA(nodeptr, _type_)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

static uint32 pg_nextpower2_32(uint32 num)

uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)

pg_prng_state pg_global_prng_state

static bool DatumGetBool(Datum X)

static Datum Int32GetDatum(int32 X)

unsigned int pq_getmsgint(StringInfo msg, int b)

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

void pq_getmsgend(StringInfo msg)

void pq_begintypsend(StringInfo buf)

int pq_getmsgbyte(StringInfo msg)

int64 pq_getmsgint64(StringInfo msg)

const char * pq_getmsgbytes(StringInfo msg, int datalen)

bytea * pq_endtypsend(StringInfo buf)

static void pq_sendint32(StringInfo buf, uint32 i)

static void pq_sendbyte(StringInfo buf, uint8 byt)

static void pq_sendint64(StringInfo buf, uint64 i)

static void pq_sendint16(StringInfo buf, uint16 i)

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

ArrayMetaState array_meta

void tuplesort_performsort(Tuplesortstate *state)

void tuplesort_end(Tuplesortstate *state)

void tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)

Tuplesortstate * tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation, bool nullsFirstFlag, int workMem, SortCoordinate coordinate, int sortopt)

bool tuplesort_getdatum(Tuplesortstate *state, bool forward, bool copy, Datum *val, bool *isNull, Datum *abbrev)

TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)

#define TYPECACHE_EQ_OPR_FINFO

#define SET_VARSIZE(PTR, len)

#define VARSIZE_ANY_EXHDR(PTR)