PostgreSQL Source Code git master
Loading...
Searching...
No Matches
array.h File Reference
#include "fmgr.h"
#include "utils/expandeddatum.h"
Include dependency graph for array.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ArrayType
 
struct  ExpandedArrayHeader
 
union  AnyArrayType
 
struct  ArrayBuildState
 
struct  ArrayBuildStateArr
 
struct  ArrayBuildStateAny
 
struct  ArrayMetaState
 
struct  ArrayMapState
 

Macros

#define MAXDIM   6
 
#define MaxArraySize   ((Size) (MaxAllocSize / sizeof(Datum)))
 
#define EA_MAGIC   689375833 /* ID for debugging crosschecks */
 
#define DatumGetArrayTypeP(X)   ((ArrayType *) PG_DETOAST_DATUM(X))
 
#define DatumGetArrayTypePCopy(X)   ((ArrayType *) PG_DETOAST_DATUM_COPY(X))
 
#define PG_GETARG_ARRAYTYPE_P(n)   DatumGetArrayTypeP(PG_GETARG_DATUM(n))
 
#define PG_GETARG_ARRAYTYPE_P_COPY(n)   DatumGetArrayTypePCopy(PG_GETARG_DATUM(n))
 
#define PG_RETURN_ARRAYTYPE_P(x)   PG_RETURN_POINTER(x)
 
#define PG_GETARG_EXPANDED_ARRAY(n)   DatumGetExpandedArray(PG_GETARG_DATUM(n))
 
#define PG_GETARG_EXPANDED_ARRAYX(n, metacache)    DatumGetExpandedArrayX(PG_GETARG_DATUM(n), metacache)
 
#define PG_RETURN_EXPANDED_ARRAY(x)   PG_RETURN_DATUM(EOHPGetRWDatum(&(x)->hdr))
 
#define PG_GETARG_ANY_ARRAY_P(n)   DatumGetAnyArrayP(PG_GETARG_DATUM(n))
 
#define ARR_SIZE(a)   VARSIZE(a)
 
#define ARR_NDIM(a)   ((a)->ndim)
 
#define ARR_HASNULL(a)   ((a)->dataoffset != 0)
 
#define ARR_ELEMTYPE(a)   ((a)->elemtype)
 
#define ARR_DIMS(a)    ((int *) (((char *) (a)) + sizeof(ArrayType)))
 
#define ARR_LBOUND(a)
 
#define ARR_NULLBITMAP(a)
 
#define ARR_OVERHEAD_NONULLS(ndims)    MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims))
 
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
 
#define ARR_DATA_OFFSET(a)    (ARR_HASNULL(a) ? (a)->dataoffset : ARR_OVERHEAD_NONULLS(ARR_NDIM(a)))
 
#define ARR_DATA_PTR(a)    (((char *) (a)) + ARR_DATA_OFFSET(a))
 
#define AARR_NDIM(a)
 
#define AARR_HASNULL(a)
 
#define AARR_ELEMTYPE(a)
 
#define AARR_DIMS(a)
 
#define AARR_LBOUND(a)
 

Typedefs

typedef struct ExprState ExprState
 
typedef struct ExprContext ExprContext
 
typedef struct ArrayType ArrayType
 
typedef struct ExpandedArrayHeader ExpandedArrayHeader
 
typedef union AnyArrayType AnyArrayType
 
typedef struct ArrayBuildState ArrayBuildState
 
typedef struct ArrayBuildStateArr ArrayBuildStateArr
 
typedef struct ArrayBuildStateAny ArrayBuildStateAny
 
typedef struct ArrayMetaState ArrayMetaState
 
typedef struct ArrayMapState ArrayMapState
 
typedef struct ArrayIteratorDataArrayIterator
 

Functions

void CopyArrayEls (ArrayType *array, const Datum *values, const bool *nulls, int nitems, int typlen, bool typbyval, char typalign, bool freedata)
 
Datum array_get_element (Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
 
Datum array_set_element (Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
 
Datum array_get_slice (Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
 
Datum array_set_slice (Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, Datum srcArrayDatum, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
 
Datum array_ref (ArrayType *array, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
 
ArrayTypearray_set (ArrayType *array, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
 
Datum array_map (Datum arrayd, ExprState *exprstate, ExprContext *econtext, Oid retType, ArrayMapState *amstate)
 
void array_bitmap_copy (bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
 
ArrayTypeconstruct_array (Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
 
ArrayTypeconstruct_array_builtin (Datum *elems, int nelems, Oid elmtype)
 
ArrayTypeconstruct_md_array (Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
 
ArrayTypeconstruct_empty_array (Oid elmtype)
 
ExpandedArrayHeaderconstruct_empty_expanded_array (Oid element_type, MemoryContext parentcontext, ArrayMetaState *metacache)
 
void deconstruct_array (const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
 
void deconstruct_array_builtin (const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
 
bool array_contains_nulls (const ArrayType *array)
 
ArrayBuildStateinitArrayResult (Oid element_type, MemoryContext rcontext, bool subcontext)
 
ArrayBuildStateinitArrayResultWithSize (Oid element_type, MemoryContext rcontext, bool subcontext, int initsize)
 
ArrayBuildStateaccumArrayResult (ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
 
Datum makeArrayResult (ArrayBuildState *astate, MemoryContext rcontext)
 
Datum makeMdArrayResult (ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)
 
ArrayBuildStateArrinitArrayResultArr (Oid array_type, Oid element_type, MemoryContext rcontext, bool subcontext)
 
ArrayBuildStateArraccumArrayResultArr (ArrayBuildStateArr *astate, Datum dvalue, bool disnull, Oid array_type, MemoryContext rcontext)
 
Datum makeArrayResultArr (ArrayBuildStateArr *astate, MemoryContext rcontext, bool release)
 
ArrayBuildStateAnyinitArrayResultAny (Oid input_type, MemoryContext rcontext, bool subcontext)
 
ArrayBuildStateAnyaccumArrayResultAny (ArrayBuildStateAny *astate, Datum dvalue, bool disnull, Oid input_type, MemoryContext rcontext)
 
Datum makeArrayResultAny (ArrayBuildStateAny *astate, MemoryContext rcontext, bool release)
 
ArrayIterator array_create_iterator (ArrayType *arr, int slice_ndim, ArrayMetaState *mstate)
 
bool array_iterate (ArrayIterator iterator, Datum *value, bool *isnull)
 
void array_free_iterator (ArrayIterator iterator)
 
int ArrayGetOffset (int n, const int *dim, const int *lb, const int *indx)
 
int ArrayGetNItems (int ndim, const int *dims)
 
int ArrayGetNItemsSafe (int ndim, const int *dims, struct Node *escontext)
 
void ArrayCheckBounds (int ndim, const int *dims, const int *lb)
 
bool ArrayCheckBoundsSafe (int ndim, const int *dims, const int *lb, struct Node *escontext)
 
void mda_get_range (int n, int *span, const int *st, const int *endp)
 
void mda_get_prod (int n, const int *range, int *prod)
 
void mda_get_offset_values (int n, int *dist, const int *prod, const int *span)
 
int mda_next_tuple (int n, int *curr, const int *span)
 
int32ArrayGetIntegerTypmods (ArrayType *arr, int *n)
 
Datum expand_array (Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
 
ExpandedArrayHeaderDatumGetExpandedArray (Datum d)
 
ExpandedArrayHeaderDatumGetExpandedArrayX (Datum d, ArrayMetaState *metacache)
 
AnyArrayTypeDatumGetAnyArrayP (Datum d)
 
void deconstruct_expanded_array (ExpandedArrayHeader *eah)
 

Variables

PGDLLIMPORT bool Array_nulls
 

Macro Definition Documentation

◆ AARR_DIMS

#define AARR_DIMS (   a)
Value:
(a)->xpn.dims : ARR_DIMS((ArrayType *) (a)))
#define ARR_DIMS(a)
Definition array.h:294
#define VARATT_IS_EXPANDED_HEADER(PTR)
int a
Definition isn.c:73

Definition at line 338 of file array.h.

340 : ARR_DIMS((ArrayType *) (a)))

◆ AARR_ELEMTYPE

#define AARR_ELEMTYPE (   a)
Value:
(a)->xpn.element_type : ARR_ELEMTYPE((ArrayType *) (a)))
#define ARR_ELEMTYPE(a)
Definition array.h:292

Definition at line 335 of file array.h.

337 : ARR_ELEMTYPE((ArrayType *) (a)))

◆ AARR_HASNULL

#define AARR_HASNULL (   a)
Value:
((a)->xpn.dvalues != NULL ? (a)->xpn.dnulls != NULL : ARR_HASNULL((a)->xpn.fvalue)) : \
#define ARR_HASNULL(a)
Definition array.h:291
static int fb(int x)

Definition at line 331 of file array.h.

333 : ARR_HASNULL((a)->xpn.fvalue)) : \
334 ARR_HASNULL((ArrayType *) (a)))

◆ AARR_LBOUND

#define AARR_LBOUND (   a)
Value:
(a)->xpn.lbound : ARR_LBOUND((ArrayType *) (a)))
#define ARR_LBOUND(a)
Definition array.h:296

Definition at line 341 of file array.h.

343 : ARR_LBOUND((ArrayType *) (a)))

◆ AARR_NDIM

#define AARR_NDIM (   a)
Value:
(a)->xpn.ndims : ARR_NDIM((ArrayType *) (a)))
#define ARR_NDIM(a)
Definition array.h:290

Definition at line 328 of file array.h.

330 : ARR_NDIM((ArrayType *) (a)))

◆ ARR_DATA_OFFSET

#define ARR_DATA_OFFSET (   a)     (ARR_HASNULL(a) ? (a)->dataoffset : ARR_OVERHEAD_NONULLS(ARR_NDIM(a)))

Definition at line 316 of file array.h.

#define ARR_OVERHEAD_NONULLS(ndims)
Definition array.h:310

◆ ARR_DATA_PTR

#define ARR_DATA_PTR (   a)     (((char *) (a)) + ARR_DATA_OFFSET(a))

Definition at line 322 of file array.h.

◆ ARR_DIMS

#define ARR_DIMS (   a)     ((int *) (((char *) (a)) + sizeof(ArrayType)))

Definition at line 294 of file array.h.

◆ ARR_ELEMTYPE

#define ARR_ELEMTYPE (   a)    ((a)->elemtype)

Definition at line 292 of file array.h.

◆ ARR_HASNULL

#define ARR_HASNULL (   a)    ((a)->dataoffset != 0)

Definition at line 291 of file array.h.

◆ ARR_LBOUND

#define ARR_LBOUND (   a)
Value:
((int *) (((char *) (a)) + sizeof(ArrayType) + \
sizeof(int) * ARR_NDIM(a)))

Definition at line 296 of file array.h.

◆ ARR_NDIM

#define ARR_NDIM (   a)    ((a)->ndim)

Definition at line 290 of file array.h.

◆ ARR_NULLBITMAP

#define ARR_NULLBITMAP (   a)
Value:
(ARR_HASNULL(a) ? \
(bits8 *) (((char *) (a)) + sizeof(ArrayType) + \
2 * sizeof(int) * ARR_NDIM(a)) \
: (bits8 *) NULL)
uint8 bits8
Definition c.h:553

Definition at line 300 of file array.h.

304 : (bits8 *) NULL)

◆ ARR_OVERHEAD_NONULLS

#define ARR_OVERHEAD_NONULLS (   ndims)     MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims))

Definition at line 310 of file array.h.

◆ ARR_OVERHEAD_WITHNULLS

#define ARR_OVERHEAD_WITHNULLS (   ndims,
  nitems 
)
Value:
MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims) + \
((nitems) + 7) / 8)
#define MAXALIGN(LEN)
Definition c.h:826
#define nitems(x)
Definition indent.h:31

Definition at line 312 of file array.h.

◆ ARR_SIZE

#define ARR_SIZE (   a)    VARSIZE(a)

Definition at line 289 of file array.h.

◆ DatumGetArrayTypeP

#define DatumGetArrayTypeP (   X)    ((ArrayType *) PG_DETOAST_DATUM(X))

Definition at line 261 of file array.h.

◆ DatumGetArrayTypePCopy

#define DatumGetArrayTypePCopy (   X)    ((ArrayType *) PG_DETOAST_DATUM_COPY(X))

Definition at line 262 of file array.h.

◆ EA_MAGIC

#define EA_MAGIC   689375833 /* ID for debugging crosschecks */

Definition at line 113 of file array.h.

◆ MaxArraySize

#define MaxArraySize   ((Size) (MaxAllocSize / sizeof(Datum)))

Definition at line 82 of file array.h.

◆ MAXDIM

#define MAXDIM   6

Definition at line 75 of file array.h.

◆ PG_GETARG_ANY_ARRAY_P

#define PG_GETARG_ANY_ARRAY_P (   n)    DatumGetAnyArrayP(PG_GETARG_DATUM(n))

Definition at line 274 of file array.h.

◆ PG_GETARG_ARRAYTYPE_P

#define PG_GETARG_ARRAYTYPE_P (   n)    DatumGetArrayTypeP(PG_GETARG_DATUM(n))

Definition at line 263 of file array.h.

◆ PG_GETARG_ARRAYTYPE_P_COPY

#define PG_GETARG_ARRAYTYPE_P_COPY (   n)    DatumGetArrayTypePCopy(PG_GETARG_DATUM(n))

Definition at line 264 of file array.h.

◆ PG_GETARG_EXPANDED_ARRAY

#define PG_GETARG_EXPANDED_ARRAY (   n)    DatumGetExpandedArray(PG_GETARG_DATUM(n))

Definition at line 268 of file array.h.

◆ PG_GETARG_EXPANDED_ARRAYX

#define PG_GETARG_EXPANDED_ARRAYX (   n,
  metacache 
)     DatumGetExpandedArrayX(PG_GETARG_DATUM(n), metacache)

Definition at line 269 of file array.h.

◆ PG_RETURN_ARRAYTYPE_P

#define PG_RETURN_ARRAYTYPE_P (   x)    PG_RETURN_POINTER(x)

Definition at line 265 of file array.h.

◆ PG_RETURN_EXPANDED_ARRAY

#define PG_RETURN_EXPANDED_ARRAY (   x)    PG_RETURN_DATUM(EOHPGetRWDatum(&(x)->hdr))

Definition at line 271 of file array.h.

Typedef Documentation

◆ AnyArrayType

◆ ArrayBuildState

◆ ArrayBuildStateAny

◆ ArrayBuildStateArr

◆ ArrayIterator

Definition at line 258 of file array.h.

◆ ArrayMapState

◆ ArrayMetaState

◆ ArrayType

◆ ExpandedArrayHeader

◆ ExprContext

Definition at line 69 of file array.h.

◆ ExprState

Definition at line 68 of file array.h.

Function Documentation

◆ accumArrayResult()

ArrayBuildState * accumArrayResult ( ArrayBuildState astate,
Datum  dvalue,
bool  disnull,
Oid  element_type,
MemoryContext  rcontext 
)
extern

Definition at line 5359 of file arrayfuncs.c.

