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);
94 static void ReadArrayStr(
char *arrayStr,
const char *origStr,
95 int nitems,
int ndim,
int *dim,
98 int typlen,
bool typbyval,
char typalign,
100 bool *hasnulls,
int32 *nbytes);
103 int typlen,
bool typbyval,
char typalign,
105 bool *hasnulls,
int32 *nbytes);
107 int nSubscripts,
int *indx,
109 int elmlen,
bool elmbyval,
char elmalign,
112 int nSubscripts,
int *indx,
113 Datum dataValue,
bool isNull,
115 int elmlen,
bool elmbyval,
char elmalign);
120 int typlen,
bool typbyval,
char typalign,
122 static char *
array_seek(
char *ptr,
int offset,
bits8 *nullbitmap,
int nitems,
123 int typlen,
bool typbyval,
char typalign);
125 int nitems,
int typlen,
bool typbyval,
char typalign);
126 static int array_copy(
char *destptr,
int nitems,
127 char *srcptr,
int offset,
bits8 *nullbitmap,
128 int typlen,
bool typbyval,
char typalign);
130 int ndim,
int *dim,
int *lb,
132 int typlen,
bool typbyval,
char typalign);
134 int ndim,
int *dim,
int *lb,
135 char *arraydataptr,
bits8 *arraynullsptr,
137 int typlen,
bool typbyval,
char typalign);
140 int ndim,
int *dim,
int *lb,
142 int typlen,
bool typbyval,
char typalign);
145 Oid elmtype,
int dataoffset);
150 Datum search,
bool search_isnull,
151 Datum replace,
bool replace_isnull,
152 bool remove,
Oid collation,
206 if (my_extra == NULL)
227 typlen = my_extra->
typlen;
262 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
263 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
266 for (q = p; isdigit((
unsigned char) *q) || (*q ==
'-') || (*q ==
'+'); q++)
270 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
271 errmsg(
"malformed array literal: \"%s\"",
string),
272 errdetail(
"\"[\" must introduce explicitly-specified array dimensions.")));
278 lBound[ndim] = atoi(p);
280 for (q = p; isdigit((
unsigned char) *q) || (*q ==
'-') || (*q ==
'+'); q++)
284 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
285 errmsg(
"malformed array literal: \"%s\"",
string),
286 errdetail(
"Missing array dimension value.")));
295 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
296 errmsg(
"malformed array literal: \"%s\"",
string),
297 errdetail(
"Missing \"%s\" after array dimensions.",
303 if (ub < lBound[ndim])
305 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
306 errmsg(
"upper bound cannot be less than lower bound")));
308 dim[ndim] = ub - lBound[ndim] + 1;
317 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
318 errmsg(
"malformed array literal: \"%s\"",
string),
319 errdetail(
"Array value must start with \"{\" or dimension information.")));
321 for (
i = 0;
i < ndim;
i++)
332 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
333 errmsg(
"malformed array literal: \"%s\"",
string),
334 errdetail(
"Missing \"%s\" after array dimensions.",
346 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
347 errmsg(
"malformed array literal: \"%s\"",
string),
348 errdetail(
"Array contents must start with \"{\".")));
349 ndim_braces =
ArrayCount(p, dim_braces, typdelim);
350 if (ndim_braces != ndim)
352 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
353 errmsg(
"malformed array literal: \"%s\"",
string),
354 errdetail(
"Specified array dimensions do not match array contents.")));
355 for (
i = 0;
i < ndim; ++
i)
357 if (dim[
i] != dim_braces[
i])
359 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
360 errmsg(
"malformed array literal: \"%s\"",
string),
361 errdetail(
"Specified array dimensions do not match array contents.")));
366 printf(
"array_in- ndim %d (", ndim);
367 for (
i = 0;
i < ndim;
i++)
371 printf(
") for %s\n",
string);
383 nullsPtr = (
bool *)
palloc(nitems *
sizeof(
bool));
386 &my_extra->
proc, typioparam, typmod,
394 nbytes += dataoffset;
412 memcpy(
ARR_DIMS(retval), dim, ndim *
sizeof(
int));
413 memcpy(
ARR_LBOUND(retval), lBound, ndim *
sizeof(
int));
416 dataPtr, nullsPtr, nitems,
464 bool in_quotes =
false;
465 bool eoArray =
false;
466 bool empty_array =
true;
472 temp[
i] = dim[
i] = nelems_last[
i] = 0;
479 bool itemdone =
false;
492 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
493 errmsg(
"malformed array literal: \"%s\"",
str),
508 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
509 errmsg(
"malformed array literal: \"%s\"",
str),
510 errdetail(
"Unexpected \"%c\" character.",
519 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
520 errmsg(
"malformed array literal: \"%s\"",
str),
534 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
535 errmsg(
"malformed array literal: \"%s\"",
str),
536 errdetail(
"Unexpected array element.")));
537 in_quotes = !in_quotes;
555 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
556 errmsg(
"malformed array literal: \"%s\"",
str),
557 errdetail(
"Unexpected \"%c\" character.",
562 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
563 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
564 nest_level + 1,
MAXDIM)));
565 temp[nest_level] = 0;
567 if (ndim < nest_level)
585 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
586 errmsg(
"malformed array literal: \"%s\"",
str),
587 errdetail(
"Unexpected \"%c\" character.",
592 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
593 errmsg(
"malformed array literal: \"%s\"",
str),
594 errdetail(
"Unmatched \"%c\" character.",
'}')));
597 if (nelems_last[nest_level] != 0 &&
598 nelems[nest_level] != nelems_last[nest_level])
600 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
601 errmsg(
"malformed array literal: \"%s\"",
str),
602 errdetail(
"Multidimensional arrays must have "
603 "sub-arrays with matching "
605 nelems_last[nest_level] = nelems[nest_level];
606 nelems[nest_level] = 1;
608 eoArray = itemdone =
true;
615 temp[nest_level - 1]++;
622 if (*ptr == typdelim)
634 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
635 errmsg(
"malformed array literal: \"%s\"",
str),
636 errdetail(
"Unexpected \"%c\" character.",
643 nelems[nest_level - 1]++;
657 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
658 errmsg(
"malformed array literal: \"%s\"",
str),
659 errdetail(
"Unexpected array element.")));
677 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
678 errmsg(
"malformed array literal: \"%s\"",
str),
679 errdetail(
"Junk after closing right brace.")));
686 for (
i = 0;
i < ndim; ++
i)
741 bool in_quotes =
false;
742 bool eoArray =
false;
749 MemSet(indx, 0,
sizeof(indx));
752 memset(nulls,
true, nitems *
sizeof(
bool));
772 bool itemdone =
false;
773 bool leadingspace =
true;
774 bool hasquoting =
false;
780 itemstart = dstptr = dstendptr = srcptr;
789 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
790 errmsg(
"malformed array literal: \"%s\"",
798 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
799 errmsg(
"malformed array literal: \"%s\"",
801 *dstptr++ = *srcptr++;
803 leadingspace =
false;
808 in_quotes = !in_quotes;
810 leadingspace =
false;
826 if (nest_level >= ndim)
828 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
829 errmsg(
"malformed array literal: \"%s\"",
832 indx[nest_level - 1] = 0;
836 *dstptr++ = *srcptr++;
843 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
844 errmsg(
"malformed array literal: \"%s\"",
848 indx[nest_level - 1] = 0;
851 eoArray = itemdone =
true;
853 indx[nest_level - 1]++;
857 *dstptr++ = *srcptr++;
861 *dstptr++ = *srcptr++;
862 else if (*srcptr == typdelim)
879 *dstptr++ = *srcptr++;
883 *dstptr++ = *srcptr++;
884 leadingspace =
false;
894 if (i < 0 || i >= nitems)
896 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
897 errmsg(
"malformed array literal: \"%s\"",
921 for (
i = 0;
i < nitems;
i++)
935 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
936 errmsg(
"array size exceeds the maximum allowed (%d)",
979 for (
i = 0;
i < nitems;
i++)
981 if (nulls && nulls[
i])
984 elog(
ERROR,
"null array element where not supported");
997 if (bitmask == 0x100)
1006 if (bitmap && bitmask != 1)
1028 dims_str[(
MAXDIM * 33) + 2];
1037 size_t overall_length;
1055 if (my_extra == NULL)
1076 typlen = my_extra->
typlen;
1096 for (
i = 0;
i < ndim;
i++)
1111 needquotes = (
bool *)
palloc(nitems *
sizeof(
bool));
1116 for (
i = 0;
i < nitems;
i++)
1129 overall_length += 4;
1144 for (tmp =
values[
i]; *tmp !=
'\0'; tmp++)
1148 overall_length += 1;
1149 if (ch ==
'"' || ch ==
'\\')
1152 overall_length += 1;
1154 else if (ch ==
'{' || ch ==
'}' || ch == typdelim ||
1160 needquotes[
i] = needquote;
1164 overall_length += 2;
1166 overall_length += 1;
1175 for (
i =
j = 0, k = 1;
i < ndim;
i++)
1177 j += k, k *= dims[
i];
1179 overall_length += 2 *
j;
1185 char *ptr = dims_str;
1187 for (
i = 0;
i < ndim;
i++)
1189 sprintf(ptr,
"[%d:%d]", lb[
i], lb[
i] + dims[
i] - 1);
1194 overall_length += ptr - dims_str;
1198 retval = (
char *)
palloc(overall_length);
1201 #define APPENDSTR(str) (strcpy(p, (str)), p += strlen(p))
1202 #define APPENDCHAR(ch) (*p++ = (ch), *p = '\0')
1207 for (
i = 0;
i < ndim;
i++)
1213 for (
i =
j;
i < ndim - 1;
i++)
1219 for (tmp =
values[k]; *tmp; tmp++)
1223 if (ch ==
'"' || ch ==
'\\')
1234 for (
i = ndim - 1;
i >= 0;
i--)
1236 if (++(indx[
i]) < dims[
i])
1254 Assert(overall_length == (p - retval + 1));
1300 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1301 errmsg(
"invalid number of dimensions: %d", ndim)));
1304 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1305 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
1309 if (flags != 0 && flags != 1)
1311 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1312 errmsg(
"invalid array flags")));
1328 if (element_type != spec_element_type)
1333 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1334 errmsg(
"binary data has array element type %u (%s) instead of expected %u (%s)",
1341 element_type = spec_element_type;
1344 for (
i = 0;
i < ndim;
i++)
1360 if (my_extra == NULL)
1377 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
1378 errmsg(
"no binary input function available for type %s",
1391 typlen = my_extra->
typlen;
1397 nullsPtr = (
bool *)
palloc(nitems *
sizeof(
bool));
1399 &my_extra->
proc, typioparam, typmod,
1402 &hasnulls, &nbytes);
1406 nbytes += dataoffset;
1415 retval->
ndim = ndim;
1418 memcpy(
ARR_DIMS(retval), dim, ndim *
sizeof(
int));
1419 memcpy(
ARR_LBOUND(retval), lBound, ndim *
sizeof(
int));
1422 dataPtr, nullsPtr, nitems,
1471 for (
i = 0;
i < nitems;
i++)
1479 if (itemlen < -1 || itemlen > (
buf->len -
buf->cursor))
1481 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1482 errmsg(
"insufficient data left in message")));
1488 typioparam, typmod);
1500 elem_buf.
maxlen = itemlen + 1;
1501 elem_buf.
len = itemlen;
1504 buf->cursor += itemlen;
1506 csave =
buf->data[
buf->cursor];
1507 buf->data[
buf->cursor] =
'\0';
1511 typioparam, typmod);
1515 if (elem_buf.
cursor != itemlen)
1517 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1518 errmsg(
"improper binary format in array element %d",
1521 buf->data[
buf->cursor] = csave;
1529 for (
i = 0;
i < nitems;
i++)
1543 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1544 errmsg(
"array size exceeds the maximum allowed (%d)",
1548 *hasnulls = hasnull;
1581 if (my_extra == NULL)
1598 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
1599 errmsg(
"no binary output function available for type %s",
1605 typlen = my_extra->
typlen;
1620 for (
i = 0;
i < ndim;
i++)
1629 for (
i = 0;
i < nitems;
i++)
1704 sprintf(p,
"[%d:%d]", lb[
i], dimv[
i] + lb[
i] - 1);
1729 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
1733 result = lb[reqdim - 1];
1757 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
1763 result = dimv[reqdim - 1] + lb[reqdim - 1] - 1;
1786 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
1791 result = dimv[reqdim - 1];
1849 bits8 *arraynullsptr;
1851 if (arraytyplen > 0)
1857 fixedDim[0] = arraytyplen / elmlen;
1862 arraynullsptr = NULL;
1891 if (ndim != nSubscripts || ndim <= 0 || ndim >
MAXDIM)
1896 for (
i = 0;
i < ndim;
i++)
1898 if (indx[
i] < lb[
i] || indx[
i] >= (dim[
i] + lb[
i]))
1923 retptr =
array_seek(arraydataptr, 0, arraynullsptr, offset,
1924 elmlen, elmbyval, elmalign);
1925 return ArrayCast(retptr, elmbyval, elmlen);
1933 int nSubscripts,
int *indx,
1935 int elmlen,
bool elmbyval,
char elmalign,
1951 Assert(arraytyplen == -1);
1963 if (ndim != nSubscripts || ndim <= 0 || ndim >
MAXDIM)
1968 for (
i = 0;
i < ndim;
i++)
1970 if (indx[
i] < lb[
i] || indx[
i] >= (dim[
i] + lb[
i]))
1994 if (dnulls && dnulls[offset])
2007 return dvalues[offset];
2045 bool *upperProvided,
2046 bool *lowerProvided,
2063 bits8 *arraynullsptr;
2068 if (arraytyplen > 0)
2077 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2078 errmsg(
"slices of fixed-length arrays not implemented")));
2086 fixedDim[0] = arraytyplen / elmlen;
2092 arraynullsptr = NULL;
2112 if (ndim < nSubscripts || ndim <= 0 || ndim >
MAXDIM)
2115 for (
i = 0;
i < nSubscripts;
i++)
2117 if (!lowerProvided[
i] || lowerIndx[
i] < lb[
i])
2118 lowerIndx[
i] = lb[
i];
2119 if (!upperProvided[
i] || upperIndx[
i] >= (dim[
i] + lb[
i]))
2120 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2121 if (lowerIndx[
i] > upperIndx[
i])
2125 for (;
i < ndim;
i++)
2127 lowerIndx[
i] = lb[
i];
2128 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2129 if (lowerIndx[
i] > upperIndx[
i])
2137 lowerIndx, upperIndx,
2138 elmlen, elmbyval, elmalign);
2147 bytes += dataoffset;
2157 newarray->
ndim = ndim;
2160 memcpy(
ARR_DIMS(newarray), span, ndim *
sizeof(
int));
2167 for (
i = 0;
i < ndim;
i++)
2172 arraydataptr, arraynullsptr,
2173 lowerIndx, upperIndx,
2174 elmlen, elmbyval, elmalign);
2231 bits8 *oldnullbitmap;
2245 if (arraytyplen > 0)
2253 if (nSubscripts != 1)
2255 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2256 errmsg(
"wrong number of array subscripts")));
2258 if (indx[0] < 0 || indx[0] >= arraytyplen / elmlen)
2260 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2261 errmsg(
"array subscript out of range")));
2265 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2266 errmsg(
"cannot assign null value to an element of a fixed-length array")));
2268 resultarray = (
char *)
palloc(arraytyplen);
2270 elt_ptr = (
char *) resultarray + indx[0] * elmlen;
2275 if (nSubscripts <= 0 || nSubscripts >
MAXDIM)
2277 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2278 errmsg(
"wrong number of array subscripts")));
2281 if (elmlen == -1 && !isNull)
2312 for (
i = 0;
i < nSubscripts;
i++)
2319 nSubscripts, dim, lb,
2321 elmlen, elmbyval, elmalign));
2324 if (ndim != nSubscripts)
2326 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2327 errmsg(
"wrong number of array subscripts")));
2330 memcpy(dim,
ARR_DIMS(array), ndim *
sizeof(
int));
2331 memcpy(lb,
ARR_LBOUND(array), ndim *
sizeof(
int));
2334 addedbefore = addedafter = 0;
2341 if (indx[0] < lb[0])
2343 addedbefore = lb[0] - indx[0];
2344 dim[0] += addedbefore;
2346 if (addedbefore > 1)
2349 if (indx[0] >= (dim[0] + lb[0]))
2351 addedafter = indx[0] - (dim[0] + lb[0]) + 1;
2352 dim[0] += addedafter;
2363 for (
i = 0;
i < ndim;
i++)
2365 if (indx[
i] < lb[
i] ||
2366 indx[
i] >= (dim[
i] + lb[
i]))
2368 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2369 errmsg(
"array subscript out of range")));
2387 olddatasize =
ARR_SIZE(array) - oldoverheadlen;
2393 lenafter = olddatasize;
2395 else if (addedafter)
2398 lenbefore = olddatasize;
2406 elmlen, elmbyval, elmalign);
2415 lenafter = (int) (olddatasize - lenbefore - olditemlen);
2426 newsize = overheadlen + lenbefore + newitemlen + lenafter;
2433 newarray->
ndim = ndim;
2434 newarray->
dataoffset = newhasnulls ? overheadlen : 0;
2436 memcpy(
ARR_DIMS(newarray), dim, ndim *
sizeof(
int));
2437 memcpy(
ARR_LBOUND(newarray), lb, ndim *
sizeof(
int));
2442 memcpy((
char *) newarray + overheadlen,
2443 (
char *) array + oldoverheadlen,
2447 (
char *) newarray + overheadlen + lenbefore);
2448 memcpy((
char *) newarray + overheadlen + lenbefore + newitemlen,
2449 (
char *) array + oldoverheadlen + lenbefore + olditemlen,
2463 MemSet(newnullbitmap, 0, (newnitems + 7) / 8);
2479 if (addedafter == 0)
2481 oldnullbitmap, offset + 1,
2482 oldnitems - offset - 1);
2498 int nSubscripts,
int *indx,
2499 Datum dataValue,
bool isNull,
2501 int elmlen,
bool elmbyval,
char elmalign)
2521 Assert(arraytyplen == -1);
2533 memcpy(dim, eah->
dims, ndim *
sizeof(
int));
2534 memcpy(lb, eah->
lbound, ndim *
sizeof(
int));
2535 dimschanged =
false;
2550 nSubscripts *
sizeof(
int));
2552 nSubscripts *
sizeof(
int));
2556 for (
i = 0;
i < nSubscripts;
i++)
2563 else if (ndim != nSubscripts)
2565 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2566 errmsg(
"wrong number of array subscripts")));
2595 newhasnulls = ((dnulls != NULL) || isNull);
2596 addedbefore = addedafter = 0;
2603 if (indx[0] < lb[0])
2605 addedbefore = lb[0] - indx[0];
2606 dim[0] += addedbefore;
2609 if (addedbefore > 1)
2612 if (indx[0] >= (dim[0] + lb[0]))
2614 addedafter = indx[0] - (dim[0] + lb[0]) + 1;
2615 dim[0] += addedafter;
2627 for (
i = 0;
i < ndim;
i++)
2629 if (indx[
i] < lb[
i] ||
2630 indx[
i] >= (dim[
i] + lb[
i]))
2632 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2633 errmsg(
"array subscript out of range")));
2651 int newlen = dim[0] + dim[0] / 8;
2653 newlen =
Max(newlen, dim[0]);
2657 eah->
dnulls = dnulls = (
bool *)
2658 repalloc(dnulls, newlen *
sizeof(
bool));
2666 if (newhasnulls && dnulls == NULL)
2667 eah->
dnulls = dnulls = (
bool *)
2685 memcpy(eah->
dims, dim, ndim *
sizeof(
int));
2686 memcpy(eah->
lbound, lb, ndim *
sizeof(
int));
2690 if (addedbefore > 0)
2692 memmove(dvalues + addedbefore, dvalues, eah->
nelems *
sizeof(
Datum));
2693 for (
i = 0;
i < addedbefore;
i++)
2697 memmove(dnulls + addedbefore, dnulls, eah->
nelems *
sizeof(
bool));
2698 for (
i = 0;
i < addedbefore;
i++)
2701 eah->
nelems += addedbefore;
2707 for (
i = 0;
i < addedafter;
i++)
2711 for (
i = 0;
i < addedafter;
i++)
2712 dnulls[eah->
nelems +
i] =
true;
2714 eah->
nelems += addedafter;
2718 if (!eah->
typbyval && (dnulls == NULL || !dnulls[offset]))
2724 dvalues[offset] = dataValue;
2726 dnulls[offset] = isNull;
2736 if (oldValue < eah->fstartptr || oldValue >= eah->
fendptr)
2790 bool *upperProvided,
2791 bool *lowerProvided,
2792 Datum srcArrayDatum,
2828 if (arraytyplen > 0)
2834 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2835 errmsg(
"updates on slices of fixed-length arrays not implemented")));
2859 &dvalues, &dnulls, &nelems);
2861 for (
i = 0;
i < nSubscripts;
i++)
2863 if (!upperProvided[
i] || !lowerProvided[
i])
2865 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2866 errmsg(
"array slice subscript must provide both boundaries"),
2867 errdetail(
"When assigning to a slice of an empty array value,"
2868 " slice boundaries must be fully specified.")));
2870 dim[
i] = 1 + upperIndx[
i] - lowerIndx[
i];
2871 lb[
i] = lowerIndx[
i];
2877 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2878 errmsg(
"source array too small")));
2882 elmlen, elmbyval, elmalign));
2885 if (ndim < nSubscripts || ndim <= 0 || ndim >
MAXDIM)
2887 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2888 errmsg(
"wrong number of array subscripts")));
2891 memcpy(dim,
ARR_DIMS(array), ndim *
sizeof(
int));
2892 memcpy(lb,
ARR_LBOUND(array), ndim *
sizeof(
int));
2895 addedbefore = addedafter = 0;
2902 Assert(nSubscripts == 1);
2903 if (!lowerProvided[0])
2904 lowerIndx[0] = lb[0];
2905 if (!upperProvided[0])
2906 upperIndx[0] = dim[0] + lb[0] - 1;
2907 if (lowerIndx[0] > upperIndx[0])
2909 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2910 errmsg(
"upper bound cannot be less than lower bound")));
2911 if (lowerIndx[0] < lb[0])
2913 if (upperIndx[0] < lb[0] - 1)
2915 addedbefore = lb[0] - lowerIndx[0];
2916 dim[0] += addedbefore;
2917 lb[0] = lowerIndx[0];
2919 if (upperIndx[0] >= (dim[0] + lb[0]))
2921 if (lowerIndx[0] > (dim[0] + lb[0]))
2923 addedafter = upperIndx[0] - (dim[0] + lb[0]) + 1;
2924 dim[0] += addedafter;
2933 for (
i = 0;
i < nSubscripts;
i++)
2935 if (!lowerProvided[
i])
2936 lowerIndx[
i] = lb[
i];
2937 if (!upperProvided[
i])
2938 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2939 if (lowerIndx[
i] > upperIndx[
i])
2941 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2942 errmsg(
"upper bound cannot be less than lower bound")));
2943 if (lowerIndx[
i] < lb[
i] ||
2944 upperIndx[
i] >= (dim[
i] + lb[
i]))
2946 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2947 errmsg(
"array subscript out of range")));
2950 for (;
i < ndim;
i++)
2952 lowerIndx[
i] = lb[
i];
2953 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2954 if (lowerIndx[
i] > upperIndx[
i])
2956 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2957 errmsg(
"upper bound cannot be less than lower bound")));
2973 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2974 errmsg(
"source array too small")));
2986 elmlen, elmbyval, elmalign);
2988 olddatasize =
ARR_SIZE(array) - oldoverheadlen;
2998 lowerIndx, upperIndx,
2999 elmlen, elmbyval, elmalign);
3000 lenbefore = lenafter = 0;
3001 itemsbefore = itemsafter = nolditems = 0;
3010 int oldub = oldlb +
ARR_DIMS(array)[0] - 1;
3011 int slicelb =
Max(oldlb, lowerIndx[0]);
3012 int sliceub =
Min(oldub, upperIndx[0]);
3017 itemsbefore =
Min(slicelb, oldub + 1) - oldlb;
3020 elmlen, elmbyval, elmalign);
3022 if (slicelb > sliceub)
3029 nolditems = sliceub - slicelb + 1;
3031 itemsbefore, oldarraybitmap,
3033 elmlen, elmbyval, elmalign);
3036 itemsafter = oldub + 1 -
Max(sliceub + 1, oldlb);
3037 lenafter = olddatasize - lenbefore - olditemsize;
3040 newsize = overheadlen + olddatasize - olditemsize + newitemsize;
3044 newarray->
ndim = ndim;
3045 newarray->
dataoffset = newhasnulls ? overheadlen : 0;
3047 memcpy(
ARR_DIMS(newarray), dim, ndim *
sizeof(
int));
3048 memcpy(
ARR_LBOUND(newarray), lb, ndim *
sizeof(
int));
3058 lowerIndx, upperIndx,
3059 elmlen, elmbyval, elmalign);
3064 memcpy((
char *) newarray + overheadlen,
3065 (
char *) array + oldoverheadlen,
3067 memcpy((
char *) newarray + overheadlen + lenbefore,
3070 memcpy((
char *) newarray + overheadlen + lenbefore + newitemsize,
3071 (
char *) array + oldoverheadlen + lenbefore + olditemsize,
3080 MemSet(newnullbitmap, 0, (nitems + 7) / 8);
3088 oldnullbitmap, itemsbefore + nolditems,
3105 int arraytyplen,
int elmlen,
bool elmbyval,
char elmalign,
3109 arraytyplen, elmlen, elmbyval, elmalign,
3122 Datum dataValue,
bool isNull,
3123 int arraytyplen,
int elmlen,
bool elmbyval,
char elmalign)
3129 elmlen, elmbyval, elmalign));
3215 inp_typlen = inp_extra->
typlen;
3216 inp_typbyval = inp_extra->
typbyval;
3217 inp_typalign = inp_extra->
typalign;
3227 typlen = ret_extra->
typlen;
3233 nulls = (
bool *)
palloc(nitems *
sizeof(
bool));
3239 for (
i = 0;
i < nitems;
i++)
3244 inp_typlen, inp_typbyval, inp_typalign);
3262 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3263 errmsg(
"array size exceeds the maximum allowed (%d)",
3272 nbytes += dataoffset;
3281 result->
ndim = ndim;
3321 int elmlen,
bool elmbyval,
char elmalign)
3330 elmtype, elmlen, elmbyval, elmalign);
3359 Oid elmtype,
int elmlen,
bool elmbyval,
char elmalign)
3370 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3371 errmsg(
"invalid number of dimensions: %d", ndims)));
3374 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3375 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
3389 for (
i = 0;
i < nelems;
i++)
3391 if (nulls && nulls[
i])
3404 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3405 errmsg(
"array size exceeds the maximum allowed (%d)",
3413 nbytes += dataoffset;
3422 result->
ndim = ndims;
3425 memcpy(
ARR_DIMS(result), dims, ndims *
sizeof(
int));
3426 memcpy(
ARR_LBOUND(result), lbs, ndims *
sizeof(
int));
3429 elems, nulls, nelems,
3430 elmlen, elmbyval, elmalign,
3493 int elmlen,
bool elmbyval,
char elmalign,
3494 Datum **elemsp,
bool **nullsp,
int *nelemsp)
3509 *nullsp = nulls = (
bool *)
palloc0(nelems *
sizeof(
bool));
3518 for (
i = 0;
i < nelems;
i++)
3521 if (bitmap && (*bitmap & bitmask) == 0)
3528 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
3529 errmsg(
"null array element not allowed in this context")));
3542 if (bitmask == 0x100)
3575 if (*bitmap != 0xFF)
3585 if ((*bitmap & bitmask) == 0)
3630 (
errcode(ERRCODE_DATATYPE_MISMATCH),
3631 errmsg(
"cannot compare arrays of different element types")));
3634 if (ndims1 != ndims2 ||
3635 memcmp(dims1, dims2, ndims1 *
sizeof(
int)) != 0 ||
3636 memcmp(lbs1, lbs2, ndims1 *
sizeof(
int)) != 0)
3647 if (typentry == NULL ||
3648 typentry->
type_id != element_type)
3654 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
3655 errmsg(
"could not identify an equality operator for type %s",
3657 fcinfo->flinfo->fn_extra = (
void *) typentry;
3659 typlen = typentry->
typlen;
3667 collation, NULL, NULL);
3674 for (
i = 0;
i < nitems;
i++)
3691 if (isnull1 && isnull2)
3693 if (isnull1 || isnull2)
3702 locfcinfo->args[0].value = elt1;
3703 locfcinfo->args[0].isnull =
false;
3704 locfcinfo->args[1].value = elt2;
3705 locfcinfo->args[1].isnull =
false;
3706 locfcinfo->isnull =
false;
3708 if (locfcinfo->isnull || !oprresult)
3801 (
errcode(ERRCODE_DATATYPE_MISMATCH),
3802 errmsg(
"cannot compare arrays of different element types")));
3811 if (typentry == NULL ||
3812 typentry->
type_id != element_type)
3818 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
3819 errmsg(
"could not identify a comparison function for type %s",
3823 typlen = typentry->
typlen;
3831 collation, NULL, NULL);
3834 min_nitems =
Min(nitems1, nitems2);
3838 for (
i = 0;
i < min_nitems;
i++)
3853 if (isnull1 && isnull2)
3869 locfcinfo->args[0].value = elt1;
3870 locfcinfo->args[0].isnull =
false;
3871 locfcinfo->args[1].value = elt2;
3872 locfcinfo->args[1].isnull =
false;
3876 Assert(!locfcinfo->isnull);
3903 if (nitems1 != nitems2)
3904 result = (nitems1 < nitems2) ? -1 : 1;
3905 else if (ndims1 != ndims2)
3906 result = (ndims1 < ndims2) ? -1 : 1;
3909 for (
i = 0;
i < ndims1;
i++)
3911 if (dims1[
i] != dims2[
i])
3913 result = (dims1[
i] < dims2[
i]) ? -1 : 1;
3922 for (
i = 0;
i < ndims1;
i++)
3924 if (lbound1[
i] != lbound2[
i])
3926 result = (lbound1[
i] < lbound2[
i]) ? -1 : 1;
3972 if (typentry == NULL ||
3973 typentry->
type_id != element_type)
3979 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
3980 errmsg(
"could not identify a hash function for type %s",
3990 if (element_type == RECORDOID)
4002 record_typentry =
palloc0(
sizeof(*record_typentry));
4003 record_typentry->
type_id = element_type;
4013 typentry = record_typentry;
4016 fcinfo->flinfo->fn_extra = (
void *) typentry;
4019 typlen = typentry->
typlen;
4033 for (
i = 0;
i < nitems;
i++)
4050 locfcinfo->args[0].value = elt;
4051 locfcinfo->args[0].isnull =
false;
4054 Assert(!locfcinfo->isnull);
4068 result = (result << 5) - result + elthash;
4100 if (typentry == NULL ||
4101 typentry->
type_id != element_type)
4107 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
4108 errmsg(
"could not identify an extended hash function for type %s",
4110 fcinfo->flinfo->fn_extra = (
void *) typentry;
4112 typlen = typentry->
typlen;
4123 for (
i = 0;
i < nitems;
i++)
4139 locfcinfo->args[0].value = elt;
4140 locfcinfo->args[0].isnull =
false;
4142 locfcinfo->args[1].isnull =
false;
4145 Assert(!locfcinfo->isnull);
4148 result = (result << 5) - result + elthash;
4173 bool matchall,
void **fn_extra)
4176 bool result = matchall;
4192 (
errcode(ERRCODE_DATATYPE_MISMATCH),
4193 errmsg(
"cannot compare arrays of different element types")));
4202 if (typentry == NULL ||
4203 typentry->
type_id != element_type)
4209 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
4210 errmsg(
"could not identify an equality operator for type %s",
4212 *fn_extra = (
void *) typentry;
4214 typlen = typentry->
typlen;
4233 element_type, typlen, typbyval,
typalign,
4234 &values2, &nulls2, &nelems2);
4240 collation, NULL, NULL);
4246 for (
i = 0;
i < nelems1;
i++)
4269 for (
j = 0;
j < nelems2;
j++)
4272 bool isnull2 = nulls2 ? nulls2[
j] :
false;
4281 locfcinfo->args[0].value = elt1;
4282 locfcinfo->args[0].isnull =
false;
4283 locfcinfo->args[1].value = elt2;
4284 locfcinfo->args[1].isnull =
false;
4285 locfcinfo->isnull =
false;
4287 if (!locfcinfo->isnull && oprresult)
4323 &fcinfo->flinfo->fn_extra);
4341 &fcinfo->flinfo->fn_extra);
4359 &fcinfo->flinfo->fn_extra);
4396 if (slice_ndim < 0 || slice_ndim >
ARR_NDIM(arr))
4397 elog(
ERROR,
"invalid arguments to array_create_iterator");
4402 iterator->
arr = arr;
4574 if (nullbitmap == NULL)
4576 if (nullbitmap[offset / 8] & (1 << (offset % 8)))
4593 nullbitmap += offset / 8;
4594 bitmask = 1 << (offset % 8);
4596 *nullbitmap &= ~bitmask;
4598 *nullbitmap |= bitmask;
4658 int typlen,
bool typbyval,
char typalign)
4664 if (typlen > 0 && !nullbitmap)
4670 nullbitmap += offset / 8;
4671 bitmask = 1 << (offset % 8);
4673 for (
i = 0;
i < nitems;
i++)
4675 if (*nullbitmap & bitmask)
4681 if (bitmask == 0x100)
4690 for (
i = 0;
i < nitems;
i++)
4706 int typlen,
bool typbyval,
char typalign)
4708 return array_seek(ptr, offset, nullbitmap, nitems,
4728 char *srcptr,
int offset,
bits8 *nullbitmap,
4729 int typlen,
bool typbyval,
char typalign)
4735 memcpy(destptr, srcptr, numbytes);
4758 const bits8 *srcbitmap,
int srcoffset,
4769 destbitmap += destoffset / 8;
4770 destbitmask = 1 << (destoffset % 8);
4771 destbitval = *destbitmap;
4774 srcbitmap += srcoffset / 8;
4775 srcbitmask = 1 << (srcoffset % 8);
4776 srcbitval = *srcbitmap;
4777 while (nitems-- > 0)
4779 if (srcbitval & srcbitmask)
4780 destbitval |= destbitmask;
4782 destbitval &= ~destbitmask;
4784 if (destbitmask == 0x100)
4786 *destbitmap++ = destbitval;
4789 destbitval = *destbitmap;
4792 if (srcbitmask == 0x100)
4797 srcbitval = *srcbitmap;
4800 if (destbitmask != 1)
4801 *destbitmap = destbitval;
4805 while (nitems-- > 0)
4807 destbitval |= destbitmask;
4809 if (destbitmask == 0x100)
4811 *destbitmap++ = destbitval;
4814 destbitval = *destbitmap;
4817 if (destbitmask != 1)
4818 *destbitmap = destbitval;
4829 int ndim,
int *dim,
int *lb,
4831 int typlen,
bool typbyval,
char typalign)
4847 if (typlen > 0 && !arraynullsptr)
4852 ptr =
array_seek(arraydataptr, 0, arraynullsptr, src_offset,
4856 for (
i = 0;
i < ndim;
i++)
4863 ptr =
array_seek(ptr, src_offset, arraynullsptr, dist[
j],
4865 src_offset += dist[
j];
4893 bits8 *arraynullsptr,
4914 srcdataptr =
array_seek(arraydataptr, 0, arraynullsptr, src_offset,
4919 for (
i = 0;
i < ndim;
i++)
4928 srcdataptr =
array_seek(srcdataptr, src_offset, arraynullsptr,
4931 src_offset += dist[
j];
4934 srcdataptr, src_offset, arraynullsptr,
4938 arraynullsptr, src_offset,
4995 origPtr, 0, origBitmap,
5001 orig_offset = dest_offset;
5005 for (
i = 0;
i < ndim;
i++)
5015 origPtr, orig_offset, origBitmap,
5021 origBitmap, orig_offset,
5023 dest_offset += dist[
j];
5024 orig_offset += dist[
j];
5028 srcPtr, src_offset, srcBitmap,
5032 srcBitmap, src_offset,
5039 origPtr =
array_seek(origPtr, orig_offset, origBitmap, 1,
5045 array_copy(destPtr, orignitems - orig_offset,
5046 origPtr, orig_offset, origBitmap,
5050 origBitmap, orig_offset,
5051 orignitems - orig_offset);
5099 astate->
alen = (subcontext ? 64 : 8);
5102 astate->
dnulls = (
bool *)
5124 Datum dvalue,
bool disnull,
5148 astate->
dnulls = (
bool *)
5162 if (astate->
typlen == -1)
5195 ndims = (astate->
nelems > 0) ? 1 : 0;
5196 dims[0] = astate->
nelems;
5284 (
errcode(ERRCODE_DATATYPE_MISMATCH),
5285 errmsg(
"data type %s is not an array type",
5292 "accumArrayResultArr",
5318 Datum dvalue,
bool disnull,
5339 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5340 errmsg(
"cannot accumulate null arrays")));
5360 if (astate->
ndims == 0)
5367 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5368 errmsg(
"cannot accumulate empty arrays")));
5371 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5372 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
5379 astate->
ndims = ndims + 1;
5380 astate->
dims[0] = 0;
5381 memcpy(&astate->
dims[1], dims, ndims *
sizeof(
int));
5383 memcpy(&astate->
lbs[1], lbs, ndims *
sizeof(
int));
5392 if (astate->
ndims != ndims + 1)
5394 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5395 errmsg(
"cannot accumulate arrays of different dimensionality")));
5396 for (
i = 0;
i < ndims;
i++)
5398 if (astate->
dims[
i + 1] != dims[
i] || astate->
lbs[
i + 1] != lbs[
i])
5400 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5401 errmsg(
"cannot accumulate arrays of different dimensionality")));
5408 astate->
nbytes + ndatabytes);
5420 astate->
nbytes += ndatabytes;
5425 int newnitems = astate->
nitems + nitems;
5439 else if (newnitems > astate->
aitems)
5450 astate->
nitems += nitems;
5451 astate->
dims[0] += 1;
5480 if (astate->
ndims == 0)
5499 nbytes += dataoffset;
5595 Datum dvalue,
bool disnull,
5605 input_type, rcontext);
5609 input_type, rcontext);
5704 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
5716 fctx->
lower = lb[reqdim - 1];
5717 fctx->
upper = dimv[reqdim - 1] + lb[reqdim - 1] - 1;
5768 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5769 errmsg(
"dimension array or low bound array cannot be null")));
5787 elog(
ERROR,
"could not determine data type of input");
5808 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5809 errmsg(
"dimension array or low bound array cannot be null")));
5826 elog(
ERROR,
"could not determine data type of input");
5834 Oid elmtype,
int dataoffset)
5840 result->
ndim = ndims;
5843 memcpy(
ARR_DIMS(result), dimv, ndims *
sizeof(
int));
5844 memcpy(
ARR_LBOUND(result), lbsv, ndims *
sizeof(
int));
5870 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5871 errmsg(
"wrong number of array subscripts"),
5872 errdetail(
"Dimension array must be one dimensional.")));
5876 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5877 errmsg(
"dimension values cannot be null")));
5884 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5885 errmsg(
"invalid number of dimensions: %d", ndims)));
5888 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5889 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
5896 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5897 errmsg(
"wrong number of array subscripts"),
5898 errdetail(
"Dimension array must be one dimensional.")));
5902 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5903 errmsg(
"dimension values cannot be null")));
5907 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5908 errmsg(
"wrong number of array subscripts"),
5909 errdetail(
"Low bound array has different size than dimensions array.")));
5936 if (my_extra == NULL)