Header And Logo

PostgreSQL
| The world's most advanced open source database.

array.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * array.h
00004  *    Declarations for Postgres arrays.
00005  *
00006  * A standard varlena array has the following internal structure:
00007  *    <vl_len_>     - standard varlena header word
00008  *    <ndim>        - number of dimensions of the array
00009  *    <dataoffset>  - offset to stored data, or 0 if no nulls bitmap
00010  *    <elemtype>    - element type OID
00011  *    <dimensions>  - length of each array axis (C array of int)
00012  *    <lower bnds>  - lower boundary of each dimension (C array of int)
00013  *    <null bitmap> - bitmap showing locations of nulls (OPTIONAL)
00014  *    <actual data> - whatever is the stored data
00015  *
00016  * The <dimensions> and <lower bnds> arrays each have ndim elements.
00017  *
00018  * The <null bitmap> may be omitted if the array contains no NULL elements.
00019  * If it is absent, the <dataoffset> field is zero and the offset to the
00020  * stored data must be computed on-the-fly.  If the bitmap is present,
00021  * <dataoffset> is nonzero and is equal to the offset from the array start
00022  * to the first data element (including any alignment padding).  The bitmap
00023  * follows the same conventions as tuple null bitmaps, ie, a 1 indicates
00024  * a non-null entry and the LSB of each bitmap byte is used first.
00025  *
00026  * The actual data starts on a MAXALIGN boundary.  Individual items in the
00027  * array are aligned as specified by the array element type.  They are
00028  * stored in row-major order (last subscript varies most rapidly).
00029  *
00030  * NOTE: it is important that array elements of toastable datatypes NOT be
00031  * toasted, since the tupletoaster won't know they are there.  (We could
00032  * support compressed toasted items; only out-of-line items are dangerous.
00033  * However, it seems preferable to store such items uncompressed and allow
00034  * the toaster to compress the whole array as one input.)
00035  *
00036  *
00037  * The OIDVECTOR and INT2VECTOR datatypes are storage-compatible with
00038  * generic arrays, but they support only one-dimensional arrays with no
00039  * nulls (and no null bitmap).
00040  *
00041  * There are also some "fixed-length array" datatypes, such as NAME and
00042  * POINT.  These are simply a sequence of a fixed number of items each
00043  * of a fixed-length datatype, with no overhead; the item size must be
00044  * a multiple of its alignment requirement, because we do no padding.
00045  * We support subscripting on these types, but array_in() and array_out()
00046  * only work with varlena arrays.
00047  *
00048  *
00049  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00050  * Portions Copyright (c) 1994, Regents of the University of California
00051  *
00052  * src/include/utils/array.h
00053  *
00054  *-------------------------------------------------------------------------
00055  */
00056 #ifndef ARRAY_H
00057 #define ARRAY_H
00058 
00059 #include "fmgr.h"
00060 
00061 /*
00062  * Arrays are varlena objects, so must meet the varlena convention that
00063  * the first int32 of the object contains the total object size in bytes.
00064  * Be sure to use VARSIZE() and SET_VARSIZE() to access it, though!
00065  *
00066  * CAUTION: if you change the header for ordinary arrays you will also
00067  * need to change the headers for oidvector and int2vector!
00068  */
00069 typedef struct
00070 {
00071     int32       vl_len_;        /* varlena header (do not touch directly!) */
00072     int         ndim;           /* # of dimensions */
00073     int32       dataoffset;     /* offset to data, or 0 if no bitmap */
00074     Oid         elemtype;       /* element type OID */
00075 } ArrayType;
00076 
00077 /*
00078  * working state for accumArrayResult() and friends
00079  */
00080 typedef struct ArrayBuildState
00081 {
00082     MemoryContext mcontext;     /* where all the temp stuff is kept */
00083     Datum      *dvalues;        /* array of accumulated Datums */
00084     bool       *dnulls;         /* array of is-null flags for Datums */
00085     int         alen;           /* allocated length of above arrays */
00086     int         nelems;         /* number of valid entries in above arrays */
00087     Oid         element_type;   /* data type of the Datums */
00088     int16       typlen;         /* needed info about datatype */
00089     bool        typbyval;
00090     char        typalign;
00091 } ArrayBuildState;
00092 
00093 /*
00094  * structure to cache type metadata needed for array manipulation
00095  */
00096 typedef struct ArrayMetaState
00097 {
00098     Oid         element_type;
00099     int16       typlen;
00100     bool        typbyval;
00101     char        typalign;
00102     char        typdelim;
00103     Oid         typioparam;
00104     Oid         typiofunc;
00105     FmgrInfo    proc;
00106 } ArrayMetaState;
00107 
00108 /*
00109  * private state needed by array_map (here because caller must provide it)
00110  */
00111 typedef struct ArrayMapState
00112 {
00113     ArrayMetaState inp_extra;
00114     ArrayMetaState ret_extra;
00115 } ArrayMapState;
00116 
00117 /* ArrayIteratorData is private in arrayfuncs.c */
00118 typedef struct ArrayIteratorData *ArrayIterator;
00119 
00120 /*
00121  * fmgr macros for array objects
00122  */
00123 #define DatumGetArrayTypeP(X)         ((ArrayType *) PG_DETOAST_DATUM(X))
00124 #define DatumGetArrayTypePCopy(X)     ((ArrayType *) PG_DETOAST_DATUM_COPY(X))
00125 #define PG_GETARG_ARRAYTYPE_P(n)      DatumGetArrayTypeP(PG_GETARG_DATUM(n))
00126 #define PG_GETARG_ARRAYTYPE_P_COPY(n) DatumGetArrayTypePCopy(PG_GETARG_DATUM(n))
00127 #define PG_RETURN_ARRAYTYPE_P(x)      PG_RETURN_POINTER(x)
00128 
00129 /*
00130  * Access macros for array header fields.
00131  *
00132  * ARR_DIMS returns a pointer to an array of array dimensions (number of
00133  * elements along the various array axes).
00134  *
00135  * ARR_LBOUND returns a pointer to an array of array lower bounds.
00136  *
00137  * That is: if the third axis of an array has elements 5 through 8, then
00138  * ARR_DIMS(a)[2] == 4 and ARR_LBOUND(a)[2] == 5.
00139  *
00140  * Unlike C, the default lower bound is 1.
00141  */
00142 #define ARR_SIZE(a)             VARSIZE(a)
00143 #define ARR_NDIM(a)             ((a)->ndim)
00144 #define ARR_HASNULL(a)          ((a)->dataoffset != 0)
00145 #define ARR_ELEMTYPE(a)         ((a)->elemtype)
00146 
00147 #define ARR_DIMS(a) \
00148         ((int *) (((char *) (a)) + sizeof(ArrayType)))
00149 #define ARR_LBOUND(a) \
00150         ((int *) (((char *) (a)) + sizeof(ArrayType) + \
00151                   sizeof(int) * ARR_NDIM(a)))
00152 
00153 #define ARR_NULLBITMAP(a) \
00154         (ARR_HASNULL(a) ? \
00155          (bits8 *) (((char *) (a)) + sizeof(ArrayType) + \
00156                     2 * sizeof(int) * ARR_NDIM(a)) \
00157          : (bits8 *) NULL)
00158 
00159 /*
00160  * The total array header size (in bytes) for an array with the specified
00161  * number of dimensions and total number of items.
00162  */
00163 #define ARR_OVERHEAD_NONULLS(ndims) \
00164         MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims))
00165 #define ARR_OVERHEAD_WITHNULLS(ndims, nitems) \
00166         MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims) + \
00167                  ((nitems) + 7) / 8)
00168 
00169 #define ARR_DATA_OFFSET(a) \
00170         (ARR_HASNULL(a) ? (a)->dataoffset : ARR_OVERHEAD_NONULLS(ARR_NDIM(a)))
00171 
00172 /*
00173  * Returns a pointer to the actual array data.
00174  */
00175 #define ARR_DATA_PTR(a) \
00176         (((char *) (a)) + ARR_DATA_OFFSET(a))
00177 
00178 
00179 /*
00180  * GUC parameter
00181  */
00182 extern bool Array_nulls;
00183 
00184 /*
00185  * prototypes for functions defined in arrayfuncs.c
00186  */
00187 extern Datum array_in(PG_FUNCTION_ARGS);
00188 extern Datum array_out(PG_FUNCTION_ARGS);
00189 extern Datum array_recv(PG_FUNCTION_ARGS);
00190 extern Datum array_send(PG_FUNCTION_ARGS);
00191 extern Datum array_eq(PG_FUNCTION_ARGS);
00192 extern Datum array_ne(PG_FUNCTION_ARGS);
00193 extern Datum array_lt(PG_FUNCTION_ARGS);
00194 extern Datum array_gt(PG_FUNCTION_ARGS);
00195 extern Datum array_le(PG_FUNCTION_ARGS);
00196 extern Datum array_ge(PG_FUNCTION_ARGS);
00197 extern Datum btarraycmp(PG_FUNCTION_ARGS);
00198 extern Datum hash_array(PG_FUNCTION_ARGS);
00199 extern Datum arrayoverlap(PG_FUNCTION_ARGS);
00200 extern Datum arraycontains(PG_FUNCTION_ARGS);
00201 extern Datum arraycontained(PG_FUNCTION_ARGS);
00202 extern Datum array_ndims(PG_FUNCTION_ARGS);
00203 extern Datum array_dims(PG_FUNCTION_ARGS);
00204 extern Datum array_lower(PG_FUNCTION_ARGS);
00205 extern Datum array_upper(PG_FUNCTION_ARGS);
00206 extern Datum array_length(PG_FUNCTION_ARGS);
00207 extern Datum array_larger(PG_FUNCTION_ARGS);
00208 extern Datum array_smaller(PG_FUNCTION_ARGS);
00209 extern Datum generate_subscripts(PG_FUNCTION_ARGS);
00210 extern Datum generate_subscripts_nodir(PG_FUNCTION_ARGS);
00211 extern Datum array_fill(PG_FUNCTION_ARGS);
00212 extern Datum array_fill_with_lower_bounds(PG_FUNCTION_ARGS);
00213 extern Datum array_unnest(PG_FUNCTION_ARGS);
00214 extern Datum array_remove(PG_FUNCTION_ARGS);
00215 extern Datum array_replace(PG_FUNCTION_ARGS);
00216 
00217 extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx,
00218           int arraytyplen, int elmlen, bool elmbyval, char elmalign,
00219           bool *isNull);
00220 extern ArrayType *array_set(ArrayType *array, int nSubscripts, int *indx,
00221           Datum dataValue, bool isNull,
00222           int arraytyplen, int elmlen, bool elmbyval, char elmalign);
00223 extern ArrayType *array_get_slice(ArrayType *array, int nSubscripts,
00224                 int *upperIndx, int *lowerIndx,
00225                 int arraytyplen, int elmlen, bool elmbyval, char elmalign);
00226 extern ArrayType *array_set_slice(ArrayType *array, int nSubscripts,
00227                 int *upperIndx, int *lowerIndx,
00228                 ArrayType *srcArray, bool isNull,
00229                 int arraytyplen, int elmlen, bool elmbyval, char elmalign);
00230 
00231 extern Datum array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType,
00232           ArrayMapState *amstate);
00233 
00234 extern void array_bitmap_copy(bits8 *destbitmap, int destoffset,
00235                   const bits8 *srcbitmap, int srcoffset,
00236                   int nitems);
00237 
00238 extern ArrayType *construct_array(Datum *elems, int nelems,
00239                 Oid elmtype,
00240                 int elmlen, bool elmbyval, char elmalign);
00241 extern ArrayType *construct_md_array(Datum *elems,
00242                    bool *nulls,
00243                    int ndims,
00244                    int *dims,
00245                    int *lbs,
00246                    Oid elmtype, int elmlen, bool elmbyval, char elmalign);
00247 extern ArrayType *construct_empty_array(Oid elmtype);
00248 extern void deconstruct_array(ArrayType *array,
00249                   Oid elmtype,
00250                   int elmlen, bool elmbyval, char elmalign,
00251                   Datum **elemsp, bool **nullsp, int *nelemsp);
00252 extern bool array_contains_nulls(ArrayType *array);
00253 extern ArrayBuildState *accumArrayResult(ArrayBuildState *astate,
00254                  Datum dvalue, bool disnull,
00255                  Oid element_type,
00256                  MemoryContext rcontext);
00257 extern Datum makeArrayResult(ArrayBuildState *astate,
00258                 MemoryContext rcontext);
00259 extern Datum makeMdArrayResult(ArrayBuildState *astate, int ndims,
00260                   int *dims, int *lbs, MemoryContext rcontext, bool release);
00261 
00262 extern ArrayIterator array_create_iterator(ArrayType *arr, int slice_ndim);
00263 extern bool array_iterate(ArrayIterator iterator, Datum *value, bool *isnull);
00264 extern void array_free_iterator(ArrayIterator iterator);
00265 
00266 /*
00267  * prototypes for functions defined in arrayutils.c
00268  */
00269 
00270 extern int  ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx);
00271 extern int  ArrayGetOffset0(int n, const int *tup, const int *scale);
00272 extern int  ArrayGetNItems(int ndim, const int *dims);
00273 extern void mda_get_range(int n, int *span, const int *st, const int *endp);
00274 extern void mda_get_prod(int n, const int *range, int *prod);
00275 extern void mda_get_offset_values(int n, int *dist, const int *prod, const int *span);
00276 extern int  mda_next_tuple(int n, int *curr, const int *span);
00277 extern int32 *ArrayGetIntegerTypmods(ArrayType *arr, int *n);
00278 
00279 /*
00280  * prototypes for functions defined in array_userfuncs.c
00281  */
00282 extern Datum array_push(PG_FUNCTION_ARGS);
00283 extern Datum array_cat(PG_FUNCTION_ARGS);
00284 
00285 extern ArrayType *create_singleton_array(FunctionCallInfo fcinfo,
00286                        Oid element_type,
00287                        Datum element,
00288                        bool isNull,
00289                        int ndims);
00290 
00291 extern Datum array_agg_transfn(PG_FUNCTION_ARGS);
00292 extern Datum array_agg_finalfn(PG_FUNCTION_ARGS);
00293 
00294 /*
00295  * prototypes for functions defined in array_typanalyze.c
00296  */
00297 extern Datum array_typanalyze(PG_FUNCTION_ARGS);
00298 
00299 #endif   /* ARRAY_H */