LCOV - differential code coverage report
Current view: top level - src/include/utils - expandeddatum.h (source / functions) Coverage Total Hit CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 100.0 % 4 4 4
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 2 2 2
Baseline: 16@8cea358b128 Branches: - 0 0
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 100.0 % 4 4 4
Function coverage date bins:
(240..) days: 100.0 % 2 2 2

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * expandeddatum.h
                                  4                 :                :  *    Declarations for access to "expanded" value representations.
                                  5                 :                :  *
                                  6                 :                :  * Complex data types, particularly container types such as arrays and
                                  7                 :                :  * records, usually have on-disk representations that are compact but not
                                  8                 :                :  * especially convenient to modify.  What's more, when we do modify them,
                                  9                 :                :  * having to recopy all the rest of the value can be extremely inefficient.
                                 10                 :                :  * Therefore, we provide a notion of an "expanded" representation that is used
                                 11                 :                :  * only in memory and is optimized more for computation than storage.
                                 12                 :                :  * The format appearing on disk is called the data type's "flattened"
                                 13                 :                :  * representation, since it is required to be a contiguous blob of bytes --
                                 14                 :                :  * but the type can have an expanded representation that is not.  Data types
                                 15                 :                :  * must provide means to translate an expanded representation back to
                                 16                 :                :  * flattened form.
                                 17                 :                :  *
                                 18                 :                :  * An expanded object is meant to survive across multiple operations, but
                                 19                 :                :  * not to be enormously long-lived; for example it might be a local variable
                                 20                 :                :  * in a PL/pgSQL procedure.  So its extra bulk compared to the on-disk format
                                 21                 :                :  * is a worthwhile trade-off.
                                 22                 :                :  *
                                 23                 :                :  * References to expanded objects are a type of TOAST pointer.
                                 24                 :                :  * Because of longstanding conventions in Postgres, this means that the
                                 25                 :                :  * flattened form of such an object must always be a varlena object.
                                 26                 :                :  * Fortunately that's no restriction in practice.
                                 27                 :                :  *
                                 28                 :                :  * There are actually two kinds of TOAST pointers for expanded objects:
                                 29                 :                :  * read-only and read-write pointers.  Possession of one of the latter
                                 30                 :                :  * authorizes a function to modify the value in-place rather than copying it
                                 31                 :                :  * as would normally be required.  Functions should always return a read-write
                                 32                 :                :  * pointer to any new expanded object they create.  Functions that modify an
                                 33                 :                :  * argument value in-place must take care that they do not corrupt the old
                                 34                 :                :  * value if they fail partway through.
                                 35                 :                :  *
                                 36                 :                :  *
                                 37                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                 38                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 39                 :                :  *
                                 40                 :                :  * src/include/utils/expandeddatum.h
                                 41                 :                :  *
                                 42                 :                :  *-------------------------------------------------------------------------
                                 43                 :                :  */
                                 44                 :                : #ifndef EXPANDEDDATUM_H
                                 45                 :                : #define EXPANDEDDATUM_H
                                 46                 :                : 
                                 47                 :                : #include "varatt.h"
                                 48                 :                : 
                                 49                 :                : /* Size of an EXTERNAL datum that contains a pointer to an expanded object */
                                 50                 :                : #define EXPANDED_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_expanded))
                                 51                 :                : 
                                 52                 :                : /*
                                 53                 :                :  * "Methods" that must be provided for any expanded object.
                                 54                 :                :  *
                                 55                 :                :  * get_flat_size: compute space needed for flattened representation (total,
                                 56                 :                :  * including header).
                                 57                 :                :  *
                                 58                 :                :  * flatten_into: construct flattened representation in the caller-allocated
                                 59                 :                :  * space at *result, of size allocated_size (which will always be the result
                                 60                 :                :  * of a preceding get_flat_size call; it's passed for cross-checking).
                                 61                 :                :  *
                                 62                 :                :  * The flattened representation must be a valid in-line, non-compressed,
                                 63                 :                :  * 4-byte-header varlena object.
                                 64                 :                :  *
                                 65                 :                :  * Note: construction of a heap tuple from an expanded datum calls
                                 66                 :                :  * get_flat_size twice, so it's worthwhile to make sure that that doesn't
                                 67                 :                :  * incur too much overhead.
                                 68                 :                :  */
                                 69                 :                : typedef Size (*EOM_get_flat_size_method) (ExpandedObjectHeader *eohptr);
                                 70                 :                : typedef void (*EOM_flatten_into_method) (ExpandedObjectHeader *eohptr,
                                 71                 :                :                                          void *result, Size allocated_size);
                                 72                 :                : 
                                 73                 :                : /* Struct of function pointers for an expanded object's methods */
                                 74                 :                : typedef struct ExpandedObjectMethods
                                 75                 :                : {
                                 76                 :                :     EOM_get_flat_size_method get_flat_size;
                                 77                 :                :     EOM_flatten_into_method flatten_into;
                                 78                 :                : } ExpandedObjectMethods;
                                 79                 :                : 
                                 80                 :                : /*
                                 81                 :                :  * Every expanded object must contain this header; typically the header
                                 82                 :                :  * is embedded in some larger struct that adds type-specific fields.
                                 83                 :                :  *
                                 84                 :                :  * It is presumed that the header object and all subsidiary data are stored
                                 85                 :                :  * in eoh_context, so that the object can be freed by deleting that context,
                                 86                 :                :  * or its storage lifespan can be altered by reparenting the context.
                                 87                 :                :  * (In principle the object could own additional resources, such as malloc'd
                                 88                 :                :  * storage, and use a memory context reset callback to free them upon reset or
                                 89                 :                :  * deletion of eoh_context.)
                                 90                 :                :  *
                                 91                 :                :  * We set up two TOAST pointers within the standard header, one read-write
                                 92                 :                :  * and one read-only.  This allows functions to return either kind of pointer
                                 93                 :                :  * without making an additional allocation, and in particular without worrying
                                 94                 :                :  * whether a separately palloc'd object would have sufficient lifespan.
                                 95                 :                :  * But note that these pointers are just a convenience; a pointer object
                                 96                 :                :  * appearing somewhere else would still be legal.
                                 97                 :                :  *
                                 98                 :                :  * The typedef declaration for this appears in postgres.h.
                                 99                 :                :  */
                                100                 :                : struct ExpandedObjectHeader
                                101                 :                : {
                                102                 :                :     /* Phony varlena header */
                                103                 :                :     int32       vl_len_;        /* always EOH_HEADER_MAGIC, see below */
                                104                 :                : 
                                105                 :                :     /* Pointer to methods required for object type */
                                106                 :                :     const ExpandedObjectMethods *eoh_methods;
                                107                 :                : 
                                108                 :                :     /* Memory context containing this header and subsidiary data */
                                109                 :                :     MemoryContext eoh_context;
                                110                 :                : 
                                111                 :                :     /* Standard R/W TOAST pointer for this object is kept here */
                                112                 :                :     char        eoh_rw_ptr[EXPANDED_POINTER_SIZE];
                                113                 :                : 
                                114                 :                :     /* Standard R/O TOAST pointer for this object is kept here */
                                115                 :                :     char        eoh_ro_ptr[EXPANDED_POINTER_SIZE];
                                116                 :                : };
                                117                 :                : 
                                118                 :                : /*
                                119                 :                :  * Particularly for read-only functions, it is handy to be able to work with
                                120                 :                :  * either regular "flat" varlena inputs or expanded inputs of the same data
                                121                 :                :  * type.  To allow determining which case an argument-fetching function has
                                122                 :                :  * returned, the first int32 of an ExpandedObjectHeader always contains -1
                                123                 :                :  * (EOH_HEADER_MAGIC to the code).  This works since no 4-byte-header varlena
                                124                 :                :  * could have that as its first 4 bytes.  Caution: we could not reliably tell
                                125                 :                :  * the difference between an ExpandedObjectHeader and a short-header object
                                126                 :                :  * with this trick.  However, it works fine if the argument fetching code
                                127                 :                :  * always returns either a 4-byte-header flat object or an expanded object.
                                128                 :                :  */
                                129                 :                : #define EOH_HEADER_MAGIC (-1)
                                130                 :                : #define VARATT_IS_EXPANDED_HEADER(PTR) \
                                131                 :                :     (((varattrib_4b *) (PTR))->va_4byte.va_header == (uint32) EOH_HEADER_MAGIC)
                                132                 :                : 
                                133                 :                : /*
                                134                 :                :  * Generic support functions for expanded objects.
                                135                 :                :  * (More of these might be worth inlining later.)
                                136                 :                :  */
                                137                 :                : 
                                138                 :                : static inline Datum
  565 peter@eisentraut.org      139                 :CBC       21027 : EOHPGetRWDatum(const struct ExpandedObjectHeader *eohptr)
                                140                 :                : {
                                141                 :          21027 :     return PointerGetDatum(eohptr->eoh_rw_ptr);
                                142                 :                : }
                                143                 :                : 
                                144                 :                : static inline Datum
                                145                 :          15510 : EOHPGetRODatum(const struct ExpandedObjectHeader *eohptr)
                                146                 :                : {
                                147                 :          15510 :     return PointerGetDatum(eohptr->eoh_ro_ptr);
                                148                 :                : }
                                149                 :                : 
                                150                 :                : /* Does the Datum represent a writable expanded object? */
                                151                 :                : #define DatumIsReadWriteExpandedObject(d, isnull, typlen) \
                                152                 :                :     (((isnull) || (typlen) != -1) ? false : \
                                153                 :                :      VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)))
                                154                 :                : 
                                155                 :                : #define MakeExpandedObjectReadOnly(d, isnull, typlen) \
                                156                 :                :     (((isnull) || (typlen) != -1) ? (d) : \
                                157                 :                :      MakeExpandedObjectReadOnlyInternal(d))
                                158                 :                : 
                                159                 :                : extern ExpandedObjectHeader *DatumGetEOHP(Datum d);
                                160                 :                : extern void EOH_init_header(ExpandedObjectHeader *eohptr,
                                161                 :                :                             const ExpandedObjectMethods *methods,
                                162                 :                :                             MemoryContext obj_context);
                                163                 :                : extern Size EOH_get_flat_size(ExpandedObjectHeader *eohptr);
                                164                 :                : extern void EOH_flatten_into(ExpandedObjectHeader *eohptr,
                                165                 :                :                              void *result, Size allocated_size);
                                166                 :                : extern Datum MakeExpandedObjectReadOnlyInternal(Datum d);
                                167                 :                : extern Datum TransferExpandedObject(Datum d, MemoryContext new_parent);
                                168                 :                : extern void DeleteExpandedObject(Datum d);
                                169                 :                : 
                                170                 :                : #endif                          /* EXPANDEDDATUM_H */
        

Generated by: LCOV version 2.1-beta2-3-g6141622