Skip to content

Commit a05dc4d

Browse files
committed
Provide readfuncs support for custom scans.
Commit a0d9f6e 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.
1 parent 39b9978 commit a05dc4d

File tree

4 files changed

+51
-20
lines changed

4 files changed

+51
-20
lines changed

doc/src/sgml/custom-scan.sgml

+4-14
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ typedef struct CustomPath
8282
by <literal>nodeToString</>, so that debugging routines that attempt to
8383
print the custom path will work as designed. <structfield>methods</> must
8484
point to a (usually statically allocated) object implementing the required
85-
custom path methods, of which there are currently only two, as further
86-
detailed below.
85+
custom path methods, of which there is currently only one. The
86+
<structfield>LibraryName</> and <structfield>SymbolName</> fields must also
87+
be initialized so that the dynamic loader can resolve them to locate the
88+
method table.
8789
</para>
8890

8991
<para>
@@ -218,18 +220,6 @@ Node *(*CreateCustomScanState) (CustomScan *cscan);
218220
the <function>BeginCustomScan</> callback will be invoked to give the
219221
custom scan provider a chance to do whatever else is needed.
220222
</para>
221-
222-
<para>
223-
<programlisting>
224-
void (*TextOutCustomScan) (StringInfo str,
225-
const CustomScan *node);
226-
</programlisting>
227-
Generate additional output when <function>nodeToString</> is invoked on
228-
this custom plan node. This callback is optional. Since
229-
<function>nodeToString</> will automatically dump all fields in the
230-
structure, including the substructure of the <quote>custom</> fields,
231-
there is usually not much need for this callback.
232-
</para>
233223
</sect2>
234224
</sect1>
235225

src/backend/nodes/outfuncs.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -613,10 +613,11 @@ _outCustomScan(StringInfo str, const CustomScan *node)
613613
WRITE_NODE_FIELD(custom_private);
614614
WRITE_NODE_FIELD(custom_scan_tlist);
615615
WRITE_BITMAPSET_FIELD(custom_relids);
616+
/* Dump library and symbol name instead of raw pointer */
616617
appendStringInfoString(str, " :methods ");
617-
_outToken(str, node->methods->CustomName);
618-
if (node->methods->TextOutCustomScan)
619-
node->methods->TextOutCustomScan(str, node);
618+
_outToken(str, node->methods->LibraryName);
619+
appendStringInfoChar(str, ' ');
620+
_outToken(str, node->methods->SymbolName);
620621
}
621622

622623
static void

src/backend/nodes/readfuncs.c

+41
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#include <math.h>
3030

31+
#include "fmgr.h"
3132
#include "nodes/parsenodes.h"
3233
#include "nodes/plannodes.h"
3334
#include "nodes/readfuncs.h"
@@ -1806,6 +1807,44 @@ _readForeignScan(void)
18061807
READ_DONE();
18071808
}
18081809

1810+
/*
1811+
* _readCustomScan
1812+
*/
1813+
static CustomScan *
1814+
_readCustomScan(void)
1815+
{
1816+
READ_LOCALS(CustomScan);
1817+
char *library_name;
1818+
char *symbol_name;
1819+
const CustomScanMethods *methods;
1820+
1821+
ReadCommonScan(&local_node->scan);
1822+
1823+
READ_UINT_FIELD(flags);
1824+
READ_NODE_FIELD(custom_plans);
1825+
READ_NODE_FIELD(custom_exprs);
1826+
READ_NODE_FIELD(custom_private);
1827+
READ_NODE_FIELD(custom_scan_tlist);
1828+
READ_BITMAPSET_FIELD(custom_relids);
1829+
1830+
/*
1831+
* Reconstruction of methods using library and symbol name
1832+
*/
1833+
token = pg_strtok(&length); /* skip methods: */
1834+
token = pg_strtok(&length); /* LibraryName */
1835+
library_name = nullable_string(token, length);
1836+
token = pg_strtok(&length); /* SymbolName */
1837+
symbol_name = nullable_string(token, length);
1838+
1839+
methods = (const CustomScanMethods *)
1840+
load_external_function(library_name, symbol_name, true, NULL);
1841+
Assert(strcmp(methods->LibraryName, library_name) == 0 &&
1842+
strcmp(methods->SymbolName, symbol_name) == 0);
1843+
local_node->methods = methods;
1844+
1845+
READ_DONE();
1846+
}
1847+
18091848
/*
18101849
* ReadCommonJoin
18111850
* Assign the basic stuff of all nodes that inherit from Join
@@ -2362,6 +2401,8 @@ parseNodeString(void)
23622401
return_value = _readWorkTableScan();
23632402
else if (MATCH("FOREIGNSCAN", 11))
23642403
return_value = _readForeignScan();
2404+
else if (MATCH("CUSTOMSCAN", 10))
2405+
return_value = _readCustomScan();
23652406
else if (MATCH("JOIN", 4))
23662407
return_value = _readJoin();
23672408
else if (MATCH("NESTLOOP", 8))

src/include/nodes/plannodes.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -557,12 +557,11 @@ struct CustomScan;
557557
typedef struct CustomScanMethods
558558
{
559559
const char *CustomName;
560+
const char *LibraryName;
561+
const char *SymbolName;
560562

561563
/* Create execution state (CustomScanState) from a CustomScan plan node */
562564
Node *(*CreateCustomScanState) (struct CustomScan *cscan);
563-
/* Optional: print custom_xxx fields in some special way */
564-
void (*TextOutCustomScan) (StringInfo str,
565-
const struct CustomScan *node);
566565
} CustomScanMethods;
567566

568567
typedef struct CustomScan

0 commit comments

Comments
 (0)