LCOV - code coverage report
Current view: top level - src/backend/nodes - extensible.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 0 33 0.0 %
Date: 2024-11-21 08:14:44 Functions: 0 6 0.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-2024, 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             :                                 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             :                                 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 1.14