LCOV - code coverage report
Current view: top level - src/backend/utils/adt - expandeddatum.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 32 32
Test Date: 2026-03-01 01:14:39 Functions: 100.0 % 7 7
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * expandeddatum.c
       4              :  *    Support functions for "expanded" value representations.
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7              :  * Portions Copyright (c) 1994, Regents of the University of California
       8              :  *
       9              :  *
      10              :  * IDENTIFICATION
      11              :  *    src/backend/utils/adt/expandeddatum.c
      12              :  *
      13              :  *-------------------------------------------------------------------------
      14              :  */
      15              : #include "postgres.h"
      16              : 
      17              : #include "utils/expandeddatum.h"
      18              : #include "utils/memutils.h"
      19              : 
      20              : /*
      21              :  * DatumGetEOHP
      22              :  *
      23              :  * Given a Datum that is an expanded-object reference, extract the pointer.
      24              :  *
      25              :  * This is a bit tedious since the pointer may not be properly aligned;
      26              :  * compare VARATT_EXTERNAL_GET_POINTER().
      27              :  */
      28              : ExpandedObjectHeader *
      29        52229 : DatumGetEOHP(Datum d)
      30              : {
      31        52229 :     varattrib_1b_e *datum = (varattrib_1b_e *) DatumGetPointer(d);
      32              :     varatt_expanded ptr;
      33              : 
      34              :     Assert(VARATT_IS_EXTERNAL_EXPANDED(datum));
      35        52229 :     memcpy(&ptr, VARDATA_EXTERNAL(datum), sizeof(ptr));
      36              :     Assert(VARATT_IS_EXPANDED_HEADER(ptr.eohptr));
      37        52229 :     return ptr.eohptr;
      38              : }
      39              : 
      40              : /*
      41              :  * EOH_init_header
      42              :  *
      43              :  * Initialize the common header of an expanded object.
      44              :  *
      45              :  * The main thing this encapsulates is initializing the TOAST pointers.
      46              :  */
      47              : void
      48        27619 : EOH_init_header(ExpandedObjectHeader *eohptr,
      49              :                 const ExpandedObjectMethods *methods,
      50              :                 MemoryContext obj_context)
      51              : {
      52              :     varatt_expanded ptr;
      53              : 
      54        27619 :     eohptr->vl_len_ = EOH_HEADER_MAGIC;
      55        27619 :     eohptr->eoh_methods = methods;
      56        27619 :     eohptr->eoh_context = obj_context;
      57              : 
      58        27619 :     ptr.eohptr = eohptr;
      59              : 
      60        27619 :     SET_VARTAG_EXTERNAL(eohptr->eoh_rw_ptr, VARTAG_EXPANDED_RW);
      61        27619 :     memcpy(VARDATA_EXTERNAL(eohptr->eoh_rw_ptr), &ptr, sizeof(ptr));
      62              : 
      63        27619 :     SET_VARTAG_EXTERNAL(eohptr->eoh_ro_ptr, VARTAG_EXPANDED_RO);
      64        27619 :     memcpy(VARDATA_EXTERNAL(eohptr->eoh_ro_ptr), &ptr, sizeof(ptr));
      65        27619 : }
      66              : 
      67              : /*
      68              :  * EOH_get_flat_size
      69              :  * EOH_flatten_into
      70              :  *
      71              :  * Convenience functions for invoking the "methods" of an expanded object.
      72              :  */
      73              : 
      74              : Size
      75         7928 : EOH_get_flat_size(ExpandedObjectHeader *eohptr)
      76              : {
      77         7928 :     return eohptr->eoh_methods->get_flat_size(eohptr);
      78              : }
      79              : 
      80              : void
      81         6532 : EOH_flatten_into(ExpandedObjectHeader *eohptr,
      82              :                  void *result, Size allocated_size)
      83              : {
      84         6532 :     eohptr->eoh_methods->flatten_into(eohptr, result, allocated_size);
      85         6532 : }
      86              : 
      87              : /*
      88              :  * If the Datum represents a R/W expanded object, change it to R/O.
      89              :  * Otherwise return the original Datum.
      90              :  *
      91              :  * Caller must ensure that the datum is a non-null varlena value.  Typically
      92              :  * this is invoked via MakeExpandedObjectReadOnly(), which checks that.
      93              :  */
      94              : Datum
      95      4649553 : MakeExpandedObjectReadOnlyInternal(Datum d)
      96              : {
      97              :     ExpandedObjectHeader *eohptr;
      98              : 
      99              :     /* Nothing to do if not a read-write expanded-object pointer */
     100      4649553 :     if (!VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)))
     101      4633417 :         return d;
     102              : 
     103              :     /* Now safe to extract the object pointer */
     104        16136 :     eohptr = DatumGetEOHP(d);
     105              : 
     106              :     /* Return the built-in read-only pointer instead of given pointer */
     107        16136 :     return EOHPGetRODatum(eohptr);
     108              : }
     109              : 
     110              : /*
     111              :  * Transfer ownership of an expanded object to a new parent memory context.
     112              :  * The object must be referenced by a R/W pointer, and what we return is
     113              :  * always its "standard" R/W pointer, which is certain to have the same
     114              :  * lifespan as the object itself.  (The passed-in pointer might not, and
     115              :  * in any case wouldn't provide a unique identifier if it's not that one.)
     116              :  */
     117              : Datum
     118         2138 : TransferExpandedObject(Datum d, MemoryContext new_parent)
     119              : {
     120         2138 :     ExpandedObjectHeader *eohptr = DatumGetEOHP(d);
     121              : 
     122              :     /* Assert caller gave a R/W pointer */
     123              :     Assert(VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)));
     124              : 
     125              :     /* Transfer ownership */
     126         2138 :     MemoryContextSetParent(eohptr->eoh_context, new_parent);
     127              : 
     128              :     /* Return the object's standard read-write pointer */
     129         2138 :     return EOHPGetRWDatum(eohptr);
     130              : }
     131              : 
     132              : /*
     133              :  * Delete an expanded object (must be referenced by a R/W pointer).
     134              :  */
     135              : void
     136         4539 : DeleteExpandedObject(Datum d)
     137              : {
     138         4539 :     ExpandedObjectHeader *eohptr = DatumGetEOHP(d);
     139              : 
     140              :     /* Assert caller gave a R/W pointer */
     141              :     Assert(VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)));
     142              : 
     143              :     /* Kill it */
     144         4539 :     MemoryContextDelete(eohptr->eoh_context);
     145         4539 : }
        

Generated by: LCOV version 2.0-1