5363{
5364 MemoryContext oldcontext;
5365
5366 if (astate == NULL)
5367 {
5368 /* First time through --- initialize */
5369 astate = initArrayResult(element_type, rcontext, true);
5370 }
5371 else
5372 {
5373 Assert(astate->element_type == element_type);
5374 }
5375
5376 oldcontext = MemoryContextSwitchTo(astate->mcontext);
5377
5378 /* enlarge dvalues[]/dnulls[] if needed */
5379 if (astate->nelems >= astate->alen)
5380 {
5381 astate->alen *= 2;
5382 /* give an array-related error if we go past MaxAllocSize */
5383 if (!AllocSizeIsValid(astate->alen * sizeof(Datum)))
5384 ereport(ERROR,
5386 errmsg("array size exceeds the maximum allowed (%zu)",
5387 MaxAllocSize)));
5388 astate->dvalues = (Datum *)
5389 repalloc(astate->dvalues, astate->alen * sizeof(Datum));
5390 astate->dnulls = (bool *)
5391 repalloc(astate->dnulls, astate->alen * sizeof(bool));
5392 }
5393
5394 /*
5395 * Ensure pass-by-ref stuff is copied into mcontext; and detoast it too if
5396 * it's varlena. (You might think that detoasting is not needed here
5397 * because construct_md_array can detoast the array elements later.
5398 * However, we must not let construct_md_array modify the ArrayBuildState
5399 * because that would mean array_agg_finalfn damages its input, which is
5400 * verboten. Also, this way frequently saves one copying step.)
5401 */
5402 if (!disnull && !astate->typbyval)
5403 {
5404 if (astate->typlen == -1)
5406 else
5407 dvalue = datumCopy(dvalue, astate->typbyval, astate->typlen);
5408 }
5409
5410 astate->dvalues[astate->nelems] = dvalue;
5411 astate->dnulls[astate->nelems] = disnull;
5412 astate->nelems++;
5413
5414 MemoryContextSwitchTo(oldcontext);
5415
5416 return astate;
5417}
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
#define Assert(condition)
Definition c.h:873
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition datum.c:132
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
#define MaxAllocSize
Definition fe_memutils.h:22
#define PG_DETOAST_DATUM_COPY(datum)
Definition fmgr.h:242
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1632
#define AllocSizeIsValid(size)
Definition memutils.h:42
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
uint64_t Datum
Definition postgres.h:70
bool * dnulls
Definition array.h:191
bool typbyval
Definition array.h:196
MemoryContext mcontext
Definition array.h:189
int16 typlen
Definition array.h:195
Oid element_type
Definition array.h:194
Datum * dvalues
Definition array.h:190

References ArrayBuildState::alen, AllocSizeIsValid, Assert, datumCopy(), ArrayBuildState::dnulls, ArrayBuildState::dvalues, ArrayBuildState::element_type, ereport, errcode(), errmsg(), ERROR, fb(), initArrayResult(), MaxAllocSize, ArrayBuildState::mcontext, MemoryContextSwitchTo(), ArrayBuildState::nelems, PG_DETOAST_DATUM_COPY, PointerGetDatum(), repalloc(), ArrayBuildState::typbyval, and ArrayBuildState::typlen.

Referenced by accumArrayResultAny(), array_agg_transfn(), array_positions(), array_to_datum_internal(), brin_minmax_multi_summary_out(), daitch_mokotoff_coding(), dblink_get_connections(), find_or_create_child_node(), multirange_agg_transfn(), optionListToArray(), parse_ident(), pg_get_statisticsobjdef_expressions(), pg_stats_ext_mcvlist_items(), PLySequence_ToArray_recurse(), populate_array_element(), range_agg_transfn(), regexp_split_to_array(), serialize_expr_stats(), split_text_accum_result(), transformRelOptions(), and tuple_data_split_internal().

◆ accumArrayResultAny()

ArrayBuildStateAny * accumArrayResultAny ( ArrayBuildStateAny astate,
Datum  dvalue,
bool  disnull,
Oid  input_type,
MemoryContext  rcontext 
)
extern

Definition at line 5838 of file arrayfuncs.c.

5842{
5843 if (astate == NULL)
5844 astate = initArrayResultAny(input_type, rcontext, true);
5845
5846 if (astate->scalarstate)
5848 dvalue, disnull,
5850 else
5851 (void) accumArrayResultArr(astate->arraystate,
5852 dvalue, disnull,
5854
5855 return astate;
5856}
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
ArrayBuildStateAny * initArrayResultAny(Oid input_type, MemoryContext rcontext, bool subcontext)
ArrayBuildStateArr * accumArrayResultArr(ArrayBuildStateArr *astate, Datum dvalue, bool disnull, Oid array_type, MemoryContext rcontext)
ArrayBuildStateArr * arraystate
Definition array.h:230
ArrayBuildState * scalarstate
Definition array.h:229

References accumArrayResult(), accumArrayResultArr(), ArrayBuildStateAny::arraystate, fb(), initArrayResultAny(), and ArrayBuildStateAny::scalarstate.

Referenced by array_sort_internal(), ExecScanSubPlan(), and ExecSetParamPlan().

◆ accumArrayResultArr()

ArrayBuildStateArr * accumArrayResultArr ( ArrayBuildStateArr astate,
Datum  dvalue,
bool  disnull,
Oid  array_type,
MemoryContext  rcontext 
)
extern

Definition at line 5559 of file arrayfuncs.c.

5563{
5564 ArrayType *arg;
5565 MemoryContext oldcontext;
5566 int *dims,
5567 *lbs,
5568 ndims,
5569 nitems,
5570 ndatabytes;
5571 char *data;
5572 int i;
5573
5574 /*
5575 * We disallow accumulating null subarrays. Another plausible definition
5576 * is to ignore them, but callers that want that can just skip calling
5577 * this function.
5578 */
5579 if (disnull)
5580 ereport(ERROR,
5582 errmsg("cannot accumulate null arrays")));
5583
5584 /* Detoast input array in caller's context */
5586
5587 if (astate == NULL)
5588 astate = initArrayResultArr(array_type, InvalidOid, rcontext, true);
5589 else
5590 Assert(astate->array_type == array_type);
5591
5592 oldcontext = MemoryContextSwitchTo(astate->mcontext);
5593
5594 /* Collect this input's dimensions */
5595 ndims = ARR_NDIM(arg);
5596 dims = ARR_DIMS(arg);
5597 lbs = ARR_LBOUND(arg);
5599 nitems = ArrayGetNItems(ndims, dims);
5601
5602 if (astate->ndims == 0)
5603 {
5604 /* First input; check/save the dimensionality info */
5605
5606 /* Should we allow empty inputs and just produce an empty output? */
5607 if (ndims == 0)
5608 ereport(ERROR,
5610 errmsg("cannot accumulate empty arrays")));
5611 if (ndims + 1 > MAXDIM)
5612 ereport(ERROR,
5614 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
5615 ndims + 1, MAXDIM)));
5616
5617 /*
5618 * The output array will have n+1 dimensions, with the ones after the
5619 * first matching the input's dimensions.
5620 */
5621 astate->ndims = ndims + 1;
5622 astate->dims[0] = 0;
5623 memcpy(&astate->dims[1], dims, ndims * sizeof(int));
5624 astate->lbs[0] = 1;
5625 memcpy(&astate->lbs[1], lbs, ndims * sizeof(int));
5626
5627 /* Allocate at least enough data space for this item */
5628 astate->abytes = pg_nextpower2_32(Max(1024, ndatabytes + 1));
5629 astate->data = (char *) palloc(astate->abytes);
5630 }
5631 else
5632 {
5633 /* Second or later input: must match first input's dimensionality */
5634 if (astate->ndims != ndims + 1)
5635 ereport(ERROR,
5637 errmsg("cannot accumulate arrays of different dimensionality")));
5638 for (i = 0; i < ndims; i++)
5639 {
5640 if (astate->dims[i + 1] != dims[i] || astate->lbs[i + 1] != lbs[i])
5641 ereport(ERROR,
5643 errmsg("cannot accumulate arrays of different dimensionality")));
5644 }
5645
5646 /* Enlarge data space if needed */
5647 if (astate->nbytes + ndatabytes > astate->abytes)
5648 {
5649 astate->abytes = Max(astate->abytes * 2,
5650 astate->nbytes + ndatabytes);
5651 astate->data = (char *) repalloc(astate->data, astate->abytes);
5652 }
5653 }
5654
5655 /*
5656 * Copy the data portion of the sub-array. Note we assume that the
5657 * advertised data length of the sub-array is properly aligned. We do not
5658 * have to worry about detoasting elements since whatever's in the
5659 * sub-array should be OK already.
5660 */
5661 memcpy(astate->data + astate->nbytes, data, ndatabytes);
5662 astate->nbytes += ndatabytes;
5663
5664 /* Deal with null bitmap if needed */
5665 if (astate->nullbitmap || ARR_HASNULL(arg))
5666 {
5667 int newnitems = astate->nitems + nitems;
5668
5669 if (astate->nullbitmap == NULL)
5670 {
5671 /*
5672 * First input with nulls; we must retrospectively handle any
5673 * previous inputs by marking all their items non-null.
5674 */
5675 astate->aitems = pg_nextpower2_32(Max(256, newnitems + 1));
5676 astate->nullbitmap = (bits8 *) palloc((astate->aitems + 7) / 8);
5677 array_bitmap_copy(astate->nullbitmap, 0,
5678 NULL, 0,
5679 astate->nitems);
5680 }
5681 else if (newnitems > astate->aitems)
5682 {
5683 astate->aitems = Max(astate->aitems * 2, newnitems);
5684 astate->nullbitmap = (bits8 *)
5685 repalloc(astate->nullbitmap, (astate->aitems + 7) / 8);
5686 }
5687 array_bitmap_copy(astate->nullbitmap, astate->nitems,
5688 ARR_NULLBITMAP(arg), 0,
5689 nitems);
5690 }
5691
5692 astate->nitems += nitems;
5693 astate->dims[0] += 1;
5694
5695 MemoryContextSwitchTo(oldcontext);
5696
5697 /* Release detoasted copy if any */
5698 if (arg != DatumGetPointer(dvalue))
5699 pfree(arg);
5700
5701 return astate;
5702}
#define ARR_DATA_PTR(a)
Definition array.h:322
#define MAXDIM
Definition array.h:75
#define ARR_NULLBITMAP(a)
Definition array.h:300
#define DatumGetArrayTypeP(X)
Definition array.h:261
#define ARR_SIZE(a)
Definition array.h:289
#define ARR_DATA_OFFSET(a)
Definition array.h:316
ArrayBuildStateArr * initArrayResultArr(Oid array_type, Oid element_type, MemoryContext rcontext, bool subcontext)
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
int ArrayGetNItems(int ndim, const int *dims)
Definition arrayutils.c:57
#define Max(x, y)
Definition c.h:991
int i
Definition isn.c:77
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc(Size size)
Definition mcxt.c:1387
void * arg
static uint32 pg_nextpower2_32(uint32 num)
const void * data
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:342
#define InvalidOid
bits8 * nullbitmap
Definition array.h:209
int lbs[MAXDIM]
Definition array.h:216
MemoryContext mcontext
Definition array.h:207
int dims[MAXDIM]
Definition array.h:215

References ArrayBuildStateArr::abytes, ArrayBuildStateArr::aitems, arg, ARR_DATA_OFFSET, ARR_DATA_PTR, ARR_DIMS, ARR_HASNULL, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ARR_SIZE, array_bitmap_copy(), ArrayBuildStateArr::array_type, ArrayGetNItems(), Assert, ArrayBuildStateArr::data, data, DatumGetArrayTypeP, DatumGetPointer(), ArrayBuildStateArr::dims, ereport, errcode(), errmsg(), ERROR, fb(), i, initArrayResultArr(), InvalidOid, ArrayBuildStateArr::lbs, Max, MAXDIM, ArrayBuildStateArr::mcontext, MemoryContextSwitchTo(), ArrayBuildStateArr::nbytes, ArrayBuildStateArr::ndims, ArrayBuildStateArr::nitems, nitems, ArrayBuildStateArr::nullbitmap, palloc(), pfree(), pg_nextpower2_32(), and repalloc().

Referenced by accumArrayResultAny(), and array_agg_array_transfn().

◆ array_bitmap_copy()

void array_bitmap_copy ( bits8 destbitmap,
int  destoffset,
const bits8 srcbitmap,
int  srcoffset,
int  nitems 
)
extern

Definition at line 4974 of file arrayfuncs.c.

4977{
4978 int destbitmask,
4979 destbitval,
4980 srcbitmask,
4981 srcbitval;
4982
4984 if (nitems <= 0)
4985 return; /* don't risk fetch off end of memory */
4986 destbitmap += destoffset / 8;
4987 destbitmask = 1 << (destoffset % 8);
4989 if (srcbitmap)
4990 {
4991 srcbitmap += srcoffset / 8;
4992 srcbitmask = 1 << (srcoffset % 8);
4994 while (nitems-- > 0)
4995 {
4996 if (srcbitval & srcbitmask)
4998 else
5000 destbitmask <<= 1;
5001 if (destbitmask == 0x100)
5002 {
5004 destbitmask = 1;
5005 if (nitems > 0)
5007 }
5008 srcbitmask <<= 1;
5009 if (srcbitmask == 0x100)
5010 {
5011 srcbitmap++;
5012 srcbitmask = 1;
5013 if (nitems > 0)
5015 }
5016 }
5017 if (destbitmask != 1)
5019 }
5020 else
5021 {
5022 while (nitems-- > 0)
5023 {
5025 destbitmask <<= 1;
5026 if (destbitmask == 0x100)
5027 {
5029 destbitmask = 1;
5030 if (nitems > 0)
5032 }
5033 }
5034 if (destbitmask != 1)
5036 }
5037}

References Assert, fb(), and nitems.

Referenced by accumArrayResultArr(), array_agg_array_combine(), array_cat(), array_extract_slice(), array_insert_slice(), array_set_element(), array_set_slice(), ExecEvalArrayExpr(), and makeArrayResultArr().

◆ array_contains_nulls()

bool array_contains_nulls ( const ArrayType array)
extern

Definition at line 3775 of file arrayfuncs.c.

3776{
3777 int nelems;
3778 bits8 *bitmap;
3779 int bitmask;
3780
3781 /* Easy answer if there's no null bitmap */
3782 if (!ARR_HASNULL(array))
3783 return false;
3784
3785 nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
3786
3787 bitmap = ARR_NULLBITMAP(array);
3788
3789 /* check whole bytes of the bitmap byte-at-a-time */
3790 while (nelems >= 8)
3791 {
3792 if (*bitmap != 0xFF)
3793 return true;
3794 bitmap++;
3795 nelems -= 8;
3796 }
3797
3798 /* check last partial byte */
3799 bitmask = 1;
3800 while (nelems > 0)
3801 {
3802 if ((*bitmap & bitmask) == 0)
3803 return true;
3804 bitmask <<= 1;
3805 nelems--;
3806 }
3807
3808 return false;
3809}

References ARR_DIMS, ARR_HASNULL, ARR_NDIM, ARR_NULLBITMAP, and ArrayGetNItems().

