1 /*-------------------------------------------------------------------------
4 * Support for extensible node types
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.
13 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
14 * Portions Copyright (c) 1994, Regents of the University of California
17 * src/backend/nodes/extensible.c
19 *-------------------------------------------------------------------------
23 #include "nodes/extensible.h"
24 #include "utils/hsearch.h"
26 static HTAB
*extensible_node_methods
= NULL
;
27 static HTAB
*custom_scan_methods
= NULL
;
31 char extnodename
[EXTNODENAME_MAX_LEN
];
32 const void *extnodemethods
;
33 } ExtensibleNodeEntry
;
36 * An internal function to register a new callback structure
39 RegisterExtensibleNodeEntry(HTAB
**p_htable
, const char *htable_label
,
40 const char *extnodename
,
41 const void *extnodemethods
)
43 ExtensibleNodeEntry
*entry
;
46 if (*p_htable
== NULL
)
50 ctl
.keysize
= EXTNODENAME_MAX_LEN
;
51 ctl
.entrysize
= sizeof(ExtensibleNodeEntry
);
53 *p_htable
= hash_create(htable_label
, 100, &ctl
,
54 HASH_ELEM
| HASH_STRINGS
);
57 if (strlen(extnodename
) >= EXTNODENAME_MAX_LEN
)
58 elog(ERROR
, "extensible node name is too long");
60 entry
= (ExtensibleNodeEntry
*) hash_search(*p_htable
,
65 (errcode(ERRCODE_DUPLICATE_OBJECT
),
66 errmsg("extensible node type \"%s\" already exists",
69 entry
->extnodemethods
= extnodemethods
;
73 * Register a new type of extensible node.
76 RegisterExtensibleNodeMethods(const ExtensibleNodeMethods
*methods
)
78 RegisterExtensibleNodeEntry(&extensible_node_methods
,
79 "Extensible Node Methods",
85 * Register a new type of custom scan node
88 RegisterCustomScanMethods(const CustomScanMethods
*methods
)
90 RegisterExtensibleNodeEntry(&custom_scan_methods
,
91 "Custom Scan Methods",
97 * An internal routine to get an ExtensibleNodeEntry by the given identifier
100 GetExtensibleNodeEntry(HTAB
*htable
, const char *extnodename
, bool missing_ok
)
102 ExtensibleNodeEntry
*entry
= NULL
;
105 entry
= (ExtensibleNodeEntry
*) hash_search(htable
,
113 (errcode(ERRCODE_UNDEFINED_OBJECT
),
114 errmsg("ExtensibleNodeMethods \"%s\" was not registered",
118 return entry
->extnodemethods
;
122 * Get the methods for a given type of extensible node.
124 const ExtensibleNodeMethods
*
125 GetExtensibleNodeMethods(const char *extnodename
, bool missing_ok
)
127 return (const ExtensibleNodeMethods
*)
128 GetExtensibleNodeEntry(extensible_node_methods
,
134 * Get the methods for a given name of CustomScanMethods
136 const CustomScanMethods
*
137 GetCustomScanMethods(const char *CustomName
, bool missing_ok
)
139 return (const CustomScanMethods
*)
140 GetExtensibleNodeEntry(custom_scan_methods
,