提交 1cbb074d 编写于 作者: T terrymanu

fix #490

上级 97d12149
......@@ -17,11 +17,15 @@
package io.shardingjdbc.core.merger;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.merger.groupby.GroupByMemoryResultSetMerger;
import io.shardingjdbc.core.merger.groupby.GroupByStreamResultSetMerger;
import io.shardingjdbc.core.merger.iterator.IteratorStreamResultSetMerger;
import io.shardingjdbc.core.merger.limit.LimitDecoratorResultSetMerger;
import io.shardingjdbc.core.merger.limit.RowNumberDecoratorResultSetMerger;
import io.shardingjdbc.core.merger.limit.TopAndRowNumberDecoratorResultSetMerger;
import io.shardingjdbc.core.merger.orderby.OrderByStreamResultSetMerger;
import io.shardingjdbc.core.parsing.parser.context.limit.Limit;
import io.shardingjdbc.core.parsing.parser.sql.dql.select.SelectStatement;
import io.shardingjdbc.core.util.SQLUtil;
......@@ -86,10 +90,19 @@ public final class MergeEngine {
}
private ResultSetMerger decorate(final ResultSetMerger resultSetMerger) throws SQLException {
ResultSetMerger result = resultSetMerger;
if (null != selectStatement.getLimit()) {
result = new LimitDecoratorResultSetMerger(result, selectStatement.getLimit());
Limit limit = selectStatement.getLimit();
if (null == limit) {
return resultSetMerger;
}
return result;
if (DatabaseType.MySQL == limit.getDatabaseType() || DatabaseType.PostgreSQL == limit.getDatabaseType() || DatabaseType.H2 == limit.getDatabaseType()) {
return new LimitDecoratorResultSetMerger(resultSetMerger, selectStatement.getLimit());
}
if (DatabaseType.Oracle == limit.getDatabaseType()) {
return new RowNumberDecoratorResultSetMerger(resultSetMerger, selectStatement.getLimit());
}
if (DatabaseType.SQLServer == limit.getDatabaseType()) {
return new TopAndRowNumberDecoratorResultSetMerger(resultSetMerger, selectStatement.getLimit());
}
return resultSetMerger;
}
}
......@@ -24,7 +24,7 @@ import io.shardingjdbc.core.parsing.parser.context.limit.Limit;
import java.sql.SQLException;
/**
* Decorator merger for limit.
* Decorator merger for limit pagination.
*
* @author zhangliang
*/
......@@ -57,9 +57,9 @@ public final class LimitDecoratorResultSetMerger extends AbstractDecoratorResult
if (skipAll) {
return false;
}
if (limit.getRowCountValue() > -1) {
return ++rowNumber <= limit.getRowCountValue() && getResultSetMerger().next();
if (limit.getRowCountValue() < 0) {
return getResultSetMerger().next();
}
return getResultSetMerger().next();
return ++rowNumber <= limit.getRowCountValue() && getResultSetMerger().next();
}
}
/*
* 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 io.shardingjdbc.core.merger.limit;
import io.shardingjdbc.core.merger.ResultSetMerger;
import io.shardingjdbc.core.merger.common.AbstractDecoratorResultSetMerger;
import io.shardingjdbc.core.parsing.parser.context.limit.Limit;
import java.sql.SQLException;
/**
* Decorator merger for rownum pagination.
*
* @author zhangliang
*/
public final class RowNumberDecoratorResultSetMerger extends AbstractDecoratorResultSetMerger {
private final Limit limit;
private final boolean skipAll;
private int rowNumber;
public RowNumberDecoratorResultSetMerger(final ResultSetMerger resultSetMerger, final Limit limit) throws SQLException {
super(resultSetMerger);
this.limit = limit;
skipAll = skipOffset();
}
private boolean skipOffset() throws SQLException {
int end = limit.isIncludeOffset() ? limit.getOffsetValue() - 1 : limit.getOffsetValue();
for (int i = 0; i < end; i++) {
if (!getResultSetMerger().next()) {
return true;
}
}
rowNumber = limit.isRowCountRewriteFlag() ? 0 : end + 1;
return false;
}
@Override
public boolean next() throws SQLException {
if (skipAll) {
return false;
}
if (limit.getRowCountValue() < 0) {
return getResultSetMerger().next();
}
if (limit.isIncludeRowCount()) {
return rowNumber++ <= limit.getRowCountValue() && getResultSetMerger().next();
}
return rowNumber++ < limit.getRowCountValue() && getResultSetMerger().next();
}
}
/*
* 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 io.shardingjdbc.core.merger.limit;
import io.shardingjdbc.core.merger.ResultSetMerger;
import io.shardingjdbc.core.merger.common.AbstractDecoratorResultSetMerger;
import io.shardingjdbc.core.parsing.parser.context.limit.Limit;
import java.sql.SQLException;
/**
* Decorator merger for rownum pagination.
*
* @author zhangliang
*/
public final class TopAndRowNumberDecoratorResultSetMerger extends AbstractDecoratorResultSetMerger {
private final Limit limit;
private final boolean skipAll;
private int rowNumber;
public TopAndRowNumberDecoratorResultSetMerger(final ResultSetMerger resultSetMerger, final Limit limit) throws SQLException {
super(resultSetMerger);
this.limit = limit;
skipAll = skipOffset();
}
private boolean skipOffset() throws SQLException {
int end = limit.isIncludeOffset() ? limit.getOffsetValue() - 1 : limit.getOffsetValue();
for (int i = 0; i < end; i++) {
if (!getResultSetMerger().next()) {
return true;
}
}
rowNumber = limit.isRowCountRewriteFlag() ? 0 : end + 1;
return false;
}
@Override
public boolean next() throws SQLException {
if (skipAll) {
return false;
}
if (limit.getRowCountValue() < 0) {
return getResultSetMerger().next();
}
return rowNumber++ <= limit.getRowCountValue() && getResultSetMerger().next();
}
}
package io.shardingjdbc.core.parsing.parser.clause;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.rule.ShardingRule;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.lexer.token.DefaultKeyword;
......@@ -36,13 +37,16 @@ import java.util.List;
*/
public class WhereClauseParser implements SQLClauseParser {
private final DatabaseType databaseType;
private final LexerEngine lexerEngine;
private final AliasClauseParser aliasClauseParser;
private final ExpressionClauseParser expressionClauseParser;
public WhereClauseParser(final LexerEngine lexerEngine) {
public WhereClauseParser(final DatabaseType databaseType, final LexerEngine lexerEngine) {
this.databaseType = databaseType;
this.lexerEngine = lexerEngine;
aliasClauseParser = new AliasClauseParser(lexerEngine);
expressionClauseParser = new ExpressionClauseParser(lexerEngine);
......@@ -88,12 +92,20 @@ public class WhereClauseParser implements SQLClauseParser {
return;
}
if (sqlStatement instanceof SelectStatement && isRowNumberCondition(items, left)) {
if (lexerEngine.skipIfEqual(Symbol.LT, Symbol.LT_EQ)) {
parseRowCountCondition((SelectStatement) sqlStatement);
if (lexerEngine.skipIfEqual(Symbol.LT)) {
parseRowCountCondition((SelectStatement) sqlStatement, false);
return;
}
if (lexerEngine.skipIfEqual(Symbol.LT_EQ)) {
parseRowCountCondition((SelectStatement) sqlStatement, true);
return;
}
if (lexerEngine.skipIfEqual(Symbol.GT)) {
parseOffsetCondition((SelectStatement) sqlStatement, false);
return;
}
if (lexerEngine.skipIfEqual(Symbol.GT, Symbol.GT_EQ)) {
parseOffsetCondition((SelectStatement) sqlStatement);
if (lexerEngine.skipIfEqual(Symbol.GT_EQ)) {
parseOffsetCondition((SelectStatement) sqlStatement, true);
return;
}
}
......@@ -163,10 +175,10 @@ public class WhereClauseParser implements SQLClauseParser {
return false;
}
private void parseRowCountCondition(final SelectStatement selectStatement) {
private void parseRowCountCondition(final SelectStatement selectStatement, final boolean includeRowCount) {
SQLExpression sqlExpression = expressionClauseParser.parse(selectStatement);
if (null == selectStatement.getLimit()) {
selectStatement.setLimit(new Limit(false));
selectStatement.setLimit(new Limit(databaseType, false));
}
if (sqlExpression instanceof SQLNumberExpression) {
int rowCount = ((SQLNumberExpression) sqlExpression).getNumber().intValue();
......@@ -176,12 +188,13 @@ public class WhereClauseParser implements SQLClauseParser {
} else if (sqlExpression instanceof SQLPlaceholderExpression) {
selectStatement.getLimit().setRowCount(new LimitValue(-1, ((SQLPlaceholderExpression) sqlExpression).getIndex()));
}
selectStatement.getLimit().setIncludeRowCount(includeRowCount);
}
private void parseOffsetCondition(final SelectStatement selectStatement) {
private void parseOffsetCondition(final SelectStatement selectStatement, final boolean includeOffset) {
SQLExpression sqlExpression = expressionClauseParser.parse(selectStatement);
if (null == selectStatement.getLimit()) {
selectStatement.setLimit(new Limit(false));
selectStatement.setLimit(new Limit(databaseType, false));
}
if (sqlExpression instanceof SQLNumberExpression) {
int offset = ((SQLNumberExpression) sqlExpression).getNumber().intValue();
......@@ -191,6 +204,7 @@ public class WhereClauseParser implements SQLClauseParser {
} else if (sqlExpression instanceof SQLPlaceholderExpression) {
selectStatement.getLimit().setOffset(new LimitValue(-1, ((SQLPlaceholderExpression) sqlExpression).getIndex()));
}
selectStatement.getLimit().setIncludeOffset(includeOffset);
}
protected Keyword[] getCustomizedOtherConditionOperators() {
......
......@@ -17,6 +17,7 @@
package io.shardingjdbc.core.parsing.parser.context.limit;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.parsing.parser.exception.SQLParsingException;
import io.shardingjdbc.core.util.NumberUtil;
import lombok.Getter;
......@@ -38,12 +39,18 @@ import java.util.List;
@ToString
public final class Limit {
private final DatabaseType databaseType;
private final boolean rowCountRewriteFlag;
private LimitValue offset;
private LimitValue rowCount;
private boolean includeOffset;
private boolean includeRowCount;
/**
* Get offset value.
*
......
......@@ -17,6 +17,7 @@
package io.shardingjdbc.core.parsing.parser.dialect.mysql.clause;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.lexer.dialect.mysql.MySQLKeyword;
import io.shardingjdbc.core.parsing.lexer.token.Literals;
......@@ -76,8 +77,10 @@ public final class MySQLLimitClauseParser implements SQLClauseParser {
if (!isParameterForValue) {
selectStatement.getSqlTokens().add(new RowCountToken(valueBeginPosition, value));
}
Limit limit = new Limit(true);
Limit limit = new Limit(DatabaseType.MySQL, true);
limit.setRowCount(new LimitValue(value, valueIndex));
limit.setIncludeRowCount(false);
limit.setIncludeOffset(true);
selectStatement.setLimit(limit);
}
......@@ -104,9 +107,11 @@ public final class MySQLLimitClauseParser implements SQLClauseParser {
if (!isParameterForRowCount) {
selectStatement.getSqlTokens().add(new RowCountToken(rowCountBeginPosition, rowCountValue));
}
Limit result = new Limit(true);
Limit result = new Limit(DatabaseType.MySQL, true);
result.setRowCount(new LimitValue(rowCountValue, rowCountIndex));
result.setOffset(new LimitValue(value, index));
result.setIncludeRowCount(false);
result.setIncludeOffset(true);
return result;
}
......@@ -132,9 +137,11 @@ public final class MySQLLimitClauseParser implements SQLClauseParser {
if (!isParameterForValue) {
selectStatement.getSqlTokens().add(new RowCountToken(valueBeginPosition, value));
}
Limit result = new Limit(true);
Limit result = new Limit(DatabaseType.MySQL, true);
result.setRowCount(new LimitValue(value, index));
result.setOffset(new LimitValue(offsetValue, offsetIndex));
result.setIncludeRowCount(false);
result.setIncludeOffset(true);
return result;
}
}
package io.shardingjdbc.core.parsing.parser.dialect.mysql.clause;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.lexer.dialect.mysql.MySQLKeyword;
import io.shardingjdbc.core.parsing.lexer.token.Keyword;
......@@ -13,7 +14,7 @@ import io.shardingjdbc.core.parsing.parser.clause.WhereClauseParser;
public final class MySQLWhereClauseParser extends WhereClauseParser {
public MySQLWhereClauseParser(final LexerEngine lexerEngine) {
super(lexerEngine);
super(DatabaseType.MySQL, lexerEngine);
}
@Override
......
package io.shardingjdbc.core.parsing.parser.dialect.mysql.clause.facade;
import io.shardingjdbc.core.rule.ShardingRule;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.parser.clause.HavingClauseParser;
import io.shardingjdbc.core.parsing.parser.clause.OrderByClauseParser;
......@@ -11,6 +10,7 @@ import io.shardingjdbc.core.parsing.parser.dialect.mysql.clause.MySQLGroupByClau
import io.shardingjdbc.core.parsing.parser.dialect.mysql.clause.MySQLSelectRestClauseParser;
import io.shardingjdbc.core.parsing.parser.dialect.mysql.clause.MySQLTableReferencesClauseParser;
import io.shardingjdbc.core.parsing.parser.dialect.mysql.clause.MySQLWhereClauseParser;
import io.shardingjdbc.core.rule.ShardingRule;
/**
* Select clause parser facade for MySQL.
......
package io.shardingjdbc.core.parsing.parser.dialect.oracle.clause;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.parser.context.selectitem.SelectItem;
import io.shardingjdbc.core.parsing.parser.clause.WhereClauseParser;
......@@ -15,7 +16,7 @@ import java.util.List;
public final class OracleWhereClauseParser extends WhereClauseParser {
public OracleWhereClauseParser(final LexerEngine lexerEngine) {
super(lexerEngine);
super(DatabaseType.Oracle, lexerEngine);
}
@Override
......
package io.shardingjdbc.core.parsing.parser.dialect.oracle.clause.facade;
import io.shardingjdbc.core.rule.ShardingRule;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.parser.clause.facade.AbstractSelectClauseParserFacade;
import io.shardingjdbc.core.parsing.parser.clause.HavingClauseParser;
import io.shardingjdbc.core.parsing.parser.clause.SelectRestClauseParser;
import io.shardingjdbc.core.parsing.parser.clause.facade.AbstractSelectClauseParserFacade;
import io.shardingjdbc.core.parsing.parser.dialect.oracle.clause.OracleDistinctClauseParser;
import io.shardingjdbc.core.parsing.parser.dialect.oracle.clause.OracleGroupByClauseParser;
import io.shardingjdbc.core.parsing.parser.dialect.oracle.clause.OracleOrderByClauseParser;
import io.shardingjdbc.core.parsing.parser.dialect.oracle.clause.OracleSelectListClauseParser;
import io.shardingjdbc.core.parsing.parser.dialect.oracle.clause.OracleTableReferencesClauseParser;
import io.shardingjdbc.core.parsing.parser.dialect.oracle.clause.OracleWhereClauseParser;
import io.shardingjdbc.core.rule.ShardingRule;
/**
* Select clause parser facade for Oracle.
......
......@@ -17,6 +17,7 @@
package io.shardingjdbc.core.parsing.parser.dialect.postgresql.clause;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.lexer.dialect.postgresql.PostgreSQLKeyword;
import io.shardingjdbc.core.parsing.lexer.token.DefaultKeyword;
......@@ -110,13 +111,15 @@ public final class PostgreSQLLimitClauseParser implements SQLClauseParser {
}
private void setLimit(final Optional<LimitValue> offset, final Optional<LimitValue> rowCount, final SelectStatement selectStatement) {
Limit limit = new Limit(true);
Limit limit = new Limit(DatabaseType.PostgreSQL, true);
if (offset.isPresent()) {
limit.setOffset(offset.get());
}
if (rowCount.isPresent()) {
limit.setRowCount(rowCount.get());
}
limit.setIncludeRowCount(false);
limit.setIncludeOffset(true);
selectStatement.setLimit(limit);
}
}
package io.shardingjdbc.core.parsing.parser.dialect.postgresql.clause.facade;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.rule.ShardingRule;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.parser.clause.WhereClauseParser;
......@@ -14,6 +15,6 @@ import io.shardingjdbc.core.parsing.parser.dialect.postgresql.clause.PostgreSQLT
public final class PostgreSQLDeleteClauseParserFacade extends AbstractDeleteClauseParserFacade {
public PostgreSQLDeleteClauseParserFacade(final ShardingRule shardingRule, final LexerEngine lexerEngine) {
super(new PostgreSQLTableReferencesClauseParser(shardingRule, lexerEngine), new WhereClauseParser(lexerEngine));
super(new PostgreSQLTableReferencesClauseParser(shardingRule, lexerEngine), new WhereClauseParser(DatabaseType.PostgreSQL, lexerEngine));
}
}
package io.shardingjdbc.core.parsing.parser.dialect.postgresql.clause.facade;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.rule.ShardingRule;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.parser.clause.DistinctClauseParser;
......@@ -21,7 +22,8 @@ public final class PostgreSQLSelectClauseParserFacade extends AbstractSelectClau
public PostgreSQLSelectClauseParserFacade(final ShardingRule shardingRule, final LexerEngine lexerEngine) {
super(new DistinctClauseParser(lexerEngine), new SelectListClauseParser(shardingRule, lexerEngine),
new PostgreSQLTableReferencesClauseParser(shardingRule, lexerEngine), new WhereClauseParser(lexerEngine), new GroupByClauseParser(lexerEngine), new HavingClauseParser(lexerEngine),
new PostgreSQLTableReferencesClauseParser(shardingRule, lexerEngine),
new WhereClauseParser(DatabaseType.PostgreSQL, lexerEngine), new GroupByClauseParser(lexerEngine), new HavingClauseParser(lexerEngine),
new PostgreSQLOrderByClauseParser(lexerEngine), new PostgreSQLSelectRestClauseParser(lexerEngine));
}
}
package io.shardingjdbc.core.parsing.parser.dialect.postgresql.clause.facade;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.rule.ShardingRule;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.parser.clause.UpdateSetItemsClauseParser;
......@@ -15,6 +16,6 @@ import io.shardingjdbc.core.parsing.parser.dialect.postgresql.clause.PostgreSQLT
public final class PostgreSQLUpdateClauseParserFacade extends AbstractUpdateClauseParserFacade {
public PostgreSQLUpdateClauseParserFacade(final ShardingRule shardingRule, final LexerEngine lexerEngine) {
super(new PostgreSQLTableReferencesClauseParser(shardingRule, lexerEngine), new UpdateSetItemsClauseParser(lexerEngine), new WhereClauseParser(lexerEngine));
super(new PostgreSQLTableReferencesClauseParser(shardingRule, lexerEngine), new UpdateSetItemsClauseParser(lexerEngine), new WhereClauseParser(DatabaseType.PostgreSQL, lexerEngine));
}
}
......@@ -17,6 +17,7 @@
package io.shardingjdbc.core.parsing.parser.dialect.sqlserver.clause;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.lexer.dialect.sqlserver.SQLServerKeyword;
import io.shardingjdbc.core.parsing.lexer.token.DefaultKeyword;
......@@ -59,7 +60,7 @@ public final class SQLServerOffsetClauseParser implements SQLClauseParser {
throw new SQLParsingException(lexerEngine);
}
lexerEngine.nextToken();
Limit limit = new Limit(true);
Limit limit = new Limit(DatabaseType.SQLServer, true);
if (lexerEngine.skipIfEqual(DefaultKeyword.FETCH)) {
lexerEngine.nextToken();
int rowCountValue = -1;
......
......@@ -17,6 +17,7 @@
package io.shardingjdbc.core.parsing.parser.dialect.sqlserver.clause;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.lexer.dialect.sqlserver.SQLServerKeyword;
import io.shardingjdbc.core.parsing.lexer.token.DefaultKeyword;
......@@ -76,7 +77,7 @@ public final class SQLServerTopClauseParser implements SQLClauseParser {
lexerEngine.unsupportedIfEqual(SQLServerKeyword.PERCENT);
lexerEngine.skipIfEqual(DefaultKeyword.WITH, SQLServerKeyword.TIES);
if (null == selectStatement.getLimit()) {
Limit limit = new Limit(false);
Limit limit = new Limit(DatabaseType.SQLServer, false);
limit.setRowCount(rowCountValue);
selectStatement.setLimit(limit);
} else {
......
package io.shardingjdbc.core.parsing.parser.dialect.sqlserver.clause;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.parser.context.selectitem.SelectItem;
import io.shardingjdbc.core.parsing.parser.clause.WhereClauseParser;
......@@ -15,7 +16,7 @@ import java.util.List;
public final class SQLServerWhereClauseParser extends WhereClauseParser {
public SQLServerWhereClauseParser(final LexerEngine lexerEngine) {
super(lexerEngine);
super(DatabaseType.SQLServer, lexerEngine);
}
@Override
......
package io.shardingjdbc.core.parsing.parser.dialect.sqlserver.clause.facade;
import io.shardingjdbc.core.rule.ShardingRule;
import io.shardingjdbc.core.parsing.lexer.LexerEngine;
import io.shardingjdbc.core.parsing.parser.clause.DistinctClauseParser;
import io.shardingjdbc.core.parsing.parser.clause.GroupByClauseParser;
......@@ -11,6 +10,7 @@ import io.shardingjdbc.core.parsing.parser.dialect.sqlserver.clause.SQLServerSel
import io.shardingjdbc.core.parsing.parser.dialect.sqlserver.clause.SQLServerSelectRestClauseParser;
import io.shardingjdbc.core.parsing.parser.dialect.sqlserver.clause.SQLServerTableReferencesClauseParser;
import io.shardingjdbc.core.parsing.parser.dialect.sqlserver.clause.SQLServerWhereClauseParser;
import io.shardingjdbc.core.rule.ShardingRule;
/**
* Select clause parser facade for SQLServer.
......
......@@ -201,6 +201,8 @@ public final class SelectStatement extends DQLStatement {
if (null != result.getLimit().getOffset()) {
limit.setOffset(result.getLimit().getOffset());
}
limit.setIncludeOffset(result.getLimit().isIncludeOffset());
limit.setIncludeRowCount(result.getLimit().isIncludeRowCount());
}
resetLimitTokens(result, limitSQLTokens);
result.setLimit(limit);
......
......@@ -18,6 +18,7 @@
package io.shardingjdbc.core.merger;
import io.shardingjdbc.core.constant.AggregationType;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.constant.OrderType;
import io.shardingjdbc.core.merger.groupby.GroupByMemoryResultSetMerger;
import io.shardingjdbc.core.merger.groupby.GroupByStreamResultSetMerger;
......@@ -71,7 +72,7 @@ public final class MergeEngineTest {
@Test
public void assertBuildIteratorStreamResultSetMergerWithLimit() throws SQLException {
selectStatement.setLimit(new Limit(true));
selectStatement.setLimit(new Limit(DatabaseType.MySQL, true));
mergeEngine = new MergeEngine(resultSets, selectStatement);
ResultSetMerger actual = mergeEngine.merge();
assertThat(actual, instanceOf(LimitDecoratorResultSetMerger.class));
......@@ -87,7 +88,7 @@ public final class MergeEngineTest {
@Test
public void assertBuildOrderByStreamResultSetMergerWithLimit() throws SQLException {
selectStatement.setLimit(new Limit(true));
selectStatement.setLimit(new Limit(DatabaseType.MySQL, true));
selectStatement.getOrderByItems().add(new OrderItem(1, OrderType.DESC, OrderType.ASC));
mergeEngine = new MergeEngine(resultSets, selectStatement);
ResultSetMerger actual = mergeEngine.merge();
......@@ -105,7 +106,7 @@ public final class MergeEngineTest {
@Test
public void assertBuildGroupByStreamResultSetMergerWithLimit() throws SQLException {
selectStatement.setLimit(new Limit(true));
selectStatement.setLimit(new Limit(DatabaseType.MySQL, true));
selectStatement.getGroupByItems().add(new OrderItem(1, OrderType.DESC, OrderType.ASC));
selectStatement.getOrderByItems().add(new OrderItem(1, OrderType.DESC, OrderType.ASC));
mergeEngine = new MergeEngine(resultSets, selectStatement);
......@@ -123,7 +124,7 @@ public final class MergeEngineTest {
@Test
public void assertBuildGroupByMemoryResultSetMergerWithLimit() throws SQLException {
selectStatement.setLimit(new Limit(true));
selectStatement.setLimit(new Limit(DatabaseType.MySQL, true));
selectStatement.getGroupByItems().add(new OrderItem(1, OrderType.DESC, OrderType.ASC));
mergeEngine = new MergeEngine(resultSets, selectStatement);
ResultSetMerger actual = mergeEngine.merge();
......@@ -140,7 +141,7 @@ public final class MergeEngineTest {
@Test
public void assertBuildGroupByMemoryResultSetMergerWithAggregationOnlyWithLimit() throws SQLException {
selectStatement.setLimit(new Limit(true));
selectStatement.setLimit(new Limit(DatabaseType.MySQL, true));
selectStatement.getItems().add(new AggregationSelectItem(AggregationType.COUNT, "(*)", Optional.<String>absent()));
mergeEngine = new MergeEngine(resultSets, selectStatement);
ResultSetMerger actual = mergeEngine.merge();
......
......@@ -17,6 +17,7 @@
package io.shardingjdbc.core.merger.limit;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.merger.MergeEngine;
import io.shardingjdbc.core.merger.ResultSetMerger;
import io.shardingjdbc.core.parsing.parser.context.limit.Limit;
......@@ -55,7 +56,7 @@ public final class LimitDecoratorResultSetMergerTest {
@Test
public void assertNextForSkipAll() throws SQLException {
Limit limit = new Limit(true);
Limit limit = new Limit(DatabaseType.MySQL, true);
limit.setOffset(new LimitValue(Integer.MAX_VALUE, -1));
selectStatement.setLimit(limit);
for (ResultSet each : resultSets) {
......@@ -68,7 +69,7 @@ public final class LimitDecoratorResultSetMergerTest {
@Test
public void assertNextWithoutRowCount() throws SQLException {
Limit limit = new Limit(true);
Limit limit = new Limit(DatabaseType.MySQL, true);
limit.setOffset(new LimitValue(2, -1));
selectStatement.setLimit(limit);
for (ResultSet each : resultSets) {
......@@ -87,7 +88,7 @@ public final class LimitDecoratorResultSetMergerTest {
@Test
public void assertNextWithRewriteRowCount() throws SQLException {
Limit limit = new Limit(true);
Limit limit = new Limit(DatabaseType.MySQL, true);
limit.setOffset(new LimitValue(2, -1));
limit.setRowCount(new LimitValue(2, -1));
selectStatement.setLimit(limit);
......@@ -103,9 +104,10 @@ public final class LimitDecoratorResultSetMergerTest {
@Test
public void assertNextWithNotRewriteRowCount() throws SQLException {
Limit limit = new Limit(false);
Limit limit = new Limit(DatabaseType.Oracle, false);
limit.setOffset(new LimitValue(2, -1));
limit.setRowCount(new LimitValue(4, -1));
limit.setIncludeOffset(true);
selectStatement.setLimit(limit);
for (ResultSet each : resultSets) {
when(each.next()).thenReturn(true, true, false);
......
package io.shardingjdbc.core.parsing.parser.jaxb.helper;
import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.constant.ShardingOperator;
import io.shardingjdbc.core.parsing.parser.context.OrderItem;
import io.shardingjdbc.core.parsing.parser.context.condition.Column;
......@@ -156,7 +157,7 @@ public class ParserAssertHelper {
if (null == limit) {
return null;
}
Limit result = new Limit(true);
Limit result = new Limit(DatabaseType.MySQL, true);
if (isPreparedStatement) {
if (null != limit.getOffsetParameterIndex()) {
result.setOffset(new LimitValue(-1, limit.getOffsetParameterIndex()));
......
......@@ -111,7 +111,7 @@ public final class SQLRewriteEngineTest {
@Test
public void assertRewriteForLimit() {
selectStatement.setLimit(new Limit(true));
selectStatement.setLimit(new Limit(DatabaseType.MySQL, true));
selectStatement.getLimit().setOffset(new LimitValue(2, -1));
selectStatement.getLimit().setRowCount(new LimitValue(2, -1));
selectStatement.getSqlTokens().add(new TableToken(17, "table_x"));
......@@ -123,33 +123,33 @@ public final class SQLRewriteEngineTest {
@Test
public void assertRewriteForRowNum() {
selectStatement.setLimit(new Limit(false));
selectStatement.setLimit(new Limit(DatabaseType.Oracle, false));
selectStatement.getLimit().setOffset(new LimitValue(2, -1));
selectStatement.getLimit().setRowCount(new LimitValue(4, -1));
selectStatement.getSqlTokens().add(new TableToken(68, "table_x"));
selectStatement.getSqlTokens().add(new OffsetToken(119, 2));
selectStatement.getSqlTokens().add(new RowCountToken(98, 4));
SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule,
"SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2", DatabaseType.MySQL, selectStatement);
"SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2", DatabaseType.Oracle, selectStatement);
assertThat(rewriteEngine.rewrite(true).toSQL(tableTokens), is("SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_1 x) row_ WHERE rownum<=4) t WHERE t.rownum_>0"));
}
@Test
public void assertRewriteForTopAndRowNumber() {
selectStatement.setLimit(new Limit(false));
selectStatement.setLimit(new Limit(DatabaseType.SQLServer, false));
selectStatement.getLimit().setOffset(new LimitValue(2, -1));
selectStatement.getLimit().setRowCount(new LimitValue(4, -1));
selectStatement.getSqlTokens().add(new TableToken(85, "table_x"));
selectStatement.getSqlTokens().add(new OffsetToken(123, 2));
selectStatement.getSqlTokens().add(new RowCountToken(26, 4));
SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule,
"SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_x x) AS row_ WHERE row_.rownum_>2", DatabaseType.MySQL, selectStatement);
"SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_x x) AS row_ WHERE row_.rownum_>2", DatabaseType.SQLServer, selectStatement);
assertThat(rewriteEngine.rewrite(true).toSQL(tableTokens), is("SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_1 x) AS row_ WHERE row_.rownum_>0"));
}
@Test
public void assertRewriteForLimitForMemoryGroupBy() {
selectStatement.setLimit(new Limit(true));
selectStatement.setLimit(new Limit(DatabaseType.MySQL, true));
selectStatement.getLimit().setOffset(new LimitValue(2, -1));
selectStatement.getLimit().setRowCount(new LimitValue(2, -1));
selectStatement.getOrderByItems().add(new OrderItem("x", "id", OrderType.ASC, OrderType.ASC, Optional.<String>absent()));
......@@ -163,7 +163,7 @@ public final class SQLRewriteEngineTest {
@Test
public void assertRewriteForRowNumForMemoryGroupBy() {
selectStatement.setLimit(new Limit(false));
selectStatement.setLimit(new Limit(DatabaseType.Oracle, false));
selectStatement.getLimit().setOffset(new LimitValue(2, -1));
selectStatement.getLimit().setRowCount(new LimitValue(4, -1));
selectStatement.getSqlTokens().add(new TableToken(68, "table_x"));
......@@ -172,14 +172,14 @@ public final class SQLRewriteEngineTest {
selectStatement.getOrderByItems().add(new OrderItem("x", "id", OrderType.ASC, OrderType.ASC, Optional.<String>absent()));
selectStatement.getGroupByItems().add(new OrderItem("x", "id", OrderType.DESC, OrderType.ASC, Optional.<String>absent()));
SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule,
"SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2", DatabaseType.MySQL, selectStatement);
"SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2", DatabaseType.Oracle, selectStatement);
assertThat(rewriteEngine.rewrite(true).toSQL(tableTokens),
is("SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_1 x) row_ WHERE rownum<=2147483647) t WHERE t.rownum_>0"));
}
@Test
public void assertRewriteForTopAndRowNumberForMemoryGroupBy() {
selectStatement.setLimit(new Limit(false));
selectStatement.setLimit(new Limit(DatabaseType.SQLServer, false));
selectStatement.getLimit().setOffset(new LimitValue(2, -1));
selectStatement.getLimit().setRowCount(new LimitValue(4, -1));
selectStatement.getSqlTokens().add(new TableToken(85, "table_x"));
......@@ -188,14 +188,14 @@ public final class SQLRewriteEngineTest {
selectStatement.getOrderByItems().add(new OrderItem("x", "id", OrderType.ASC, OrderType.ASC, Optional.<String>absent()));
selectStatement.getGroupByItems().add(new OrderItem("x", "id", OrderType.DESC, OrderType.ASC, Optional.<String>absent()));
SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule,
"SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_x x) AS row_ WHERE row_.rownum_>2", DatabaseType.MySQL, selectStatement);
"SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_x x) AS row_ WHERE row_.rownum_>2", DatabaseType.SQLServer, selectStatement);
assertThat(rewriteEngine.rewrite(true).toSQL(tableTokens),
is("SELECT * FROM (SELECT TOP(2147483647) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_1 x) AS row_ WHERE row_.rownum_>0"));
}
@Test
public void assertRewriteForLimitForNotRewriteLimit() {
selectStatement.setLimit(new Limit(true));
selectStatement.setLimit(new Limit(DatabaseType.MySQL, true));
selectStatement.getLimit().setOffset(new LimitValue(2, -1));
selectStatement.getLimit().setRowCount(new LimitValue(2, -1));
selectStatement.getSqlTokens().add(new TableToken(17, "table_x"));
......@@ -207,27 +207,27 @@ public final class SQLRewriteEngineTest {
@Test
public void assertRewriteForRowNumForNotRewriteLimit() {
selectStatement.setLimit(new Limit(false));
selectStatement.setLimit(new Limit(DatabaseType.Oracle, false));
selectStatement.getLimit().setOffset(new LimitValue(2, -1));
selectStatement.getLimit().setRowCount(new LimitValue(4, -1));
selectStatement.getSqlTokens().add(new TableToken(68, "table_x"));
selectStatement.getSqlTokens().add(new OffsetToken(119, 2));
selectStatement.getSqlTokens().add(new RowCountToken(98, 4));
SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule,
"SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2", DatabaseType.MySQL, selectStatement);
"SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_x x) row_ WHERE rownum<=4) t WHERE t.rownum_>2", DatabaseType.Oracle, selectStatement);
assertThat(rewriteEngine.rewrite(false).toSQL(tableTokens), is("SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT x.id FROM table_1 x) row_ WHERE rownum<=4) t WHERE t.rownum_>2"));
}
@Test
public void assertRewriteForTopAndRowNumberForNotRewriteLimit() {
selectStatement.setLimit(new Limit(false));
selectStatement.setLimit(new Limit(DatabaseType.SQLServer, false));
selectStatement.getLimit().setOffset(new LimitValue(2, -1));
selectStatement.getLimit().setRowCount(new LimitValue(4, -1));
selectStatement.getSqlTokens().add(new TableToken(85, "table_x"));
selectStatement.getSqlTokens().add(new OffsetToken(123, 2));
selectStatement.getSqlTokens().add(new RowCountToken(26, 4));
SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule,
"SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_x x) AS row_ WHERE row_.rownum_>2", DatabaseType.MySQL, selectStatement);
"SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_x x) AS row_ WHERE row_.rownum_>2", DatabaseType.SQLServer, selectStatement);
assertThat(rewriteEngine.rewrite(false).toSQL(tableTokens),
is("SELECT * FROM (SELECT TOP(4) row_number() OVER (ORDER BY x.id) AS rownum_, x.id FROM table_1 x) AS row_ WHERE row_.rownum_>2"));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册