db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bryan Pendleton <bpendle...@amberpoint.com>
Subject Optimizer: question about predicate pushdown and handling of intermediate costs
Date Wed, 22 Nov 2006 23:50:26 GMT
Hi Optimizer Enthusiasts!

I've been thinking about predicate pushdown and have a question. The question
specifically involves this section of code in OptimizerImpl:

                 double newCost = currentCost.getEstimatedCost();
                 double pullCost = 0.0;
                 CostEstimate pullCostEstimate =
                                 pullMe.getBestAccessPath().getCostEstimate();
                 if (pullCostEstimate != null)
                 {
                     pullCost = pullCostEstimate.getEstimatedCost();

                     newCost -= pullCost;

                     /*
                     ** It's possible for newCost to go negative here due to
                     ** loss of precision.
                     */
                     if (newCost < 0.0)
                         newCost = 0.0;
                 }

This code gets run when we are removing the optimizable at the current join
position from the join order.

I have two questions about this code, both related to the edge-cases of
floating point behavior:

1) if newCost is Infinite and pullCost is Infinite, then newCost -= pullCost
    results in NaN. I'm not quite sure what ought to happen here, but one thought
    I had is that perhaps the last line should look like:
                     if (newCost < 0.0 || Double.isNaN(newCost))
                         newCost = 0.0;

2) if newCost is Infinite, but pullCost is finite, then it would seem that
    during the costing of this optimizable, the estimate crossed over from being
    finite to being Infinite, but in that case, subtracting the finite pullCost
    back out from newCost will not bring the current cost estimate back to being
    a finite number; it will remain Infinite. I wonder whether there should be
    a line like:
                     if (Double.isInfinite(newCost) && ! Double.isInfinite(pullCost))
                         newCost = Double.MAX_VALUE - pullCost;

Please understand that I don't have any examples of actual queries in which either
of these situations arise; these are just based on my reading and thinking about
the code. So these questions may be totally nonsensical.

thanks,

bryan




Mime
View raw message