Commit 2db83d8a authored by terrymanu's avatar terrymanu
Browse files

refactor derived column to rewrite module

parent b4286edf
Loading
Loading
Loading
Loading
+0 −51
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import com.dangdang.ddframe.rdb.sharding.parsing.parser.expr.SQLIdentifierExpr;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.expr.SQLNumberExpr;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.expr.SQLPropertyExpr;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.SQLStatementParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.ItemsToken;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.TableToken;
import com.dangdang.ddframe.rdb.sharding.util.SQLUtil;
import com.google.common.base.Optional;
@@ -62,8 +61,6 @@ public abstract class AbstractSelectParser implements SQLStatementParser {
    
    private int derivedColumnOffset;
    
    private ItemsToken itemsToken;
    
    public AbstractSelectParser(final SQLParser sqlParser) {
        this.sqlParser = sqlParser;
        sqlContext = new SelectSQLContext();
@@ -74,9 +71,6 @@ public abstract class AbstractSelectParser implements SQLStatementParser {
        query();
        sqlContext.getOrderByContexts().addAll(parseOrderBy());
        customizedSelect();
        if (!itemsToken.getItems().isEmpty()) {
            sqlContext.getSqlTokens().add(itemsToken);
        }
        return sqlContext;
    }
    
@@ -121,23 +115,6 @@ public abstract class AbstractSelectParser implements SQLStatementParser {
            index++;
        } while (sqlParser.skipIfEqual(Symbol.COMMA));
        sqlContext.setSelectListLastPosition(sqlParser.getLexer().getCurrentToken().getEndPosition() - sqlParser.getLexer().getCurrentToken().getLiterals().length());
        itemsToken = new ItemsToken(sqlContext.getSelectListLastPosition());
        for (SelectItemContext each : sqlContext.getItemContexts()) {
            if (each instanceof AggregationSelectItemContext) {
                AggregationSelectItemContext aggregationSelectItemContext = (AggregationSelectItemContext) each;
                if (AggregationType.AVG.equals(aggregationSelectItemContext.getAggregationType())) {
                    AggregationSelectItemContext countSelectItemContext = new AggregationSelectItemContext(
                            aggregationSelectItemContext.getInnerExpression(), Optional.of(generateDerivedColumnAlias()), -1, AggregationType.COUNT);
                    AggregationSelectItemContext sumSelectItemContext = new AggregationSelectItemContext(
                            aggregationSelectItemContext.getInnerExpression(), Optional.of(generateDerivedColumnAlias()), -1, AggregationType.SUM);
                    aggregationSelectItemContext.getDerivedAggregationSelectItemContexts().add(countSelectItemContext);
                    aggregationSelectItemContext.getDerivedAggregationSelectItemContexts().add(sumSelectItemContext);
                    // TODO 将AVG列替换成常数,避免数据库再计算无用的AVG函数
                    itemsToken.getItems().add(countSelectItemContext.getExpression() + " AS " + countSelectItemContext.getAlias().get() + " ");
                    itemsToken.getItems().add(sumSelectItemContext.getExpression() + " AS " + sumSelectItemContext.getAlias().get() + " ");
                }
            }
        }
    }
    
    private SelectItemContext parseSelectItem(final int index) {
@@ -221,20 +198,6 @@ public abstract class AbstractSelectParser implements SQLStatementParser {
        } else {
            return Optional.absent();
        }
        if (!result.getIndex().isPresent()) {
            boolean found = false;
            String orderByExpression = result.getOwner().isPresent() ? result.getOwner().get() + "." + result.getName().get() : result.getName().get();
            for (SelectItemContext context : sqlContext.getItemContexts()) {
                if (context.getExpression().equalsIgnoreCase(orderByExpression) || orderByExpression.equalsIgnoreCase(context.getAlias().orNull())) {
                    found = true;
                    break;
                }
            }
            // TODO 需重构,目前的做法是通过补列有别名则补列,如果不包含select item则生成别名,进而补列,这里逻辑不直观
            if (!found && result.getAlias().isPresent()) {
                itemsToken.getItems().add(orderByExpression + " AS " + result.getAlias().get() + " ");
            }
        }
        return Optional.of(result);
    }
    
@@ -278,20 +241,6 @@ public abstract class AbstractSelectParser implements SQLStatementParser {
            return;
        }
        sqlContext.getGroupByContexts().add(groupByContext);
    
        boolean found = false;
        String groupByExpression = groupByContext.getOwner().isPresent() ? groupByContext.getOwner().get() + "." + groupByContext.getName() : groupByContext.getName();
        for (SelectItemContext context : sqlContext.getItemContexts()) {
            if ((!context.getAlias().isPresent() && context.getExpression().equalsIgnoreCase(groupByExpression))
                    || (context.getAlias().isPresent() && context.getAlias().get().equalsIgnoreCase(groupByExpression))) {
                found = true;
                break;
            }
        }
        // TODO 需重构,目前的做法是通过补列有别名则补列,如果不包含select item则生成别名,进而补列,这里逻辑不直观
        if (!found && groupByContext.getAlias().isPresent()) {
            itemsToken.getItems().add(groupByExpression + " AS " + groupByContext.getAlias().get() + " ");
        }
    }
    
    private Optional<String> getAlias(final String name) {
+112 −0
Original line number Diff line number Diff line
/*
 * Copyright 1999-2015 dangdang.com.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * </p>
 */

package com.dangdang.ddframe.rdb.sharding.rewrite;

import com.dangdang.ddframe.rdb.sharding.constant.AggregationType;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.AggregationSelectItemContext;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.GroupByContext;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.OrderByContext;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.SelectItemContext;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.SelectSQLContext;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.ItemsToken;
import com.google.common.base.Optional;

/**
 * 补列工具类.
 *
 * @author zhangliang
 */
public final class DerivedUtils {
    
    private static final String DERIVED_COUNT_ALIAS = "AVG_DERIVED_COUNT_%s";
    
    private static final String DERIVED_SUM_ALIAS = "AVG_DERIVED_SUM_%s";
    
    /**
     * 追加派生列.
     *
     * @param selectSQLContext 解析结果
     */
    public static void appendDerivedColumns(final SelectSQLContext selectSQLContext) {
        ItemsToken itemsToken = new ItemsToken(selectSQLContext.getSelectListLastPosition());
        appendAvgDerivedColumns(selectSQLContext, itemsToken);
        appendOrderByDerivedColumns(selectSQLContext, itemsToken);
        appendGroupByDerivedColumns(selectSQLContext, itemsToken);
        if (!itemsToken.getItems().isEmpty()) {
            selectSQLContext.getSqlTokens().add(itemsToken);
        }
    }
    
    private static void appendAvgDerivedColumns(final SelectSQLContext selectSQLContext, final ItemsToken itemsToken) {
        int derivedColumnOffset = 0;
        for (SelectItemContext each : selectSQLContext.getItemContexts()) {
            if (each instanceof AggregationSelectItemContext) {
                AggregationSelectItemContext aggregationSelectItemContext = (AggregationSelectItemContext) each;
                if (AggregationType.AVG.equals(aggregationSelectItemContext.getAggregationType())) {
                    AggregationSelectItemContext countSelectItemContext = new AggregationSelectItemContext(
                            aggregationSelectItemContext.getInnerExpression(), Optional.of(String.format(DERIVED_COUNT_ALIAS, derivedColumnOffset)), -1, AggregationType.COUNT);
                    AggregationSelectItemContext sumSelectItemContext = new AggregationSelectItemContext(
                            aggregationSelectItemContext.getInnerExpression(), Optional.of(String.format(DERIVED_SUM_ALIAS, derivedColumnOffset)), -1, AggregationType.SUM);
                    aggregationSelectItemContext.getDerivedAggregationSelectItemContexts().add(countSelectItemContext);
                    aggregationSelectItemContext.getDerivedAggregationSelectItemContexts().add(sumSelectItemContext);
                    // TODO 将AVG列替换成常数,避免数据库再计算无用的AVG函数
                    itemsToken.getItems().add(countSelectItemContext.getExpression() + " AS " + countSelectItemContext.getAlias().get() + " ");
                    itemsToken.getItems().add(sumSelectItemContext.getExpression() + " AS " + sumSelectItemContext.getAlias().get() + " ");
                    derivedColumnOffset++;
                }
            }
        }
    }
    
    private static void appendOrderByDerivedColumns(final SelectSQLContext selectSQLContext, final ItemsToken itemsToken) {
        for (OrderByContext each : selectSQLContext.getOrderByContexts()) {
            if (!each.getIndex().isPresent()) {
                boolean found = false;
                String orderByExpression = each.getOwner().isPresent() ? each.getOwner().get() + "." + each.getName().get() : each.getName().get();
                for (SelectItemContext context : selectSQLContext.getItemContexts()) {
                    if (context.getExpression().equalsIgnoreCase(orderByExpression) || orderByExpression.equalsIgnoreCase(context.getAlias().orNull())) {
                        found = true;
                        break;
                    }
                }
                // TODO 需重构,目前的做法是通过补列有别名则补列,如果不包含select item则生成别名,进而补列,这里逻辑不直观
                if (!found && each.getAlias().isPresent()) {
                    itemsToken.getItems().add(orderByExpression + " AS " + each.getAlias().get() + " ");
                }
            }
        }
    }
    
    private static void appendGroupByDerivedColumns(final SelectSQLContext selectSQLContext, final ItemsToken itemsToken) {
        for (GroupByContext each : selectSQLContext.getGroupByContexts()) {
            boolean found = false;
            String groupByExpression = each.getOwner().isPresent() ? each.getOwner().get() + "." + each.getName() : each.getName();
            for (SelectItemContext context : selectSQLContext.getItemContexts()) {
                if ((!context.getAlias().isPresent() && context.getExpression().equalsIgnoreCase(groupByExpression))
                        || (context.getAlias().isPresent() && context.getAlias().get().equalsIgnoreCase(groupByExpression))) {
                    found = true;
                    break;
                }
            }
            // TODO 需重构,目前的做法是通过补列有别名则补列,如果不包含select item则生成别名,进而补列,这里逻辑不直观
            if (!found && each.getAlias().isPresent()) {
                itemsToken.getItems().add(groupByExpression + " AS " + each.getAlias().get() + " ");
            }
        }
    }
}
+19 −2
Original line number Diff line number Diff line
/*
 * Copyright 1999-2015 dangdang.com.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * </p>
 */

package com.dangdang.ddframe.rdb.sharding.rewrite;

import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
@@ -12,11 +29,11 @@ import java.util.Collection;
import java.util.List;

/**
 * .
 * 自增主键工具类.
 *
 * @author zhangliang
 */
public class GenerateKeysUtils {
public final class GenerateKeysUtils {
    
    /**
     * 追加自增主键.
+4 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.UpdateSQLContext
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.OffsetLimitToken;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.RowCountLimitToken;
import com.dangdang.ddframe.rdb.sharding.rewrite.DerivedUtils;
import com.dangdang.ddframe.rdb.sharding.rewrite.GenerateKeysUtils;
import com.dangdang.ddframe.rdb.sharding.rewrite.SQLBuilder;
import com.dangdang.ddframe.rdb.sharding.rewrite.SQLRewriteEngine;
@@ -98,6 +99,9 @@ public final class SQLRouteEngine {
        if (result instanceof InsertSQLContext) {
            GenerateKeysUtils.appendGenerateKeys(shardingRule, parameters, (InsertSQLContext) result);
        }
        if (result instanceof SelectSQLContext) {
            DerivedUtils.appendDerivedColumns((SelectSQLContext) result);
        }
        return result;
    }
    
+1 −1
Original line number Diff line number Diff line
<dataset>
    <t_order user_id_avg="19.5" SHARDING_GEN_1="40" SHARDING_GEN_2="780" />
    <t_order user_id_avg="19.5" AVG_DERIVED_COUNT_0="40" AVG_DERIVED_SUM_0="780" />
</dataset>
Loading