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