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 */
32typedef 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 */
60typedef 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
73extern void RegisterExtensibleNodeMethods(const ExtensibleNodeMethods *method);
74extern 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 */
88typedef 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 */
108typedef 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 */
120typedef 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
156extern void RegisterCustomScanMethods(const CustomScanMethods *methods);
157extern const CustomScanMethods *GetCustomScanMethods(const char *CustomName,
158 bool missing_ok);
159
160#endif /* EXTENSIBLE_H */
161