Commit a05dc4d7 authored by Robert Haas's avatar Robert Haas

Provide readfuncs support for custom scans.

Commit a0d9f6e4 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.
parent 39b9978d
......@@ -82,8 +82,10 @@ typedef struct CustomPath
by <literal>nodeToString</>, so that debugging routines that attempt to
print the custom path will work as designed. <structfield>methods</> must
point to a (usually statically allocated) object implementing the required
custom path methods, of which there are currently only two, as further
detailed below.
custom path methods, of which there is currently only one. The
<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>
......@@ -218,18 +220,6 @@ Node *(*CreateCustomScanState) (CustomScan *cscan);
the <function>BeginCustomScan</> callback will be invoked to give the
custom scan provider a chance to do whatever else is needed.
</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>
</sect1>
......
......@@ -613,10 +613,11 @@ _outCustomScan(StringInfo str, const CustomScan *node)
WRITE_NODE_FIELD(custom_private);
WRITE_NODE_FIELD(custom_scan_tlist);
WRITE_BITMAPSET_FIELD(custom_relids);
/* Dump library and symbol name instead of raw pointer */
appendStringInfoString(str, " :methods ");
_outToken(str, node->methods->CustomName);
if (node->methods->TextOutCustomScan)
node->methods->TextOutCustomScan(str, node);
_outToken(str, node->methods->LibraryName);
appendStringInfoChar(str, ' ');
_outToken(str, node->methods->SymbolName);
}
static void
......
......@@ -28,6 +28,7 @@
#include <math.h>
#include "fmgr.h"
#include "nodes/parsenodes.h"
#include "nodes/plannodes.h"
#include "nodes/readfuncs.h"
......@@ -1806,6 +1807,44 @@ _readForeignScan(void)
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
* Assign the basic stuff of all nodes that inherit from Join
......@@ -2362,6 +2401,8 @@ parseNodeString(void)
return_value = _readWorkTableScan();
else if (MATCH("FOREIGNSCAN", 11))
return_value = _readForeignScan();
else if (MATCH("CUSTOMSCAN", 10))
return_value = _readCustomScan();
else if (MATCH("JOIN", 4))
return_value = _readJoin();
else if (MATCH("NESTLOOP", 8))
......
......@@ -557,12 +557,11 @@ struct CustomScan;
typedef struct CustomScanMethods
{
const char *CustomName;
const char *LibraryName;
const char *SymbolName;
/* Create execution state (CustomScanState) from a CustomScan plan node */
Node *(*CreateCustomScanState) (struct CustomScan *cscan);
/* Optional: print custom_xxx fields in some special way */
void (*TextOutCustomScan) (StringInfo str,
const struct CustomScan *node);
} CustomScanMethods;
typedef struct CustomScan
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment