mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-02 03:21:14 +02:00
29275b1d17
Reported-by: Michael Paquier Discussion: https://postgr.es/m/ZZKTDPxBBMt3C0J9@paquier.xyz Backpatch-through: 12
165 lines
5.6 KiB
C
165 lines
5.6 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* extensible.h
|
|
* Definitions for extensible nodes and custom scans
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2024, 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 */
|