&& sourceCost < RuleChooseDependent.DEFAULT_INDEPENDENT_CARDINALITY && !plannedResult.mergeJoin) {
//TODO: see if a dependent join applies the other direction
return current;
}
RelationalPlan originalPlan = (RelationalPlan)plannedResult.query.getProcessorPlan();
Number originalCardinality = originalPlan.getRootNode().getEstimateNodeCardinality();
if (!plannedResult.mergeJoin && originalCardinality.floatValue() == NewCalculateCostUtil.UNKNOWN_VALUE) {
//TODO: this check isn't really accurate - exists and scalarsubqueries will always have cardinality 2/1
//if it's currently unknown, removing criteria won't make it any better
return current;
}
Collection<GroupSymbol> leftGroups = FrameUtil.findJoinSourceNode(current).getGroups();
if (!planQuery(leftGroups, false, plannedResult)) {
if (plannedResult.mergeJoin && analysisRecord != null && analysisRecord.recordAnnotations()) {
this.analysisRecord.addAnnotation(new Annotation(Annotation.HINTS, "could not plan as a merge join: " + crit, "ignoring hint", Priority.MEDIUM)); //$NON-NLS-1$ //$NON-NLS-2$
}
return current;
}
//add an order by, which hopefully will get pushed down
plannedResult.query.setOrderBy(new OrderBy(plannedResult.rightExpressions).clone());
for (OrderByItem item : plannedResult.query.getOrderBy().getOrderByItems()) {
int index = plannedResult.query.getProjectedSymbols().indexOf(item.getSymbol());
item.setExpressionPosition(index);
}
try {
//clone the symbols as they may change during planning
List<SingleElementSymbol> projectedSymbols = LanguageObject.Util.deepClone(plannedResult.query.getProjectedSymbols(), SingleElementSymbol.class);
//NOTE: we could tap into the relationalplanner at a lower level to get this in a plan node form,
//the major benefit would be to reuse the dependent join planning logic if possible.
if (analysisRecord != null && analysisRecord.recordDebug()) {
analysisRecord.println("Attempting to plan " + crit + " as a merge join"); //$NON-NLS-1$ //$NON-NLS-2$
}
RelationalPlan subPlan = (RelationalPlan)QueryOptimizer.optimizePlan(plannedResult.query, metadata, idGenerator, capFinder, analysisRecord, context);
Number planCardinality = subPlan.getRootNode().getEstimateNodeCardinality();
if (!plannedResult.mergeJoin) {
//if we don't have a specific hint, then use costing
if (planCardinality.floatValue() == NewCalculateCostUtil.UNKNOWN_VALUE
|| planCardinality.floatValue() > 10000000