Referenced by _arrq_cons(), _lca(), _lt_q_regex(), _ltree_compress(), array_fill_internal(), array_iterator(), array_position_common(), array_positions(), ArrayGetIntegerTypmods(), arrq_cons(), check_mcvlist_array(), cube_a_f8(), cube_a_f8_f8(), cube_subset(), get_jsonb_path_all(), get_path_all(), getWeights(), lt_q_regex(), pg_isolation_test_session_is_blocked(), pg_logical_slot_get_changes_guts(), sanity_check_array(), sanity_check_tid_array(), statatt_build_stavalues(), stats_check_arg_array(), width_bucket_array(), and worker_spi_launch().

◆ array_create_iterator()

ArrayIterator array_create_iterator ( ArrayType arr,
int  slice_ndim,
ArrayMetaState mstate 
)
extern

Definition at line 4603 of file arrayfuncs.c.

4604{
4606
4607 /*
4608 * Sanity-check inputs --- caller should have got this right already
4609 */
4610 Assert(arr);
4612 elog(ERROR, "invalid arguments to array_create_iterator");
4613
4614 /*
4615 * Remember basic info about the array and its element type
4616 */
4617 iterator->arr = arr;
4618 iterator->nullbitmap = ARR_NULLBITMAP(arr);
4619 iterator->nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
4620
4621 if (mstate != NULL)
4622 {
4623 Assert(mstate->element_type == ARR_ELEMTYPE(arr));
4624
4625 iterator->typlen = mstate->typlen;
4626 iterator->typbyval = mstate->typbyval;
4627 iterator->typalign = mstate->typalign;
4628 }
4629 else
4631 &iterator->typlen,
4632 &iterator->typbyval,
4633 &iterator->typalign);
4634 iterator->typalignby = typalign_to_alignby(iterator->typalign);
4635
4636 /*
4637 * Remember the slicing parameters.
4638 */
4639 iterator->slice_ndim = slice_ndim;
4640
4641 if (slice_ndim > 0)
4642 {
4643 /*
4644 * Get pointers into the array's dims and lbound arrays to represent
4645 * the dims/lbound arrays of a slice. These are the same as the
4646 * rightmost N dimensions of the array.
4647 */
4648 iterator->slice_dims = ARR_DIMS(arr) + ARR_NDIM(arr) - slice_ndim;
4649 iterator->slice_lbound = ARR_LBOUND(arr) + ARR_NDIM(arr) - slice_ndim;
4650
4651 /*
4652 * Compute number of elements in a slice.
4653 */
4654 iterator->slice_len = ArrayGetNItems(slice_ndim,
4655 iterator->slice_dims);
4656
4657 /*
4658 * Create workspace for building sub-arrays.
4659 */
4660 iterator->slice_values = (Datum *)
4661 palloc(iterator->slice_len * sizeof(Datum));
4662 iterator->slice_nulls = (bool *)
4663 palloc(iterator->slice_len * sizeof(bool));
4664 }
4665
4666 /*
4667 * Initialize our data pointer and linear element number. These will
4668 * advance through the array during array_iterate().
4669 */
4670 iterator->data_ptr = ARR_DATA_PTR(arr);
4671 iterator->current_item = 0;
4672
4673 return iterator;
4674}
#define elog(elevel,...)
Definition elog.h:226
#define palloc0_object(type)
Definition fe_memutils.h:75
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition lsyscache.c:2421
static uint8 typalign_to_alignby(char typalign)
Definition tupmacs.h:80

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ArrayGetNItems(), Assert, elog, ERROR, fb(), get_typlenbyvalalign(), palloc(), palloc0_object, and typalign_to_alignby().

Referenced by array_position_common(), array_positions(), array_sort_internal(), and exec_stmt_foreach_a().

◆ array_free_iterator()

void array_free_iterator ( ArrayIterator  iterator)
extern

Definition at line 4766 of file arrayfuncs.c.

4767{
4768 if (iterator->slice_ndim > 0)
4769 {
4770 pfree(iterator->slice_values);
4771 pfree(iterator->slice_nulls);
4772 }
4773 pfree(iterator);
4774}

References fb(), and pfree().

Referenced by array_position_common(), array_positions(), and array_sort_internal().

◆ array_get_element()

Datum array_get_element ( Datum  arraydatum,
int  nSubscripts,
int indx,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign,
bool isNull 
)
extern

Definition at line 1824 of file arrayfuncs.c.

1832{
1833 int i,
1834 ndim,
1835 *dim,
1836 *lb,
1837 offset,
1838 fixedDim[1],
1839 fixedLb[1];
1840 char *arraydataptr,
1841 *retptr;
1843
1844 if (arraytyplen > 0)
1845 {
1846 /*
1847 * fixed-length arrays -- these are assumed to be 1-d, 0-based
1848 */
1849 ndim = 1;
1850 fixedDim[0] = arraytyplen / elmlen;
1851 fixedLb[0] = 0;
1852 dim = fixedDim;
1853 lb = fixedLb;
1856 }
1858 {
1859 /* expanded array: let's do this in a separate function */
1862 indx,
1864 elmlen,
1865 elmbyval,
1866 elmalign,
1867 isNull);
1868 }
1869 else
1870 {
1871 /* detoast array if necessary, producing normal varlena input */
1873
1874 ndim = ARR_NDIM(array);
1875 dim = ARR_DIMS(array);
1876 lb = ARR_LBOUND(array);
1877 arraydataptr = ARR_DATA_PTR(array);
1879 }
1880
1881 /*
1882 * Return NULL for invalid subscript
1883 */
1884 if (ndim != nSubscripts || ndim <= 0 || ndim > MAXDIM)
1885 {
1886 *isNull = true;
1887 return (Datum) 0;
1888 }
1889 for (i = 0; i < ndim; i++)
1890 {
1891 if (indx[i] < lb[i] || indx[i] >= (dim[i] + lb[i]))
1892 {
1893 *isNull = true;
1894 return (Datum) 0;
1895 }
1896 }
1897
1898 /*
1899 * Calculate the element number
1900 */
1901 offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
1902
1903 /*
1904 * Check for NULL array element
1905 */
1906 if (array_get_isnull(arraynullsptr, offset))
1907 {
1908 *isNull = true;
1909 return (Datum) 0;
1910 }
1911
1912 /*
1913 * OK, get the element
1914 */
1915 *isNull = false;
1917 elmlen, elmbyval, elmalign);
1918 return ArrayCast(retptr, elmbyval, elmlen);
1919}
static bool array_get_isnull(const bits8 *nullbitmap, int offset)
static Datum array_get_element_expanded(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
static Datum ArrayCast(char *value, bool byval, int len)
static char * array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)
int ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx)
Definition arrayutils.c:32
static bool VARATT_IS_EXTERNAL_EXPANDED(const void *PTR)
Definition varatt.h:389

References ARR_DATA_PTR, ARR_DIMS, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, array_get_element_expanded(), array_get_isnull(), array_seek(), ArrayCast(), ArrayGetOffset(), DatumGetArrayTypeP, DatumGetPointer(), fb(), i, MAXDIM, and VARATT_IS_EXTERNAL_EXPANDED().

Referenced by array_ref(), array_subscript_fetch(), array_subscript_fetch_old(), ATExecAlterColumnType(), and RelationBuildTupleDesc().

◆ array_get_slice()

Datum array_get_slice ( Datum  arraydatum,
int  nSubscripts,
int upperIndx,
int lowerIndx,
bool upperProvided,
bool lowerProvided,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign 
)
extern

Definition at line 2034 of file arrayfuncs.c.

2044{
2045 ArrayType *array;
2047 int i,
2048 ndim,
2049 *dim,
2050 *lb,
2051 *newlb;
2052 int fixedDim[1],
2053 fixedLb[1];
2054 Oid elemtype;
2055 char *arraydataptr;
2057 int32 dataoffset;
2058 int bytes,
2059 span[MAXDIM];
2060
2061 if (arraytyplen > 0)
2062 {
2063 /*
2064 * fixed-length arrays -- currently, cannot slice these because parser
2065 * labels output as being of the fixed-length array type! Code below
2066 * shows how we could support it if the parser were changed to label
2067 * output as a suitable varlena array type.
2068 */
2069 ereport(ERROR,
2071 errmsg("slices of fixed-length arrays not implemented")));
2072
2073 /*
2074 * fixed-length arrays -- these are assumed to be 1-d, 0-based
2075 *
2076 * XXX where would we get the correct ELEMTYPE from?
2077 */
2078 ndim = 1;
2079 fixedDim[0] = arraytyplen / elmlen;
2080 fixedLb[0] = 0;
2081 dim = fixedDim;
2082 lb = fixedLb;
2083 elemtype = InvalidOid; /* XXX */
2086 }
2087 else
2088 {
2089 /* detoast input array if necessary */
2091
2092 ndim = ARR_NDIM(array);
2093 dim = ARR_DIMS(array);
2094 lb = ARR_LBOUND(array);
2095 elemtype = ARR_ELEMTYPE(array);
2096 arraydataptr = ARR_DATA_PTR(array);
2098 }
2099
2100 /*
2101 * Check provided subscripts. A slice exceeding the current array limits
2102 * is silently truncated to the array limits. If we end up with an empty
2103 * slice, return an empty array.
2104 */
2106 return PointerGetDatum(construct_empty_array(elemtype));
2107
2108 for (i = 0; i < nSubscripts; i++)
2109 {
2110 if (!lowerProvided[i] || lowerIndx[i] < lb[i])
2111 lowerIndx[i] = lb[i];
2112 if (!upperProvided[i] || upperIndx[i] >= (dim[i] + lb[i]))
2113 upperIndx[i] = dim[i] + lb[i] - 1;
2114 if (lowerIndx[i] > upperIndx[i])
2115 return PointerGetDatum(construct_empty_array(elemtype));
2116 }
2117 /* fill any missing subscript positions with full array range */
2118 for (; i < ndim; i++)
2119 {
2120 lowerIndx[i] = lb[i];
2121 upperIndx[i] = dim[i] + lb[i] - 1;
2122 if (lowerIndx[i] > upperIndx[i])
2123 return PointerGetDatum(construct_empty_array(elemtype));
2124 }
2125
2127
2129 ndim, dim, lb,
2131 elmlen, elmbyval, elmalign);
2132
2133 /*
2134 * Currently, we put a null bitmap in the result if the source has one;
2135 * could be smarter ...
2136 */
2137 if (arraynullsptr)
2138 {
2139 dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, ArrayGetNItems(ndim, span));
2140 bytes += dataoffset;
2141 }
2142 else
2143 {
2144 dataoffset = 0; /* marker for no null bitmap */
2145 bytes += ARR_OVERHEAD_NONULLS(ndim);
2146 }
2147
2148 newarray = (ArrayType *) palloc0(bytes);
2149 SET_VARSIZE(newarray, bytes);
2150 newarray->ndim = ndim;
2151 newarray->dataoffset = dataoffset;
2152 newarray->elemtype = elemtype;
2153 memcpy(ARR_DIMS(newarray), span, ndim * sizeof(int));
2154
2155 /*
2156 * Lower bounds of the new array are set to 1. Formerly (before 7.3) we
2157 * copied the given lowerIndx values ... but that seems confusing.
2158 */
2160 for (i = 0; i < ndim; i++)
2161 newlb[i] = 1;
2162
2164 ndim, dim, lb,
2167 elmlen, elmbyval, elmalign);
2168
2169 return PointerGetDatum(newarray);
2170}
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
Definition array.h:312
ArrayType * construct_empty_array(Oid elmtype)
static int array_slice_size(char *arraydataptr, bits8 *arraynullsptr, int ndim, int *dim, int *lb, int *st, int *endp, int typlen, bool typbyval, char typalign)
static 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)
void mda_get_range(int n, int *span, const int *st, const int *endp)
Definition arrayutils.c:153
int32_t int32
Definition c.h:542
void * palloc0(Size size)
Definition mcxt.c:1417
unsigned int Oid
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, array_extract_slice(), array_slice_size(), ArrayGetNItems(), construct_empty_array(), DatumGetArrayTypeP, DatumGetPointer(), ereport, errcode(), errmsg(), ERROR, fb(), i, InvalidOid, MAXDIM, mda_get_range(), palloc0(), PointerGetDatum(), and SET_VARSIZE().

Referenced by array_subscript_fetch_old_slice(), array_subscript_fetch_slice(), and trim_array().

◆ array_iterate()

bool array_iterate ( ArrayIterator  iterator,
Datum value,
bool isnull 
)
extern

Definition at line 4683 of file arrayfuncs.c.

4684{
4685 /* Done if we have reached the end of the array */
4686 if (iterator->current_item >= iterator->nitems)
4687 return false;
4688
4689 if (iterator->slice_ndim == 0)
4690 {
4691 /*
4692 * Scalar case: return one element.
4693 */
4694 if (array_get_isnull(iterator->nullbitmap, iterator->current_item++))
4695 {
4696 *isnull = true;
4697 *value = (Datum) 0;
4698 }
4699 else
4700 {
4701 /* non-NULL, so fetch the individual Datum to return */
4702 char *p = iterator->data_ptr;
4703
4704 *isnull = false;
4705 *value = fetch_att(p, iterator->typbyval, iterator->typlen);
4706
4707 /* Move our data pointer forward to the next element */
4708 p = att_addlength_pointer(p, iterator->typlen, p);
4709 p = (char *) att_nominal_alignby(p, iterator->typalignby);
4710 iterator->data_ptr = p;
4711 }
4712 }
4713 else
4714 {
4715 /*
4716 * Slice case: build and return an array of the requested size.
4717 */
4718 ArrayType *result;
4719 Datum *values = iterator->slice_values;
4720 bool *nulls = iterator->slice_nulls;
4721 char *p = iterator->data_ptr;
4722 int i;
4723
4724 for (i = 0; i < iterator->slice_len; i++)
4725 {
4726 if (array_get_isnull(iterator->nullbitmap,
4727 iterator->current_item++))
4728 {
4729 nulls[i] = true;
4730 values[i] = (Datum) 0;
4731 }
4732 else
4733 {
4734 nulls[i] = false;
4735 values[i] = fetch_att(p, iterator->typbyval, iterator->typlen);
4736
4737 /* Move our data pointer forward to the next element */
4738 p = att_addlength_pointer(p, iterator->typlen, p);
4739 p = (char *) att_nominal_alignby(p, iterator->typalignby);
4740 }
4741 }
4742
4743 iterator->data_ptr = p;
4744
4745 result = construct_md_array(values,
4746 nulls,
4747 iterator->slice_ndim,
4748 iterator->slice_dims,
4749 iterator->slice_lbound,
4750 ARR_ELEMTYPE(iterator->arr),
4751 iterator->typlen,
4752 iterator->typbyval,
4753 iterator->typalign);
4754
4755 *isnull = false;
4756 *value = PointerGetDatum(result);
4757 }
4758
4759 return true;
4760}
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
static Datum values[MAXATTR]
Definition bootstrap.c:155
static struct @170 value
#define att_nominal_alignby(cur_offset, attalignby)
Definition tupmacs.h:189
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition tupmacs.h:209
static Datum fetch_att(const void *T, bool attbyval, int attlen)
Definition tupmacs.h:50

References ARR_ELEMTYPE, array_get_isnull(), att_addlength_pointer, att_nominal_alignby, construct_md_array(), fb(), fetch_att(), i, PointerGetDatum(), value, and values.

Referenced by array_position_common(), array_positions(), array_sort_internal(), and exec_stmt_foreach_a().

◆ array_map()

Datum array_map ( Datum  arrayd,
ExprState exprstate,
ExprContext econtext,
Oid  retType,
ArrayMapState amstate 
)
extern

Definition at line 3206 of file arrayfuncs.c.

3209{
3211 ArrayType *result;
3212 Datum *values;
3213 bool *nulls;
3214 int *dim;
3215 int ndim;
3216 int nitems;
3217 int i;
3218 int32 nbytes = 0;
3219 int32 dataoffset;
3220 bool hasnulls;
3221 Oid inpType;
3222 int inp_typlen;
3223 bool inp_typbyval;
3224 char inp_typalign;
3225 int typlen;
3226 bool typbyval;
3227 char typalign;
3228 uint8 typalignby;
3229 array_iter iter;
3230 ArrayMetaState *inp_extra;
3231 ArrayMetaState *ret_extra;
3234
3236 ndim = AARR_NDIM(v);
3237 dim = AARR_DIMS(v);
3238 nitems = ArrayGetNItems(ndim, dim);
3239
3240 /* Check for empty array */
3241 if (nitems <= 0)
3242 {
3243 /* Return empty array */
3245 }
3246
3247 /*
3248 * We arrange to look up info about input and return element types only
3249 * once per series of calls, assuming the element type doesn't change
3250 * underneath us.
3251 */
3252 inp_extra = &amstate->inp_extra;
3253 ret_extra = &amstate->ret_extra;
3254
3255 if (inp_extra->element_type != inpType)
3256 {
3258 &inp_extra->typlen,
3259 &inp_extra->typbyval,
3260 &inp_extra->typalign);
3261 inp_extra->element_type = inpType;
3262 }
3263 inp_typlen = inp_extra->typlen;
3264 inp_typbyval = inp_extra->typbyval;
3265 inp_typalign = inp_extra->typalign;
3266
3267 if (ret_extra->element_type != retType)
3268 {
3270 &ret_extra->typlen,
3271 &ret_extra->typbyval,
3272 &ret_extra->typalign);
3273 ret_extra->element_type = retType;
3274 }
3275 typlen = ret_extra->typlen;
3276 typbyval = ret_extra->typbyval;
3277 typalign = ret_extra->typalign;
3278 typalignby = typalign_to_alignby(typalign);
3279
3280 /* Allocate temporary arrays for new values */
3281 values = (Datum *) palloc(nitems * sizeof(Datum));
3282 nulls = (bool *) palloc(nitems * sizeof(bool));
3283
3284 /* Loop over source data */
3286 hasnulls = false;
3287
3288 for (i = 0; i < nitems; i++)
3289 {
3290 /* Get source element, checking for NULL */
3293
3294 /* Apply the given expression to source element */
3295 values[i] = ExecEvalExpr(exprstate, econtext, &nulls[i]);
3296
3297 if (nulls[i])
3298 hasnulls = true;
3299 else
3300 {
3301 /* Ensure data is not toasted */
3302 if (typlen == -1)
3304 /* Update total result size */
3305 nbytes = att_addlength_datum(nbytes, typlen, values[i]);
3306 nbytes = att_nominal_alignby(nbytes, typalignby);
3307 /* check for overflow of total request */
3308 if (!AllocSizeIsValid(nbytes))
3309 ereport(ERROR,
3311 errmsg("array size exceeds the maximum allowed (%zu)",
3312 MaxAllocSize)));
3313 }
3314 }
3315
3316 /* Allocate and fill the result array */
3317 if (hasnulls)
3318 {
3319 dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems);
3320 nbytes += dataoffset;
3321 }
3322 else
3323 {
3324 dataoffset = 0; /* marker for no null bitmap */
3325 nbytes += ARR_OVERHEAD_NONULLS(ndim);
3326 }
3327 result = (ArrayType *) palloc0(nbytes);
3328 SET_VARSIZE(result, nbytes);
3329 result->ndim = ndim;
3330 result->dataoffset = dataoffset;
3331 result->elemtype = retType;
3332 memcpy(ARR_DIMS(result), AARR_DIMS(v), ndim * sizeof(int));
3333 memcpy(ARR_LBOUND(result), AARR_LBOUND(v), ndim * sizeof(int));
3334
3335 CopyArrayEls(result,
3336 values, nulls, nitems,
3337 typlen, typbyval, typalign,
3338 false);
3339
3340 /*
3341 * Note: do not risk trying to pfree the results of the called expression
3342 */
3343 pfree(values);
3344 pfree(nulls);
3345
3346 return PointerGetDatum(result);
3347}
#define AARR_DIMS(a)
Definition array.h:338
#define AARR_ELEMTYPE(a)
Definition array.h:335
#define AARR_LBOUND(a)
Definition array.h:341
#define AARR_NDIM(a)
Definition array.h:328
AnyArrayType * DatumGetAnyArrayP(Datum d)
static Datum array_iter_next(array_iter *it, bool *isnull, int i)
Definition arrayaccess.h:90
static void array_iter_setup(array_iter *it, AnyArrayType *a, int elmlen, bool elmbyval, char elmalign)
Definition arrayaccess.h:54
void CopyArrayEls(ArrayType *array, const Datum *values, const bool *nulls, int nitems, int typlen, bool typbyval, char typalign, bool freedata)
Definition arrayfuncs.c:965
uint8_t uint8
Definition c.h:544
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition executor.h:393
#define PG_DETOAST_DATUM(datum)
Definition fmgr.h:240
char typalign
Definition pg_type.h:176
ArrayMetaState inp_extra
Definition array.h:253
ArrayMetaState ret_extra
Definition array.h:254
char typalign
Definition array.h:241
int16 typlen
Definition array.h:239
Oid element_type
Definition array.h:238
bool typbyval
Definition array.h:240
Oid elemtype
Definition array.h:97
int ndim
Definition array.h:95
int32 dataoffset
Definition array.h:96
bool * innermost_casenull
Definition execnodes.h:138
Datum * innermost_caseval
Definition execnodes.h:137
#define att_addlength_datum(cur_offset, attlen, attdatum)
Definition tupmacs.h:197

References AARR_DIMS, AARR_ELEMTYPE, AARR_LBOUND, AARR_NDIM, AllocSizeIsValid, ARR_DIMS, ARR_LBOUND, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, array_iter_next(), array_iter_setup(), ArrayGetNItems(), att_addlength_datum, att_nominal_alignby, construct_empty_array(), CopyArrayEls(), ArrayType::dataoffset, DatumGetAnyArrayP(), ArrayMetaState::element_type, ArrayType::elemtype, ereport, errcode(), errmsg(), ERROR, ExecEvalExpr(), fb(), get_typlenbyvalalign(), i, ExprState::innermost_casenull, ExprState::innermost_caseval, ArrayMapState::inp_extra, MaxAllocSize, ArrayType::ndim, nitems, palloc(), palloc0(), pfree(), PG_DETOAST_DATUM, PointerGetDatum(), ArrayMapState::ret_extra, SET_VARSIZE(), typalign, ArrayMetaState::typalign, typalign_to_alignby(), ArrayMetaState::typbyval, ArrayMetaState::typlen, and values.

Referenced by ExecEvalArrayCoerce().

◆ array_ref()

Datum array_ref ( ArrayType array,
int  nSubscripts,
int indx,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign,
bool isNull 
)
extern

Definition at line 3151 of file arrayfuncs.c.

3154{
3156 arraytyplen, elmlen, elmbyval, elmalign,
3157 isNull);
3158}
Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)

References array_get_element(), fb(), and PointerGetDatum().

Referenced by GUCArrayAdd(), GUCArrayDelete(), GUCArrayReset(), pg_get_functiondef(), and TransformGUCArray().

◆ array_set()

ArrayType * array_set ( ArrayType array,
int  nSubscripts,
int indx,
Datum  dataValue,
bool  isNull,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign 
)
extern

Definition at line 3168 of file arrayfuncs.c.

3171{
3174 dataValue, isNull,
3176 elmlen, elmbyval, elmalign));
3177}
Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)

References array_set_element(), DatumGetArrayTypeP, fb(), and PointerGetDatum().

Referenced by GUCArrayAdd(), GUCArrayDelete(), GUCArrayReset(), and pg_extension_config_dump().

◆ array_set_element()

Datum array_set_element ( Datum  arraydatum,
int  nSubscripts,
int indx,
Datum  dataValue,
bool  isNull,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign 
)
extern

Definition at line 2205 of file arrayfuncs.c.

2214{
2215 ArrayType *array;
2217 int i,
2218 ndim,
2219 dim[MAXDIM],
2220 lb[MAXDIM],
2221 offset;
2222 char *elt_ptr;
2223 bool newhasnulls;
2225 int oldnitems,
2226 newnitems,
2228 newsize,
2229 olditemlen,
2230 newitemlen,
2234 addedafter,
2235 lenbefore,
2236 lenafter;
2237 uint8 elmalignby = typalign_to_alignby(elmalign);
2238
2239 if (arraytyplen > 0)
2240 {
2241 /*
2242 * fixed-length arrays -- these are assumed to be 1-d, 0-based. We
2243 * cannot extend them, either.
2244 */
2245 char *resultarray;
2246
2247 if (nSubscripts != 1)
2248 ereport(ERROR,
2250 errmsg("wrong number of array subscripts")));
2251
2252 if (indx[0] < 0 || indx[0] >= arraytyplen / elmlen)
2253 ereport(ERROR,
2255 errmsg("array subscript out of range")));
2256
2257 if (isNull)
2258 ereport(ERROR,
2260 errmsg("cannot assign null value to an element of a fixed-length array")));
2261
2262 resultarray = (char *) palloc(arraytyplen);
2264 elt_ptr = resultarray + indx[0] * elmlen;
2265 ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalignby, elt_ptr);
2267 }
2268
2270 ereport(ERROR,
2272 errmsg("wrong number of array subscripts")));
2273
2274 /* make sure item to be inserted is not toasted */
2275 if (elmlen == -1 && !isNull)
2277
2279 {
2280 /* expanded array: let's do this in a separate function */
2283 indx,
2284 dataValue,
2285 isNull,
2287 elmlen,
2288 elmbyval,
2289 elmalign);
2290 }
2291
2292 /* detoast input array if necessary */
2294
2295 ndim = ARR_NDIM(array);
2296
2297 /*
2298 * if number of dims is zero, i.e. an empty array, create an array with
2299 * nSubscripts dimensions, and set the lower bounds to the supplied
2300 * subscripts
2301 */
2302 if (ndim == 0)
2303 {
2304 Oid elmtype = ARR_ELEMTYPE(array);
2305
2306 for (i = 0; i < nSubscripts; i++)
2307 {
2308 dim[i] = 1;
2309 lb[i] = indx[i];
2310 }
2311
2313 nSubscripts, dim, lb,
2314 elmtype,
2315 elmlen, elmbyval, elmalign));
2316 }
2317
2318 if (ndim != nSubscripts)
2319 ereport(ERROR,
2321 errmsg("wrong number of array subscripts")));
2322
2323 /* copy dim/lb since we may modify them */
2324 memcpy(dim, ARR_DIMS(array), ndim * sizeof(int));
2325 memcpy(lb, ARR_LBOUND(array), ndim * sizeof(int));
2326
2327 newhasnulls = (ARR_HASNULL(array) || isNull);
2328 addedbefore = addedafter = 0;
2329
2330 /*
2331 * Check subscripts. We assume the existing subscripts passed
2332 * ArrayCheckBounds, so that dim[i] + lb[i] can be computed without
2333 * overflow. But we must beware of other overflows in our calculations of
2334 * new dim[] values.
2335 */
2336 if (ndim == 1)
2337 {
2338 if (indx[0] < lb[0])
2339 {
2340 /* addedbefore = lb[0] - indx[0]; */
2341 /* dim[0] += addedbefore; */
2342 if (pg_sub_s32_overflow(lb[0], indx[0], &addedbefore) ||
2343 pg_add_s32_overflow(dim[0], addedbefore, &dim[0]))
2344 ereport(ERROR,
2346 errmsg("array size exceeds the maximum allowed (%zu)",
2347 MaxArraySize)));
2348 lb[0] = indx[0];
2349 if (addedbefore > 1)
2350 newhasnulls = true; /* will insert nulls */
2351 }
2352 if (indx[0] >= (dim[0] + lb[0]))
2353 {
2354 /* addedafter = indx[0] - (dim[0] + lb[0]) + 1; */
2355 /* dim[0] += addedafter; */
2356 if (pg_sub_s32_overflow(indx[0], dim[0] + lb[0], &addedafter) ||
2358 pg_add_s32_overflow(dim[0], addedafter, &dim[0]))
2359 ereport(ERROR,
2361 errmsg("array size exceeds the maximum allowed (%zu)",
2362 MaxArraySize)));
2363 if (addedafter > 1)
2364 newhasnulls = true; /* will insert nulls */
2365 }
2366 }
2367 else
2368 {
2369 /*
2370 * XXX currently we do not support extending multi-dimensional arrays
2371 * during assignment
2372 */
2373 for (i = 0; i < ndim; i++)
2374 {
2375 if (indx[i] < lb[i] ||
2376 indx[i] >= (dim[i] + lb[i]))
2377 ereport(ERROR,
2379 errmsg("array subscript out of range")));
2380 }
2381 }
2382
2383 /* This checks for overflow of the array dimensions */
2384 newnitems = ArrayGetNItems(ndim, dim);
2385 ArrayCheckBounds(ndim, dim, lb);
2386
2387 /*
2388 * Compute sizes of items and areas to copy
2389 */
2390 if (newhasnulls)
2392 else
2394 oldnitems = ArrayGetNItems(ndim, ARR_DIMS(array));
2398 if (addedbefore)
2399 {
2400 offset = 0;
2401 lenbefore = 0;
2402 olditemlen = 0;
2404 }
2405 else if (addedafter)
2406 {
2407 offset = oldnitems;
2409 olditemlen = 0;
2410 lenafter = 0;
2411 }
2412 else
2413 {
2414 offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
2415 elt_ptr = array_seek(ARR_DATA_PTR(array), 0, oldnullbitmap, offset,
2416 elmlen, elmbyval, elmalign);
2417 lenbefore = (int) (elt_ptr - ARR_DATA_PTR(array));
2418 if (array_get_isnull(oldnullbitmap, offset))
2419 olditemlen = 0;
2420 else
2421 {
2424 }
2426 }
2427
2428 if (isNull)
2429 newitemlen = 0;
2430 else
2431 {
2434 }
2435
2437
2438 /*
2439 * OK, create the new array and fill in header/dimensions
2440 */
2443 newarray->ndim = ndim;
2444 newarray->dataoffset = newhasnulls ? overheadlen : 0;
2445 newarray->elemtype = ARR_ELEMTYPE(array);
2446 memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));
2447 memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));
2448
2449 /*
2450 * Fill in data
2451 */
2452 memcpy((char *) newarray + overheadlen,
2453 (char *) array + oldoverheadlen,
2454 lenbefore);
2455 if (!isNull)
2456 ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalignby,
2457 (char *) newarray + overheadlen + lenbefore);
2459 (char *) array + oldoverheadlen + lenbefore + olditemlen,
2460 lenafter);
2461
2462 /*
2463 * Fill in nulls bitmap if needed
2464 *
2465 * Note: it's possible we just replaced the last NULL with a non-NULL, and
2466 * could get rid of the bitmap. Seems not worth testing for though.
2467 */
2468 if (newhasnulls)
2469 {
2471
2472 /* palloc0 above already marked any inserted positions as nulls */
2473 /* Fix the inserted value */
2474 if (addedafter)
2476 else
2477 array_set_isnull(newnullbitmap, offset, isNull);
2478 /* Fix the copied range(s) */
2479 if (addedbefore)
2481 oldnullbitmap, 0,
2482 oldnitems);
2483 else
2484 {
2486 oldnullbitmap, 0,
2487 offset);
2488 if (addedafter == 0)
2489 array_bitmap_copy(newnullbitmap, offset + 1,
2490 oldnullbitmap, offset + 1,
2491 oldnitems - offset - 1);
2492 }
2493 }
2494
2495 return PointerGetDatum(newarray);
2496}
#define MaxArraySize
Definition array.h:82
static Datum array_set_element_expanded(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
static void array_set_isnull(bits8 *nullbitmap, int offset, bool isNull)
static int ArrayCastAndSet(Datum src, int typlen, bool typbyval, uint8 typalignby, char *dest)
void ArrayCheckBounds(int ndim, const int *dims, const int *lb)
Definition arrayutils.c:117
static bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
Definition int.h:169
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition int.h:151

References ARR_DATA_OFFSET, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, ARR_SIZE, array_bitmap_copy(), array_get_isnull(), array_seek(), array_set_element_expanded(), array_set_isnull(), ArrayCastAndSet(), ArrayCheckBounds(), ArrayGetNItems(), ArrayGetOffset(), att_addlength_datum, att_addlength_pointer, att_nominal_alignby, construct_md_array(), DatumGetArrayTypeP, DatumGetPointer(), ereport, errcode(), errmsg(), ERROR, fb(), i, MaxArraySize, MAXDIM, palloc(), palloc0(), pg_add_s32_overflow(), PG_DETOAST_DATUM, pg_sub_s32_overflow(), PointerGetDatum(), SET_VARSIZE(), typalign_to_alignby(), and VARATT_IS_EXTERNAL_EXPANDED().

Referenced by array_append(), array_prepend(), array_set(), and array_subscript_assign().

◆ array_set_slice()

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 
)
extern

