| 1 | /*------------------------------------------------------------------------- | 
|---|
| 2 | * | 
|---|
| 3 | * array.h | 
|---|
| 4 | *	  Declarations for Postgres arrays. | 
|---|
| 5 | * | 
|---|
| 6 | * A standard varlena array has the following internal structure: | 
|---|
| 7 | *	  <vl_len_>		- standard varlena header word | 
|---|
| 8 | *	  <ndim>		- number of dimensions of the array | 
|---|
| 9 | *	  <dataoffset>	- offset to stored data, or 0 if no nulls bitmap | 
|---|
| 10 | *	  <elemtype>	- element type OID | 
|---|
| 11 | *	  <dimensions>	- length of each array axis (C array of int) | 
|---|
| 12 | *	  <lower bnds>	- lower boundary of each dimension (C array of int) | 
|---|
| 13 | *	  <null bitmap> - bitmap showing locations of nulls (OPTIONAL) | 
|---|
| 14 | *	  <actual data> - whatever is the stored data | 
|---|
| 15 | * | 
|---|
| 16 | * The <dimensions> and <lower bnds> arrays each have ndim elements. | 
|---|
| 17 | * | 
|---|
| 18 | * The <null bitmap> may be omitted if the array contains no NULL elements. | 
|---|
| 19 | * If it is absent, the <dataoffset> field is zero and the offset to the | 
|---|
| 20 | * stored data must be computed on-the-fly.  If the bitmap is present, | 
|---|
| 21 | * <dataoffset> is nonzero and is equal to the offset from the array start | 
|---|
| 22 | * to the first data element (including any alignment padding).  The bitmap | 
|---|
| 23 | * follows the same conventions as tuple null bitmaps, ie, a 1 indicates | 
|---|
| 24 | * a non-null entry and the LSB of each bitmap byte is used first. | 
|---|
| 25 | * | 
|---|
| 26 | * The actual data starts on a MAXALIGN boundary.  Individual items in the | 
|---|
| 27 | * array are aligned as specified by the array element type.  They are | 
|---|
| 28 | * stored in row-major order (last subscript varies most rapidly). | 
|---|
| 29 | * | 
|---|
| 30 | * NOTE: it is important that array elements of toastable datatypes NOT be | 
|---|
| 31 | * toasted, since the tupletoaster won't know they are there.  (We could | 
|---|
| 32 | * support compressed toasted items; only out-of-line items are dangerous. | 
|---|
| 33 | * However, it seems preferable to store such items uncompressed and allow | 
|---|
| 34 | * the toaster to compress the whole array as one input.) | 
|---|
| 35 | * | 
|---|
| 36 | * | 
|---|
| 37 | * The OIDVECTOR and INT2VECTOR datatypes are storage-compatible with | 
|---|
| 38 | * generic arrays, but they support only one-dimensional arrays with no | 
|---|
| 39 | * nulls (and no null bitmap).  They don't support being toasted, either. | 
|---|
| 40 | * | 
|---|
| 41 | * There are also some "fixed-length array" datatypes, such as NAME and | 
|---|
| 42 | * POINT.  These are simply a sequence of a fixed number of items each | 
|---|
| 43 | * of a fixed-length datatype, with no overhead; the item size must be | 
|---|
| 44 | * a multiple of its alignment requirement, because we do no padding. | 
|---|
| 45 | * We support subscripting on these types, but array_in() and array_out() | 
|---|
| 46 | * only work with varlena arrays. | 
|---|
| 47 | * | 
|---|
| 48 | * In addition, arrays are a major user of the "expanded object" TOAST | 
|---|
| 49 | * infrastructure.  This allows a varlena array to be converted to a | 
|---|
| 50 | * separate representation that may include "deconstructed" Datum/isnull | 
|---|
| 51 | * arrays holding the elements. | 
|---|
| 52 | * | 
|---|
| 53 | * | 
|---|
| 54 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group | 
|---|
| 55 | * Portions Copyright (c) 1994, Regents of the University of California | 
|---|
| 56 | * | 
|---|
| 57 | * src/include/utils/array.h | 
|---|
| 58 | * | 
|---|
| 59 | *------------------------------------------------------------------------- | 
|---|
| 60 | */ | 
|---|
| 61 | #ifndef ARRAY_H | 
|---|
| 62 | #define ARRAY_H | 
|---|
| 63 |  | 
|---|
| 64 | #include "fmgr.h" | 
|---|
| 65 | #include "utils/expandeddatum.h" | 
|---|
| 66 |  | 
|---|
| 67 | /* avoid including execnodes.h here */ | 
|---|
| 68 | struct ExprState; | 
|---|
| 69 | struct ExprContext; | 
|---|
| 70 |  | 
|---|
| 71 |  | 
|---|
| 72 | /* | 
|---|
| 73 | * Arrays are varlena objects, so must meet the varlena convention that | 
|---|
| 74 | * the first int32 of the object contains the total object size in bytes. | 
|---|
| 75 | * Be sure to use VARSIZE() and SET_VARSIZE() to access it, though! | 
|---|
| 76 | * | 
|---|
| 77 | * CAUTION: if you change the header for ordinary arrays you will also | 
|---|
| 78 | * need to change the headers for oidvector and int2vector! | 
|---|
| 79 | */ | 
|---|
| 80 | typedef struct | 
|---|
| 81 | { | 
|---|
| 82 | int32		vl_len_;		/* varlena header (do not touch directly!) */ | 
|---|
| 83 | int			ndim;			/* # of dimensions */ | 
|---|
| 84 | int32		dataoffset;		/* offset to data, or 0 if no bitmap */ | 
|---|
| 85 | Oid			elemtype;		/* element type OID */ | 
|---|
| 86 | } ArrayType; | 
|---|
| 87 |  | 
|---|
| 88 | /* | 
|---|
| 89 | * An expanded array is contained within a private memory context (as | 
|---|
| 90 | * all expanded objects must be) and has a control structure as below. | 
|---|
| 91 | * | 
|---|
| 92 | * The expanded array might contain a regular "flat" array if that was the | 
|---|
| 93 | * original input and we've not modified it significantly.  Otherwise, the | 
|---|
| 94 | * contents are represented by Datum/isnull arrays plus dimensionality and | 
|---|
| 95 | * type information.  We could also have both forms, if we've deconstructed | 
|---|
| 96 | * the original array for access purposes but not yet changed it.  For pass- | 
|---|
| 97 | * by-reference element types, the Datums would point into the flat array in | 
|---|
| 98 | * this situation.  Once we start modifying array elements, new pass-by-ref | 
|---|
| 99 | * elements are separately palloc'd within the memory context. | 
|---|
| 100 | */ | 
|---|
| 101 | #define EA_MAGIC 689375833		/* ID for debugging crosschecks */ | 
|---|
| 102 |  | 
|---|
| 103 | typedef struct ExpandedArrayHeader | 
|---|
| 104 | { | 
|---|
| 105 | /* Standard header for expanded objects */ | 
|---|
| 106 | ExpandedObjectHeader hdr; | 
|---|
| 107 |  | 
|---|
| 108 | /* Magic value identifying an expanded array (for debugging only) */ | 
|---|
| 109 | int			ea_magic; | 
|---|
| 110 |  | 
|---|
| 111 | /* Dimensionality info (always valid) */ | 
|---|
| 112 | int			ndims;			/* # of dimensions */ | 
|---|
| 113 | int		   *dims;			/* array dimensions */ | 
|---|
| 114 | int		   *lbound;			/* index lower bounds for each dimension */ | 
|---|
| 115 |  | 
|---|
| 116 | /* Element type info (always valid) */ | 
|---|
| 117 | Oid			element_type;	/* element type OID */ | 
|---|
| 118 | int16		typlen;			/* needed info about element datatype */ | 
|---|
| 119 | bool		typbyval; | 
|---|
| 120 | char		typalign; | 
|---|
| 121 |  | 
|---|
| 122 | /* | 
|---|
| 123 | * If we have a Datum-array representation of the array, it's kept here; | 
|---|
| 124 | * else dvalues/dnulls are NULL.  The dvalues and dnulls arrays are always | 
|---|
| 125 | * palloc'd within the object private context, but may change size from | 
|---|
| 126 | * time to time.  For pass-by-ref element types, dvalues entries might | 
|---|
| 127 | * point either into the fstartptr..fendptr area, or to separately | 
|---|
| 128 | * palloc'd chunks.  Elements should always be fully detoasted, as they | 
|---|
| 129 | * are in the standard flat representation. | 
|---|
| 130 | * | 
|---|
| 131 | * Even when dvalues is valid, dnulls can be NULL if there are no null | 
|---|
| 132 | * elements. | 
|---|
| 133 | */ | 
|---|
| 134 | Datum	   *dvalues;		/* array of Datums */ | 
|---|
| 135 | bool	   *dnulls;			/* array of is-null flags for Datums */ | 
|---|
| 136 | int			dvalueslen;		/* allocated length of above arrays */ | 
|---|
| 137 | int			nelems;			/* number of valid entries in above arrays */ | 
|---|
| 138 |  | 
|---|
| 139 | /* | 
|---|
| 140 | * flat_size is the current space requirement for the flat equivalent of | 
|---|
| 141 | * the expanded array, if known; otherwise it's 0.  We store this to make | 
|---|
| 142 | * consecutive calls of get_flat_size cheap. | 
|---|
| 143 | */ | 
|---|
| 144 | Size		flat_size; | 
|---|
| 145 |  | 
|---|
| 146 | /* | 
|---|
| 147 | * fvalue points to the flat representation if it is valid, else it is | 
|---|
| 148 | * NULL.  If we have or ever had a flat representation then | 
|---|
| 149 | * fstartptr/fendptr point to the start and end+1 of its data area; this | 
|---|
| 150 | * is so that we can tell which Datum pointers point into the flat | 
|---|
| 151 | * representation rather than being pointers to separately palloc'd data. | 
|---|
| 152 | */ | 
|---|
| 153 | ArrayType  *fvalue;			/* must be a fully detoasted array */ | 
|---|
| 154 | char	   *fstartptr;		/* start of its data area */ | 
|---|
| 155 | char	   *fendptr;		/* end+1 of its data area */ | 
|---|
| 156 | } ExpandedArrayHeader; | 
|---|
| 157 |  | 
|---|
| 158 | /* | 
|---|
| 159 | * Functions that can handle either a "flat" varlena array or an expanded | 
|---|
| 160 | * array use this union to work with their input.  Don't refer to "flt"; | 
|---|
| 161 | * instead, cast to ArrayType.  This struct nominally requires 8-byte | 
|---|
| 162 | * alignment on 64-bit, but it's often used for an ArrayType having 4-byte | 
|---|
| 163 | * alignment.  UBSan complains about referencing "flt" in such cases. | 
|---|
| 164 | */ | 
|---|
| 165 | typedef union AnyArrayType | 
|---|
| 166 | { | 
|---|
| 167 | ArrayType	flt; | 
|---|
| 168 | ExpandedArrayHeader xpn; | 
|---|
| 169 | } AnyArrayType; | 
|---|
| 170 |  | 
|---|
| 171 | /* | 
|---|
| 172 | * working state for accumArrayResult() and friends | 
|---|
| 173 | * note that the input must be scalars (legal array elements) | 
|---|
| 174 | */ | 
|---|
| 175 | typedef struct ArrayBuildState | 
|---|
| 176 | { | 
|---|
| 177 | MemoryContext mcontext;		/* where all the temp stuff is kept */ | 
|---|
| 178 | Datum	   *dvalues;		/* array of accumulated Datums */ | 
|---|
| 179 | bool	   *dnulls;			/* array of is-null flags for Datums */ | 
|---|
| 180 | int			alen;			/* allocated length of above arrays */ | 
|---|
| 181 | int			nelems;			/* number of valid entries in above arrays */ | 
|---|
| 182 | Oid			element_type;	/* data type of the Datums */ | 
|---|
| 183 | int16		typlen;			/* needed info about datatype */ | 
|---|
| 184 | bool		typbyval; | 
|---|
| 185 | char		typalign; | 
|---|
| 186 | bool		private_cxt;	/* use private memory context */ | 
|---|
| 187 | } ArrayBuildState; | 
|---|
| 188 |  | 
|---|
| 189 | /* | 
|---|
| 190 | * working state for accumArrayResultArr() and friends | 
|---|
| 191 | * note that the input must be arrays, and the same array type is returned | 
|---|
| 192 | */ | 
|---|
| 193 | typedef struct ArrayBuildStateArr | 
|---|
| 194 | { | 
|---|
| 195 | MemoryContext mcontext;		/* where all the temp stuff is kept */ | 
|---|
| 196 | char	   *data;			/* accumulated data */ | 
|---|
| 197 | bits8	   *nullbitmap;		/* bitmap of is-null flags, or NULL if none */ | 
|---|
| 198 | int			abytes;			/* allocated length of "data" */ | 
|---|
| 199 | int			nbytes;			/* number of bytes used so far */ | 
|---|
| 200 | int			aitems;			/* allocated length of bitmap (in elements) */ | 
|---|
| 201 | int			nitems;			/* total number of elements in result */ | 
|---|
| 202 | int			ndims;			/* current dimensions of result */ | 
|---|
| 203 | int			dims[MAXDIM]; | 
|---|
| 204 | int			lbs[MAXDIM]; | 
|---|
| 205 | Oid			array_type;		/* data type of the arrays */ | 
|---|
| 206 | Oid			element_type;	/* data type of the array elements */ | 
|---|
| 207 | bool		private_cxt;	/* use private memory context */ | 
|---|
| 208 | } ArrayBuildStateArr; | 
|---|
| 209 |  | 
|---|
| 210 | /* | 
|---|
| 211 | * working state for accumArrayResultAny() and friends | 
|---|
| 212 | * these functions handle both cases | 
|---|
| 213 | */ | 
|---|
| 214 | typedef struct ArrayBuildStateAny | 
|---|
| 215 | { | 
|---|
| 216 | /* Exactly one of these is not NULL: */ | 
|---|
| 217 | ArrayBuildState *scalarstate; | 
|---|
| 218 | ArrayBuildStateArr *arraystate; | 
|---|
| 219 | } ArrayBuildStateAny; | 
|---|
| 220 |  | 
|---|
| 221 | /* | 
|---|
| 222 | * structure to cache type metadata needed for array manipulation | 
|---|
| 223 | */ | 
|---|
| 224 | typedef struct ArrayMetaState | 
|---|
| 225 | { | 
|---|
| 226 | Oid			element_type; | 
|---|
| 227 | int16		typlen; | 
|---|
| 228 | bool		typbyval; | 
|---|
| 229 | char		typalign; | 
|---|
| 230 | char		typdelim; | 
|---|
| 231 | Oid			typioparam; | 
|---|
| 232 | Oid			typiofunc; | 
|---|
| 233 | FmgrInfo	proc; | 
|---|
| 234 | } ArrayMetaState; | 
|---|
| 235 |  | 
|---|
| 236 | /* | 
|---|
| 237 | * private state needed by array_map (here because caller must provide it) | 
|---|
| 238 | */ | 
|---|
| 239 | typedef struct ArrayMapState | 
|---|
| 240 | { | 
|---|
| 241 | ArrayMetaState ; | 
|---|
| 242 | ArrayMetaState ; | 
|---|
| 243 | } ArrayMapState; | 
|---|
| 244 |  | 
|---|
| 245 | /* ArrayIteratorData is private in arrayfuncs.c */ | 
|---|
| 246 | typedef struct ArrayIteratorData *ArrayIterator; | 
|---|
| 247 |  | 
|---|
| 248 | /* fmgr macros for regular varlena array objects */ | 
|---|
| 249 | #define DatumGetArrayTypeP(X)		  ((ArrayType *) PG_DETOAST_DATUM(X)) | 
|---|
| 250 | #define DatumGetArrayTypePCopy(X)	  ((ArrayType *) PG_DETOAST_DATUM_COPY(X)) | 
|---|
| 251 | #define PG_GETARG_ARRAYTYPE_P(n)	  DatumGetArrayTypeP(PG_GETARG_DATUM(n)) | 
|---|
| 252 | #define PG_GETARG_ARRAYTYPE_P_COPY(n) DatumGetArrayTypePCopy(PG_GETARG_DATUM(n)) | 
|---|
| 253 | #define PG_RETURN_ARRAYTYPE_P(x)	  PG_RETURN_POINTER(x) | 
|---|
| 254 |  | 
|---|
| 255 | /* fmgr macros for expanded array objects */ | 
|---|
| 256 | #define PG_GETARG_EXPANDED_ARRAY(n)  DatumGetExpandedArray(PG_GETARG_DATUM(n)) | 
|---|
| 257 | #define PG_GETARG_EXPANDED_ARRAYX(n, metacache) \ | 
|---|
| 258 | DatumGetExpandedArrayX(PG_GETARG_DATUM(n), metacache) | 
|---|
| 259 | #define PG_RETURN_EXPANDED_ARRAY(x)  PG_RETURN_DATUM(EOHPGetRWDatum(&(x)->hdr)) | 
|---|
| 260 |  | 
|---|
| 261 | /* fmgr macros for AnyArrayType (ie, get either varlena or expanded form) */ | 
|---|
| 262 | #define PG_GETARG_ANY_ARRAY_P(n)	DatumGetAnyArrayP(PG_GETARG_DATUM(n)) | 
|---|
| 263 |  | 
|---|
| 264 | /* | 
|---|
| 265 | * Access macros for varlena array header fields. | 
|---|
| 266 | * | 
|---|
| 267 | * ARR_DIMS returns a pointer to an array of array dimensions (number of | 
|---|
| 268 | * elements along the various array axes). | 
|---|
| 269 | * | 
|---|
| 270 | * ARR_LBOUND returns a pointer to an array of array lower bounds. | 
|---|
| 271 | * | 
|---|
| 272 | * That is: if the third axis of an array has elements 5 through 8, then | 
|---|
| 273 | * ARR_DIMS(a)[2] == 4 and ARR_LBOUND(a)[2] == 5. | 
|---|
| 274 | * | 
|---|
| 275 | * Unlike C, the default lower bound is 1. | 
|---|
| 276 | */ | 
|---|
| 277 | #define ARR_SIZE(a)				VARSIZE(a) | 
|---|
| 278 | #define ARR_NDIM(a)				((a)->ndim) | 
|---|
| 279 | #define ARR_HASNULL(a)			((a)->dataoffset != 0) | 
|---|
| 280 | #define ARR_ELEMTYPE(a)			((a)->elemtype) | 
|---|
| 281 |  | 
|---|
| 282 | #define ARR_DIMS(a) \ | 
|---|
| 283 | ((int *) (((char *) (a)) + sizeof(ArrayType))) | 
|---|
| 284 | #define ARR_LBOUND(a) \ | 
|---|
| 285 | ((int *) (((char *) (a)) + sizeof(ArrayType) + \ | 
|---|
| 286 | sizeof(int) * ARR_NDIM(a))) | 
|---|
| 287 |  | 
|---|
| 288 | #define ARR_NULLBITMAP(a) \ | 
|---|
| 289 | (ARR_HASNULL(a) ? \ | 
|---|
| 290 | (bits8 *) (((char *) (a)) + sizeof(ArrayType) + \ | 
|---|
| 291 | 2 * sizeof(int) * ARR_NDIM(a)) \ | 
|---|
| 292 | : (bits8 *) NULL) | 
|---|
| 293 |  | 
|---|
| 294 | /* | 
|---|
| 295 | * The total array header size (in bytes) for an array with the specified | 
|---|
| 296 | * number of dimensions and total number of items. | 
|---|
| 297 | */ | 
|---|
| 298 | #define ARR_OVERHEAD_NONULLS(ndims) \ | 
|---|
| 299 | MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims)) | 
|---|
| 300 | #define ARR_OVERHEAD_WITHNULLS(ndims, nitems) \ | 
|---|
| 301 | MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims) + \ | 
|---|
| 302 | ((nitems) + 7) / 8) | 
|---|
| 303 |  | 
|---|
| 304 | #define ARR_DATA_OFFSET(a) \ | 
|---|
| 305 | (ARR_HASNULL(a) ? (a)->dataoffset : ARR_OVERHEAD_NONULLS(ARR_NDIM(a))) | 
|---|
| 306 |  | 
|---|
| 307 | /* | 
|---|
| 308 | * Returns a pointer to the actual array data. | 
|---|
| 309 | */ | 
|---|
| 310 | #define ARR_DATA_PTR(a) \ | 
|---|
| 311 | (((char *) (a)) + ARR_DATA_OFFSET(a)) | 
|---|
| 312 |  | 
|---|
| 313 | /* | 
|---|
| 314 | * Macros for working with AnyArrayType inputs.  Beware multiple references! | 
|---|
| 315 | */ | 
|---|
| 316 | #define AARR_NDIM(a) \ | 
|---|
| 317 | (VARATT_IS_EXPANDED_HEADER(a) ? \ | 
|---|
| 318 | (a)->xpn.ndims : ARR_NDIM((ArrayType *) (a))) | 
|---|
| 319 | #define AARR_HASNULL(a) \ | 
|---|
| 320 | (VARATT_IS_EXPANDED_HEADER(a) ? \ | 
|---|
| 321 | ((a)->xpn.dvalues != NULL ? (a)->xpn.dnulls != NULL : ARR_HASNULL((a)->xpn.fvalue)) : \ | 
|---|
| 322 | ARR_HASNULL((ArrayType *) (a))) | 
|---|
| 323 | #define AARR_ELEMTYPE(a) \ | 
|---|
| 324 | (VARATT_IS_EXPANDED_HEADER(a) ? \ | 
|---|
| 325 | (a)->xpn.element_type : ARR_ELEMTYPE((ArrayType *) (a))) | 
|---|
| 326 | #define AARR_DIMS(a) \ | 
|---|
| 327 | (VARATT_IS_EXPANDED_HEADER(a) ? \ | 
|---|
| 328 | (a)->xpn.dims : ARR_DIMS((ArrayType *) (a))) | 
|---|
| 329 | #define AARR_LBOUND(a) \ | 
|---|
| 330 | (VARATT_IS_EXPANDED_HEADER(a) ? \ | 
|---|
| 331 | (a)->xpn.lbound : ARR_LBOUND((ArrayType *) (a))) | 
|---|
| 332 |  | 
|---|
| 333 |  | 
|---|
| 334 | /* | 
|---|
| 335 | * GUC parameter | 
|---|
| 336 | */ | 
|---|
| 337 | extern bool Array_nulls; | 
|---|
| 338 |  | 
|---|
| 339 | /* | 
|---|
| 340 | * prototypes for functions defined in arrayfuncs.c | 
|---|
| 341 | */ | 
|---|
| 342 | extern void CopyArrayEls(ArrayType *array, | 
|---|
| 343 | Datum *values, | 
|---|
| 344 | bool *nulls, | 
|---|
| 345 | int nitems, | 
|---|
| 346 | int typlen, | 
|---|
| 347 | bool typbyval, | 
|---|
| 348 | char typalign, | 
|---|
| 349 | bool freedata); | 
|---|
| 350 |  | 
|---|
| 351 | extern Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, | 
|---|
| 352 | int arraytyplen, int elmlen, bool elmbyval, char elmalign, | 
|---|
| 353 | bool *isNull); | 
|---|
| 354 | extern Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, | 
|---|
| 355 | Datum dataValue, bool isNull, | 
|---|
| 356 | int arraytyplen, int elmlen, bool elmbyval, char elmalign); | 
|---|
| 357 | extern Datum array_get_slice(Datum arraydatum, int nSubscripts, | 
|---|
| 358 | int *upperIndx, int *lowerIndx, | 
|---|
| 359 | bool *upperProvided, bool *lowerProvided, | 
|---|
| 360 | int arraytyplen, int elmlen, bool elmbyval, char elmalign); | 
|---|
| 361 | extern Datum array_set_slice(Datum arraydatum, int nSubscripts, | 
|---|
| 362 | int *upperIndx, int *lowerIndx, | 
|---|
| 363 | bool *upperProvided, bool *lowerProvided, | 
|---|
| 364 | Datum srcArrayDatum, bool isNull, | 
|---|
| 365 | int arraytyplen, int elmlen, bool elmbyval, char elmalign); | 
|---|
| 366 |  | 
|---|
| 367 | extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx, | 
|---|
| 368 | int arraytyplen, int elmlen, bool elmbyval, char elmalign, | 
|---|
| 369 | bool *isNull); | 
|---|
| 370 | extern ArrayType *array_set(ArrayType *array, int nSubscripts, int *indx, | 
|---|
| 371 | Datum dataValue, bool isNull, | 
|---|
| 372 | int arraytyplen, int elmlen, bool elmbyval, char elmalign); | 
|---|
| 373 |  | 
|---|
| 374 | extern Datum array_map(Datum arrayd, | 
|---|
| 375 | struct ExprState *exprstate, struct ExprContext *econtext, | 
|---|
| 376 | Oid retType, ArrayMapState *amstate); | 
|---|
| 377 |  | 
|---|
| 378 | extern void array_bitmap_copy(bits8 *destbitmap, int destoffset, | 
|---|
| 379 | const bits8 *srcbitmap, int srcoffset, | 
|---|
| 380 | int nitems); | 
|---|
| 381 |  | 
|---|
| 382 | extern ArrayType *construct_array(Datum *elems, int nelems, | 
|---|
| 383 | Oid elmtype, | 
|---|
| 384 | int elmlen, bool elmbyval, char elmalign); | 
|---|
| 385 | extern ArrayType *construct_md_array(Datum *elems, | 
|---|
| 386 | bool *nulls, | 
|---|
| 387 | int ndims, | 
|---|
| 388 | int *dims, | 
|---|
| 389 | int *lbs, | 
|---|
| 390 | Oid elmtype, int elmlen, bool elmbyval, char elmalign); | 
|---|
| 391 | extern ArrayType *construct_empty_array(Oid elmtype); | 
|---|
| 392 | extern ExpandedArrayHeader *construct_empty_expanded_array(Oid element_type, | 
|---|
| 393 | MemoryContext parentcontext, | 
|---|
| 394 | ArrayMetaState *metacache); | 
|---|
| 395 | extern void deconstruct_array(ArrayType *array, | 
|---|
| 396 | Oid elmtype, | 
|---|
| 397 | int elmlen, bool elmbyval, char elmalign, | 
|---|
| 398 | Datum **elemsp, bool **nullsp, int *nelemsp); | 
|---|
| 399 | extern bool array_contains_nulls(ArrayType *array); | 
|---|
| 400 |  | 
|---|
| 401 | extern ArrayBuildState *initArrayResult(Oid element_type, | 
|---|
| 402 | MemoryContext rcontext, bool subcontext); | 
|---|
| 403 | extern ArrayBuildState *accumArrayResult(ArrayBuildState *astate, | 
|---|
| 404 | Datum dvalue, bool disnull, | 
|---|
| 405 | Oid element_type, | 
|---|
| 406 | MemoryContext rcontext); | 
|---|
| 407 | extern Datum makeArrayResult(ArrayBuildState *astate, | 
|---|
| 408 | MemoryContext rcontext); | 
|---|
| 409 | extern Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, | 
|---|
| 410 | int *dims, int *lbs, MemoryContext rcontext, bool release); | 
|---|
| 411 |  | 
|---|
| 412 | extern ArrayBuildStateArr *initArrayResultArr(Oid array_type, Oid element_type, | 
|---|
| 413 | MemoryContext rcontext, bool subcontext); | 
|---|
| 414 | extern ArrayBuildStateArr *accumArrayResultArr(ArrayBuildStateArr *astate, | 
|---|
| 415 | Datum dvalue, bool disnull, | 
|---|
| 416 | Oid array_type, | 
|---|
| 417 | MemoryContext rcontext); | 
|---|
| 418 | extern Datum makeArrayResultArr(ArrayBuildStateArr *astate, | 
|---|
| 419 | MemoryContext rcontext, bool release); | 
|---|
| 420 |  | 
|---|
| 421 | extern ArrayBuildStateAny *initArrayResultAny(Oid input_type, | 
|---|
| 422 | MemoryContext rcontext, bool subcontext); | 
|---|
| 423 | extern ArrayBuildStateAny *accumArrayResultAny(ArrayBuildStateAny *astate, | 
|---|
| 424 | Datum dvalue, bool disnull, | 
|---|
| 425 | Oid input_type, | 
|---|
| 426 | MemoryContext rcontext); | 
|---|
| 427 | extern Datum makeArrayResultAny(ArrayBuildStateAny *astate, | 
|---|
| 428 | MemoryContext rcontext, bool release); | 
|---|
| 429 |  | 
|---|
| 430 | extern ArrayIterator array_create_iterator(ArrayType *arr, int slice_ndim, ArrayMetaState *mstate); | 
|---|
| 431 | extern bool array_iterate(ArrayIterator iterator, Datum *value, bool *isnull); | 
|---|
| 432 | extern void array_free_iterator(ArrayIterator iterator); | 
|---|
| 433 |  | 
|---|
| 434 | /* | 
|---|
| 435 | * prototypes for functions defined in arrayutils.c | 
|---|
| 436 | */ | 
|---|
| 437 |  | 
|---|
| 438 | extern int	ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx); | 
|---|
| 439 | extern int	ArrayGetOffset0(int n, const int *tup, const int *scale); | 
|---|
| 440 | extern int	ArrayGetNItems(int ndim, const int *dims); | 
|---|
| 441 | extern void mda_get_range(int n, int *span, const int *st, const int *endp); | 
|---|
| 442 | extern void mda_get_prod(int n, const int *range, int *prod); | 
|---|
| 443 | extern void mda_get_offset_values(int n, int *dist, const int *prod, const int *span); | 
|---|
| 444 | extern int	mda_next_tuple(int n, int *curr, const int *span); | 
|---|
| 445 | extern int32 *ArrayGetIntegerTypmods(ArrayType *arr, int *n); | 
|---|
| 446 |  | 
|---|
| 447 | /* | 
|---|
| 448 | * prototypes for functions defined in array_expanded.c | 
|---|
| 449 | */ | 
|---|
| 450 | extern Datum expand_array(Datum arraydatum, MemoryContext parentcontext, | 
|---|
| 451 | ArrayMetaState *metacache); | 
|---|
| 452 | extern ExpandedArrayHeader *DatumGetExpandedArray(Datum d); | 
|---|
| 453 | extern ExpandedArrayHeader *DatumGetExpandedArrayX(Datum d, | 
|---|
| 454 | ArrayMetaState *metacache); | 
|---|
| 455 | extern AnyArrayType *DatumGetAnyArrayP(Datum d); | 
|---|
| 456 | extern void deconstruct_expanded_array(ExpandedArrayHeader *eah); | 
|---|
| 457 |  | 
|---|
| 458 | #endif							/* ARRAY_H */ | 
|---|
| 459 |  | 
|---|