This hook seems very strangely defined to me.  Why did you not put the
hook at the point where the current geqo-vs-regular decision is made?
The reason is that I thought about gaining a control over the algorithm
used to solve individual subproblems in make_rel_from_joinlist. If we would
have a couple of algorithms to be tested we can implement a plugin
using join_order_search_hook which will compare the results of
those algorithms. Doing the same at the place where geqo/regular code is
called might make thinks a bit more difficult.

Later on, we could also implement a code trying to run some "very fast"
algorithm at first (for the master problem and all subproblems) to get
some estimates and decide whether it makes sense to try to find a better
plan in longer time.

Also, "optimizer_hook" seems nearly content-free as a name for use
in this area; I see no reason why the particular sub-section of the
planner we're discussing here has more title to that name than other
parts.  Something like "join_order_search_hook" might be more
appropriate.
I completely agree and I have renamed the hook.

The new version V3 of the patch is attached.

Thanks for the comments.

Regards

Julius Stroffek
*** ./src/backend/optimizer/path/allpaths.c.orig	Sat May 26 20:23:01 2007
--- ./src/backend/optimizer/path/allpaths.c	Tue Sep 25 11:37:19 2007
***************
*** 37,43 ****
--- 37,45 ----
  bool		enable_geqo = false;	/* just in case GUC doesn't set it */
  int			geqo_threshold;
  
+ join_order_search_hook_type join_order_search_hook = NULL;
  
+ 
  static void set_base_rel_pathlists(PlannerInfo *root);
  static void set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
  							 Index rti, RangeTblEntry *rte);
***************
*** 52,60 ****
  					  RangeTblEntry *rte);
  static void set_values_pathlist(PlannerInfo *root, RelOptInfo *rel,
  					RangeTblEntry *rte);
- static RelOptInfo *make_rel_from_joinlist(PlannerInfo *root, List *joinlist);
- static RelOptInfo *make_one_rel_by_joins(PlannerInfo *root, int levels_needed,
- 					  List *initial_rels);
  static bool subquery_is_pushdown_safe(Query *subquery, Query *topquery,
  						  bool *differentTypes);
  static bool recurse_pushdown_safe(Node *setOp, Query *topquery,
--- 54,59 ----
***************
*** 87,93 ****
  	/*
  	 * Generate access paths for the entire join tree.
  	 */
! 	rel = make_rel_from_joinlist(root, joinlist);
  
  	/*
  	 * The result should join all and only the query's base rels.
--- 86,95 ----
  	/*
  	 * Generate access paths for the entire join tree.
  	 */
! 	if (join_order_search_hook)
! 		rel = join_order_search_hook(root, joinlist);
! 	else
! 		rel = make_rel_from_joinlist(root, joinlist);
  
  	/*
  	 * The result should join all and only the query's base rels.
***************
*** 612,618 ****
   * See comments for deconstruct_jointree() for definition of the joinlist
   * data structure.
   */
! static RelOptInfo *
  make_rel_from_joinlist(PlannerInfo *root, List *joinlist)
  {
  	int			levels_needed;
--- 614,620 ----
   * See comments for deconstruct_jointree() for definition of the joinlist
   * data structure.
   */
! RelOptInfo *
  make_rel_from_joinlist(PlannerInfo *root, List *joinlist)
  {
  	int			levels_needed;
***************
*** 695,701 ****
   * Returns the final level of join relations, i.e., the relation that is
   * the result of joining all the original relations together.
   */
! static RelOptInfo *
  make_one_rel_by_joins(PlannerInfo *root, int levels_needed, List *initial_rels)
  {
  	List	  **joinitems;
--- 697,703 ----
   * Returns the final level of join relations, i.e., the relation that is
   * the result of joining all the original relations together.
   */
! RelOptInfo *
  make_one_rel_by_joins(PlannerInfo *root, int levels_needed, List *initial_rels)
  {
  	List	  **joinitems;
*** ./src/include/optimizer/paths.h.orig	Tue May 22 03:40:33 2007
--- ./src/include/optimizer/paths.h	Tue Sep 25 11:32:34 2007
***************
*** 23,30 ****
  extern bool enable_geqo;
  extern int	geqo_threshold;
  
! extern RelOptInfo *make_one_rel(PlannerInfo *root, List *joinlist);
  
  #ifdef OPTIMIZER_DEBUG
  extern void debug_print_rel(PlannerInfo *root, RelOptInfo *rel);
  #endif
--- 23,46 ----
  extern bool enable_geqo;
  extern int	geqo_threshold;
  
! /* A macro pointing to the standard joinorder search function. */
! #define standard_join_order_search make_rel_from_joinlist
  
+ /* Hook for plugins to get control in make_one_rel() */
+ typedef RelOptInfo * (*join_order_search_hook_type) (PlannerInfo * root,
+ 											 List * joinlist);
+ extern PGDLLIMPORT join_order_search_hook_type join_order_search_hook;
+ 
+ /*
+  * Functions related to searching the space
+  * of all possible join orders.
+  */
+ extern RelOptInfo *make_one_rel(PlannerInfo *root, List *joinlist);
+ extern RelOptInfo *make_rel_from_joinlist(PlannerInfo *root,
+ 										  List *joinlist);
+ extern RelOptInfo *make_one_rel_by_joins(PlannerInfo *root,
+ 										 int levels_needed,
+ 										 List *initial_rels);
  #ifdef OPTIMIZER_DEBUG
  extern void debug_print_rel(PlannerInfo *root, RelOptInfo *rel);
  #endif
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Reply via email to