Definition at line 2811 of file arrayfuncs.c.

2823{
2824 ArrayType *array;
2827 int i,
2828 ndim,
2829 dim[MAXDIM],
2830 lb[MAXDIM],
2831 span[MAXDIM];
2832 bool newhasnulls;
2833 int nitems,
2834 nsrcitems,
2836 newsize,
2842 addedafter,
2843 lenbefore,
2844 lenafter,
2846 itemsafter,
2847 nolditems;
2848
2849 /* Currently, assignment from a NULL source array is a no-op */
2850 if (isNull)
2851 return arraydatum;
2852
2853 if (arraytyplen > 0)
2854 {
2855 /*
2856 * fixed-length arrays -- not got round to doing this...
2857 */
2858 ereport(ERROR,
2860 errmsg("updates on slices of fixed-length arrays not implemented")));
2861 }
2862
2863 /* detoast arrays if necessary */
2866
2867 /* note: we assume srcArray contains no toasted elements */
2868
2869 ndim = ARR_NDIM(array);
2870
2871 /*
2872 * if number of dims is zero, i.e. an empty array, create an array with
2873 * nSubscripts dimensions, and set the upper and lower bounds to the
2874 * supplied subscripts
2875 */
2876 if (ndim == 0)
2877 {
2878 Datum *dvalues;
2879 bool *dnulls;
2880 int nelems;
2881 Oid elmtype = ARR_ELEMTYPE(array);
2882
2883 deconstruct_array(srcArray, elmtype, elmlen, elmbyval, elmalign,
2884 &dvalues, &dnulls, &nelems);
2885
2886 for (i = 0; i < nSubscripts; i++)
2887 {
2888 if (!upperProvided[i] || !lowerProvided[i])
2889 ereport(ERROR,
2891 errmsg("array slice subscript must provide both boundaries"),
2892 errdetail("When assigning to a slice of an empty array value,"
2893 " slice boundaries must be fully specified.")));
2894
2895 /* compute "upperIndx[i] - lowerIndx[i] + 1", detecting overflow */
2896 if (pg_sub_s32_overflow(upperIndx[i], lowerIndx[i], &dim[i]) ||
2897 pg_add_s32_overflow(dim[i], 1, &dim[i]))
2898 ereport(ERROR,
2900 errmsg("array size exceeds the maximum allowed (%zu)",
2901 MaxArraySize)));
2902
2903 lb[i] = lowerIndx[i];
2904 }
2905
2906 /* complain if too few source items; we ignore extras, however */
2907 if (nelems < ArrayGetNItems(nSubscripts, dim))
2908 ereport(ERROR,
2910 errmsg("source array too small")));
2911
2912 return PointerGetDatum(construct_md_array(dvalues, dnulls, nSubscripts,
2913 dim, lb, elmtype,
2914 elmlen, elmbyval, elmalign));
2915 }
2916
2918 ereport(ERROR,
2920 errmsg("wrong number of array subscripts")));
2921
2922 /* copy dim/lb since we may modify them */
2923 memcpy(dim, ARR_DIMS(array), ndim * sizeof(int));
2924 memcpy(lb, ARR_LBOUND(array), ndim * sizeof(int));
2925
2927 addedbefore = addedafter = 0;
2928
2929 /*
2930 * Check subscripts. We assume the existing subscripts passed
2931 * ArrayCheckBounds, so that dim[i] + lb[i] can be computed without
2932 * overflow. But we must beware of other overflows in our calculations of
2933 * new dim[] values.
2934 */
2935 if (ndim == 1)
2936 {
2937 Assert(nSubscripts == 1);
2938 if (!lowerProvided[0])
2939 lowerIndx[0] = lb[0];
2940 if (!upperProvided[0])
2941 upperIndx[0] = dim[0] + lb[0] - 1;
2942 if (lowerIndx[0] > upperIndx[0])
2943 ereport(ERROR,
2945 errmsg("upper bound cannot be less than lower bound")));
2946 if (lowerIndx[0] < lb[0])
2947 {
2948 /* addedbefore = lb[0] - lowerIndx[0]; */
2949 /* dim[0] += addedbefore; */
2950 if (pg_sub_s32_overflow(lb[0], lowerIndx[0], &addedbefore) ||
2951 pg_add_s32_overflow(dim[0], addedbefore, &dim[0]))
2952 ereport(ERROR,
2954 errmsg("array size exceeds the maximum allowed (%zu)",
2955 MaxArraySize)));
2956 lb[0] = lowerIndx[0];
2957 if (addedbefore > 1)
2958 newhasnulls = true; /* will insert nulls */
2959 }
2960 if (upperIndx[0] >= (dim[0] + lb[0]))
2961 {
2962 /* addedafter = upperIndx[0] - (dim[0] + lb[0]) + 1; */
2963 /* dim[0] += addedafter; */
2964 if (pg_sub_s32_overflow(upperIndx[0], dim[0] + lb[0], &addedafter) ||
2966 pg_add_s32_overflow(dim[0], addedafter, &dim[0]))
2967 ereport(ERROR,
2969 errmsg("array size exceeds the maximum allowed (%zu)",
2970 MaxArraySize)));
2971 if (addedafter > 1)
2972 newhasnulls = true; /* will insert nulls */
2973 }
2974 }
2975 else
2976 {
2977 /*
2978 * XXX currently we do not support extending multi-dimensional arrays
2979 * during assignment
2980 */
2981 for (i = 0; i < nSubscripts; i++)
2982 {
2983 if (!lowerProvided[i])
2984 lowerIndx[i] = lb[i];
2985 if (!upperProvided[i])
2986 upperIndx[i] = dim[i] + lb[i] - 1;
2987 if (lowerIndx[i] > upperIndx[i])
2988 ereport(ERROR,
2990 errmsg("upper bound cannot be less than lower bound")));
2991 if (lowerIndx[i] < lb[i] ||
2992 upperIndx[i] >= (dim[i] + lb[i]))
2993 ereport(ERROR,
2995 errmsg("array subscript out of range")));
2996 }
2997 /* fill any missing subscript positions with full array range */
2998 for (; i < ndim; i++)
2999 {
3000 lowerIndx[i] = lb[i];
3001 upperIndx[i] = dim[i] + lb[i] - 1;
3002 if (lowerIndx[i] > upperIndx[i])
3003 ereport(ERROR,
3005 errmsg("upper bound cannot be less than lower bound")));
3006 }
3007 }
3008
3009 /* Do this mainly to check for overflow */
3010 nitems = ArrayGetNItems(ndim, dim);
3011 ArrayCheckBounds(ndim, dim, lb);
3012
3013 /*
3014 * Make sure source array has enough entries. Note we ignore the shape of
3015 * the source array and just read entries serially.
3016 */
3018 nsrcitems = ArrayGetNItems(ndim, span);
3020 ereport(ERROR,
3022 errmsg("source array too small")));
3023
3024 /*
3025 * Compute space occupied by new entries, space occupied by replaced
3026 * entries, and required space for new array.
3027 */
3028 if (newhasnulls)
3030 else
3034 elmlen, elmbyval, elmalign);
3037 if (ndim > 1)
3038 {
3039 /*
3040 * here we do not need to cope with extension of the array; it would
3041 * be a lot more complicated if we had to do so...
3042 */
3044 ARR_NULLBITMAP(array),
3045 ndim, dim, lb,
3047 elmlen, elmbyval, elmalign);
3048 lenbefore = lenafter = 0; /* keep compiler quiet */
3050 }
3051 else
3052 {
3053 /*
3054 * here we must allow for possibility of slice larger than orig array
3055 * and/or not adjacent to orig array subscripts
3056 */
3057 int oldlb = ARR_LBOUND(array)[0];
3058 int oldub = oldlb + ARR_DIMS(array)[0] - 1;
3059 int slicelb = Max(oldlb, lowerIndx[0]);
3060 int sliceub = Min(oldub, upperIndx[0]);
3061 char *oldarraydata = ARR_DATA_PTR(array);
3063
3064 /* count/size of old array entries that will go before the slice */
3065 itemsbefore = Min(slicelb, oldub + 1) - oldlb;
3068 elmlen, elmbyval, elmalign);
3069 /* count/size of old array entries that will be replaced by slice */
3070 if (slicelb > sliceub)
3071 {
3072 nolditems = 0;
3073 olditemsize = 0;
3074 }
3075 else
3076 {
3077 nolditems = sliceub - slicelb + 1;
3080 nolditems,
3081 elmlen, elmbyval, elmalign);
3082 }
3083 /* count/size of old array entries that will go after the slice */
3084 itemsafter = oldub + 1 - Max(sliceub + 1, oldlb);
3086 }
3087
3089
3092 newarray->ndim = ndim;
3093 newarray->dataoffset = newhasnulls ? overheadlen : 0;
3094 newarray->elemtype = ARR_ELEMTYPE(array);
3095 memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));
3096 memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));
3097
3098 if (ndim > 1)
3099 {
3100 /*
3101 * here we do not need to cope with extension of the array; it would
3102 * be a lot more complicated if we had to do so...
3103 */
3105 ndim, dim, lb,
3107 elmlen, elmbyval, elmalign);
3108 }
3109 else
3110 {
3111 /* fill in data */
3112 memcpy((char *) newarray + overheadlen,
3113 (char *) array + oldoverheadlen,
3114 lenbefore);
3115 memcpy((char *) newarray + overheadlen + lenbefore,
3117 newitemsize);
3119 (char *) array + oldoverheadlen + lenbefore + olditemsize,
3120 lenafter);
3121 /* fill in nulls bitmap if needed */
3122 if (newhasnulls)
3123 {
3126
3127 /* palloc0 above already marked any inserted positions as nulls */
3129 oldnullbitmap, 0,
3130 itemsbefore);
3133 nsrcitems);
3136 itemsafter);
3137 }
3138 }
3139
3140 return PointerGetDatum(newarray);
3141}
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 int array_nelems_size(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)
void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
#define Min(x, y)
Definition c.h:997
int errdetail(const char *fmt,...)
Definition elog.c:1216

References ARR_DATA_OFFSET, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, ARR_SIZE, array_bitmap_copy(), array_insert_slice(), array_nelems_size(), array_slice_size(), ArrayCheckBounds(), ArrayGetNItems(), Assert, construct_md_array(), DatumGetArrayTypeP, deconstruct_array(), ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), i, Max, MaxArraySize, MAXDIM, mda_get_range(), Min, nitems, palloc0(), pg_add_s32_overflow(), pg_sub_s32_overflow(), PointerGetDatum(), and SET_VARSIZE().

Referenced by array_subscript_assign_slice().

◆ ArrayCheckBounds()

void ArrayCheckBounds ( int  ndim,
const int dims,
const int lb 
)
extern

Definition at line 117 of file arrayutils.c.

118{
119 (void) ArrayCheckBoundsSafe(ndim, dims, lb, NULL);
120}
bool ArrayCheckBoundsSafe(int ndim, const int *dims, const int *lb, struct Node *escontext)
Definition arrayutils.c:127

References ArrayCheckBoundsSafe(), and fb().

Referenced by array_cat(), array_fill_internal(), array_recv(), array_set_element(), array_set_element_expanded(), array_set_slice(), construct_md_array(), ExecEvalArrayExpr(), and makeArrayResultArr().

◆ ArrayCheckBoundsSafe()

bool ArrayCheckBoundsSafe ( int  ndim,
const int dims,
const int lb,
struct Node escontext 
)
extern

Definition at line 127 of file arrayutils.c.

129{
130 int i;
131
132 for (i = 0; i < ndim; i++)
133 {
134 /* PG_USED_FOR_ASSERTS_ONLY prevents variable-isn't-read warnings */
136
137 if (pg_add_s32_overflow(dims[i], lb[i], &sum))
138 ereturn(escontext, false,
140 errmsg("array lower bound is too large: %d",
141 lb[i])));
142 }
143
144 return true;
145}
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:223
#define ereturn(context, dummy_value,...)
Definition elog.h:278

References ereturn, errcode(), errmsg(), fb(), i, pg_add_s32_overflow(), and PG_USED_FOR_ASSERTS_ONLY.

Referenced by ArrayCheckBounds().

◆ ArrayGetIntegerTypmods()

int32 * ArrayGetIntegerTypmods ( ArrayType arr,
int n 
)
extern

Definition at line 233 of file arrayutils.c.

