1 /*-------------------------------------------------------------------------
4 * Declarations for element-by-element access to Postgres arrays.
7 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * src/include/utils/arrayaccess.h
12 *-------------------------------------------------------------------------
17 #include "access/tupmacs.h"
18 #include "utils/array.h"
22 * Functions for iterating through elements of a flat or expanded array.
23 * These require a state struct "array_iter iter".
25 * Use "array_iter_setup(&iter, arrayptr);" to prepare to iterate, and
26 * "datumvar = array_iter_next(&iter, &isnullvar, index, ...);" to fetch
27 * the next element into datumvar/isnullvar.
28 * "index" must be the zero-origin element number; we make caller provide
29 * this since caller is generally counting the elements anyway. Despite
30 * that, these functions can only fetch elements sequentially.
33 typedef struct array_iter
35 /* datumptr being NULL or not tells if we have flat or expanded array */
37 /* Fields used when we have an expanded array */
38 Datum
*datumptr
; /* Pointer to Datum array */
39 bool *isnullptr
; /* Pointer to isnull array */
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 */
49 array_iter_setup(array_iter
*it
, AnyArrayType
*a
)
51 if (VARATT_IS_EXPANDED_HEADER(a
))
55 it
->datumptr
= a
->xpn
.dvalues
;
56 it
->isnullptr
= a
->xpn
.dnulls
;
57 /* we must fill all fields to prevent compiler warnings */
63 /* Work with flat array embedded in the expanded datum */
66 it
->dataptr
= ARR_DATA_PTR(a
->xpn
.fvalue
);
67 it
->bitmapptr
= ARR_NULLBITMAP(a
->xpn
.fvalue
);
74 it
->dataptr
= ARR_DATA_PTR((ArrayType
*) a
);
75 it
->bitmapptr
= ARR_NULLBITMAP((ArrayType
*) a
);
81 array_iter_next(array_iter
*it
, bool *isnull
, int i
,
82 int elmlen
, bool elmbyval
, char elmalign
)
88 ret
= it
->datumptr
[i
];
89 *isnull
= it
->isnullptr
? it
->isnullptr
[i
] : false;
93 if (it
->bitmapptr
&& (*(it
->bitmapptr
) & it
->bitmask
) == 0)
101 ret
= fetch_att(it
->dataptr
, elmbyval
, elmlen
);
102 it
->dataptr
= att_addlength_pointer(it
->dataptr
, elmlen
,
104 it
->dataptr
= (char *) att_align_nominal(it
->dataptr
, elmalign
);
107 if (it
->bitmask
== 0x100)
118 #endif /* ARRAYACCESS_H */