PostgreSQL Source Code git master
extensible.c
Go to the documentation of this file.
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-2025, 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
28
29typedef struct
30{
31 char extnodename[EXTNODENAME_MAX_LEN];
32 const void *extnodemethods;
34
35/*
36 * An internal function to register a new callback structure
37 */
38static void
39RegisterExtensibleNodeEntry(HTAB **p_htable, const char *htable_label,
40 const char *extnodename,
41 const void *extnodemethods)
42{
44 bool found;
45
46 if (*p_htable == NULL)
47 {
49
50 ctl.keysize = EXTNODENAME_MAX_LEN;
51 ctl.entrysize = sizeof(ExtensibleNodeEntry);
52
53 *p_htable = hash_create(htable_label, 100, &ctl,
55 }
56
57 if (strlen(extnodename) >= EXTNODENAME_MAX_LEN)
58 elog(ERROR, "extensible node name is too long");
59
60 entry = (ExtensibleNodeEntry *) hash_search(*p_htable,
61 extnodename,
62 HASH_ENTER, &found);
63 if (found)
66 errmsg("extensible node type \"%s\" already exists",
67 extnodename)));
68
69 entry->extnodemethods = extnodemethods;
70}
71
72/*
73 * Register a new type of extensible node.
74 */
75void
77{
79 "Extensible Node Methods",
80 methods->extnodename,
81 methods);
82}
83
84/*
85 * Register a new type of custom scan node
86 */
87void
89{
91 "Custom Scan Methods",
92 methods->CustomName,
93 methods);
94}
95
96/*
97 * An internal routine to get an ExtensibleNodeEntry by the given identifier
98 */
99static const void *
100GetExtensibleNodeEntry(HTAB *htable, const char *extnodename, bool missing_ok)
101{
102 ExtensibleNodeEntry *entry = NULL;
103
104 if (htable != NULL)
105 entry = (ExtensibleNodeEntry *) hash_search(htable,
106 extnodename,
107 HASH_FIND, NULL);
108 if (!entry)
109 {
110 if (missing_ok)
111 return NULL;
113 (errcode(ERRCODE_UNDEFINED_OBJECT),
114 errmsg("ExtensibleNodeMethods \"%s\" was not registered",
115 extnodename)));
116 }
117
118 return entry->extnodemethods;
119}
120
121/*
122 * Get the methods for a given type of extensible node.
123 */
125GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
126{
127 return (const ExtensibleNodeMethods *)
129 extnodename,
130 missing_ok);
131}
132
133/*
134 * Get the methods for a given name of CustomScanMethods
135 */
136const CustomScanMethods *
137GetCustomScanMethods(const char *CustomName, bool missing_ok)
138{
139 return (const CustomScanMethods *)
141 CustomName,
142 missing_ok);
143}
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
static HTAB * extensible_node_methods
Definition: extensible.c:26
void RegisterExtensibleNodeMethods(const ExtensibleNodeMethods *methods)
Definition: extensible.c:76
static const void * GetExtensibleNodeEntry(HTAB *htable, const char *extnodename, bool missing_ok)
Definition: extensible.c:100
void RegisterCustomScanMethods(const CustomScanMethods *methods)
Definition: extensible.c:88
const ExtensibleNodeMethods * GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
Definition: extensible.c:125
static HTAB * custom_scan_methods
Definition: extensible.c:27
static void RegisterExtensibleNodeEntry(HTAB **p_htable, const char *htable_label, const char *extnodename, const void *extnodemethods)
Definition: extensible.c:39
const CustomScanMethods * GetCustomScanMethods(const char *CustomName, bool missing_ok)
Definition: extensible.c:137
#define EXTNODENAME_MAX_LEN
Definition: extensible.h:24
#define HASH_STRINGS
Definition: hsearch.h:96
@ HASH_FIND
Definition: hsearch.h:113
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_ELEM
Definition: hsearch.h:95
tree ctl
Definition: radixtree.h:1838
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:30
const char * CustomName
Definition: extensible.h:114
const void * extnodemethods
Definition: extensible.c:32
const char * extnodename
Definition: extensible.h:64
Definition: dynahash.c:220