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 15:15:32 Functions: 100.0 % 2 2 2 2
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           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
     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                 : 
     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