LCOV - code coverage report
Current view: top level - src/backend/nodes - extensible.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 0.0 % 35 0
Test Date: 2026-03-01 23:14:58 Functions: 0.0 % 6 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * extensible.c
       4              :  *    Support for extensible node types
       5              :  *
       6              :  * Loadable modules can define what are in effect new types of nodes using
       7              :  * the routines in this file.  All such nodes are flagged T_ExtensibleNode,
       8              :  * with the extnodename field distinguishing the specific type.  Use
       9              :  * RegisterExtensibleNodeMethods to register a new type of extensible node,
      10              :  * and GetExtensibleNodeMethods to get information about a previously
      11              :  * registered type of extensible node.
      12              :  *
      13              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      14              :  * Portions Copyright (c) 1994, Regents of the University of California
      15              :  *
      16              :  * IDENTIFICATION
      17              :  *    src/backend/nodes/extensible.c
      18              :  *
      19              :  *-------------------------------------------------------------------------
      20              :  */
      21              : #include "postgres.h"
      22              : 
      23              : #include "nodes/extensible.h"
      24              : #include "utils/hsearch.h"
      25              : 
      26              : static HTAB *extensible_node_methods = NULL;
      27              : static HTAB *custom_scan_methods = NULL;
      28              : 
      29              : typedef struct
      30              : {
      31              :     char        extnodename[EXTNODENAME_MAX_LEN];
      32              :     const void *extnodemethods;
      33              : } ExtensibleNodeEntry;
      34              : 
      35              : /*
      36              :  * An internal function to register a new callback structure
      37              :  */
      38              : static void
      39            0 : RegisterExtensibleNodeEntry(HTAB **p_htable, const char *htable_label,
      40              :                             const char *extnodename,
      41              :                             const void *extnodemethods)
      42              : {
      43              :     ExtensibleNodeEntry *entry;
      44              :     bool        found;
      45              : 
      46            0 :     if (*p_htable == NULL)
      47              :     {
      48              :         HASHCTL     ctl;
      49              : 
      50            0 :         ctl.keysize = EXTNODENAME_MAX_LEN;
      51            0 :         ctl.entrysize = sizeof(ExtensibleNodeEntry);
      52              : 
      53            0 :         *p_htable = hash_create(htable_label, 100, &ctl,
      54              :                                 HASH_ELEM | HASH_STRINGS);
      55              :     }
      56              : 
      57            0 :     if (strlen(extnodename) >= EXTNODENAME_MAX_LEN)
      58            0 :         elog(ERROR, "extensible node name is too long");
      59              : 
      60            0 :     entry = (ExtensibleNodeEntry *) hash_search(*p_htable,
      61              :                                                 extnodename,
      62              :                                                 HASH_ENTER, &found);
      63            0 :     if (found)
      64            0 :         ereport(ERROR,
      65              :                 (errcode(ERRCODE_DUPLICATE_OBJECT),
      66              :                  errmsg("extensible node type \"%s\" already exists",
      67              :                         extnodename)));
      68              : 
      69            0 :     entry->extnodemethods = extnodemethods;
      70            0 : }
      71              : 
      72              : /*
      73              :  * Register a new type of extensible node.
      74              :  */
      75              : void
      76            0 : RegisterExtensibleNodeMethods(const ExtensibleNodeMethods *methods)
      77              : {
      78            0 :     RegisterExtensibleNodeEntry(&extensible_node_methods,
      79              :                                 "Extensible Node Methods",
      80            0 :                                 methods->extnodename,
      81              :                                 methods);
      82            0 : }
      83              : 
      84              : /*
      85              :  * Register a new type of custom scan node
      86              :  */
      87              : void
      88            0 : RegisterCustomScanMethods(const CustomScanMethods *methods)
      89              : {
      90            0 :     RegisterExtensibleNodeEntry(&custom_scan_methods,
      91              :                                 "Custom Scan Methods",
      92            0 :                                 methods->CustomName,
      93              :                                 methods);
      94            0 : }
      95              : 
      96              : /*
      97              :  * An internal routine to get an ExtensibleNodeEntry by the given identifier
      98              :  */
      99              : static const void *
     100            0 : GetExtensibleNodeEntry(HTAB *htable, const char *extnodename, bool missing_ok)
     101              : {
     102            0 :     ExtensibleNodeEntry *entry = NULL;
     103              : 
     104            0 :     if (htable != NULL)
     105            0 :         entry = (ExtensibleNodeEntry *) hash_search(htable,
     106              :                                                     extnodename,
     107              :                                                     HASH_FIND, NULL);
     108            0 :     if (!entry)
     109              :     {
     110            0 :         if (missing_ok)
     111            0 :             return NULL;
     112            0 :         ereport(ERROR,
     113              :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
     114              :                  errmsg("ExtensibleNodeMethods \"%s\" was not registered",
     115              :                         extnodename)));
     116              :     }
     117              : 
     118            0 :     return entry->extnodemethods;
     119              : }
     120              : 
     121              : /*
     122              :  * Get the methods for a given type of extensible node.
     123              :  */
     124              : const ExtensibleNodeMethods *
     125            0 : GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
     126              : {
     127            0 :     return (const ExtensibleNodeMethods *)
     128            0 :         GetExtensibleNodeEntry(extensible_node_methods,
     129              :                                extnodename,
     130              :                                missing_ok);
     131              : }
     132              : 
     133              : /*
     134              :  * Get the methods for a given name of CustomScanMethods
     135              :  */
     136              : const CustomScanMethods *
     137            0 : GetCustomScanMethods(const char *CustomName, bool missing_ok)
     138              : {
     139            0 :     return (const CustomScanMethods *)
     140            0 :         GetExtensibleNodeEntry(custom_scan_methods,
     141              :                                CustomName,
     142              :                                missing_ok);
     143              : }
        

Generated by: LCOV version 2.0-1