LCOV - code coverage report
Current view: top level - src/backend/utils/adt - expandeddatum.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 32 32 100.0 %
Date: 2024-04-25 15:13:21 Functions: 7 7 100.0 %
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-2024, 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      100532 : DatumGetEOHP(Datum d)
      30             : {
      31      100532 :     varattrib_1b_e *datum = (varattrib_1b_e *) DatumGetPointer(d);
      32             :     varatt_expanded ptr;
      33             : 
      34             :     Assert(VARATT_IS_EXTERNAL_EXPANDED(datum));
      35      100532 :     memcpy(&ptr, VARDATA_EXTERNAL(datum), sizeof(ptr));
      36             :     Assert(VARATT_IS_EXPANDED_HEADER(ptr.eohptr));
      37      100532 :     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       53038 : EOH_init_header(ExpandedObjectHeader *eohptr,
      49             :                 const ExpandedObjectMethods *methods,
      50             :                 MemoryContext obj_context)
      51             : {
      52             :     varatt_expanded ptr;
      53             : 
      54       53038 :     eohptr->vl_len_ = EOH_HEADER_MAGIC;
      55       53038 :     eohptr->eoh_methods = methods;
      56       53038 :     eohptr->eoh_context = obj_context;
      57             : 
      58       53038 :     ptr.eohptr = eohptr;
      59             : 
      60       53038 :     SET_VARTAG_EXTERNAL(eohptr->eoh_rw_ptr, VARTAG_EXPANDED_RW);
      61       53038 :     memcpy(VARDATA_EXTERNAL(eohptr->eoh_rw_ptr), &ptr, sizeof(ptr));
      62             : 
      63       53038 :     SET_VARTAG_EXTERNAL(eohptr->eoh_ro_ptr, VARTAG_EXPANDED_RO);
      64       53038 :     memcpy(VARDATA_EXTERNAL(eohptr->eoh_ro_ptr), &ptr, sizeof(ptr));
      65       53038 : }
      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       14756 : EOH_get_flat_size(ExpandedObjectHeader *eohptr)
      76             : {
      77       14756 :     return eohptr->eoh_methods->get_flat_size(eohptr);
      78             : }
      79             : 
      80             : void
      81       11786 : EOH_flatten_into(ExpandedObjectHeader *eohptr,
      82             :                  void *result, Size allocated_size)
      83             : {
      84       11786 :     eohptr->eoh_methods->flatten_into(eohptr, result, allocated_size);
      85       11786 : }
      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     7819170 : MakeExpandedObjectReadOnlyInternal(Datum d)
      96             : {
      97             :     ExpandedObjectHeader *eohptr;
      98             : 
      99             :     /* Nothing to do if not a read-write expanded-object pointer */
     100     7819170 :     if (!VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)))
     101     7788346 :         return d;
     102             : 
     103             :     /* Now safe to extract the object pointer */
     104       30824 :     eohptr = DatumGetEOHP(d);
     105             : 
     106             :     /* Return the built-in read-only pointer instead of given pointer */
     107       30824 :     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        3742 : TransferExpandedObject(Datum d, MemoryContext new_parent)
     119             : {
     120        3742 :     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        3742 :     MemoryContextSetParent(eohptr->eoh_context, new_parent);
     127             : 
     128             :     /* Return the object's standard read-write pointer */
     129        3742 :     return EOHPGetRWDatum(eohptr);
     130             : }
     131             : 
     132             : /*
     133             :  * Delete an expanded object (must be referenced by a R/W pointer).
     134             :  */
     135             : void
     136        8898 : DeleteExpandedObject(Datum d)
     137             : {
     138        8898 :     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        8898 :     MemoryContextDelete(eohptr->eoh_context);
     145        8898 : }

Generated by: LCOV version 1.14