mirror of
https://github.com/actiontech/dble.git
synced 2026-01-05 20:30:40 -06:00
[inner-2320] fix: shardingTable can direct route only when the rules and nodes are the same
globalTable nodes are the same, they can be direct route
This commit is contained in:
@@ -12,6 +12,7 @@ import com.actiontech.dble.config.ErrorCode;
|
||||
import com.actiontech.dble.config.model.SystemConfig;
|
||||
import com.actiontech.dble.config.model.sharding.SchemaConfig;
|
||||
import com.actiontech.dble.config.model.sharding.table.BaseTableConfig;
|
||||
import com.actiontech.dble.config.model.sharding.table.ChildTableConfig;
|
||||
import com.actiontech.dble.config.model.sharding.table.GlobalTableConfig;
|
||||
import com.actiontech.dble.config.model.sharding.table.ShardingTableConfig;
|
||||
import com.actiontech.dble.config.privileges.ShardingPrivileges;
|
||||
@@ -240,56 +241,68 @@ public class DruidSelectParser extends DefaultDruidParser {
|
||||
}
|
||||
|
||||
List<Pair<String, String>> tables = ctx.getTables();
|
||||
int index = 0;
|
||||
AbstractPartitionAlgorithm firstRule = null;
|
||||
boolean directRoute = true;
|
||||
Set<String> firstDataNodes = new HashSet<>();
|
||||
Map<String, BaseTableConfig> tableConfigMap = schemaConfig.getTables() == null ? null : schemaConfig.getTables();
|
||||
|
||||
if (tableConfigMap != null) {
|
||||
for (Pair<String, String> table : tables) {
|
||||
String tableName = table.getValue();
|
||||
BaseTableConfig tc = tableConfigMap.get(tableName);
|
||||
if (tc == null) {
|
||||
Map<String, String> tableAliasMap = ctx.getTableAliasMap();
|
||||
if (tableAliasMap != null && tableAliasMap.get(tableName) != null) {
|
||||
tc = tableConfigMap.get(tableAliasMap.get(tableName));
|
||||
}
|
||||
}
|
||||
|
||||
if (index == 0) {
|
||||
if (tc != null) {
|
||||
if (!(tc instanceof ShardingTableConfig)) {
|
||||
continue;
|
||||
}
|
||||
firstRule = ((ShardingTableConfig) tc).getFunction();
|
||||
firstDataNodes.addAll(tc.getShardingNodes());
|
||||
}
|
||||
} else {
|
||||
if (tc != null) {
|
||||
if (!(tc instanceof ShardingTableConfig)) {
|
||||
continue;
|
||||
}
|
||||
AbstractPartitionAlgorithm ruleCfg = ((ShardingTableConfig) tc).getFunction();
|
||||
Set<String> dataNodes = new HashSet<>(tc.getShardingNodes());
|
||||
if (firstRule != null && ((!ruleCfg.equals(firstRule)) || !dataNodes.equals(firstDataNodes))) {
|
||||
directRoute = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
RouteResultset rrsResult = rrs;
|
||||
if (directRoute) {
|
||||
if (canDirectRoute(tables, tableConfigMap)) {
|
||||
rrs.setStatement(RouterUtil.removeSchema(rrs.getStatement(), schemaConfig.getName()));
|
||||
rrsResult = tryRoute(schemaConfig, rrs);
|
||||
}
|
||||
return rrsResult;
|
||||
}
|
||||
|
||||
private boolean canDirectRoute(List<Pair<String, String>> tables, Map<String, BaseTableConfig> tableConfigMap) {
|
||||
if (CollectionUtil.isEmpty(tableConfigMap) || CollectionUtil.isEmpty(tables)) {
|
||||
return true;
|
||||
}
|
||||
boolean directRoute = true;
|
||||
AbstractPartitionAlgorithm firstRule = null;
|
||||
Set<String> firstShardingDataNodes = null;
|
||||
for (Pair<String, String> table : tables) {
|
||||
String tableName = table.getValue();
|
||||
BaseTableConfig tc = tableConfigMap.get(tableName);
|
||||
if (tc == null) {
|
||||
Map<String, String> tableAliasMap = ctx.getTableAliasMap();
|
||||
if (tableAliasMap != null && tableAliasMap.get(tableName) != null) {
|
||||
tc = tableConfigMap.get(tableAliasMap.get(tableName));
|
||||
}
|
||||
}
|
||||
if (tc != null) {
|
||||
AbstractPartitionAlgorithm ruleCfg = null;
|
||||
Set<String> dataNodes;
|
||||
if (tc instanceof ShardingTableConfig) {
|
||||
ruleCfg = ((ShardingTableConfig) tc).getFunction();
|
||||
dataNodes = new HashSet<>(tc.getShardingNodes());
|
||||
} else if (tc instanceof ChildTableConfig) {
|
||||
ruleCfg = ((ChildTableConfig) tc).getDirectRouteTC().getFunction();
|
||||
dataNodes = new HashSet<>(tc.getShardingNodes());
|
||||
} else if (tc instanceof GlobalTableConfig) {
|
||||
dataNodes = new HashSet<>(tc.getShardingNodes());
|
||||
} else {
|
||||
directRoute = false;
|
||||
break;
|
||||
}
|
||||
if (firstRule == null && ruleCfg != null) {
|
||||
firstRule = ruleCfg;
|
||||
}
|
||||
if (firstShardingDataNodes == null) {
|
||||
firstShardingDataNodes = dataNodes;
|
||||
}
|
||||
|
||||
if (firstRule != null && ruleCfg != null && ((!ruleCfg.equals(firstRule)) || !dataNodes.equals(firstShardingDataNodes))) {
|
||||
//sharding/child
|
||||
directRoute = false;
|
||||
break;
|
||||
} else if ((firstRule == null || ruleCfg == null) && !dataNodes.equals(firstShardingDataNodes)) {
|
||||
//global
|
||||
directRoute = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return directRoute;
|
||||
}
|
||||
|
||||
private RouteResultset tryRoute(SchemaConfig schema, RouteResultset rrs) throws SQLException {
|
||||
if ((ctx.getTables() == null || ctx.getTables().size() == 0) && (ctx.getTableAliasMap() == null || ctx.getTableAliasMap().isEmpty())) {
|
||||
rrs = RouterUtil.routeToSingleNode(rrs, schema.getRandomShardingNode(), null);
|
||||
|
||||
Reference in New Issue
Block a user