diff options
Diffstat (limited to 'src/include/nodes/extensible.h')
-rw-r--r-- | src/include/nodes/extensible.h | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/include/nodes/extensible.h b/src/include/nodes/extensible.h new file mode 100644 index 0000000..7d51c60 --- /dev/null +++ b/src/include/nodes/extensible.h @@ -0,0 +1,164 @@ +/*------------------------------------------------------------------------- + * + * extensible.h + * Definitions for extensible nodes and custom scans + * + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/extensible.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXTENSIBLE_H +#define EXTENSIBLE_H + +#include "access/parallel.h" +#include "commands/explain.h" +#include "nodes/execnodes.h" +#include "nodes/pathnodes.h" +#include "nodes/plannodes.h" + +/* maximum length of an extensible node identifier */ +#define EXTNODENAME_MAX_LEN 64 + +/* + * An extensible node is a new type of node defined by an extension. The + * type is always T_ExtensibleNode, while the extnodename identifies the + * specific type of node. extnodename can be looked up to find the + * ExtensibleNodeMethods for this node type. + */ +typedef struct ExtensibleNode +{ + pg_node_attr(custom_copy_equal, custom_read_write) + + NodeTag type; + const char *extnodename; /* identifier of ExtensibleNodeMethods */ +} ExtensibleNode; + +/* + * node_size is the size of an extensible node of this type in bytes. + * + * nodeCopy is a function which performs a deep copy from oldnode to newnode. + * It does not need to copy type or extnodename, which are copied by the + * core system. + * + * nodeEqual is a function which performs a deep equality comparison between + * a and b and returns true or false accordingly. It does not need to compare + * type or extnodename, which are compared by the core system. + * + * nodeOut is a serialization function for the node type. It should use the + * output conventions typical for outfuncs.c. It does not need to output + * type or extnodename; the core system handles those. + * + * nodeRead is a deserialization function for the node type. It does not need + * to read type or extnodename; the core system handles those. It should fetch + * the next token using pg_strtok() from the current input stream, and then + * reconstruct the private fields according to the manner in readfuncs.c. + * + * All callbacks are mandatory. + */ +typedef struct ExtensibleNodeMethods +{ + const char *extnodename; + Size node_size; + void (*nodeCopy) (struct ExtensibleNode *newnode, + const struct ExtensibleNode *oldnode); + bool (*nodeEqual) (const struct ExtensibleNode *a, + const struct ExtensibleNode *b); + void (*nodeOut) (struct StringInfoData *str, + const struct ExtensibleNode *node); + void (*nodeRead) (struct ExtensibleNode *node); +} ExtensibleNodeMethods; + +extern void RegisterExtensibleNodeMethods(const ExtensibleNodeMethods *methods); +extern const ExtensibleNodeMethods *GetExtensibleNodeMethods(const char *extnodename, + bool missing_ok); + +/* + * Flags for custom paths, indicating what capabilities the resulting scan + * will have. The flags fields of CustomPath and CustomScan nodes are + * bitmasks of these flags. + */ +#define CUSTOMPATH_SUPPORT_BACKWARD_SCAN 0x0001 +#define CUSTOMPATH_SUPPORT_MARK_RESTORE 0x0002 +#define CUSTOMPATH_SUPPORT_PROJECTION 0x0004 + +/* + * Custom path methods. Mostly, we just need to know how to convert a + * CustomPath to a plan. + */ +typedef struct CustomPathMethods +{ + const char *CustomName; + + /* Convert Path to a Plan */ + struct Plan *(*PlanCustomPath) (PlannerInfo *root, + RelOptInfo *rel, + struct CustomPath *best_path, + List *tlist, + List *clauses, + List *custom_plans); + struct List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root, + List *custom_private, + RelOptInfo *child_rel); +} CustomPathMethods; + +/* + * Custom scan. Here again, there's not much to do: we need to be able to + * generate a ScanState corresponding to the scan. + */ +typedef struct CustomScanMethods +{ + const char *CustomName; + + /* Create execution state (CustomScanState) from a CustomScan plan node */ + Node *(*CreateCustomScanState) (CustomScan *cscan); +} CustomScanMethods; + +/* + * Execution-time methods for a CustomScanState. This is more complex than + * what we need for a custom path or scan. + */ +typedef struct CustomExecMethods +{ + const char *CustomName; + + /* Required executor methods */ + void (*BeginCustomScan) (CustomScanState *node, + EState *estate, + int eflags); + TupleTableSlot *(*ExecCustomScan) (CustomScanState *node); + void (*EndCustomScan) (CustomScanState *node); + void (*ReScanCustomScan) (CustomScanState *node); + + /* Optional methods: needed if mark/restore is supported */ + void (*MarkPosCustomScan) (CustomScanState *node); + void (*RestrPosCustomScan) (CustomScanState *node); + + /* Optional methods: needed if parallel execution is supported */ + Size (*EstimateDSMCustomScan) (CustomScanState *node, + ParallelContext *pcxt); + void (*InitializeDSMCustomScan) (CustomScanState *node, + ParallelContext *pcxt, + void *coordinate); + void (*ReInitializeDSMCustomScan) (CustomScanState *node, + ParallelContext *pcxt, + void *coordinate); + void (*InitializeWorkerCustomScan) (CustomScanState *node, + shm_toc *toc, + void *coordinate); + void (*ShutdownCustomScan) (CustomScanState *node); + + /* Optional: print additional information in EXPLAIN */ + void (*ExplainCustomScan) (CustomScanState *node, + List *ancestors, + ExplainState *es); +} CustomExecMethods; + +extern void RegisterCustomScanMethods(const CustomScanMethods *methods); +extern const CustomScanMethods *GetCustomScanMethods(const char *CustomName, + bool missing_ok); + +#endif /* EXTENSIBLE_H */ |