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:565

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:838
#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 5365 of file arrayfuncs.c.

5369{
5370 MemoryContext oldcontext;
5371
5372 if (astate == NULL)
5373 {
5374 /* First time through --- initialize */
5375 astate = initArrayResult(element_type, rcontext, true);
5376 }
5377 else
5378 {
5379 Assert(astate->element_type == element_type);
5380 }
5381
5382 oldcontext = MemoryContextSwitchTo(astate->mcontext);
5383
5384 /* enlarge dvalues[]/dnulls[] if needed */
5385 if (astate->nelems >= astate->alen)
5386 {
5387 astate->alen *= 2;
5388 /* give an array-related error if we go past MaxAllocSize */
5389 if (!AllocSizeIsValid(astate->alen * sizeof(Datum)))
5390 ereport(ERROR,
5392 errmsg("array size exceeds the maximum allowed (%zu)",
5393 MaxAllocSize)));
5394 astate->dvalues = (Datum *)
5395 repalloc(astate->dvalues, astate->alen * sizeof(Datum));
5396 astate->dnulls = (bool *)
5397 repalloc(astate->dnulls, astate->alen * sizeof(bool));
5398 }
5399
5400 /*
5401 * Ensure pass-by-ref stuff is copied into mcontext; and detoast it too if
5402 * it's varlena. (You might think that detoasting is not needed here
5403 * because construct_md_array can detoast the array elements later.
5404 * However, we must not let construct_md_array modify the ArrayBuildState
5405 * because that would mean array_agg_finalfn damages its input, which is
5406 * verboten. Also, this way frequently saves one copying step.)
5407 */
5408 if (!disnull && !astate->typbyval)
5409 {
5410 if (astate->typlen == -1)
5412 else
5413 dvalue = datumCopy(dvalue, astate->typbyval, astate->typlen);
5414 }
5415
5416 astate->dvalues[astate->nelems] = dvalue;
5417 astate->dnulls[astate->nelems] = disnull;
5418 astate->nelems++;
5419
5420 MemoryContextSwitchTo(oldcontext);
5421
5422 return astate;
5423}
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
#define Assert(condition)
Definition c.h:885
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition datum.c:132
int errcode(int sqlerrcode)
Definition elog.c:874
int errmsg(const char *fmt,...)
Definition elog.c:1093
#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 5844 of file arrayfuncs.c.

