Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 955b3e0

Browse files
committed
Allow CustomScan providers to say whether they support projections.
Previously, all CustomScan providers had to support projections, but there may be cases where this is inconvenient. Add a flag bit to say if it's supported. Important item for the release notes: this is non-backwards-compatible since the default is now to assume that CustomScan providers can't project, instead of assuming that they can. It's fail-soft, but could result in visible performance penalties due to adding unnecessary Result nodes. Sven Klemm, reviewed by Aleksander Alekseev; some cosmetic fiddling by me. Discussion: https://postgr.es/m/CAMCrgp1kyakOz6c8aKhNDJXjhQ1dEjEnp+6KNT3KxPrjNtsrDg@mail.gmail.com
1 parent 5798ca5 commit 955b3e0

File tree

4 files changed

+26
-16
lines changed

4 files changed

+26
-16
lines changed

doc/src/sgml/custom-scan.sgml

+10-3
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,17 @@ typedef struct CustomPath
7171
<para>
7272
<structfield>path</structfield> must be initialized as for any other path, including
7373
the row-count estimate, start and total cost, and sort ordering provided
74-
by this path. <structfield>flags</structfield> is a bit mask, which should include
74+
by this path. <structfield>flags</structfield> is a bit mask, which
75+
specifies whether the scan provider can support certain optional
76+
capabilities. <structfield>flags</structfield> should include
7577
<literal>CUSTOMPATH_SUPPORT_BACKWARD_SCAN</literal> if the custom path can support
76-
a backward scan and <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> if it
77-
can support mark and restore. Both capabilities are optional.
78+
a backward scan, <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> if it
79+
can support mark and restore,
80+
and <literal>CUSTOMPATH_SUPPORT_PROJECTION</literal> if it can perform
81+
projections. (If <literal>CUSTOMPATH_SUPPORT_PROJECTION</literal> is not
82+
set, the scan node will only be asked to produce Vars of the scanned
83+
relation; while if that flag is set, the scan node must be able to
84+
evaluate scalar expressions over these Vars.)
7885
An optional <structfield>custom_paths</structfield> is a list of <structname>Path</structname>
7986
nodes used by this custom-path node; these will be transformed into
8087
<structname>Plan</structname> nodes by planner.

src/backend/executor/execAmi.c

+5-12
Original file line numberDiff line numberDiff line change
@@ -438,13 +438,10 @@ ExecSupportsMarkRestore(Path *pathnode)
438438
return true;
439439

440440
case T_CustomScan:
441-
{
442-
CustomPath *customPath = castNode(CustomPath, pathnode);
441+
if (castNode(CustomPath, pathnode)->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE)
442+
return true;
443+
return false;
443444

444-
if (customPath->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE)
445-
return true;
446-
return false;
447-
}
448445
case T_Result:
449446

450447
/*
@@ -567,12 +564,8 @@ ExecSupportsBackwardScan(Plan *node)
567564
return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan);
568565

569566
case T_CustomScan:
570-
{
571-
uint32 flags = ((CustomScan *) node)->flags;
572-
573-
if (flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN)
574-
return true;
575-
}
567+
if (((CustomScan *) node)->flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN)
568+
return true;
576569
return false;
577570

578571
case T_SeqScan:

src/backend/optimizer/plan/createplan.c

+8
Original file line numberDiff line numberDiff line change
@@ -7046,6 +7046,10 @@ is_projection_capable_path(Path *path)
70467046
case T_MergeAppend:
70477047
case T_RecursiveUnion:
70487048
return false;
7049+
case T_CustomScan:
7050+
if (castNode(CustomPath, path)->flags & CUSTOMPATH_SUPPORT_PROJECTION)
7051+
return true;
7052+
return false;
70497053
case T_Append:
70507054

70517055
/*
@@ -7092,6 +7096,10 @@ is_projection_capable_plan(Plan *plan)
70927096
case T_MergeAppend:
70937097
case T_RecursiveUnion:
70947098
return false;
7099+
case T_CustomScan:
7100+
if (((CustomScan *) plan)->flags & CUSTOMPATH_SUPPORT_PROJECTION)
7101+
return true;
7102+
return false;
70957103
case T_ProjectSet:
70967104

70977105
/*

src/include/nodes/extensible.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,12 @@ extern const ExtensibleNodeMethods *GetExtensibleNodeMethods(const char *name,
7676

7777
/*
7878
* Flags for custom paths, indicating what capabilities the resulting scan
79-
* will have.
79+
* will have. The flags fields of CustomPath and CustomScan nodes are
80+
* bitmasks of these flags.
8081
*/
8182
#define CUSTOMPATH_SUPPORT_BACKWARD_SCAN 0x0001
8283
#define CUSTOMPATH_SUPPORT_MARK_RESTORE 0x0002
84+
#define CUSTOMPATH_SUPPORT_PROJECTION 0x0004
8385

8486
/*
8587
* Custom path methods. Mostly, we just need to know how to convert a

0 commit comments

Comments
 (0)