 src/backend/optimizer/util/pathnode.c | 26 ++++++++++++++++++++++++++
 src/include/optimizer/pathnode.h      |  9 +++++++++
 2 files changed, 35 insertions(+)

diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 34acb73..0955271 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -58,6 +58,7 @@ static List *reparameterize_pathlist_by_child(PlannerInfo *root,
 											  List *pathlist,
 											  RelOptInfo *child_rel);
 
+path_removal_decision_hook_type path_removal_decision_hook = NULL;
 
 /*****************************************************************************
  *		MISC. PATH UTILITIES
@@ -581,6 +582,22 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
 		}
 
 		/*
+		 * This hook allows extension to provide an extra decision
+		 * whether add_path() retains the dominated path by other new
+		 * path, from different dimensions.
+		 * Even if the old_path is not cheapest at this level, we can
+		 * assume a combination with an expected upper path may have
+		 * cheaper cost on the upper level.
+		 */
+		if (remove_old && path_removal_decision_hook)
+		{
+			remove_old = path_removal_decision_hook(parent_rel,
+													new_path,
+													old_path,
+													false);
+		}
+
+		/*
 		 * Remove current element from pathlist if dominated by new.
 		 */
 		if (remove_old)
@@ -816,6 +833,15 @@ add_partial_path(RelOptInfo *parent_rel, Path *new_path)
 			}
 		}
 
+		if (remove_old && path_removal_decision_hook)
+		{
+			/* see comments at add_path() */
+			remove_old = path_removal_decision_hook(parent_rel,
+													new_path,
+													old_path,
+													true);
+		}
+
 		/*
 		 * Remove current element from partial_pathlist if dominated by new.
 		 */
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index a12af54..82a5e5e 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -17,6 +17,15 @@
 #include "nodes/bitmapset.h"
 #include "nodes/pathnodes.h"
 
+/*
+ * Plugins can provide extra decision whether (partial_)pathlist retain
+ * a path dominated by other new paths.
+ */
+typedef bool (*path_removal_decision_hook_type)(RelOptInfo *parent_rel,
+												Path *new_path,
+												Path *old_path,
+												bool is_partial_pathlist);
+extern PGDLLIMPORT path_removal_decision_hook_type path_removal_decision_hook;
 
 /*
  * prototypes for pathnode.c