5848{
5849 if (astate == NULL)
5850 astate = initArrayResultAny(input_type, rcontext, true);
5851
5852 if (astate->scalarstate)
5854 dvalue, disnull,
5856 else
5857 (void) accumArrayResultArr(astate->arraystate,
5858 dvalue, disnull,
5860
5861 return astate;
5862}
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 5565 of file arrayfuncs.c.

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

4983{
4984 int destbitmask,
4985 destbitval,
4986 srcbitmask,
4987 srcbitval;
4988
4990 if (nitems <= 0)
4991 return; /* don't risk fetch off end of memory */
4992 destbitmap += destoffset / 8;
4993 destbitmask = 1 << (destoffset % 8);
4995 if (srcbitmap)
4996 {
4997 srcbitmap += srcoffset / 8;
4998 srcbitmask = 1 << (srcoffset % 8);
5000 while (nitems-- > 0)
5001 {
5002 if (srcbitval & srcbitmask)
5004 else
5006 destbitmask <<= 1;
5007 if (destbitmask == 0x100)
5008 {
5010 destbitmask = 1;
5011 if (nitems > 0)
5013 }
5014 srcbitmask <<= 1;
5015 if (srcbitmask == 0x100)
5016 {
5017 srcbitmap++;
5018 srcbitmask = 1;
5019 if (nitems > 0)
5021 }
5022 }
5023 if (destbitmask != 1)
5025 }
5026 else
5027 {
5028 while (nitems-- > 0)
5029 {
5031 destbitmask <<= 1;
5032 if (destbitmask == 0x100)
5033 {
5035 destbitmask = 1;
5036 if (nitems > 0)
5038 }
5039 }
5040 if (destbitmask != 1)
5042 }
5043}

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 3781 of file arrayfuncs.c.

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

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 4609 of file arrayfuncs.c.

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

4773{
4774 if (iterator->slice_ndim > 0)
4775 {
4776 pfree(iterator->slice_values);
4777 pfree(iterator->slice_nulls);
4778 }
4779 pfree(iterator);
4780}

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:554
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 4689 of file arrayfuncs.c.

4690{
4691 /* Done if we have reached the end of the array */
4692 if (iterator->current_item >= iterator->nitems)
4693 return false;
4694
4695 if (iterator->slice_ndim == 0)
4696 {
4697 /*
4698 * Scalar case: return one element.
4699 */
4700 if (array_get_isnull(iterator->nullbitmap, iterator->current_item++))
4701 {
4702 *isnull = true;
4703 *value = (Datum) 0;
4704 }
4705 else
4706 {
4707 /* non-NULL, so fetch the individual Datum to return */
4708 char *p = iterator->data_ptr;
4709
4710 *isnull = false;
4711 *value = fetch_att(p, iterator->typbyval, iterator->typlen);
4712
4713 /* Move our data pointer forward to the next element */
4714 p = att_addlength_pointer(p, iterator->typlen, p);
4715 p = (char *) att_nominal_alignby(p, iterator->typalignby);
4716 iterator->data_ptr = p;
4717 }
4718 }
4719 else
4720 {
4721 /*
4722 * Slice case: build and return an array of the requested size.
4723 */
4724 ArrayType *result;
4725 Datum *values = iterator->slice_values;
4726 bool *nulls = iterator->slice_nulls;
4727 char *p = iterator->data_ptr;
4728 int i;
4729
4730 for (i = 0; i < iterator->slice_len; i++)
4731 {
4732 if (array_get_isnull(iterator->nullbitmap,
4733 iterator->current_item++))
4734 {
4735 nulls[i] = true;
4736 values[i] = (Datum) 0;
4737 }
4738 else
4739 {
4740 nulls[i] = false;
4741 values[i] = fetch_att(p, iterator->typbyval, iterator->typlen);
4742
4743 /* Move our data pointer forward to the next element */
4744 p = att_addlength_pointer(p, iterator->typlen, p);
4745 p = (char *) att_nominal_alignby(p, iterator->typalignby);
4746 }
4747 }
4748
4749 iterator->data_ptr = p;
4750
4751 result = construct_md_array(values,
4752 nulls,
4753 iterator->slice_ndim,
4754 iterator->slice_dims,
4755 iterator->slice_lbound,
4756 ARR_ELEMTYPE(iterator->arr),
4757 iterator->typlen,
4758 iterator->typbyval,
4759 iterator->typalign);
4760
4761 *isnull = false;
4762 *value = PointerGetDatum(result);
4763 }
4764
4765 return true;
4766}
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:147
static struct @174 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:556
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:178
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:1019
int errdetail(const char *fmt,...) pg_attribute_printf(1

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:235
#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:555
size_t Size
Definition c.h:631

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:656
int16_t int16
Definition c.h:553
float float4
Definition c.h:655
uint32 TransactionId
Definition c.h:678
#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(), test_text_to_wchars(), 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 INT4OID:
3740 elmlen = sizeof(int32);
3741 elmbyval = true;
3743 break;
3744
3745 case OIDOID:
3746 elmlen = sizeof(Oid);
3747 elmbyval = true;
3749 break;
3750
3751 case TEXTOID:
3752 elmlen = -1;
3753 elmbyval = false;
3755 break;
3756
3757 case TIDOID:
3758 elmlen = sizeof(ItemPointerData);
3759 elmbyval = false;
3761 break;
3762
3763 default:
3764 elog(ERROR, "type %u not supported by deconstruct_array_builtin()", elmtype);
3765 /* keep compiler quiet */
3766 elmlen = 0;
3767 elmbyval = false;
3768 elmalign = 0;
3769 }
3770
3771 deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, elemsp, nullsp, nelemsp);
3772}

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(), InsertOneProargdefaultsValue(), 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(), test_wchars_to_text(), 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 5308 of file arrayfuncs.c.

