Skip to content

Commit

Permalink
fix #25 OR表达式下会出现重复结果问题
Browse files Browse the repository at this point in the history
  • Loading branch information
hanahmily committed Mar 14, 2016
1 parent b005981 commit 75cdafc
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.dangdang.ddframe.rdb.sharding.api.rule.DataNode;
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule;
import com.dangdang.ddframe.rdb.sharding.exception.SQLParserException;
import com.dangdang.ddframe.rdb.sharding.router.SQLExecutionUnit;
import com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine;
import com.dangdang.ddframe.rdb.sharding.router.SQLRouteResult;
import com.google.common.collect.Lists;
Expand Down Expand Up @@ -61,35 +62,35 @@ public void testLongValueAlgorithm() throws FileNotFoundException, SQLParserExce
SQLRouteEngine engine = new SQLRouteEngine(getShardingRuleBuilder("algorithm").build(), DatabaseType.MySQL);

SQLRouteResult result = engine.route("select * from order1 where order_id = 1", null);
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE order_id = 1"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE order_id = 1"));
result = engine.route("select * from order1 where order_id = ?", Lists.newArrayList((Object) 1));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE order_id = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE order_id = ?"));

result = engine.route("select * from order1 where order_id = '1'", null);
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE order_id = '1'"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE order_id = '1'"));
result = engine.route("select * from order1 where order_id = ?", Lists.newArrayList((Object) "1"));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE order_id = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE order_id = ?"));

result = engine.route("select * from order1 where order_id = ?", Lists.newArrayList((Object) new java.sql.Date(12000111L)));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE order_id = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE order_id = ?"));
}

@Test
public void testDoubleValueAlgorithm() throws FileNotFoundException, SQLParserException {
SQLRouteEngine engine = new SQLRouteEngine(getShardingRuleBuilder("algorithm").build(), DatabaseType.MySQL);

SQLRouteResult result = engine.route("select * from order2 where order_id = 1.11", null);
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE order_id = 1.11"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE order_id = 1.11"));
result = engine.route("select * from order2 where order_id = ?", Lists.newArrayList((Object) 1.11));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE order_id = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE order_id = ?"));

result = engine.route("select * from order2 where order_id = '1.11'", null);
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE order_id = '1.11'"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE order_id = '1.11'"));
result = engine.route("select * from order2 where order_id = ?", Lists.newArrayList((Object) "1.11"));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE order_id = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE order_id = ?"));

result = engine.route("select * from order2 where order_id = ?", Lists.newArrayList((Object) new java.sql.Date(12000111L)));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_0 WHERE order_id = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_0 WHERE order_id = ?"));
}

@Test(expected = UnsupportedOperationException.class)
Expand All @@ -103,13 +104,13 @@ public void testDateValueAlgorithm() throws FileNotFoundException, SQLParserExce
SQLRouteEngine engine = new SQLRouteEngine(getShardingRuleBuilder("algorithm").build(), DatabaseType.MySQL);

SQLRouteResult result = engine.route("select * from order3 where date = ?", Lists.newArrayList((Object) new SimpleDateFormat("yyyyMMdd").parse("20151015")));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_0 WHERE date = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_0 WHERE date = ?"));

result = engine.route("select * from order3 where date = ?", Lists.newArrayList((Object) "20151115"));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE date = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE date = ?"));

result = engine.route("select * from order3 where date = ?", Lists.newArrayList((Object) new SimpleDateFormat("yyyyMMdd").parse("20151015").getTime()));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_0 WHERE date = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_0 WHERE date = ?"));

}

Expand All @@ -118,24 +119,24 @@ public void testDateValueToStringAlgorithm() throws FileNotFoundException, SQLPa
SQLRouteEngine engine = new SQLRouteEngine(getShardingRuleBuilder("algorithm").build(), DatabaseType.MySQL);

SQLRouteResult result = engine.route("select * from order4 where date = ?", Lists.newArrayList((Object) new SimpleDateFormat("yyyyMMdd").parse("20151015")));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_201510 WHERE date = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_201510 WHERE date = ?"));

result = engine.route("select * from order4 where date = ?", Lists.newArrayList((Object) new SimpleDateFormat("yyyyMMdd").parse("20151015").getTime()));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_201510 WHERE date = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_201510 WHERE date = ?"));

result = engine.route("select * from order4 where date = ?", Lists.newArrayList((Object) "201511"));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_201511 WHERE date = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_201511 WHERE date = ?"));
}

