mirror of
https://github.com/postgres/postgres.git
synced 2026-04-01 23:36:06 -04:00
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
127 lines
3.2 KiB
C
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 */
|