234{
235 int32 *result;
236 Datum *elem_values;
237 int i;
238
239 if (ARR_ELEMTYPE(arr) != CSTRINGOID)
242 errmsg("typmod array must be type cstring[]")));
243
244 if (ARR_NDIM(arr) != 1)
247 errmsg("typmod array must be one-dimensional")));
248
249 if (array_contains_nulls(arr))
252 errmsg("typmod array must not contain nulls")));
253
254 deconstruct_array_builtin(arr, CSTRINGOID, &elem_values, NULL, n);
255
256 result = (int32 *) palloc(*n * sizeof(int32));
257
258 for (i = 0; i < *n; i++)
259 result[i] = pg_strtoint32(DatumGetCString(elem_values[i]));
260
261 pfree(elem_values);
262
263 return result;
264}
bool array_contains_nulls(const ArrayType *array)
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
int32 pg_strtoint32(const char *s)
Definition numutils.c:382
static char * DatumGetCString(Datum X)
Definition postgres.h:365

References ARR_ELEMTYPE, ARR_NDIM, array_contains_nulls(), DatumGetCString(), deconstruct_array_builtin(), ereport, errcode(), errmsg(), ERROR, fb(), i, palloc(), pfree(), and pg_strtoint32().

Referenced by anybit_typmodin(), anychar_typmodin(), anytime_typmodin(), anytimestamp_typmodin(), intervaltypmodin(), and numerictypmodin().

◆ ArrayGetNItems()

◆ ArrayGetNItemsSafe()

int ArrayGetNItemsSafe ( int  ndim,
const int dims,
struct Node escontext 
)
extern

Definition at line 67 of file arrayutils.c.

68{
69 int32 ret;
70 int i;
71
72 if (ndim <= 0)
73 return 0;
74 ret = 1;
75 for (i = 0; i < ndim; i++)
76 {
77 int64 prod;
78
79 /* A negative dimension implies that UB-LB overflowed ... */
80 if (dims[i] < 0)
81 ereturn(escontext, -1,
83 errmsg("array size exceeds the maximum allowed (%d)",
84 (int) MaxArraySize)));
85
86 prod = (int64) ret * (int64) dims[i];
87
88 ret = (int32) prod;
89 if ((int64) ret != prod)
90 ereturn(escontext, -1,
92 errmsg("array size exceeds the maximum allowed (%d)",
93 (int) MaxArraySize)));
94 }
95 Assert(ret >= 0);
96 if ((Size) ret > MaxArraySize)
97 ereturn(escontext, -1,
99 errmsg("array size exceeds the maximum allowed (%d)",
100 (int) MaxArraySize)));
101 return (int) ret;
102}
int64_t int64
Definition c.h:543
size_t Size
Definition c.h:619

References Assert, ereturn, errcode(), errmsg(), fb(), i, and MaxArraySize.

Referenced by ArrayGetNItems().

◆ ArrayGetOffset()

int ArrayGetOffset ( int  n,
const int dim,
const int lb,
const int indx 
)
extern

Definition at line 32 of file arrayutils.c.

33{
34 int i,
35 scale = 1,
36 offset = 0;
37
38 for (i = n - 1; i >= 0; i--)
39 {
40 offset += (indx[i] - lb[i]) * scale;
41 scale *= dim[i];
42 }
43 return offset;
44}
static int scale
Definition pgbench.c:182

References fb(), i, and scale.

Referenced by array_extract_slice(), array_get_element(), array_get_element_expanded(), array_insert_slice(), array_set_element(), array_set_element_expanded(), and array_slice_size().

◆ construct_array()

ArrayType * construct_array ( Datum elems,
int  nelems,
Oid  elmtype,
int  elmlen,
bool  elmbyval,
char  elmalign 
)
extern

Definition at line 3367 of file arrayfuncs.c.

3370{
3371 int dims[1];
3372 int lbs[1];
3373
3374 dims[0] = nelems;
3375 lbs[0] = 1;
3376
3377 return construct_md_array(elems, NULL, 1, dims, lbs,
3378 elmtype, elmlen, elmbyval, elmalign);
3379}

References construct_md_array(), and fb().

Referenced by ATExecAlterColumnType(), construct_array_builtin(), enum_range_internal(), serialize_expr_stats(), StoreAttrMissingVal(), and update_attstats().

◆ construct_array_builtin()

ArrayType * construct_array_builtin ( Datum elems,
int  nelems,
Oid  elmtype 
)
extern

Definition at line 3387 of file arrayfuncs.c.

3388{
3389 int elmlen;
3390 bool elmbyval;
3391 char elmalign;
3392
3393 switch (elmtype)
3394 {
3395 case CHAROID:
3396 elmlen = 1;
3397 elmbyval = true;
3399 break;
3400
3401 case CSTRINGOID:
3402 elmlen = -2;
3403 elmbyval = false;
3405 break;
3406
3407 case FLOAT4OID:
3408 elmlen = sizeof(float4);
3409 elmbyval = true;
3411 break;
3412
3413 case FLOAT8OID:
3414 elmlen = sizeof(float8);
3415 elmbyval = true;
3417 break;
3418
3419 case INT2OID:
3420 elmlen = sizeof(int16);
3421 elmbyval = true;
3423 break;
3424
3425 case INT4OID:
3426 elmlen = sizeof(int32);
3427 elmbyval = true;
3429 break;
3430
3431 case INT8OID:
3432 elmlen = sizeof(int64);
3433 elmbyval = true;
3435 break;
3436
3437 case NAMEOID:
3438 elmlen = NAMEDATALEN;
3439 elmbyval = false;
3441 break;
3442
3443 case OIDOID:
3444 case REGTYPEOID:
3445 elmlen = sizeof(Oid);
3446 elmbyval = true;
3448 break;
3449
3450 case TEXTOID:
3451 elmlen = -1;
3452 elmbyval = false;
3454 break;
3455
3456 case TIDOID:
3457 elmlen = sizeof(ItemPointerData);
3458 elmbyval = false;
3460 break;
3461
3462 case XIDOID:
3463 elmlen = sizeof(TransactionId);
3464 elmbyval = true;
3466 break;
3467
3468 default:
3469 elog(ERROR, "type %u not supported by construct_array_builtin()", elmtype);
3470 /* keep compiler quiet */
3471 elmlen = 0;
3472 elmbyval = false;
3473 elmalign = 0;
3474 }
3475
3476 return construct_array(elems, nelems, elmtype, elmlen, elmbyval, elmalign);
3477}
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
double float8
Definition c.h:644
int16_t int16
Definition c.h:541
float float4
Definition c.h:643
uint32 TransactionId
Definition c.h:666
#define NAMEDATALEN

References construct_array(), elog, ERROR, fb(), and NAMEDATALEN.

Referenced by AlterPolicy(), attribute_statistics_update(), bt_page_print_tuples(), build_regtype_array(), convert_requires_to_datum(), CreateConstraintEntry(), CreateFunction(), CreatePolicy(), CreateStatistics(), current_schemas(), executeItemOptUnwrapTarget(), extension_config_remove(), filter_list_to_array(), float4_accum(), float8_accum(), float8_combine(), float8_regr_accum(), float8_regr_combine(), get_environ(), get_hba_options(), GetWALBlockInfo(), gin_leafpage_items(), gin_page_opaque_info(), gist_page_opaque_info(), GUCArrayAdd(), GUCArrayDelete(), GUCArrayReset(), hash_metapage_info(), heap_tuple_infomask_flags(), hstore_akeys(), int_list_to_array(), interpret_function_parameter_list(), makeMultirangeConstructors(), pg_blocking_pids(), pg_extension_config_dump(), pg_get_logical_snapshot_info(), pg_safe_snapshot_blocking_pids(), pg_settings_get_flags(), publicationListToArray(), RemoveRoleFromObjectPolicy(), serialize_expr_stats(), show_trgm(), test_rls_hooks_permissive(), test_rls_hooks_restrictive(), ts_lexize(), tsvector_to_array(), tsvector_unnest(), typenameTypeMod(), and update_attstats().

◆ construct_empty_array()

◆ construct_empty_expanded_array()

ExpandedArrayHeader * construct_empty_expanded_array ( Oid  element_type,
MemoryContext  parentcontext,
ArrayMetaState metacache 
)
extern

Definition at line 3604 of file arrayfuncs.c.

3607{
3608 ArrayType *array = construct_empty_array(element_type);
3609 Datum d;
3610
3612 pfree(array);
3613 return (ExpandedArrayHeader *) DatumGetEOHP(d);
3614}
Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
ExpandedObjectHeader * DatumGetEOHP(Datum d)

References construct_empty_array(), DatumGetEOHP(), expand_array(), fb(), pfree(), and PointerGetDatum().

Referenced by fetch_array_arg_replace_nulls().

◆ construct_md_array()

ArrayType * construct_md_array ( Datum elems,
bool nulls,
int  ndims,
int dims,
int lbs,
Oid  elmtype,
int  elmlen,
bool  elmbyval,
char  elmalign 
)
extern

Definition at line 3500 of file arrayfuncs.c.

3506{
3507 ArrayType *result;
3508 bool hasnulls;
3509 int32 nbytes;
3510 int32 dataoffset;
3511 int i;
3512 int nelems;
3513 uint8 elmalignby = typalign_to_alignby(elmalign);
3514
3515 if (ndims < 0) /* we do allow zero-dimension arrays */
3516 ereport(ERROR,
3518 errmsg("invalid number of dimensions: %d", ndims)));
3519 if (ndims > MAXDIM)
3520 ereport(ERROR,
3522 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
3523 ndims, MAXDIM)));
3524
3525 /* This checks for overflow of the array dimensions */
3526 nelems = ArrayGetNItems(ndims, dims);
3527 ArrayCheckBounds(ndims, dims, lbs);
3528
3529 /* if ndims <= 0 or any dims[i] == 0, return empty array */
3530 if (nelems <= 0)
3532
3533 /* compute required space */
3534 nbytes = 0;
3535 hasnulls = false;
3536 for (i = 0; i < nelems; i++)
3537 {
3538 if (nulls && nulls[i])
3539 {
3540 hasnulls = true;
3541 continue;
3542 }
3543 /* make sure data is not toasted */
3544 if (elmlen == -1)
3545 elems[i] = PointerGetDatum(PG_DETOAST_DATUM(elems[i]));
3546 nbytes = att_addlength_datum(nbytes, elmlen, elems[i]);
3547 nbytes = att_nominal_alignby(nbytes, elmalignby);
3548 /* check for overflow of total request */
3549 if (!AllocSizeIsValid(nbytes))
3550 ereport(ERROR,
3552 errmsg("array size exceeds the maximum allowed (%zu)",
3553 MaxAllocSize)));
3554 }
3555
3556 /* Allocate and initialize result array */
3557 if (hasnulls)
3558 {
3559 dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nelems);
3560 nbytes += dataoffset;
3561 }
3562 else
3563 {
3564 dataoffset = 0; /* marker for no null bitmap */
3565 nbytes += ARR_OVERHEAD_NONULLS(ndims);
3566 }
3567 result = (ArrayType *) palloc0(nbytes);
3568 SET_VARSIZE(result, nbytes);
3569 result->ndim = ndims;
3570 result->dataoffset = dataoffset;
3571 result->elemtype = elmtype;
3572 memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
3573 memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
3574
3575 CopyArrayEls(result,
3576 elems, nulls, nelems,
3577 elmlen, elmbyval, elmalign,
3578 false);
3579
3580 return result;
3581}

References AllocSizeIsValid, ARR_DIMS, ARR_LBOUND, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, ArrayCheckBounds(), ArrayGetNItems(), att_addlength_datum, att_nominal_alignby, construct_empty_array(), CopyArrayEls(), ArrayType::dataoffset, ArrayType::elemtype, ereport, errcode(), errmsg(), ERROR, fb(), i, MaxAllocSize, MAXDIM, ArrayType::ndim, palloc0(), PG_DETOAST_DATUM, PointerGetDatum(), SET_VARSIZE(), and typalign_to_alignby().

Referenced by array_iterate(), array_reverse_n(), array_set_element(), array_set_slice(), array_shuffle_n(), build_regexp_match_result(), build_test_info_result(), build_test_match_result(), construct_array(), ExecEvalArrayExpr(), hstore_avals(), hstore_slice_to_array(), hstore_to_array_internal(), make_SAOP_expr(), makeMdArrayResult(), percentile_cont_multi_final_common(), percentile_disc_multi_final(), plpgsql_fulfill_promise(), and strlist_to_textarray().

◆ CopyArrayEls()

void CopyArrayEls ( ArrayType array,
const Datum values,
const bool nulls,
int  nitems,
int  typlen,
bool  typbyval,
char  typalign,
bool  freedata 
)
extern

Definition at line 965 of file arrayfuncs.c.

973{
974 char *p = ARR_DATA_PTR(array);
975 bits8 *bitmap = ARR_NULLBITMAP(array);
976 int bitval = 0;
977 int bitmask = 1;
978 uint8 typalignby = typalign_to_alignby(typalign);
979 int i;
980
981 if (typbyval)
982 freedata = false;
983
984 for (i = 0; i < nitems; i++)
985 {
986 if (nulls && nulls[i])
987 {
988 if (!bitmap) /* shouldn't happen */
989 elog(ERROR, "null array element where not supported");
990 /* bitmap bit stays 0 */
991 }
992 else
993 {
994 bitval |= bitmask;
995 p += ArrayCastAndSet(values[i], typlen, typbyval, typalignby, p);
996 if (freedata)
998 }
999 if (bitmap)
1000 {
1001 bitmask <<= 1;
1002 if (bitmask == 0x100)
1003 {
1004 *bitmap++ = bitval;
1005 bitval = 0;
1006 bitmask = 1;
1007 }
1008 }
1009 }
1010
1011 if (bitmap && bitmask != 1)
1012 *bitmap = bitval;
1013}

References ARR_DATA_PTR, ARR_NULLBITMAP, ArrayCastAndSet(), DatumGetPointer(), elog, ERROR, fb(), i, nitems, pfree(), typalign, typalign_to_alignby(), and values.

Referenced by array_in(), array_map(), array_recv(), array_replace_internal(), construct_md_array(), and EA_flatten_into().

◆ DatumGetAnyArrayP()

AnyArrayType * DatumGetAnyArrayP ( Datum  d)
extern

Definition at line 403 of file array_expanded.c.

404{
406
407 /*
408 * If it's an expanded array (RW or RO), return the header pointer.
409 */
411 {
413 Assert(eah->ea_magic == EA_MAGIC);
414 return (AnyArrayType *) eah;
415 }
416
417 /* Else do regular detoasting as needed */
418 return (AnyArrayType *) PG_DETOAST_DATUM(d);
419}
#define EA_MAGIC
Definition array.h:113

References Assert, DatumGetEOHP(), DatumGetPointer(), EA_MAGIC, fb(), PG_DETOAST_DATUM, and VARATT_IS_EXTERNAL_EXPANDED().

Referenced by array_map().

◆ DatumGetExpandedArray()

ExpandedArrayHeader * DatumGetExpandedArray ( Datum  d)
extern

Definition at line 354 of file array_expanded.c.