@Test
public void testDateValueToDateAlgorithm() throws FileNotFoundException, SQLParserException, ParseException {
SQLRouteEngine engine = new SQLRouteEngine(getShardingRuleBuilder("algorithm").build(), DatabaseType.MySQL);

SQLRouteResult result = engine.route("select * from order5 where date = ?", Lists.newArrayList((Object) new SimpleDateFormat("yyyyMMdd").parse("20151015")));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_0 WHERE date = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_0 WHERE date = ?"));

result = engine.route("select * from order5 where date = ?", Lists.newArrayList((Object) new SimpleDateFormat("yyyyMMdd").parse("20151015").getTime()));
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_0 WHERE date = ?"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_0 WHERE date = ?"));

}

Expand All @@ -144,7 +145,7 @@ public void testInValueAlgorithm() throws FileNotFoundException, SQLParserExcept
SQLRouteEngine engine = new SQLRouteEngine(getShardingRuleBuilder("algorithm").build(), DatabaseType.MySQL);

SQLRouteResult result = engine.route("select * from order1 where order_id in (1,3)", null);
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 WHERE order_id IN (1, 3)"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 WHERE order_id IN (1, 3)"));
}

@Test(expected = UnsupportedOperationException.class)
Expand All @@ -169,29 +170,28 @@ public void testUnsupportedDateValueToDateAlgorithm() throws FileNotFoundExcepti
public void testNullRouteResult() throws FileNotFoundException, SQLParserException, ParseException {
SQLRouteEngine engine = new SQLRouteEngine(getShardingRuleBuilder("algorithm").build(), DatabaseType.MySQL);
SQLRouteResult result = engine.route("select * from order6 where order_id = 1", null);
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_0 WHERE order_id = 1"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_0 WHERE order_id = 1"));
}

@Test
public void testDefaultStrategy() throws SQLParserException, FileNotFoundException {
SQLRouteEngine engine = new SQLRouteEngine(getShardingRuleBuilder("defaultStrategy").build(), DatabaseType.MySQL);
SQLRouteResult result = engine.route("select * from order1 where order_id = 1", null);
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_0 WHERE order_id = 1"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_0 WHERE order_id = 1"));
}

@Test
public void testBindingTable() {
SQLRouteEngine engine = new SQLRouteEngine(getShardingRuleBuilder("binding_table").build(), DatabaseType.MySQL);
SQLRouteResult result = engine.route("select * from t_order o ,t_order_item i where o.order_id = i.order_id and o.order_id = 11", null);
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_1 o, t_order_item_1 i WHERE o.order_id = i.order_id AND o.order_id = 11"));
assertThat(result.getExecutionUnits().iterator().next().getSql(), is("SELECT * FROM t_order_1 o, t_order_item_1 i WHERE o.order_id = i.order_id AND o.order_id = 11"));
}

