postgresql/src/include/utils/arrayaccess.h
Nathan Bossart bab2f27eaa Remove bits* typedefs.
In addition to removing the bits8, bits16, and bits32 typedefs,
this commit replaces all uses with uint8, uint16, or uint32.  bits*
provided little benefit beyond establishing the intent of the
variable, and they were inconsistently used for that purpose.
Third-party code should instead use the corresponding uint*
typedef.

Suggested-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Discussion: https://postgr.es/m/absbX33E4eaA0Ity%40nathan
2026-03-30 16:12:08 -05:00

127 lines
3.2 KiB
C

/*-------------------------------------------------------------------------
*
* arrayaccess.h
* Declarations for element-by-element access to Postgres arrays.
*
*
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/utils/arrayaccess.h
*
*-------------------------------------------------------------------------
*/
#ifndef ARRAYACCESS_H
#define ARRAYACCESS_H
#include "access/tupmacs.h"
#include "utils/array.h"
/*
* Functions for iterating through elements of a flat or expanded array.
* These require a state struct "array_iter iter".
*
* Use "array_iter_setup(&iter, arrayptr, ...);" to prepare to iterate,
* and "datumvar = array_iter_next(&iter, &isnullvar, index);" to fetch
* the next element into datumvar/isnullvar.
* "index" must be the zero-origin element number; we make caller provide
* this since caller is generally counting the elements anyway. Despite
* that, these functions can only fetch elements sequentially.
*/
typedef struct array_iter
{
/* datumptr being NULL or not tells if we have flat or expanded array */
/* Fields used when we have an expanded array */
Datum *datumptr; /* Pointer to Datum array */
bool *isnullptr; /* Pointer to isnull array */
/* Fields used when we have a flat array */
char *dataptr; /* Current spot in the data area */
uint8 *bitmapptr; /* Current byte of the nulls bitmap, or NULL */
int bitmask; /* mask for current bit in nulls bitmap */
/* Fields used in both cases: data about array's element type */
int elmlen;
bool elmbyval;
uint8 elmalignby;
} array_iter;
static inline void
array_iter_setup(array_iter *it, AnyArrayType *a,
int elmlen, bool elmbyval, char elmalign)
{
if (VARATT_IS_EXPANDED_HEADER(a))
{
if (a->xpn.dvalues)
{
it->datumptr = a->xpn.dvalues;
it->isnullptr = a->xpn.dnulls;
/* we must fill all fields to prevent compiler warnings */
it->dataptr = NULL;
it->bitmapptr = NULL;
}
else
{
/* Work with flat array embedded in the expanded datum */
it->datumptr = NULL;
it->isnullptr = NULL;
it->dataptr = ARR_DATA_PTR(a->xpn.fvalue);
it->bitmapptr = ARR_NULLBITMAP(a->xpn.fvalue);
}
}
else
{
it->datumptr = NULL;
it->isnullptr = NULL;
it->dataptr = ARR_DATA_PTR((ArrayType *) a);
it->bitmapptr = ARR_NULLBITMAP((ArrayType *) a);
}
it->bitmask = 1;
it->elmlen = elmlen;
it->elmbyval = elmbyval;
it->elmalignby = typalign_to_alignby(elmalign);
}
static inline Datum
array_iter_next(array_iter *it, bool *isnull, int i)
{
Datum ret;
if (it->datumptr)
{
ret = it->datumptr[i];
*isnull = it->isnullptr ? it->isnullptr[i] : false;
}
else
{
if (it->bitmapptr && (*(it->bitmapptr) & it->bitmask) == 0)
{
*isnull = true;
ret = (Datum) 0;
}
else
{
*isnull = false;
ret = fetch_att(it->dataptr, it->elmbyval, it->elmlen);
it->dataptr = att_addlength_pointer(it->dataptr, it->elmlen,
it->dataptr);
it->dataptr = (char *) att_nominal_alignby(it->dataptr,
it->elmalignby);
}
it->bitmask <<= 1;
if (it->bitmask == 0x100)
{
if (it->bitmapptr)
it->bitmapptr++;
it->bitmask = 1;
}
}
return ret;
}
#endif /* ARRAYACCESS_H */