355{
356 /* If it's a writable expanded array already, just return it */
358 {
360
361 Assert(eah->ea_magic == EA_MAGIC);
362 return eah;
363 }
364
365 /* Else expand the hard way */
367 return (ExpandedArrayHeader *) DatumGetEOHP(d);
368}
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
static bool VARATT_IS_EXTERNAL_EXPANDED_RW(const void *PTR)
Definition varatt.h:382

References Assert, CurrentMemoryContext, DatumGetEOHP(), DatumGetPointer(), EA_MAGIC, expand_array(), fb(), and VARATT_IS_EXTERNAL_EXPANDED_RW().

Referenced by array_set_element_expanded(), and statext_expressions_load().

◆ DatumGetExpandedArrayX()

ExpandedArrayHeader * DatumGetExpandedArrayX ( Datum  d,
ArrayMetaState metacache 
)
extern

Definition at line 374 of file array_expanded.c.

375{
376 /* If it's a writable expanded array already, just return it */
378 {
380
381 Assert(eah->ea_magic == EA_MAGIC);
382 /* Update cache if provided */
383 if (metacache)
384 {
385 metacache->element_type = eah->element_type;
386 metacache->typlen = eah->typlen;
387 metacache->typbyval = eah->typbyval;
388 metacache->typalign = eah->typalign;
389 }
390 return eah;
391 }
392
393 /* Else expand using caller's cache if any */
395 return (ExpandedArrayHeader *) DatumGetEOHP(d);
396}

References Assert, CurrentMemoryContext, DatumGetEOHP(), DatumGetPointer(), EA_MAGIC, expand_array(), fb(), and VARATT_IS_EXTERNAL_EXPANDED_RW().

◆ deconstruct_array()

void deconstruct_array ( const ArrayType array,
Oid  elmtype,
int  elmlen,
bool  elmbyval,
char  elmalign,
Datum **  elemsp,
bool **  nullsp,
int nelemsp 
)
extern

Definition at line 3638 of file arrayfuncs.c.

3642{
3643 Datum *elems;
3644 bool *nulls;
3645 int nelems;
3646 char *p;
3647 bits8 *bitmap;
3648 int bitmask;
3649 int i;
3650 uint8 elmalignby = typalign_to_alignby(elmalign);
3651
3652 Assert(ARR_ELEMTYPE(array) == elmtype);
3653
3654 nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
3655 *elemsp = elems = palloc_array(Datum, nelems);
3656 if (nullsp)
3657 *nullsp = nulls = palloc0_array(bool, nelems);
3658 else
3659 nulls = NULL;
3660 *nelemsp = nelems;
3661
3662 p = ARR_DATA_PTR(array);
3663 bitmap = ARR_NULLBITMAP(array);
3664 bitmask = 1;
3665
3666 for (i = 0; i < nelems; i++)
3667 {
3668 /* Get source element, checking for NULL */
3669 if (bitmap && (*bitmap & bitmask) == 0)
3670 {
3671 elems[i] = (Datum) 0;
3672 if (nulls)
3673 nulls[i] = true;
3674 else
3675 ereport(ERROR,
3677 errmsg("null array element not allowed in this context")));
3678 }
3679 else
3680 {
3681 elems[i] = fetch_att(p, elmbyval, elmlen);
3682 p = att_addlength_pointer(p, elmlen, p);
3683 p = (char *) att_nominal_alignby(p, elmalignby);
3684 }
3685
3686 /* advance bitmap pointer if any */
3687 if (bitmap)
3688 {
3689 bitmask <<= 1;
3690 if (bitmask == 0x100)
3691 {
3692 bitmap++;
3693 bitmask = 1;
3694 }
3695 }
3696 }
3697}
#define palloc_array(type, count)
Definition fe_memutils.h:76
#define palloc0_array(type, count)
Definition fe_memutils.h:77

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, ARR_NULLBITMAP, ArrayGetNItems(), Assert, att_addlength_pointer, att_nominal_alignby, ereport, errcode(), errmsg(), ERROR, fb(), fetch_att(), i, palloc0_array, palloc_array, and typalign_to_alignby().

Referenced by _bt_preprocess_array_keys(), array_contain_compare(), array_reverse_n(), array_set_slice(), array_shuffle_n(), array_to_json_internal(), array_to_jsonb_internal(), arrayconst_startup_fn(), compute_array_stats(), deconstruct_array_builtin(), deconstruct_expanded_array(), ExecIndexEvalArrayKeys(), extract_variadic_args(), get_attstatsslot(), ginarrayextract(), gincost_scalararrayopexpr(), ginqueryarrayextract(), map_sql_value_to_xml_value(), match_clause_to_partition_key(), mcelem_array_selec(), mcv_get_match_bitmap(), multirange_constructor2(), plperl_ref_from_pg_array(), satisfies_hash_partition(), scalararraysel(), test_bms_overlap_list(), and text_format().

◆ deconstruct_array_builtin()

void deconstruct_array_builtin ( const ArrayType array,
Oid  elmtype,
Datum **  elemsp,
bool **  nullsp,
int nelemsp 
)
extern

Definition at line 3705 of file arrayfuncs.c.

3708{
3709 int elmlen;
3710 bool elmbyval;
3711 char elmalign;
3712
3713 switch (elmtype)
3714 {
3715 case CHAROID:
3716 elmlen = 1;
3717 elmbyval = true;
3719 break;
3720
3721 case CSTRINGOID:
3722 elmlen = -2;
3723 elmbyval = false;
3725 break;
3726
3727 case FLOAT8OID:
3728 elmlen = sizeof(float8);
3729 elmbyval = true;
3731 break;
3732
3733 case INT2OID:
3734 elmlen = sizeof(int16);
3735 elmbyval = true;
3737 break;
3738
3739 case OIDOID:
3740 elmlen = sizeof(Oid);
3741 elmbyval = true;
3743 break;
3744
3745 case TEXTOID:
3746 elmlen = -1;
3747 elmbyval = false;
3749 break;
3750
3751 case TIDOID:
3752 elmlen = sizeof(ItemPointerData);
3753 elmbyval = false;
3755 break;
3756
3757 default:
3758 elog(ERROR, "type %u not supported by deconstruct_array_builtin()", elmtype);
3759 /* keep compiler quiet */
3760 elmlen = 0;
3761 elmbyval = false;
3762 elmalign = 0;
3763 }
3764
3765 deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, elemsp, nullsp, nelemsp);
3766}

References deconstruct_array(), elog, ERROR, and fb().

Referenced by array_to_tsvector(), ArrayGetIntegerTypmods(), binary_upgrade_create_empty_extension(), build_function_result_tupdesc_d(), DecodeTextArrayToBitmapset(), decompile_column_index_array(), extension_config_remove(), generateClonedIndexStmt(), get_func_arg_info(), get_func_input_arg_names(), get_func_result_name(), get_jsonb_path_all(), get_path_all(), get_reloptions(), ghstore_consistent(), gin_extract_hstore_query(), gin_extract_jsonb_query(), hstore_from_array(), hstore_from_arrays(), hstore_slice_to_array(), hstoreArrayToPairs(), import_mcv(), json_object(), json_object_two_arg(), jsonb_delete_array(), jsonb_delete_path(), jsonb_exists_all(), jsonb_exists_any(), jsonb_insert(), jsonb_object(), jsonb_object_two_arg(), jsonb_set(), oid_array_to_list(), parse_key_value_arrays(), parseRelOptionsInternal(), percentile_cont_multi_final_common(), percentile_disc_multi_final(), pg_get_constraintdef_worker(), pg_get_object_address(), pg_get_publication_tables(), pg_logical_slot_get_changes_guts(), textarray_to_stringlist(), textarray_to_strvaluelist(), TidListEval(), transformRelOptions(), tsvector_delete_arr(), tsvector_filter(), tsvector_setweight_by_filter(), untransformRelOptions(), and worker_spi_launch().

◆ deconstruct_expanded_array()

void deconstruct_expanded_array ( ExpandedArrayHeader eah)
extern

Definition at line 426 of file array_expanded.c.

427{
428 if (eah->dvalues == NULL)
429 {
430 MemoryContext oldcxt = MemoryContextSwitchTo(eah->hdr.eoh_context);
431 Datum *dvalues;
432 bool *dnulls;
433 int nelems;
434
435 dnulls = NULL;
436 deconstruct_array(eah->fvalue,
437 eah->element_type,
438 eah->typlen, eah->typbyval, eah->typalign,
439 &dvalues,
440 ARR_HASNULL(eah->fvalue) ? &dnulls : NULL,
441 &nelems);
442
443 /*
444 * Update header only after successful completion of this step. If
445 * deconstruct_array fails partway through, worst consequence is some
446 * leaked memory in the object's context. If the caller fails at a
447 * later point, that's fine, since the deconstructed representation is
448 * valid anyhow.
449 */
450 eah->dvalues = dvalues;
451 eah->dnulls = dnulls;
452 eah->dvalueslen = eah->nelems = nelems;
454 }
455}

References ARR_HASNULL, deconstruct_array(), fb(), and MemoryContextSwitchTo().

Referenced by array_contain_compare(), array_get_element_expanded(), array_set_element_expanded(), and statext_expressions_load().

◆ expand_array()

Datum expand_array ( Datum  arraydatum,
MemoryContext  parentcontext,
ArrayMetaState metacache 
)
extern

Definition at line 50 of file array_expanded.c.

52{
53 ArrayType *array;
58
59 /*
60 * Allocate private context for expanded object. We start by assuming
61 * that the array won't be very large; but if it does grow a lot, don't
62 * constrain aset.c's large-context behavior.
63 */
65 "expanded array",
67
68 /* Set up expanded array header */
71
73 eah->ea_magic = EA_MAGIC;
74
75 /* If the source is an expanded array, we may be able to optimize */
77 {
79
80 Assert(oldeah->ea_magic == EA_MAGIC);
81
82 /*
83 * Update caller's cache if provided; we don't need it this time, but
84 * next call might be for a non-expanded source array. Furthermore,
85 * if the caller didn't provide a cache area, use some local storage
86 * to cache anyway, thereby avoiding a catalog lookup in the case
87 * where we fall through to the flat-copy code path.
88 */
89 if (metacache == NULL)
91 metacache->element_type = oldeah->element_type;
92 metacache->typlen = oldeah->typlen;
93 metacache->typbyval = oldeah->typbyval;
94 metacache->typalign = oldeah->typalign;
95
96 /*
97 * If element type is pass-by-value and we have a Datum-array
98 * representation, just copy the source's metadata and Datum/isnull
99 * arrays. The original flat array, if present at all, adds no
100 * additional information so we need not copy it.
101 */
102 if (oldeah->typbyval && oldeah->dvalues != NULL)
103 {
105 /* return a R/W pointer to the expanded array */
106 return EOHPGetRWDatum(&eah->hdr);
107 }
108
109 /*
110 * Otherwise, either we have only a flat representation or the
111 * elements are pass-by-reference. In either case, the best thing
112 * seems to be to copy the source as a flat representation and then
113 * deconstruct that later if necessary. For the pass-by-ref case, we
114 * could perhaps save some cycles with custom code that generates the
115 * deconstructed representation in parallel with copying the values,
116 * but it would be a lot of extra code for fairly marginal gain. So,
117 * fall through into the flat-source code path.
118 */
119 }
120
121 /*
122 * Detoast and copy source array into private context, as a flat array.
123 *
124 * Note that this coding risks leaking some memory in the private context
125 * if we have to fetch data from a TOAST table; however, experimentation
126 * says that the leak is minimal. Doing it this way saves a copy step,
127 * which seems worthwhile, especially if the array is large enough to need
128 * external storage.
129 */
133
134 eah->ndims = ARR_NDIM(array);
135 /* note these pointers point into the fvalue header! */
136 eah->dims = ARR_DIMS(array);
137 eah->lbound = ARR_LBOUND(array);
138
139 /* Save array's element-type data for possible use later */
140 eah->element_type = ARR_ELEMTYPE(array);
141 if (metacache && metacache->element_type == eah->element_type)
142 {
143 /* We have a valid cache of representational data */
144 eah->typlen = metacache->typlen;
145 eah->typbyval = metacache->typbyval;
146 eah->typalign = metacache->typalign;
147 }
148 else
149 {
150 /* No, so look it up */
151 get_typlenbyvalalign(eah->element_type,
152 &eah->typlen,
153 &eah->typbyval,
154 &eah->typalign);
155 /* Update cache if provided */
156 if (metacache)
157 {
158 metacache->element_type = eah->element_type;
159 metacache->typlen = eah->typlen;
160 metacache->typbyval = eah->typbyval;
161 metacache->typalign = eah->typalign;
162 }
163 }
164
165 /* we don't make a deconstructed representation now */
166 eah->dvalues = NULL;
167 eah->dnulls = NULL;
168 eah->dvalueslen = 0;
169 eah->nelems = 0;
170 eah->flat_size = 0;
171
172 /* remember we have a flat representation */
173 eah->fvalue = array;
174 eah->fstartptr = ARR_DATA_PTR(array);
175 eah->fendptr = ((char *) array) + ARR_SIZE(array);
176
177 /* return a R/W pointer to the expanded array */
178 return EOHPGetRWDatum(&eah->hdr);
179}
#define DatumGetArrayTypePCopy(X)
Definition array.h:262
static void copy_byval_expanded_array(ExpandedArrayHeader *eah, ExpandedArrayHeader *oldeah)
static const ExpandedObjectMethods EA_methods
void EOH_init_header(ExpandedObjectHeader *eohptr, const ExpandedObjectMethods *methods, MemoryContext obj_context)
static Datum EOHPGetRWDatum(const struct ExpandedObjectHeader *eohptr)
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_START_SMALL_SIZES
Definition memutils.h:177

References ALLOCSET_START_SMALL_SIZES, AllocSetContextCreate, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, ARR_SIZE, Assert, copy_byval_expanded_array(), DatumGetArrayTypePCopy, DatumGetEOHP(), DatumGetPointer(), EA_MAGIC, EA_methods, EOH_init_header(), EOHPGetRWDatum(), fb(), get_typlenbyvalalign(), MemoryContextAlloc(), MemoryContextSwitchTo(), and VARATT_IS_EXTERNAL_EXPANDED().

Referenced by construct_empty_expanded_array(), DatumGetExpandedArray(), DatumGetExpandedArrayX(), exec_assign_value(), and plpgsql_exec_function().

◆ initArrayResult()

ArrayBuildState * initArrayResult ( Oid  element_type,
MemoryContext  rcontext,
bool  subcontext 
)
extern

Definition at line 5302 of file arrayfuncs.c.

5303{
5304 /*
5305 * When using a subcontext, we can afford to start with a somewhat larger
5306 * initial array size. Without subcontexts, we'd better hope that most of
5307 * the states stay small ...
5308 */
5309 return initArrayResultWithSize(element_type, rcontext, subcontext,
5310 subcontext ? 64 : 8);
5311}
ArrayBuildState * initArrayResultWithSize(Oid element_type, MemoryContext rcontext, bool subcontext, int initsize)

References fb(), and initArrayResultWithSize().

Referenced by accumArrayResult(), array_agg_transfn(), array_positions(), array_to_datum_internal(), daitch_mokotoff(), initArrayResultAny(), multirange_agg_transfn(), PLySequence_ToArray_recurse(), populate_array(), range_agg_transfn(), tuple_data_split_internal(), and xpath().

