package com.taobao.tddl.optimizer.costbased.after; import java.math.BigDecimal; import java.util.Map; import com.taobao.tddl.common.jdbc.ParameterContext; import com.taobao.tddl.optimizer.core.plan.IDataNodeExecutor; import com.taobao.tddl.optimizer.core.plan.IQueryTree; import com.taobao.tddl.optimizer.core.plan.query.IJoin; import com.taobao.tddl.optimizer.core.plan.query.IMerge; import com.taobao.tddl.optimizer.core.plan.query.IQuery; /** * 遍历所有的节点,如果有merge的情况下,记录下merge的limit from to。 会修改所有merge节点下面的limit from to * * @author Whisper */ public class LimitOptimizer implements QueryPlanOptimizer { public LimitOptimizer(){ } /** * 如果设置了MergeConcurrent 并且值为True,则将所有的Merge变为并行 */ @Override public IDataNodeExecutor optimize(IDataNodeExecutor dne, Map<Integer, ParameterContext> parameterSettings, Map<String, Object> extraCmd) { if (dne instanceof IQueryTree) { this.findMergeAndOptimizerLimit(dne); } return dne; } void findMergeAndOptimizerLimit(IDataNodeExecutor dne) { if (dne instanceof IQueryTree) { IQueryTree q = (IQueryTree) dne; if (q.getLimitFrom() instanceof Integer) { q.setLimitFrom(new Long((Integer) q.getLimitFrom())); } if (q.getLimitFrom() instanceof BigDecimal) { q.setLimitFrom(new Long(((BigDecimal) q.getLimitFrom()).longValue())); } if (q.getLimitTo() instanceof Integer) { q.setLimitTo(new Long((Integer) q.getLimitTo())); } if (q.getLimitTo() instanceof BigDecimal) { q.setLimitTo(new Long(((BigDecimal) q.getLimitTo()).longValue())); } } if (dne instanceof IMerge) { Comparable from = ((IMerge) dne).getLimitFrom(); Comparable to = ((IMerge) dne).getLimitTo(); if (from instanceof Long && to instanceof Long) { if ((from != null && (Long) from != -1) || (to != null && (Long) to != -1)) { for (IDataNodeExecutor child : ((IMerge) dne).getSubNode()) { if (child instanceof IQueryTree) { ((IQueryTree) child).setLimitFrom(0L); ((IQueryTree) child).setLimitTo((Long) from + (Long) to); } } } } for (IDataNodeExecutor child : ((IMerge) dne).getSubNode()) this.findMergeAndOptimizerLimit(child); } if (dne instanceof IJoin) { this.findMergeAndOptimizerLimit(((IJoin) dne).getLeftNode()); this.findMergeAndOptimizerLimit(((IJoin) dne).getRightNode()); } if (dne instanceof IQuery && ((IQuery) dne).getSubQuery() != null) { this.findMergeAndOptimizerLimit(((IQuery) dne).getSubQuery()); } } }