LCOV - code coverage report
Current view: top level - src/backend/utils/misc - queryenvironment.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 78.1 % 32 25
Test Date: 2026-03-03 04:14:52 Functions: 83.3 % 6 5
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * queryenvironment.c
       4              :  *    Query environment, to store context-specific values like ephemeral named
       5              :  *    relations.  Initial use is for named tuplestores for delta information
       6              :  *    from "normal" relations.
       7              :  *
       8              :  * The initial implementation uses a list because the number of such relations
       9              :  * in any one context is expected to be very small.  If that becomes a
      10              :  * performance problem, the implementation can be changed with no other impact
      11              :  * on callers, since this is an opaque structure.  This is the reason to
      12              :  * require a create function.
      13              :  *
      14              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      15              :  * Portions Copyright (c) 1994, Regents of the University of California
      16              :  *
      17              :  *
      18              :  * IDENTIFICATION
      19              :  *    src/backend/utils/misc/queryenvironment.c
      20              :  *
      21              :  *-------------------------------------------------------------------------
      22              :  */
      23              : #include "postgres.h"
      24              : 
      25              : #include "access/table.h"
      26              : #include "utils/queryenvironment.h"
      27              : #include "utils/rel.h"
      28              : 
      29              : /*
      30              :  * Private state of a query environment.
      31              :  */
      32              : struct QueryEnvironment
      33              : {
      34              :     List       *namedRelList;
      35              : };
      36              : 
      37              : 
      38              : QueryEnvironment *
      39          285 : create_queryEnv(void)
      40              : {
      41          285 :     return palloc0_object(QueryEnvironment);
      42              : }
      43              : 
      44              : EphemeralNamedRelationMetadata
      45       149489 : get_visible_ENR_metadata(QueryEnvironment *queryEnv, const char *refname)
      46              : {
      47              :     EphemeralNamedRelation enr;
      48              : 
      49              :     Assert(refname != NULL);
      50              : 
      51       149489 :     if (queryEnv == NULL)
      52       148979 :         return NULL;
      53              : 
      54          510 :     enr = get_ENR(queryEnv, refname);
      55              : 
      56          510 :     if (enr)
      57          489 :         return &(enr->md);
      58              : 
      59           21 :     return NULL;
      60              : }
      61              : 
      62              : /*
      63              :  * Register a named relation for use in the given environment.
      64              :  *
      65              :  * If this is intended exclusively for planning purposes, the tstate field can
      66              :  * be left NULL;
      67              :  */
      68              : void
      69          360 : register_ENR(QueryEnvironment *queryEnv, EphemeralNamedRelation enr)
      70              : {
      71              :     Assert(enr != NULL);
      72              :     Assert(get_ENR(queryEnv, enr->md.name) == NULL);
      73              : 
      74          360 :     queryEnv->namedRelList = lappend(queryEnv->namedRelList, enr);
      75          360 : }
      76              : 
      77              : /*
      78              :  * Unregister an ephemeral relation by name.  This will probably be a rarely
      79              :  * used function, but seems like it should be provided "just in case".
      80              :  */
      81              : void
      82            0 : unregister_ENR(QueryEnvironment *queryEnv, const char *name)
      83              : {
      84              :     EphemeralNamedRelation match;
      85              : 
      86            0 :     match = get_ENR(queryEnv, name);
      87            0 :     if (match)
      88            0 :         queryEnv->namedRelList = list_delete(queryEnv->namedRelList, match);
      89            0 : }
      90              : 
      91              : /*
      92              :  * This returns an ENR if there is a name match in the given collection.  It
      93              :  * must quietly return NULL if no match is found.
      94              :  */
      95              : EphemeralNamedRelation
      96          930 : get_ENR(QueryEnvironment *queryEnv, const char *name)
      97              : {
      98              :     ListCell   *lc;
      99              : 
     100              :     Assert(name != NULL);
     101              : 
     102          930 :     if (queryEnv == NULL)
     103            0 :         return NULL;
     104              : 
     105         1197 :     foreach(lc, queryEnv->namedRelList)
     106              :     {
     107         1101 :         EphemeralNamedRelation enr = (EphemeralNamedRelation) lfirst(lc);
     108              : 
     109         1101 :         if (strcmp(enr->md.name, name) == 0)
     110          834 :             return enr;
     111              :     }
     112              : 
     113           96 :     return NULL;
     114              : }
     115              : 
     116              : /*
     117              :  * Gets the TupleDesc for a Ephemeral Named Relation, based on which field was
     118              :  * filled.
     119              :  *
     120              :  * When the TupleDesc is based on a relation from the catalogs, we count on
     121              :  * that relation being used at the same time, so that appropriate locks will
     122              :  * already be held.  Locking here would be too late anyway.
     123              :  */
     124              : TupleDesc
     125          588 : ENRMetadataGetTupDesc(EphemeralNamedRelationMetadata enrmd)
     126              : {
     127              :     TupleDesc   tupdesc;
     128              : 
     129              :     /* One, and only one, of these fields must be filled. */
     130              :     Assert((enrmd->reliddesc == InvalidOid) != (enrmd->tupdesc == NULL));
     131              : 
     132          588 :     if (enrmd->tupdesc != NULL)
     133            0 :         tupdesc = enrmd->tupdesc;
     134              :     else
     135              :     {
     136              :         Relation    relation;
     137              : 
     138          588 :         relation = table_open(enrmd->reliddesc, NoLock);
     139          588 :         tupdesc = relation->rd_att;
     140          588 :         table_close(relation, NoLock);
     141              :     }
     142              : 
     143          588 :     return tupdesc;
     144              : }
        

Generated by: LCOV version 2.0-1