inner 1466,1477

This commit is contained in:
yanhuqing666
2021-11-18 13:22:41 +08:00
parent a6e21b16bb
commit 85e5df107b
6 changed files with 78 additions and 49 deletions

View File

@@ -229,7 +229,7 @@ public abstract class BaseHandlerBuilder {
*/
protected void noShardBuild() {
this.needCommon = false;
GlobalVisitor visitor = new GlobalVisitor(node, true);
GlobalVisitor visitor = new GlobalVisitor(node, true, false);
visitor.visit();
String sql = visitor.getSql().toString();
Map<String, String> mapTableToSimple = visitor.getMapTableToSimple();
@@ -555,8 +555,15 @@ public abstract class BaseHandlerBuilder {
Set<String> routeNodes = HandlerBuilder.canRouteToNodes(merges);
if (routeNodes != null && routeNodes.size() > 0) {
this.needCommon = false;
PushDownVisitor visitor = new PushDownVisitor(node, true);
RouteResultset rrs = visitor.buildRouteResultset();
GlobalVisitor visitor = new GlobalVisitor(node, true, true);
visitor.visit();
String sql = visitor.getSql().toString();
Map<String, String> mapTableToSimple = visitor.getMapTableToSimple();
for (Map.Entry<String, String> tableToSimple : mapTableToSimple.entrySet()) {
sql = sql.replace(tableToSimple.getKey(), tableToSimple.getValue());
}
RouteResultset rrs = new RouteResultset(sql, ServerParse.SELECT);
rrs.setStatement(sql);
rrs.setComplexSQL(true);
buildOneMergeHandler(routeNodes, rrs);
return true;
@@ -605,4 +612,13 @@ public abstract class BaseHandlerBuilder {
public PlanNode getNode() {
return node;
}
public boolean isExistView() {
return subQueryBuilderList.stream().anyMatch(BaseHandlerBuilder::isExistView) || node.isExistView();
}
public boolean isContainSubQuery(PlanNode planNode) {
return planNode.getSubQueries().size() > 0 || planNode.getChildren().stream().anyMatch(this::isContainSubQuery);
}
}

View File

@@ -5,6 +5,7 @@
package com.actiontech.dble.backend.mysql.nio.handler.builder;
import com.actiontech.dble.backend.mysql.nio.handler.builder.sqlvisitor.GlobalVisitor;
import com.actiontech.dble.backend.mysql.nio.handler.query.DMLResponseHandler;
import com.actiontech.dble.backend.mysql.nio.handler.query.impl.BaseSelectHandler;
import com.actiontech.dble.backend.mysql.nio.handler.query.impl.MultiNodeEasyMergeHandler;
@@ -13,15 +14,14 @@ import com.actiontech.dble.plan.node.*;
import com.actiontech.dble.route.RouteResultsetNode;
import com.actiontech.dble.route.util.RouterUtil;
import com.actiontech.dble.server.NonBlockingSession;
import com.actiontech.dble.server.parser.ServerParse;
import com.actiontech.dble.services.factorys.FinalHandlerFactory;
import com.actiontech.dble.singleton.TraceManager;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
public class HandlerBuilder {
private static final Logger LOGGER = LoggerFactory.getLogger(HandlerBuilder.class);
@@ -79,7 +79,7 @@ public class HandlerBuilder {
}
}
public String build() throws Exception {
public RouteResultsetNode build() throws Exception {
TraceManager.TraceObject traceObject = TraceManager.serviceTrace(session.getShardingService(), "build&execute-complex-sql");
try {
final long startTime = System.nanoTime();
@@ -98,7 +98,7 @@ public class HandlerBuilder {
if (endHandler.getMerges().size() == 1 && builder.getSubQueryBuilderList().size() == 0) {
RouteResultsetNode[] routes = ((MultiNodeMergeHandler) (endHandler.getMerges().get(0))).getRoute();
if (routes.length == 1) {
return routes[0].getName();
return getRouteResultsetNode(builder, routes[0].getName());
}
}
HandlerBuilder.startHandler(fh);
@@ -112,6 +112,27 @@ public class HandlerBuilder {
return null;
}
private RouteResultsetNode getRouteResultsetNode(BaseHandlerBuilder builder, String nodeName) {
Set<String> tableSet = Sets.newHashSet();
for (RouteResultsetNode routeResultsetNode : rrsNodes) {
Set<String> set = routeResultsetNode.getTableSet();
if (null != set) {
tableSet.addAll(set);
}
}
String sql = node.getSql();
if (builder.isExistView() || builder.isContainSubQuery(node)) {
GlobalVisitor visitor = new GlobalVisitor(node, true, true);
visitor.visit();
sql = visitor.getSql().toString();
Map<String, String> mapTableToSimple = visitor.getMapTableToSimple();
for (Map.Entry<String, String> tableToSimple : mapTableToSimple.entrySet()) {
sql = sql.replace(tableToSimple.getKey(), tableToSimple.getValue());
}
}
return new RouteResultsetNode(nodeName, ServerParse.SELECT, sql, tableSet);
}
/**
* DBLE0REQ-504
* According to the execution plan, judge whether it can be routed to the same node to simplify the query

View File

@@ -29,8 +29,10 @@ import com.actiontech.dble.util.StringUtil;
*/
public class GlobalVisitor extends MysqlVisitor {
public GlobalVisitor(PlanNode globalQuery, boolean isTopQuery) {
private final boolean rebuildSubQuery;
public GlobalVisitor(PlanNode globalQuery, boolean isTopQuery, boolean rebuildSubQuery) {
super(globalQuery, isTopQuery);
this.rebuildSubQuery = rebuildSubQuery;
}
public void visit() {
@@ -118,7 +120,7 @@ public class GlobalVisitor extends MysqlVisitor {
}
sqlBuilder.append('(');
PlanNode child = query.getChild();
MysqlVisitor childVisitor = new GlobalVisitor(child, true);
MysqlVisitor childVisitor = new GlobalVisitor(child, true, rebuildSubQuery);
childVisitor.visit();
mapTableToSimple.putAll(childVisitor.getMapTableToSimple());
sqlBuilder.append(childVisitor.getSql()).append(") ").append(query.getAlias());
@@ -142,7 +144,7 @@ public class GlobalVisitor extends MysqlVisitor {
boolean isUnion = merge.isUnion();
boolean isFirst = true;
for (PlanNode child : merge.getChildren()) {
MysqlVisitor childVisitor = new GlobalVisitor(child, true);
MysqlVisitor childVisitor = new GlobalVisitor(child, true, rebuildSubQuery);
childVisitor.visit();
if (isFirst) {
isFirst = false;
@@ -186,7 +188,7 @@ public class GlobalVisitor extends MysqlVisitor {
}
PlanNode left = join.getLeftNode();
MysqlVisitor leftVisitor = new GlobalVisitor(left, false);
MysqlVisitor leftVisitor = new GlobalVisitor(left, false, rebuildSubQuery);
leftVisitor.visit();
mapTableToSimple.putAll(leftVisitor.getMapTableToSimple());
sqlBuilder.append(leftVisitor.getSql());
@@ -201,7 +203,7 @@ public class GlobalVisitor extends MysqlVisitor {
sqlBuilder.append(" join ");
PlanNode right = join.getRightNode();
MysqlVisitor rightVisitor = new GlobalVisitor(right, false);
MysqlVisitor rightVisitor = new GlobalVisitor(right, false, rebuildSubQuery);
rightVisitor.visit();
mapTableToSimple.putAll(rightVisitor.getMapTableToSimple());
sqlBuilder.append(rightVisitor.getSql());
@@ -328,7 +330,12 @@ public class GlobalVisitor extends MysqlVisitor {
protected String visitPushDownNameSel(Item item) {
String orgPushDownName;
if (item.isWithSubQuery()) {
orgPushDownName = buildSubQueryItem(item, false);
if (rebuildSubQuery) {
Item tmpItem = PlanUtil.rebuildSubQueryItem(item);
orgPushDownName = tmpItem.getItemName();
} else {
orgPushDownName = buildSubQueryItem(item, false);
}
} else {
orgPushDownName = item.getItemName();
}
@@ -364,7 +371,12 @@ public class GlobalVisitor extends MysqlVisitor {
// pushDown's name of not in select list
protected final String visitUnSelPushDownName(Item item, boolean canUseAlias) {
if (item.isWithSubQuery()) {
return buildSubQueryItem(item, canUseAlias);
if (rebuildSubQuery) {
Item tmpItem = PlanUtil.rebuildSubQueryItem(item);
return tmpItem.getItemName();
} else {
return buildSubQueryItem(item, canUseAlias);
}
}
String selName = getItemName(item);
String nameInMap = pushNameMap.get(selName);
@@ -394,7 +406,7 @@ public class GlobalVisitor extends MysqlVisitor {
}
builder.append(" in ");
PlanNode child = inSubItem.getPlanNode();
MysqlVisitor childVisitor = new GlobalVisitor(child, true);
MysqlVisitor childVisitor = new GlobalVisitor(child, true, rebuildSubQuery);
childVisitor.visit();
builder.append("(");
builder.append(childVisitor.getSql());
@@ -409,7 +421,7 @@ public class GlobalVisitor extends MysqlVisitor {
}
builder.append(" exists ");
PlanNode child = existsSubQuery.getPlanNode();
MysqlVisitor childVisitor = new GlobalVisitor(child, true);
MysqlVisitor childVisitor = new GlobalVisitor(child, true, rebuildSubQuery);
childVisitor.visit();
builder.append("(");
builder.append(childVisitor.getSql());
@@ -439,7 +451,7 @@ public class GlobalVisitor extends MysqlVisitor {
private String buildScalarSubQuery(ItemScalarSubQuery item) {
PlanNode child = item.getPlanNode();
MysqlVisitor childVisitor = new GlobalVisitor(child, true);
MysqlVisitor childVisitor = new GlobalVisitor(child, true, rebuildSubQuery);
childVisitor.visit();
mapTableToSimple.putAll(childVisitor.getMapTableToSimple());
return "(" + childVisitor.getSql() + ")";
@@ -464,7 +476,7 @@ public class GlobalVisitor extends MysqlVisitor {
builder.append(" any ");
}
PlanNode child = allAnySubItem.getPlanNode();
MysqlVisitor childVisitor = new GlobalVisitor(child, true);
MysqlVisitor childVisitor = new GlobalVisitor(child, true, rebuildSubQuery);
childVisitor.visit();
builder.append("(");
builder.append(childVisitor.getSql());

View File

@@ -113,7 +113,7 @@ public class PushDownVisitor extends MysqlVisitor {
}
PlanNode left = join.getLeftNode();
MysqlVisitor leftVisitor = new GlobalVisitor(left, false);
MysqlVisitor leftVisitor = new GlobalVisitor(left, false, true);
leftVisitor.visit();
mapTableToSimple.putAll(leftVisitor.getMapTableToSimple());
replaceableSqlBuilder.append(leftVisitor.getSql());
@@ -129,7 +129,7 @@ public class PushDownVisitor extends MysqlVisitor {
sqlBuilder.append(" join ");
PlanNode right = join.getRightNode();
MysqlVisitor rightVisitor = new GlobalVisitor(right, false);
MysqlVisitor rightVisitor = new GlobalVisitor(right, false, true);
rightVisitor.visit();
mapTableToSimple.putAll(rightVisitor.getMapTableToSimple());
replaceableSqlBuilder.append(rightVisitor.getSql());
@@ -156,7 +156,7 @@ public class PushDownVisitor extends MysqlVisitor {
boolean isUnion = merge.isUnion();
boolean isFirst = true;
for (PlanNode child : merge.getChildren()) {
MysqlVisitor childVisitor = new GlobalVisitor(child, true);
MysqlVisitor childVisitor = new GlobalVisitor(child, true, true);
childVisitor.visit();
if (isFirst) {
isFirst = false;

View File

@@ -10,7 +10,6 @@ import com.actiontech.dble.backend.datasource.ShardingNode;
import com.actiontech.dble.backend.mysql.nio.handler.*;
import com.actiontech.dble.backend.mysql.nio.handler.builder.BaseHandlerBuilder;
import com.actiontech.dble.backend.mysql.nio.handler.builder.HandlerBuilder;
import com.actiontech.dble.backend.mysql.nio.handler.builder.sqlvisitor.GlobalVisitor;
import com.actiontech.dble.backend.mysql.nio.handler.query.DMLResponseHandler;
import com.actiontech.dble.backend.mysql.nio.handler.query.impl.OutputHandler;
import com.actiontech.dble.backend.mysql.nio.handler.transaction.ImplicitCommitHandler;
@@ -42,7 +41,6 @@ import com.actiontech.dble.server.status.LoadDataBatch;
import com.actiontech.dble.server.status.SlowQueryLog;
import com.actiontech.dble.server.trace.TraceRecord;
import com.actiontech.dble.server.trace.TraceResult;
import com.actiontech.dble.util.exception.NeedDelayedException;
import com.actiontech.dble.services.mysqlsharding.MySQLResponseService;
import com.actiontech.dble.services.mysqlsharding.ShardingService;
import com.actiontech.dble.singleton.DDLTraceManager;
@@ -52,10 +50,9 @@ import com.actiontech.dble.singleton.TraceManager;
import com.actiontech.dble.statistic.sql.StatisticListener;
import com.actiontech.dble.statistic.stat.QueryTimeCost;
import com.actiontech.dble.statistic.stat.QueryTimeCostContainer;
import com.actiontech.dble.util.StringUtil;
import com.actiontech.dble.util.exception.NeedDelayedException;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -606,26 +603,9 @@ public class NonBlockingSession extends Session {
init();
HandlerBuilder builder = new HandlerBuilder(node, this);
try {
String nodeName = builder.build();
if (!StringUtil.isBlank(nodeName)) {
Set<String> tableSet = Sets.newHashSet();
for (RouteResultsetNode routeResultsetNode : builder.getRrsNodes()) {
Set<String> set = routeResultsetNode.getTableSet();
if (null != set) {
tableSet.addAll(set);
}
}
String sql = node.getSql();
if (node.isExistView()) {
GlobalVisitor visitor = new GlobalVisitor(node, true);
visitor.visit();
sql = visitor.getSql().toString();
Map<String, String> mapTableToSimple = visitor.getMapTableToSimple();
for (Map.Entry<String, String> tableToSimple : mapTableToSimple.entrySet()) {
sql = sql.replace(tableToSimple.getKey(), tableToSimple.getValue());
}
}
RouteResultsetNode[] nodes = {new RouteResultsetNode(nodeName, rrs.getSqlType(), sql, tableSet)};
RouteResultsetNode rrsNode = builder.build();
if (rrsNode != null) {
RouteResultsetNode[] nodes = {rrsNode};
rrs.setNodes(nodes);
setRouteResultToTrace(nodes);
// dml or simple select

View File

@@ -239,8 +239,8 @@ public final class ExplainHandler {
if (!StringUtil.isBlank(routeNode)) {
PlanNode node = builder.getNode();
String sql = node.getSql();
if (node.isExistView()) {
GlobalVisitor visitor = new GlobalVisitor(node, true);
if (builder.isExistView() || builder.isContainSubQuery(node)) {
GlobalVisitor visitor = new GlobalVisitor(node, true, true);
visitor.visit();
sql = visitor.getSql().toString();
Map<String, String> mapTableToSimple = visitor.getMapTableToSimple();