Hi Tom,

Thanks for your feedback. I completely agree with you that a higher-level
hook is better suited for this case. I have adjusted the PoC patch to this
email.

Now it is located in the clauselist_selectivity_ext function, where we
first check if the hook is defined. If so, we let the hook estimate the
selectivity and return the result. With this one, I can also develop
extensions to better estimate the selectivity.

I hope it makes more sense. Also please forgive me if I am understanding
Postgres somehow wrong, as I am quite new to this community :)

Best regards,
Xiaozhe
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index d263ecf082..841306ca6c 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -26,6 +26,9 @@
 #include "utils/lsyscache.h"
 #include "utils/selfuncs.h"
 
+/* Hooks for plugins to get control when we ask for selectivity */
+clauselist_selectivity_hook_type clauselist_selectivity_hook = NULL;
+
 /*
  * Data structure for accumulating info about possible range-query
  * clause pairs in clauselist_selectivity.
@@ -130,6 +133,12 @@ clauselist_selectivity_ext(PlannerInfo *root,
 	ListCell   *l;
 	int			listidx;
 
+	/*
+	* If we have a hook for selectivity estimation, then go for it
+	*/
+	if (clauselist_selectivity_hook)
+		return clauselist_selectivity_hook(root, clauses, varRelid, jointype, sjinfo, use_extended_stats);
+
 	/*
 	 * If there's exactly one clause, just go directly to
 	 * clause_selectivity_ext(). None of what we might do below is relevant.
diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h
index 41b49b2662..b8b9b34946 100644
--- a/src/include/optimizer/optimizer.h
+++ b/src/include/optimizer/optimizer.h
@@ -202,4 +202,16 @@ extern int	locate_var_of_level(Node *node, int levelsup);
 extern List *pull_var_clause(Node *node, int flags);
 extern Node *flatten_join_alias_vars(Query *query, Node *node);
 
+/* Hooks for external selectivity estimation */
+typedef Selectivity (*clauselist_selectivity_hook_type) (
+						   PlannerInfo *root,
+						   List *clauses,
+						   int varRelid,
+						   JoinType jointype,
+						   SpecialJoinInfo *sjinfo,
+						   bool use_extended_stats);
+
+extern PGDLLIMPORT clauselist_selectivity_hook_type clauselist_selectivity_hook;
+
+
 #endif							/* OPTIMIZER_H */

Reply via email to