summaryrefslogtreecommitdiff
path: root/src/backend/nodes/extensible.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2016-03-29 11:00:18 -0400
committerRobert Haas <rhaas@postgresql.org>2016-03-29 11:28:04 -0400
commitf9143d102ffd0947ca904c62b1d3d6fd587e0c80 (patch)
treee75fb310cbad87d2641291fec320302531f5c548 /src/backend/nodes/extensible.c
parent534da37927f97ae7cb1b468963ba9bca747209ea (diff)
Rework custom scans to work more like the new extensible node stuff.
Per discussion, the new extensible node framework is thought to be better designed than the custom path/scan/scanstate stuff we added in PostgreSQL 9.5. Rework the latter to be more like the former. This is not backward-compatible, but we generally don't promise that for C APIs, and there probably aren't many people using this yet anyway. KaiGai Kohei, reviewed by Petr Jelinek and me. Some further cosmetic changes by me.
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);
}