diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/MergeEngine.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/MergeEngine.java index a98f7ac7cab68..eee02eb14b0df 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/MergeEngine.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/MergeEngine.java @@ -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 @@ private ResultSetMerger build() throws SQLException { } 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; } } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/limit/LimitDecoratorResultSetMerger.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/limit/LimitDecoratorResultSetMerger.java index 7fc2173f62ba8..ee470f2ea4c64 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/limit/LimitDecoratorResultSetMerger.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/limit/LimitDecoratorResultSetMerger.java @@ -24,7 +24,7 @@ import java.sql.SQLException; /** - * Decorator merger for limit. + * Decorator merger for limit pagination. * * @author zhangliang */ @@ -57,9 +57,9 @@ public boolean next() throws SQLException { 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(); } } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/limit/RowNumberDecoratorResultSetMerger.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/limit/RowNumberDecoratorResultSetMerger.java new file mode 100644 index 0000000000000..fddd149f9dcf1 --- /dev/null +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/limit/RowNumberDecoratorResultSetMerger.java @@ -0,0 +1,69 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * 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. + *

+ */ + +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(); + } +} diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/limit/TopAndRowNumberDecoratorResultSetMerger.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/limit/TopAndRowNumberDecoratorResultSetMerger.java new file mode 100644 index 0000000000000..61595232df9fc --- /dev/null +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/merger/limit/TopAndRowNumberDecoratorResultSetMerger.java @@ -0,0 +1,66 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * 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. + *

