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 | |