◆ initArrayResultAny()

ArrayBuildStateAny * initArrayResultAny ( Oid  input_type,
MemoryContext  rcontext,
bool  subcontext 
)
extern

Definition at line 5791 of file arrayfuncs.c.

5792{
5793 ArrayBuildStateAny *astate;
5794
5795 /*
5796 * int2vector and oidvector will satisfy both get_element_type and
5797 * get_array_type. We prefer to treat them as scalars, to be consistent
5798 * with get_promoted_array_type. Hence, check get_array_type not
5799 * get_element_type.
5800 */
5802 {
5803 /* Array case */
5804 ArrayBuildStateArr *arraystate;
5805
5806 arraystate = initArrayResultArr(input_type, InvalidOid, rcontext, subcontext);
5807 astate = (ArrayBuildStateAny *)
5808 MemoryContextAlloc(arraystate->mcontext,
5809 sizeof(ArrayBuildStateAny));
5810 astate->scalarstate = NULL;
5811 astate->arraystate = arraystate;
5812 }
5813 else
5814 {
5815 /* Scalar case */
5816 ArrayBuildState *scalarstate;
5817
5818 scalarstate = initArrayResult(input_type, rcontext, subcontext);
5819 astate = (ArrayBuildStateAny *)
5820 MemoryContextAlloc(scalarstate->mcontext,
5821 sizeof(ArrayBuildStateAny));
5822 astate->scalarstate = scalarstate;
5823 astate->arraystate = NULL;
5824 }
5825
5826 return astate;
5827}
#define OidIsValid(objectId)
Definition c.h:788
Oid get_array_type(Oid typid)
Definition lsyscache.c:2937

References ArrayBuildStateAny::arraystate, fb(), get_array_type(), initArrayResult(), initArrayResultArr(), InvalidOid, ArrayBuildState::mcontext, ArrayBuildStateArr::mcontext, MemoryContextAlloc(), OidIsValid, and ArrayBuildStateAny::scalarstate.

Referenced by accumArrayResultAny(), ExecScanSubPlan(), and ExecSetParamPlan().

◆ initArrayResultArr()

ArrayBuildStateArr * initArrayResultArr ( Oid  array_type,
Oid  element_type,
MemoryContext  rcontext,
bool  subcontext 
)
extern

Definition at line 5513 of file arrayfuncs.c.

5515{
5516 ArrayBuildStateArr *astate;
5517 MemoryContext arr_context = rcontext; /* by default use the parent ctx */
5518
5519 /* Lookup element type, unless element_type already provided */
5520 if (!OidIsValid(element_type))
5521 {
5522 element_type = get_element_type(array_type);
5523
5524 if (!OidIsValid(element_type))
5525 ereport(ERROR,
5527 errmsg("data type %s is not an array type",
5528 format_type_be(array_type))));
5529 }
5530
5531 /* Make a temporary context to hold all the junk */
5532 if (subcontext)
5534 "accumArrayResultArr",
5536
5537 /* Note we initialize all fields to zero */
5538 astate = (ArrayBuildStateArr *)
5540 astate->mcontext = arr_context;
5541 astate->private_cxt = subcontext;
5542
5543 /* Save relevant datatype information */
5544 astate->array_type = array_type;
5545 astate->element_type = element_type;
5546
5547 return astate;
5548}
char * format_type_be(Oid type_oid)
Oid get_element_type(Oid typid)
Definition lsyscache.c:2909
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1266
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ArrayBuildStateArr::array_type, ArrayBuildStateArr::element_type, ereport, errcode(), errmsg(), ERROR, fb(), format_type_be(), get_element_type(), ArrayBuildStateArr::mcontext, MemoryContextAllocZero(), OidIsValid, and ArrayBuildStateArr::private_cxt.

Referenced by accumArrayResultArr(), array_agg_array_combine(), array_agg_array_deserialize(), array_agg_array_transfn(), and initArrayResultAny().

◆ initArrayResultWithSize()

ArrayBuildState * initArrayResultWithSize ( Oid  element_type,
MemoryContext  rcontext,
bool  subcontext,
int  initsize 
)
extern

Definition at line 5319 of file arrayfuncs.c.

5321{
5322 ArrayBuildState *astate;
5324
5325 /* Make a temporary context to hold all the junk */
5326 if (subcontext)
5328 "accumArrayResult",
5330
5331 astate = (ArrayBuildState *)
5333 astate->mcontext = arr_context;
5334 astate->private_cxt = subcontext;
5335 astate->alen = initsize;
5336 astate->dvalues = (Datum *)
5337 MemoryContextAlloc(arr_context, astate->alen * sizeof(Datum));
5338 astate->dnulls = (bool *)
5339 MemoryContextAlloc(arr_context, astate->alen * sizeof(bool));
5340 astate->nelems = 0;
5341 astate->element_type = element_type;
5342 get_typlenbyvalalign(element_type,
5343 &astate->typlen,
5344 &astate->typbyval,
5345 &astate->typalign);
5346
5347 return astate;
5348}
bool private_cxt
Definition array.h:198
char typalign
Definition array.h:197

References ArrayBuildState::alen, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ArrayBuildState::dnulls, ArrayBuildState::dvalues, ArrayBuildState::element_type, fb(), get_typlenbyvalalign(), ArrayBuildState::mcontext, MemoryContextAlloc(), ArrayBuildState::nelems, ArrayBuildState::private_cxt, ArrayBuildState::typalign, ArrayBuildState::typbyval, and ArrayBuildState::typlen.

Referenced by array_agg_combine(), array_agg_deserialize(), and initArrayResult().

◆ makeArrayResult()

Datum makeArrayResult ( ArrayBuildState astate,
MemoryContext  rcontext 
)
extern

Definition at line 5429 of file arrayfuncs.c.

5431{
5432 int ndims;
5433 int dims[1];
5434 int lbs[1];
5435
5436 /* If no elements were presented, we want to create an empty array */
5437 ndims = (astate->nelems > 0) ? 1 : 0;
5438 dims[0] = astate->nelems;
5439 lbs[0] = 1;
5440
5441 return makeMdArrayResult(astate, ndims, dims, lbs, rcontext,
5442 astate->private_cxt);
5443}
Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)

References fb(), makeMdArrayResult(), ArrayBuildState::nelems, and ArrayBuildState::private_cxt.

Referenced by array_positions(), brin_minmax_multi_summary_out(), daitch_mokotoff(), dblink_get_connections(), optionListToArray(), parse_ident(), pg_get_statisticsobjdef_expressions(), pg_stats_ext_mcvlist_items(), regexp_split_to_array(), serialize_expr_stats(), text_to_array(), transformRelOptions(), tuple_data_split_internal(), and xpath().

◆ makeArrayResultAny()

Datum makeArrayResultAny ( ArrayBuildStateAny astate,
MemoryContext  rcontext,
bool  release 
)
extern

Definition at line 5866 of file arrayfuncs.c.

5868{
5869 Datum result;
5870
5871 if (astate->scalarstate)
5872 {
5873 /* Must use makeMdArrayResult to support "release" parameter */
5874 int ndims;
5875 int dims[1];
5876 int lbs[1];
5877
5878 /* If no elements were presented, we want to create an empty array */
5879 ndims = (astate->scalarstate->nelems > 0) ? 1 : 0;
5880 dims[0] = astate->scalarstate->nelems;
5881 lbs[0] = 1;
5882
5883 result = makeMdArrayResult(astate->scalarstate, ndims, dims, lbs,
5884 rcontext, release);
5885 }
5886 else
5887 {
5888 result = makeArrayResultArr(astate->arraystate,
5889 rcontext, release);
5890 }
5891 return result;
5892}
Datum makeArrayResultArr(ArrayBuildStateArr *astate, MemoryContext rcontext, bool release)

References ArrayBuildStateAny::arraystate, fb(), makeArrayResultArr(), makeMdArrayResult(), ArrayBuildState::nelems, and ArrayBuildStateAny::scalarstate.

Referenced by array_sort_internal(), ExecScanSubPlan(), and ExecSetParamPlan().

◆ makeArrayResultArr()

Datum makeArrayResultArr ( ArrayBuildStateArr astate,
MemoryContext  rcontext,
bool  release 
)
extern

Definition at line 5712 of file arrayfuncs.c.

5715{
5716 ArrayType *result;
5717 MemoryContext oldcontext;
5718
5719 /* Build the final array result in rcontext */
5720 oldcontext = MemoryContextSwitchTo(rcontext);
5721
5722 if (astate->ndims == 0)
5723 {
5724 /* No inputs, return empty array */
5725 result = construct_empty_array(astate->element_type);
5726 }
5727 else
5728 {
5729 int dataoffset,
5730 nbytes;
5731
5732 /* Check for overflow of the array dimensions */
5733 (void) ArrayGetNItems(astate->ndims, astate->dims);
5734 ArrayCheckBounds(astate->ndims, astate->dims, astate->lbs);
5735
5736 /* Compute required space */
5737 nbytes = astate->nbytes;
5738 if (astate->nullbitmap != NULL)
5739 {
5740 dataoffset = ARR_OVERHEAD_WITHNULLS(astate->ndims, astate->nitems);
5741 nbytes += dataoffset;
5742 }
5743 else
5744 {
5745 dataoffset = 0;
5746 nbytes += ARR_OVERHEAD_NONULLS(astate->ndims);
5747 }
5748
5749 result = (ArrayType *) palloc0(nbytes);
5750 SET_VARSIZE(result, nbytes);
5751 result->ndim = astate->ndims;
5752 result->dataoffset = dataoffset;
5753 result->elemtype = astate->element_type;
5754
5755 memcpy(ARR_DIMS(result), astate->dims, astate->ndims * sizeof(int));
5756 memcpy(ARR_LBOUND(result), astate->lbs, astate->ndims * sizeof(int));
5757 memcpy(ARR_DATA_PTR(result), astate->data, astate->nbytes);
5758
5759 if (astate->nullbitmap != NULL)
5761 astate->nullbitmap, 0,
5762 astate->nitems);
5763 }
5764
5765 MemoryContextSwitchTo(oldcontext);
5766
5767 /* Clean up all the junk */
5768 if (release)
5769 {
5770 Assert(astate->private_cxt);
5772 }
5773
5774 return PointerGetDatum(result);
5775}
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472

References ARR_DATA_PTR, ARR_DIMS, ARR_LBOUND, ARR_NULLBITMAP, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, array_bitmap_copy(), ArrayCheckBounds(), ArrayGetNItems(), Assert, construct_empty_array(), ArrayBuildStateArr::data, ArrayType::dataoffset, ArrayBuildStateArr::dims, ArrayBuildStateArr::element_type, ArrayType::elemtype, fb(), ArrayBuildStateArr::lbs, ArrayBuildStateArr::mcontext, MemoryContextDelete(), MemoryContextSwitchTo(), ArrayBuildStateArr::nbytes, ArrayType::ndim, ArrayBuildStateArr::ndims, ArrayBuildStateArr::nitems, ArrayBuildStateArr::nullbitmap, palloc0(), PointerGetDatum(), ArrayBuildStateArr::private_cxt, and SET_VARSIZE().

Referenced by array_agg_array_finalfn(), and makeArrayResultAny().

◆ makeMdArrayResult()

Datum makeMdArrayResult ( ArrayBuildState astate,
int  ndims,
int dims,
int lbs,
MemoryContext  rcontext,
bool  release 
)
extern

Definition at line 5461 of file arrayfuncs.c.

5467{
5468 ArrayType *result;
5469 MemoryContext oldcontext;
5470
5471 /* Build the final array result in rcontext */
5472 oldcontext = MemoryContextSwitchTo(rcontext);
5473
5474 result = construct_md_array(astate->dvalues,
5475 astate->dnulls,
5476 ndims,
5477 dims,
5478 lbs,
5479 astate->element_type,
5480 astate->typlen,
5481 astate->typbyval,
5482 astate->typalign);
5483
5484 MemoryContextSwitchTo(oldcontext);
5485
5486 /* Clean up all the junk */
5487 if (release)
5488 {
5489 Assert(astate->private_cxt);
5491 }
5492
5493 return PointerGetDatum(result);
5494}

References Assert, construct_md_array(), ArrayBuildState::dnulls, ArrayBuildState::dvalues, ArrayBuildState::element_type, fb(), ArrayBuildState::mcontext, MemoryContextDelete(), MemoryContextSwitchTo(), PointerGetDatum(), ArrayBuildState::private_cxt, ArrayBuildState::typalign, ArrayBuildState::typbyval, and ArrayBuildState::typlen.

Referenced by array_agg_finalfn(), makeArrayResult(), makeArrayResultAny(), plperl_array_to_datum(), PLySequence_ToArray(), and populate_array().

◆ mda_get_offset_values()

void mda_get_offset_values ( int  n,
int dist,
const int prod,
const int span 
)
extern

Definition at line 183 of file arrayutils.c.

184{
185 int i,
186 j;
187
188 dist[n - 1] = 0;
189 for (j = n - 2; j >= 0; j--)
190 {
191 dist[j] = prod[j] - 1;
192 for (i = j + 1; i < n; i++)
193 dist[j] -= (span[i] - 1) * prod[i];
194 }
195}
int j
Definition isn.c:78

References fb(), i, and j.

Referenced by array_extract_slice(), array_insert_slice(), and array_slice_size().

◆ mda_get_prod()

void mda_get_prod ( int  n,
const int range,
int prod 
)
extern

Definition at line 167 of file arrayutils.c.

168{
169 int i;
170
171 prod[n - 1] = 1;
172 for (i = n - 2; i >= 0; i--)
173 prod[i] = prod[i + 1] * range[i + 1];
174}
static struct cvec * range(struct vars *v, chr a, chr b, int cases)

References i, and range().

Referenced by array_extract_slice(), array_insert_slice(), and array_slice_size().

◆ mda_get_range()

void mda_get_range ( int  n,
int span,
const int st,
const int endp 
)
extern

Definition at line 153 of file arrayutils.c.

154{
155 int i;
156
157 for (i = 0; i < n; i++)
158 span[i] = endp[i] - st[i] + 1;
159}

References fb(), and i.

Referenced by array_extract_slice(), array_get_slice(), array_insert_slice(), array_set_slice(), and array_slice_size().

◆ mda_next_tuple()

int mda_next_tuple ( int  n,
int curr,
const int span 
)
extern

Definition at line 208 of file arrayutils.c.

209{
210 int i;
211
212 if (n <= 0)
213 return -1;
214
215 curr[n - 1] = (curr[n - 1] + 1) % span[n - 1];
216 for (i = n - 1; i && curr[i] == 0; i--)
217 curr[i - 1] = (curr[i - 1] + 1) % span[i - 1];
218
219 if (i)
220 return i;
221 if (curr[0])
222 return 0;
223
224 return -1;
225}

References fb(), and i.

Referenced by array_extract_slice(), array_insert_slice(), and array_slice_size().

Variable Documentation

◆ Array_nulls

PGDLLIMPORT bool Array_nulls
extern

Definition at line 44 of file arrayfuncs.c.

Referenced by ReadArrayToken().