@ -49,6 +49,9 @@ static bool desirable_join(PlannerInfo *root,
* geqo_eval
* geqo_eval
*
*
* Returns cost of a query tree as an individual of the population .
* Returns cost of a query tree as an individual of the population .
*
* If no legal join order can be extracted from the proposed tour ,
* returns DBL_MAX .
*/
*/
Cost
Cost
geqo_eval ( PlannerInfo * root , Gene * tour , int num_gene )
geqo_eval ( PlannerInfo * root , Gene * tour , int num_gene )
@ -56,7 +59,6 @@ geqo_eval(PlannerInfo *root, Gene *tour, int num_gene)
MemoryContext mycontext ;
MemoryContext mycontext ;
MemoryContext oldcxt ;
MemoryContext oldcxt ;
RelOptInfo * joinrel ;
RelOptInfo * joinrel ;
Path * best_path ;
Cost fitness ;
Cost fitness ;
int savelength ;
int savelength ;
struct HTAB * savehash ;
struct HTAB * savehash ;
@ -100,16 +102,22 @@ geqo_eval(PlannerInfo *root, Gene *tour, int num_gene)
/* construct the best path for the given combination of relations */
/* construct the best path for the given combination of relations */
joinrel = gimme_tree ( root , tour , num_gene ) ;
joinrel = gimme_tree ( root , tour , num_gene ) ;
best_path = joinrel - > cheapest_total_path ;
/*
/*
* compute fitness
* compute fitness , if we found a valid join
*
*
* XXX geqo does not currently support optimization for partial result
* XXX geqo does not currently support optimization for partial result
* retrieval , nor do we take any cognizance of possible use of
* retrieval , nor do we take any cognizance of possible use of
* parameterized paths - - - how to fix ?
* parameterized paths - - - how to fix ?
*/
*/
fitness = best_path - > total_cost ;
if ( joinrel )
{
Path * best_path = joinrel - > cheapest_total_path ;
fitness = best_path - > total_cost ;
}
else
fitness = DBL_MAX ;
/*
/*
* Restore join_rel_list to its former state , and put back original
* Restore join_rel_list to its former state , and put back original
@ -134,7 +142,8 @@ geqo_eval(PlannerInfo *root, Gene *tour, int num_gene)
* ' tour ' is the proposed join order , of length ' num_gene '
* ' tour ' is the proposed join order , of length ' num_gene '
*
*
* Returns a new join relation whose cheapest path is the best plan for
* Returns a new join relation whose cheapest path is the best plan for
* this join order .
* this join order . NB : will return NULL if join order is invalid and
* we can ' t modify it into a valid order .
*
*
* The original implementation of this routine always joined in the specified
* The original implementation of this routine always joined in the specified
* order , and so could only build left - sided plans ( and right - sided and
* order , and so could only build left - sided plans ( and right - sided and
@ -147,7 +156,10 @@ geqo_eval(PlannerInfo *root, Gene *tour, int num_gene)
* postpones joins that are illegal or seem unsuitable according to some
* postpones joins that are illegal or seem unsuitable according to some
* heuristic rules . This allows correct bushy plans to be generated at need ,
* heuristic rules . This allows correct bushy plans to be generated at need ,
* and as a nice side - effect it seems to materially improve the quality of the
* and as a nice side - effect it seems to materially improve the quality of the
* generated plans .
* generated plans . Note however that since it ' s just a heuristic , it can
* still fail in some cases . ( In particular , we might clump together
* relations that actually mustn ' t be joined yet due to LATERAL restrictions ;
* since there ' s no provision for un - clumping , this must lead to failure . )
*/
*/
RelOptInfo *
RelOptInfo *
gimme_tree ( PlannerInfo * root , Gene * tour , int num_gene )
gimme_tree ( PlannerInfo * root , Gene * tour , int num_gene )
@ -164,9 +176,8 @@ gimme_tree(PlannerInfo *root, Gene *tour, int num_gene)
* to ; if there is none then it becomes a new clump of its own . When we
* to ; if there is none then it becomes a new clump of its own . When we
* enlarge an existing clump we check to see if it can now be merged with
* enlarge an existing clump we check to see if it can now be merged with
* any other clumps . After the tour is all scanned , we forget about the
* any other clumps . After the tour is all scanned , we forget about the
* heuristics and try to forcibly join any remaining clumps . Some forced
* heuristics and try to forcibly join any remaining clumps . If we are
* joins might still fail due to semantics , but we should always be able
* unable to merge all the clumps into one , fail .
* to find some join order that works .
*/
*/
clumps = NIL ;
clumps = NIL ;
@ -208,7 +219,7 @@ gimme_tree(PlannerInfo *root, Gene *tour, int num_gene)
/* Did we succeed in forming a single join relation? */
/* Did we succeed in forming a single join relation? */
if ( list_length ( clumps ) ! = 1 )
if ( list_length ( clumps ) ! = 1 )
elog ( ERROR , " failed to join all relations together " ) ;
return NULL ;
return ( ( Clump * ) linitial ( clumps ) ) - > joinrel ;
return ( ( Clump * ) linitial ( clumps ) ) - > joinrel ;
}
}