@Test
public void testReturnMultiResult() {
SQLRouteEngine engine = new SQLRouteEngine(getShardingRuleBuilder("algorithm").build(), DatabaseType.MySQL);
SQLRouteResult result = engine.route("select * from order7 o where o.order_id = 1", null);
assertThat(result.getExecutionUnits().get(0).getSql(), is("SELECT * FROM t_order_0 o WHERE o.order_id = 1"));
assertThat(result.getExecutionUnits().get(1).getSql(), is("SELECT * FROM t_order_1 o WHERE o.order_id = 1"));
assertThat(result.getExecutionUnits(), hasItems(new SQLExecutionUnit("db0", "SELECT * FROM t_order_0 o WHERE o.order_id = 1"), new SQLExecutionUnit("db0", "SELECT * FROM t_order_1 o WHERE o.order_id = 1")));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.dangdang.ddframe.rdb.sharding.router;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -29,6 +30,7 @@
@Getter
@Slf4j
@ToString
@EqualsAndHashCode
public class SQLExecutionUnit {

private final String dataSource;
Expand All @@ -38,6 +40,6 @@ public class SQLExecutionUnit {
public SQLExecutionUnit(final String dataSource, final String sql) {
this.dataSource = dataSource;
this.sql = sql;
log.debug("route sql to db: [{}] sql: [{}]", dataSource, sql);
log.trace("route sql to db: [{}] sql: [{}]", dataSource, sql);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
* SQL路由引擎.
*
* @author gaohongtao, zhangiang
*/
@RequiredArgsConstructor
@Slf4j
public final class SQLRouteEngine {

private final ShardingRule shardingRule;
Expand Down Expand Up @@ -82,6 +84,8 @@ public String apply(final Table input) {
}), parsedResult.getRouteContext().getSqlBuilder(), parsedResult.getRouteContext().getSqlStatementType()));
}
MetricsContext.stop(context);
log.debug("final route result:{}", result.getExecutionUnits());
log.debug("merge context:{}", result.getMergeContext());
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@

package com.dangdang.ddframe.rdb.sharding.router;

import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Set;

import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

Expand All @@ -36,5 +35,5 @@ public final class SQLRouteResult {

private final MergeContext mergeContext;

private final List<SQLExecutionUnit> executionUnits = new ArrayList<>();
private final Set<SQLExecutionUnit> executionUnits = new HashSet<>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@

package com.dangdang.ddframe.rdb.sharding.router;

import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
Expand All @@ -29,11 +25,8 @@
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.sql.DataSource;

import org.junit.Before;

import com.dangdang.ddframe.rdb.sharding.api.DatabaseType;
import com.dangdang.ddframe.rdb.sharding.api.rule.BindingTableRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
Expand All @@ -45,10 +38,15 @@
import com.dangdang.ddframe.rdb.sharding.router.fixture.OrderAttrShardingAlgorithm;
import com.dangdang.ddframe.rdb.sharding.router.fixture.OrderShardingAlgorithm;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;

import lombok.AccessLevel;
import lombok.Getter;
import org.junit.Before;

import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public abstract class AbstractBaseRouteSqlTest {

Expand Down Expand Up @@ -87,15 +85,15 @@ protected void assertMultipleTargets(final String originSql, final List<Object>
final Collection<String> targetDataSources, final Collection<String> targetSQLs) throws SQLParserException {
SQLRouteResult actual = new SQLRouteEngine(getShardingRule(), DatabaseType.MySQL).route(originSql, parameters);
assertThat(actual.getExecutionUnits().size(), is(expectedSize));
Set<String> actualDdataSources = new HashSet<String>(Lists.transform(actual.getExecutionUnits(), new Function<SQLExecutionUnit, String>() {
Set<String> actualDdataSources = new HashSet<>(Collections2.transform(actual.getExecutionUnits(), new Function<SQLExecutionUnit, String>() {

@Override
public String apply(final SQLExecutionUnit input) {
return input.getDataSource();
}
}));
assertThat(actualDdataSources, hasItems(targetDataSources.toArray(new String[0])));
List<String> actualSQLs = Lists.transform(actual.getExecutionUnits(), new Function<SQLExecutionUnit, String>() {
Collection<String> actualSQLs = Collections2.transform(actual.getExecutionUnits(), new Function<SQLExecutionUnit, String>() {

@Override
public String apply(final SQLExecutionUnit input) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,23 @@ public void assertSelectWithIn() throws SQLParserException {
Arrays.asList("ds_0", "ds_1"), Arrays.asList("SELECT * FROM order_0", "SELECT * FROM order_1"));
}

@Test
public void assertSelectWithInAndIntersection() throws SQLParserException {
assertMultipleTargets("select * from order where order_id in (?,?) or order_id in (?,?)", Arrays.<Object>asList(1, 2, 100, 2), 4,
Arrays.asList("ds_0", "ds_1"), Arrays.asList("SELECT * FROM order_1 WHERE order_id IN (?, ?) OR order_id IN (?, ?)", "SELECT * FROM order_1 WHERE order_id IN (?, ?) OR order_id IN (?, ?)"));
}

@Test
public void assertSelectWithBetween() throws SQLParserException {
assertMultipleTargets("select * from order where order_id between ? and ?", Arrays.<Object>asList(1, 100), 4,
Arrays.asList("ds_0", "ds_1"), Arrays.asList("SELECT * FROM order_0 WHERE order_id BETWEEN ? AND ?", "SELECT * FROM order_1 WHERE order_id BETWEEN ? AND ?"));
assertMultipleTargets(Lists.newArrayList(new ShardingValuePair("order", Condition.BinaryOperator.BETWEEN, 1, 100)), "select * from order", 4,
Arrays.asList("ds_0", "ds_1"), Arrays.asList("SELECT * FROM order_0", "SELECT * FROM order_1"));
}

@Test
public void assertSelectWithBetweenAndIntersection() throws SQLParserException {
assertMultipleTargets("select * from order where order_id between ? and ? or order_id between ? and ? ", Arrays.<Object>asList(1, 50, 29, 100), 4,
Arrays.asList("ds_0", "ds_1"), Arrays.asList("SELECT * FROM order_0 WHERE order_id BETWEEN ? AND ? OR order_id BETWEEN ? AND ?", "SELECT * FROM order_1 WHERE order_id BETWEEN ? AND ? OR order_id BETWEEN ? AND ?"));
}
}

0 comments on commit 75cdafc

Please sign in to comment.