diff --git a/doc/src/sgml/custom-scan.sgml b/doc/src/sgml/custom-scan.sgml
index 239ba29de7..0fd8494e45 100644
--- a/doc/src/sgml/custom-scan.sgml
+++ b/doc/src/sgml/custom-scan.sgml
@@ -73,8 +73,9 @@ typedef struct CustomPath
the row-count estimate, start and total cost, and sort ordering provided
by this path. flags is a bit mask, which should include
CUSTOMPATH_SUPPORT_BACKWARD_SCAN if the custom path can support
- a backward scan and CUSTOMPATH_SUPPORT_MARK_RESTORE if it
- can support mark and restore. Both capabilities are optional.
+ a backward scan, CUSTOMPATH_SUPPORT_MARK_RESTORE if it
+ can support mark and restore, and CUSTOMPATH_SUPPORT_PROJECTION
+ if it can support projections. All capabilities are optional.
An optional custom_paths is a list of Path
nodes used by this custom-path node; these will be transformed into
Plan nodes by planner.
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index a9aff24831..c9c8b140e5 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -7051,6 +7051,8 @@ is_projection_capable_path(Path *path)
* get relaxed later.
*/
return false;
+ case T_CustomScan:
+ return castNode(CustomPath, path)->flags & CUSTOMPATH_SUPPORT_PROJECTION;
default:
break;
}
@@ -7089,6 +7091,8 @@ is_projection_capable_plan(Plan *plan)
* get relaxed later.
*/
return false;
+ case T_CustomScan:
+ return castNode(CustomScan, plan)->flags & CUSTOMPATH_SUPPORT_PROJECTION;
default:
break;
}
diff --git a/src/include/nodes/extensible.h b/src/include/nodes/extensible.h
index 9e425e5651..7d3dc7e828 100644
--- a/src/include/nodes/extensible.h
+++ b/src/include/nodes/extensible.h
@@ -80,6 +80,7 @@ extern const ExtensibleNodeMethods *GetExtensibleNodeMethods(const char *name,
*/
#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