mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Provide readfuncs support for custom scans.
Commit a0d9f6e434bb56f7e5441b7988f3982feead33b3 added this support for all other plan node types; this fills in the gap. Since TextOutCustomScan complicates this and is pretty well useless, remove it. KaiGai Kohei, with some modifications by me.
This commit is contained in:
parent
39b9978d9c
commit
a05dc4d7fd
@ -82,8 +82,10 @@ typedef struct CustomPath
|
|||||||
by <literal>nodeToString</>, so that debugging routines that attempt to
|
by <literal>nodeToString</>, so that debugging routines that attempt to
|
||||||
print the custom path will work as designed. <structfield>methods</> must
|
print the custom path will work as designed. <structfield>methods</> must
|
||||||
point to a (usually statically allocated) object implementing the required
|
point to a (usually statically allocated) object implementing the required
|
||||||
custom path methods, of which there are currently only two, as further
|
custom path methods, of which there is currently only one. The
|
||||||
detailed below.
|
<structfield>LibraryName</> and <structfield>SymbolName</> fields must also
|
||||||
|
be initialized so that the dynamic loader can resolve them to locate the
|
||||||
|
method table.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -218,18 +220,6 @@ Node *(*CreateCustomScanState) (CustomScan *cscan);
|
|||||||
the <function>BeginCustomScan</> callback will be invoked to give the
|
the <function>BeginCustomScan</> callback will be invoked to give the
|
||||||
custom scan provider a chance to do whatever else is needed.
|
custom scan provider a chance to do whatever else is needed.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
<programlisting>
|
|
||||||
void (*TextOutCustomScan) (StringInfo str,
|
|
||||||
const CustomScan *node);
|
|
||||||
</programlisting>
|
|
||||||
Generate additional output when <function>nodeToString</> is invoked on
|
|
||||||
this custom plan node. This callback is optional. Since
|
|
||||||
<function>nodeToString</> will automatically dump all fields in the
|
|
||||||
structure, including the substructure of the <quote>custom</> fields,
|
|
||||||
there is usually not much need for this callback.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
</sect2>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
@ -613,10 +613,11 @@ _outCustomScan(StringInfo str, const CustomScan *node)
|
|||||||
WRITE_NODE_FIELD(custom_private);
|
WRITE_NODE_FIELD(custom_private);
|
||||||
WRITE_NODE_FIELD(custom_scan_tlist);
|
WRITE_NODE_FIELD(custom_scan_tlist);
|
||||||
WRITE_BITMAPSET_FIELD(custom_relids);
|
WRITE_BITMAPSET_FIELD(custom_relids);
|
||||||
|
/* Dump library and symbol name instead of raw pointer */
|
||||||
appendStringInfoString(str, " :methods ");
|
appendStringInfoString(str, " :methods ");
|
||||||
_outToken(str, node->methods->CustomName);
|
_outToken(str, node->methods->LibraryName);
|
||||||
if (node->methods->TextOutCustomScan)
|
appendStringInfoChar(str, ' ');
|
||||||
node->methods->TextOutCustomScan(str, node);
|
_outToken(str, node->methods->SymbolName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "fmgr.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "nodes/plannodes.h"
|
#include "nodes/plannodes.h"
|
||||||
#include "nodes/readfuncs.h"
|
#include "nodes/readfuncs.h"
|
||||||
@ -1806,6 +1807,44 @@ _readForeignScan(void)
|
|||||||
READ_DONE();
|
READ_DONE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _readCustomScan
|
||||||
|
*/
|
||||||
|
static CustomScan *
|
||||||
|
_readCustomScan(void)
|
||||||
|
{
|
||||||
|
READ_LOCALS(CustomScan);
|
||||||
|
char *library_name;
|
||||||
|
char *symbol_name;
|
||||||
|
const CustomScanMethods *methods;
|
||||||
|
|
||||||
|
ReadCommonScan(&local_node->scan);
|
||||||
|
|
||||||
|
READ_UINT_FIELD(flags);
|
||||||
|
READ_NODE_FIELD(custom_plans);
|
||||||
|
READ_NODE_FIELD(custom_exprs);
|
||||||
|
READ_NODE_FIELD(custom_private);
|
||||||
|
READ_NODE_FIELD(custom_scan_tlist);
|
||||||
|
READ_BITMAPSET_FIELD(custom_relids);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reconstruction of methods using library and symbol name
|
||||||
|
*/
|
||||||
|
token = pg_strtok(&length); /* skip methods: */
|
||||||
|
token = pg_strtok(&length); /* LibraryName */
|
||||||
|
library_name = nullable_string(token, length);
|
||||||
|
token = pg_strtok(&length); /* SymbolName */
|
||||||
|
symbol_name = nullable_string(token, length);
|
||||||
|
|
||||||
|
methods = (const CustomScanMethods *)
|
||||||
|
load_external_function(library_name, symbol_name, true, NULL);
|
||||||
|
Assert(strcmp(methods->LibraryName, library_name) == 0 &&
|
||||||
|
strcmp(methods->SymbolName, symbol_name) == 0);
|
||||||
|
local_node->methods = methods;
|
||||||
|
|
||||||
|
READ_DONE();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ReadCommonJoin
|
* ReadCommonJoin
|
||||||
* Assign the basic stuff of all nodes that inherit from Join
|
* Assign the basic stuff of all nodes that inherit from Join
|
||||||
@ -2362,6 +2401,8 @@ parseNodeString(void)
|
|||||||
return_value = _readWorkTableScan();
|
return_value = _readWorkTableScan();
|
||||||
else if (MATCH("FOREIGNSCAN", 11))
|
else if (MATCH("FOREIGNSCAN", 11))
|
||||||
return_value = _readForeignScan();
|
return_value = _readForeignScan();
|
||||||
|
else if (MATCH("CUSTOMSCAN", 10))
|
||||||
|
return_value = _readCustomScan();
|
||||||
else if (MATCH("JOIN", 4))
|
else if (MATCH("JOIN", 4))
|
||||||
return_value = _readJoin();
|
return_value = _readJoin();
|
||||||
else if (MATCH("NESTLOOP", 8))
|
else if (MATCH("NESTLOOP", 8))
|
||||||
|
@ -557,12 +557,11 @@ struct CustomScan;
|
|||||||
typedef struct CustomScanMethods
|
typedef struct CustomScanMethods
|
||||||
{
|
{
|
||||||
const char *CustomName;
|
const char *CustomName;
|
||||||
|
const char *LibraryName;
|
||||||
|
const char *SymbolName;
|
||||||
|
|
||||||
/* Create execution state (CustomScanState) from a CustomScan plan node */
|
/* Create execution state (CustomScanState) from a CustomScan plan node */
|
||||||
Node *(*CreateCustomScanState) (struct CustomScan *cscan);
|
Node *(*CreateCustomScanState) (struct CustomScan *cscan);
|
||||||
/* Optional: print custom_xxx fields in some special way */
|
|
||||||
void (*TextOutCustomScan) (StringInfo str,
|
|
||||||
const struct CustomScan *node);
|
|
||||||
} CustomScanMethods;
|
} CustomScanMethods;
|
||||||
|
|
||||||
typedef struct CustomScan
|
typedef struct CustomScan
|
||||||
|
Loading…
x
Reference in New Issue
Block a user