📄 intersectorexceptnode.java
字号:
CostEstimate outerCost,
Optimizer optimizer,
RowOrdering rowOrdering)
throws StandardException
{
leftResultSet = optimizeSource(
optimizer,
leftResultSet,
(PredicateList) null,
outerCost);
rightResultSet = optimizeSource(
optimizer,
rightResultSet,
(PredicateList) null,
outerCost);
CostEstimate costEstimate = getCostEstimate(optimizer);
CostEstimate leftCostEstimate = leftResultSet.getCostEstimate();
CostEstimate rightCostEstimate = rightResultSet.getCostEstimate();
// The cost is the sum of the two child costs plus the cost of sorting the union.
costEstimate.setCost( leftCostEstimate.getEstimatedCost() + rightCostEstimate.getEstimatedCost(),
getRowCountEstimate( leftCostEstimate.rowCount(),
rightCostEstimate.rowCount()),
getSingleScanRowCountEstimate( leftCostEstimate.singleScanRowCount(),
rightCostEstimate.singleScanRowCount()));
return costEstimate;
} // End of estimateCost
/**
* @see Optimizable#modifyAccessPath
*
* @exception StandardException Thrown on error
*/
public Optimizable modifyAccessPath(JBitSet outerTables) throws StandardException
{
Optimizable retOptimizable;
retOptimizable = super.modifyAccessPath(outerTables);
/* We only want call addNewNodes() once */
if (addNewNodesCalled)
{
return retOptimizable;
}
return (Optimizable) addNewNodes();
}
/**
* @see ResultSetNode#modifyAccessPaths
*
* @exception StandardException Thrown on error
*/
public ResultSetNode modifyAccessPaths() throws StandardException
{
ResultSetNode retRSN;
retRSN = super.modifyAccessPaths();
/* We only want call addNewNodes() once */
if (addNewNodesCalled)
{
return retRSN;
}
return addNewNodes();
}
/**
* Add any new ResultSetNodes that are necessary to the tree.
* We wait until after optimization to do this in order to
* make it easier on the optimizer.
*
* @return (Potentially new) head of the ResultSetNode tree.
*
* @exception StandardException Thrown on error
*/
private ResultSetNode addNewNodes()
throws StandardException
{
/* Only call addNewNodes() once */
if (addNewNodesCalled)
{
return this;
}
addNewNodesCalled = true;
if( orderByList == null)
return this;
// Generate an order by node on top of the intersect/except
return (ResultSetNode) getNodeFactory().getNode( C_NodeTypes.ORDER_BY_NODE,
this,
orderByList,
tableProperties,
getContextManager());
} // end of addNewNodes
/**
* Generate the code.
*
* @exception StandardException Thrown on error
*/
public void generate( ActivationClassBuilder acb,
MethodBuilder mb)
throws StandardException
{
/* Get the next ResultSet #, so that we can number this ResultSetNode, its
* ResultColumnList and ResultSet.
*/
assignResultSetNumber();
// Get our final cost estimate based on the child estimates.
costEstimate = getFinalCostEstimate();
// build up the tree.
/* Generate the SetOpResultSet. Arguments:
* 1) expression for left child ResultSet
* 2) expression for right child ResultSet
* 3) activation
* 4) resultSetNumber
* 5) estimated row count
* 6) estimated cost
* 7) opType
* 8) all
* 9) close method
* 10) intermediateOrderByColumns saved object index
* 11) intermediateOrderByDirection saved object index
*/
acb.pushGetResultSetFactoryExpression(mb); // instance for getUnionResultSet
getLeftResultSet().generate( acb, mb);
getRightResultSet().generate( acb, mb);
acb.pushThisAsActivation(mb);
mb.push(resultSetNumber);
mb.push( costEstimate.getEstimatedRowCount());
mb.push( costEstimate.getEstimatedCost());
mb.push( getOpType());
mb.push( all);
closeMethodArgument(acb, mb);
mb.push( getCompilerContext().addSavedObject( intermediateOrderByColumns));
mb.push( getCompilerContext().addSavedObject( intermediateOrderByDirection));
mb.callMethod(VMOpcode.INVOKEINTERFACE,
(String) null,
"getSetOpResultSet",
ClassName.NoPutResultSet, 11);
} // end of generate
/**
* @see ResultSetNode#getFinalCostEstimate
*
* Get the final CostEstimate for this IntersectOrExceptNode.
*
* @return The final CostEstimate for this IntersectOrExceptNode,
* which is the sum of the two child costs. The final number of
* rows depends on whether this is an INTERSECT or EXCEPT (see
* getRowCountEstimate() in this class for more).
*/
public CostEstimate getFinalCostEstimate()
throws StandardException
{
if (finalCostEstimate != null)
return finalCostEstimate;
CostEstimate leftCE = leftResultSet.getFinalCostEstimate();
CostEstimate rightCE = rightResultSet.getFinalCostEstimate();
finalCostEstimate = getNewCostEstimate();
finalCostEstimate.setCost(
leftCE.getEstimatedCost() + rightCE.getEstimatedCost(),
getRowCountEstimate(leftCE.rowCount(), rightCE.rowCount()),
getSingleScanRowCountEstimate(leftCE.singleScanRowCount(),
rightCE.singleScanRowCount()));
return finalCostEstimate;
}
String getOperatorName()
{
switch( opType)
{
case INTERSECT_OP:
return "INTERSECT";
case EXCEPT_OP:
return "EXCEPT";
}
if( SanityManager.DEBUG)
SanityManager.THROWASSERT( "Invalid intersectOrExcept opType: " + opType);
return "?";
}
double getRowCountEstimate( double leftRowCount, double rightRowCount)
{
switch( opType)
{
case INTERSECT_OP:
// The result has at most min( leftRowCount, rightRowCount). Estimate the actual row count at
// half that.
return Math.min( leftRowCount, rightRowCount)/2;
case EXCEPT_OP:
// The result has at most leftRowCount rows and at least
// max(0, leftRowCount - rightRowCount) rows. Use the mean
// of those two as the estimate.
return (leftRowCount + Math.max(0, leftRowCount - rightRowCount))/2;
}
if( SanityManager.DEBUG)
SanityManager.THROWASSERT( "Invalid intersectOrExcept opType: " + opType);
return 1.0;
} // end of getRowCountEstimate
double getSingleScanRowCountEstimate( double leftSingleScanRowCount, double rightSingleScanRowCount)
{
return getRowCountEstimate( leftSingleScanRowCount, rightSingleScanRowCount);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -