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 */