32 #include "utils/fmgroids.h"
49 #define AARR_FREE_IF_COPY(array,n) \
51 if (!VARATT_IS_EXPANDED_HEADER(array)) \
52 PG_FREE_IF_COPY(array, n); \
93 static int ArrayCount(
const char *
str,
int *dim,
char typdelim,
95 static bool ReadArrayStr(
char *arrayStr,
const char *origStr,
96 int nitems,
int ndim,
int *dim,
99 int typlen,
bool typbyval,
char typalign,
101 bool *hasnulls,
int32 *nbytes,
Node *escontext);
104 int typlen,
bool typbyval,
char typalign,
106 bool *hasnulls,
int32 *nbytes);
108 int nSubscripts,
int *indx,
110 int elmlen,
bool elmbyval,
char elmalign,
113 int nSubscripts,
int *indx,
114 Datum dataValue,
bool isNull,
116 int elmlen,
bool elmbyval,
char elmalign);
121 int typlen,
bool typbyval,
char typalign,
124 int typlen,
bool typbyval,
char typalign);
128 char *srcptr,
int offset,
bits8 *nullbitmap,
129 int typlen,
bool typbyval,
char typalign);
131 int ndim,
int *dim,
int *lb,
133 int typlen,
bool typbyval,
char typalign);
135 int ndim,
int *dim,
int *lb,
136 char *arraydataptr,
bits8 *arraynullsptr,
138 int typlen,
bool typbyval,
char typalign);
141 int ndim,
int *dim,
int *lb,
143 int typlen,
bool typbyval,
char typalign);
146 Oid elmtype,
int dataoffset);
151 Datum search,
bool search_isnull,
152 Datum replace,
bool replace_isnull,
153 bool remove,
Oid collation,
181 Node *escontext = fcinfo->context;
208 if (my_extra == NULL)
229 typlen = my_extra->
typlen;
264 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
265 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
268 for (q = p; isdigit((
unsigned char) *q) || (*q ==
'-') || (*q ==
'+'); q++)
272 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
273 errmsg(
"malformed array literal: \"%s\"",
string),
274 errdetail(
"\"[\" must introduce explicitly-specified array dimensions.")));
280 lBound[ndim] = atoi(p);
282 for (q = p; isdigit((
unsigned char) *q) || (*q ==
'-') || (*q ==
'+'); q++)
286 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
287 errmsg(
"malformed array literal: \"%s\"",
string),
288 errdetail(
"Missing array dimension value.")));
297 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
298 errmsg(
"malformed array literal: \"%s\"",
string),
299 errdetail(
"Missing \"%s\" after array dimensions.",
305 if (ub < lBound[ndim])
307 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
308 errmsg(
"upper bound cannot be less than lower bound")));
310 dim[ndim] = ub - lBound[ndim] + 1;
319 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
320 errmsg(
"malformed array literal: \"%s\"",
string),
321 errdetail(
"Array value must start with \"{\" or dimension information.")));
322 ndim =
ArrayCount(p, dim, typdelim, escontext);
325 for (
i = 0;
i < ndim;
i++)
336 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
337 errmsg(
"malformed array literal: \"%s\"",
string),
338 errdetail(
"Missing \"%s\" after array dimensions.",
350 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
351 errmsg(
"malformed array literal: \"%s\"",
string),
352 errdetail(
"Array contents must start with \"{\".")));
353 ndim_braces =
ArrayCount(p, dim_braces, typdelim, escontext);
356 if (ndim_braces != ndim)
358 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
359 errmsg(
"malformed array literal: \"%s\"",
string),
360 errdetail(
"Specified array dimensions do not match array contents.")));
361 for (
i = 0;
i < ndim; ++
i)
363 if (dim[
i] != dim_braces[
i])
365 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
366 errmsg(
"malformed array literal: \"%s\"",
string),
367 errdetail(
"Specified array dimensions do not match array contents.")));
372 printf(
"array_in- ndim %d (", ndim);
373 for (
i = 0;
i < ndim;
i++)
377 printf(
") for %s\n",
string);
395 &my_extra->
proc, typioparam, typmod,
399 &hasnulls, &nbytes, escontext))
404 nbytes += dataoffset;
422 memcpy(
ARR_DIMS(retval), dim, ndim *
sizeof(
int));
423 memcpy(
ARR_LBOUND(retval), lBound, ndim *
sizeof(
int));
426 dataPtr, nullsPtr,
nitems,
477 bool in_quotes =
false;
478 bool eoArray =
false;
479 bool empty_array =
true;
485 temp[
i] = dim[
i] = nelems_last[
i] = 0;
492 bool itemdone =
false;
505 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
506 errmsg(
"malformed array literal: \"%s\"",
str),
520 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
521 errmsg(
"malformed array literal: \"%s\"",
str),
522 errdetail(
"Unexpected \"%c\" character.",
531 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
532 errmsg(
"malformed array literal: \"%s\"",
str),
546 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
547 errmsg(
"malformed array literal: \"%s\"",
str),
548 errdetail(
"Unexpected array element.")));
549 in_quotes = !in_quotes;
567 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
568 errmsg(
"malformed array literal: \"%s\"",
str),
569 errdetail(
"Unexpected \"%c\" character.",
574 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
575 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
576 nest_level + 1,
MAXDIM)));
577 temp[nest_level] = 0;
579 if (ndim < nest_level)
597 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
598 errmsg(
"malformed array literal: \"%s\"",
str),
599 errdetail(
"Unexpected \"%c\" character.",
604 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
605 errmsg(
"malformed array literal: \"%s\"",
str),
606 errdetail(
"Unmatched \"%c\" character.",
'}')));
609 if (nelems_last[nest_level] != 0 &&
610 nelems[nest_level] != nelems_last[nest_level])
612 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
613 errmsg(
"malformed array literal: \"%s\"",
str),
614 errdetail(
"Multidimensional arrays must have "
615 "sub-arrays with matching "
617 nelems_last[nest_level] = nelems[nest_level];
618 nelems[nest_level] = 1;
620 eoArray = itemdone =
true;
627 temp[nest_level - 1]++;
634 if (*ptr == typdelim)
646 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
647 errmsg(
"malformed array literal: \"%s\"",
str),
648 errdetail(
"Unexpected \"%c\" character.",
655 nelems[nest_level - 1]++;
669 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
670 errmsg(
"malformed array literal: \"%s\"",
str),
671 errdetail(
"Unexpected array element.")));
689 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
690 errmsg(
"malformed array literal: \"%s\"",
str),
691 errdetail(
"Junk after closing right brace.")));
698 for (
i = 0;
i < ndim; ++
i)
759 bool in_quotes =
false;
760 bool eoArray =
false;
769 memset(nulls,
true,
nitems *
sizeof(
bool));
789 bool itemdone =
false;
790 bool leadingspace =
true;
791 bool hasquoting =
false;
797 itemstart = dstptr = dstendptr = srcptr;
806 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
807 errmsg(
"malformed array literal: \"%s\"",
815 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
816 errmsg(
"malformed array literal: \"%s\"",
818 *dstptr++ = *srcptr++;
820 leadingspace =
false;
825 in_quotes = !in_quotes;
827 leadingspace =
false;
843 if (nest_level >= ndim)
845 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
846 errmsg(
"malformed array literal: \"%s\"",
849 indx[nest_level - 1] = 0;
853 *dstptr++ = *srcptr++;
860 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
861 errmsg(
"malformed array literal: \"%s\"",
865 indx[nest_level - 1] = 0;
868 eoArray = itemdone =
true;
870 indx[nest_level - 1]++;
874 *dstptr++ = *srcptr++;
878 *dstptr++ = *srcptr++;
879 else if (*srcptr == typdelim)
896 *dstptr++ = *srcptr++;
900 *dstptr++ = *srcptr++;
901 leadingspace =
false;
913 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
914 errmsg(
"malformed array literal: \"%s\"",
958 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
959 errmsg(
"array size exceeds the maximum allowed (%d)",
1005 if (nulls && nulls[
i])
1008 elog(
ERROR,
"null array element where not supported");
1021 if (bitmask == 0x100)
1030 if (bitmap && bitmask != 1)
1052 dims_str[(
MAXDIM * 33) + 2];
1061 size_t overall_length;
1079 if (my_extra == NULL)
1100 typlen = my_extra->
typlen;
1120 for (
i = 0;
i < ndim;
i++)
1153 overall_length += 4;
1168 for (tmp =
values[
i]; *tmp !=
'\0'; tmp++)
1172 overall_length += 1;
1173 if (ch ==
'"' || ch ==
'\\')
1176 overall_length += 1;
1178 else if (ch ==
'{' || ch ==
'}' || ch == typdelim ||
1184 needquotes[
i] = needquote;
1188 overall_length += 2;
1190 overall_length += 1;
1199 for (
i =
j = 0, k = 1;
i < ndim;
i++)
1201 j += k, k *= dims[
i];
1203 overall_length += 2 *
j;
1209 char *ptr = dims_str;
1211 for (
i = 0;
i < ndim;
i++)
1213 sprintf(ptr,
"[%d:%d]", lb[
i], lb[
i] + dims[
i] - 1);
1218 overall_length += ptr - dims_str;
1222 retval = (
char *)
palloc(overall_length);
1225 #define APPENDSTR(str) (strcpy(p, (str)), p += strlen(p))
1226 #define APPENDCHAR(ch) (*p++ = (ch), *p = '\0')
1231 for (
i = 0;
i < ndim;
i++)
1237 for (
i =
j;
i < ndim - 1;
i++)
1243 for (tmp =
values[k]; *tmp; tmp++)
1247 if (ch ==
'"' || ch ==
'\\')
1258 for (
i = ndim - 1;
i >= 0;
i--)
1260 if (++(indx[
i]) < dims[
i])
1278 Assert(overall_length == (p - retval + 1));
1324 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1325 errmsg(
"invalid number of dimensions: %d", ndim)));
1328 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1329 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
1333 if (flags != 0 && flags != 1)
1335 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1336 errmsg(
"invalid array flags")));
1352 if (element_type != spec_element_type)
1357 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1358 errmsg(
"binary data has array element type %u (%s) instead of expected %u (%s)",
1365 element_type = spec_element_type;
1368 for (
i = 0;
i < ndim;
i++)
1384 if (my_extra == NULL)
1401 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
1402 errmsg(
"no binary input function available for type %s",
1415 typlen = my_extra->
typlen;
1423 &my_extra->
proc, typioparam, typmod,
1426 &hasnulls, &nbytes);
1430 nbytes += dataoffset;
1439 retval->
ndim = ndim;
1442 memcpy(
ARR_DIMS(retval), dim, ndim *
sizeof(
int));
1443 memcpy(
ARR_LBOUND(retval), lBound, ndim *
sizeof(
int));
1446 dataPtr, nullsPtr,
nitems,
1503 if (itemlen < -1 || itemlen > (
buf->len -
buf->cursor))
1505 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1506 errmsg(
"insufficient data left in message")));
1512 typioparam, typmod);
1524 elem_buf.
maxlen = itemlen + 1;
1525 elem_buf.
len = itemlen;
1528 buf->cursor += itemlen;
1530 csave =
buf->data[
buf->cursor];
1531 buf->data[
buf->cursor] =
'\0';
1535 typioparam, typmod);
1539 if (elem_buf.
cursor != itemlen)
1541 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1542 errmsg(
"improper binary format in array element %d",
1545 buf->data[
buf->cursor] = csave;
1567 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1568 errmsg(
"array size exceeds the maximum allowed (%d)",
1572 *hasnulls = hasnull;
1605 if (my_extra == NULL)
1622 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
1623 errmsg(
"no binary output function available for type %s",
1629 typlen = my_extra->
typlen;
1644 for (
i = 0;
i < ndim;
i++)
1728 sprintf(p,
"[%d:%d]", lb[
i], dimv[
i] + lb[
i] - 1);
1753 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
1757 result = lb[reqdim - 1];
1781 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
1787 result = dimv[reqdim - 1] + lb[reqdim - 1] - 1;
1810 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
1815 result = dimv[reqdim - 1];
1873 bits8 *arraynullsptr;
1875 if (arraytyplen > 0)
1881 fixedDim[0] = arraytyplen / elmlen;
1886 arraynullsptr = NULL;
1915 if (ndim != nSubscripts || ndim <= 0 || ndim >
MAXDIM)
1920 for (
i = 0;
i < ndim;
i++)
1922 if (indx[
i] < lb[
i] || indx[
i] >= (dim[
i] + lb[
i]))
1947 retptr =
array_seek(arraydataptr, 0, arraynullsptr, offset,
1948 elmlen, elmbyval, elmalign);
1949 return ArrayCast(retptr, elmbyval, elmlen);
1957 int nSubscripts,
int *indx,
1959 int elmlen,
bool elmbyval,
char elmalign,
1975 Assert(arraytyplen == -1);
1987 if (ndim != nSubscripts || ndim <= 0 || ndim >
MAXDIM)
1992 for (
i = 0;
i < ndim;
i++)
1994 if (indx[
i] < lb[
i] || indx[
i] >= (dim[
i] + lb[
i]))
2018 if (dnulls && dnulls[offset])
2031 return dvalues[offset];
2069 bool *upperProvided,
2070 bool *lowerProvided,
2087 bits8 *arraynullsptr;
2092 if (arraytyplen > 0)
2101 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2102 errmsg(
"slices of fixed-length arrays not implemented")));
2110 fixedDim[0] = arraytyplen / elmlen;
2116 arraynullsptr = NULL;
2136 if (ndim < nSubscripts || ndim <= 0 || ndim >
MAXDIM)
2139 for (
i = 0;
i < nSubscripts;
i++)
2141 if (!lowerProvided[
i] || lowerIndx[
i] < lb[
i])
2142 lowerIndx[
i] = lb[
i];
2143 if (!upperProvided[
i] || upperIndx[
i] >= (dim[
i] + lb[
i]))
2144 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2145 if (lowerIndx[
i] > upperIndx[
i])
2149 for (;
i < ndim;
i++)
2151 lowerIndx[
i] = lb[
i];
2152 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2153 if (lowerIndx[
i] > upperIndx[
i])
2161 lowerIndx, upperIndx,
2162 elmlen, elmbyval, elmalign);
2171 bytes += dataoffset;
2181 newarray->
ndim = ndim;
2184 memcpy(
ARR_DIMS(newarray), span, ndim *
sizeof(
int));
2191 for (
i = 0;
i < ndim;
i++)
2196 arraydataptr, arraynullsptr,
2197 lowerIndx, upperIndx,
2198 elmlen, elmbyval, elmalign);
2255 bits8 *oldnullbitmap;
2269 if (arraytyplen > 0)
2277 if (nSubscripts != 1)
2279 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2280 errmsg(
"wrong number of array subscripts")));
2282 if (indx[0] < 0 || indx[0] >= arraytyplen / elmlen)
2284 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2285 errmsg(
"array subscript out of range")));
2289 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2290 errmsg(
"cannot assign null value to an element of a fixed-length array")));
2292 resultarray = (
char *)
palloc(arraytyplen);
2294 elt_ptr = (
char *) resultarray + indx[0] * elmlen;
2299 if (nSubscripts <= 0 || nSubscripts >
MAXDIM)
2301 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2302 errmsg(
"wrong number of array subscripts")));
2305 if (elmlen == -1 && !isNull)
2336 for (
i = 0;
i < nSubscripts;
i++)
2343 nSubscripts, dim, lb,
2345 elmlen, elmbyval, elmalign));
2348 if (ndim != nSubscripts)
2350 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2351 errmsg(
"wrong number of array subscripts")));
2354 memcpy(dim,
ARR_DIMS(array), ndim *
sizeof(
int));
2355 memcpy(lb,
ARR_LBOUND(array), ndim *
sizeof(
int));
2358 addedbefore = addedafter = 0;
2365 if (indx[0] < lb[0])
2367 addedbefore = lb[0] - indx[0];
2368 dim[0] += addedbefore;
2370 if (addedbefore > 1)
2373 if (indx[0] >= (dim[0] + lb[0]))
2375 addedafter = indx[0] - (dim[0] + lb[0]) + 1;
2376 dim[0] += addedafter;
2387 for (
i = 0;
i < ndim;
i++)
2389 if (indx[
i] < lb[
i] ||
2390 indx[
i] >= (dim[
i] + lb[
i]))
2392 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2393 errmsg(
"array subscript out of range")));
2411 olddatasize =
ARR_SIZE(array) - oldoverheadlen;
2417 lenafter = olddatasize;
2419 else if (addedafter)
2422 lenbefore = olddatasize;
2430 elmlen, elmbyval, elmalign);
2439 lenafter = (int) (olddatasize - lenbefore - olditemlen);
2450 newsize = overheadlen + lenbefore + newitemlen + lenafter;
2457 newarray->
ndim = ndim;
2458 newarray->
dataoffset = newhasnulls ? overheadlen : 0;
2460 memcpy(
ARR_DIMS(newarray), dim, ndim *
sizeof(
int));
2461 memcpy(
ARR_LBOUND(newarray), lb, ndim *
sizeof(
int));
2466 memcpy((
char *) newarray + overheadlen,
2467 (
char *) array + oldoverheadlen,
2471 (
char *) newarray + overheadlen + lenbefore);
2472 memcpy((
char *) newarray + overheadlen + lenbefore + newitemlen,
2473 (
char *) array + oldoverheadlen + lenbefore + olditemlen,
2487 MemSet(newnullbitmap, 0, (newnitems + 7) / 8);
2503 if (addedafter == 0)
2505 oldnullbitmap, offset + 1,
2506 oldnitems - offset - 1);
2522 int nSubscripts,
int *indx,
2523 Datum dataValue,
bool isNull,
2525 int elmlen,
bool elmbyval,
char elmalign)
2545 Assert(arraytyplen == -1);
2557 memcpy(dim, eah->
dims, ndim *
sizeof(
int));
2558 memcpy(lb, eah->
lbound, ndim *
sizeof(
int));
2559 dimschanged =
false;
2574 nSubscripts *
sizeof(
int));
2576 nSubscripts *
sizeof(
int));
2580 for (
i = 0;
i < nSubscripts;
i++)
2587 else if (ndim != nSubscripts)
2589 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2590 errmsg(
"wrong number of array subscripts")));
2619 newhasnulls = ((dnulls != NULL) || isNull);
2620 addedbefore = addedafter = 0;
2627 if (indx[0] < lb[0])
2629 addedbefore = lb[0] - indx[0];
2630 dim[0] += addedbefore;
2633 if (addedbefore > 1)
2636 if (indx[0] >= (dim[0] + lb[0]))
2638 addedafter = indx[0] - (dim[0] + lb[0]) + 1;
2639 dim[0] += addedafter;
2651 for (
i = 0;
i < ndim;
i++)
2653 if (indx[
i] < lb[
i] ||
2654 indx[
i] >= (dim[
i] + lb[
i]))
2656 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2657 errmsg(
"array subscript out of range")));
2675 int newlen = dim[0] + dim[0] / 8;
2677 newlen =
Max(newlen, dim[0]);
2681 eah->
dnulls = dnulls = (
bool *)
2682 repalloc(dnulls, newlen *
sizeof(
bool));
2690 if (newhasnulls && dnulls == NULL)
2691 eah->
dnulls = dnulls = (
bool *)
2709 memcpy(eah->
dims, dim, ndim *
sizeof(
int));
2710 memcpy(eah->
lbound, lb, ndim *
sizeof(
int));
2714 if (addedbefore > 0)
2716 memmove(dvalues + addedbefore, dvalues, eah->
nelems *
sizeof(
Datum));
2717 for (
i = 0;
i < addedbefore;
i++)
2721 memmove(dnulls + addedbefore, dnulls, eah->
nelems *
sizeof(
bool));
2722 for (
i = 0;
i < addedbefore;
i++)
2725 eah->
nelems += addedbefore;
2731 for (
i = 0;
i < addedafter;
i++)
2735 for (
i = 0;
i < addedafter;
i++)
2736 dnulls[eah->
nelems +
i] =
true;
2738 eah->
nelems += addedafter;
2742 if (!eah->
typbyval && (dnulls == NULL || !dnulls[offset]))
2748 dvalues[offset] = dataValue;
2750 dnulls[offset] = isNull;
2760 if (oldValue < eah->fstartptr || oldValue >= eah->
fendptr)
2814 bool *upperProvided,
2815 bool *lowerProvided,
2816 Datum srcArrayDatum,
2852 if (arraytyplen > 0)
2858 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2859 errmsg(
"updates on slices of fixed-length arrays not implemented")));
2883 &dvalues, &dnulls, &nelems);
2885 for (
i = 0;
i < nSubscripts;
i++)
2887 if (!upperProvided[
i] || !lowerProvided[
i])
2889 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2890 errmsg(
"array slice subscript must provide both boundaries"),
2891 errdetail(
"When assigning to a slice of an empty array value,"
2892 " slice boundaries must be fully specified.")));
2894 dim[
i] = 1 + upperIndx[
i] - lowerIndx[
i];
2895 lb[
i] = lowerIndx[
i];
2901 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2902 errmsg(
"source array too small")));
2906 elmlen, elmbyval, elmalign));
2909 if (ndim < nSubscripts || ndim <= 0 || ndim >
MAXDIM)
2911 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2912 errmsg(
"wrong number of array subscripts")));
2915 memcpy(dim,
ARR_DIMS(array), ndim *
sizeof(
int));
2916 memcpy(lb,
ARR_LBOUND(array), ndim *
sizeof(
int));
2919 addedbefore = addedafter = 0;
2926 Assert(nSubscripts == 1);
2927 if (!lowerProvided[0])
2928 lowerIndx[0] = lb[0];
2929 if (!upperProvided[0])
2930 upperIndx[0] = dim[0] + lb[0] - 1;
2931 if (lowerIndx[0] > upperIndx[0])
2933 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2934 errmsg(
"upper bound cannot be less than lower bound")));
2935 if (lowerIndx[0] < lb[0])
2937 if (upperIndx[0] < lb[0] - 1)
2939 addedbefore = lb[0] - lowerIndx[0];
2940 dim[0] += addedbefore;
2941 lb[0] = lowerIndx[0];
2943 if (upperIndx[0] >= (dim[0] + lb[0]))
2945 if (lowerIndx[0] > (dim[0] + lb[0]))
2947 addedafter = upperIndx[0] - (dim[0] + lb[0]) + 1;
2948 dim[0] += addedafter;
2957 for (
i = 0;
i < nSubscripts;
i++)
2959 if (!lowerProvided[
i])
2960 lowerIndx[
i] = lb[
i];
2961 if (!upperProvided[
i])
2962 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2963 if (lowerIndx[
i] > upperIndx[
i])
2965 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2966 errmsg(
"upper bound cannot be less than lower bound")));
2967 if (lowerIndx[
i] < lb[
i] ||
2968 upperIndx[
i] >= (dim[
i] + lb[
i]))
2970 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2971 errmsg(
"array subscript out of range")));
2974 for (;
i < ndim;
i++)
2976 lowerIndx[
i] = lb[
i];
2977 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2978 if (lowerIndx[
i] > upperIndx[
i])
2980 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2981 errmsg(
"upper bound cannot be less than lower bound")));
2997 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2998 errmsg(
"source array too small")));
3010 elmlen, elmbyval, elmalign);
3012 olddatasize =
ARR_SIZE(array) - oldoverheadlen;
3022 lowerIndx, upperIndx,
3023 elmlen, elmbyval, elmalign);
3024 lenbefore = lenafter = 0;
3025 itemsbefore = itemsafter = nolditems = 0;
3034 int oldub = oldlb +
ARR_DIMS(array)[0] - 1;
3035 int slicelb =
Max(oldlb, lowerIndx[0]);
3036 int sliceub =
Min(oldub, upperIndx[0]);
3041 itemsbefore =
Min(slicelb, oldub + 1) - oldlb;
3044 elmlen, elmbyval, elmalign);
3046 if (slicelb > sliceub)
3053 nolditems = sliceub - slicelb + 1;
3055 itemsbefore, oldarraybitmap,
3057 elmlen, elmbyval, elmalign);
3060 itemsafter = oldub + 1 -
Max(sliceub + 1, oldlb);
3061 lenafter = olddatasize - lenbefore - olditemsize;
3064 newsize = overheadlen + olddatasize - olditemsize + newitemsize;
3068 newarray->
ndim = ndim;
3069 newarray->
dataoffset = newhasnulls ? overheadlen : 0;
3071 memcpy(
ARR_DIMS(newarray), dim, ndim *
sizeof(
int));
3072 memcpy(
ARR_LBOUND(newarray), lb, ndim *
sizeof(
int));
3082 lowerIndx, upperIndx,
3083 elmlen, elmbyval, elmalign);
3088 memcpy((
char *) newarray + overheadlen,
3089 (
char *) array + oldoverheadlen,
3091 memcpy((
char *) newarray + overheadlen + lenbefore,
3094 memcpy((
char *) newarray + overheadlen + lenbefore + newitemsize,
3095 (
char *) array + oldoverheadlen + lenbefore + olditemsize,
3112 oldnullbitmap, itemsbefore + nolditems,
3129 int arraytyplen,
int elmlen,
bool elmbyval,
char elmalign,
3133 arraytyplen, elmlen, elmbyval, elmalign,
3146 Datum dataValue,
bool isNull,
3147 int arraytyplen,
int elmlen,
bool elmbyval,
char elmalign)
3153 elmlen, elmbyval, elmalign));
3239 inp_typlen = inp_extra->
typlen;
3240 inp_typbyval = inp_extra->
typbyval;
3241 inp_typalign = inp_extra->
typalign;
3251 typlen = ret_extra->
typlen;
3268 inp_typlen, inp_typbyval, inp_typalign);
3286 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3287 errmsg(
"array size exceeds the maximum allowed (%d)",
3296 nbytes += dataoffset;
3305 result->
ndim = ndim;
3345 int elmlen,
bool elmbyval,
char elmalign)
3354 elmtype, elmlen, elmbyval, elmalign);
3375 elmalign = TYPALIGN_CHAR;
3381 elmalign = TYPALIGN_CHAR;
3387 elmalign = TYPALIGN_INT;
3391 elmlen =
sizeof(
int16);
3393 elmalign = TYPALIGN_SHORT;
3397 elmlen =
sizeof(
int32);
3399 elmalign = TYPALIGN_INT;
3403 elmlen =
sizeof(int64);
3405 elmalign = TYPALIGN_DOUBLE;
3411 elmalign = TYPALIGN_CHAR;
3416 elmlen =
sizeof(
Oid);
3418 elmalign = TYPALIGN_INT;
3424 elmalign = TYPALIGN_INT;
3430 elmalign = TYPALIGN_SHORT;
3434 elog(
ERROR,
"type %u not supported by construct_array_builtin()", elmtype);
3441 return construct_array(elems, nelems, elmtype, elmlen, elmbyval, elmalign);
3470 Oid elmtype,
int elmlen,
bool elmbyval,
char elmalign)
3481 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3482 errmsg(
"invalid number of dimensions: %d", ndims)));
3485 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3486 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
3500 for (
i = 0;
i < nelems;
i++)
3502 if (nulls && nulls[
i])
3515 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3516 errmsg(
"array size exceeds the maximum allowed (%d)",
3524 nbytes += dataoffset;
3533 result->
ndim = ndims;
3536 memcpy(
ARR_DIMS(result), dims, ndims *
sizeof(
int));
3537 memcpy(
ARR_LBOUND(result), lbs, ndims *
sizeof(
int));
3540 elems, nulls, nelems,
3541 elmlen, elmbyval, elmalign,
3604 int elmlen,
bool elmbyval,
char elmalign,
3605 Datum **elemsp,
bool **nullsp,
int *nelemsp)
3620 *nullsp = nulls = (
bool *)
palloc0(nelems *
sizeof(
bool));
3629 for (
i = 0;
i < nelems;
i++)
3632 if (bitmap && (*bitmap & bitmask) == 0)
3639 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
3640 errmsg(
"null array element not allowed in this context")));
3653 if (bitmask == 0x100)
3670 Datum **elemsp,
bool **nullsp,
int *nelemsp)
3681 elmalign = TYPALIGN_CHAR;
3687 elmalign = TYPALIGN_CHAR;
3693 elmalign = TYPALIGN_DOUBLE;
3697 elmlen =
sizeof(
int16);
3699 elmalign = TYPALIGN_SHORT;
3703 elmlen =
sizeof(
Oid);
3705 elmalign = TYPALIGN_INT;
3711 elmalign = TYPALIGN_INT;
3717 elmalign = TYPALIGN_SHORT;
3721 elog(
ERROR,
"type %u not supported by deconstruct_array_builtin()", elmtype);
3728 deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, elemsp, nullsp, nelemsp);
3755 if (*bitmap != 0xFF)
3765 if ((*bitmap & bitmask) == 0)
3810 (
errcode(ERRCODE_DATATYPE_MISMATCH),
3811 errmsg(
"cannot compare arrays of different element types")));
3814 if (ndims1 != ndims2 ||
3815 memcmp(dims1, dims2, ndims1 *
sizeof(
int)) != 0 ||
3816 memcmp(lbs1, lbs2, ndims1 *
sizeof(
int)) != 0)
3827 if (typentry == NULL ||
3828 typentry->
type_id != element_type)
3834 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
3835 errmsg(
"could not identify an equality operator for type %s",
3837 fcinfo->flinfo->fn_extra = (
void *) typentry;
3839 typlen = typentry->
typlen;
3847 collation, NULL, NULL);
3871 if (isnull1 && isnull2)
3873 if (isnull1 || isnull2)
3882 locfcinfo->args[0].value = elt1;
3883 locfcinfo->args[0].isnull =
false;
3884 locfcinfo->args[1].value = elt2;
3885 locfcinfo->args[1].isnull =
false;
3886 locfcinfo->isnull =
false;
3888 if (locfcinfo->isnull || !oprresult)
3981 (
errcode(ERRCODE_DATATYPE_MISMATCH),
3982 errmsg(
"cannot compare arrays of different element types")));
3991 if (typentry == NULL ||
3992 typentry->
type_id != element_type)
3998 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
3999 errmsg(
"could not identify a comparison function for type %s",
4003 typlen = typentry->
typlen;
4011 collation, NULL, NULL);
4014 min_nitems =
Min(nitems1, nitems2);
4018 for (
i = 0;
i < min_nitems;
i++)
4033 if (isnull1 && isnull2)
4049 locfcinfo->args[0].value = elt1;
4050 locfcinfo->args[0].isnull =
false;
4051 locfcinfo->args[1].value = elt2;
4052 locfcinfo->args[1].isnull =
false;
4056 Assert(!locfcinfo->isnull);
4083 if (nitems1 != nitems2)
4084 result = (nitems1 < nitems2) ? -1 : 1;
4085 else if (ndims1 != ndims2)
4086 result = (ndims1 < ndims2) ? -1 : 1;
4089 for (
i = 0;
i < ndims1;
i++)
4091 if (dims1[
i] != dims2[
i])
4093 result = (dims1[
i] < dims2[
i]) ? -1 : 1;
4102 for (
i = 0;
i < ndims1;
i++)
4104 if (lbound1[
i] != lbound2[
i])
4106 result = (lbound1[
i] < lbound2[
i]) ? -1 : 1;
4152 if (typentry == NULL ||
4153 typentry->
type_id != element_type)
4159 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
4160 errmsg(
"could not identify a hash function for type %s",
4170 if (element_type == RECORDOID)
4182 record_typentry =
palloc0(
sizeof(*record_typentry));
4183 record_typentry->
type_id = element_type;
4193 typentry = record_typentry;
4196 fcinfo->flinfo->fn_extra = (
void *) typentry;
4199 typlen = typentry->
typlen;
4230 locfcinfo->args[0].value = elt;
4231 locfcinfo->args[0].isnull =
false;
4234 Assert(!locfcinfo->isnull);
4248 result = (result << 5) - result + elthash;
4280 if (typentry == NULL ||
4281 typentry->
type_id != element_type)
4287 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
4288 errmsg(
"could not identify an extended hash function for type %s",
4290 fcinfo->flinfo->fn_extra = (
void *) typentry;
4292 typlen = typentry->
typlen;
4319 locfcinfo->args[0].value = elt;
4320 locfcinfo->args[0].isnull =
false;
4322 locfcinfo->args[1].isnull =
false;
4325 Assert(!locfcinfo->isnull);
4328 result = (result << 5) - result + elthash;
4353 bool matchall,
void **fn_extra)
4356 bool result = matchall;
4372 (
errcode(ERRCODE_DATATYPE_MISMATCH),
4373 errmsg(
"cannot compare arrays of different element types")));
4382 if (typentry == NULL ||
4383 typentry->
type_id != element_type)
4389 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
4390 errmsg(
"could not identify an equality operator for type %s",
4392 *fn_extra = (
void *) typentry;
4394 typlen = typentry->
typlen;
4413 element_type, typlen, typbyval,
typalign,
4414 &values2, &nulls2, &nelems2);
4420 collation, NULL, NULL);
4426 for (
i = 0;
i < nelems1;
i++)
4449 for (
j = 0;
j < nelems2;
j++)
4452 bool isnull2 = nulls2 ? nulls2[
j] :
false;
4461 locfcinfo->args[0].value = elt1;
4462 locfcinfo->args[0].isnull =
false;
4463 locfcinfo->args[1].value = elt2;
4464 locfcinfo->args[1].isnull =
false;
4465 locfcinfo->isnull =
false;
4467 if (!locfcinfo->isnull && oprresult)
4503 &fcinfo->flinfo->fn_extra);
4521 &fcinfo->flinfo->fn_extra);
4539 &fcinfo->flinfo->fn_extra);
4576 if (slice_ndim < 0 || slice_ndim >
ARR_NDIM(arr))
4577 elog(
ERROR,
"invalid arguments to array_create_iterator");
4582 iterator->
arr = arr;
4754 if (nullbitmap == NULL)
4756 if (nullbitmap[offset / 8] & (1 << (offset % 8)))
4773 nullbitmap += offset / 8;
4774 bitmask = 1 << (offset % 8);
4776 *nullbitmap &= ~bitmask;
4778 *nullbitmap |= bitmask;
4838 int typlen,
bool typbyval,
char typalign)
4844 if (typlen > 0 && !nullbitmap)
4850 nullbitmap += offset / 8;
4851 bitmask = 1 << (offset % 8);
4855 if (*nullbitmap & bitmask)
4861 if (bitmask == 0x100)
4886 int typlen,
bool typbyval,
char typalign)
4908 char *srcptr,
int offset,
bits8 *nullbitmap,
4909 int typlen,
bool typbyval,
char typalign)
4915 memcpy(destptr, srcptr, numbytes);
4938 const bits8 *srcbitmap,
int srcoffset,
4949 destbitmap += destoffset / 8;
4950 destbitmask = 1 << (destoffset % 8);
4951 destbitval = *destbitmap;
4954 srcbitmap += srcoffset / 8;
4955 srcbitmask = 1 << (srcoffset % 8);
4956 srcbitval = *srcbitmap;
4959 if (srcbitval & srcbitmask)
4960 destbitval |= destbitmask;
4962 destbitval &= ~destbitmask;
4964 if (destbitmask == 0x100)
4966 *destbitmap++ = destbitval;
4969 destbitval = *destbitmap;
4972 if (srcbitmask == 0x100)
4977 srcbitval = *srcbitmap;
4980 if (destbitmask != 1)
4981 *destbitmap = destbitval;
4987 destbitval |= destbitmask;
4989 if (destbitmask == 0x100)
4991 *destbitmap++ = destbitval;
4994 destbitval = *destbitmap;
4997 if (destbitmask != 1)
4998 *destbitmap = destbitval;
5009 int ndim,
int *dim,
int *lb,
5011 int typlen,
bool typbyval,
char typalign)
5027 if (typlen > 0 && !arraynullsptr)
5032 ptr =
array_seek(arraydataptr, 0, arraynullsptr, src_offset,
5036 for (
i = 0;
i < ndim;
i++)
5043 ptr =
array_seek(ptr, src_offset, arraynullsptr, dist[
j],
5045 src_offset += dist[
j];
5073 bits8 *arraynullsptr,
5094 srcdataptr =
array_seek(arraydataptr, 0, arraynullsptr, src_offset,
5099 for (
i = 0;
i < ndim;
i++)
5108 srcdataptr =
array_seek(srcdataptr, src_offset, arraynullsptr,
5111 src_offset += dist[
j];
5114 srcdataptr, src_offset, arraynullsptr,
5118 arraynullsptr, src_offset,
5175 origPtr, 0, origBitmap,
5181 orig_offset = dest_offset;
5185 for (
i = 0;
i < ndim;
i++)
5195 origPtr, orig_offset, origBitmap,
5201 origBitmap, orig_offset,
5203 dest_offset += dist[
j];
5204 orig_offset += dist[
j];
5208 srcPtr, src_offset, srcBitmap,
5212 srcBitmap, src_offset,
5219 origPtr =
array_seek(origPtr, orig_offset, origBitmap, 1,
5225 array_copy(destPtr, orignitems - orig_offset,
5226 origPtr, orig_offset, origBitmap,
5230 origBitmap, orig_offset,
5231 orignitems - orig_offset);
5272 subcontext ? 64 : 8);
5282 bool subcontext,
int initsize)
5297 astate->
alen = initsize;
5300 astate->
dnulls = (
bool *)
5322 Datum dvalue,
bool disnull,
5346 astate->
dnulls = (
bool *)
5360 if (astate->
typlen == -1)
5393 ndims = (astate->
nelems > 0) ? 1 : 0;
5394 dims[0] = astate->
nelems;
5482 (
errcode(ERRCODE_DATATYPE_MISMATCH),
5483 errmsg(
"data type %s is not an array type",
5490 "accumArrayResultArr",
5516 Datum dvalue,
bool disnull,
5537 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5538 errmsg(
"cannot accumulate null arrays")));
5558 if (astate->
ndims == 0)
5565 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5566 errmsg(
"cannot accumulate empty arrays")));
5569 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5570 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
5577 astate->
ndims = ndims + 1;
5578 astate->
dims[0] = 0;
5579 memcpy(&astate->
dims[1], dims, ndims *
sizeof(
int));
5581 memcpy(&astate->
lbs[1], lbs, ndims *
sizeof(
int));
5590 if (astate->
ndims != ndims + 1)
5592 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5593 errmsg(
"cannot accumulate arrays of different dimensionality")));
5594 for (
i = 0;
i < ndims;
i++)
5596 if (astate->
dims[
i + 1] != dims[
i] || astate->
lbs[
i + 1] != lbs[
i])
5598 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5599 errmsg(
"cannot accumulate arrays of different dimensionality")));
5606 astate->
nbytes + ndatabytes);
5618 astate->
nbytes += ndatabytes;
5637 else if (newnitems > astate->
aitems)
5649 astate->
dims[0] += 1;
5678 if (astate->
ndims == 0)
5697 nbytes += dataoffset;
5793 Datum dvalue,
bool disnull,
5803 input_type, rcontext);
5807 input_type, rcontext);
5902 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
5914 fctx->
lower = lb[reqdim - 1];
5915 fctx->
upper = dimv[reqdim - 1] + lb[reqdim - 1] - 1;