diff options
author | Robert Haas <rhaas@postgresql.org> | 2016-03-29 11:00:18 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2016-03-29 11:28:04 -0400 |
commit | f9143d102ffd0947ca904c62b1d3d6fd587e0c80 (patch) | |
tree | e75fb310cbad87d2641291fec320302531f5c548 /src/backend/nodes/extensible.c | |
parent | 534da37927f97ae7cb1b468963ba9bca747209ea (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.c | 88 |
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); } |