LCOV - code coverage report
Current view: top level - src/include - varatt.h (source / functions) Coverage Total Hit
Test: Code coverage Lines: 95.6 % 90 86
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 33 33
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 90.0 % 30 27

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * varatt.h
       4                 :             :  *        variable-length datatypes (TOAST support)
       5                 :             :  *
       6                 :             :  *
       7                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       8                 :             :  * Portions Copyright (c) 1995, Regents of the University of California
       9                 :             :  *
      10                 :             :  * src/include/varatt.h
      11                 :             :  *
      12                 :             :  *-------------------------------------------------------------------------
      13                 :             :  */
      14                 :             : 
      15                 :             : #ifndef VARATT_H
      16                 :             : #define VARATT_H
      17                 :             : 
      18                 :             : /*
      19                 :             :  * struct varatt_external is a traditional "TOAST pointer", that is, the
      20                 :             :  * information needed to fetch a Datum stored out-of-line in a TOAST table.
      21                 :             :  * The data is compressed if and only if the external size stored in
      22                 :             :  * va_extinfo is less than va_rawsize - VARHDRSZ.
      23                 :             :  *
      24                 :             :  * This struct must not contain any padding, because we sometimes compare
      25                 :             :  * these pointers using memcmp.
      26                 :             :  *
      27                 :             :  * Note that this information is stored unaligned within actual tuples, so
      28                 :             :  * you need to memcpy from the tuple into a local struct variable before
      29                 :             :  * you can look at these fields!  (The reason we use memcmp is to avoid
      30                 :             :  * having to do that just to detect equality of two TOAST pointers...)
      31                 :             :  */
      32                 :             : typedef struct varatt_external
      33                 :             : {
      34                 :             :         int32           va_rawsize;             /* Original data size (includes header) */
      35                 :             :         uint32          va_extinfo;             /* External saved size (without header) and
      36                 :             :                                                                  * compression method */
      37                 :             :         Oid                     va_valueid;             /* Unique ID of value within TOAST table */
      38                 :             :         Oid                     va_toastrelid;  /* RelID of TOAST table containing it */
      39                 :             : }                       varatt_external;
      40                 :             : 
      41                 :             : /*
      42                 :             :  * These macros define the "saved size" portion of va_extinfo.  Its remaining
      43                 :             :  * two high-order bits identify the compression method.
      44                 :             :  */
      45                 :             : #define VARLENA_EXTSIZE_BITS    30
      46                 :             : #define VARLENA_EXTSIZE_MASK    ((1U << VARLENA_EXTSIZE_BITS) - 1)
      47                 :             : 
      48                 :             : /*
      49                 :             :  * struct varatt_indirect is a "TOAST pointer" representing an out-of-line
      50                 :             :  * Datum that's stored in memory, not in an external toast relation.
      51                 :             :  * The creator of such a Datum is entirely responsible that the referenced
      52                 :             :  * storage survives for as long as referencing pointer Datums can exist.
      53                 :             :  *
      54                 :             :  * Note that just as for struct varatt_external, this struct is stored
      55                 :             :  * unaligned within any containing tuple.
      56                 :             :  */
      57                 :             : typedef struct varatt_indirect
      58                 :             : {
      59                 :             :         struct varlena *pointer;        /* Pointer to in-memory varlena */
      60                 :             : }                       varatt_indirect;
      61                 :             : 
      62                 :             : /*
      63                 :             :  * struct varatt_expanded is a "TOAST pointer" representing an out-of-line
      64                 :             :  * Datum that is stored in memory, in some type-specific, not necessarily
      65                 :             :  * physically contiguous format that is convenient for computation not
      66                 :             :  * storage.  APIs for this, in particular the definition of struct
      67                 :             :  * ExpandedObjectHeader, are in src/include/utils/expandeddatum.h.
      68                 :             :  *
      69                 :             :  * Note that just as for struct varatt_external, this struct is stored
      70                 :             :  * unaligned within any containing tuple.
      71                 :             :  */
      72                 :             : typedef struct ExpandedObjectHeader ExpandedObjectHeader;
      73                 :             : 
      74                 :             : typedef struct varatt_expanded
      75                 :             : {
      76                 :             :         ExpandedObjectHeader *eohptr;
      77                 :             : } varatt_expanded;
      78                 :             : 
      79                 :             : /*
      80                 :             :  * Type tag for the various sorts of "TOAST pointer" datums.  The peculiar
      81                 :             :  * value for VARTAG_ONDISK comes from a requirement for on-disk compatibility
      82                 :             :  * with a previous notion that the tag field was the pointer datum's length.
      83                 :             :  */
      84                 :             : typedef enum vartag_external
      85                 :             : {
      86                 :             :         VARTAG_INDIRECT = 1,
      87                 :             :         VARTAG_EXPANDED_RO = 2,
      88                 :             :         VARTAG_EXPANDED_RW = 3,
      89                 :             :         VARTAG_ONDISK = 18
      90                 :             : } vartag_external;
      91                 :             : 
      92                 :             : /* Is a TOAST pointer either type of expanded-object pointer? */
      93                 :             : /* this test relies on the specific tag values above */
      94                 :             : static inline bool
      95                 :       30823 : VARTAG_IS_EXPANDED(vartag_external tag)
      96                 :             : {
      97                 :       30823 :         return ((tag & ~1) == VARTAG_EXPANDED_RO);
      98                 :             : }
      99                 :             : 
     100                 :             : /* Size of the data part of a "TOAST pointer" datum */
     101                 :             : static inline Size
     102                 :        4247 : VARTAG_SIZE(vartag_external tag)
     103                 :             : {
     104         [ +  + ]:        4247 :         if (tag == VARTAG_INDIRECT)
     105                 :         288 :                 return sizeof(varatt_indirect);
     106         [ -  + ]:        3959 :         else if (VARTAG_IS_EXPANDED(tag))
     107                 :           0 :                 return sizeof(varatt_expanded);
     108         [ +  - ]:        3959 :         else if (tag == VARTAG_ONDISK)
     109                 :        3959 :                 return sizeof(varatt_external);
     110                 :             :         else
     111                 :             :         {
     112                 :           0 :                 Assert(false);
     113                 :           0 :                 return 0;
     114                 :             :         }
     115                 :        4247 : }
     116                 :             : 
     117                 :             : /*
     118                 :             :  * These structs describe the header of a varlena object that may have been
     119                 :             :  * TOASTed.  Generally, don't reference these structs directly, but use the
     120                 :             :  * functions and macros below.
     121                 :             :  *
     122                 :             :  * We use separate structs for the aligned and unaligned cases because the
     123                 :             :  * compiler might otherwise think it could generate code that assumes
     124                 :             :  * alignment while touching fields of a 1-byte-header varlena.
     125                 :             :  */
     126                 :             : typedef union
     127                 :             : {
     128                 :             :         struct                                          /* Normal varlena (4-byte length) */
     129                 :             :         {
     130                 :             :                 uint32          va_header;
     131                 :             :                 char            va_data[FLEXIBLE_ARRAY_MEMBER];
     132                 :             :         }                       va_4byte;
     133                 :             :         struct                                          /* Compressed-in-line format */
     134                 :             :         {
     135                 :             :                 uint32          va_header;
     136                 :             :                 uint32          va_tcinfo;      /* Original data size (excludes header) and
     137                 :             :                                                                  * compression method; see va_extinfo */
     138                 :             :                 char            va_data[FLEXIBLE_ARRAY_MEMBER]; /* Compressed data */
     139                 :             :         }                       va_compressed;
     140                 :             : } varattrib_4b;
     141                 :             : 
     142                 :             : typedef struct
     143                 :             : {
     144                 :             :         uint8           va_header;
     145                 :             :         char            va_data[FLEXIBLE_ARRAY_MEMBER]; /* Data begins here */
     146                 :             : } varattrib_1b;
     147                 :             : 
     148                 :             : /* TOAST pointers are a subset of varattrib_1b with an identifying tag byte */
     149                 :             : typedef struct
     150                 :             : {
     151                 :             :         uint8           va_header;              /* Always 0x80 or 0x01 */
     152                 :             :         uint8           va_tag;                 /* Type of datum */
     153                 :             :         char            va_data[FLEXIBLE_ARRAY_MEMBER]; /* Type-specific data */
     154                 :             : } varattrib_1b_e;
     155                 :             : 
     156                 :             : /*
     157                 :             :  * Bit layouts for varlena headers on big-endian machines:
     158                 :             :  *
     159                 :             :  * 00xxxxxx 4-byte length word, aligned, uncompressed data (up to 1G)
     160                 :             :  * 01xxxxxx 4-byte length word, aligned, *compressed* data (up to 1G)
     161                 :             :  * 10000000 1-byte length word, unaligned, TOAST pointer
     162                 :             :  * 1xxxxxxx 1-byte length word, unaligned, uncompressed data (up to 126b)
     163                 :             :  *
     164                 :             :  * Bit layouts for varlena headers on little-endian machines:
     165                 :             :  *
     166                 :             :  * xxxxxx00 4-byte length word, aligned, uncompressed data (up to 1G)
     167                 :             :  * xxxxxx10 4-byte length word, aligned, *compressed* data (up to 1G)
     168                 :             :  * 00000001 1-byte length word, unaligned, TOAST pointer
     169                 :             :  * xxxxxxx1 1-byte length word, unaligned, uncompressed data (up to 126b)
     170                 :             :  *
     171                 :             :  * The "xxx" bits are the length field (which includes itself in all cases).
     172                 :             :  * In the big-endian case we mask to extract the length, in the little-endian
     173                 :             :  * case we shift.  Note that in both cases the flag bits are in the physically
     174                 :             :  * first byte.  Also, it is not possible for a 1-byte length word to be zero;
     175                 :             :  * this lets us disambiguate alignment padding bytes from the start of an
     176                 :             :  * unaligned datum.  (We now *require* pad bytes to be filled with zero!)
     177                 :             :  *
     178                 :             :  * In TOAST pointers the va_tag field (see varattrib_1b_e) is used to discern
     179                 :             :  * the specific type and length of the pointer datum.
     180                 :             :  */
     181                 :             : 
     182                 :             : /*
     183                 :             :  * Endian-dependent macros.  These are considered internal --- use the
     184                 :             :  * external functions below instead of using these directly.  All of these
     185                 :             :  * expect an argument that is a pointer, not a Datum.  Some of them have
     186                 :             :  * multiple-evaluation hazards, too.
     187                 :             :  *
     188                 :             :  * Note: IS_1B is true for external toast records but VARSIZE_1B will return 0
     189                 :             :  * for such records. Hence you should usually check for IS_EXTERNAL before
     190                 :             :  * checking for IS_1B.
     191                 :             :  */
     192                 :             : 
     193                 :             : #ifdef WORDS_BIGENDIAN
     194                 :             : 
     195                 :             : #define VARATT_IS_4B(PTR) \
     196                 :             :         ((((varattrib_1b *) (PTR))->va_header & 0x80) == 0x00)
     197                 :             : #define VARATT_IS_4B_U(PTR) \
     198                 :             :         ((((varattrib_1b *) (PTR))->va_header & 0xC0) == 0x00)
     199                 :             : #define VARATT_IS_4B_C(PTR) \
     200                 :             :         ((((varattrib_1b *) (PTR))->va_header & 0xC0) == 0x40)
     201                 :             : #define VARATT_IS_1B(PTR) \
     202                 :             :         ((((varattrib_1b *) (PTR))->va_header & 0x80) == 0x80)
     203                 :             : #define VARATT_IS_1B_E(PTR) \
     204                 :             :         ((((varattrib_1b *) (PTR))->va_header) == 0x80)
     205                 :             : #define VARATT_NOT_PAD_BYTE(PTR) \
     206                 :             :         (*((uint8 *) (PTR)) != 0)
     207                 :             : 
     208                 :             : /* VARSIZE_4B() should only be used on known-aligned data */
     209                 :             : #define VARSIZE_4B(PTR) \
     210                 :             :         (((varattrib_4b *) (PTR))->va_4byte.va_header & 0x3FFFFFFF)
     211                 :             : #define VARSIZE_1B(PTR) \
     212                 :             :         (((varattrib_1b *) (PTR))->va_header & 0x7F)
     213                 :             : #define VARTAG_1B_E(PTR) \
     214                 :             :         ((vartag_external) ((varattrib_1b_e *) (PTR))->va_tag)
     215                 :             : 
     216                 :             : #define SET_VARSIZE_4B(PTR,len) \
     217                 :             :         (((varattrib_4b *) (PTR))->va_4byte.va_header = (len) & 0x3FFFFFFF)
     218                 :             : #define SET_VARSIZE_4B_C(PTR,len) \
     219                 :             :         (((varattrib_4b *) (PTR))->va_4byte.va_header = ((len) & 0x3FFFFFFF) | 0x40000000)
     220                 :             : #define SET_VARSIZE_1B(PTR,len) \
     221                 :             :         (((varattrib_1b *) (PTR))->va_header = (len) | 0x80)
     222                 :             : #define SET_VARTAG_1B_E(PTR,tag) \
     223                 :             :         (((varattrib_1b_e *) (PTR))->va_header = 0x80, \
     224                 :             :          ((varattrib_1b_e *) (PTR))->va_tag = (tag))
     225                 :             : 
     226                 :             : #else                                                   /* !WORDS_BIGENDIAN */
     227                 :             : 
     228                 :             : #define VARATT_IS_4B(PTR) \
     229                 :             :         ((((varattrib_1b *) (PTR))->va_header & 0x01) == 0x00)
     230                 :             : #define VARATT_IS_4B_U(PTR) \
     231                 :             :         ((((varattrib_1b *) (PTR))->va_header & 0x03) == 0x00)
     232                 :             : #define VARATT_IS_4B_C(PTR) \
     233                 :             :         ((((varattrib_1b *) (PTR))->va_header & 0x03) == 0x02)
     234                 :             : #define VARATT_IS_1B(PTR) \
     235                 :             :         ((((varattrib_1b *) (PTR))->va_header & 0x01) == 0x01)
     236                 :             : #define VARATT_IS_1B_E(PTR) \
     237                 :             :         ((((varattrib_1b *) (PTR))->va_header) == 0x01)
     238                 :             : #define VARATT_NOT_PAD_BYTE(PTR) \
     239                 :             :         (*((uint8 *) (PTR)) != 0)
     240                 :             : 
     241                 :             : /* VARSIZE_4B() should only be used on known-aligned data */
     242                 :             : #define VARSIZE_4B(PTR) \
     243                 :             :         ((((varattrib_4b *) (PTR))->va_4byte.va_header >> 2) & 0x3FFFFFFF)
     244                 :             : #define VARSIZE_1B(PTR) \
     245                 :             :         ((((varattrib_1b *) (PTR))->va_header >> 1) & 0x7F)
     246                 :             : #define VARTAG_1B_E(PTR) \
     247                 :             :         ((vartag_external) ((varattrib_1b_e *) (PTR))->va_tag)
     248                 :             : 
     249                 :             : #define SET_VARSIZE_4B(PTR,len) \
     250                 :             :         (((varattrib_4b *) (PTR))->va_4byte.va_header = (((uint32) (len)) << 2))
     251                 :             : #define SET_VARSIZE_4B_C(PTR,len) \
     252                 :             :         (((varattrib_4b *) (PTR))->va_4byte.va_header = (((uint32) (len)) << 2) | 0x02)
     253                 :             : #define SET_VARSIZE_1B(PTR,len) \
     254                 :             :         (((varattrib_1b *) (PTR))->va_header = (((uint8) (len)) << 1) | 0x01)
     255                 :             : #define SET_VARTAG_1B_E(PTR,tag) \
     256                 :             :         (((varattrib_1b_e *) (PTR))->va_header = 0x01, \
     257                 :             :          ((varattrib_1b_e *) (PTR))->va_tag = (tag))
     258                 :             : 
     259                 :             : #endif                                                  /* WORDS_BIGENDIAN */
     260                 :             : 
     261                 :             : #define VARDATA_4B(PTR)         (((varattrib_4b *) (PTR))->va_4byte.va_data)
     262                 :             : #define VARDATA_4B_C(PTR)       (((varattrib_4b *) (PTR))->va_compressed.va_data)
     263                 :             : #define VARDATA_1B(PTR)         (((varattrib_1b *) (PTR))->va_data)
     264                 :             : #define VARDATA_1B_E(PTR)       (((varattrib_1b_e *) (PTR))->va_data)
     265                 :             : 
     266                 :             : /*
     267                 :             :  * Externally visible TOAST functions and macros begin here.  All of these
     268                 :             :  * were originally macros, accounting for the upper-case naming.
     269                 :             :  *
     270                 :             :  * Most of these functions accept a pointer to a value of a toastable data
     271                 :             :  * type.  The caller's variable might be declared "text *" or the like,
     272                 :             :  * so we use "void *" here.  Callers that are working with a Datum variable
     273                 :             :  * must apply DatumGetPointer before calling these functions.
     274                 :             :  */
     275                 :             : 
     276                 :             : #define VARHDRSZ_EXTERNAL               offsetof(varattrib_1b_e, va_data)
     277                 :             : #define VARHDRSZ_COMPRESSED             offsetof(varattrib_4b, va_compressed.va_data)
     278                 :             : #define VARHDRSZ_SHORT                  offsetof(varattrib_1b, va_data)
     279                 :             : #define VARATT_SHORT_MAX                0x7F
     280                 :             : 
     281                 :             : /*
     282                 :             :  * In consumers oblivious to data alignment, call PG_DETOAST_DATUM_PACKED(),
     283                 :             :  * VARDATA_ANY(), VARSIZE_ANY() and VARSIZE_ANY_EXHDR().  Elsewhere, call
     284                 :             :  * PG_DETOAST_DATUM(), VARDATA() and VARSIZE().  Directly fetching an int16,
     285                 :             :  * int32 or wider field in the struct representing the datum layout requires
     286                 :             :  * aligned data.  memcpy() is alignment-oblivious, as are most operations on
     287                 :             :  * datatypes, such as text, whose layout struct contains only char fields.
     288                 :             :  *
     289                 :             :  * Code assembling a new datum should call VARDATA() and SET_VARSIZE().
     290                 :             :  * (Datums begin life untoasted.)
     291                 :             :  *
     292                 :             :  * Other functions here should usually be used only by tuple assembly/disassembly
     293                 :             :  * code and code that specifically wants to work with still-toasted Datums.
     294                 :             :  */
     295                 :             : 
     296                 :             : /* Size of a known-not-toasted varlena datum, including header */
     297                 :             : static inline Size
     298                 :    23823615 : VARSIZE(const void *PTR)
     299                 :             : {
     300                 :    23823615 :         return VARSIZE_4B(PTR);
     301                 :             : }
     302                 :             : 
     303                 :             : /* Start of data area of a known-not-toasted varlena datum */
     304                 :             : static inline char *
     305                 :    11958920 : VARDATA(const void *PTR)
     306                 :             : {
     307                 :    11958920 :         return VARDATA_4B(PTR);
     308                 :             : }
     309                 :             : 
     310                 :             : /* Size of a known-short-header varlena datum, including header */
     311                 :             : static inline Size
     312                 :     9397519 : VARSIZE_SHORT(const void *PTR)
     313                 :             : {
     314                 :     9397519 :         return VARSIZE_1B(PTR);
     315                 :             : }
     316                 :             : 
     317                 :             : /* Start of data area of a known-short-header varlena datum */
     318                 :             : static inline char *
     319                 :     7224229 : VARDATA_SHORT(const void *PTR)
     320                 :             : {
     321                 :     7224229 :         return VARDATA_1B(PTR);
     322                 :             : }
     323                 :             : 
     324                 :             : /* Type tag of a "TOAST pointer" datum */
     325                 :             : static inline vartag_external
     326                 :       44370 : VARTAG_EXTERNAL(const void *PTR)
     327                 :             : {
     328                 :       44370 :         return VARTAG_1B_E(PTR);
     329                 :             : }
     330                 :             : 
     331                 :             : /* Size of a "TOAST pointer" datum, including header */
     332                 :             : static inline Size
     333                 :        4247 : VARSIZE_EXTERNAL(const void *PTR)
     334                 :             : {
     335                 :        4247 :         return VARHDRSZ_EXTERNAL + VARTAG_SIZE(VARTAG_EXTERNAL(PTR));
     336                 :             : }
     337                 :             : 
     338                 :             : /* Start of data area of a "TOAST pointer" datum */
     339                 :             : static inline char *
     340                 :       31979 : VARDATA_EXTERNAL(const void *PTR)
     341                 :             : {
     342                 :       31979 :         return VARDATA_1B_E(PTR);
     343                 :             : }
     344                 :             : 
     345                 :             : /* Is varlena datum in inline-compressed format? */
     346                 :             : static inline bool
     347                 :    33801169 : VARATT_IS_COMPRESSED(const void *PTR)
     348                 :             : {
     349                 :    33801169 :         return VARATT_IS_4B_C(PTR);
     350                 :             : }
     351                 :             : 
     352                 :             : /* Is varlena datum a "TOAST pointer" datum? */
     353                 :             : static inline bool
     354                 :    61067229 : VARATT_IS_EXTERNAL(const void *PTR)
     355                 :             : {
     356                 :    61067229 :         return VARATT_IS_1B_E(PTR);
     357                 :             : }
     358                 :             : 
     359                 :             : /* Is varlena datum a pointer to on-disk toasted data? */
     360                 :             : static inline bool
     361                 :     9662549 : VARATT_IS_EXTERNAL_ONDISK(const void *PTR)
     362                 :             : {
     363         [ +  + ]:     9662549 :         return VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_ONDISK;
     364                 :             : }
     365                 :             : 
     366                 :             : /* Is varlena datum an indirect pointer? */
     367                 :             : static inline bool
     368                 :     9660335 : VARATT_IS_EXTERNAL_INDIRECT(const void *PTR)
     369                 :             : {
     370         [ +  + ]:     9660335 :         return VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_INDIRECT;
     371                 :             : }
     372                 :             : 
     373                 :             : /* Is varlena datum a read-only pointer to an expanded object? */
     374                 :             : static inline bool
     375                 :        4798 : VARATT_IS_EXTERNAL_EXPANDED_RO(const void *PTR)
     376                 :             : {
     377         [ +  + ]:        4798 :         return VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_EXPANDED_RO;
     378                 :             : }
     379                 :             : 
     380                 :             : /* Is varlena datum a read-write pointer to an expanded object? */
     381                 :             : static inline bool
     382                 :     1019869 : VARATT_IS_EXTERNAL_EXPANDED_RW(const void *PTR)
     383                 :             : {
     384         [ +  + ]:     1019869 :         return VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_EXPANDED_RW;
     385                 :             : }
     386                 :             : 
     387                 :             : /* Is varlena datum either type of pointer to an expanded object? */
     388                 :             : static inline bool
     389                 :    14718528 : VARATT_IS_EXTERNAL_EXPANDED(const void *PTR)
     390                 :             : {
     391         [ +  + ]:    14718528 :         return VARATT_IS_EXTERNAL(PTR) && VARTAG_IS_EXPANDED(VARTAG_EXTERNAL(PTR));
     392                 :             : }
     393                 :             : 
     394                 :             : /* Is varlena datum a "TOAST pointer", but not for an expanded object? */
     395                 :             : static inline bool
     396                 :        7260 : VARATT_IS_EXTERNAL_NON_EXPANDED(const void *PTR)
     397                 :             : {
     398         [ +  + ]:        7260 :         return VARATT_IS_EXTERNAL(PTR) && !VARTAG_IS_EXPANDED(VARTAG_EXTERNAL(PTR));
     399                 :             : }
     400                 :             : 
     401                 :             : /* Is varlena datum a short-header datum? */
     402                 :             : static inline bool
     403                 :    13541551 : VARATT_IS_SHORT(const void *PTR)
     404                 :             : {
     405                 :    13541551 :         return VARATT_IS_1B(PTR);
     406                 :             : }
     407                 :             : 
     408                 :             : /* Is varlena datum not in traditional (4-byte-header, uncompressed) format? */
     409                 :             : static inline bool
     410                 :    18834221 : VARATT_IS_EXTENDED(const void *PTR)
     411                 :             : {
     412                 :    18834221 :         return !VARATT_IS_4B_U(PTR);
     413                 :             : }
     414                 :             : 
     415                 :             : /* Is varlena datum short enough to convert to short-header format? */
     416                 :             : static inline bool
     417                 :     5067382 : VARATT_CAN_MAKE_SHORT(const void *PTR)
     418                 :             : {
     419         [ +  + ]:     9542024 :         return VARATT_IS_4B_U(PTR) &&
     420                 :     4474642 :                 (VARSIZE(PTR) - VARHDRSZ + VARHDRSZ_SHORT) <= VARATT_SHORT_MAX;
     421                 :             : }
     422                 :             : 
     423                 :             : /* Size that datum will have in short-header format, including header */
     424                 :             : static inline Size
     425                 :     3733650 : VARATT_CONVERTED_SHORT_SIZE(const void *PTR)
     426                 :             : {
     427                 :     3733650 :         return VARSIZE(PTR) - VARHDRSZ + VARHDRSZ_SHORT;
     428                 :             : }
     429                 :             : 
     430                 :             : /* Set the size (including header) of a 4-byte-header varlena datum */
     431                 :             : static inline void
     432                 :    13517381 : SET_VARSIZE(void *PTR, Size len)
     433                 :             : {
     434                 :    13517381 :         SET_VARSIZE_4B(PTR, len);
     435                 :    13517381 : }
     436                 :             : 
     437                 :             : /* Set the size (including header) of a short-header varlena datum */
     438                 :             : static inline void
     439                 :     1792358 : SET_VARSIZE_SHORT(void *PTR, Size len)
     440                 :             : {
     441                 :     1792358 :         SET_VARSIZE_1B(PTR, len);
     442                 :     1792358 : }
     443                 :             : 
     444                 :             : /* Set the size (including header) of an inline-compressed varlena datum */
     445                 :             : static inline void
     446                 :        2838 : SET_VARSIZE_COMPRESSED(void *PTR, Size len)
     447                 :             : {
     448                 :        2838 :         SET_VARSIZE_4B_C(PTR, len);
     449                 :        2838 : }
     450                 :             : 
     451                 :             : /* Set the type tag of a "TOAST pointer" datum */
     452                 :             : static inline void
     453                 :       15782 : SET_VARTAG_EXTERNAL(void *PTR, vartag_external tag)
     454                 :             : {
     455                 :       15782 :         SET_VARTAG_1B_E(PTR, tag);
     456                 :       15782 : }
     457                 :             : 
     458                 :             : /* Size of a varlena datum of any format, including header */
     459                 :             : static inline Size
     460                 :    13503628 : VARSIZE_ANY(const void *PTR)
     461                 :             : {
     462         [ +  + ]:    13503628 :         if (VARATT_IS_1B_E(PTR))
     463                 :        2594 :                 return VARSIZE_EXTERNAL(PTR);
     464         [ +  + ]:    13501034 :         else if (VARATT_IS_1B(PTR))
     465                 :     9074828 :                 return VARSIZE_1B(PTR);
     466                 :             :         else
     467                 :     4426206 :                 return VARSIZE_4B(PTR);
     468                 :    13503628 : }
     469                 :             : 
     470                 :             : /* Size of a varlena datum of any format, excluding header */
     471                 :             : static inline Size
     472                 :    22925118 : VARSIZE_ANY_EXHDR(const void *PTR)
     473                 :             : {
     474         [ -  + ]:    22925118 :         if (VARATT_IS_1B_E(PTR))
     475                 :           0 :                 return VARSIZE_EXTERNAL(PTR) - VARHDRSZ_EXTERNAL;
     476         [ +  + ]:    22925118 :         else if (VARATT_IS_1B(PTR))
     477                 :     2984425 :                 return VARSIZE_1B(PTR) - VARHDRSZ_SHORT;
     478                 :             :         else
     479                 :    19940693 :                 return VARSIZE_4B(PTR) - VARHDRSZ;
     480                 :    22925118 : }
     481                 :             : 
     482                 :             : /* Start of data area of a plain or short-header varlena datum */
     483                 :             : /* caution: this will not work on an external or compressed-in-line Datum */
     484                 :             : /* caution: this will return a possibly unaligned pointer */
     485                 :             : static inline char *
     486                 :    24113102 : VARDATA_ANY(const void *PTR)
     487                 :             : {
     488         [ +  + ]:    24113102 :         return VARATT_IS_1B(PTR) ? VARDATA_1B(PTR) : VARDATA_4B(PTR);
     489                 :             : }
     490                 :             : 
     491                 :             : /* Decompressed size of a compressed-in-line varlena datum */
     492                 :             : static inline Size
     493                 :       17079 : VARDATA_COMPRESSED_GET_EXTSIZE(const void *PTR)
     494                 :             : {
     495                 :       17079 :         return ((varattrib_4b *) PTR)->va_compressed.va_tcinfo & VARLENA_EXTSIZE_MASK;
     496                 :             : }
     497                 :             : 
     498                 :             : /* Compression method of a compressed-in-line varlena datum */
     499                 :             : static inline uint32
     500                 :         369 : VARDATA_COMPRESSED_GET_COMPRESS_METHOD(const void *PTR)
     501                 :             : {
     502                 :         369 :         return ((varattrib_4b *) PTR)->va_compressed.va_tcinfo >> VARLENA_EXTSIZE_BITS;
     503                 :             : }
     504                 :             : 
     505                 :             : /* Same for external Datums; but note argument is a struct varatt_external */
     506                 :             : static inline Size
     507                 :        1884 : VARATT_EXTERNAL_GET_EXTSIZE(struct varatt_external toast_pointer)
     508                 :             : {
     509                 :        1884 :         return toast_pointer.va_extinfo & VARLENA_EXTSIZE_MASK;
     510                 :             : }
     511                 :             : 
     512                 :             : static inline uint32
     513                 :          11 : VARATT_EXTERNAL_GET_COMPRESS_METHOD(struct varatt_external toast_pointer)
     514                 :             : {
     515                 :          11 :         return toast_pointer.va_extinfo >> VARLENA_EXTSIZE_BITS;
     516                 :             : }
     517                 :             : 
     518                 :             : /* Set size and compress method of an externally-stored varlena datum */
     519                 :             : /* This has to remain a macro; beware multiple evaluations! */
     520                 :             : #define VARATT_EXTERNAL_SET_SIZE_AND_COMPRESS_METHOD(toast_pointer, len, cm) \
     521                 :             :         do { \
     522                 :             :                 Assert((cm) == TOAST_PGLZ_COMPRESSION_ID || \
     523                 :             :                            (cm) == TOAST_LZ4_COMPRESSION_ID); \
     524                 :             :                 ((toast_pointer).va_extinfo = \
     525                 :             :                         (len) | ((uint32) (cm) << VARLENA_EXTSIZE_BITS)); \
     526                 :             :         } while (0)
     527                 :             : 
     528                 :             : /*
     529                 :             :  * Testing whether an externally-stored value is compressed now requires
     530                 :             :  * comparing size stored in va_extinfo (the actual length of the external data)
     531                 :             :  * to rawsize (the original uncompressed datum's size).  The latter includes
     532                 :             :  * VARHDRSZ overhead, the former doesn't.  We never use compression unless it
     533                 :             :  * actually saves space, so we expect either equality or less-than.
     534                 :             :  */
     535                 :             : static inline bool
     536                 :        1066 : VARATT_EXTERNAL_IS_COMPRESSED(struct varatt_external toast_pointer)
     537                 :             : {
     538                 :        2132 :         return VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer) <
     539                 :        1066 :                 (Size) (toast_pointer.va_rawsize - VARHDRSZ);
     540                 :             : }
     541                 :             : 
     542                 :             : #endif
        

Generated by: LCOV version 2.3.2-1