summaryrefslogtreecommitdiff
path: root/src/backend/nodes/extensible.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/nodes/extensible.c')
-rw-r--r--src/backend/nodes/extensible.c88
1 files changed, 69 insertions, 19 deletions
diff --git a/src/backend/nodes/extensible.c b/src/backend/nodes/extensible.c
index 2473b658b17..d61be58c45d 100644
--- a/src/backend/nodes/extensible.c
+++ b/src/backend/nodes/extensible.c
@@ -24,61 +24,87 @@
#include "utils/hsearch.h"
static HTAB *extensible_node_methods = NULL;
+static HTAB *custom_scan_methods = NULL;
typedef struct
{
char extnodename[EXTNODENAME_MAX_LEN];
- const ExtensibleNodeMethods *methods;
+ const void *extnodemethods;
} ExtensibleNodeEntry;
/*
- * Register a new type of extensible node.
+ * An internal function to register a new callback structure
*/
-void
-RegisterExtensibleNodeMethods(const ExtensibleNodeMethods *methods)
+static void
+RegisterExtensibleNodeEntry(HTAB **p_htable, const char *htable_label,
+ const char *extnodename,
+ const void *extnodemethods)
{
ExtensibleNodeEntry *entry;
bool found;
- if (extensible_node_methods == NULL)
+ if (*p_htable == NULL)
{
HASHCTL ctl;
memset(&ctl, 0, sizeof(HASHCTL));
ctl.keysize = EXTNODENAME_MAX_LEN;
ctl.entrysize = sizeof(ExtensibleNodeEntry);
- extensible_node_methods = hash_create("Extensible Node Methods",
- 100, &ctl, HASH_ELEM);
+
+ *p_htable = hash_create(htable_label, 100, &ctl, HASH_ELEM);
}
- if (strlen(methods->extnodename) >= EXTNODENAME_MAX_LEN)
+ if (strlen(extnodename) >= EXTNODENAME_MAX_LEN)
elog(ERROR, "extensible node name is too long");
- entry = (ExtensibleNodeEntry *) hash_search(extensible_node_methods,
- methods->extnodename,
+ entry = (ExtensibleNodeEntry *) hash_search(*p_htable,
+ extnodename,
HASH_ENTER, &found);
if (found)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("extensible node type \"%s\" already exists",
- methods->extnodename)));
+ extnodename)));
- entry->methods = methods;
+ entry->extnodemethods = extnodemethods;
}
/*
- * Get the methods for a given type of extensible node.
+ * Register a new type of extensible node.
*/
-const ExtensibleNodeMethods *
-GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
+void
+RegisterExtensibleNodeMethods(const ExtensibleNodeMethods *methods)
+{
+ RegisterExtensibleNodeEntry(&extensible_node_methods,
+ "Extensible Node Methods",
+ methods->extnodename,
+ methods);
+}
+
+/*
+ * Register a new type of custom scan node
+ */
+void
+RegisterCustomScanMethods(const CustomScanMethods *methods)
+{
+ RegisterExtensibleNodeEntry(&custom_scan_methods,
+ "Custom Scan Methods",
+ methods->CustomName,
+ methods);
+}
+
+/*
+ * An internal routine to get an ExtensibleNodeEntry by the given identifier
+ */
+static const void *
+GetExtensibleNodeEntry(HTAB *htable, const char *extnodename, bool missing_ok)
{
ExtensibleNodeEntry *entry = NULL;
- if (extensible_node_methods != NULL)
- entry = (ExtensibleNodeEntry *) hash_search(extensible_node_methods,
+ if (htable != NULL)
+ entry = (ExtensibleNodeEntry *) hash_search(htable,
extnodename,
HASH_FIND, NULL);
-
if (!entry)
{
if (missing_ok)
@@ -89,5 +115,29 @@ GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
extnodename)));
}
- return entry->methods;
+ return entry->extnodemethods;
+}
+
+/*
+ * Get the methods for a given type of extensible node.
+ */
+const ExtensibleNodeMethods *
+GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
+{
+ return (const ExtensibleNodeMethods *)
+ GetExtensibleNodeEntry(extensible_node_methods,
+ extnodename,
+ missing_ok);
+}
+
+/*
+ * Get the methods for a given name of CustomScanMethods
+ */
+const CustomScanMethods *
+GetCustomScanMethods(const char *CustomName, bool missing_ok)
+{
+ return (const CustomScanMethods *)
+ GetExtensibleNodeEntry(custom_scan_methods,
+ CustomName,
+ missing_ok);
}