From c4026f3c481b4565c9d0ad5e967b4e3577ea6dba Mon Sep 17 00:00:00 2001 From: terrymanu Date: Wed, 26 Jul 2017 17:14:41 +0800 Subject: [PATCH] refactor parsing --- .../sharding/parsing/parser/SQLParser.java | 2 - .../parser/dialect/mysql/MySQLParser.java | 107 ------------------ .../dialect/mysql/MySQLSelectParser.java | 99 +++++++++++++++- .../sqlserver/SQLServerDeleteParser.java | 8 +- .../dialect/sqlserver/SQLServerParser.java | 91 --------------- .../sqlserver/SQLServerSelectParser.java | 101 ++++++++++++++--- .../insert/AbstractInsertParser.java | 3 +- .../update/AbstractUpdateParser.java | 1 + 8 files changed, 195 insertions(+), 217 deletions(-) diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/SQLParser.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/SQLParser.java index 0600f62d92..9f6029828f 100755 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/SQLParser.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/SQLParser.java @@ -44,7 +44,6 @@ import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.TableToken; import com.dangdang.ddframe.rdb.sharding.util.SQLUtil; import com.google.common.base.Optional; import lombok.Getter; -import lombok.Setter; import java.util.LinkedList; import java.util.List; @@ -55,7 +54,6 @@ import java.util.List; * @author zhangliang */ @Getter -@Setter public class SQLParser extends AbstractParser { private final ShardingRule shardingRule; diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/mysql/MySQLParser.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/mysql/MySQLParser.java index 305dc2df24..648d301acd 100755 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/mysql/MySQLParser.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/mysql/MySQLParser.java @@ -18,18 +18,8 @@ package com.dangdang.ddframe.rdb.sharding.parsing.parser.dialect.mysql; import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule; -import com.dangdang.ddframe.rdb.sharding.parsing.lexer.dialect.mysql.MySQLKeyword; import com.dangdang.ddframe.rdb.sharding.parsing.lexer.dialect.mysql.MySQLLexer; -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.SQLParser; -import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit; -import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.LimitValue; -import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingException; -import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.SQLStatement; -import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.SelectStatement; -import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.OffsetToken; -import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.RowCountToken; /** * MySQL解析器. @@ -42,101 +32,4 @@ public final class MySQLParser extends SQLParser { super(new MySQLLexer(sql), shardingRule); getLexer().nextToken(); } - - /** - * 解析分页. - * - * @param selectStatement SQL语句对象 - * @param parametersIndex 参数索引 - */ - public void parseLimit(final SelectStatement selectStatement, final int parametersIndex) { - skipIfEqual(MySQLKeyword.LIMIT); - int valueIndex = -1; - int valueBeginPosition = getLexer().getCurrentToken().getEndPosition(); - int value; - boolean isParameterForValue = false; - if (equalAny(Literals.INT)) { - value = Integer.parseInt(getLexer().getCurrentToken().getLiterals()); - valueBeginPosition = valueBeginPosition - (value + "").length(); - } else if (equalAny(Symbol.QUESTION)) { - valueIndex = parametersIndex; - value = -1; - valueBeginPosition--; - isParameterForValue = true; - } else { - throw new SQLParsingException(getLexer()); - } - getLexer().nextToken(); - if (skipIfEqual(Symbol.COMMA)) { - selectStatement.setLimit(getLimitWithComma(selectStatement, parametersIndex, valueIndex, valueBeginPosition, value, isParameterForValue)); - return; - } - if (skipIfEqual(MySQLKeyword.OFFSET)) { - selectStatement.setLimit(getLimitWithOffset(selectStatement, parametersIndex, valueIndex, valueBeginPosition, value, isParameterForValue)); - return; - } - if (!isParameterForValue) { - selectStatement.getSqlTokens().add(new RowCountToken(valueBeginPosition, value)); - } - Limit limit = new Limit(true); - limit.setRowCount(new LimitValue(value, valueIndex)); - selectStatement.setLimit(limit); - } - - private Limit getLimitWithComma(final SQLStatement sqlStatement, final int parametersIndex, final int index, final int valueBeginPosition, final int value, final boolean isParameterForValue) { - int rowCountBeginPosition = getLexer().getCurrentToken().getEndPosition(); - int rowCountValue; - int rowCountIndex = -1; - boolean isParameterForRowCount = false; - if (equalAny(Literals.INT)) { - rowCountValue = Integer.parseInt(getLexer().getCurrentToken().getLiterals()); - rowCountBeginPosition = rowCountBeginPosition - (rowCountValue + "").length(); - } else if (equalAny(Symbol.QUESTION)) { - rowCountIndex = -1 == index ? parametersIndex : index + 1; - rowCountValue = -1; - rowCountBeginPosition--; - isParameterForRowCount = true; - } else { - throw new SQLParsingException(getLexer()); - } - getLexer().nextToken(); - if (!isParameterForValue) { - sqlStatement.getSqlTokens().add(new OffsetToken(valueBeginPosition, value)); - } - if (!isParameterForRowCount) { - sqlStatement.getSqlTokens().add(new RowCountToken(rowCountBeginPosition, rowCountValue)); - } - Limit result = new Limit(true); - result.setRowCount(new LimitValue(rowCountValue, rowCountIndex)); - result.setOffset(new LimitValue(value, index)); - return result; - } - - private Limit getLimitWithOffset(final SQLStatement sqlStatement, final int parametersIndex, final int index, final int valueBeginPosition, final int value, final boolean isParameterForValue) { - int offsetBeginPosition = getLexer().getCurrentToken().getEndPosition(); - int offsetValue = -1; - int offsetIndex = -1; - boolean isParameterForOffset = false; - if (equalAny(Literals.INT)) { - offsetValue = Integer.parseInt(getLexer().getCurrentToken().getLiterals()); - offsetBeginPosition = offsetBeginPosition - (offsetValue + "").length(); - } else if (equalAny(Symbol.QUESTION)) { - offsetIndex = -1 == index ? parametersIndex : index + 1; - offsetBeginPosition--; - isParameterForOffset = true; - } else { - throw new SQLParsingException(getLexer()); - } - getLexer().nextToken(); - if (!isParameterForOffset) { - sqlStatement.getSqlTokens().add(new OffsetToken(offsetBeginPosition, offsetValue)); - } - if (!isParameterForValue) { - sqlStatement.getSqlTokens().add(new RowCountToken(valueBeginPosition, value)); - } - Limit result = new Limit(true); - result.setRowCount(new LimitValue(value, index)); - result.setOffset(new LimitValue(offsetValue, offsetIndex)); - return result; - } } diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/mysql/MySQLSelectParser.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/mysql/MySQLSelectParser.java index 05f0348a7d..13caa0298f 100755 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/mysql/MySQLSelectParser.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/mysql/MySQLSelectParser.java @@ -21,9 +21,17 @@ import com.dangdang.ddframe.rdb.sharding.parsing.lexer.dialect.mysql.MySQLKeywor import com.dangdang.ddframe.rdb.sharding.parsing.lexer.dialect.oracle.OracleKeyword; import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Assist; import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.DefaultKeyword; +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.SQLParser; +import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit; +import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.LimitValue; +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.statement.SQLStatement; import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.AbstractSelectParser; +import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.OffsetToken; +import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.RowCountToken; public class MySQLSelectParser extends AbstractSelectParser { @@ -53,9 +61,96 @@ public class MySQLSelectParser extends AbstractSelectParser { } private void parseLimit() { - if (getSqlParser().equalAny(MySQLKeyword.LIMIT)) { - ((MySQLParser) getSqlParser()).parseLimit(getSelectStatement(), getParametersIndex()); + if (!getSqlParser().skipIfEqual(MySQLKeyword.LIMIT)) { + return; + } + int valueIndex = -1; + int valueBeginPosition = getSqlParser().getLexer().getCurrentToken().getEndPosition(); + int value; + boolean isParameterForValue = false; + if (getSqlParser().equalAny(Literals.INT)) { + value = Integer.parseInt(getSqlParser().getLexer().getCurrentToken().getLiterals()); + valueBeginPosition = valueBeginPosition - (value + "").length(); + } else if (getSqlParser().equalAny(Symbol.QUESTION)) { + valueIndex = getParametersIndex(); + value = -1; + valueBeginPosition--; + isParameterForValue = true; + } else { + throw new SQLParsingException(getSqlParser().getLexer()); + } + getSqlParser().getLexer().nextToken(); + if (getSqlParser().skipIfEqual(Symbol.COMMA)) { + getSelectStatement().setLimit(getLimitWithComma(getSelectStatement(), getParametersIndex(), valueIndex, valueBeginPosition, value, isParameterForValue)); + return; + } + if (getSqlParser().skipIfEqual(MySQLKeyword.OFFSET)) { + getSelectStatement().setLimit(getLimitWithOffset(getSelectStatement(), getParametersIndex(), valueIndex, valueBeginPosition, value, isParameterForValue)); + return; + } + if (!isParameterForValue) { + getSelectStatement().getSqlTokens().add(new RowCountToken(valueBeginPosition, value)); + } + Limit limit = new Limit(true); + limit.setRowCount(new LimitValue(value, valueIndex)); + getSelectStatement().setLimit(limit); + } + + private Limit getLimitWithComma(final SQLStatement sqlStatement, final int parametersIndex, final int index, final int valueBeginPosition, final int value, final boolean isParameterForValue) { + int rowCountBeginPosition = getSqlParser().getLexer().getCurrentToken().getEndPosition(); + int rowCountValue; + int rowCountIndex = -1; + boolean isParameterForRowCount = false; + if (getSqlParser().equalAny(Literals.INT)) { + rowCountValue = Integer.parseInt(getSqlParser().getLexer().getCurrentToken().getLiterals()); + rowCountBeginPosition = rowCountBeginPosition - (rowCountValue + "").length(); + } else if (getSqlParser().equalAny(Symbol.QUESTION)) { + rowCountIndex = -1 == index ? parametersIndex : index + 1; + rowCountValue = -1; + rowCountBeginPosition--; + isParameterForRowCount = true; + } else { + throw new SQLParsingException(getSqlParser().getLexer()); + } + getSqlParser().getLexer().nextToken(); + if (!isParameterForValue) { + sqlStatement.getSqlTokens().add(new OffsetToken(valueBeginPosition, value)); + } + if (!isParameterForRowCount) { + sqlStatement.getSqlTokens().add(new RowCountToken(rowCountBeginPosition, rowCountValue)); + } + Limit result = new Limit(true); + result.setRowCount(new LimitValue(rowCountValue, rowCountIndex)); + result.setOffset(new LimitValue(value, index)); + return result; + } + + private Limit getLimitWithOffset(final SQLStatement sqlStatement, final int parametersIndex, final int index, final int valueBeginPosition, final int value, final boolean isParameterForValue) { + int offsetBeginPosition = getSqlParser().getLexer().getCurrentToken().getEndPosition(); + int offsetValue = -1; + int offsetIndex = -1; + boolean isParameterForOffset = false; + if (getSqlParser().equalAny(Literals.INT)) { + offsetValue = Integer.parseInt(getSqlParser().getLexer().getCurrentToken().getLiterals()); + offsetBeginPosition = offsetBeginPosition - (offsetValue + "").length(); + } else if (getSqlParser().equalAny(Symbol.QUESTION)) { + offsetIndex = -1 == index ? parametersIndex : index + 1; + offsetBeginPosition--; + isParameterForOffset = true; + } else { + throw new SQLParsingException(getSqlParser().getLexer()); + } + getSqlParser().getLexer().nextToken(); + if (!isParameterForOffset) { + sqlStatement.getSqlTokens().add(new OffsetToken(offsetBeginPosition, offsetValue)); + } + if (!isParameterForValue) { + sqlStatement.getSqlTokens().add(new RowCountToken(valueBeginPosition, value)); } + Limit result = new Limit(true); + result.setRowCount(new LimitValue(value, index)); + result.setOffset(new LimitValue(offsetValue, offsetIndex)); + return result; } private void skipToFrom() { diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerDeleteParser.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerDeleteParser.java index 9397305f31..1e5ce746c2 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerDeleteParser.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerDeleteParser.java @@ -39,7 +39,13 @@ public final class SQLServerDeleteParser extends AbstractDeleteParser { if (getSqlParser().equalAny(SQLServerKeyword.TOP)) { throw new SQLParsingUnsupportedException(getSqlParser().getLexer().getCurrentToken().getType()); } - ((SQLServerParser) getSqlParser()).skipOutput(); + skipOutput(); getSqlParser().skipIfEqual(DefaultKeyword.FROM); } + + private void skipOutput() { + if (getSqlParser().equalAny(SQLServerKeyword.OUTPUT)) { + throw new SQLParsingUnsupportedException(SQLServerKeyword.OUTPUT); + } + } } diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerParser.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerParser.java index a9513a0abf..348b73b4af 100755 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerParser.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerParser.java @@ -18,22 +18,10 @@ package com.dangdang.ddframe.rdb.sharding.parsing.parser.dialect.sqlserver; import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule; -import com.dangdang.ddframe.rdb.sharding.parsing.lexer.dialect.sqlserver.SQLServerKeyword; import com.dangdang.ddframe.rdb.sharding.parsing.lexer.dialect.sqlserver.SQLServerLexer; -import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.DefaultKeyword; -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.SQLParser; -import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit; -import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.LimitValue; 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.SQLExpression; -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.dangdang.ddframe.rdb.sharding.parsing.parser.token.RowCountToken; import com.google.common.base.Optional; /** @@ -58,83 +46,4 @@ public final class SQLServerParser extends SQLParser { } return columnLabel.equalsIgnoreCase(rowNumberAlias.orNull()); } - - /** - * 解析TOP. - * - * @param selectStatement SQL语句对象 - */ - public void parseTop(final SelectStatement selectStatement) { - if (skipIfEqual(SQLServerKeyword.TOP)) { - int beginPosition = getLexer().getCurrentToken().getEndPosition(); - if (!skipIfEqual(Symbol.LEFT_PAREN)) { - beginPosition = getLexer().getCurrentToken().getEndPosition() - getLexer().getCurrentToken().getLiterals().length(); - } - SQLExpression sqlExpression = parseExpression(); - skipIfEqual(Symbol.RIGHT_PAREN); - LimitValue rowCountValue; - if (sqlExpression instanceof SQLNumberExpression) { - int rowCount = ((SQLNumberExpression) sqlExpression).getNumber().intValue(); - rowCountValue = new LimitValue(rowCount, -1); - selectStatement.getSqlTokens().add(new RowCountToken(beginPosition, rowCount)); - } else if (sqlExpression instanceof SQLPlaceholderExpression) { - rowCountValue = new LimitValue(-1, ((SQLPlaceholderExpression) sqlExpression).getIndex()); - } else { - throw new SQLParsingException(getLexer()); - } - if (skipIfEqual(SQLServerKeyword.PERCENT)) { - return; - } - if (null == selectStatement.getLimit()) { - Limit limit = new Limit(false); - limit.setRowCount(rowCountValue); - selectStatement.setLimit(limit); - } else { - selectStatement.getLimit().setRowCount(rowCountValue); - } - } - } - - protected void skipOutput() { - if (equalAny(SQLServerKeyword.OUTPUT)) { - throw new SQLParsingUnsupportedException(SQLServerKeyword.OUTPUT); - } - } - - public void parseOffset(final SelectStatement selectStatement) { - getLexer().nextToken(); - int offsetValue = -1; - int offsetIndex = -1; - if (equalAny(Literals.INT)) { - offsetValue = Integer.parseInt(getLexer().getCurrentToken().getLiterals()); - } else if (equalAny(Symbol.QUESTION)) { - offsetIndex = getParametersIndex(); - increaseParametersIndex(); - } else { - throw new SQLParsingException(getLexer()); - } - getLexer().nextToken(); - Limit limit = new Limit(true); - if (skipIfEqual(DefaultKeyword.FETCH)) { - getLexer().nextToken(); - int rowCountValue = -1; - int rowCountIndex = -1; - getLexer().nextToken(); - if (equalAny(Literals.INT)) { - rowCountValue = Integer.parseInt(getLexer().getCurrentToken().getLiterals()); - } else if (equalAny(Symbol.QUESTION)) { - rowCountIndex = getParametersIndex(); - increaseParametersIndex(); - } else { - throw new SQLParsingException(getLexer()); - } - getLexer().nextToken(); - getLexer().nextToken(); - limit.setRowCount(new LimitValue(rowCountValue, rowCountIndex)); - limit.setOffset(new LimitValue(offsetValue, offsetIndex)); - } else { - limit.setOffset(new LimitValue(offsetValue, offsetIndex)); - } - selectStatement.setLimit(limit); - } } diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerSelectParser.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerSelectParser.java index 169e1a913f..ee729a3a2c 100755 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerSelectParser.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/dialect/sqlserver/SQLServerSelectParser.java @@ -19,13 +19,21 @@ 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.Literals; 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.LimitValue; 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.SQLParsingException; import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingUnsupportedException; +import com.dangdang.ddframe.rdb.sharding.parsing.parser.expression.SQLExpression; +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.AbstractSelectParser; import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.SelectStatement; +import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.RowCountToken; import com.google.common.base.Optional; public class SQLServerSelectParser extends AbstractSelectParser { @@ -34,23 +42,11 @@ public class SQLServerSelectParser extends AbstractSelectParser { super(sqlParser); } - @Override - protected void customizedSelect() { - if (getSqlParser().equalAny(DefaultKeyword.FOR)) { - parseFor(); - } - if (getSqlParser().equalAny(SQLServerKeyword.OFFSET)) { - ((SQLServerParser) getSqlParser()).parseOffset(getSelectStatement()); - } - } - @Override public void query() { if (getSqlParser().skipIfEqual(DefaultKeyword.SELECT)) { parseDistinct(); - if (getSqlParser().equalAny(SQLServerKeyword.TOP)) { - ((SQLServerParser) getSqlParser()).parseTop(getSelectStatement()); - } + parseTop(); parseSelectList(); } if (getSqlParser().equalAny(DefaultKeyword.INTO)) { @@ -62,6 +58,38 @@ public class SQLServerSelectParser extends AbstractSelectParser { queryRest(); } + private void parseTop() { + if (!getSqlParser().skipIfEqual(SQLServerKeyword.TOP)) { + return; + } + int beginPosition = getSqlParser().getLexer().getCurrentToken().getEndPosition(); + if (!getSqlParser().skipIfEqual(Symbol.LEFT_PAREN)) { + beginPosition = getSqlParser().getLexer().getCurrentToken().getEndPosition() - getSqlParser().getLexer().getCurrentToken().getLiterals().length(); + } + SQLExpression sqlExpression = getSqlParser().parseExpression(); + getSqlParser().skipIfEqual(Symbol.RIGHT_PAREN); + LimitValue rowCountValue; + if (sqlExpression instanceof SQLNumberExpression) { + int rowCount = ((SQLNumberExpression) sqlExpression).getNumber().intValue(); + rowCountValue = new LimitValue(rowCount, -1); + getSelectStatement().getSqlTokens().add(new RowCountToken(beginPosition, rowCount)); + } else if (sqlExpression instanceof SQLPlaceholderExpression) { + rowCountValue = new LimitValue(-1, ((SQLPlaceholderExpression) sqlExpression).getIndex()); + } else { + throw new SQLParsingException(getSqlParser().getLexer()); + } + if (getSqlParser().skipIfEqual(SQLServerKeyword.PERCENT)) { + return; + } + if (null == getSelectStatement().getLimit()) { + Limit limit = new Limit(false); + limit.setRowCount(rowCountValue); + getSelectStatement().setLimit(limit); + } else { + getSelectStatement().getLimit().setRowCount(rowCountValue); + } + } + @Override protected boolean isRowNumberSelectItem() { return getSqlParser().getLexer().getCurrentToken().getLiterals().equalsIgnoreCase("ROW_NUMBER"); @@ -93,6 +121,53 @@ public class SQLServerSelectParser extends AbstractSelectParser { super.parseJoinTable(); } + @Override + protected void customizedSelect() { + if (getSqlParser().equalAny(DefaultKeyword.FOR)) { + parseFor(); + } + if (getSqlParser().equalAny(SQLServerKeyword.OFFSET)) { + parseOffset(); + } + } + + private void parseOffset() { + getSqlParser().getLexer().nextToken(); + int offsetValue = -1; + int offsetIndex = -1; + if (getSqlParser().equalAny(Literals.INT)) { + offsetValue = Integer.parseInt(getSqlParser().getLexer().getCurrentToken().getLiterals()); + } else if (getSqlParser().equalAny(Symbol.QUESTION)) { + offsetIndex = getParametersIndex(); + getSqlParser().increaseParametersIndex(); + } else { + throw new SQLParsingException(getSqlParser().getLexer()); + } + getSqlParser().getLexer().nextToken(); + Limit limit = new Limit(true); + if (getSqlParser().skipIfEqual(DefaultKeyword.FETCH)) { + getSqlParser().getLexer().nextToken(); + int rowCountValue = -1; + int rowCountIndex = -1; + getSqlParser().getLexer().nextToken(); + if (getSqlParser().equalAny(Literals.INT)) { + rowCountValue = Integer.parseInt(getSqlParser().getLexer().getCurrentToken().getLiterals()); + } else if (getSqlParser().equalAny(Symbol.QUESTION)) { + rowCountIndex = getParametersIndex(); + getSqlParser().increaseParametersIndex(); + } else { + throw new SQLParsingException(getSqlParser().getLexer()); + } + getSqlParser().getLexer().nextToken(); + getSqlParser().getLexer().nextToken(); + limit.setRowCount(new LimitValue(rowCountValue, rowCountIndex)); + limit.setOffset(new LimitValue(offsetValue, offsetIndex)); + } else { + limit.setOffset(new LimitValue(offsetValue, offsetIndex)); + } + getSelectStatement().setLimit(limit); + } + private void parseFor() { getSqlParser().getLexer().nextToken(); if (getSqlParser().equalAny(SQLServerKeyword.BROWSE)) { diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/insert/AbstractInsertParser.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/insert/AbstractInsertParser.java index f21f7d6004..a5093af4c0 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/insert/AbstractInsertParser.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/insert/AbstractInsertParser.java @@ -60,6 +60,7 @@ public abstract class AbstractInsertParser implements SQLStatementParser { private final InsertStatement insertStatement; + @Getter(AccessLevel.NONE) private int generateKeyColumnIndex = -1; public AbstractInsertParser(final ShardingRule shardingRule, final SQLParser sqlParser) { @@ -154,7 +155,7 @@ public abstract class AbstractInsertParser implements SQLStatementParser { int count = 0; for (Column each : insertStatement.getColumns()) { SQLExpression sqlExpression = sqlExpressions.get(count); - insertStatement.getConditions().add(new Condition(each, sqlExpression), getShardingRule()); + insertStatement.getConditions().add(new Condition(each, sqlExpression), shardingRule); if (generateKeyColumnIndex == count) { insertStatement.setGeneratedKey(createGeneratedKey(each, sqlExpression)); } diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/update/AbstractUpdateParser.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/update/AbstractUpdateParser.java index 7c323b7155..efe23a7683 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/update/AbstractUpdateParser.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/update/AbstractUpdateParser.java @@ -38,6 +38,7 @@ public abstract class AbstractUpdateParser implements SQLStatementParser { private final UpdateStatement updateStatement; + @Getter(AccessLevel.NONE) private int parametersIndex; public AbstractUpdateParser(final SQLParser sqlParser) { -- GitLab