LCOV - code coverage report
Current view: top level - src/backend/utils/adt - expandeddatum.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 100.0 % 42 42
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 7 7
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 60.0 % 10 6

             Branch data     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                 :       15009 : DatumGetEOHP(Datum d)
      30                 :             : {
      31                 :       15009 :         varattrib_1b_e *datum = (varattrib_1b_e *) DatumGetPointer(d);
      32                 :       15009 :         varatt_expanded ptr;
      33                 :             : 
      34         [ +  - ]:       15009 :         Assert(VARATT_IS_EXTERNAL_EXPANDED(datum));
      35                 :       15009 :         memcpy(&ptr, VARDATA_EXTERNAL(datum), sizeof(ptr));
      36         [ +  - ]:       15009 :         Assert(VARATT_IS_EXPANDED_HEADER(ptr.eohptr));
      37                 :       30018 :         return ptr.eohptr;
      38                 :       15009 : }
      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                 :        7705 : EOH_init_header(ExpandedObjectHeader *eohptr,
      49                 :             :                                 const ExpandedObjectMethods *methods,
      50                 :             :                                 MemoryContext obj_context)
      51                 :             : {
      52                 :        7705 :         varatt_expanded ptr;
      53                 :             : 
      54                 :        7705 :         eohptr->vl_len_ = EOH_HEADER_MAGIC;
      55                 :        7705 :         eohptr->eoh_methods = methods;
      56                 :        7705 :         eohptr->eoh_context = obj_context;
      57                 :             : 
      58                 :        7705 :         ptr.eohptr = eohptr;
      59                 :             : 
      60                 :        7705 :         SET_VARTAG_EXTERNAL(eohptr->eoh_rw_ptr, VARTAG_EXPANDED_RW);
      61                 :        7705 :         memcpy(VARDATA_EXTERNAL(eohptr->eoh_rw_ptr), &ptr, sizeof(ptr));
      62                 :             : 
      63                 :        7705 :         SET_VARTAG_EXTERNAL(eohptr->eoh_ro_ptr, VARTAG_EXPANDED_RO);
      64                 :        7705 :         memcpy(VARDATA_EXTERNAL(eohptr->eoh_ro_ptr), &ptr, sizeof(ptr));
      65                 :        7705 : }
      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                 :        1832 : EOH_get_flat_size(ExpandedObjectHeader *eohptr)
      76                 :             : {
      77                 :        1832 :         return eohptr->eoh_methods->get_flat_size(eohptr);
      78                 :             : }
      79                 :             : 
      80                 :             : void
      81                 :        1369 : EOH_flatten_into(ExpandedObjectHeader *eohptr,
      82                 :             :                                  void *result, Size allocated_size)
      83                 :             : {
      84                 :        1369 :         eohptr->eoh_methods->flatten_into(eohptr, result, allocated_size);
      85                 :        1369 : }
      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                 :      956646 : MakeExpandedObjectReadOnlyInternal(Datum d)
      96                 :             : {
      97                 :      956646 :         ExpandedObjectHeader *eohptr;
      98                 :             : 
      99                 :             :         /* Nothing to do if not a read-write expanded-object pointer */
     100         [ +  + ]:      956646 :         if (!VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)))
     101                 :      951678 :                 return d;
     102                 :             : 
     103                 :             :         /* Now safe to extract the object pointer */
     104                 :        4968 :         eohptr = DatumGetEOHP(d);
     105                 :             : 
     106                 :             :         /* Return the built-in read-only pointer instead of given pointer */
     107                 :        4968 :         return EOHPGetRODatum(eohptr);
     108                 :      956646 : }
     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                 :          81 : TransferExpandedObject(Datum d, MemoryContext new_parent)
     119                 :             : {
     120                 :          81 :         ExpandedObjectHeader *eohptr = DatumGetEOHP(d);
     121                 :             : 
     122                 :             :         /* Assert caller gave a R/W pointer */
     123         [ +  - ]:          81 :         Assert(VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)));
     124                 :             : 
     125                 :             :         /* Transfer ownership */
     126                 :          81 :         MemoryContextSetParent(eohptr->eoh_context, new_parent);
     127                 :             : 
     128                 :             :         /* Return the object's standard read-write pointer */
     129                 :         162 :         return EOHPGetRWDatum(eohptr);
     130                 :          81 : }
     131                 :             : 
     132                 :             : /*
     133                 :             :  * Delete an expanded object (must be referenced by a R/W pointer).
     134                 :             :  */
     135                 :             : void
     136                 :        1427 : DeleteExpandedObject(Datum d)
     137                 :             : {
     138                 :        1427 :         ExpandedObjectHeader *eohptr = DatumGetEOHP(d);
     139                 :             : 
     140                 :             :         /* Assert caller gave a R/W pointer */
     141         [ +  - ]:        1427 :         Assert(VARATT_IS_EXTERNAL_EXPANDED_RW(DatumGetPointer(d)));
     142                 :             : 
     143                 :             :         /* Kill it */
     144                 :        1427 :         MemoryContextDelete(eohptr->eoh_context);
     145                 :        1427 : }
        

Generated by: LCOV version 2.3.2-1