codekingpro/portable-devtools
115k
1/*-------------------------------------------------------------------------2 *3 * arrayaccess.h4 * Declarations for element-by-element access to Postgres arrays.5 *6 *7 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group8 * Portions Copyright (c) 1994, Regents of the University of California9 *10 * src/include/utils/arrayaccess.h11 *12 *-------------------------------------------------------------------------13 */14#ifndef ARRAYACCESS_H15#define ARRAYACCESS_H16 17#include "access/tupmacs.h"18#include "utils/array.h"19 20 21/*22 * Functions for iterating through elements of a flat or expanded array.23 * These require a state struct "array_iter iter".24 *25 * Use "array_iter_setup(&iter, arrayptr);" to prepare to iterate, and26 * "datumvar = array_iter_next(&iter, &isnullvar, index, ...);" to fetch27 * the next element into datumvar/isnullvar.28 * "index" must be the zero-origin element number; we make caller provide29 * this since caller is generally counting the elements anyway. Despite30 * that, these functions can only fetch elements sequentially.31 */32 33typedef struct array_iter34{35 /* datumptr being NULL or not tells if we have flat or expanded array */36 37 /* Fields used when we have an expanded array */38 Datum *datumptr; /* Pointer to Datum array */39 bool *isnullptr; /* Pointer to isnull array */40 41 /* Fields used when we have a flat array */42 char *dataptr; /* Current spot in the data area */43 bits8 *bitmapptr; /* Current byte of the nulls bitmap, or NULL */44 int bitmask; /* mask for current bit in nulls bitmap */45} array_iter;46 47 48static inline void49array_iter_setup(array_iter *it, AnyArrayType *a)50{51 if (VARATT_IS_EXPANDED_HEADER(a))52 {53 if (a->xpn.dvalues)54 {55 it->datumptr = a->xpn.dvalues;56 it->isnullptr = a->xpn.dnulls;57 /* we must fill all fields to prevent compiler warnings */58 it->dataptr = NULL;59 it->bitmapptr = NULL;60 }61 else62 {63 /* Work with flat array embedded in the expanded datum */64 it->datumptr = NULL;65 it->isnullptr = NULL;66 it->dataptr = ARR_DATA_PTR(a->xpn.fvalue);67 it->bitmapptr = ARR_NULLBITMAP(a->xpn.fvalue);68 }69 }70 else71 {72 it->datumptr = NULL;73 it->isnullptr = NULL;74 it->dataptr = ARR_DATA_PTR((ArrayType *) a);75 it->bitmapptr = ARR_NULLBITMAP((ArrayType *) a);76 }77 it->bitmask = 1;78}79 80static inline Datum81array_iter_next(array_iter *it, bool *isnull, int i,82 int elmlen, bool elmbyval, char elmalign)83{84 Datum ret;85 86 if (it->datumptr)87 {88 ret = it->datumptr[i];89 *isnull = it->isnullptr ? it->isnullptr[i] : false;90 }91 else92 {93 if (it->bitmapptr && (*(it->bitmapptr) & it->bitmask) == 0)94 {95 *isnull = true;96 ret = (Datum) 0;97 }98 else99 {100 *isnull = false;101 ret = fetch_att(it->dataptr, elmbyval, elmlen);102 it->dataptr = att_addlength_pointer(it->dataptr, elmlen,103 it->dataptr);104 it->dataptr = (char *) att_align_nominal(it->dataptr, elmalign);105 }106 it->bitmask <<= 1;107 if (it->bitmask == 0x100)108 {109 if (it->bitmapptr)110 it->bitmapptr++;111 it->bitmask = 1;112 }113 }114 115 return ret;116}117 118#endif /* ARRAYACCESS_H */119 