+ */ + +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(); + } +} diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/clause/WhereClauseParser.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/clause/WhereClauseParser.java index 987501c5d46ec..03949c160d61c 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/clause/WhereClauseParser.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/clause/WhereClauseParser.java @@ -1,5 +1,6 @@ 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 @@ */ 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 @@ private void parseComparisonCondition(final ShardingRule shardingRule, final SQL 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 @@ protected boolean isRowNumberCondition(final List items, final Strin 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 @@ private void parseRowCountCondition(final SelectStatement selectStatement) { } 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 @@ private void parseOffsetCondition(final SelectStatement selectStatement) { } else if (sqlExpression instanceof SQLPlaceholderExpression) { selectStatement.getLimit().setOffset(new LimitValue(-1, ((SQLPlaceholderExpression) sqlExpression).getIndex())); } + selectStatement.getLimit().setIncludeOffset(includeOffset); } protected Keyword[] getCustomizedOtherConditionOperators() { diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/context/limit/Limit.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/context/limit/Limit.java index f07db9e0c217e..457640d858538 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/context/limit/Limit.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/context/limit/Limit.java @@ -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 @@ @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. * diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/MySQLLimitClauseParser.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/MySQLLimitClauseParser.java index 7d9290d46fb80..b63e9592b88fd 100755 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/MySQLLimitClauseParser.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/MySQLLimitClauseParser.java @@ -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 void parse(final SelectStatement selectStatement) { 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 @@ private Limit getLimitWithComma(final int index, final int valueBeginPosition, f 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 @@ private Limit getLimitWithOffset(final int index, final int valueBeginPosition, 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; } } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/MySQLWhereClauseParser.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/MySQLWhereClauseParser.java index 4b14e75dcee9b..9028b69d3bbe1 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/MySQLWhereClauseParser.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/MySQLWhereClauseParser.java @@ -1,5 +1,6 @@ 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 @@ public final class MySQLWhereClauseParser extends WhereClauseParser { public MySQLWhereClauseParser(final LexerEngine lexerEngine) { - super(lexerEngine); + super(DatabaseType.MySQL, lexerEngine); } @Override diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/facade/MySQLSelectClauseParserFacade.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/facade/MySQLSelectClauseParserFacade.java index 87ba98f14a42e..d8a0dd2847afc 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/facade/MySQLSelectClauseParserFacade.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/mysql/clause/facade/MySQLSelectClauseParserFacade.java @@ -1,6 +1,5 @@ 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.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. diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/oracle/clause/OracleWhereClauseParser.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/oracle/clause/OracleWhereClauseParser.java index 6987541cf0777..df8df6e04037b 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/oracle/clause/OracleWhereClauseParser.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/oracle/clause/OracleWhereClauseParser.java @@ -1,5 +1,6 @@ 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 @@ public final class OracleWhereClauseParser extends WhereClauseParser { public OracleWhereClauseParser(final LexerEngine lexerEngine) { - super(lexerEngine); + super(DatabaseType.Oracle, lexerEngine); } @Override diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/oracle/clause/facade/OracleSelectClauseParserFacade.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/oracle/clause/facade/OracleSelectClauseParserFacade.java index 081483b592f21..6aeaedc5f02ef 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/oracle/clause/facade/OracleSelectClauseParserFacade.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/oracle/clause/facade/OracleSelectClauseParserFacade.java @@ -1,16 +1,16 @@ 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. diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/PostgreSQLLimitClauseParser.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/PostgreSQLLimitClauseParser.java index 7c76732c57fe1..d8303979c8df3 100755 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/PostgreSQLLimitClauseParser.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/PostgreSQLLimitClauseParser.java @@ -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 @@ private Optional buildOffset(final SelectStatement selectStatement) } private void setLimit(final Optional offset, final Optional 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); } } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLDeleteClauseParserFacade.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLDeleteClauseParserFacade.java index 73aceec14c01b..17902325efa16 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLDeleteClauseParserFacade.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLDeleteClauseParserFacade.java @@ -1,5 +1,6 @@ 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 @@ 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)); } } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLSelectClauseParserFacade.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLSelectClauseParserFacade.java index a113835a35737..e5325fe157caf 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLSelectClauseParserFacade.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLSelectClauseParserFacade.java @@ -1,5 +1,6 @@ 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)); } } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLUpdateClauseParserFacade.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLUpdateClauseParserFacade.java index 416bc6fef12af..cd66a014d65e1 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLUpdateClauseParserFacade.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/postgresql/clause/facade/PostgreSQLUpdateClauseParserFacade.java @@ -1,5 +1,6 @@ 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 @@ 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)); } } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerOffsetClauseParser.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerOffsetClauseParser.java index 25ed529b4fc7c..8d9781477b5b7 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerOffsetClauseParser.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerOffsetClauseParser.java @@ -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 void parse(final SelectStatement selectStatement) { 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; diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerTopClauseParser.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerTopClauseParser.java index 1effc3dfcac49..6684639ef6525 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerTopClauseParser.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerTopClauseParser.java @@ -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 void parse(final SelectStatement selectStatement) { 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 { diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerWhereClauseParser.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerWhereClauseParser.java index 8fac40e1eea16..f489849d7357b 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerWhereClauseParser.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/SQLServerWhereClauseParser.java @@ -1,5 +1,6 @@ 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 @@ public final class SQLServerWhereClauseParser extends WhereClauseParser { public SQLServerWhereClauseParser(final LexerEngine lexerEngine) { - super(lexerEngine); + super(DatabaseType.SQLServer, lexerEngine); } @Override diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/facade/SQLServerSelectClauseParserFacade.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/facade/SQLServerSelectClauseParserFacade.java index 8bc9f0c871dd2..3e42d283f8e42 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/facade/SQLServerSelectClauseParserFacade.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/dialect/sqlserver/clause/facade/SQLServerSelectClauseParserFacade.java @@ -1,6 +1,5 @@ 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.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. diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/sql/dql/select/SelectStatement.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/sql/dql/select/SelectStatement.java index d4b72cbdb763d..9564569ad6d7b 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/sql/dql/select/SelectStatement.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/parsing/parser/sql/dql/select/SelectStatement.java @@ -201,6 +201,8 @@ private SelectStatement processLimitForSubQuery() { 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); diff --git a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/merger/MergeEngineTest.java b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/merger/MergeEngineTest.java index fcafeff484cfe..3da77218a7e36 100644 --- a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/merger/MergeEngineTest.java +++ b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/merger/MergeEngineTest.java @@ -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 void assertBuildIteratorStreamResultSetMerger() throws SQLException { @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 void assertBuildOrderByStreamResultSetMerger() throws SQLException { @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 void assertBuildGroupByStreamResultSetMerger() throws SQLException { @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 void assertBuildGroupByMemoryResultSetMerger() throws SQLException { @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 void assertBuildGroupByMemoryResultSetMergerWithAggregationOnly() throws @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.absent())); mergeEngine = new MergeEngine(resultSets, selectStatement); ResultSetMerger actual = mergeEngine.merge(); diff --git a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/merger/limit/LimitDecoratorResultSetMergerTest.java b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/merger/limit/LimitDecoratorResultSetMergerTest.java index 3a8bbc9da8c44..4786dfbc1a37d 100644 --- a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/merger/limit/LimitDecoratorResultSetMergerTest.java +++ b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/merger/limit/LimitDecoratorResultSetMergerTest.java @@ -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 void setUp() throws SQLException { @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 void assertNextForSkipAll() throws SQLException { @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 void assertNextWithoutRowCount() throws SQLException { @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 void assertNextWithRewriteRowCount() throws SQLException { @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); diff --git a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/parsing/parser/jaxb/helper/ParserAssertHelper.java b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/parsing/parser/jaxb/helper/ParserAssertHelper.java index d15b8fa24b8fc..a7932b7ec0b6f 100644 --- a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/parsing/parser/jaxb/helper/ParserAssertHelper.java +++ b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/parsing/parser/jaxb/helper/ParserAssertHelper.java @@ -1,5 +1,6 @@ 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 @@ private static Limit buildExpectedLimit(final io.shardingjdbc.core.parsing.parse 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())); diff --git a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/rewrite/SQLRewriteEngineTest.java b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/rewrite/SQLRewriteEngineTest.java index ecdbaf2941be9..6150bcc6ca71b 100644 --- a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/rewrite/SQLRewriteEngineTest.java +++ b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/rewrite/SQLRewriteEngineTest.java @@ -111,7 +111,7 @@ public void assertRewriteForAutoGeneratedKeyColumn() { @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 void assertRewriteForLimit() { @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.absent())); @@ -163,7 +163,7 @@ public void assertRewriteForLimitForMemoryGroupBy() { @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 void assertRewriteForRowNumForMemoryGroupBy() { selectStatement.getOrderByItems().add(new OrderItem("x", "id", OrderType.ASC, OrderType.ASC, Optional.absent())); selectStatement.getGroupByItems().add(new OrderItem("x", "id", OrderType.DESC, OrderType.ASC, Optional.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 void assertRewriteForTopAndRowNumberForMemoryGroupBy() { selectStatement.getOrderByItems().add(new OrderItem("x", "id", OrderType.ASC, OrderType.ASC, Optional.absent())); selectStatement.getGroupByItems().add(new OrderItem("x", "id", OrderType.DESC, OrderType.ASC, Optional.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 void assertRewriteForLimitForNotRewriteLimit() { @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")); }