5309{
5310 /*
5311 * When using a subcontext, we can afford to start with a somewhat larger
5312 * initial array size. Without subcontexts, we'd better hope that most of
5313 * the states stay small ...
5314 */
5315 return initArrayResultWithSize(element_type, rcontext, subcontext,
5316 subcontext ? 64 : 8);
5317}
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 5797 of file arrayfuncs.c.

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

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 5519 of file arrayfuncs.c.

5521{
5522 ArrayBuildStateArr *astate;
5523 MemoryContext arr_context = rcontext; /* by default use the parent ctx */
5524
5525 /* Lookup element type, unless element_type already provided */
5526 if (!OidIsValid(element_type))
5527 {
5528 element_type = get_element_type(array_type);
5529
5530 if (!OidIsValid(element_type))
5531 ereport(ERROR,
5533 errmsg("data type %s is not an array type",
5534 format_type_be(array_type))));
5535 }
5536
5537 /* Make a temporary context to hold all the junk */
5538 if (subcontext)
5540 "accumArrayResultArr",
5542
5543 /* Note we initialize all fields to zero */
5544 astate = (ArrayBuildStateArr *)
5546 astate->mcontext = arr_context;
5547 astate->private_cxt = subcontext;
5548
5549 /* Save relevant datatype information */
5550 astate->array_type = array_type;
5551 astate->element_type = element_type;
5552
5553 return astate;
5554}
char * format_type_be(Oid type_oid)
Oid get_element_type(Oid typid)
Definition lsyscache.c:2911
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 5325 of file arrayfuncs.c.

5327{
5328 ArrayBuildState *astate;
5330
5331 /* Make a temporary context to hold all the junk */
5332 if (subcontext)
5334 "accumArrayResult",
5336
5337 astate = (ArrayBuildState *)
5339 astate->mcontext = arr_context;
5340 astate->private_cxt = subcontext;
5341 astate->alen = initsize;
5342 astate->dvalues = (Datum *)
5343 MemoryContextAlloc(arr_context, astate->alen * sizeof(Datum));
5344 astate->dnulls = (bool *)
5345 MemoryContextAlloc(arr_context, astate->alen * sizeof(bool));
5346 astate->nelems = 0;
5347 astate->element_type = element_type;
5348 get_typlenbyvalalign(element_type,
5349 &astate->typlen,
5350 &astate->typbyval,
5351 &astate->typalign);
5352
5353 return astate;
5354}
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 5435 of file arrayfuncs.c.

5437{
5438 int ndims;
5439 int dims[1];
5440 int lbs[1];
5441
5442 /* If no elements were presented, we want to create an empty array */
5443 ndims = (astate->nelems > 0) ? 1 : 0;
5444 dims[0] = astate->nelems;
5445 lbs[0] = 1;
5446
5447 return makeMdArrayResult(astate, ndims, dims, lbs, rcontext,
5448 astate->private_cxt);
5449}
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 5872 of file arrayfuncs.c.

5874{
5875 Datum result;
5876
5877 if (astate->scalarstate)
5878 {
5879 /* Must use makeMdArrayResult to support "release" parameter */
5880 int ndims;
5881 int dims[1];
5882 int lbs[1];
5883
5884 /* If no elements were presented, we want to create an empty array */
5885 ndims = (astate->scalarstate->nelems > 0) ? 1 : 0;
5886 dims[0] = astate->scalarstate->nelems;
5887 lbs[0] = 1;
5888
5889 result = makeMdArrayResult(astate->scalarstate, ndims, dims, lbs,
5890 rcontext, release);
5891 }
5892 else
5893 {
5894 result = makeArrayResultArr(astate->arraystate,
5895 rcontext, release);
5896 }
5897 return result;
5898}
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 5718 of file arrayfuncs.c.

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

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

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().