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
77
78
79 int slice_ndim;
84 bool *slice_nulls;
85
86
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 {
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 }
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])
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
2115 {
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;
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 {
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;
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 {
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++)
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
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])
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
2994 {
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 {
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 {
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)