46 #define AARR_FREE_IF_COPY(array,n) \
48 if (!VARATT_IS_EXPANDED_HEADER(array)) \
49 PG_FREE_IF_COPY(array, n); \
90 static int ArrayCount(
const char *str,
int *dim,
char typdelim);
91 static void ReadArrayStr(
char *arrayStr,
const char *origStr,
92 int nitems,
int ndim,
int *dim,
95 int typlen,
bool typbyval,
char typalign,
97 bool *hasnulls,
int32 *nbytes);
100 int typlen,
bool typbyval,
char typalign,
102 bool *hasnulls,
int32 *nbytes);
104 int nSubscripts,
int *indx,
106 int elmlen,
bool elmbyval,
char elmalign,
109 int nSubscripts,
int *indx,
110 Datum dataValue,
bool isNull,
112 int elmlen,
bool elmbyval,
char elmalign);
117 int typlen,
bool typbyval,
char typalign,
119 static char *
array_seek(
char *ptr,
int offset,
bits8 *nullbitmap,
int nitems,
120 int typlen,
bool typbyval,
char typalign);
122 int nitems,
int typlen,
bool typbyval,
char typalign);
123 static int array_copy(
char *destptr,
int nitems,
124 char *srcptr,
int offset,
bits8 *nullbitmap,
125 int typlen,
bool typbyval,
char typalign);
127 int ndim,
int *dim,
int *lb,
129 int typlen,
bool typbyval,
char typalign);
131 int ndim,
int *dim,
int *lb,
132 char *arraydataptr,
bits8 *arraynullsptr,
134 int typlen,
bool typbyval,
char typalign);
137 int ndim,
int *dim,
int *lb,
139 int typlen,
bool typbyval,
char typalign);
142 Oid elmtype,
int dataoffset);
147 Datum search,
bool search_isnull,
148 Datum replace,
bool replace_isnull,
149 bool remove,
Oid collation,
203 if (my_extra ==
NULL)
224 typlen = my_extra->
typlen;
259 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
260 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
263 for (q = p; isdigit((
unsigned char) *q) || (*q ==
'-') || (*q ==
'+'); q++)
267 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
268 errmsg(
"malformed array literal: \"%s\"",
string),
269 errdetail(
"\"[\" must introduce explicitly-specified array dimensions.")));
275 lBound[ndim] = atoi(p);
277 for (q = p; isdigit((
unsigned char) *q) || (*q ==
'-') || (*q ==
'+'); q++)
281 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
282 errmsg(
"malformed array literal: \"%s\"",
string),
283 errdetail(
"Missing array dimension value.")));
292 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
293 errmsg(
"malformed array literal: \"%s\"",
string),
294 errdetail(
"Missing \"%s\" after array dimensions.",
300 if (ub < lBound[ndim])
302 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
303 errmsg(
"upper bound cannot be less than lower bound")));
305 dim[ndim] = ub - lBound[ndim] + 1;
314 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
315 errmsg(
"malformed array literal: \"%s\"",
string),
316 errdetail(
"Array value must start with \"{\" or dimension information.")));
318 for (i = 0; i < ndim; i++)
329 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
330 errmsg(
"malformed array literal: \"%s\"",
string),
331 errdetail(
"Missing \"%s\" after array dimensions.",
343 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
344 errmsg(
"malformed array literal: \"%s\"",
string),
345 errdetail(
"Array contents must start with \"{\".")));
346 ndim_braces =
ArrayCount(p, dim_braces, typdelim);
347 if (ndim_braces != ndim)
349 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
350 errmsg(
"malformed array literal: \"%s\"",
string),
351 errdetail(
"Specified array dimensions do not match array contents.")));
352 for (i = 0; i < ndim; ++
i)
354 if (dim[i] != dim_braces[i])
356 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
357 errmsg(
"malformed array literal: \"%s\"",
string),
358 errdetail(
"Specified array dimensions do not match array contents.")));
363 printf(
"array_in- ndim %d (", ndim);
364 for (i = 0; i < ndim; i++)
366 printf(
" %d", dim[i]);
368 printf(
") for %s\n",
string);
378 nullsPtr = (
bool *)
palloc(nitems *
sizeof(
bool));
381 &my_extra->
proc, typioparam, typmod,
383 typlen, typbyval, typalign,
389 nbytes += dataoffset;
407 memcpy(
ARR_DIMS(retval), dim, ndim *
sizeof(
int));
408 memcpy(
ARR_LBOUND(retval), lBound, ndim *
sizeof(
int));
411 dataPtr, nullsPtr, nitems,
412 typlen, typbyval, typalign,
459 bool in_quotes =
false;
460 bool eoArray =
false;
461 bool empty_array =
true;
467 temp[
i] = dim[
i] = nelems_last[
i] = 0;
474 bool itemdone =
false;
487 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
488 errmsg(
"malformed array literal: \"%s\"", str),
503 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
504 errmsg(
"malformed array literal: \"%s\"", str),
505 errdetail(
"Unexpected \"%c\" character.",
514 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
515 errmsg(
"malformed array literal: \"%s\"", str),
529 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
530 errmsg(
"malformed array literal: \"%s\"", str),
531 errdetail(
"Unexpected array element.")));
532 in_quotes = !in_quotes;
550 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
551 errmsg(
"malformed array literal: \"%s\"", str),
552 errdetail(
"Unexpected \"%c\" character.",
555 if (nest_level >= MAXDIM)
557 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
558 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
559 nest_level + 1, MAXDIM)));
560 temp[nest_level] = 0;
562 if (ndim < nest_level)
580 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
581 errmsg(
"malformed array literal: \"%s\"", str),
582 errdetail(
"Unexpected \"%c\" character.",
587 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
588 errmsg(
"malformed array literal: \"%s\"", str),
589 errdetail(
"Unmatched \"%c\" character.",
'}')));
592 if (nelems_last[nest_level] != 0 &&
593 nelems[nest_level] != nelems_last[nest_level])
595 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
596 errmsg(
"malformed array literal: \"%s\"", str),
597 errdetail(
"Multidimensional arrays must have "
598 "sub-arrays with matching "
600 nelems_last[nest_level] = nelems[nest_level];
601 nelems[nest_level] = 1;
603 eoArray = itemdone =
true;
610 temp[nest_level - 1]++;
617 if (*ptr == typdelim)
629 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
630 errmsg(
"malformed array literal: \"%s\"", str),
631 errdetail(
"Unexpected \"%c\" character.",
638 nelems[nest_level - 1]++;
652 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
653 errmsg(
"malformed array literal: \"%s\"", str),
654 errdetail(
"Unexpected array element.")));
672 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
673 errmsg(
"malformed array literal: \"%s\"", str),
674 errdetail(
"Junk after closing right brace.")));
681 for (
i = 0;
i < ndim; ++
i)
736 bool in_quotes =
false;
737 bool eoArray =
false;
744 MemSet(indx, 0,
sizeof(indx));
747 memset(nulls,
true, nitems *
sizeof(
bool));
767 bool itemdone =
false;
768 bool leadingspace =
true;
769 bool hasquoting =
false;
775 itemstart = dstptr = dstendptr = srcptr;
784 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
785 errmsg(
"malformed array literal: \"%s\"",
793 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
794 errmsg(
"malformed array literal: \"%s\"",
796 *dstptr++ = *srcptr++;
798 leadingspace =
false;
803 in_quotes = !in_quotes;
805 leadingspace =
false;
821 if (nest_level >= ndim)
823 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
824 errmsg(
"malformed array literal: \"%s\"",
827 indx[nest_level - 1] = 0;
831 *dstptr++ = *srcptr++;
838 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
839 errmsg(
"malformed array literal: \"%s\"",
843 indx[nest_level - 1] = 0;
846 eoArray = itemdone =
true;
848 indx[nest_level - 1]++;
852 *dstptr++ = *srcptr++;
856 *dstptr++ = *srcptr++;
857 else if (*srcptr == typdelim)
874 *dstptr++ = *srcptr++;
878 *dstptr++ = *srcptr++;
879 leadingspace =
false;
889 if (i < 0 || i >= nitems)
891 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
892 errmsg(
"malformed array literal: \"%s\"",
916 for (i = 0; i < nitems; i++)
930 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
931 errmsg(
"array size exceeds the maximum allowed (%d)",
974 for (i = 0; i < nitems; i++)
976 if (nulls && nulls[i])
979 elog(
ERROR,
"null array element where not supported");
992 if (bitmask == 0x100)
1001 if (bitmap && bitmask != 1)
1023 dims_str[(
MAXDIM * 33) + 2];
1050 if (my_extra ==
NULL)
1071 typlen = my_extra->
typlen;
1091 for (i = 0; i < ndim; i++)
1105 values = (
char **)
palloc(nitems *
sizeof(
char *));
1106 needquotes = (
bool *)
palloc(nitems *
sizeof(
bool));
1111 for (i = 0; i < nitems; i++)
1119 typlen, typbyval, typalign);
1124 overall_length += 4;
1132 if (values[i][0] ==
'\0')
1139 for (tmp = values[i]; *tmp !=
'\0'; tmp++)
1143 overall_length += 1;
1144 if (ch ==
'"' || ch ==
'\\')
1147 overall_length += 1;
1149 else if (ch ==
'{' || ch ==
'}' || ch == typdelim ||
1155 needquotes[
i] = needquote;
1159 overall_length += 2;
1161 overall_length += 1;
1167 for (i = j = 0, k = 1; i < ndim; i++)
1168 k *= dims[i], j += k;
1175 char *ptr = dims_str;
1177 for (i = 0; i < ndim; i++)
1179 sprintf(ptr,
"[%d:%d]", lb[i], lb[i] + dims[i] - 1);
1186 retval = (
char *)
palloc(strlen(dims_str) + overall_length + 2 * j);
1189 #define APPENDSTR(str) (strcpy(p, (str)), p += strlen(p))
1190 #define APPENDCHAR(ch) (*p++ = (ch), *p = '\0')
1195 for (i = 0; i < ndim; i++)
1201 for (i = j; i < ndim - 1; i++)
1207 for (tmp = values[k]; *tmp; tmp++)
1211 if (ch ==
'"' || ch ==
'\\')
1222 for (i = ndim - 1; i >= 0; i--)
1224 indx[
i] = (indx[
i] + 1) % dims[i];
1283 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1284 errmsg(
"invalid number of dimensions: %d", ndim)));
1287 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1288 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
1292 if (flags != 0 && flags != 1)
1294 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1295 errmsg(
"invalid array flags")));
1298 if (element_type != spec_element_type)
1302 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1303 errmsg(
"wrong element type")));
1306 for (i = 0; i < ndim; i++)
1317 int ub = lBound[
i] + dim[
i] - 1;
1321 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1322 errmsg(
"integer out of range")));
1335 if (my_extra ==
NULL)
1352 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
1353 errmsg(
"no binary input function available for type %s",
1366 typlen = my_extra->
typlen;
1372 nullsPtr = (
bool *)
palloc(nitems *
sizeof(
bool));
1374 &my_extra->
proc, typioparam, typmod,
1375 typlen, typbyval, typalign,
1377 &hasnulls, &nbytes);
1381 nbytes += dataoffset;
1390 retval->
ndim = ndim;
1393 memcpy(
ARR_DIMS(retval), dim, ndim *
sizeof(
int));
1394 memcpy(
ARR_LBOUND(retval), lBound, ndim *
sizeof(
int));
1397 dataPtr, nullsPtr, nitems,
1398 typlen, typbyval, typalign,
1446 for (i = 0; i < nitems; i++)
1454 if (itemlen < -1 || itemlen > (buf->
len - buf->
cursor))
1456 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1457 errmsg(
"insufficient data left in message")));
1463 typioparam, typmod);
1475 elem_buf.
maxlen = itemlen + 1;
1476 elem_buf.
len = itemlen;
1486 typioparam, typmod);
1490 if (elem_buf.
cursor != itemlen)
1492 (
errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1493 errmsg(
"improper binary format in array element %d",
1504 for (i = 0; i < nitems; i++)
1518 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1519 errmsg(
"array size exceeds the maximum allowed (%d)",
1523 *hasnulls = hasnull;
1556 if (my_extra ==
NULL)
1573 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
1574 errmsg(
"no binary output function available for type %s",
1580 typlen = my_extra->
typlen;
1595 for (i = 0; i < ndim; i++)
1604 for (i = 0; i < nitems; i++)
1611 typlen, typbyval, typalign);
1679 sprintf(p,
"[%d:%d]", lb[i], dimv[i] + lb[i] - 1);
1704 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
1708 result = lb[reqdim - 1];
1732 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
1738 result = dimv[reqdim - 1] + lb[reqdim - 1] - 1;
1761 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
1766 result = dimv[reqdim - 1];
1824 bits8 *arraynullsptr;
1826 if (arraytyplen > 0)
1832 fixedDim[0] = arraytyplen / elmlen;
1837 arraynullsptr =
NULL;
1866 if (ndim != nSubscripts || ndim <= 0 || ndim >
MAXDIM)
1871 for (i = 0; i < ndim; i++)
1873 if (indx[i] < lb[i] || indx[i] >= (dim[i] + lb[i]))
1898 retptr =
array_seek(arraydataptr, 0, arraynullsptr, offset,
1899 elmlen, elmbyval, elmalign);
1900 return ArrayCast(retptr, elmbyval, elmlen);
1908 int nSubscripts,
int *indx,
1910 int elmlen,
bool elmbyval,
char elmalign,
1926 Assert(arraytyplen == -1);
1938 if (ndim != nSubscripts || ndim <= 0 || ndim >
MAXDIM)
1943 for (i = 0; i < ndim; i++)
1945 if (indx[i] < lb[i] || indx[i] >= (dim[i] + lb[i]))
1969 if (dnulls && dnulls[offset])
1982 return dvalues[offset];
2019 bool *upperProvided,
2020 bool *lowerProvided,
2037 bits8 *arraynullsptr;
2042 if (arraytyplen > 0)
2051 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2052 errmsg(
"slices of fixed-length arrays not implemented")));
2060 fixedDim[0] = arraytyplen / elmlen;
2066 arraynullsptr =
NULL;
2086 if (ndim < nSubscripts || ndim <= 0 || ndim >
MAXDIM)
2089 for (i = 0; i < nSubscripts; i++)
2091 if (!lowerProvided[i] || lowerIndx[i] < lb[i])
2092 lowerIndx[
i] = lb[
i];
2093 if (!upperProvided[i] || upperIndx[i] >= (dim[i] + lb[i]))
2094 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2095 if (lowerIndx[i] > upperIndx[i])
2099 for (; i < ndim; i++)
2101 lowerIndx[
i] = lb[
i];
2102 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2103 if (lowerIndx[i] > upperIndx[i])
2111 lowerIndx, upperIndx,
2112 elmlen, elmbyval, elmalign);
2121 bytes += dataoffset;
2131 newarray->
ndim = ndim;
2134 memcpy(
ARR_DIMS(newarray), span, ndim *
sizeof(
int));
2141 for (i = 0; i < ndim; i++)
2146 arraydataptr, arraynullsptr,
2147 lowerIndx, upperIndx,
2148 elmlen, elmbyval, elmalign);
2205 bits8 *oldnullbitmap;
2219 if (arraytyplen > 0)
2227 if (nSubscripts != 1)
2229 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2230 errmsg(
"wrong number of array subscripts")));
2232 if (indx[0] < 0 || indx[0] * elmlen >= arraytyplen)
2234 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2235 errmsg(
"array subscript out of range")));
2239 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2240 errmsg(
"cannot assign null value to an element of a fixed-length array")));
2242 resultarray = (
char *)
palloc(arraytyplen);
2244 elt_ptr = (
char *) resultarray + indx[0] * elmlen;
2249 if (nSubscripts <= 0 || nSubscripts >
MAXDIM)
2251 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2252 errmsg(
"wrong number of array subscripts")));
2255 if (elmlen == -1 && !isNull)
2286 for (i = 0; i < nSubscripts; i++)
2293 nSubscripts, dim, lb,
2295 elmlen, elmbyval, elmalign));
2298 if (ndim != nSubscripts)
2300 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2301 errmsg(
"wrong number of array subscripts")));
2304 memcpy(dim,
ARR_DIMS(array), ndim *
sizeof(
int));
2305 memcpy(lb,
ARR_LBOUND(array), ndim *
sizeof(
int));
2308 addedbefore = addedafter = 0;
2315 if (indx[0] < lb[0])
2317 addedbefore = lb[0] - indx[0];
2318 dim[0] += addedbefore;
2320 if (addedbefore > 1)
2323 if (indx[0] >= (dim[0] + lb[0]))
2325 addedafter = indx[0] - (dim[0] + lb[0]) + 1;
2326 dim[0] += addedafter;
2337 for (i = 0; i < ndim; i++)
2339 if (indx[i] < lb[i] ||
2340 indx[i] >= (dim[i] + lb[i]))
2342 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2343 errmsg(
"array subscript out of range")));
2358 olddatasize =
ARR_SIZE(array) - oldoverheadlen;
2364 lenafter = olddatasize;
2366 else if (addedafter)
2369 lenbefore = olddatasize;
2377 elmlen, elmbyval, elmalign);
2386 lenafter = (int) (olddatasize - lenbefore - olditemlen);
2397 newsize = overheadlen + lenbefore + newitemlen + lenafter;
2404 newarray->
ndim = ndim;
2405 newarray->
dataoffset = newhasnulls ? overheadlen : 0;
2407 memcpy(
ARR_DIMS(newarray), dim, ndim *
sizeof(
int));
2408 memcpy(
ARR_LBOUND(newarray), lb, ndim *
sizeof(
int));
2413 memcpy((
char *) newarray + overheadlen,
2414 (
char *) array + oldoverheadlen,
2418 (
char *) newarray + overheadlen + lenbefore);
2419 memcpy((
char *) newarray + overheadlen + lenbefore + newitemlen,
2420 (
char *) array + oldoverheadlen + lenbefore + olditemlen,
2434 MemSet(newnullbitmap, 0, (newnitems + 7) / 8);
2450 if (addedafter == 0)
2452 oldnullbitmap, offset + 1,
2453 oldnitems - offset - 1);
2469 int nSubscripts,
int *indx,
2470 Datum dataValue,
bool isNull,
2472 int elmlen,
bool elmbyval,
char elmalign)
2492 Assert(arraytyplen == -1);
2504 memcpy(dim, eah->
dims, ndim *
sizeof(
int));
2505 memcpy(lb, eah->
lbound, ndim *
sizeof(
int));
2506 dimschanged =
false;
2521 nSubscripts *
sizeof(
int));
2523 nSubscripts *
sizeof(
int));
2527 for (i = 0; i < nSubscripts; i++)
2534 else if (ndim != nSubscripts)
2536 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2537 errmsg(
"wrong number of array subscripts")));
2563 newhasnulls = ((dnulls !=
NULL) || isNull);
2564 addedbefore = addedafter = 0;
2571 if (indx[0] < lb[0])
2573 addedbefore = lb[0] - indx[0];
2574 dim[0] += addedbefore;
2577 if (addedbefore > 1)
2580 if (indx[0] >= (dim[0] + lb[0]))
2582 addedafter = indx[0] - (dim[0] + lb[0]) + 1;
2583 dim[0] += addedafter;
2595 for (i = 0; i < ndim; i++)
2597 if (indx[i] < lb[i] ||
2598 indx[i] >= (dim[i] + lb[i]))
2600 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2601 errmsg(
"array subscript out of range")));
2612 int newlen = dim[0] + dim[0] / 8;
2614 newlen =
Max(newlen, dim[0]);
2618 eah->
dnulls = dnulls = (
bool *)
2619 repalloc(dnulls, newlen *
sizeof(
bool));
2627 if (newhasnulls && dnulls ==
NULL)
2628 eah->
dnulls = dnulls = (
bool *)
2646 memcpy(eah->
dims, dim, ndim *
sizeof(
int));
2647 memcpy(eah->
lbound, lb, ndim *
sizeof(
int));
2651 if (addedbefore > 0)
2654 for (i = 0; i < addedbefore; i++)
2655 dvalues[i] = (
Datum) 0;
2658 memmove(dnulls + addedbefore, dnulls, eah->
nelems *
sizeof(
bool));
2659 for (i = 0; i < addedbefore; i++)
2662 eah->
nelems += addedbefore;
2668 for (i = 0; i < addedafter; i++)
2672 for (i = 0; i < addedafter; i++)
2673 dnulls[eah->
nelems + i] =
true;
2675 eah->
nelems += addedafter;
2679 if (!eah->
typbyval && (dnulls ==
NULL || !dnulls[offset]))
2685 dvalues[offset] = dataValue;
2687 dnulls[offset] = isNull;
2697 if (oldValue < eah->fstartptr || oldValue >= eah->
fendptr)
2750 bool *upperProvided,
2751 bool *lowerProvided,
2752 Datum srcArrayDatum,
2788 if (arraytyplen > 0)
2794 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2795 errmsg(
"updates on slices of fixed-length arrays not implemented")));
2819 &dvalues, &dnulls, &nelems);
2821 for (i = 0; i < nSubscripts; i++)
2823 if (!upperProvided[i] || !lowerProvided[i])
2825 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2826 errmsg(
"array slice subscript must provide both boundaries"),
2827 errdetail(
"When assigning to a slice of an empty array value,"
2828 " slice boundaries must be fully specified.")));
2830 dim[
i] = 1 + upperIndx[
i] - lowerIndx[
i];
2831 lb[
i] = lowerIndx[
i];
2837 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2838 errmsg(
"source array too small")));
2842 elmlen, elmbyval, elmalign));
2845 if (ndim < nSubscripts || ndim <= 0 || ndim >
MAXDIM)
2847 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2848 errmsg(
"wrong number of array subscripts")));
2851 memcpy(dim,
ARR_DIMS(array), ndim *
sizeof(
int));
2852 memcpy(lb,
ARR_LBOUND(array), ndim *
sizeof(
int));
2855 addedbefore = addedafter = 0;
2862 Assert(nSubscripts == 1);
2863 if (!lowerProvided[0])
2864 lowerIndx[0] = lb[0];
2865 if (!upperProvided[0])
2866 upperIndx[0] = dim[0] + lb[0] - 1;
2867 if (lowerIndx[0] > upperIndx[0])
2869 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2870 errmsg(
"upper bound cannot be less than lower bound")));
2871 if (lowerIndx[0] < lb[0])
2873 if (upperIndx[0] < lb[0] - 1)
2875 addedbefore = lb[0] - lowerIndx[0];
2876 dim[0] += addedbefore;
2877 lb[0] = lowerIndx[0];
2879 if (upperIndx[0] >= (dim[0] + lb[0]))
2881 if (lowerIndx[0] > (dim[0] + lb[0]))
2883 addedafter = upperIndx[0] - (dim[0] + lb[0]) + 1;
2884 dim[0] += addedafter;
2893 for (i = 0; i < nSubscripts; i++)
2895 if (!lowerProvided[i])
2896 lowerIndx[
i] = lb[
i];
2897 if (!upperProvided[i])
2898 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2899 if (lowerIndx[i] > upperIndx[i])
2901 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2902 errmsg(
"upper bound cannot be less than lower bound")));
2903 if (lowerIndx[i] < lb[i] ||
2904 upperIndx[i] >= (dim[i] + lb[i]))
2906 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2907 errmsg(
"array subscript out of range")));
2910 for (; i < ndim; i++)
2912 lowerIndx[
i] = lb[
i];
2913 upperIndx[
i] = dim[
i] + lb[
i] - 1;
2914 if (lowerIndx[i] > upperIndx[i])
2916 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2917 errmsg(
"upper bound cannot be less than lower bound")));
2932 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2933 errmsg(
"source array too small")));
2945 elmlen, elmbyval, elmalign);
2947 olddatasize =
ARR_SIZE(array) - oldoverheadlen;
2957 lowerIndx, upperIndx,
2958 elmlen, elmbyval, elmalign);
2959 lenbefore = lenafter = 0;
2960 itemsbefore = itemsafter = nolditems = 0;
2969 int oldub = oldlb +
ARR_DIMS(array)[0] - 1;
2970 int slicelb =
Max(oldlb, lowerIndx[0]);
2971 int sliceub =
Min(oldub, upperIndx[0]);
2976 itemsbefore =
Min(slicelb, oldub + 1) - oldlb;
2979 elmlen, elmbyval, elmalign);
2981 if (slicelb > sliceub)
2988 nolditems = sliceub - slicelb + 1;
2990 itemsbefore, oldarraybitmap,
2992 elmlen, elmbyval, elmalign);
2995 itemsafter = oldub + 1 -
Max(sliceub + 1, oldlb);
2996 lenafter = olddatasize - lenbefore - olditemsize;
2999 newsize = overheadlen + olddatasize - olditemsize + newitemsize;
3003 newarray->
ndim = ndim;
3004 newarray->
dataoffset = newhasnulls ? overheadlen : 0;
3006 memcpy(
ARR_DIMS(newarray), dim, ndim *
sizeof(
int));
3007 memcpy(
ARR_LBOUND(newarray), lb, ndim *
sizeof(
int));
3017 lowerIndx, upperIndx,
3018 elmlen, elmbyval, elmalign);
3023 memcpy((
char *) newarray + overheadlen,
3024 (
char *) array + oldoverheadlen,
3026 memcpy((
char *) newarray + overheadlen + lenbefore,
3029 memcpy((
char *) newarray + overheadlen + lenbefore + newitemsize,
3030 (
char *) array + oldoverheadlen + lenbefore + olditemsize,
3039 MemSet(newnullbitmap, 0, (nitems + 7) / 8);
3047 oldnullbitmap, itemsbefore + nolditems,
3064 int arraytyplen,
int elmlen,
bool elmbyval,
char elmalign,
3068 arraytyplen, elmlen, elmbyval, elmalign,
3081 Datum dataValue,
bool isNull,
3082 int arraytyplen,
int elmlen,
bool elmbyval,
char elmalign)
3088 elmlen, elmbyval, elmalign));
3145 if (fcinfo->
nargs < 1)
3179 inp_typlen = inp_extra->
typlen;
3180 inp_typbyval = inp_extra->
typbyval;
3181 inp_typalign = inp_extra->
typalign;
3191 typlen = ret_extra->
typlen;
3197 nulls = (
bool *)
palloc(nitems *
sizeof(
bool));
3203 for (i = 0; i < nitems; i++)
3209 inp_typlen, inp_typbyval, inp_typalign);
3218 for (j = 0; j < fcinfo->
nargs; j++)
3250 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3251 errmsg(
"array size exceeds the maximum allowed (%d)",
3260 nbytes += dataoffset;
3269 result->
ndim = ndim;
3279 values, nulls, nitems,
3280 typlen, typbyval, typalign,
3308 int elmlen,
bool elmbyval,
char elmalign)
3317 elmtype, elmlen, elmbyval, elmalign);
3345 Oid elmtype,
int elmlen,
bool elmbyval,
char elmalign)
3356 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3357 errmsg(
"invalid number of dimensions: %d", ndims)));
3360 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3361 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
3373 for (i = 0; i < nelems; i++)
3375 if (nulls && nulls[i])
3388 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3389 errmsg(
"array size exceeds the maximum allowed (%d)",
3397 nbytes += dataoffset;
3406 result->
ndim = ndims;
3409 memcpy(
ARR_DIMS(result), dims, ndims *
sizeof(
int));
3410 memcpy(
ARR_LBOUND(result), lbs, ndims *
sizeof(
int));
3413 elems, nulls, nelems,
3414 elmlen, elmbyval, elmalign,
3477 int elmlen,
bool elmbyval,
char elmalign,
3478 Datum **elemsp,
bool **nullsp,
int *nelemsp)
3493 *nullsp = nulls = (
bool *)
palloc0(nelems *
sizeof(
bool));
3502 for (i = 0; i < nelems; i++)
3505 if (bitmap && (*bitmap & bitmask) == 0)
3512 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
3513 errmsg(
"null array element not allowed in this context")));
3526 if (bitmask == 0x100)
3559 if (*bitmap != 0xFF)
3569 if ((*bitmap & bitmask) == 0)
3614 (
errcode(ERRCODE_DATATYPE_MISMATCH),
3615 errmsg(
"cannot compare arrays of different element types")));
3618 if (ndims1 != ndims2 ||
3619 memcmp(dims1, dims2, ndims1 *
sizeof(
int)) != 0 ||
3620 memcmp(lbs1, lbs2, ndims1 *
sizeof(
int)) != 0)
3631 if (typentry ==
NULL ||
3632 typentry->
type_id != element_type)
3638 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
3639 errmsg(
"could not identify an equality operator for type %s",
3641 fcinfo->flinfo->fn_extra = (
void *) typentry;
3643 typlen = typentry->
typlen;
3658 for (i = 0; i < nitems; i++)
3668 typlen, typbyval, typalign);
3670 typlen, typbyval, typalign);
3675 if (isnull1 && isnull2)
3677 if (isnull1 || isnull2)
3686 locfcinfo.
arg[0] = elt1;
3687 locfcinfo.
arg[1] = elt2;
3690 locfcinfo.
isnull =
false;
3785 (
errcode(ERRCODE_DATATYPE_MISMATCH),
3786 errmsg(
"cannot compare arrays of different element types")));
3795 if (typentry ==
NULL ||
3796 typentry->
type_id != element_type)
3802 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
3803 errmsg(
"could not identify a comparison function for type %s",
3807 typlen = typentry->
typlen;
3818 min_nitems =
Min(nitems1, nitems2);
3822 for (i = 0; i < min_nitems; i++)
3831 elt1 =
array_iter_next(&it1, &isnull1, i, typlen, typbyval, typalign);
3832 elt2 =
array_iter_next(&it2, &isnull2, i, typlen, typbyval, typalign);
3837 if (isnull1 && isnull2)
3853 locfcinfo.
arg[0] = elt1;
3854 locfcinfo.
arg[1] = elt2;
3857 locfcinfo.
isnull =
false;
3885 if (nitems1 != nitems2)
3886 result = (nitems1 < nitems2) ? -1 : 1;
3887 else if (ndims1 != ndims2)
3888 result = (ndims1 < ndims2) ? -1 : 1;
3891 for (i = 0; i < ndims1; i++)
3893 if (dims1[i] != dims2[i])
3895 result = (dims1[
i] < dims2[
i]) ? -1 : 1;
3904 for (i = 0; i < ndims1; i++)
3906 if (lbound1[i] != lbound2[i])
3908 result = (lbound1[
i] < lbound2[
i]) ? -1 : 1;
3954 if (typentry ==
NULL ||
3955 typentry->
type_id != element_type)
3961 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
3962 errmsg(
"could not identify a hash function for type %s",
3964 fcinfo->flinfo->fn_extra = (
void *) typentry;
3966 typlen = typentry->
typlen;
3980 for (i = 0; i < nitems; i++)
3997 locfcinfo.
arg[0] = elt;
3999 locfcinfo.
isnull =
false;
4014 result = (result << 5) - result + elthash;
4040 bool matchall,
void **fn_extra)
4042 bool result = matchall;
4059 (
errcode(ERRCODE_DATATYPE_MISMATCH),
4060 errmsg(
"cannot compare arrays of different element types")));
4069 if (typentry ==
NULL ||
4070 typentry->
type_id != element_type)
4076 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
4077 errmsg(
"could not identify an equality operator for type %s",
4079 *fn_extra = (
void *) typentry;
4081 typlen = typentry->
typlen;
4100 element_type, typlen, typbyval, typalign,
4101 &values2, &nulls2, &nelems2);
4113 for (i = 0; i < nelems1; i++)
4119 elt1 =
array_iter_next(&it1, &isnull1, i, typlen, typbyval, typalign);
4136 for (j = 0; j < nelems2; j++)
4138 Datum elt2 = values2[j];
4139 bool isnull2 = nulls2 ? nulls2[j] :
false;
4148 locfcinfo.
arg[0] = elt1;
4149 locfcinfo.
arg[1] = elt2;
4152 locfcinfo.
isnull =
false;
4190 &fcinfo->flinfo->fn_extra);
4208 &fcinfo->flinfo->fn_extra);
4226 &fcinfo->flinfo->fn_extra);
4263 if (slice_ndim < 0 || slice_ndim >
ARR_NDIM(arr))
4264 elog(
ERROR,
"invalid arguments to array_create_iterator");
4269 iterator->
arr = arr;
4375 for (i = 0; i < iterator->
slice_len; i++)
4441 if (nullbitmap ==
NULL)
4443 if (nullbitmap[offset / 8] & (1 << (offset % 8)))
4460 nullbitmap += offset / 8;
4461 bitmask = 1 << (offset % 8);
4463 *nullbitmap &= ~bitmask;
4465 *nullbitmap |= bitmask;
4525 int typlen,
bool typbyval,
char typalign)
4531 if (typlen > 0 && !nullbitmap)
4537 nullbitmap += offset / 8;
4538 bitmask = 1 << (offset % 8);
4540 for (i = 0; i < nitems; i++)
4542 if (*nullbitmap & bitmask)
4548 if (bitmask == 0x100)
4557 for (i = 0; i < nitems; i++)
4573 int typlen,
bool typbyval,
char typalign)
4575 return array_seek(ptr, offset, nullbitmap, nitems,
4576 typlen, typbyval, typalign) - ptr;
4595 char *srcptr,
int offset,
bits8 *nullbitmap,
4596 int typlen,
bool typbyval,
char typalign)
4601 typlen, typbyval, typalign);
4602 memcpy(destptr, srcptr, numbytes);
4625 const bits8 *srcbitmap,
int srcoffset,
4636 destbitmap += destoffset / 8;
4637 destbitmask = 1 << (destoffset % 8);
4638 destbitval = *destbitmap;
4641 srcbitmap += srcoffset / 8;
4642 srcbitmask = 1 << (srcoffset % 8);
4643 srcbitval = *srcbitmap;
4644 while (nitems-- > 0)
4646 if (srcbitval & srcbitmask)
4647 destbitval |= destbitmask;
4649 destbitval &= ~destbitmask;
4651 if (destbitmask == 0x100)
4653 *destbitmap++ = destbitval;
4656 destbitval = *destbitmap;
4659 if (srcbitmask == 0x100)
4664 srcbitval = *srcbitmap;
4667 if (destbitmask != 1)
4668 *destbitmap = destbitval;
4672 while (nitems-- > 0)
4674 destbitval |= destbitmask;
4676 if (destbitmask == 0x100)
4678 *destbitmap++ = destbitval;
4681 destbitval = *destbitmap;
4684 if (destbitmask != 1)
4685 *destbitmap = destbitval;
4696 int ndim,
int *dim,
int *lb,
4698 int typlen,
bool typbyval,
char typalign)
4714 if (typlen > 0 && !arraynullsptr)
4719 ptr =
array_seek(arraydataptr, 0, arraynullsptr, src_offset,
4720 typlen, typbyval, typalign);
4723 for (i = 0; i < ndim; i++)
4730 ptr =
array_seek(ptr, src_offset, arraynullsptr, dist[j],
4731 typlen, typbyval, typalign);
4732 src_offset += dist[j];
4760 bits8 *arraynullsptr,
4781 srcdataptr =
array_seek(arraydataptr, 0, arraynullsptr, src_offset,
4782 typlen, typbyval, typalign);
4786 for (i = 0; i < ndim; i++)
4795 srcdataptr =
array_seek(srcdataptr, src_offset, arraynullsptr,
4797 typlen, typbyval, typalign);
4798 src_offset += dist[j];
4801 srcdataptr, src_offset, arraynullsptr,
4802 typlen, typbyval, typalign);
4805 arraynullsptr, src_offset,
4862 origPtr, 0, origBitmap,
4863 typlen, typbyval, typalign);
4868 orig_offset = dest_offset;
4872 for (i = 0; i < ndim; i++)
4882 origPtr, orig_offset, origBitmap,
4883 typlen, typbyval, typalign);
4888 origBitmap, orig_offset,
4890 dest_offset += dist[j];
4891 orig_offset += dist[j];
4895 srcPtr, src_offset, srcBitmap,
4896 typlen, typbyval, typalign);
4899 srcBitmap, src_offset,
4906 origPtr =
array_seek(origPtr, orig_offset, origBitmap, 1,
4907 typlen, typbyval, typalign);
4912 array_copy(destPtr, orignitems - orig_offset,
4913 origPtr, orig_offset, origBitmap,
4914 typlen, typbyval, typalign);
4917 origBitmap, orig_offset,
4918 orignitems - orig_offset);
4968 astate->
alen = (subcontext ? 64 : 8);
4972 astate->
dnulls = (
bool *)
4994 Datum dvalue,
bool disnull,
5018 astate->
dnulls = (
bool *)
5032 if (astate->
typlen == -1)
5065 ndims = (astate->
nelems > 0) ? 1 : 0;
5066 dims[0] = astate->
nelems;
5155 (
errcode(ERRCODE_DATATYPE_MISMATCH),
5156 errmsg(
"data type %s is not an array type",
5163 "accumArrayResultArr",
5191 Datum dvalue,
bool disnull,
5212 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5213 errmsg(
"cannot accumulate null arrays")));
5233 if (astate->
ndims == 0)
5240 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5241 errmsg(
"cannot accumulate empty arrays")));
5244 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5245 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
5252 astate->
ndims = ndims + 1;
5253 astate->
dims[0] = 0;
5254 memcpy(&astate->
dims[1], dims, ndims *
sizeof(
int));
5256 memcpy(&astate->
lbs[1], lbs, ndims *
sizeof(
int));
5260 while (astate->
abytes <= ndatabytes)
5267 if (astate->
ndims != ndims + 1)
5269 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5270 errmsg(
"cannot accumulate arrays of different dimensionality")));
5271 for (i = 0; i < ndims; i++)
5273 if (astate->
dims[i + 1] != dims[i] || astate->
lbs[i + 1] != lbs[i])
5275 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5276 errmsg(
"cannot accumulate arrays of different dimensionality")));
5283 astate->
nbytes + ndatabytes);
5294 memcpy(astate->
data + astate->
nbytes, data, ndatabytes);
5295 astate->
nbytes += ndatabytes;
5300 int newnitems = astate->
nitems + nitems;
5309 while (astate->
aitems <= newnitems)
5316 else if (newnitems > astate->
aitems)
5327 astate->
nitems += nitems;
5328 astate->
dims[0] += 1;
5357 if (astate->
ndims == 0)
5372 nbytes += dataoffset;
5468 Datum dvalue,
bool disnull,
5478 input_type, rcontext);
5482 input_type, rcontext);
5577 if (reqdim <= 0 || reqdim >
AARR_NDIM(v))
5589 fctx->
lower = lb[reqdim - 1];
5590 fctx->
upper = dimv[reqdim - 1] + lb[reqdim - 1] - 1;
5641 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5642 errmsg(
"dimension array or low bound array cannot be null")));
5660 elog(
ERROR,
"could not determine data type of input");
5681 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5682 errmsg(
"dimension array or low bound array cannot be null")));
5699 elog(
ERROR,
"could not determine data type of input");
5707 Oid elmtype,
int dataoffset)
5713 result->
ndim = ndims;
5716 memcpy(
ARR_DIMS(result), dimv, ndims *
sizeof(
int));
5717 memcpy(
ARR_LBOUND(result), lbsv, ndims *
sizeof(
int));
5743 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5744 errmsg(
"wrong number of array subscripts"),
5745 errdetail(
"Dimension array must be one dimensional.")));
5749 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5750 errmsg(
"wrong range of array subscripts"),
5751 errdetail(
"Lower bound of dimension array must be one.")));
5755 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5756 errmsg(
"dimension values cannot be null")));
5763 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5764 errmsg(
"invalid number of dimensions: %d", ndims)));
5767 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5768 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
5775 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5776 errmsg(
"wrong number of array subscripts"),
5777 errdetail(
"Dimension array must be one dimensional.")));
5781 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5782 errmsg(
"wrong range of array subscripts"),
5783 errdetail(
"Lower bound of dimension array must be one.")));
5787 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5788 errmsg(
"dimension values cannot be null")));
5792 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5793 errmsg(
"wrong number of array subscripts"),
5794 errdetail(
"Low bound array has different size than dimensions array.")));
5802 for (i = 0; i <
MAXDIM; i++)
5819 if (my_extra ==
NULL)
5837 elmlen = my_extra->
typlen;
5857 totbytes = nbytes * nitems;
5860 if (totbytes / nbytes != nitems ||
5863 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5864 errmsg(
"array size exceeds the maximum allowed (%d)",
5877 for (i = 0; i < nitems; i++)
5886 nbytes = dataoffset;
5889 elmtype, dataoffset);
5912 } array_unnest_fctx;
5915 array_unnest_fctx *fctx;
5941 fctx = (array_unnest_fctx *)
palloc(
sizeof(array_unnest_fctx));
5969 if (fctx->nextelem < fctx->numelems)
5971 int offset = fctx->nextelem++;
5975 fctx->elmlen, fctx->elmbyval, fctx->elmalign);
5997 Datum search,
bool search_isnull,
5998 Datum replace,
bool replace_isnull,
5999 bool remove,
Oid collation,
6020 bool changed =
false;
6037 if (
remove && ndim > 1)
6039 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6040 errmsg(
"removing elements from multidimensional arrays is not supported")));
6047 if (typentry ==
NULL ||
6048 typentry->
type_id != element_type)
6054 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
6055 errmsg(
"could not identify an equality operator for type %s",
6059 typlen = typentry->
typlen;
6072 if (!replace_isnull)
6082 nulls = (
bool *)
palloc(nitems *
sizeof(
bool));
6091 for (i = 0; i < nitems; i++)
6099 if (bitmap && (*bitmap & bitmask) == 0)
6110 else if (!replace_isnull)
6112 values[nresult] = replace;
6121 elt =
fetch_att(arraydataptr, typbyval, typlen);
6128 values[nresult] = elt;
6135 locfcinfo.
arg[0] = elt;
6136 locfcinfo.
arg[1] = search;
6139 locfcinfo.
isnull =
false;
6144 values[nresult] = elt;
6154 values[nresult] = replace;
6155 isNull = replace_isnull;
6163 nulls[nresult] = isNull;
6174 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
6175 errmsg(
"array size exceeds the maximum allowed (%d)",
6185 if (bitmask == 0x100)
6215 nbytes += dataoffset;
6224 result->
ndim = ndim;
6238 values, nulls, nresult,
6239 typlen, typbyval, typalign,
6265 search, search_isnull,
6289 search, search_isnull,
6290 replace, replace_isnull,
6316 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
6317 errmsg(
"thresholds must be one-dimensional array")));
6321 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6322 errmsg(
"thresholds array must not contain NULLs")));
6333 if (typentry ==
NULL ||
6334 typentry->
type_id != element_type)
6340 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
6341 errmsg(
"could not identify a comparison function for type %s",
6343 fcinfo->flinfo->fn_extra = (
void *) typentry;
6350 if (typentry->
typlen > 0)
6352 collation, typentry);
6355 collation, typentry);
6395 while (left < right)
6397 int mid = (left + right) / 2;
6399 if (isnan(thresholds_data[mid]) || op < thresholds_data[mid])
6417 char *thresholds_data;
6418 int typlen = typentry->
typlen;
6419 bool typbyval = typentry->
typbyval;
6436 while (left < right)
6438 int mid = (left + right) / 2;
6442 ptr = thresholds_data + mid * typlen;
6444 locfcinfo.
arg[0] = operand;
6448 locfcinfo.
isnull =
false;
6470 char *thresholds_data;
6471 int typlen = typentry->
typlen;
6472 bool typbyval = typentry->
typbyval;
6473 char typalign = typentry->
typalign;
6486 while (left < right)
6488 int mid = (left + right) / 2;
6494 ptr = thresholds_data;
6495 for (i = left; i < mid; i++)
6501 locfcinfo.
arg[0] = operand;
6505 locfcinfo.
isnull =
false;
Datum btarraycmp(PG_FUNCTION_ARGS)
Datum generate_subscripts(PG_FUNCTION_ARGS)
#define DatumGetUInt32(X)
ArrayIterator array_create_iterator(ArrayType *arr, int slice_ndim, ArrayMetaState *mstate)
Datum makeArrayResultArr(ArrayBuildStateArr *astate, MemoryContext rcontext, bool release)
Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)
Datum array_ne(PG_FUNCTION_ARGS)
Datum array_get_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
#define PG_GETARG_INT32(n)
static void skip(struct vars *v)
void MemoryContextDelete(MemoryContext context)
Datum array_send(PG_FUNCTION_ARGS)
static bool array_isspace(char ch)
#define PG_DETOAST_DATUM_COPY(datum)
Datum array_fill_with_lower_bounds(PG_FUNCTION_ARGS)
Datum array_ge(PG_FUNCTION_ARGS)
#define ARR_OVERHEAD_NONULLS(ndims)
ArrayBuildStateAny * initArrayResultAny(Oid input_type, MemoryContext rcontext, bool subcontext)
#define att_align_nominal(cur_offset, attalign)
void deconstruct_expanded_array(ExpandedArrayHeader *eah)
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Datum array_map(FunctionCallInfo fcinfo, Oid retType, ArrayMapState *amstate)
static ArrayType * array_fill_internal(ArrayType *dims, ArrayType *lbs, Datum value, bool isnull, Oid elmtype, FunctionCallInfo fcinfo)
Datum array_unnest(PG_FUNCTION_ARGS)
static ArrayType * create_array_envelope(int ndims, int *dimv, int *lbv, int nbytes, Oid elmtype, int dataoffset)
Datum array_replace(PG_FUNCTION_ARGS)
int ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx)
static int ArrayCastAndSet(Datum src, int typlen, bool typbyval, char typalign, char *dest)
static Datum array_iter_next(array_iter *it, bool *isnull, int i, int elmlen, bool elmbyval, char elmalign)
Oid get_element_type(Oid typid)
#define SRF_IS_FIRSTCALL()
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
#define PointerGetDatum(X)
#define PG_GETARG_DATUM(n)
void mda_get_prod(int n, const int *range, int *prod)
Oid get_array_type(Oid typid)
char * pstrdup(const char *in)
#define TYPECACHE_EQ_OPR_FINFO
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
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)
StringInfoData * StringInfo
#define TYPECACHE_HASH_PROC_FINFO
int ArrayGetNItems(int ndim, const int *dims)
Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define PG_RETURN_INT32(x)
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
int errcode(int sqlerrcode)
#define MemSet(start, val, len)
Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
ArrayType * array_set(ArrayType *array, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
#define PG_GETARG_POINTER(n)
Datum array_recv(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)
static int array_cmp(FunctionCallInfo fcinfo)
#define PG_GETARG_BOOL(n)
int pg_strcasecmp(const char *s1, const char *s2)
#define PG_RETURN_BYTEA_P(x)
Datum array_cardinality(PG_FUNCTION_ARGS)
ArrayType * construct_empty_array(Oid elmtype)
ArrayBuildState * scalarstate
#define OidIsValid(objectId)
#define SRF_PERCALL_SETUP()
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
Datum array_out(PG_FUNCTION_ARGS)
#define PG_GET_COLLATION()
#define ALLOCSET_DEFAULT_MINSIZE
static int array_copy(char *destptr, int nitems, char *srcptr, int offset, bits8 *nullbitmap, int typlen, bool typbyval, char typalign)
#define PG_RETURN_UINT32(x)
static void ReadArrayStr(char *arrayStr, const char *origStr, int nitems, int ndim, int *dim, FmgrInfo *inputproc, Oid typioparam, int32 typmod, char typdelim, int typlen, bool typbyval, char typalign, Datum *values, bool *nulls, bool *hasnulls, int32 *nbytes)
Datum array_gt(PG_FUNCTION_ARGS)
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
ArrayBuildStateArr * initArrayResultArr(Oid array_type, Oid element_type, MemoryContext rcontext, bool subcontext)
#define ARR_DATA_OFFSET(a)
Datum arrayoverlap(PG_FUNCTION_ARGS)
#define SRF_RETURN_NEXT(_funcctx, _result)
struct ArrayIteratorData ArrayIteratorData
#define PG_GETARG_ARRAYTYPE_P(n)
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 pfree(void *pointer)
bool array_iterate(ArrayIterator iterator, Datum *value, bool *isnull)
#define PG_GETARG_ANY_ARRAY(n)
ExpandedArrayHeader * DatumGetExpandedArray(Datum d)
static int width_bucket_array_variable(Datum operand, ArrayType *thresholds, Oid collation, TypeCacheEntry *typentry)
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf, Oid typioparam, int32 typmod)
ArrayBuildStateArr * accumArrayResultArr(ArrayBuildStateArr *astate, Datum dvalue, bool disnull, Oid array_type, MemoryContext rcontext)
static bool array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation, bool matchall, void **fn_extra)
#define FunctionCallInvoke(fcinfo)
static Datum array_get_element_expanded(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
static int width_bucket_array_fixed(Datum operand, ArrayType *thresholds, Oid collation, TypeCacheEntry *typentry)
static void array_iter_setup(array_iter *it, AnyArrayType *a)
static Datum array_set_element_expanded(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
int errdetail(const char *fmt,...)
struct generate_subscripts_fctx generate_subscripts_fctx
Datum array_upper(PG_FUNCTION_ARGS)
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
bool argnull[FUNC_MAX_ARGS]
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
#define PG_RETURN_ARRAYTYPE_P(x)
#define att_addlength_pointer(cur_offset, attlen, attptr)
#define ereport(elevel, rest)
void mda_get_offset_values(int n, int *dist, const int *prod, const int *span)
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Datum datumCopy(Datum value, bool typByVal, int typLen)
Datum array_ref(ArrayType *array, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
#define AllocSizeIsValid(size)
ArrayBuildStateAny * accumArrayResultAny(ArrayBuildStateAny *astate, Datum dvalue, bool disnull, Oid input_type, MemoryContext rcontext)
ExpandedObjectHeader * DatumGetEOHP(Datum d)
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)
ExpandedArrayHeader * construct_empty_expanded_array(Oid element_type, MemoryContext parentcontext, ArrayMetaState *metacache)
ArrayBuildStateArr * arraystate
#define store_att_byval(T, newdatum, attlen)
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
void * palloc0(Size size)
#define DatumGetFloat8(X)
#define PG_RETURN_BOOL(x)
#define PG_RETURN_DATUM(x)
Datum generate_subscripts_nodir(PG_FUNCTION_ARGS)
Datum arraycontains(PG_FUNCTION_ARGS)
void mda_get_range(int n, int *span, const int *st, const int *endp)
Datum arraycontained(PG_FUNCTION_ARGS)
static void array_set_isnull(bits8 *nullbitmap, int offset, bool isNull)
void * MemoryContextAllocZero(MemoryContext context, Size size)
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
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_ndims(PG_FUNCTION_ARGS)
Datum array_eq(PG_FUNCTION_ARGS)
Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
#define PG_RETURN_TEXT_P(x)
void array_free_iterator(ArrayIterator iterator)
text * cstring_to_text(const char *s)
Datum array_le(PG_FUNCTION_ARGS)
Datum array_lt(PG_FUNCTION_ARGS)
#define Assert(condition)
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)
static char * array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)
#define PG_RETURN_CSTRING(x)
MemoryContext multi_call_memory_ctx
static Datum ArrayCast(char *value, bool byval, int len)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
#define AARR_FREE_IF_COPY(array, n)
#define PG_FREE_IF_COPY(ptr, n)
Datum width_bucket_array(PG_FUNCTION_ARGS)
Datum array_larger(PG_FUNCTION_ARGS)
static bool array_get_isnull(const bits8 *nullbitmap, int offset)
void * repalloc(void *pointer, Size size)
static int ArrayCount(const char *str, int *dim, char typdelim)
void CopyArrayEls(ArrayType *array, Datum *values, bool *nulls, int nitems, int typlen, bool typbyval, char typalign, bool freedata)
#define VARATT_IS_EXPANDED_HEADER(PTR)
Datum array_dims(PG_FUNCTION_ARGS)
#define DatumGetPointer(X)
Datum array_length(PG_FUNCTION_ARGS)
#define EOHPGetRWDatum(eohptr)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
static Datum values[MAXATTR]
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Datum makeArrayResultAny(ArrayBuildStateAny *astate, MemoryContext rcontext, bool release)
int mda_next_tuple(int n, int *curr, const int *span)
Datum array_smaller(PG_FUNCTION_ARGS)
#define att_addlength_datum(cur_offset, attlen, attdatum)
int errmsg(const char *fmt,...)
#define fetch_att(T, attbyval, attlen)
void * MemoryContextAlloc(MemoryContext context, Size size)
#define ALLOCSET_DEFAULT_INITSIZE
#define PG_GETARG_CSTRING(n)
#define PG_DETOAST_DATUM(datum)
static int width_bucket_array_float8(Datum operand, ArrayType *thresholds)
#define ALLOCSET_DEFAULT_MAXSIZE
Datum array_fill(PG_FUNCTION_ARGS)
#define TYPECACHE_CMP_PROC_FINFO
Datum array_remove(PG_FUNCTION_ARGS)
#define SET_VARSIZE(PTR, len)
Datum hash_array(PG_FUNCTION_ARGS)
static int array_nelems_size(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)
Datum array_lower(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)
bool array_contains_nulls(ArrayType *array)
#define PointerIsValid(pointer)
MemoryContext eoh_context
#define ARR_NULLBITMAP(a)
Datum array_in(PG_FUNCTION_ARGS)
int ArrayGetOffset0(int n, const int *tup, const int *scale)
#define SRF_RETURN_DONE(_funcctx)
#define DatumGetArrayTypeP(X)
#define SRF_FIRSTCALL_INIT()
void get_type_io_data(Oid typid, IOFuncSelector which_func, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *func)