| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * extensible.h |
| 4 | * Definitions for extensible nodes and custom scans |
| 5 | * |
| 6 | * |
| 7 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 8 | * Portions Copyright (c) 1994, Regents of the University of California |
| 9 | * |
| 10 | * src/include/nodes/extensible.h |
| 11 | * |
| 12 | *------------------------------------------------------------------------- |
| 13 | */ |
| 14 | #ifndef EXTENSIBLE_H |
| 15 | #define EXTENSIBLE_H |
| 16 | |
| 17 | #include "access/parallel.h" |
| 18 | #include "commands/explain.h" |
| 19 | #include "nodes/execnodes.h" |
| 20 | #include "nodes/pathnodes.h" |
| 21 | #include "nodes/plannodes.h" |
| 22 | |
| 23 | /* maximum length of an extensible node identifier */ |
| 24 | #define EXTNODENAME_MAX_LEN 64 |
| 25 | |
| 26 | /* |
| 27 | * An extensible node is a new type of node defined by an extension. The |
| 28 | * type is always T_ExtensibleNode, while the extnodename identifies the |
| 29 | * specific type of node. extnodename can be looked up to find the |
| 30 | * ExtensibleNodeMethods for this node type. |
| 31 | */ |
| 32 | typedef struct ExtensibleNode |
| 33 | { |
| 34 | NodeTag type; |
| 35 | const char *extnodename; /* identifier of ExtensibleNodeMethods */ |
| 36 | } ExtensibleNode; |
| 37 | |
| 38 | /* |
| 39 | * node_size is the size of an extensible node of this type in bytes. |
| 40 | * |
| 41 | * nodeCopy is a function which performs a deep copy from oldnode to newnode. |
| 42 | * It does not need to copy type or extnodename, which are copied by the |
| 43 | * core system. |
| 44 | * |
| 45 | * nodeEqual is a function which performs a deep equality comparison between |
| 46 | * a and b and returns true or false accordingly. It does not need to compare |
| 47 | * type or extnodename, which are compared by the core system. |
| 48 | * |
| 49 | * nodeOut is a serialization function for the node type. It should use the |
| 50 | * output conventions typical for outfuncs.c. It does not need to output |
| 51 | * type or extnodename; the core system handles those. |
| 52 | * |
| 53 | * nodeRead is a deserialization function for the node type. It does not need |
| 54 | * to read type or extnodename; the core system handles those. It should fetch |
| 55 | * the next token using pg_strtok() from the current input stream, and then |
| 56 | * reconstruct the private fields according to the manner in readfuncs.c. |
| 57 | * |
| 58 | * All callbacks are mandatory. |
| 59 | */ |
| 60 | typedef struct ExtensibleNodeMethods |
| 61 | { |
| 62 | const char *extnodename; |
| 63 | Size node_size; |
| 64 | void (*nodeCopy) (struct ExtensibleNode *newnode, |
| 65 | const struct ExtensibleNode *oldnode); |
| 66 | bool (*nodeEqual) (const struct ExtensibleNode *a, |
| 67 | const struct ExtensibleNode *b); |
| 68 | void (*nodeOut) (struct StringInfoData *str, |
| 69 | const struct ExtensibleNode *node); |
| 70 | void (*nodeRead) (struct ExtensibleNode *node); |
| 71 | } ExtensibleNodeMethods; |
| 72 | |
| 73 | extern void RegisterExtensibleNodeMethods(const ExtensibleNodeMethods *method); |
| 74 | extern const ExtensibleNodeMethods *GetExtensibleNodeMethods(const char *name, |
| 75 | bool missing_ok); |
| 76 | |
| 77 | /* |
| 78 | * Flags for custom paths, indicating what capabilities the resulting scan |
| 79 | * will have. |
| 80 | */ |
| 81 | #define CUSTOMPATH_SUPPORT_BACKWARD_SCAN 0x0001 |
| 82 | #define CUSTOMPATH_SUPPORT_MARK_RESTORE 0x0002 |
| 83 | |
| 84 | /* |
| 85 | * Custom path methods. Mostly, we just need to know how to convert a |
| 86 | * CustomPath to a plan. |
| 87 | */ |
| 88 | typedef struct CustomPathMethods |
| 89 | { |
| 90 | const char *CustomName; |
| 91 | |
| 92 | /* Convert Path to a Plan */ |
| 93 | struct Plan *(*PlanCustomPath) (PlannerInfo *root, |
| 94 | RelOptInfo *rel, |
| 95 | struct CustomPath *best_path, |
| 96 | List *tlist, |
| 97 | List *clauses, |
| 98 | List *custom_plans); |
| 99 | struct List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root, |
| 100 | List *custom_private, |
| 101 | RelOptInfo *child_rel); |
| 102 | } CustomPathMethods; |
| 103 | |
| 104 | /* |
| 105 | * Custom scan. Here again, there's not much to do: we need to be able to |
| 106 | * generate a ScanState corresponding to the scan. |
| 107 | */ |
| 108 | typedef struct CustomScanMethods |
| 109 | { |
| 110 | const char *CustomName; |
| 111 | |
| 112 | /* Create execution state (CustomScanState) from a CustomScan plan node */ |
| 113 | Node *(*CreateCustomScanState) (CustomScan *cscan); |
| 114 | } CustomScanMethods; |
| 115 | |
| 116 | /* |
| 117 | * Execution-time methods for a CustomScanState. This is more complex than |
| 118 | * what we need for a custom path or scan. |
| 119 | */ |
| 120 | typedef struct CustomExecMethods |
| 121 | { |
| 122 | const char *CustomName; |
| 123 | |
| 124 | /* Required executor methods */ |
| 125 | void (*BeginCustomScan) (CustomScanState *node, |
| 126 | EState *estate, |
| 127 | int eflags); |
| 128 | TupleTableSlot *(*ExecCustomScan) (CustomScanState *node); |
| 129 | void (*EndCustomScan) (CustomScanState *node); |
| 130 | void (*ReScanCustomScan) (CustomScanState *node); |
| 131 | |
| 132 | /* Optional methods: needed if mark/restore is supported */ |
| 133 | void (*MarkPosCustomScan) (CustomScanState *node); |
| 134 | void (*RestrPosCustomScan) (CustomScanState *node); |
| 135 | |
| 136 | /* Optional methods: needed if parallel execution is supported */ |
| 137 | Size (*EstimateDSMCustomScan) (CustomScanState *node, |
| 138 | ParallelContext *pcxt); |
| 139 | void (*InitializeDSMCustomScan) (CustomScanState *node, |
| 140 | ParallelContext *pcxt, |
| 141 | void *coordinate); |
| 142 | void (*ReInitializeDSMCustomScan) (CustomScanState *node, |
| 143 | ParallelContext *pcxt, |
| 144 | void *coordinate); |
| 145 | void (*InitializeWorkerCustomScan) (CustomScanState *node, |
| 146 | shm_toc *toc, |
| 147 | void *coordinate); |
| 148 | void (*ShutdownCustomScan) (CustomScanState *node); |
| 149 | |
| 150 | /* Optional: print additional information in EXPLAIN */ |
| 151 | void (*ExplainCustomScan) (CustomScanState *node, |
| 152 | List *ancestors, |
| 153 | ExplainState *es); |
| 154 | } CustomExecMethods; |
| 155 | |
| 156 | extern void RegisterCustomScanMethods(const CustomScanMethods *methods); |
| 157 | extern const CustomScanMethods *GetCustomScanMethods(const char *CustomName, |
| 158 | bool missing_ok); |
| 159 | |
| 160 | #endif /* EXTENSIBLE_H */ |
| 161 | |