postgresql/src/include/nodes/extensible.h

165 lines
5.6 KiB
C

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