Commit 4512441d authored by terrymanu's avatar terrymanu
Browse files

support row number for sqlserver

parent 370f8922
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Literals;
import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Symbol;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.condition.Column;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.condition.Condition;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.OffsetLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.RowCountLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.table.Table;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.table.Tables;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingUnsupportedException;
@@ -278,8 +281,8 @@ public class SQLParser extends AbstractParser {
            return;
        }
        if (equalAny(Symbol.LT, Symbol.GT, Symbol.LT_EQ, Symbol.GT_EQ)) {
            if (left instanceof SQLIdentifierExpression && sqlStatement instanceof SelectStatement && isSpecialCondition((SelectStatement) sqlStatement, (SQLIdentifierExpression) left)) {
                parseSpecialCondition((SelectStatement) sqlStatement);
            if (left instanceof SQLIdentifierExpression && sqlStatement instanceof SelectStatement && isRowNumberCondition((SelectStatement) sqlStatement, (SQLIdentifierExpression) left)) {
                parseRowNumberCondition((SelectStatement) sqlStatement);
            } else {
                parseOtherCondition(sqlStatement);
            }
@@ -329,11 +332,30 @@ public class SQLParser extends AbstractParser {
        }
    }
    
    protected boolean isSpecialCondition(final SelectStatement selectStatement, final SQLIdentifierExpression left) {
    protected boolean isRowNumberCondition(final SelectStatement selectStatement, final SQLIdentifierExpression left) {
        return false;
    }
    
    protected void parseSpecialCondition(final SelectStatement selectStatement) {
    private void parseRowNumberCondition(final SelectStatement selectStatement) {
        Symbol symbol = (Symbol) getLexer().getCurrentToken().getType();
        getLexer().nextToken();
        SQLExpression sqlExpression = parseExpression(selectStatement);
        if (null == selectStatement.getLimit()) {
            selectStatement.setLimit(new Limit(false));
        }
        if (Symbol.LT == symbol || Symbol.LT_EQ == symbol) {
            if (sqlExpression instanceof SQLNumberExpression) {
                selectStatement.getLimit().setRowCountLimit(new RowCountLimit(((SQLNumberExpression) sqlExpression).getNumber().intValue(), -1));
            } else if (sqlExpression instanceof SQLPlaceholderExpression) {
                selectStatement.getLimit().setRowCountLimit(new RowCountLimit(-1, ((SQLPlaceholderExpression) sqlExpression).getIndex()));
            }
        } else if (Symbol.GT == symbol || Symbol.GT_EQ == symbol) {
            if (sqlExpression instanceof SQLNumberExpression) {
                selectStatement.getLimit().setOffsetLimit(new OffsetLimit(((SQLNumberExpression) sqlExpression).getNumber().intValue(), -1));
            } else if (sqlExpression instanceof SQLPlaceholderExpression) {
                selectStatement.getLimit().setOffsetLimit(new OffsetLimit(-1, ((SQLPlaceholderExpression) sqlExpression).getIndex()));
            }
        }
    }
    
    private void parseOtherCondition(final SQLStatement sqlStatement) {
+4 −34
Original line number Diff line number Diff line
@@ -20,16 +20,9 @@ package com.dangdang.ddframe.rdb.sharding.parsing.parser.dialect.oracle;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.parsing.lexer.dialect.oracle.OracleKeyword;
import com.dangdang.ddframe.rdb.sharding.parsing.lexer.dialect.oracle.OracleLexer;
import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Symbol;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.SQLParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.OffsetLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.RowCountLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.selectitem.SelectItem;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.expression.SQLExpression;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.expression.SQLIdentifierExpression;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.expression.SQLNumberExpression;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.expression.SQLPlaceholderExpression;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.SelectStatement;
import com.google.common.base.Optional;

@@ -54,36 +47,13 @@ public final class OracleParser extends SQLParser {
    }
    
    @Override
    protected boolean isSpecialCondition(final SelectStatement selectStatement, final SQLIdentifierExpression expression) {
        Optional<String> rownumAlias = Optional.absent();
    protected boolean isRowNumberCondition(final SelectStatement selectStatement, final SQLIdentifierExpression expression) {
        Optional<String> rowNumberAlias = Optional.absent();
        for (SelectItem each : selectStatement.getItems()) {
            if (each.getAlias().isPresent() && "rownum".equalsIgnoreCase(each.getExpression())) {
                rownumAlias = each.getAlias();
            }
        }
        return "rownum".equalsIgnoreCase(expression.getName()) || expression.getName().equalsIgnoreCase(rownumAlias.orNull());
    }
    
    @Override
    protected void parseSpecialCondition(final SelectStatement selectStatement) {
        Symbol symbol = (Symbol) getLexer().getCurrentToken().getType();
        getLexer().nextToken();
        SQLExpression sqlExpression = parseExpression(selectStatement);
        if (null == selectStatement.getLimit()) {
            selectStatement.setLimit(new Limit(false));
        }
        if (Symbol.LT == symbol || Symbol.LT_EQ == symbol) {
            if (sqlExpression instanceof SQLNumberExpression) {
                selectStatement.getLimit().setRowCountLimit(new RowCountLimit(((SQLNumberExpression) sqlExpression).getNumber().intValue(), -1));
            } else if (sqlExpression instanceof SQLPlaceholderExpression) {
                selectStatement.getLimit().setRowCountLimit(new RowCountLimit(-1, ((SQLPlaceholderExpression) sqlExpression).getIndex()));
            }
        } else if (Symbol.GT == symbol || Symbol.GT_EQ == symbol) {
            if (sqlExpression instanceof SQLNumberExpression) {
                selectStatement.getLimit().setOffsetLimit(new OffsetLimit(((SQLNumberExpression) sqlExpression).getNumber().intValue(), -1));
            } else if (sqlExpression instanceof SQLPlaceholderExpression) {
                selectStatement.getLimit().setOffsetLimit(new OffsetLimit(-1, ((SQLPlaceholderExpression) sqlExpression).getIndex()));
                rowNumberAlias = each.getAlias();
            }
        }
        return "rownum".equalsIgnoreCase(expression.getName()) || expression.getName().equalsIgnoreCase(rowNumberAlias.orNull());
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -27,9 +27,12 @@ import com.dangdang.ddframe.rdb.sharding.parsing.parser.SQLParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.OffsetLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.RowCountLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.selectitem.SelectItem;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingUnsupportedException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.expression.SQLIdentifierExpression;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.SelectStatement;
import com.google.common.base.Optional;

/**
 * SQLServer解析器.
@@ -43,6 +46,17 @@ public final class SQLServerParser extends SQLParser {
        getLexer().nextToken();
    }
    
    @Override
    protected boolean isRowNumberCondition(final SelectStatement selectStatement, final SQLIdentifierExpression expression) {
        Optional<String> rowNumberAlias = Optional.absent();
        for (SelectItem each : selectStatement.getItems()) {
            if (each.getAlias().isPresent() && "ROW_NUMBER".equalsIgnoreCase(each.getExpression())) {
                rowNumberAlias = each.getAlias();
            }
        }
        return expression.getName().equalsIgnoreCase(rowNumberAlias.orNull());
    }
    
    public void skipTop() {
        if (skipIfEqual(SQLServerKeyword.TOP)) {
            parseExpression();
+22 −2
Original line number Diff line number Diff line
@@ -20,9 +20,12 @@ package com.dangdang.ddframe.rdb.sharding.parsing.parser.dialect.sqlserver;
import com.dangdang.ddframe.rdb.sharding.parsing.lexer.dialect.sqlserver.SQLServerKeyword;
import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.DefaultKeyword;
import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Symbol;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.AbstractSelectParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingUnsupportedException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.SQLParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.selectitem.CommonSelectItem;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.selectitem.SelectItem;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingUnsupportedException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.AbstractSelectParser;
import com.google.common.base.Optional;

public class SQLServerSelectParser extends AbstractSelectParser {
    
@@ -58,6 +61,23 @@ public class SQLServerSelectParser extends AbstractSelectParser {
        queryRest();
    }
    
    @Override
    protected boolean isRowNumberSelectItem() {
        return getSqlParser().getLexer().getCurrentToken().getLiterals().equalsIgnoreCase("ROW_NUMBER");
    }
    
    @Override
    protected SelectItem parseRowNumberSelectItem() {
        if (getSqlParser().equalAny(Symbol.LEFT_PAREN)) {
            getSqlParser().skipUntil(DefaultKeyword.AS);
            getSqlParser().getLexer().nextToken();
            SelectItem result = new CommonSelectItem("ROW_NUMBER", Optional.of(getSqlParser().getLexer().getCurrentToken().getLiterals()), false);
            getSqlParser().getLexer().nextToken();
            return result;
        }
        return new CommonSelectItem("ROW_NUMBER", getSqlParser().parseAlias(), false);
    }
    
    @Override
    protected void parseJoinTable() {
        if (getSqlParser().skipIfEqual(DefaultKeyword.WITH)) {
+11 −0
Original line number Diff line number Diff line
@@ -122,6 +122,9 @@ public abstract class AbstractSelectParser implements SQLStatementParser {
    }
    
    private SelectItem parseSelectItem() {
        if (isRowNumberSelectItem()) {
            return parseRowNumberSelectItem();
        }
        sqlParser.skipIfEqual(DefaultKeyword.CONNECT_BY_ROOT);
        String literals = sqlParser.getLexer().getCurrentToken().getLiterals();
        if (sqlParser.equalAny(Symbol.STAR) || Symbol.STAR.getLiterals().equals(SQLUtil.getExactlyValue(literals))) {
@@ -146,6 +149,14 @@ public abstract class AbstractSelectParser implements SQLStatementParser {
        return new CommonSelectItem(SQLUtil.getExactlyValue(expression.toString()), sqlParser.parseAlias(), false);
    }
    
    protected boolean isRowNumberSelectItem() {
        return false;
    }
    
    protected SelectItem parseRowNumberSelectItem() {
        throw new UnsupportedOperationException("Cannot support special select item.");
    }
    
    protected void queryRest() {
        if (sqlParser.equalAny(DefaultKeyword.UNION, DefaultKeyword.EXCEPT, DefaultKeyword.INTERSECT, DefaultKeyword.MINUS)) {
            throw new SQLParsingUnsupportedException(sqlParser.getLexer().getCurrentToken().getType());