提交 27607d96 编写于 作者: T terrymanu

refactor merger into ShardingResultSet 7th version, refactor SQLStatement and SelectStatement

上级 fa78b18d
......@@ -27,6 +27,7 @@ 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;
......@@ -45,10 +46,10 @@ public final class MySQLParser extends SQLParser {
/**
* 解析分页.
*
* @param sqlStatement SQL语句对象
* @param selectStatement SQL语句对象
* @param parametersIndex 参数索引
*/
public void parseLimit(final SQLStatement sqlStatement, final int parametersIndex) {
public void parseLimit(final SelectStatement selectStatement, final int parametersIndex) {
skipIfEqual(MySQLKeyword.LIMIT);
int valueIndex = -1;
int valueBeginPosition = getLexer().getCurrentToken().getEndPosition();
......@@ -67,19 +68,19 @@ public final class MySQLParser extends SQLParser {
}
getLexer().nextToken();
if (skipIfEqual(Symbol.COMMA)) {
sqlStatement.setLimit(getLimitWithComma(sqlStatement, parametersIndex, valueIndex, valueBeginPosition, value, isParameterForValue));
selectStatement.setLimit(getLimitWithComma(selectStatement, parametersIndex, valueIndex, valueBeginPosition, value, isParameterForValue));
return;
}
if (skipIfEqual(MySQLKeyword.OFFSET)) {
sqlStatement.setLimit(getLimitWithOffset(sqlStatement, parametersIndex, valueIndex, valueBeginPosition, value, isParameterForValue));
selectStatement.setLimit(getLimitWithOffset(selectStatement, parametersIndex, valueIndex, valueBeginPosition, value, isParameterForValue));
return;
}
if (!isParameterForValue) {
sqlStatement.getSqlTokens().add(new RowCountToken(valueBeginPosition, value));
selectStatement.getSqlTokens().add(new RowCountToken(valueBeginPosition, value));
}
Limit limit = new Limit(true);
limit.setRowCount(new LimitValue(value, valueIndex));
sqlStatement.setLimit(limit);
selectStatement.setLimit(limit);
}
private Limit getLimitWithComma(final SQLStatement sqlStatement, final int parametersIndex, final int index, final int valueBeginPosition, final int value, final boolean isParameterForValue) {
......
......@@ -17,9 +17,11 @@
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.parser.statement.delete.AbstractDeleteParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.SQLParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingUnsupportedException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.delete.AbstractDeleteParser;
/**
* SQLServer Delete语句解析器.
......@@ -34,7 +36,9 @@ public final class SQLServerDeleteParser extends AbstractDeleteParser {
@Override
protected void skipBetweenDeleteAndTable() {
((SQLServerParser) getSqlParser()).parseTop(getDeleteStatement());
if (getSqlParser().equalAny(SQLServerKeyword.TOP)) {
throw new SQLParsingUnsupportedException(getSqlParser().getLexer().getCurrentToken().getType());
}
((SQLServerParser) getSqlParser()).skipOutput();
getSqlParser().skipIfEqual(DefaultKeyword.FROM);
}
......
......@@ -32,7 +32,6 @@ import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingUnsu
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.SQLStatement;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.SelectStatement;
import com.google.common.base.Optional;
......@@ -59,7 +58,12 @@ public final class SQLServerParser extends SQLParser {
return columnLabel.equalsIgnoreCase(rowNumberAlias.orNull());
}
public void parseTop(final SQLStatement sqlStatement) {
/**
* 解析TOP.
*
* @param selectStatement SQL语句对象
*/
public void parseTop(final SelectStatement selectStatement) {
if (skipIfEqual(SQLServerKeyword.TOP)) {
skipIfEqual(Symbol.LEFT_PAREN);
SQLExpression sqlExpression = parseExpression();
......@@ -75,12 +79,12 @@ public final class SQLServerParser extends SQLParser {
if (skipIfEqual(SQLServerKeyword.PERCENT)) {
return;
}
if (null == sqlStatement.getLimit()) {
if (null == selectStatement.getLimit()) {
Limit limit = new Limit(false);
limit.setRowCount(rowCount);
sqlStatement.setLimit(limit);
selectStatement.setLimit(limit);
} else {
sqlStatement.getLimit().setRowCount(rowCount);
selectStatement.getLimit().setRowCount(rowCount);
}
}
}
......
......@@ -17,6 +17,8 @@
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.parser.exception.SQLParsingUnsupportedException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.update.AbstractUpdateParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.SQLParser;
......@@ -33,6 +35,8 @@ public final class SQLServerUpdateParser extends AbstractUpdateParser {
@Override
protected void skipBetweenUpdateAndTable() {
((SQLServerParser) getSqlParser()).parseTop(getUpdateStatement());
if (getSqlParser().equalAny(SQLServerKeyword.TOP)) {
throw new SQLParsingUnsupportedException(getSqlParser().getLexer().getCurrentToken().getType());
}
}
}
......@@ -18,17 +18,13 @@
package com.dangdang.ddframe.rdb.sharding.parsing.parser.statement;
import com.dangdang.ddframe.rdb.sharding.constant.SQLType;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.OrderItem;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.condition.Conditions;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.selectitem.AggregationSelectItem;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.table.Tables;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.SQLToken;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
......@@ -54,33 +50,4 @@ public abstract class AbstractSQLStatement implements SQLStatement {
public final SQLType getType() {
return type;
}
public List<OrderItem> getOrderByItems() {
return Collections.emptyList();
}
public List<OrderItem> getGroupByItems() {
return Collections.emptyList();
}
@Override
public List<AggregationSelectItem> getAggregationSelectItems() {
return Collections.emptyList();
}
public Limit getLimit() {
return null;
}
public void setLimit(final Limit limit) {
}
/**
* 判断是否需要内存排序.
*
* @return 是否需要内存排序
*/
public boolean isGroupByAndOrderByDifferent() {
return !getGroupByItems().isEmpty() && !getOrderByItems().equals(getGroupByItems());
}
}
......@@ -18,10 +18,7 @@
package com.dangdang.ddframe.rdb.sharding.parsing.parser.statement;
import com.dangdang.ddframe.rdb.sharding.constant.SQLType;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.OrderItem;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.condition.Conditions;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.selectitem.AggregationSelectItem;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.table.Tables;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.SQLToken;
......@@ -55,52 +52,10 @@ public interface SQLStatement {
*/
Conditions getConditions();
/**
* 获取排序集合.
*
* @return 排序集合
*/
List<OrderItem> getOrderByItems();
/**
* 获取分组集合.
*
* @return 分组集合
*/
List<OrderItem> getGroupByItems();
/**
* 获取聚合选择项集合.
*
* @return 聚合选择项
*/
List<AggregationSelectItem> getAggregationSelectItems();
/**
* 获取分页.
*
* @return 分页
*/
Limit getLimit();
/**
* 设置分页.
*
* @param limit 分页
*/
void setLimit(Limit limit);
/**
* 获取SQL标记集合.
*
* @return SQL标记集合
*/
List<SQLToken> getSqlTokens();
/**
* 判断是否需要内存排序.
*
* @return 是否需要内存排序
*/
boolean isGroupByAndOrderByDifferent();
}
......@@ -58,7 +58,11 @@ public final class SelectStatement extends AbstractSQLStatement {
super(SQLType.SELECT);
}
@Override
/**
* 获取聚合选择项集合.
*
* @return 聚合选择项
*/
public List<AggregationSelectItem> getAggregationSelectItems() {
List<AggregationSelectItem> result = new LinkedList<>();
for (SelectItem each : items) {
......@@ -73,7 +77,12 @@ public final class SelectStatement extends AbstractSQLStatement {
return result;
}
public Limit getLimit() {
return limit;
/**
* 判断是否需要内存排序.
*
* @return 是否需要内存排序
*/
public boolean isGroupByAndOrderByDifferent() {
return !getGroupByItems().isEmpty() && !getOrderByItems().equals(getGroupByItems());
}
}
......@@ -22,6 +22,7 @@ import com.dangdang.ddframe.rdb.sharding.api.rule.BindingTableRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
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.ItemsToken;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.OffsetToken;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.RowCountToken;
......@@ -61,7 +62,11 @@ public final class SQLRewriteEngine {
this.originalSQL = originalSQL;
sqlTokens.addAll(sqlStatement.getSqlTokens());
tableNames = sqlStatement.getTables().getTableNames();
limit = sqlStatement.getLimit();
if (sqlStatement instanceof SelectStatement) {
limit = ((SelectStatement) sqlStatement).getLimit();
} else {
limit = null;
}
}
/**
......
......@@ -26,6 +26,7 @@ import com.dangdang.ddframe.rdb.sharding.parsing.SQLParsingEngine;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.GeneratedKey;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.SQLStatement;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.insert.InsertStatement;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.SelectStatement;
import com.dangdang.ddframe.rdb.sharding.rewrite.SQLBuilder;
import com.dangdang.ddframe.rdb.sharding.rewrite.SQLRewriteEngine;
import com.dangdang.ddframe.rdb.sharding.routing.SQLExecutionUnit;
......@@ -86,8 +87,8 @@ public final class ParsingSQLRouter implements SQLRouter {
RoutingResult routingResult = route(parameters, sqlStatement);
SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, logicSQL, sqlStatement);
boolean isSingleRouting = routingResult.isSingleRouting();
if (null != sqlStatement.getLimit()) {
sqlStatement.getLimit().processParameters(parameters, !isSingleRouting);
if (sqlStatement instanceof SelectStatement && null != ((SelectStatement) sqlStatement).getLimit()) {
((SelectStatement) sqlStatement).getLimit().processParameters(parameters, !isSingleRouting);
}
SQLBuilder sqlBuilder = rewriteEngine.rewrite(!isSingleRouting);
if (routingResult instanceof CartesianRoutingResult) {
......
......@@ -82,10 +82,17 @@ public abstract class AbstractBaseParseTest {
this.sql = sql;
this.expectedTables = expectedTables;
this.expectedConditions = expectedConditions;
this.expectedOrderByColumns = expectedSQLStatement.getOrderByItems().iterator();
this.expectedGroupByColumns = expectedSQLStatement.getGroupByItems().iterator();
this.expectedAggregationSelectItems = expectedSQLStatement.getAggregationSelectItems().iterator();
this.expectedLimit = expectedSQLStatement.getLimit();
if (expectedSQLStatement instanceof SelectStatement) {
expectedOrderByColumns = ((SelectStatement) expectedSQLStatement).getOrderByItems().iterator();
expectedGroupByColumns = ((SelectStatement) expectedSQLStatement).getGroupByItems().iterator();
expectedAggregationSelectItems = ((SelectStatement) expectedSQLStatement).getAggregationSelectItems().iterator();
expectedLimit = ((SelectStatement) expectedSQLStatement).getLimit();
} else {
expectedOrderByColumns = null;
expectedGroupByColumns = null;
expectedAggregationSelectItems = null;
expectedLimit = null;
}
}
protected static Collection<Object[]> dataParameters(final String path) {
......@@ -219,10 +226,12 @@ public abstract class AbstractBaseParseTest {
protected final void assertSQLStatement(final SQLStatement actual) {
assertExpectedTables(actual);
assertExpectedConditions(actual);
assertOrderBy(actual);
assertGroupBy(actual);
assertAggregationSelectItem(actual);
assertLimit(actual);
if (actual instanceof SelectStatement) {
assertOrderBy((SelectStatement) actual);
assertGroupBy((SelectStatement) actual);
assertAggregationSelectItem((SelectStatement) actual);
assertLimit((SelectStatement) actual);
}
}
private void assertExpectedTables(final SQLStatement actual) {
......@@ -233,21 +242,21 @@ public abstract class AbstractBaseParseTest {
assertTrue(new ReflectionEquals(expectedConditions).matches(actual.getConditions()));
}
private void assertOrderBy(final SQLStatement actual) {
private void assertOrderBy(final SelectStatement actual) {
for (OrderItem each : actual.getOrderByItems()) {
assertTrue(new ReflectionEquals(expectedOrderByColumns.next()).matches(each));
}
assertFalse(expectedOrderByColumns.hasNext());
}
private void assertGroupBy(final SQLStatement actual) {
private void assertGroupBy(final SelectStatement actual) {
for (OrderItem each : actual.getGroupByItems()) {
assertTrue(new ReflectionEquals(expectedGroupByColumns.next()).matches(each));
}
assertFalse(expectedGroupByColumns.hasNext());
}
private void assertAggregationSelectItem(final SQLStatement actual) {
private void assertAggregationSelectItem(final SelectStatement actual) {
for (AggregationSelectItem each : actual.getAggregationSelectItems()) {
AggregationSelectItem expected = expectedAggregationSelectItems.next();
assertTrue(new ReflectionEquals(expected, "derivedAggregationSelectItems").matches(each));
......@@ -258,7 +267,7 @@ public abstract class AbstractBaseParseTest {
assertFalse(expectedAggregationSelectItems.hasNext());
}
private void assertLimit(final SQLStatement actual) {
private void assertLimit(final SelectStatement actual) {
if (null != actual.getLimit()) {
if (null != actual.getLimit().getOffset()) {
assertTrue(new ReflectionEquals(expectedLimit.getOffset()).matches(actual.getLimit().getOffset()));
......
......@@ -37,7 +37,7 @@ public final class SQLStatementTest {
@Test
public void assertIsNeedMemorySortForGroupByWithGroupByAndOrderBySame() throws SQLException {
SQLStatement actual = new SelectStatement();
SelectStatement actual = new SelectStatement();
actual.getOrderByItems().add(new OrderItem("col", OrderType.ASC, Optional.<String>absent()));
actual.getGroupByItems().add(new OrderItem("col", OrderType.ASC, Optional.<String>absent()));
assertFalse(actual.isGroupByAndOrderByDifferent());
......@@ -45,7 +45,7 @@ public final class SQLStatementTest {
@Test
public void assertIsNeedMemorySortForGroupByWithGroupByAndOrderByDifferent() throws SQLException {
SQLStatement actual = new SelectStatement();
SelectStatement actual = new SelectStatement();
actual.getOrderByItems().add(new OrderItem("order_col", OrderType.ASC, Optional.<String>absent()));
actual.getGroupByItems().add(new OrderItem("group_col", OrderType.ASC, Optional.<String>absent()));
assertTrue(actual.isGroupByAndOrderByDifferent());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册