prevSingleScanRowCount = outermostCostEstimate.singleScanRowCount();
}
else
{
prevPosition = proposedJoinOrder[joinPosition - 1];
CostEstimate localCE =
optimizableList.
getOptimizable(prevPosition).
getBestAccessPath().
getCostEstimate();
prevRowCount = localCE.rowCount();
prevSingleScanRowCount = localCE.singleScanRowCount();
}
/*
** If there is no feasible join order, the cost estimate
** in the best access path may never have been set.
** In this case, do not subtract anything from the
** current cost, since nothing was added to the current
** cost.
*/
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--but that should ONLY happen if the
** optimizable we just pulled was at position 0. If we
** have a newCost that is <= 0 at any other time, then
** it's the result of a different kind of precision loss--
** namely, the estimated cost of pullMe was so large that
** we lost the precision of the accumulated cost as it
** existed prior to pullMe. Then when we subtracted
** pullMe's cost out, we ended up setting newCost to zero.
** That's an unfortunate side effect of optimizer cost
** estimates that grow too large. If that's what happened
** here,try to make some sense of things by adding up costs
** as they existed prior to pullMe...
*/
if (newCost <= 0.0)
{
if (joinPosition == 0)
newCost = 0.0;
else
newCost = recoverCostFromProposedJoinOrder(false);
}
}
/* If we are choosing a new outer table, then
* we rest the starting cost to the outermostCost.
* (Thus avoiding any problems with floating point
* accuracy and going negative.)
*/
if (joinPosition == 0)
{
if (outermostCostEstimate != null)
{
newCost = outermostCostEstimate.getEstimatedCost();
}
else
{
newCost = 0.0;
}
}
currentCost.setCost(
newCost,
prevRowCount,
prevSingleScanRowCount);
/*
** Subtract from the sort avoidance cost if there is a
** required row ordering.
**
** NOTE: It is not necessary here to check whether the
** best cost was ever set for the sort avoidance path,
** because it considerSortAvoidancePath() would not be
** set if there cost were not set.
*/
if (requiredRowOrdering != null)
{
if (pullMe.considerSortAvoidancePath())
{
AccessPath ap = pullMe.getBestSortAvoidancePath();
double prevEstimatedCost = 0.0d;
/*
** Subtract the sort avoidance cost estimate of the
** optimizable being removed from the total sort
** avoidance cost estimate.
**
** The total cost is the sum of all the costs, but the
** total number of rows is the number of rows returned
** by the innermost optimizable.
*/
if (joinPosition == 0)
{
prevRowCount = outermostCostEstimate.rowCount();
prevSingleScanRowCount =
outermostCostEstimate.singleScanRowCount();
/* If we are choosing a new outer table, then
* we rest the starting cost to the outermostCost.
* (Thus avoiding any problems with floating point
* accuracy and going negative.)
*/
prevEstimatedCost =
outermostCostEstimate.getEstimatedCost();
}
else
{
CostEstimate localCE =
optimizableList.
getOptimizable(prevPosition).
getBestSortAvoidancePath().
getCostEstimate();
prevRowCount = localCE.rowCount();
prevSingleScanRowCount = localCE.singleScanRowCount();
prevEstimatedCost =
currentSortAvoidanceCost.getEstimatedCost() -
ap.getCostEstimate().getEstimatedCost();
}