I've applied this patch with revision to put the hook where I thought it
made sense. Attached is a modification of your dummy.c to show use of
the hook. I didn't test it heavily, but I did check that it seemed to
work with either order of calling geqo() and standard_join_search().
regards, tom lane
#include "postgres.h"
#include "fmgr.h"
#include "optimizer/geqo.h"
#include "optimizer/paths.h"
#include "optimizer/pathnode.h"
PG_MODULE_MAGIC;
void _PG_init(void);
void _PG_fini(void);
static RelOptInfo *
my_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
{
RelOptInfo *dynamic_result, *geqo_result;
Cost dynamic_cost, geqo_cost;
List *dynamic_list, *geqo_list;
struct HTAB *dynamic_hash, *geqo_hash;
int savelength;
savelength = list_length(root->join_rel_list);
root->join_rel_hash = NULL;
elog(LOG, "Starting a join order search \"dynamic\"...");
dynamic_result = standard_join_search(root, levels_needed, initial_rels);
dynamic_cost = dynamic_result->cheapest_total_path->total_cost;
dynamic_list = list_copy(root->join_rel_list);
dynamic_hash = root->join_rel_hash;
root->join_rel_list = list_truncate(root->join_rel_list,
savelength);
root->join_rel_hash = NULL;
elog(LOG, "Starting a join order search \"geqo\"...");
geqo_result = geqo(root, levels_needed, initial_rels);
geqo_cost = geqo_result->cheapest_total_path->total_cost;
geqo_list = list_copy(root->join_rel_list);
geqo_hash = root->join_rel_hash;
fprintf(stderr, "GEQO cost: %f Dynamic programming cost: %f\n",
geqo_cost, dynamic_cost);
if (geqo_cost < dynamic_cost)
{
root->join_rel_list = geqo_list;
root->join_rel_hash = geqo_hash;
return geqo_result;
}
else
{
root->join_rel_list = dynamic_list;
root->join_rel_hash = dynamic_hash;
return dynamic_result;
}
}
void
_PG_init(void)
{
join_search_hook = my_join_search;
}
void
_PG_fini(void)
{
join_search_hook = NULL;
}