LCOV - code coverage report
Current view: top level - src/include/utils - arrayaccess.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 37 37
Test Date: 2026-03-03 13:15:30 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            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              :     bits8      *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
      54      9145193 : array_iter_setup(array_iter *it, AnyArrayType *a,
      55              :                  int elmlen, bool elmbyval, char elmalign)
      56              : {
      57      9145193 :     if (VARATT_IS_EXPANDED_HEADER(a))
      58              :     {
      59         3742 :         if (a->xpn.dvalues)
      60              :         {
      61         1365 :             it->datumptr = a->xpn.dvalues;
      62         1365 :             it->isnullptr = a->xpn.dnulls;
      63              :             /* we must fill all fields to prevent compiler warnings */
      64         1365 :             it->dataptr = NULL;
      65         1365 :             it->bitmapptr = NULL;
      66              :         }
      67              :         else
      68              :         {
      69              :             /* Work with flat array embedded in the expanded datum */
      70         2377 :             it->datumptr = NULL;
      71         2377 :             it->isnullptr = NULL;
      72         2377 :             it->dataptr = ARR_DATA_PTR(a->xpn.fvalue);
      73         2377 :             it->bitmapptr = ARR_NULLBITMAP(a->xpn.fvalue);
      74              :         }
      75              :     }
      76              :     else
      77              :     {
      78      9141451 :         it->datumptr = NULL;
      79      9141451 :         it->isnullptr = NULL;
      80      9141451 :         it->dataptr = ARR_DATA_PTR((ArrayType *) a);
      81      9141451 :         it->bitmapptr = ARR_NULLBITMAP((ArrayType *) a);
      82              :     }
      83      9145193 :     it->bitmask = 1;
      84      9145193 :     it->elmlen = elmlen;
      85      9145193 :     it->elmbyval = elmbyval;
      86      9145193 :     it->elmalignby = typalign_to_alignby(elmalign);
      87      9145193 : }
      88              : 
      89              : static inline Datum
      90     17118702 : array_iter_next(array_iter *it, bool *isnull, int i)
      91              : {
      92              :     Datum       ret;
      93              : 
      94     17118702 :     if (it->datumptr)
      95              :     {
      96        91662 :         ret = it->datumptr[i];
      97        91662 :         *isnull = it->isnullptr ? it->isnullptr[i] : false;
      98              :     }
      99              :     else
     100              :     {
     101     17027040 :         if (it->bitmapptr && (*(it->bitmapptr) & it->bitmask) == 0)
     102              :         {
     103        17299 :             *isnull = true;
     104        17299 :             ret = (Datum) 0;
     105              :         }
     106              :         else
     107              :         {
     108     17009741 :             *isnull = false;
     109     17009741 :             ret = fetch_att(it->dataptr, it->elmbyval, it->elmlen);
     110     17009741 :             it->dataptr = att_addlength_pointer(it->dataptr, it->elmlen,
     111              :                                                 it->dataptr);
     112     17009741 :             it->dataptr = (char *) att_nominal_alignby(it->dataptr,
     113              :                                                        it->elmalignby);
     114              :         }
     115     17027040 :         it->bitmask <<= 1;
     116     17027040 :         if (it->bitmask == 0x100)
     117              :         {
     118       100870 :             if (it->bitmapptr)
     119         3891 :                 it->bitmapptr++;
     120       100870 :             it->bitmask = 1;
     121              :         }
     122              :     }
     123              : 
     124     17118702 :     return ret;
     125              : }
     126              : 
     127              : #endif                          /* ARRAYACCESS_H */
        

Generated by: LCOV version 2.0-1