LCOV - differential code coverage report
Current view: top level - src/include/utils - expandeddatum.h (source / functions) Coverage Total Hit GNC ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 100.0 % 4 4 4 4
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 2 2 2 2
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (180,240] days: 100.0 % 4 4 4
Legend: Lines: hit not hit Function coverage date bins:
(180,240] days: 100.0 % 2 2 2
(240..) days: 0.0 % 2 0 2

 Age         Owner                  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-2023, 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
  194 peter                     139 GNC       20764 : EOHPGetRWDatum(const struct ExpandedObjectHeader *eohptr)
                                140                 : {
                                141           20764 :     return PointerGetDatum(eohptr->eoh_rw_ptr);
                                142                 : }
                                143                 : 
                                144                 : static inline Datum
                                145           15392 : EOHPGetRODatum(const struct ExpandedObjectHeader *eohptr)
                                146                 : {
                                147           15392 :     return PointerGetDatum(eohptr->eoh_ro_ptr);
                                148                 : }
                                149                 : 
 2501 tgl                       150 ECB             : /* 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 v1.16-55-g56c0a2a