Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * arrayaccess.h
4 : : * Declarations for element-by-element access to Postgres arrays.
5 : : *
6 : : *
7 : : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
8 : : * Portions Copyright (c) 1994, Regents of the University of California
9 : : *
10 : : * src/include/utils/arrayaccess.h
11 : : *
12 : : *-------------------------------------------------------------------------
13 : : */
14 : : #ifndef ARRAYACCESS_H
15 : : #define ARRAYACCESS_H
16 : :
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,
26 : : * and "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.
31 : : */
32 : :
33 : : typedef struct array_iter
34 : : {
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 : : uint8 *bitmapptr; /* Current byte of the nulls bitmap, or NULL */
44 : : int bitmask; /* mask for current bit in nulls bitmap */
45 : :
46 : : /* Fields used in both cases: data about array's element type */
47 : : int elmlen;
48 : : bool elmbyval;
49 : : uint8 elmalignby;
50 : : } array_iter;
51 : :
52 : :
53 : : static inline void
92 tgl@sss.pgh.pa.us 54 :GNC 12404288 : array_iter_setup(array_iter *it, AnyArrayType *a,
55 : : int elmlen, bool elmbyval, char elmalign)
56 : : {
4009 tgl@sss.pgh.pa.us 57 [ + + ]:CBC 12404288 : if (VARATT_IS_EXPANDED_HEADER(a))
58 : : {
59 [ + + ]: 5006 : if (a->xpn.dvalues)
60 : : {
61 : 1819 : it->datumptr = a->xpn.dvalues;
62 : 1819 : it->isnullptr = a->xpn.dnulls;
63 : : /* we must fill all fields to prevent compiler warnings */
64 : 1819 : it->dataptr = NULL;
65 : 1819 : it->bitmapptr = NULL;
66 : : }
67 : : else
68 : : {
69 : : /* Work with flat array embedded in the expanded datum */
70 : 3187 : it->datumptr = NULL;
71 : 3187 : it->isnullptr = NULL;
72 [ - + ]: 3187 : it->dataptr = ARR_DATA_PTR(a->xpn.fvalue);
73 [ - + ]: 3187 : it->bitmapptr = ARR_NULLBITMAP(a->xpn.fvalue);
74 : : }
75 : : }
76 : : else
77 : : {
78 : 12399282 : it->datumptr = NULL;
79 : 12399282 : it->isnullptr = NULL;
2501 noah@leadboat.com 80 [ + + ]: 12399282 : it->dataptr = ARR_DATA_PTR((ArrayType *) a);
81 [ + + ]: 12399282 : it->bitmapptr = ARR_NULLBITMAP((ArrayType *) a);
82 : : }
4009 tgl@sss.pgh.pa.us 83 : 12404288 : it->bitmask = 1;
92 tgl@sss.pgh.pa.us 84 :GNC 12404288 : it->elmlen = elmlen;
85 : 12404288 : it->elmbyval = elmbyval;
86 : 12404288 : it->elmalignby = typalign_to_alignby(elmalign);
4009 tgl@sss.pgh.pa.us 87 :CBC 12404288 : }
88 : :
89 : : static inline Datum
92 tgl@sss.pgh.pa.us 90 :GNC 23152634 : array_iter_next(array_iter *it, bool *isnull, int i)
91 : : {
92 : : Datum ret;
93 : :
4009 tgl@sss.pgh.pa.us 94 [ + + ]:CBC 23152634 : if (it->datumptr)
95 : : {
96 : 122214 : ret = it->datumptr[i];
97 [ - + - - ]: 122214 : *isnull = it->isnullptr ? it->isnullptr[i] : false;
98 : : }
99 : : else
100 : : {
101 [ + + + + ]: 23030420 : if (it->bitmapptr && (*(it->bitmapptr) & it->bitmask) == 0)
102 : : {
103 : 23107 : *isnull = true;
104 : 23107 : ret = (Datum) 0;
105 : : }
106 : : else
107 : : {
108 : 23007313 : *isnull = false;
92 tgl@sss.pgh.pa.us 109 :GNC 23007313 : ret = fetch_att(it->dataptr, it->elmbyval, it->elmlen);
110 [ + + + - : 23007313 : it->dataptr = att_addlength_pointer(it->dataptr, it->elmlen,
- - ]
111 : : it->dataptr);
112 : 23007313 : it->dataptr = (char *) att_nominal_alignby(it->dataptr,
113 : : it->elmalignby);
114 : : }
4009 tgl@sss.pgh.pa.us 115 :CBC 23030420 : it->bitmask <<= 1;
116 [ + + ]: 23030420 : if (it->bitmask == 0x100)
117 : : {
118 [ + + ]: 116604 : if (it->bitmapptr)
119 : 5217 : it->bitmapptr++;
120 : 116604 : it->bitmask = 1;
121 : : }
122 : : }
123 : :
124 : 23152634 : return ret;
125 : : }
126 : :
127 : : #endif /* ARRAYACCESS_H */
|