#ifndef ARRAY_H
#define ARRAY_H
#include "fmgr.h"
#include "utils/expandeddatum.h"
struct ExprState;
struct ExprContext;
#define MAXDIM 6
#define MaxArraySize ((Size) (MaxAllocSize / sizeof(Datum)))
typedef struct ArrayType
{
int32 vl_len_;
int ndim;
int32 dataoffset;
Oid elemtype;
} ArrayType;
#define EA_MAGIC 689375833
typedef struct ExpandedArrayHeader
{
ExpandedObjectHeader hdr;
int ea_magic;
int ndims;
int *dims;
int *lbound;
Oid element_type;
int16 typlen;
bool typbyval;
char typalign;
Datum *dvalues;
bool *dnulls;
int dvalueslen;
int nelems;
Size flat_size;
ArrayType *fvalue;
char *fstartptr;
char *fendptr;
} ExpandedArrayHeader;
typedef union AnyArrayType
{
ArrayType flt;
ExpandedArrayHeader xpn;
} AnyArrayType;
typedef struct ArrayBuildState
{
MemoryContext mcontext;
Datum *dvalues;
bool *dnulls;
int alen;
int nelems;
Oid element_type;
int16 typlen;
bool typbyval;
char typalign;
bool private_cxt;
} ArrayBuildState;
typedef struct ArrayBuildStateArr
{
MemoryContext mcontext;
char *data;
bits8 *nullbitmap;
int abytes;
int nbytes;
int aitems;
int nitems;
int ndims;
int dims[MAXDIM];
int lbs[MAXDIM];
Oid array_type;
Oid element_type;
bool private_cxt;
} ArrayBuildStateArr;
typedef struct ArrayBuildStateAny
{
ArrayBuildState *scalarstate;
ArrayBuildStateArr *arraystate;
} ArrayBuildStateAny;
typedef struct ArrayMetaState
{
Oid element_type;
int16 typlen;
bool typbyval;
char typalign;
char typdelim;
Oid typioparam;
Oid typiofunc;
FmgrInfo proc;
} ArrayMetaState;
typedef struct ArrayMapState
{
ArrayMetaState inp_extra;
ArrayMetaState ret_extra;
} ArrayMapState;
typedef struct ArrayIteratorData *ArrayIterator;
#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) \
((int *) (((char *) (a)) + sizeof(ArrayType) + \
sizeof(int) * ARR_NDIM(a)))
#define ARR_NULLBITMAP(a) \
(ARR_HASNULL(a) ? \
(bits8 *) (((char *) (a)) + sizeof(ArrayType) + \
2 * sizeof(int) * ARR_NDIM(a)) \
: (bits8 *) NULL)
#define ARR_OVERHEAD_NONULLS(ndims) \
MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims))
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems) \
MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims) + \
((nitems) + 7) / 8)
#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) \
(VARATT_IS_EXPANDED_HEADER(a) ? \
(a)->xpn.ndims : ARR_NDIM((ArrayType *) (a)))
#define AARR_HASNULL(a) \
(VARATT_IS_EXPANDED_HEADER(a) ? \
((a)->xpn.dvalues != NULL ? (a)->xpn.dnulls != NULL : ARR_HASNULL((a)->xpn.fvalue)) : \
ARR_HASNULL((ArrayType *) (a)))
#define AARR_ELEMTYPE(a) \
(VARATT_IS_EXPANDED_HEADER(a) ? \
(a)->xpn.element_type : ARR_ELEMTYPE((ArrayType *) (a)))
#define AARR_DIMS(a) \
(VARATT_IS_EXPANDED_HEADER(a) ? \
(a)->xpn.dims : ARR_DIMS((ArrayType *) (a)))
#define AARR_LBOUND(a) \
(VARATT_IS_EXPANDED_HEADER(a) ? \
(a)->xpn.lbound : ARR_LBOUND((ArrayType *) (a)))
extern PGDLLIMPORT bool Array_nulls;
extern void CopyArrayEls(ArrayType *array,
Datum *values,
bool *nulls,
int nitems,
int typlen,
bool typbyval,
char typalign,
bool freedata);
extern Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx,
int arraytyplen, int elmlen, bool elmbyval, char elmalign,
bool *isNull);
extern Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx,
Datum dataValue, bool isNull,
int arraytyplen, int elmlen, bool elmbyval, char elmalign);
extern 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 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 Datum array_ref(ArrayType *array, int nSubscripts, int *indx,
int arraytyplen, int elmlen, bool elmbyval, char elmalign,
bool *isNull);
extern ArrayType *array_set(ArrayType *array, int nSubscripts, int *indx,
Datum dataValue, bool isNull,
int arraytyplen, int elmlen, bool elmbyval, char elmalign);
extern Datum array_map(Datum arrayd,
struct ExprState *exprstate, struct ExprContext *econtext,
Oid retType, ArrayMapState *amstate);
extern void array_bitmap_copy(bits8 *destbitmap, int destoffset,
const bits8 *srcbitmap, int srcoffset,
int nitems);
extern ArrayType *construct_array(Datum *elems, int nelems,
Oid elmtype,
int elmlen, bool elmbyval, char elmalign);
extern ArrayType *construct_array_builtin(Datum *elems, int nelems, Oid elmtype);
extern ArrayType *construct_md_array(Datum *elems,
bool *nulls,
int ndims,
int *dims,
int *lbs,
Oid elmtype, int elmlen, bool elmbyval, char elmalign);
extern ArrayType *construct_empty_array(Oid elmtype);
extern ExpandedArrayHeader *construct_empty_expanded_array(Oid element_type,
MemoryContext parentcontext,
ArrayMetaState *metacache);
extern void deconstruct_array(ArrayType *array,
Oid elmtype,
int elmlen, bool elmbyval, char elmalign,
Datum **elemsp, bool **nullsp, int *nelemsp);
extern void deconstruct_array_builtin(ArrayType *array,
Oid elmtype,
Datum **elemsp, bool **nullsp, int *nelemsp);
extern bool array_contains_nulls(ArrayType *array);
extern ArrayBuildState *initArrayResult(Oid element_type,
MemoryContext rcontext, bool subcontext);
extern ArrayBuildState *initArrayResultWithSize(Oid element_type,
MemoryContext rcontext,
bool subcontext, int initsize);
extern ArrayBuildState *accumArrayResult(ArrayBuildState *astate,
Datum dvalue, bool disnull,
Oid element_type,
MemoryContext rcontext);
extern Datum makeArrayResult(ArrayBuildState *astate,
MemoryContext rcontext);
extern Datum makeMdArrayResult(ArrayBuildState *astate, int ndims,
int *dims, int *lbs, MemoryContext rcontext, bool release);
extern ArrayBuildStateArr *initArrayResultArr(Oid array_type, Oid element_type,
MemoryContext rcontext, bool subcontext);
extern ArrayBuildStateArr *accumArrayResultArr(ArrayBuildStateArr *astate,
Datum dvalue, bool disnull,
Oid array_type,
MemoryContext rcontext);
extern Datum makeArrayResultArr(ArrayBuildStateArr *astate,
MemoryContext rcontext, bool release);
extern ArrayBuildStateAny *initArrayResultAny(Oid input_type,
MemoryContext rcontext, bool subcontext);
extern ArrayBuildStateAny *accumArrayResultAny(ArrayBuildStateAny *astate,
Datum dvalue, bool disnull,
Oid input_type,
MemoryContext rcontext);
extern Datum makeArrayResultAny(ArrayBuildStateAny *astate,
MemoryContext rcontext, bool release);
extern ArrayIterator array_create_iterator(ArrayType *arr, int slice_ndim, ArrayMetaState *mstate);
extern bool array_iterate(ArrayIterator iterator, Datum *value, bool *isnull);
extern void array_free_iterator(ArrayIterator iterator);
extern int ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx);
extern int ArrayGetNItems(int ndim, const int *dims);
extern int ArrayGetNItemsSafe(int ndim, const int *dims,
struct Node *escontext);
extern void ArrayCheckBounds(int ndim, const int *dims, const int *lb);
extern bool ArrayCheckBoundsSafe(int ndim, const int *dims, const int *lb,
struct Node *escontext);
extern void mda_get_range(int n, int *span, const int *st, const int *endp);
extern void mda_get_prod(int n, const int *range, int *prod);
extern void mda_get_offset_values(int n, int *dist, const int *prod, const int *span);
extern int mda_next_tuple(int n, int *curr, const int *span);
extern int32 *ArrayGetIntegerTypmods(ArrayType *arr, int *n);
extern Datum expand_array(Datum arraydatum, MemoryContext parentcontext,
ArrayMetaState *metacache);
extern ExpandedArrayHeader *DatumGetExpandedArray(Datum d);
extern ExpandedArrayHeader *DatumGetExpandedArrayX(Datum d,
ArrayMetaState *metacache);
extern AnyArrayType *DatumGetAnyArrayP(Datum d);
extern void deconstruct_expanded_array(ExpandedArrayHeader *eah);
#endif