PostgreSQL Source Code: src/backend/utils/adt/arrayfuncs.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
17#include <ctype.h>
18#include <math.h>
19
34#include "utils/fmgroids.h"
39
40
41
42
43
45
46
47
48
49#define ASSGN "="
50
51#define AARR_FREE_IF_COPY(array,n) \
52 do { \
53 if (!VARATT_IS_EXPANDED_HEADER(array)) \
54 PG_FREE_IF_COPY(array, n); \
55 } while (0)
56
57
58typedef enum
59{
67
68
70{
71
78
79
80 int slice_ndim;
85 bool *slice_nulls;
86
87
89 int current_item;
91
93 int *dim, int *lBound,
94 const char *origStr, Node *escontext);
96 const char *origStr, Node *escontext);
99 char typdelim,
100 int typlen, bool typbyval, char typalign,
101 int *ndim_p, int *dim,
102 int *nitems_p,
103 Datum **values_p, bool **nulls_p,
104 const char *origStr, Node *escontext);
106 const char *origStr, Node *escontext);
109 int typlen, bool typbyval, char typalign,
111 bool *hasnulls, int32 *nbytes);
113 int nSubscripts, int *indx,
114 int arraytyplen,
115 int elmlen, bool elmbyval, char elmalign,
116 bool *isNull);
118 int nSubscripts, int *indx,
119 Datum dataValue, bool isNull,
120 int arraytyplen,
121 int elmlen, bool elmbyval, char elmalign);
126 int typlen, bool typbyval, char typalign,
129 int typlen, bool typbyval, char typalign);
131 int nitems, int typlen, bool typbyval, char typalign);
133 char *srcptr, int offset, bits8 *nullbitmap,
134 int typlen, bool typbyval, char typalign);
136 int ndim, int *dim, int *lb,
137 int *st, int *endp,
138 int typlen, bool typbyval, char typalign);
140 int ndim, int *dim, int *lb,
141 char *arraydataptr, bits8 *arraynullsptr,
142 int *st, int *endp,
143 int typlen, bool typbyval, char typalign);
146 int ndim, int *dim, int *lb,
147 int *st, int *endp,
148 int typlen, bool typbyval, char typalign);
151 Oid elmtype, int dataoffset);
156 Datum search, bool search_isnull,
157 Datum replace, bool replace_isnull,
158 bool remove, Oid collation,
163 Oid collation,
167 Oid collation,
169
170
171
172
173
174
175
176
177
178
181{
184
186 Node *escontext = fcinfo->context;
187 int typlen;
188 bool typbyval;
190 char typdelim;
191 Oid typioparam;
192 char *p;
195 bool *nulls;
196 bool hasnulls;
198 int32 dataoffset;
200 int ndim,
204
205
206
207
208
209
210 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
211 if (my_extra == NULL)
212 {
213 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
215 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
217 }
218
220 {
221
222
223
229 fcinfo->flinfo->fn_mcxt);
231 }
232 typlen = my_extra->typlen;
233 typbyval = my_extra->typbyval;
235 typdelim = my_extra->typdelim;
237
238
239
240
241
242
244 {
245 dim[i] = -1;
246 lBound[i] = 1;
247 }
248
249
250
251
252
253
254
257 return (Datum) 0;
258
259 if (ndim == 0)
260 {
261
262 if (*p != '{')
264 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
265 errmsg("malformed array literal: \"%s\"", string),
266 errdetail("Array value must start with \"{\" or dimension information.")));
267 }
268 else
269 {
270
271 if (strncmp(p, ASSGN, strlen(ASSGN)) != 0)
273 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
274 errmsg("malformed array literal: \"%s\"", string),
275 errdetail("Missing \"%s\" after array dimensions.",
277 p += strlen(ASSGN);
278
280 p++;
281
282 if (*p != '{')
284 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
285 errmsg("malformed array literal: \"%s\"", string),
286 errdetail("Array contents must start with \"{\".")));
287 }
288
289
291 &my_extra->proc, typioparam, typmod,
292 typdelim,
294 &ndim,
295 dim,
298 string,
299 escontext))
300 return (Datum) 0;
301
302
303 while (*p)
304 {
307 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
308 errmsg("malformed array literal: \"%s\"", string),
309 errdetail("Junk after closing right brace.")));
310 }
311
312
315
316
317
318
319 hasnulls = false;
320 nbytes = 0;
322 {
323 if (nulls[i])
324 hasnulls = true;
325 else
326 {
327
328 if (typlen == -1)
332
335 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
336 errmsg("array size exceeds the maximum allowed (%zu)",
338 }
339 }
340 if (hasnulls)
341 {
343 nbytes += dataoffset;
344 }
345 else
346 {
347 dataoffset = 0;
349 }
350
351
352
353
356 retval->ndim = ndim;
358
359
360
361
362
363
364 retval->elemtype = element_type;
365 memcpy(ARR_DIMS(retval), dim, ndim * sizeof(int));
366 memcpy(ARR_LBOUND(retval), lBound, ndim * sizeof(int));
367
371 true);
372
375
377}
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402static bool
404 const char *origStr, Node *escontext)
405{
406 char *p = *srcptr;
407 int ndim;
408
409
410
411
412
413 ndim = 0;
414 for (;;)
415 {
416 char *q;
417 int ub;
418 int i;
419
420
421
422
423
425 p++;
426 if (*p != '[')
427 break;
428 p++;
430 ereturn(escontext, false,
431 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
432 errmsg("number of array dimensions exceeds the maximum allowed (%d)",
434
435 q = p;
437 return false;
438 if (p == q)
439 ereturn(escontext, false,
440 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
441 errmsg("malformed array literal: \"%s\"", origStr),
442 errdetail("\"[\" must introduce explicitly-specified array dimensions.")));
443
444 if (*p == ':')
445 {
446
447 lBound[ndim] = i;
448 p++;
449 q = p;
451 return false;
452 if (p == q)
453 ereturn(escontext, false,
454 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
455 errmsg("malformed array literal: \"%s\"", origStr),
456 errdetail("Missing array dimension value.")));
457 }
458 else
459 {
460
461 lBound[ndim] = 1;
462 ub = i;
463 }
464 if (*p != ']')
465 ereturn(escontext, false,
466 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
467 errmsg("malformed array literal: \"%s\"", origStr),
468 errdetail("Missing \"%s\" after array dimensions.",
469 "]")));
470 p++;
471
472
473
474
475
476
477
478
479 if (ub < lBound[ndim])
480 ereturn(escontext, false,
481 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
482 errmsg("upper bound cannot be less than lower bound")));
483
484
485 if (ub == INT_MAX)
486 ereturn(escontext, false,
487 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
488 errmsg("array upper bound is too large: %d", ub)));
489
490
493 ereturn(escontext, false,
494 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
495 errmsg("array size exceeds the maximum allowed (%zu)",
497
498 dim[ndim] = ub;
499 ndim++;
500 }
501
502 *srcptr = p;
503 *ndim_p = ndim;
504 return true;
505}
506
507
508
509
510
511
512
513
514
515
516
517
518
519static bool
521 const char *origStr, Node *escontext)
522{
523 char *p = *srcptr;
524 long l;
525
526
527 if (!isdigit((unsigned char) *p) && *p != '-' && *p != '+')
528 {
529 *result = 0;
530 return true;
531 }
532
533 errno = 0;
534 l = strtol(p, srcptr, 10);
535
537 ereturn(escontext, false,
538 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
539 errmsg("array bound is out of integer range")));
540
541 *result = (int) l;
542 return true;
543}
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579static bool
582 Oid typioparam,
584 char typdelim,
585 int typlen,
586 bool typbyval,
588 int *ndim_p,
589 int *dim,
590 int *nitems_p,
591 Datum **values_p,
592 bool **nulls_p,
593 const char *origStr,
594 Node *escontext)
595{
596 int ndim = *ndim_p;
597 bool dimensions_specified = (ndim != 0);
598 int maxitems;
600 bool *nulls;
602 int nest_level;
604 bool ndim_frozen;
605 bool expect_delim;
607
608
609 maxitems = 16;
612
613
615
616
617 Assert(**srcptr == '{');
618
619
620 nest_level = 0;
622 ndim_frozen = dimensions_specified;
623 expect_delim = false;
624 do
625 {
627
628 tok = ReadArrayToken(srcptr, &elembuf, typdelim, origStr, escontext);
629
630 switch (tok)
631 {
633
634 if (expect_delim)
635 ereturn(escontext, false,
636 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
637 errmsg("malformed array literal: \"%s\"", origStr),
638 errdetail("Unexpected \"%c\" character.", '{')));
639
640
641 if (nest_level >= MAXDIM)
642 ereturn(escontext, false,
643 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
644 errmsg("number of array dimensions exceeds the maximum allowed (%d)",
646
647 nelems[nest_level] = 0;
648 nest_level++;
649 if (nest_level > ndim)
650 {
651
652 if (ndim_frozen)
653 goto dimension_error;
654 ndim = nest_level;
655 }
656 break;
657
659
660 Assert(nest_level > 0);
661
662
663
664
665
666 if (nelems[nest_level - 1] > 0 && !expect_delim)
667 ereturn(escontext, false,
668 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
669 errmsg("malformed array literal: \"%s\"", origStr),
670 errdetail("Unexpected \"%c\" character.",
671 '}')));
672 nest_level--;
673
674 if (nest_level > 0)
675 nelems[nest_level - 1]++;
676
677
678
679
680
681
682 if (dim[nest_level] < 0)
683 {
684
685 dim[nest_level] = nelems[nest_level];
686 }
687 else if (nelems[nest_level] != dim[nest_level])
688 {
689
690 goto dimension_error;
691 }
692
693
694
695
696
697 expect_delim = true;
698 break;
699
701 if (!expect_delim)
702 ereturn(escontext, false,
703 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
704 errmsg("malformed array literal: \"%s\"", origStr),
705 errdetail("Unexpected \"%c\" character.",
706 typdelim)));
707 expect_delim = false;
708 break;
709
712
713 Assert(nest_level > 0);
714
715
716 if (expect_delim)
717 ereturn(escontext, false,
718 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
719 errmsg("malformed array literal: \"%s\"", origStr),
720 errdetail("Unexpected array element.")));
721
722
723 if (nitems >= maxitems)
724 {
726 ereturn(escontext, false,
727 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
728 errmsg("array size exceeds the maximum allowed (%zu)",
733 }
734
735
738 typioparam, typmod,
739 escontext,
741 return false;
744
745
746
747
748
749
750 ndim_frozen = true;
751 if (nest_level != ndim)
752 goto dimension_error;
753
754 nelems[nest_level - 1]++;
755
756
757 expect_delim = true;
758 break;
759
761 return false;
762 }
763 } while (nest_level > 0);
764
765
767
768 *ndim_p = ndim;
771 *nulls_p = nulls;
772 return true;
773
774dimension_error:
775 if (dimensions_specified)
776 ereturn(escontext, false,
777 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
778 errmsg("malformed array literal: \"%s\"", origStr),
779 errdetail("Specified array dimensions do not match array contents.")));
780 else
781 ereturn(escontext, false,
782 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
783 errmsg("malformed array literal: \"%s\"", origStr),
784 errdetail("Multidimensional arrays must have sub-arrays with matching dimensions.")));
785}
786
787
788
789
790
791
792
793
794
795
798 const char *origStr, Node *escontext)
799{
800 char *p = *srcptr;
801 int dstlen;
802 bool has_escapes;
803
805
806
807 for (;;)
808 {
809 switch (*p)
810 {
811 case '\0':
812 goto ending_error;
813 case '{':
814 *srcptr = p + 1;
816 case '}':
817 *srcptr = p + 1;
819 case '"':
820 p++;
821 goto quoted_element;
822 default:
823 if (*p == typdelim)
824 {
825 *srcptr = p + 1;
827 }
829 {
830 p++;
831 continue;
832 }
833 goto unquoted_element;
834 }
835 }
836
837quoted_element:
838 for (;;)
839 {
840 switch (*p)
841 {
842 case '\0':
843 goto ending_error;
844 case '\\':
845
846 p++;
847 if (*p == '\0')
848 goto ending_error;
850 break;
851 case '"':
852
853
854
855
856
857
858
859
860
861 while (*(++p) != '\0')
862 {
863 if (*p == typdelim || *p == '}' || *p == '{')
864 {
865 *srcptr = p;
867 }
870 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
871 errmsg("malformed array literal: \"%s\"", origStr),
872 errdetail("Incorrectly quoted array element.")));
873 }
874 goto ending_error;
875 default:
877 break;
878 }
879 }
880
881unquoted_element:
882
883
884
885
886
887 dstlen = 0;
888 has_escapes = false;
889 for (;;)
890 {
891 switch (*p)
892 {
893 case '\0':
894 goto ending_error;
895 case '{':
897 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
898 errmsg("malformed array literal: \"%s\"", origStr),
899 errdetail("Unexpected \"%c\" character.",
900 '{')));
901 case '"':
902
904 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
905 errmsg("malformed array literal: \"%s\"", origStr),
906 errdetail("Incorrectly quoted array element.")));
907 case '\\':
908
909 p++;
910 if (*p == '\0')
911 goto ending_error;
913 dstlen = elembuf->len;
914 has_escapes = true;
915 break;
916 default:
917
918 if (*p == typdelim || *p == '}')
919 {
920
921 elembuf->data[dstlen] = '\0';
922 elembuf->len = dstlen;
923 *srcptr = p;
924
928 else
930 }
933 dstlen = elembuf->len;
934 p++;
935 break;
936 }
937 }
938
939ending_error:
941 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
942 errmsg("malformed array literal: \"%s\"", origStr),
943 errdetail("Unexpected end of input.")));
944}
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961void
964 const bool *nulls,
966 int typlen,
967 bool typbyval,
969 bool freedata)
970{
973 int bitval = 0;
974 int bitmask = 1;
975 int i;
976
977 if (typbyval)
978 freedata = false;
979
981 {
982 if (nulls && nulls[i])
983 {
984 if (!bitmap)
985 elog(ERROR, "null array element where not supported");
986
987 }
988 else
989 {
990 bitval |= bitmask;
992 if (freedata)
994 }
995 if (bitmap)
996 {
997 bitmask <<= 1;
998 if (bitmask == 0x100)
999 {
1000 *bitmap++ = bitval;
1001 bitval = 0;
1002 bitmask = 1;
1003 }
1004 }
1005 }
1006
1007 if (bitmap && bitmask != 1)
1008 *bitmap = bitval;
1009}
1010
1011
1012
1013
1014
1015
1018{
1021 int typlen;
1022 bool typbyval;
1024 char typdelim;
1025 char *p,
1026 *tmp,
1027 *retval,
1029 dims_str[(MAXDIM * 33) + 2];
1030
1031
1032
1033
1034
1035
1036 bool *needquotes,
1037 needdims = false;
1038 size_t overall_length;
1040 i,
1041 j,
1042 k,
1044 int ndim,
1045 *dims,
1046 *lb;
1049
1050
1051
1052
1053
1054
1055 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
1056 if (my_extra == NULL)
1057 {
1058 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
1060 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
1062 }
1063
1065 {
1066
1067
1068
1074 fcinfo->flinfo->fn_mcxt);
1076 }
1077 typlen = my_extra->typlen;
1078 typbyval = my_extra->typbyval;
1080 typdelim = my_extra->typdelim;
1081
1086
1088 {
1091 }
1092
1093
1094
1095
1096
1097 for (i = 0; i < ndim; i++)
1098 {
1099 if (lb[i] != 1)
1100 {
1101 needdims = true;
1102 break;
1103 }
1104 }
1105
1106
1107
1108
1109
1110
1112 needquotes = (bool *) palloc(nitems * sizeof(bool));
1113 overall_length = 0;
1114
1116
1118 {
1119 Datum itemvalue;
1120 bool isnull;
1121 bool needquote;
1122
1123
1125 typlen, typbyval, typalign);
1126
1127 if (isnull)
1128 {
1130 overall_length += 4;
1131 needquote = false;
1132 }
1133 else
1134 {
1136
1137
1138 if (values[i][0] == '\0')
1139 needquote = true;
1141 needquote = true;
1142 else
1143 needquote = false;
1144
1145 for (tmp = values[i]; *tmp != '\0'; tmp++)
1146 {
1147 char ch = *tmp;
1148
1149 overall_length += 1;
1150 if (ch == '"' || ch == '\\')
1151 {
1152 needquote = true;
1153 overall_length += 1;
1154 }
1155 else if (ch == '{' || ch == '}' || ch == typdelim ||
1157 needquote = true;
1158 }
1159 }
1160
1161 needquotes[i] = needquote;
1162
1163
1164 if (needquote)
1165 overall_length += 2;
1166
1167 overall_length += 1;
1168 }
1169
1170
1171
1172
1173
1174
1175
1176 for (i = j = 0, k = 1; i < ndim; i++)
1177 {
1179 }
1180 overall_length += 2 * j;
1181
1182
1183 dims_str[0] = '\0';
1184 if (needdims)
1185 {
1186 char *ptr = dims_str;
1187
1188 for (i = 0; i < ndim; i++)
1189 {
1190 sprintf(ptr, "[%d:%d]", lb[i], lb[i] + dims[i] - 1);
1191 ptr += strlen(ptr);
1192 }
1193 *ptr++ = *ASSGN;
1194 *ptr = '\0';
1195 overall_length += ptr - dims_str;
1196 }
1197
1198
1199 retval = (char *) palloc(overall_length);
1200 p = retval;
1201
1202#define APPENDSTR(str) (strcpy(p, (str)), p += strlen(p))
1203#define APPENDCHAR(ch) (*p++ = (ch), *p = '\0')
1204
1205 if (needdims)
1208 for (i = 0; i < ndim; i++)
1209 indx[i] = 0;
1210 j = 0;
1211 k = 0;
1212 do
1213 {
1214 for (i = j; i < ndim - 1; i++)
1216
1217 if (needquotes[k])
1218 {
1220 for (tmp = values[k]; *tmp; tmp++)
1221 {
1222 char ch = *tmp;
1223
1224 if (ch == '"' || ch == '\\')
1225 *p++ = '\\';
1226 *p++ = ch;
1227 }
1228 *p = '\0';
1230 }
1231 else
1234
1235 for (i = ndim - 1; i >= 0; i--)
1236 {
1237 if (++(indx[i]) < dims[i])
1238 {
1240 break;
1241 }
1242 else
1243 {
1244 indx[i] = 0;
1246 }
1247 }
1249 } while (j != -1);
1250
1251#undef APPENDSTR
1252#undef APPENDCHAR
1253
1254
1255 Assert(overall_length == (p - retval + 1));
1256
1258 pfree(needquotes);
1259
1261}
1262
1263
1264
1265
1266
1267
1268
1269
1270
1273{
1275 Oid spec_element_type = PG_GETARG_OID(1);
1276
1278 Oid element_type;
1279 int typlen;
1280 bool typbyval;
1282 Oid typioparam;
1283 int i,
1286 bool *nullsPtr;
1287 bool hasnulls;
1289 int32 dataoffset;
1291 int ndim,
1292 flags,
1296
1297
1299 if (ndim < 0)
1301 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1302 errmsg("invalid number of dimensions: %d", ndim)));
1305 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1306 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
1308
1310 if (flags != 0 && flags != 1)
1312 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1313 errmsg("invalid array flags")));
1314
1315
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329 if (element_type != spec_element_type)
1330 {
1334 (errcode(ERRCODE_DATATYPE_MISMATCH),
1335 errmsg("binary data has array element type %u (%s) instead of expected %u (%s)",
1336 element_type,
1339 spec_element_type,
1342 element_type = spec_element_type;
1343 }
1344
1345 for (i = 0; i < ndim; i++)
1346 {
1349 }
1350
1351
1354
1355
1356
1357
1358
1359
1360 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
1361 if (my_extra == NULL)
1362 {
1363 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
1365 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
1367 }
1368
1370 {
1371
1378 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1379 errmsg("no binary input function available for type %s",
1382 fcinfo->flinfo->fn_mcxt);
1384 }
1385
1387 {
1388
1390 }
1391
1392 typlen = my_extra->typlen;
1393 typbyval = my_extra->typbyval;
1396
1398 nullsPtr = (bool *) palloc(nitems * sizeof(bool));
1400 &my_extra->proc, typioparam, typmod,
1402 dataPtr, nullsPtr,
1403 &hasnulls, &nbytes);
1404 if (hasnulls)
1405 {
1407 nbytes += dataoffset;
1408 }
1409 else
1410 {
1411 dataoffset = 0;
1413 }
1416 retval->ndim = ndim;
1418 retval->elemtype = element_type;
1419 memcpy(ARR_DIMS(retval), dim, ndim * sizeof(int));
1420 memcpy(ARR_LBOUND(retval), lBound, ndim * sizeof(int));
1421
1423 dataPtr, nullsPtr, nitems,
1425 true);
1426
1428 pfree(nullsPtr);
1429
1431}
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454static void
1458 Oid typioparam,
1460 int typlen,
1461 bool typbyval,
1464 bool *nulls,
1465 bool *hasnulls,
1467{
1468 int i;
1469 bool hasnull;
1471
1473 {
1474 int itemlen;
1476
1477
1479 if (itemlen < -1 || itemlen > (buf->len - buf->cursor))
1481 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1482 errmsg("insufficient data left in message")));
1483
1484 if (itemlen == -1)
1485 {
1486
1488 typioparam, typmod);
1489 nulls[i] = true;
1490 continue;
1491 }
1492
1493
1494
1495
1496
1498
1499 buf->cursor += itemlen;
1500
1501
1503 typioparam, typmod);
1504 nulls[i] = false;
1505
1506
1507 if (elem_buf.cursor != itemlen)
1509 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1510 errmsg("improper binary format in array element %d",
1511 i + 1)));
1512 }
1513
1514
1515
1516
1517 hasnull = false;
1518 totbytes = 0;
1520 {
1521 if (nulls[i])
1522 hasnull = true;
1523 else
1524 {
1525
1526 if (typlen == -1)
1530
1533 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1534 errmsg("array size exceeds the maximum allowed (%zu)",
1536 }
1537 }
1538 *hasnulls = hasnull;
1539 *nbytes = totbytes;
1540}
1541
1542
1543
1544
1545
1546
1547
1550{
1553 int typlen;
1554 bool typbyval;
1557 i;
1558 int ndim,
1559 *dim,
1560 *lb;
1564
1565
1566
1567
1568
1569
1570 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
1571 if (my_extra == NULL)
1572 {
1573 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
1575 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
1577 }
1578
1580 {
1581
1588 (errcode(ERRCODE_UNDEFINED_FUNCTION),
1589 errmsg("no binary output function available for type %s",
1592 fcinfo->flinfo->fn_mcxt);
1594 }
1595 typlen = my_extra->typlen;
1596 typbyval = my_extra->typbyval;
1598
1603
1605
1606
1610 for (i = 0; i < ndim; i++)
1611 {
1614 }
1615
1616
1618
1620 {
1621 Datum itemvalue;
1622 bool isnull;
1623
1624
1626 typlen, typbyval, typalign);
1627
1628 if (isnull)
1629 {
1630
1632 }
1633 else
1634 {
1635 bytea *outputbytes;
1636
1641 pfree(outputbytes);
1642 }
1643 }
1644
1646}
1647
1648
1649
1650
1651
1654{
1656
1657
1660
1662}
1663
1664
1665
1666
1667
1670{
1672 char *p;
1673 int i;
1674 int *dimv,
1675 *lb;
1676
1677
1678
1679
1680
1681
1683
1684
1687
1690
1691 p = buf;
1693 {
1694 sprintf(p, "[%d:%d]", lb[i], dimv[i] + lb[i] - 1);
1695 p += strlen(p);
1696 }
1697
1699}
1700
1701
1702
1703
1704
1705
1708{
1711 int *lb;
1712 int result;
1713
1714
1717
1718
1719 if (reqdim <= 0 || reqdim > AARR_NDIM(v))
1721
1723 result = lb[reqdim - 1];
1724
1726}
1727
1728
1729
1730
1731
1732
1735{
1738 int *dimv,
1739 *lb;
1740 int result;
1741
1742
1745
1746
1747 if (reqdim <= 0 || reqdim > AARR_NDIM(v))
1749
1752
1753 result = dimv[reqdim - 1] + lb[reqdim - 1] - 1;
1754
1756}
1757
1758
1759
1760
1761
1762
1765{
1768 int *dimv;
1769 int result;
1770
1771
1774
1775
1776 if (reqdim <= 0 || reqdim > AARR_NDIM(v))
1778
1780
1781 result = dimv[reqdim - 1];
1782
1784}
1785
1786
1787
1788
1789
1792{
1794
1796}
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1822 int nSubscripts,
1823 int *indx,
1824 int arraytyplen,
1825 int elmlen,
1826 bool elmbyval,
1827 char elmalign,
1828 bool *isNull)
1829{
1830 int i,
1831 ndim,
1832 *dim,
1833 *lb,
1834 offset,
1835 fixedDim[1],
1836 fixedLb[1];
1837 char *arraydataptr,
1838 *retptr;
1839 bits8 *arraynullsptr;
1840
1841 if (arraytyplen > 0)
1842 {
1843
1844
1845
1846 ndim = 1;
1847 fixedDim[0] = arraytyplen / elmlen;
1848 fixedLb[0] = 0;
1849 dim = fixedDim;
1850 lb = fixedLb;
1852 arraynullsptr = NULL;
1853 }
1855 {
1856
1858 nSubscripts,
1859 indx,
1860 arraytyplen,
1861 elmlen,
1862 elmbyval,
1863 elmalign,
1864 isNull);
1865 }
1866 else
1867 {
1868
1870
1876 }
1877
1878
1879
1880
1881 if (ndim != nSubscripts || ndim <= 0 || ndim > MAXDIM)
1882 {
1883 *isNull = true;
1884 return (Datum) 0;
1885 }
1886 for (i = 0; i < ndim; i++)
1887 {
1888 if (indx[i] < lb[i] || indx[i] >= (dim[i] + lb[i]))
1889 {
1890 *isNull = true;
1891 return (Datum) 0;
1892 }
1893 }
1894
1895
1896
1897
1898 offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
1899
1900
1901
1902
1904 {
1905 *isNull = true;
1906 return (Datum) 0;
1907 }
1908
1909
1910
1911
1912 *isNull = false;
1913 retptr = array_seek(arraydataptr, 0, arraynullsptr, offset,
1914 elmlen, elmbyval, elmalign);
1915 return ArrayCast(retptr, elmbyval, elmlen);
1916}
1917
1918
1919
1920
1923 int nSubscripts, int *indx,
1924 int arraytyplen,
1925 int elmlen, bool elmbyval, char elmalign,
1926 bool *isNull)
1927{
1929 int i,
1930 ndim,
1931 *dim,
1932 *lb,
1933 offset;
1935 bool *dnulls;
1936
1939
1940
1941 Assert(arraytyplen == -1);
1945
1946 ndim = eah->ndims;
1947 dim = eah->dims;
1949
1950
1951
1952
1953 if (ndim != nSubscripts || ndim <= 0 || ndim > MAXDIM)
1954 {
1955 *isNull = true;
1956 return (Datum) 0;
1957 }
1958 for (i = 0; i < ndim; i++)
1959 {
1960 if (indx[i] < lb[i] || indx[i] >= (dim[i] + lb[i]))
1961 {
1962 *isNull = true;
1963 return (Datum) 0;
1964 }
1965 }
1966
1967
1968
1969
1970 offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
1971
1972
1973
1974
1975
1977
1979 dnulls = eah->dnulls;
1980
1981
1982
1983
1984 if (dnulls && dnulls[offset])
1985 {
1986 *isNull = true;
1987 return (Datum) 0;
1988 }
1989
1990
1991
1992
1993
1994
1995
1996 *isNull = false;
1997 return dvalues[offset];
1998}
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2032 int nSubscripts,
2033 int *upperIndx,
2034 int *lowerIndx,
2035 bool *upperProvided,
2036 bool *lowerProvided,
2037 int arraytyplen,
2038 int elmlen,
2039 bool elmbyval,
2040 char elmalign)
2041{
2044 int i,
2045 ndim,
2046 *dim,
2047 *lb,
2048 *newlb;
2049 int fixedDim[1],
2050 fixedLb[1];
2051 Oid elemtype;
2052 char *arraydataptr;
2053 bits8 *arraynullsptr;
2054 int32 dataoffset;
2055 int bytes,
2057
2058 if (arraytyplen > 0)
2059 {
2060
2061
2062
2063
2064
2065
2067 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2068 errmsg("slices of fixed-length arrays not implemented")));
2069
2070
2071
2072
2073
2074
2075 ndim = 1;
2076 fixedDim[0] = arraytyplen / elmlen;
2077 fixedLb[0] = 0;
2078 dim = fixedDim;
2079 lb = fixedLb;
2082 arraynullsptr = NULL;
2083 }
2084 else
2085 {
2086
2088
2095 }
2096
2097
2098
2099
2100
2101
2102 if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
2104
2105 for (i = 0; i < nSubscripts; i++)
2106 {
2107 if (!lowerProvided[i] || lowerIndx[i] < lb[i])
2109 if (!upperProvided[i] || upperIndx[i] >= (dim[i] + lb[i]))
2110 upperIndx[i] = dim[i] + lb[i] - 1;
2111 if (lowerIndx[i] > upperIndx[i])
2113 }
2114
2116 {
2118 upperIndx[i] = dim[i] + lb[i] - 1;
2119 if (lowerIndx[i] > upperIndx[i])
2121 }
2122
2123 mda_get_range(ndim, span, lowerIndx, upperIndx);
2124
2126 ndim, dim, lb,
2127 lowerIndx, upperIndx,
2128 elmlen, elmbyval, elmalign);
2129
2130
2131
2132
2133
2134 if (arraynullsptr)
2135 {
2137 bytes += dataoffset;
2138 }
2139 else
2140 {
2141 dataoffset = 0;
2143 }
2144
2147 newarray->ndim = ndim;
2149 newarray->elemtype = elemtype;
2150 memcpy(ARR_DIMS(newarray), span, ndim * sizeof(int));
2151
2152
2153
2154
2155
2157 for (i = 0; i < ndim; i++)
2158 newlb[i] = 1;
2159
2161 ndim, dim, lb,
2162 arraydataptr, arraynullsptr,
2163 lowerIndx, upperIndx,
2164 elmlen, elmbyval, elmalign);
2165
2167}
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2203 int nSubscripts,
2204 int *indx,
2205 Datum dataValue,
2206 bool isNull,
2207 int arraytyplen,
2208 int elmlen,
2209 bool elmbyval,
2210 char elmalign)
2211{
2214 int i,
2215 ndim,
2218 offset;
2219 char *elt_ptr;
2220 bool newhasnulls;
2221 bits8 *oldnullbitmap;
2222 int oldnitems,
2223 newnitems,
2224 olddatasize,
2225 newsize,
2226 olditemlen,
2227 newitemlen,
2228 overheadlen,
2229 oldoverheadlen,
2230 addedbefore,
2231 addedafter,
2232 lenbefore,
2233 lenafter;
2234
2235 if (arraytyplen > 0)
2236 {
2237
2238
2239
2240
2241 char *resultarray;
2242
2243 if (nSubscripts != 1)
2245 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2246 errmsg("wrong number of array subscripts")));
2247
2248 if (indx[0] < 0 || indx[0] >= arraytyplen / elmlen)
2250 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2251 errmsg("array subscript out of range")));
2252
2253 if (isNull)
2255 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2256 errmsg("cannot assign null value to an element of a fixed-length array")));
2257
2258 resultarray = (char *) palloc(arraytyplen);
2259 memcpy(resultarray, DatumGetPointer(arraydatum), arraytyplen);
2260 elt_ptr = resultarray + indx[0] * elmlen;
2261 ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elt_ptr);
2263 }
2264
2265 if (nSubscripts <= 0 || nSubscripts > MAXDIM)
2267 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2268 errmsg("wrong number of array subscripts")));
2269
2270
2271 if (elmlen == -1 && !isNull)
2273
2275 {
2276
2278 nSubscripts,
2279 indx,
2280 dataValue,
2281 isNull,
2282 arraytyplen,
2283 elmlen,
2284 elmbyval,
2285 elmalign);
2286 }
2287
2288
2290
2292
2293
2294
2295
2296
2297
2298 if (ndim == 0)
2299 {
2301
2302 for (i = 0; i < nSubscripts; i++)
2303 {
2304 dim[i] = 1;
2306 }
2307
2309 nSubscripts, dim, lb,
2310 elmtype,
2311 elmlen, elmbyval, elmalign));
2312 }
2313
2314 if (ndim != nSubscripts)
2316 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2317 errmsg("wrong number of array subscripts")));
2318
2319
2320 memcpy(dim, ARR_DIMS(array), ndim * sizeof(int));
2321 memcpy(lb, ARR_LBOUND(array), ndim * sizeof(int));
2322
2323 newhasnulls = (ARR_HASNULL(array) || isNull);
2324 addedbefore = addedafter = 0;
2325
2326
2327
2328
2329
2330
2331
2332 if (ndim == 1)
2333 {
2334 if (indx[0] < lb[0])
2335 {
2336
2337
2341 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2342 errmsg("array size exceeds the maximum allowed (%zu)",
2344 lb[0] = indx[0];
2345 if (addedbefore > 1)
2346 newhasnulls = true;
2347 }
2348 if (indx[0] >= (dim[0] + lb[0]))
2349 {
2350
2351
2356 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2357 errmsg("array size exceeds the maximum allowed (%zu)",
2359 if (addedafter > 1)
2360 newhasnulls = true;
2361 }
2362 }
2363 else
2364 {
2365
2366
2367
2368
2369 for (i = 0; i < ndim; i++)
2370 {
2372 indx[i] >= (dim[i] + lb[i]))
2374 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2375 errmsg("array subscript out of range")));
2376 }
2377 }
2378
2379
2382
2383
2384
2385
2386 if (newhasnulls)
2388 else
2393 olddatasize = ARR_SIZE(array) - oldoverheadlen;
2394 if (addedbefore)
2395 {
2396 offset = 0;
2397 lenbefore = 0;
2398 olditemlen = 0;
2399 lenafter = olddatasize;
2400 }
2401 else if (addedafter)
2402 {
2403 offset = oldnitems;
2404 lenbefore = olddatasize;
2405 olditemlen = 0;
2406 lenafter = 0;
2407 }
2408 else
2409 {
2410 offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
2412 elmlen, elmbyval, elmalign);
2413 lenbefore = (int) (elt_ptr - ARR_DATA_PTR(array));
2415 olditemlen = 0;
2416 else
2417 {
2420 }
2421 lenafter = olddatasize - lenbefore - olditemlen;
2422 }
2423
2424 if (isNull)
2425 newitemlen = 0;
2426 else
2427 {
2430 }
2431
2432 newsize = overheadlen + lenbefore + newitemlen + lenafter;
2433
2434
2435
2436
2439 newarray->ndim = ndim;
2440 newarray->dataoffset = newhasnulls ? overheadlen : 0;
2442 memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));
2443 memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));
2444
2445
2446
2447
2448 memcpy((char *) newarray + overheadlen,
2449 (char *) array + oldoverheadlen,
2450 lenbefore);
2451 if (!isNull)
2453 (char *) newarray + overheadlen + lenbefore);
2454 memcpy((char *) newarray + overheadlen + lenbefore + newitemlen,
2455 (char *) array + oldoverheadlen + lenbefore + olditemlen,
2456 lenafter);
2457
2458
2459
2460
2461
2462
2463
2464 if (newhasnulls)
2465 {
2467
2468
2469
2470 if (addedafter)
2472 else
2474
2475 if (addedbefore)
2477 oldnullbitmap, 0,
2478 oldnitems);
2479 else
2480 {
2482 oldnullbitmap, 0,
2483 offset);
2484 if (addedafter == 0)
2486 oldnullbitmap, offset + 1,
2487 oldnitems - offset - 1);
2488 }
2489 }
2490
2492}
2493
2494
2495
2496
2497
2498
2499
2500
2503 int nSubscripts, int *indx,
2504 Datum dataValue, bool isNull,
2505 int arraytyplen,
2506 int elmlen, bool elmbyval, char elmalign)
2507{
2510 bool *dnulls;
2511 int i,
2512 ndim,
2515 offset;
2516 bool dimschanged,
2517 newhasnulls;
2518 int addedbefore,
2519 addedafter;
2520 char *oldValue;
2521
2522
2524
2525
2526 Assert(arraytyplen == -1);
2530
2531
2532
2533
2534
2535
2536 ndim = eah->ndims;
2538 memcpy(dim, eah->dims, ndim * sizeof(int));
2539 memcpy(lb, eah->lbound, ndim * sizeof(int));
2540 dimschanged = false;
2541
2542
2543
2544
2545
2546
2547 if (ndim == 0)
2548 {
2549
2550
2551
2552
2553 Assert(nSubscripts > 0 && nSubscripts <= MAXDIM);
2555 nSubscripts * sizeof(int));
2557 nSubscripts * sizeof(int));
2558
2559
2560 ndim = nSubscripts;
2561 for (i = 0; i < nSubscripts; i++)
2562 {
2563 dim[i] = 0;
2565 }
2566 dimschanged = true;
2567 }
2568 else if (ndim != nSubscripts)
2570 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2571 errmsg("wrong number of array subscripts")));
2572
2573
2574
2575
2576
2577
2578
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589 if (!eah->typbyval && !isNull)
2590 {
2592
2595 }
2596
2598 dnulls = eah->dnulls;
2599
2600 newhasnulls = ((dnulls != NULL) || isNull);
2601 addedbefore = addedafter = 0;
2602
2603
2604
2605
2606
2607
2608
2609 if (ndim == 1)
2610 {
2611 if (indx[0] < lb[0])
2612 {
2613
2614
2618 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2619 errmsg("array size exceeds the maximum allowed (%zu)",
2621 lb[0] = indx[0];
2622 dimschanged = true;
2623 if (addedbefore > 1)
2624 newhasnulls = true;
2625 }
2626 if (indx[0] >= (dim[0] + lb[0]))
2627 {
2628
2629
2634 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2635 errmsg("array size exceeds the maximum allowed (%zu)",
2637 dimschanged = true;
2638 if (addedafter > 1)
2639 newhasnulls = true;
2640 }
2641 }
2642 else
2643 {
2644
2645
2646
2647
2648 for (i = 0; i < ndim; i++)
2649 {
2651 indx[i] >= (dim[i] + lb[i]))
2653 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2654 errmsg("array subscript out of range")));
2655 }
2656 }
2657
2658
2659 if (dimschanged)
2660 {
2663 }
2664
2665
2666 offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
2667
2668
2670 {
2671
2672 int newlen = dim[0] + dim[0] / 8;
2673
2674 newlen = Max(newlen, dim[0]);
2677 if (dnulls)
2678 eah->dnulls = dnulls = (bool *)
2679 repalloc(dnulls, newlen * sizeof(bool));
2681 }
2682
2683
2684
2685
2686
2687 if (newhasnulls && dnulls == NULL)
2688 eah->dnulls = dnulls = (bool *)
2691
2692
2693
2694
2695
2696
2697
2699
2701
2702
2703 if (dimschanged)
2704 {
2705 eah->ndims = ndim;
2706 memcpy(eah->dims, dim, ndim * sizeof(int));
2707 memcpy(eah->lbound, lb, ndim * sizeof(int));
2708 }
2709
2710
2711 if (addedbefore > 0)
2712 {
2713 memmove(dvalues + addedbefore, dvalues, eah->nelems * sizeof(Datum));
2714 for (i = 0; i < addedbefore; i++)
2716 if (dnulls)
2717 {
2718 memmove(dnulls + addedbefore, dnulls, eah->nelems * sizeof(bool));
2719 for (i = 0; i < addedbefore; i++)
2720 dnulls[i] = true;
2721 }
2722 eah->nelems += addedbefore;
2723 }
2724
2725
2726 if (addedafter > 0)
2727 {
2728 for (i = 0; i < addedafter; i++)
2730 if (dnulls)
2731 {
2732 for (i = 0; i < addedafter; i++)
2733 dnulls[eah->nelems + i] = true;
2734 }
2735 eah->nelems += addedafter;
2736 }
2737
2738
2739 if (!eah->typbyval && (dnulls == NULL || !dnulls[offset]))
2741 else
2742 oldValue = NULL;
2743
2744
2745 dvalues[offset] = dataValue;
2746 if (dnulls)
2747 dnulls[offset] = isNull;
2748
2749
2750
2751
2752
2753
2754 if (oldValue)
2755 {
2756
2757 if (oldValue < eah->fstartptr || oldValue >= eah->fendptr)
2758 pfree(oldValue);
2759 }
2760
2761
2763}
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2808 int nSubscripts,
2809 int *upperIndx,
2810 int *lowerIndx,
2811 bool *upperProvided,
2812 bool *lowerProvided,
2813 Datum srcArrayDatum,
2814 bool isNull,
2815 int arraytyplen,
2816 int elmlen,
2817 bool elmbyval,
2818 char elmalign)
2819{
2823 int i,
2824 ndim,
2828 bool newhasnulls;
2830 nsrcitems,
2831 olddatasize,
2832 newsize,
2833 olditemsize,
2834 newitemsize,
2835 overheadlen,
2836 oldoverheadlen,
2837 addedbefore,
2838 addedafter,
2839 lenbefore,
2840 lenafter,
2841 itemsbefore,
2842 itemsafter,
2843 nolditems;
2844
2845
2846 if (isNull)
2847 return arraydatum;
2848
2849 if (arraytyplen > 0)
2850 {
2851
2852
2853
2855 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2856 errmsg("updates on slices of fixed-length arrays not implemented")));
2857 }
2858
2859
2862
2863
2864
2866
2867
2868
2869
2870
2871
2872 if (ndim == 0)
2873 {
2875 bool *dnulls;
2876 int nelems;
2878
2879 deconstruct_array(srcArray, elmtype, elmlen, elmbyval, elmalign,
2880 &dvalues, &dnulls, &nelems);
2881
2882 for (i = 0; i < nSubscripts; i++)
2883 {
2884 if (!upperProvided[i] || !lowerProvided[i])
2886 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2887 errmsg("array slice subscript must provide both boundaries"),
2888 errdetail("When assigning to a slice of an empty array value,"
2889 " slice boundaries must be fully specified.")));
2890
2891
2895 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2896 errmsg("array size exceeds the maximum allowed (%zu)",
2898
2900 }
2901
2902
2905 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2906 errmsg("source array too small")));
2907
2909 dim, lb, elmtype,
2910 elmlen, elmbyval, elmalign));
2911 }
2912
2913 if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
2915 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2916 errmsg("wrong number of array subscripts")));
2917
2918
2919 memcpy(dim, ARR_DIMS(array), ndim * sizeof(int));
2920 memcpy(lb, ARR_LBOUND(array), ndim * sizeof(int));
2921
2923 addedbefore = addedafter = 0;
2924
2925
2926
2927
2928
2929
2930
2931 if (ndim == 1)
2932 {
2933 Assert(nSubscripts == 1);
2934 if (!lowerProvided[0])
2935 lowerIndx[0] = lb[0];
2936 if (!upperProvided[0])
2937 upperIndx[0] = dim[0] + lb[0] - 1;
2938 if (lowerIndx[0] > upperIndx[0])
2940 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2941 errmsg("upper bound cannot be less than lower bound")));
2942 if (lowerIndx[0] < lb[0])
2943 {
2944
2945
2949 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2950 errmsg("array size exceeds the maximum allowed (%zu)",
2952 lb[0] = lowerIndx[0];
2953 if (addedbefore > 1)
2954 newhasnulls = true;
2955 }
2956 if (upperIndx[0] >= (dim[0] + lb[0]))
2957 {
2958
2959
2964 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2965 errmsg("array size exceeds the maximum allowed (%zu)",
2967 if (addedafter > 1)
2968 newhasnulls = true;
2969 }
2970 }
2971 else
2972 {
2973
2974
2975
2976
2977 for (i = 0; i < nSubscripts; i++)
2978 {
2979 if (!lowerProvided[i])
2981 if (!upperProvided[i])
2982 upperIndx[i] = dim[i] + lb[i] - 1;
2983 if (lowerIndx[i] > upperIndx[i])
2985 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2986 errmsg("upper bound cannot be less than lower bound")));
2987 if (lowerIndx[i] < lb[i] ||
2988 upperIndx[i] >= (dim[i] + lb[i]))
2990 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2991 errmsg("array subscript out of range")));
2992 }
2993
2995 {
2997 upperIndx[i] = dim[i] + lb[i] - 1;
2998 if (lowerIndx[i] > upperIndx[i])
3000 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3001 errmsg("upper bound cannot be less than lower bound")));
3002 }
3003 }
3004
3005
3008
3009
3010
3011
3012
3013 mda_get_range(ndim, span, lowerIndx, upperIndx);
3017 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3018 errmsg("source array too small")));
3019
3020
3021
3022
3023
3024 if (newhasnulls)
3026 else
3030 elmlen, elmbyval, elmalign);
3032 olddatasize = ARR_SIZE(array) - oldoverheadlen;
3033 if (ndim > 1)
3034 {
3035
3036
3037
3038
3041 ndim, dim, lb,
3042 lowerIndx, upperIndx,
3043 elmlen, elmbyval, elmalign);
3044 lenbefore = lenafter = 0;
3045 itemsbefore = itemsafter = nolditems = 0;
3046 }
3047 else
3048 {
3049
3050
3051
3052
3054 int oldub = oldlb + ARR_DIMS(array)[0] - 1;
3055 int slicelb = Max(oldlb, lowerIndx[0]);
3056 int sliceub = Min(oldub, upperIndx[0]);
3059
3060
3061 itemsbefore = Min(slicelb, oldub + 1) - oldlb;
3063 itemsbefore,
3064 elmlen, elmbyval, elmalign);
3065
3066 if (slicelb > sliceub)
3067 {
3068 nolditems = 0;
3069 olditemsize = 0;
3070 }
3071 else
3072 {
3073 nolditems = sliceub - slicelb + 1;
3075 itemsbefore, oldarraybitmap,
3076 nolditems,
3077 elmlen, elmbyval, elmalign);
3078 }
3079
3080 itemsafter = oldub + 1 - Max(sliceub + 1, oldlb);
3081 lenafter = olddatasize - lenbefore - olditemsize;
3082 }
3083
3084 newsize = overheadlen + olddatasize - olditemsize + newitemsize;
3085
3088 newarray->ndim = ndim;
3089 newarray->dataoffset = newhasnulls ? overheadlen : 0;
3091 memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));
3092 memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));
3093
3094 if (ndim > 1)
3095 {
3096
3097
3098
3099
3101 ndim, dim, lb,
3102 lowerIndx, upperIndx,
3103 elmlen, elmbyval, elmalign);
3104 }
3105 else
3106 {
3107
3108 memcpy((char *) newarray + overheadlen,
3109 (char *) array + oldoverheadlen,
3110 lenbefore);
3111 memcpy((char *) newarray + overheadlen + lenbefore,
3113 newitemsize);
3114 memcpy((char *) newarray + overheadlen + lenbefore + newitemsize,
3115 (char *) array + oldoverheadlen + lenbefore + olditemsize,
3116 lenafter);
3117
3118 if (newhasnulls)
3119 {
3122
3123
3125 oldnullbitmap, 0,
3126 itemsbefore);
3129 nsrcitems);
3130 array_bitmap_copy(newnullbitmap, addedbefore + itemsbefore + nolditems,
3131 oldnullbitmap, itemsbefore + nolditems,
3132 itemsafter);
3133 }
3134 }
3135
3137}
3138
3139
3140
3141
3142
3143
3144
3145
3148 int arraytyplen, int elmlen, bool elmbyval, char elmalign,
3149 bool *isNull)
3150{
3152 arraytyplen, elmlen, elmbyval, elmalign,
3153 isNull);
3154}
3155
3156
3157
3158
3159
3160
3161
3162
3165 Datum dataValue, bool isNull,
3166 int arraytyplen, int elmlen, bool elmbyval, char elmalign)
3167{
3169 nSubscripts, indx,
3170 dataValue, isNull,
3171 arraytyplen,
3172 elmlen, elmbyval, elmalign));
3173}
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3205{
3209 bool *nulls;
3210 int *dim;
3211 int ndim;
3213 int i;
3214 int32 nbytes = 0;
3215 int32 dataoffset;
3216 bool hasnulls;
3217 Oid inpType;
3218 int inp_typlen;
3219 bool inp_typbyval;
3220 char inp_typalign;
3221 int typlen;
3222 bool typbyval;
3229
3234
3235
3237 {
3238
3240 }
3241
3242
3243
3244
3245
3246
3247 inp_extra = &amstate->inp_extra;
3248 ret_extra = &amstate->ret_extra;
3249
3251 {
3257 }
3258 inp_typlen = inp_extra->typlen;
3259 inp_typbyval = inp_extra->typbyval;
3260 inp_typalign = inp_extra->typalign;
3261
3263 {
3269 }
3270 typlen = ret_extra->typlen;
3271 typbyval = ret_extra->typbyval;
3273
3274
3276 nulls = (bool *) palloc(nitems * sizeof(bool));
3277
3278
3280 hasnulls = false;
3281
3283 {
3284
3285 *transform_source =
3287 inp_typlen, inp_typbyval, inp_typalign);
3288
3289
3291
3292 if (nulls[i])
3293 hasnulls = true;
3294 else
3295 {
3296
3297 if (typlen == -1)
3299
3302
3305 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3306 errmsg("array size exceeds the maximum allowed (%zu)",
3308 }
3309 }
3310
3311
3312 if (hasnulls)
3313 {
3315 nbytes += dataoffset;
3316 }
3317 else
3318 {
3319 dataoffset = 0;
3321 }
3324 result->ndim = ndim;
3329
3333 false);
3334
3335
3336
3337
3340
3342}
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3363 Oid elmtype,
3364 int elmlen, bool elmbyval, char elmalign)
3365{
3366 int dims[1];
3367 int lbs[1];
3368
3369 dims[0] = nelems;
3370 lbs[0] = 1;
3371
3373 elmtype, elmlen, elmbyval, elmalign);
3374}
3375
3376
3377
3378
3379
3380
3383{
3384 int elmlen;
3385 bool elmbyval;
3386 char elmalign;
3387
3388 switch (elmtype)
3389 {
3390 case CHAROID:
3391 elmlen = 1;
3392 elmbyval = true;
3393 elmalign = TYPALIGN_CHAR;
3394 break;
3395
3396 case CSTRINGOID:
3397 elmlen = -2;
3398 elmbyval = false;
3399 elmalign = TYPALIGN_CHAR;
3400 break;
3401
3402 case FLOAT4OID:
3403 elmlen = sizeof(float4);
3404 elmbyval = true;
3405 elmalign = TYPALIGN_INT;
3406 break;
3407
3408 case FLOAT8OID:
3409 elmlen = sizeof(float8);
3410 elmbyval = true;
3411 elmalign = TYPALIGN_DOUBLE;
3412 break;
3413
3414 case INT2OID:
3415 elmlen = sizeof(int16);
3416 elmbyval = true;
3417 elmalign = TYPALIGN_SHORT;
3418 break;
3419
3420 case INT4OID:
3421 elmlen = sizeof(int32);
3422 elmbyval = true;
3423 elmalign = TYPALIGN_INT;
3424 break;
3425
3426 case INT8OID:
3427 elmlen = sizeof(int64);
3428 elmbyval = true;
3429 elmalign = TYPALIGN_DOUBLE;
3430 break;
3431
3432 case NAMEOID:
3434 elmbyval = false;
3435 elmalign = TYPALIGN_CHAR;
3436 break;
3437
3438 case OIDOID:
3439 case REGTYPEOID:
3440 elmlen = sizeof(Oid);
3441 elmbyval = true;
3442 elmalign = TYPALIGN_INT;
3443 break;
3444
3445 case TEXTOID:
3446 elmlen = -1;
3447 elmbyval = false;
3448 elmalign = TYPALIGN_INT;
3449 break;
3450
3451 case TIDOID:
3453 elmbyval = false;
3454 elmalign = TYPALIGN_SHORT;
3455 break;
3456
3457 case XIDOID:
3459 elmbyval = true;
3460 elmalign = TYPALIGN_INT;
3461 break;
3462
3463 default:
3464 elog(ERROR, "type %u not supported by construct_array_builtin()", elmtype);
3465
3466 elmlen = 0;
3467 elmbyval = false;
3468 elmalign = 0;
3469 }
3470
3471 return construct_array(elems, nelems, elmtype, elmlen, elmbyval, elmalign);
3472}
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3496 bool *nulls,
3497 int ndims,
3498 int *dims,
3499 int *lbs,
3500 Oid elmtype, int elmlen, bool elmbyval, char elmalign)
3501{
3503 bool hasnulls;
3505 int32 dataoffset;
3506 int i;
3507 int nelems;
3508
3509 if (ndims < 0)
3511 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3512 errmsg("invalid number of dimensions: %d", ndims)));
3515 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3516 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
3518
3519
3522
3523
3524 if (nelems <= 0)
3526
3527
3528 nbytes = 0;
3529 hasnulls = false;
3530 for (i = 0; i < nelems; i++)
3531 {
3532 if (nulls && nulls[i])
3533 {
3534 hasnulls = true;
3535 continue;
3536 }
3537
3538 if (elmlen == -1)
3542
3545 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3546 errmsg("array size exceeds the maximum allowed (%zu)",
3548 }
3549
3550
3551 if (hasnulls)
3552 {
3554 nbytes += dataoffset;
3555 }
3556 else
3557 {
3558 dataoffset = 0;
3560 }
3563 result->ndim = ndims;
3566 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
3567 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
3568
3570 elems, nulls, nelems,
3571 elmlen, elmbyval, elmalign,
3572 false);
3573
3574 return result;
3575}
3576
3577
3578
3579
3582{
3584
3587 result->ndim = 0;
3590 return result;
3591}
3592
3593
3594
3595
3596
3601{
3604
3608}
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631void
3633 Oid elmtype,
3634 int elmlen, bool elmbyval, char elmalign,
3635 Datum **elemsp, bool **nullsp, int *nelemsp)
3636{
3638 bool *nulls;
3639 int nelems;
3640 char *p;
3642 int bitmask;
3643 int i;
3644
3646
3649 if (nullsp)
3651 else
3652 nulls = NULL;
3653 *nelemsp = nelems;
3654
3657 bitmask = 1;
3658
3659 for (i = 0; i < nelems; i++)
3660 {
3661
3662 if (bitmap && (*bitmap & bitmask) == 0)
3663 {
3665 if (nulls)
3666 nulls[i] = true;
3667 else
3669 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
3670 errmsg("null array element not allowed in this context")));
3671 }
3672 else
3673 {
3674 elems[i] = fetch_att(p, elmbyval, elmlen);
3677 }
3678
3679
3680 if (bitmap)
3681 {
3682 bitmask <<= 1;
3683 if (bitmask == 0x100)
3684 {
3685 bitmap++;
3686 bitmask = 1;
3687 }
3688 }
3689 }
3690}
3691
3692
3693
3694
3695
3696
3697void
3699 Oid elmtype,
3700 Datum **elemsp, bool **nullsp, int *nelemsp)
3701{
3702 int elmlen;
3703 bool elmbyval;
3704 char elmalign;
3705
3706 switch (elmtype)
3707 {
3708 case CHAROID:
3709 elmlen = 1;
3710 elmbyval = true;
3711 elmalign = TYPALIGN_CHAR;
3712 break;
3713
3714 case CSTRINGOID:
3715 elmlen = -2;
3716 elmbyval = false;
3717 elmalign = TYPALIGN_CHAR;
3718 break;
3719
3720 case FLOAT8OID:
3721 elmlen = sizeof(float8);
3722 elmbyval = true;
3723 elmalign = TYPALIGN_DOUBLE;
3724 break;
3725
3726 case INT2OID:
3727 elmlen = sizeof(int16);
3728 elmbyval = true;
3729 elmalign = TYPALIGN_SHORT;
3730 break;
3731
3732 case OIDOID:
3733 elmlen = sizeof(Oid);
3734 elmbyval = true;
3735 elmalign = TYPALIGN_INT;
3736 break;
3737
3738 case TEXTOID:
3739 elmlen = -1;
3740 elmbyval = false;
3741 elmalign = TYPALIGN_INT;
3742 break;
3743
3744 case TIDOID:
3746 elmbyval = false;
3747 elmalign = TYPALIGN_SHORT;
3748 break;
3749
3750 default:
3751 elog(ERROR, "type %u not supported by deconstruct_array_builtin()", elmtype);
3752
3753 elmlen = 0;
3754 elmbyval = false;
3755 elmalign = 0;
3756 }
3757
3758 deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, elemsp, nullsp, nelemsp);
3759}
3760
3761
3762
3763
3764
3765
3766
3767bool
3769{
3770 int nelems;
3772 int bitmask;
3773
3774
3776 return false;
3777
3779
3781
3782
3783 while (nelems >= 8)
3784 {
3785 if (*bitmap != 0xFF)
3786 return true;
3787 bitmap++;
3788 nelems -= 8;
3789 }
3790
3791
3792 bitmask = 1;
3793 while (nelems > 0)
3794 {
3795 if ((*bitmap & bitmask) == 0)
3796 return true;
3797 bitmask <<= 1;
3798 nelems--;
3799 }
3800
3801 return false;
3802}
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3816{
3828 bool result = true;
3831 int typlen;
3832 bool typbyval;
3836 int i;
3837
3840 (errcode(ERRCODE_DATATYPE_MISMATCH),
3841 errmsg("cannot compare arrays of different element types")));
3842
3843
3844 if (ndims1 != ndims2 ||
3845 memcmp(dims1, dims2, ndims1 * sizeof(int)) != 0 ||
3846 memcmp(lbs1, lbs2, ndims1 * sizeof(int)) != 0)
3847 result = false;
3848 else
3849 {
3850
3851
3852
3853
3854
3855
3856 typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
3857 if (typentry == NULL ||
3858 typentry->type_id != element_type)
3859 {
3864 (errcode(ERRCODE_UNDEFINED_FUNCTION),
3865 errmsg("could not identify an equality operator for type %s",
3867 fcinfo->flinfo->fn_extra = typentry;
3868 }
3869 typlen = typentry->typlen;
3870 typbyval = typentry->typbyval;
3872
3873
3874
3875
3877 collation, NULL, NULL);
3878
3879
3883
3885 {
3888 bool isnull1;
3889 bool isnull2;
3890 bool oprresult;
3891
3892
3894 typlen, typbyval, typalign);
3896 typlen, typbyval, typalign);
3897
3898
3899
3900
3901 if (isnull1 && isnull2)
3902 continue;
3903 if (isnull1 || isnull2)
3904 {
3905 result = false;
3906 break;
3907 }
3908
3909
3910
3911
3912 locfcinfo->args[0].value = elt1;
3913 locfcinfo->args[0].isnull = false;
3914 locfcinfo->args[1].value = elt2;
3915 locfcinfo->args[1].isnull = false;
3916 locfcinfo->isnull = false;
3918 if (locfcinfo->isnull || !oprresult)
3919 {
3920 result = false;
3921 break;
3922 }
3923 }
3924 }
3925
3926
3929
3931}
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3945{
3947}
3948
3951{
3953}
3954
3957{
3959}
3960
3963{
3965}
3966
3969{
3971}
3972
3975{
3977}
3978
3979
3980
3981
3982
3983
3984
3985static int
3987{
3999 int result = 0;
4001 int typlen;
4002 bool typbyval;
4004 int min_nitems;
4007 int i;
4008
4011 (errcode(ERRCODE_DATATYPE_MISMATCH),
4012 errmsg("cannot compare arrays of different element types")));
4013
4014
4015
4016
4017
4018
4019
4021 if (typentry == NULL ||
4022 typentry->type_id != element_type)
4023 {
4028 (errcode(ERRCODE_UNDEFINED_FUNCTION),
4029 errmsg("could not identify a comparison function for type %s",
4032 }
4033 typlen = typentry->typlen;
4034 typbyval = typentry->typbyval;
4036
4037
4038
4039
4041 collation, NULL, NULL);
4042
4043
4044 min_nitems = Min(nitems1, nitems2);
4047
4048 for (i = 0; i < min_nitems; i++)
4049 {
4052 bool isnull1;
4053 bool isnull2;
4054 int32 cmpresult;
4055
4056
4059
4060
4061
4062
4063 if (isnull1 && isnull2)
4064 continue;
4065 if (isnull1)
4066 {
4067
4068 result = 1;
4069 break;
4070 }
4071 if (isnull2)
4072 {
4073
4074 result = -1;
4075 break;
4076 }
4077
4078
4079 locfcinfo->args[0].value = elt1;
4080 locfcinfo->args[0].isnull = false;
4081 locfcinfo->args[1].value = elt2;
4082 locfcinfo->args[1].isnull = false;
4084
4085
4086 Assert(!locfcinfo->isnull);
4087
4088 if (cmpresult == 0)
4089 continue;
4090
4091 if (cmpresult < 0)
4092 {
4093
4094 result = -1;
4095 break;
4096 }
4097 else
4098 {
4099
4100 result = 1;
4101 break;
4102 }
4103 }
4104
4105
4106
4107
4108
4109
4110
4111 if (result == 0)
4112 {
4113 if (nitems1 != nitems2)
4114 result = (nitems1 < nitems2) ? -1 : 1;
4115 else if (ndims1 != ndims2)
4116 result = (ndims1 < ndims2) ? -1 : 1;
4117 else
4118 {
4119 for (i = 0; i < ndims1; i++)
4120 {
4121 if (dims1[i] != dims2[i])
4122 {
4123 result = (dims1[i] < dims2[i]) ? -1 : 1;
4124 break;
4125 }
4126 }
4127 if (result == 0)
4128 {
4131
4132 for (i = 0; i < ndims1; i++)
4133 {
4134 if (lbound1[i] != lbound2[i])
4135 {
4136 result = (lbound1[i] < lbound2[i]) ? -1 : 1;
4137 break;
4138 }
4139 }
4140 }
4141 }
4142 }
4143
4144
4147
4148 return result;
4149}
4150
4151
4152
4153
4154
4155
4156
4157
4160{
4169 int typlen;
4170 bool typbyval;
4172 int i;
4174
4175
4176
4177
4178
4179
4180
4181 typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
4182 if (typentry == NULL ||
4183 typentry->type_id != element_type)
4184 {
4189 (errcode(ERRCODE_UNDEFINED_FUNCTION),
4190 errmsg("could not identify a hash function for type %s",
4192
4193
4194
4195
4196
4197
4198
4199
4200 if (element_type == RECORDOID)
4201 {
4204
4206
4207
4208
4209
4210
4211
4213 record_typentry->type_id = element_type;
4214
4215
4220
4222
4223 typentry = record_typentry;
4224 }
4225
4226 fcinfo->flinfo->fn_extra = typentry;
4227 }
4228
4229 typlen = typentry->typlen;
4230 typbyval = typentry->typbyval;
4232
4233
4234
4235
4238
4239
4242
4244 {
4246 bool isnull;
4248
4249
4251
4252 if (isnull)
4253 {
4254
4255 elthash = 0;
4256 }
4257 else
4258 {
4259
4260 locfcinfo->args[0].value = elt;
4261 locfcinfo->args[0].isnull = false;
4263
4264 Assert(!locfcinfo->isnull);
4265 }
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278 result = (result << 5) - result + elthash;
4279 }
4280
4281
4283
4285}
4286
4287
4288
4289
4290
4293{
4303 int typlen;
4304 bool typbyval;
4306 int i;
4308
4309 typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
4310 if (typentry == NULL ||
4311 typentry->type_id != element_type)
4312 {
4317 (errcode(ERRCODE_UNDEFINED_FUNCTION),
4318 errmsg("could not identify an extended hash function for type %s",
4320 fcinfo->flinfo->fn_extra = typentry;
4321 }
4322 typlen = typentry->typlen;
4323 typbyval = typentry->typbyval;
4325
4328
4329
4332
4334 {
4336 bool isnull;
4338
4339
4341
4342 if (isnull)
4343 {
4344 elthash = 0;
4345 }
4346 else
4347 {
4348
4349 locfcinfo->args[0].value = elt;
4350 locfcinfo->args[0].isnull = false;
4352 locfcinfo->args[1].isnull = false;
4354
4355 Assert(!locfcinfo->isnull);
4356 }
4357
4358 result = (result << 5) - result + elthash;
4359 }
4360
4362
4364}
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381static bool
4383 bool matchall, void **fn_extra)
4384{
4386 bool result = matchall;
4389 int nelems1;
4391 bool *nulls2;
4392 int nelems2;
4393 int typlen;
4394 bool typbyval;
4396 int i;
4397 int j;
4399
4402 (errcode(ERRCODE_DATATYPE_MISMATCH),
4403 errmsg("cannot compare arrays of different element types")));
4404
4405
4406
4407
4408
4409
4410
4412 if (typentry == NULL ||
4413 typentry->type_id != element_type)
4414 {
4419 (errcode(ERRCODE_UNDEFINED_FUNCTION),
4420 errmsg("could not identify an equality operator for type %s",
4422 *fn_extra = typentry;
4423 }
4424 typlen = typentry->typlen;
4425 typbyval = typentry->typbyval;
4427
4428
4429
4430
4431
4432
4434 {
4435
4440 }
4441 else
4443 element_type, typlen, typbyval, typalign,
4444 &values2, &nulls2, &nelems2);
4445
4446
4447
4448
4450 collation, NULL, NULL);
4451
4452
4455
4456 for (i = 0; i < nelems1; i++)
4457 {
4459 bool isnull1;
4460
4461
4463
4464
4465
4466
4467
4468
4469 if (isnull1)
4470 {
4471 if (matchall)
4472 {
4473 result = false;
4474 break;
4475 }
4476 continue;
4477 }
4478
4479 for (j = 0; j < nelems2; j++)
4480 {
4482 bool isnull2 = nulls2 ? nulls2[j] : false;
4483 bool oprresult;
4484
4485 if (isnull2)
4486 continue;
4487
4488
4489
4490
4491 locfcinfo->args[0].value = elt1;
4492 locfcinfo->args[0].isnull = false;
4493 locfcinfo->args[1].value = elt2;
4494 locfcinfo->args[1].isnull = false;
4495 locfcinfo->isnull = false;
4497 if (!locfcinfo->isnull && oprresult)
4498 break;
4499 }
4500
4501 if (j < nelems2)
4502 {
4503
4504 if (!matchall)
4505 {
4506 result = true;
4507 break;
4508 }
4509 }
4510 else
4511 {
4512
4513 if (matchall)
4514 {
4515 result = false;
4516 break;
4517 }
4518 }
4519 }
4520
4521 return result;
4522}
4523
4526{
4530 bool result;
4531
4533 &fcinfo->flinfo->fn_extra);
4534
4535
4538
4540}
4541
4544{
4548 bool result;
4549
4551 &fcinfo->flinfo->fn_extra);
4552
4553
4556
4558}
4559
4562{
4566 bool result;
4567
4569 &fcinfo->flinfo->fn_extra);
4570
4571
4574
4576}
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4599{
4601
4602
4603
4604
4606 if (slice_ndim < 0 || slice_ndim > ARR_NDIM(arr))
4607 elog(ERROR, "invalid arguments to array_create_iterator");
4608
4609
4610
4611
4612 iterator->arr = arr;
4615
4616 if (mstate != NULL)
4617 {
4619
4623 }
4624 else
4629
4630
4631
4632
4634
4635 if (slice_ndim > 0)
4636 {
4637
4638
4639
4640
4641
4644
4645
4646
4647
4650
4651
4652
4653
4658 }
4659
4660
4661
4662
4663
4666
4667 return iterator;
4668}
4669
4670
4671
4672
4673
4674
4675
4676bool
4678{
4679
4681 return false;
4682
4684 {
4685
4686
4687
4689 {
4690 *isnull = true;
4692 }
4693 else
4694 {
4695
4696 char *p = iterator->data_ptr;
4697
4698 *isnull = false;
4700
4701
4705 }
4706 }
4707 else
4708 {
4709
4710
4711
4715 char *p = iterator->data_ptr;
4716 int i;
4717
4719 {
4722 {
4723 nulls[i] = true;
4725 }
4726 else
4727 {
4728 nulls[i] = false;
4730
4731
4734 }
4735 }
4736
4738
4740 nulls,
4748
4749 *isnull = false;
4751 }
4752
4753 return true;
4754}
4755
4756
4757
4758
4759void
4761{
4763 {
4766 }
4767 pfree(iterator);
4768}
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781static bool
4783{
4784 if (nullbitmap == NULL)
4785 return false;
4786 if (nullbitmap[offset / 8] & (1 << (offset % 8)))
4787 return false;
4788 return true;
4789}
4790
4791
4792
4793
4794
4795
4796
4797
4798static void
4800{
4801 int bitmask;
4802
4803 nullbitmap += offset / 8;
4804 bitmask = 1 << (offset % 8);
4805 if (isNull)
4806 *nullbitmap &= ~bitmask;
4807 else
4808 *nullbitmap |= bitmask;
4809}
4810
4811
4812
4813
4814
4815
4818{
4820}
4821
4822
4823
4824
4825
4826
4827static int
4829 int typlen,
4830 bool typbyval,
4833{
4834 int inc;
4835
4836 if (typlen > 0)
4837 {
4838 if (typbyval)
4840 else
4843 }
4844 else
4845 {
4850 }
4851
4852 return inc;
4853}
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866static char *
4868 int typlen, bool typbyval, char typalign)
4869{
4870 int bitmask;
4871 int i;
4872
4873
4874 if (typlen > 0 && !nullbitmap)
4876
4877
4878 if (nullbitmap)
4879 {
4880 nullbitmap += offset / 8;
4881 bitmask = 1 << (offset % 8);
4882
4884 {
4885 if (*nullbitmap & bitmask)
4886 {
4889 }
4890 bitmask <<= 1;
4891 if (bitmask == 0x100)
4892 {
4893 nullbitmap++;
4894 bitmask = 1;
4895 }
4896 }
4897 }
4898 else
4899 {
4901 {
4904 }
4905 }
4906 return ptr;
4907}
4908
4909
4910
4911
4912
4913
4914static int
4916 int typlen, bool typbyval, char typalign)
4917{
4919 typlen, typbyval, typalign) - ptr;
4920}
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936static int
4938 char *srcptr, int offset, bits8 *nullbitmap,
4939 int typlen, bool typbyval, char typalign)
4940{
4941 int numbytes;
4942
4944 typlen, typbyval, typalign);
4945 memcpy(destptr, srcptr, numbytes);
4946 return numbytes;
4947}
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966void
4968 const bits8 *srcbitmap, int srcoffset,
4970{
4971 int destbitmask,
4972 destbitval,
4973 srcbitmask,
4974 srcbitval;
4975
4978 return;
4979 destbitmap += destoffset / 8;
4980 destbitmask = 1 << (destoffset % 8);
4981 destbitval = *destbitmap;
4982 if (srcbitmap)
4983 {
4984 srcbitmap += srcoffset / 8;
4985 srcbitmask = 1 << (srcoffset % 8);
4986 srcbitval = *srcbitmap;
4987 while (nitems-- > 0)
4988 {
4989 if (srcbitval & srcbitmask)
4990 destbitval |= destbitmask;
4991 else
4992 destbitval &= ~destbitmask;
4993 destbitmask <<= 1;
4994 if (destbitmask == 0x100)
4995 {
4996 *destbitmap++ = destbitval;
4997 destbitmask = 1;
4999 destbitval = *destbitmap;
5000 }
5001 srcbitmask <<= 1;
5002 if (srcbitmask == 0x100)
5003 {
5004 srcbitmap++;
5005 srcbitmask = 1;
5007 srcbitval = *srcbitmap;
5008 }
5009 }
5010 if (destbitmask != 1)
5011 *destbitmap = destbitval;
5012 }
5013 else
5014 {
5015 while (nitems-- > 0)
5016 {
5017 destbitval |= destbitmask;
5018 destbitmask <<= 1;
5019 if (destbitmask == 0x100)
5020 {
5021 *destbitmap++ = destbitval;
5022 destbitmask = 1;
5024 destbitval = *destbitmap;
5025 }
5026 }
5027 if (destbitmask != 1)
5028 *destbitmap = destbitval;
5029 }
5030}
5031
5032
5033
5034
5035
5036
5037static int
5039 int ndim, int *dim, int *lb,
5040 int *st, int *endp,
5041 int typlen, bool typbyval, char typalign)
5042{
5043 int src_offset,
5048 char *ptr;
5049 int i,
5050 j,
5051 inc;
5052 int count = 0;
5053
5055
5056
5057 if (typlen > 0 && !arraynullsptr)
5059
5060
5062 ptr = array_seek(arraydataptr, 0, arraynullsptr, src_offset,
5063 typlen, typbyval, typalign);
5066 for (i = 0; i < ndim; i++)
5067 indx[i] = 0;
5068 j = ndim - 1;
5069 do
5070 {
5071 if (dist[j])
5072 {
5073 ptr = array_seek(ptr, src_offset, arraynullsptr, dist[j],
5074 typlen, typbyval, typalign);
5075 src_offset += dist[j];
5076 }
5078 {
5081 ptr += inc;
5082 count += inc;
5083 }
5084 src_offset++;
5086 return count;
5087}
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097static void
5099 int ndim,
5100 int *dim,
5101 int *lb,
5102 char *arraydataptr,
5103 bits8 *arraynullsptr,
5104 int *st,
5105 int *endp,
5106 int typlen,
5107 bool typbyval,
5109{
5112 char *srcdataptr;
5113 int src_offset,
5114 dest_offset,
5119 int i,
5120 j,
5121 inc;
5122
5124 srcdataptr = array_seek(arraydataptr, 0, arraynullsptr, src_offset,
5125 typlen, typbyval, typalign);
5129 for (i = 0; i < ndim; i++)
5130 indx[i] = 0;
5131 dest_offset = 0;
5132 j = ndim - 1;
5133 do
5134 {
5135 if (dist[j])
5136 {
5137
5138 srcdataptr = array_seek(srcdataptr, src_offset, arraynullsptr,
5139 dist[j],
5140 typlen, typbyval, typalign);
5141 src_offset += dist[j];
5142 }
5144 srcdataptr, src_offset, arraynullsptr,
5145 typlen, typbyval, typalign);
5146 if (destnullsptr)
5148 arraynullsptr, src_offset,
5149 1);
5150 destdataptr += inc;
5151 srcdataptr += inc;
5152 src_offset++;
5153 dest_offset++;
5155}
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170static void
5174 int ndim,
5175 int *dim,
5176 int *lb,
5177 int *st,
5178 int *endp,
5179 int typlen,
5180 bool typbyval,
5182{
5191 int dest_offset,
5192 orig_offset,
5193 src_offset,
5198 int i,
5199 j,
5200 inc;
5201
5203
5204 inc = array_copy(destPtr, dest_offset,
5205 origPtr, 0, origBitmap,
5206 typlen, typbyval, typalign);
5207 destPtr += inc;
5208 origPtr += inc;
5209 if (destBitmap)
5211 orig_offset = dest_offset;
5215 for (i = 0; i < ndim; i++)
5216 indx[i] = 0;
5217 src_offset = 0;
5218 j = ndim - 1;
5219 do
5220 {
5221
5222 if (dist[j])
5223 {
5225 origPtr, orig_offset, origBitmap,
5226 typlen, typbyval, typalign);
5227 destPtr += inc;
5228 origPtr += inc;
5229 if (destBitmap)
5231 origBitmap, orig_offset,
5232 dist[j]);
5233 dest_offset += dist[j];
5234 orig_offset += dist[j];
5235 }
5236
5238 srcPtr, src_offset, srcBitmap,
5239 typlen, typbyval, typalign);
5240 if (destBitmap)
5242 srcBitmap, src_offset,
5243 1);
5244 destPtr += inc;
5245 srcPtr += inc;
5246 dest_offset++;
5247 src_offset++;
5248
5249 origPtr = array_seek(origPtr, orig_offset, origBitmap, 1,
5250 typlen, typbyval, typalign);
5251 orig_offset++;
5253
5254
5255 array_copy(destPtr, orignitems - orig_offset,
5256 origPtr, orig_offset, origBitmap,
5257 typlen, typbyval, typalign);
5258 if (destBitmap)
5260 origBitmap, orig_offset,
5261 orignitems - orig_offset);
5262}
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5295{
5296
5297
5298
5299
5300
5302 subcontext ? 64 : 8);
5303}
5304
5305
5306
5307
5308
5309
5312 bool subcontext, int initsize)
5313{
5316
5317
5318 if (subcontext)
5320 "accumArrayResult",
5322
5325 astate->mcontext = arr_context;
5327 astate->alen = initsize;
5330 astate->dnulls = (bool *)
5338
5339 return astate;
5340}
5341
5342
5343
5344
5345
5346
5347
5348
5349
5352 Datum dvalue, bool disnull,
5353 Oid element_type,
5355{
5357
5358 if (astate == NULL)
5359 {
5360
5362 }
5363 else
5364 {
5366 }
5367
5369
5370
5372 {
5373 astate->alen *= 2;
5374
5377 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5378 errmsg("array size exceeds the maximum allowed (%zu)",
5382 astate->dnulls = (bool *)
5384 }
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394 if (!disnull && !astate->typbyval)
5395 {
5396 if (astate->typlen == -1)
5398 else
5400 }
5401
5405
5407
5408 return astate;
5409}
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5423{
5424 int ndims;
5425 int dims[1];
5426 int lbs[1];
5427
5428
5429 ndims = (astate->nelems > 0) ? 1 : 0;
5430 dims[0] = astate->nelems;
5431 lbs[0] = 1;
5432
5435}
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5454 int ndims,
5455 int *dims,
5456 int *lbs,
5458 bool release)
5459{
5462
5463
5465
5468 ndims,
5469 dims,
5470 lbs,
5475
5477
5478
5479 if (release)
5480 {
5483 }
5484
5486}
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5506 bool subcontext)
5507{
5509 MemoryContext arr_context = rcontext;
5510
5511
5513 {
5515
5518 (errcode(ERRCODE_DATATYPE_MISMATCH),
5519 errmsg("data type %s is not an array type",
5521 }
5522
5523
5524 if (subcontext)
5526 "accumArrayResultArr",
5528
5529
5532 astate->mcontext = arr_context;
5534
5535
5538
5539 return astate;
5540}
5541
5542
5543
5544
5545
5546
5547
5548
5549
5552 Datum dvalue, bool disnull,
5553 Oid array_type,
5555{
5558 int *dims,
5559 *lbs,
5560 ndims,
5562 ndatabytes;
5564 int i;
5565
5566
5567
5568
5569
5570
5571 if (disnull)
5573 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5574 errmsg("cannot accumulate null arrays")));
5575
5576
5578
5579 if (astate == NULL)
5581 else
5583
5585
5586
5593
5594 if (astate->ndims == 0)
5595 {
5596
5597
5598
5599 if (ndims == 0)
5601 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5602 errmsg("cannot accumulate empty arrays")));
5603 if (ndims + 1 > MAXDIM)
5605 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5606 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
5607 ndims + 1, MAXDIM)));
5608
5609
5610
5611
5612
5613 astate->ndims = ndims + 1;
5614 astate->dims[0] = 0;
5615 memcpy(&astate->dims[1], dims, ndims * sizeof(int));
5616 astate->lbs[0] = 1;
5617 memcpy(&astate->lbs[1], lbs, ndims * sizeof(int));
5618
5619
5622 }
5623 else
5624 {
5625
5626 if (astate->ndims != ndims + 1)
5628 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5629 errmsg("cannot accumulate arrays of different dimensionality")));
5630 for (i = 0; i < ndims; i++)
5631 {
5632 if (astate->dims[i + 1] != dims[i] || astate->lbs[i + 1] != lbs[i])
5634 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5635 errmsg("cannot accumulate arrays of different dimensionality")));
5636 }
5637
5638
5639 if (astate->nbytes + ndatabytes > astate->abytes)
5640 {
5642 astate->nbytes + ndatabytes);
5644 }
5645 }
5646
5647
5648
5649
5650
5651
5652
5653 memcpy(astate->data + astate->nbytes, data, ndatabytes);
5654 astate->nbytes += ndatabytes;
5655
5656
5658 {
5660
5662 {
5663
5664
5665
5666
5670 NULL, 0,
5672 }
5673 else if (newnitems > astate->aitems)
5674 {
5678 }
5682 }
5683
5685 astate->dims[0] += 1;
5686
5688
5689
5692
5693 return astate;
5694}
5695
5696
5697
5698
5699
5700
5701
5702
5706 bool release)
5707{
5710
5711
5713
5714 if (astate->ndims == 0)
5715 {
5716
5718 }
5719 else
5720 {
5721 int dataoffset,
5722 nbytes;
5723
5724
5727
5728
5729 nbytes = astate->nbytes;
5731 {
5733 nbytes += dataoffset;
5734 }
5735 else
5736 {
5737 dataoffset = 0;
5739 }
5740
5746
5747 memcpy(ARR_DIMS(result), astate->dims, astate->ndims * sizeof(int));
5748 memcpy(ARR_LBOUND(result), astate->lbs, astate->ndims * sizeof(int));
5750
5755 }
5756
5758
5759
5760 if (release)
5761 {
5764 }
5765
5767}
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5784{
5786
5787
5788
5789
5790
5791
5792
5794 {
5795
5797
5804 }
5805 else
5806 {
5807
5809
5810 scalarstate = initArrayResult(input_type, rcontext, subcontext);
5816 }
5817
5818 return astate;
5819}
5820
5821
5822
5823
5824
5825
5826
5827
5828
5831 Datum dvalue, bool disnull,
5832 Oid input_type,
5834{
5835 if (astate == NULL)
5837
5840 dvalue, disnull,
5841 input_type, rcontext);
5842 else
5844 dvalue, disnull,
5845 input_type, rcontext);
5846
5847 return astate;
5848}
5849
5850
5851
5852
5853
5854
5855
5856
5860{
5862
5864 {
5865
5866 int ndims;
5867 int dims[1];
5868 int lbs[1];
5869
5870
5873 lbs[0] = 1;
5874
5876 rcontext, release);
5877 }
5878 else
5879 {
5881 rcontext, release);
5882 }
5883 return result;
5884}
5885
5886
5889{
5892 else
5894}
5895
5898{
5901 else
5903}
5904
5905
5907{
5912
5913
5914
5915
5916
5919{
5923
5924
5926 {
5929 int *lb,
5930 *dimv;
5931
5932
5934
5935
5938
5939
5940 if (reqdim <= 0 || reqdim > AARR_NDIM(v))
5942
5943
5944
5945
5948
5951
5952 fctx->lower = lb[reqdim - 1];
5953 fctx->upper = dimv[reqdim - 1] + lb[reqdim - 1] - 1;
5955
5957
5959 }
5960
5962
5964
5966 {
5969 else
5971 }
5972 else
5973
5975}
5976
5977
5978
5979
5980
5983{
5984
5986}
5987
5988
5989
5990
5991
5994{
5998 Oid elmtype;
6000 bool isnull;
6001
6004 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6005 errmsg("dimension array or low bound array cannot be null")));
6006
6009
6011 {
6013 isnull = false;
6014 }
6015 else
6016 {
6018 isnull = true;
6019 }
6020
6023 elog(ERROR, "could not determine data type of input");
6024
6027}
6028
6029
6030
6031
6032
6035{
6038 Oid elmtype;
6040 bool isnull;
6041
6044 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6045 errmsg("dimension array or low bound array cannot be null")));
6046
6048
6050 {
6052 isnull = false;
6053 }
6054 else
6055 {
6057 isnull = true;
6058 }
6059
6062 elog(ERROR, "could not determine data type of input");
6063
6066}
6067
6070 Oid elmtype, int dataoffset)
6071{
6073
6076 result->ndim = ndims;
6079 memcpy(ARR_DIMS(result), dimv, ndims * sizeof(int));
6080 memcpy(ARR_LBOUND(result), lbsv, ndims * sizeof(int));
6081
6082 return result;
6083}
6084
6089{
6091 int *dimv;
6092 int *lbsv;
6093 int ndims;
6097 bool elmbyval;
6098 char elmalign;
6100
6101
6102
6103
6106 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
6107 errmsg("wrong number of array subscripts"),
6108 errdetail("Dimension array must be one dimensional.")));
6109
6112 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6113 errmsg("dimension values cannot be null")));
6114
6117
6118 if (ndims < 0)
6120 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6121 errmsg("invalid number of dimensions: %d", ndims)));
6124 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
6125 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
6127
6128 if (lbs != NULL)
6129 {
6132 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
6133 errmsg("wrong number of array subscripts"),
6134 errdetail("Dimension array must be one dimensional.")));
6135
6138 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6139 errmsg("dimension values cannot be null")));
6140
6143 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
6144 errmsg("wrong number of array subscripts"),
6145 errdetail("Low bound array has different size than dimensions array.")));
6146
6148 }
6149 else
6150 {
6151 int i;
6152
6154 deflbs[i] = 1;
6155
6156 lbsv = deflbs;
6157 }
6158
6159
6162
6163
6166
6167
6168
6169
6170
6172 if (my_extra == NULL)
6173 {
6178 }
6179
6181 {
6182
6188 }
6189
6190 elmlen = my_extra->typlen;
6191 elmbyval = my_extra->typbyval;
6192 elmalign = my_extra->typalign;
6193
6194
6195 if (!isnull)
6196 {
6197 int i;
6198 char *p;
6199 int nbytes;
6200 int totbytes;
6201
6202
6203 if (elmlen == -1)
6205
6209
6210 totbytes = nbytes * nitems;
6211
6212
6213 if (totbytes / nbytes != nitems ||
6216 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
6217 errmsg("array size exceeds the maximum allowed (%zu)",
6219
6220
6221
6222
6223
6225
6227 elmtype, 0);
6228
6232 }
6233 else
6234 {
6235 int nbytes;
6236 int dataoffset;
6237
6239 nbytes = dataoffset;
6240
6242 elmtype, dataoffset);
6243
6244
6245 }
6246
6247 return result;
6248}
6249
6250
6251
6252
6253
6256{
6257 typedef struct
6258 {
6260 int nextelem;
6261 int numelems;
6263 bool elmbyval;
6264 char elmalign;
6265 } array_unnest_fctx;
6266
6268 array_unnest_fctx *fctx;
6270
6271
6273 {
6275
6276
6278
6279
6280
6281
6283
6284
6285
6286
6287
6288
6289
6290
6292
6293
6295
6296
6298 fctx->nextelem = 0;
6300
6302 {
6303
6307 }
6308 else
6310 &fctx->elmlen,
6311 &fctx->elmbyval,
6312 &fctx->elmalign);
6313
6316 }
6317
6318
6321
6322 if (fctx->nextelem < fctx->numelems)
6323 {
6324 int offset = fctx->nextelem++;
6326
6327 elem = array_iter_next(&fctx->iter, &fcinfo->isnull, offset,
6328 fctx->elmlen, fctx->elmbyval, fctx->elmalign);
6329
6331 }
6332 else
6333 {
6334
6336 }
6337}
6338
6339
6340
6341
6342
6343
6344
6347{
6349 Node *ret = NULL;
6350
6352 {
6353
6355
6357 {
6360
6361
6363
6365 ret = (Node *) req;
6366 }
6367 }
6368
6370}
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6383 Datum search, bool search_isnull,
6384 Datum replace, bool replace_isnull,
6385 bool remove, Oid collation,
6387{
6390 Oid element_type;
6392 bool *nulls;
6393 int *dim;
6394 int ndim;
6396 nresult;
6397 int i;
6398 int32 nbytes = 0;
6399 int32 dataoffset;
6400 bool hasnulls;
6401 int typlen;
6402 bool typbyval;
6404 char *arraydataptr;
6406 int bitmask;
6407 bool changed = false;
6409
6414
6415
6417 return array;
6418
6419
6420
6421
6422
6423 if (remove && ndim > 1)
6425 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6426 errmsg("removing elements from multidimensional arrays is not supported")));
6427
6428
6429
6430
6431
6433 if (typentry == NULL ||
6434 typentry->type_id != element_type)
6435 {
6440 (errcode(ERRCODE_UNDEFINED_FUNCTION),
6441 errmsg("could not identify an equality operator for type %s",
6444 }
6445 typlen = typentry->typlen;
6446 typbyval = typentry->typbyval;
6448
6449
6450
6451
6452
6453
6454 if (typlen == -1)
6455 {
6456 if (!search_isnull)
6458 if (!replace_isnull)
6460 }
6461
6462
6464 collation, NULL, NULL);
6465
6466
6468 nulls = (bool *) palloc(nitems * sizeof(bool));
6469
6470
6473 bitmask = 1;
6474 hasnulls = false;
6475 nresult = 0;
6476
6478 {
6480 bool isNull;
6481 bool oprresult;
6482 bool skip = false;
6483
6484
6485 if (bitmap && (*bitmap & bitmask) == 0)
6486 {
6487 isNull = true;
6488
6489 if (search_isnull)
6490 {
6491 if (remove)
6492 {
6493 skip = true;
6494 changed = true;
6495 }
6496 else if (!replace_isnull)
6497 {
6498 values[nresult] = replace;
6499 isNull = false;
6500 changed = true;
6501 }
6502 }
6503 }
6504 else
6505 {
6506 isNull = false;
6507 elt = fetch_att(arraydataptr, typbyval, typlen);
6510
6511 if (search_isnull)
6512 {
6513
6514 values[nresult] = elt;
6515 }
6516 else
6517 {
6518
6519
6520
6521 locfcinfo->args[0].value = elt;
6522 locfcinfo->args[0].isnull = false;
6523 locfcinfo->args[1].value = search;
6524 locfcinfo->args[1].isnull = false;
6525 locfcinfo->isnull = false;
6527 if (locfcinfo->isnull || !oprresult)
6528 {
6529
6530 values[nresult] = elt;
6531 }
6532 else
6533 {
6534
6535 changed = true;
6536 if (remove)
6537 skip = true;
6538 else
6539 {
6540 values[nresult] = replace;
6541 isNull = replace_isnull;
6542 }
6543 }
6544 }
6545 }
6546
6548 {
6549 nulls[nresult] = isNull;
6550 if (isNull)
6551 hasnulls = true;
6552 else
6553 {
6554
6557
6560 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
6561 errmsg("array size exceeds the maximum allowed (%zu)",
6563 }
6564 nresult++;
6565 }
6566
6567
6568 if (bitmap)
6569 {
6570 bitmask <<= 1;
6571 if (bitmask == 0x100)
6572 {
6573 bitmap++;
6574 bitmask = 1;
6575 }
6576 }
6577 }
6578
6579
6580
6581
6582 if (!changed)
6583 {
6586 return array;
6587 }
6588
6589
6590 if (nresult == 0)
6591 {
6595 }
6596
6597
6598 if (hasnulls)
6599 {
6601 nbytes += dataoffset;
6602 }
6603 else
6604 {
6605 dataoffset = 0;
6607 }
6610 result->ndim = ndim;
6612 result->elemtype = element_type;
6613 memcpy(ARR_DIMS(result), ARR_DIMS(array), ndim * sizeof(int));
6615
6616 if (remove)
6617 {
6618
6619 ARR_DIMS(result)[0] = nresult;
6620 }
6621
6622
6624 values, nulls, nresult,
6626 false);
6627
6630
6631 return result;
6632}
6633
6634
6635
6636
6637
6638
6641{
6645
6649
6651 search, search_isnull,
6652 (Datum) 0, true,
6654 fcinfo);
6656}
6657
6658
6659
6660
6663{
6669
6673
6675 search, search_isnull,
6676 replace, replace_isnull,
6678 fcinfo);
6680}
6681
6682
6683
6684
6685
6686
6687
6688
6689
6692{
6697 int result;
6698
6699
6700 if (ARR_NDIM(thresholds) > 1)
6702 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
6703 errmsg("thresholds must be one-dimensional array")));
6704
6707 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6708 errmsg("thresholds array must not contain NULLs")));
6709
6710
6711 if (element_type == FLOAT8OID)
6713 else
6714 {
6716
6717
6718 typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
6719 if (typentry == NULL ||
6720 typentry->type_id != element_type)
6721 {
6726 (errcode(ERRCODE_UNDEFINED_FUNCTION),
6727 errmsg("could not identify a comparison function for type %s",
6729 fcinfo->flinfo->fn_extra = typentry;
6730 }
6731
6732
6733
6734
6735
6736 if (typentry->typlen > 0)
6738 collation, typentry);
6739 else
6741 collation, typentry);
6742 }
6743
6744
6746
6748}
6749
6750
6751
6752
6753static int
6755{
6757 float8 *thresholds_data;
6758 int left;
6759 int right;
6760
6761
6762
6763
6764
6766
6767 left = 0;
6769
6770
6771
6772
6773
6774
6775
6776
6777 if (isnan(op))
6778 return right;
6779
6780
6781 while (left < right)
6782 {
6783 int mid = (left + right) / 2;
6784
6785 if (isnan(thresholds_data[mid]) || op < thresholds_data[mid])
6786 right = mid;
6787 else
6788 left = mid + 1;
6789 }
6790
6791 return left;
6792}
6793
6794
6795
6796
6797static int
6800 Oid collation,
6802{
6804 char *thresholds_data;
6805 int typlen = typentry->typlen;
6806 bool typbyval = typentry->typbyval;
6807 int left;
6808 int right;
6809
6810
6811
6812
6813
6814 thresholds_data = (char *) ARR_DATA_PTR(thresholds);
6815
6817 collation, NULL, NULL);
6818
6819
6820 left = 0;
6822 while (left < right)
6823 {
6824 int mid = (left + right) / 2;
6825 char *ptr;
6826 int32 cmpresult;
6827
6828 ptr = thresholds_data + mid * typlen;
6829
6830 locfcinfo->args[0].value = operand;
6831 locfcinfo->args[0].isnull = false;
6832 locfcinfo->args[1].value = fetch_att(ptr, typbyval, typlen);
6833 locfcinfo->args[1].isnull = false;
6834
6836
6837
6838 Assert(!locfcinfo->isnull);
6839
6840 if (cmpresult < 0)
6841 right = mid;
6842 else
6843 left = mid + 1;
6844 }
6845
6846 return left;
6847}
6848
6849
6850
6851
6852static int
6855 Oid collation,
6857{
6859 char *thresholds_data;
6860 int typlen = typentry->typlen;
6861 bool typbyval = typentry->typbyval;
6863 int left;
6864 int right;
6865
6866 thresholds_data = (char *) ARR_DATA_PTR(thresholds);
6867
6869 collation, NULL, NULL);
6870
6871
6872 left = 0;
6874 while (left < right)
6875 {
6876 int mid = (left + right) / 2;
6877 char *ptr;
6878 int i;
6879 int32 cmpresult;
6880
6881
6882 ptr = thresholds_data;
6883 for (i = left; i < mid; i++)
6884 {
6887 }
6888
6889 locfcinfo->args[0].value = operand;
6890 locfcinfo->args[0].isnull = false;
6891 locfcinfo->args[1].value = fetch_att(ptr, typbyval, typlen);
6892 locfcinfo->args[1].isnull = false;
6893
6895
6896
6897 Assert(!locfcinfo->isnull);
6898
6899 if (cmpresult < 0)
6900 right = mid;
6901 else
6902 {
6903 left = mid + 1;
6904
6905
6906
6907
6908
6909
6912 }
6913 }
6914
6915 return left;
6916}
6917
6918
6919
6920
6921
6924{
6929 bool elmbyval;
6930 char elmalign;
6933 bool lowerProvided[MAXDIM];
6934 bool upperProvided[MAXDIM];
6936
6937
6940 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
6941 errmsg("number of elements to trim must be between 0 and %d",
6943
6944
6945 memset(lowerProvided, false, sizeof(lowerProvided));
6946 memset(upperProvided, false, sizeof(upperProvided));
6948 {
6950 upperProvided[0] = true;
6951 }
6952
6953
6955
6956
6958 upper, lower, upperProvided, lowerProvided,
6959 -1, elmlen, elmbyval, elmalign);
6960
6962}
#define PG_GETARG_ANY_ARRAY_P(n)
#define PG_GETARG_ARRAYTYPE_P(n)
#define ARR_NULLBITMAP(a)
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
#define DatumGetArrayTypeP(X)
#define PG_RETURN_ARRAYTYPE_P(x)
#define ARR_OVERHEAD_NONULLS(ndims)
#define ARR_DATA_OFFSET(a)
Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
void deconstruct_expanded_array(ExpandedArrayHeader *eah)
ExpandedArrayHeader * DatumGetExpandedArray(Datum d)
AnyArrayType * DatumGetAnyArrayP(Datum d)
static Datum array_iter_next(array_iter *it, bool *isnull, int i, int elmlen, bool elmbyval, char elmalign)
static void array_iter_setup(array_iter *it, AnyArrayType *a)
Datum array_eq(PG_FUNCTION_ARGS)
Datum arraycontained(PG_FUNCTION_ARGS)
Datum array_lt(PG_FUNCTION_ARGS)
ArrayType * array_set(ArrayType *array, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
static bool ReadArrayStr(char **srcptr, FmgrInfo *inputproc, Oid typioparam, int32 typmod, char typdelim, int typlen, bool typbyval, char typalign, int *ndim_p, int *dim, int *nitems_p, Datum **values_p, bool **nulls_p, const char *origStr, Node *escontext)
Datum array_fill(PG_FUNCTION_ARGS)
Datum array_replace(PG_FUNCTION_ARGS)
static ArrayType * array_replace_internal(ArrayType *array, Datum search, bool search_isnull, Datum replace, bool replace_isnull, bool remove, Oid collation, FunctionCallInfo fcinfo)
Datum array_smaller(PG_FUNCTION_ARGS)
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
static bool ReadArrayDimensions(char **srcptr, int *ndim_p, int *dim, int *lBound, const char *origStr, Node *escontext)
Datum array_cardinality(PG_FUNCTION_ARGS)
ExpandedArrayHeader * construct_empty_expanded_array(Oid element_type, MemoryContext parentcontext, ArrayMetaState *metacache)
bool array_iterate(ArrayIterator iterator, Datum *value, bool *isnull)
static Datum array_set_element_expanded(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
void array_free_iterator(ArrayIterator iterator)
Datum array_recv(PG_FUNCTION_ARGS)
Datum generate_subscripts_nodir(PG_FUNCTION_ARGS)
Datum hash_array(PG_FUNCTION_ARGS)
static int width_bucket_array_float8(Datum operand, ArrayType *thresholds)
ArrayBuildStateAny * initArrayResultAny(Oid input_type, MemoryContext rcontext, bool subcontext)
ArrayBuildStateAny * accumArrayResultAny(ArrayBuildStateAny *astate, Datum dvalue, bool disnull, Oid input_type, MemoryContext rcontext)
ArrayType * construct_empty_array(Oid elmtype)
Datum array_dims(PG_FUNCTION_ARGS)
bool array_contains_nulls(const ArrayType *array)
static ArrayToken ReadArrayToken(char **srcptr, StringInfo elembuf, char typdelim, const char *origStr, Node *escontext)
Datum arraycontains(PG_FUNCTION_ARGS)
static int array_slice_size(char *arraydataptr, bits8 *arraynullsptr, int ndim, int *dim, int *lb, int *st, int *endp, int typlen, bool typbyval, char typalign)
static bool array_get_isnull(const bits8 *nullbitmap, int offset)
Datum makeArrayResultArr(ArrayBuildStateArr *astate, MemoryContext rcontext, bool release)
#define AARR_FREE_IF_COPY(array, n)
Datum array_upper(PG_FUNCTION_ARGS)
Datum makeArrayResultAny(ArrayBuildStateAny *astate, MemoryContext rcontext, bool release)
static ArrayType * array_fill_internal(ArrayType *dims, ArrayType *lbs, Datum value, bool isnull, Oid elmtype, FunctionCallInfo fcinfo)
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Datum array_map(Datum arrayd, ExprState *exprstate, ExprContext *econtext, Oid retType, ArrayMapState *amstate)
Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)
struct ArrayIteratorData ArrayIteratorData
static bool ReadDimensionInt(char **srcptr, int *result, const char *origStr, Node *escontext)
ArrayBuildStateArr * initArrayResultArr(Oid array_type, Oid element_type, MemoryContext rcontext, bool subcontext)
static bool array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation, bool matchall, void **fn_extra)
Datum array_lower(PG_FUNCTION_ARGS)
static int width_bucket_array_fixed(Datum operand, ArrayType *thresholds, Oid collation, TypeCacheEntry *typentry)
ArrayBuildStateArr * accumArrayResultArr(ArrayBuildStateArr *astate, Datum dvalue, bool disnull, Oid array_type, MemoryContext rcontext)
static int array_cmp(FunctionCallInfo fcinfo)
ArrayIterator array_create_iterator(ArrayType *arr, int slice_ndim, ArrayMetaState *mstate)
Datum btarraycmp(PG_FUNCTION_ARGS)
Datum array_ref(ArrayType *array, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
static void ReadArrayBinary(StringInfo buf, int nitems, FmgrInfo *receiveproc, Oid typioparam, int32 typmod, int typlen, bool typbyval, char typalign, Datum *values, bool *nulls, bool *hasnulls, int32 *nbytes)
static Datum array_get_element_expanded(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
ArrayBuildState * initArrayResultWithSize(Oid element_type, MemoryContext rcontext, bool subcontext, int initsize)
Datum hash_array_extended(PG_FUNCTION_ARGS)
Datum generate_subscripts(PG_FUNCTION_ARGS)
static void array_insert_slice(ArrayType *destArray, ArrayType *origArray, ArrayType *srcArray, int ndim, int *dim, int *lb, int *st, int *endp, int typlen, bool typbyval, char typalign)
Datum array_send(PG_FUNCTION_ARGS)
Datum array_le(PG_FUNCTION_ARGS)
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
static int array_copy(char *destptr, int nitems, char *srcptr, int offset, bits8 *nullbitmap, int typlen, bool typbyval, char typalign)
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Datum array_gt(PG_FUNCTION_ARGS)
Datum array_unnest(PG_FUNCTION_ARGS)
static ArrayType * create_array_envelope(int ndims, int *dimv, int *lbsv, int nbytes, Oid elmtype, int dataoffset)
Datum array_remove(PG_FUNCTION_ARGS)
Datum array_ne(PG_FUNCTION_ARGS)
Datum array_larger(PG_FUNCTION_ARGS)
Datum array_in(PG_FUNCTION_ARGS)
static void array_extract_slice(ArrayType *newarray, int ndim, int *dim, int *lb, char *arraydataptr, bits8 *arraynullsptr, int *st, int *endp, int typlen, bool typbyval, char typalign)
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
static int width_bucket_array_variable(Datum operand, ArrayType *thresholds, Oid collation, TypeCacheEntry *typentry)
Datum array_length(PG_FUNCTION_ARGS)
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
static int array_nelems_size(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)
static void array_set_isnull(bits8 *nullbitmap, int offset, bool isNull)
void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
static int ArrayCastAndSet(Datum src, int typlen, bool typbyval, char typalign, char *dest)
static Datum ArrayCast(char *value, bool byval, int len)
Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
Datum array_out(PG_FUNCTION_ARGS)
Datum array_fill_with_lower_bounds(PG_FUNCTION_ARGS)
Datum array_ndims(PG_FUNCTION_ARGS)
static char * array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)
Datum array_get_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Datum array_ge(PG_FUNCTION_ARGS)
Datum width_bucket_array(PG_FUNCTION_ARGS)
Datum arrayoverlap(PG_FUNCTION_ARGS)
Datum array_set_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, Datum srcArrayDatum, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
void CopyArrayEls(ArrayType *array, const Datum *values, const bool *nulls, int nitems, int typlen, bool typbyval, char typalign, bool freedata)
Datum trim_array(PG_FUNCTION_ARGS)
Datum array_unnest_support(PG_FUNCTION_ARGS)
struct generate_subscripts_fctx generate_subscripts_fctx
void mda_get_offset_values(int n, int *dist, const int *prod, const int *span)
int ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx)
void mda_get_range(int n, int *span, const int *st, const int *endp)
int ArrayGetNItems(int ndim, const int *dims)
void mda_get_prod(int n, const int *range, int *prod)
void ArrayCheckBounds(int ndim, const int *dims, const int *lb)
int mda_next_tuple(int n, int *curr, const int *span)
static Datum values[MAXATTR]
#define FORMAT_TYPE_ALLOW_INVALID
#define OidIsValid(objectId)
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Datum datumCopy(Datum value, bool typByVal, int typLen)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereturn(context, dummy_value,...)
#define ereport(elevel,...)
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
ExpandedObjectHeader * DatumGetEOHP(Datum d)
#define VARATT_IS_EXPANDED_HEADER(PTR)
static Datum EOHPGetRWDatum(const struct ExpandedObjectHeader *eohptr)
#define palloc_object(type)
#define repalloc_array(pointer, type, count)
#define palloc_array(type, count)
#define palloc0_array(type, count)
#define palloc0_object(type)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
bool InputFunctionCallSafe(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod, Node *escontext, Datum *result)
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf, Oid typioparam, int32 typmod)
#define PG_FREE_IF_COPY(ptr, n)
#define PG_RETURN_UINT32(x)
#define PG_RETURN_BYTEA_P(x)
#define PG_DETOAST_DATUM_COPY(datum)
#define PG_GETARG_POINTER(n)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
#define PG_RETURN_CSTRING(x)
#define PG_GETARG_DATUM(n)
#define LOCAL_FCINFO(name, nargs)
#define PG_GETARG_CSTRING(n)
#define PG_GETARG_INT64(n)
#define PG_RETURN_UINT64(x)
#define PG_DETOAST_DATUM(datum)
#define FunctionCallInvoke(fcinfo)
#define PG_RETURN_TEXT_P(x)
#define PG_RETURN_INT32(x)
#define PG_GETARG_INT32(n)
#define PG_GETARG_BOOL(n)
#define PG_RETURN_DATUM(x)
#define PG_RETURN_POINTER(x)
#define PG_GET_COLLATION()
#define PG_RETURN_BOOL(x)
char * format_type_extended(Oid type_oid, int32 typemod, bits16 flags)
char * format_type_be(Oid type_oid)
#define SRF_IS_FIRSTCALL()
#define SRF_PERCALL_SETUP()
#define SRF_RETURN_NEXT(_funcctx, _result)
#define SRF_FIRSTCALL_INIT()
#define SRF_RETURN_DONE(_funcctx)
Assert(PointerIsAligned(start, uint64))
static bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
if(TABLE==NULL||TABLE_index==NULL)
struct ItemPointerData ItemPointerData
Oid get_element_type(Oid typid)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
void get_type_io_data(Oid typid, IOFuncSelector which_func, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *func)
Oid get_array_type(Oid typid)
void * MemoryContextAlloc(MemoryContext context, Size size)
void * MemoryContextAllocZero(MemoryContext context, Size size)
char * pstrdup(const char *in)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define AllocSizeIsValid(size)
static bool is_funcclause(const void *clause)
#define IsA(nodeptr, _type_)
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static uint32 pg_nextpower2_32(uint32 num)
static const struct exclude_list_item skip[]
static char buf[DEFAULT_XLOG_SEG_SIZE]
int pg_strcasecmp(const char *s1, const char *s2)
static uint32 DatumGetUInt32(Datum X)
static Datum Int64GetDatum(int64 X)
static uint64 DatumGetUInt64(Datum X)
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
static float8 DatumGetFloat8(Datum X)
static Pointer DatumGetPointer(Datum X)
static Datum Int32GetDatum(int32 X)
static int32 DatumGetInt32(Datum X)
unsigned int pq_getmsgint(StringInfo msg, int b)
void pq_sendbytes(StringInfo buf, const void *data, int datalen)
void pq_begintypsend(StringInfo buf)
bytea * pq_endtypsend(StringInfo buf)
static void pq_sendint32(StringInfo buf, uint32 i)
bool scanner_isspace(char ch)
double estimate_array_length(PlannerInfo *root, Node *arrayexpr)
struct StringInfoData * StringInfo
void resetStringInfo(StringInfo str)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
static void initReadOnlyStringInfo(StringInfo str, char *data, int len)
ArrayBuildStateArr * arraystate
ArrayBuildState * scalarstate
MemoryContext eoh_context
bool * innermost_casenull
Datum * innermost_caseval
MemoryContext multi_call_memory_ctx
FmgrInfo hash_extended_proc_finfo
#define FirstGenbkiObjectId
#define att_align_nominal(cur_offset, attalign)
#define att_addlength_pointer(cur_offset, attlen, attptr)
static Datum fetch_att(const void *T, bool attbyval, int attlen)
#define att_addlength_datum(cur_offset, attlen, attdatum)
static void store_att_byval(void *T, Datum newdatum, int attlen)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
#define TYPECACHE_HASH_PROC_FINFO
#define TYPECACHE_EQ_OPR_FINFO
#define TYPECACHE_HASH_EXTENDED_PROC_FINFO
#define TYPECACHE_CMP_PROC_FINFO
static Size VARSIZE(const void *PTR)
static char * VARDATA(const void *PTR)
static bool VARATT_IS_EXTERNAL_EXPANDED(const void *PTR)
static void SET_VARSIZE(void *PTR, Size len)
text * cstring_to_text(const char *s)