diff --git a/src/main/java/com/actiontech/dble/backend/mysql/nio/MySQLConnection.java b/src/main/java/com/actiontech/dble/backend/mysql/nio/MySQLConnection.java index 9fe961bed..42f05cc12 100644 --- a/src/main/java/com/actiontech/dble/backend/mysql/nio/MySQLConnection.java +++ b/src/main/java/com/actiontech/dble/backend/mysql/nio/MySQLConnection.java @@ -18,8 +18,8 @@ import com.actiontech.dble.route.RouteResultsetNode; import com.actiontech.dble.route.parser.util.Pair; import com.actiontech.dble.server.NonBlockingSession; import com.actiontech.dble.server.ServerConnection; -import com.actiontech.dble.server.variables.SystemVariables; import com.actiontech.dble.server.parser.ServerParse; +import com.actiontech.dble.server.variables.SystemVariables; import com.actiontech.dble.util.StringUtil; import com.actiontech.dble.util.TimeUtil; import com.actiontech.dble.util.exception.UnknownTxIsolationException; @@ -429,6 +429,11 @@ public class MySQLConnection extends BackendAIOConnection { //tmp now = backend -(backend &&frontend) for (Map.Entry entry : tmpSysVars.entrySet()) { String value = SystemVariables.getSysVars().getDefaultValue(entry.getKey()); + try { + Long.parseLong(value); + } catch (NumberFormatException e) { + value = "`" + value + "`"; + } setVars.add(new Pair<>(entry.getKey(), value)); toResetSys.add(entry.getKey()); } diff --git a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/NewConnectionRespHandler.java b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/NewConnectionRespHandler.java index 324a8ca4a..5d6e3ae27 100644 --- a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/NewConnectionRespHandler.java +++ b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/NewConnectionRespHandler.java @@ -11,6 +11,7 @@ import com.actiontech.dble.net.mysql.RowDataPacket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.List; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; @@ -21,16 +22,19 @@ public class NewConnectionRespHandler implements ResponseHandler { private ReentrantLock lock = new ReentrantLock(); private Condition initiated = lock.newCondition(); - public BackendConnection getBackConn() { + public BackendConnection getBackConn() throws IOException { lock.lock(); try { - while (backConn == null) { + if (backConn == null) { initiated.await(); } + if (backConn == null) { + throw new IOException("get backend connection error "); + } return backConn; } catch (InterruptedException e) { LOGGER.warn("getBackConn " + e); - return null; + throw new IOException(e.getMessage()); } finally { lock.unlock(); } @@ -39,7 +43,12 @@ public class NewConnectionRespHandler implements ResponseHandler { @Override public void connectionError(Throwable e, BackendConnection conn) { LOGGER.warn(conn + " connectionError " + e); - + lock.lock(); + try { + initiated.signal(); + } finally { + lock.unlock(); + } } @Override diff --git a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/GlobalVisitor.java b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/GlobalVisitor.java index 549371f1e..087204ea4 100644 --- a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/GlobalVisitor.java +++ b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/GlobalVisitor.java @@ -74,6 +74,8 @@ public class GlobalVisitor extends MysqlVisitor { buildHaving(query); buildOrderBy(query); buildLimit(query); + } else { + whereFilter = query.getWhereFilter(); } if (query.isSubQuery() && !parentIsQuery && !isTopQuery) { @@ -146,10 +148,9 @@ public class GlobalVisitor extends MysqlVisitor { if (!isTopQuery) { sqlBuilder.append(" ( "); } - if (join.isSubQuery() || isTopQuery) { - buildSelect(join); - sqlBuilder.append(" from "); - } + + buildSelect(join); + sqlBuilder.append(" from "); PlanNode left = join.getLeftNode(); MysqlVisitor leftVisitor = new GlobalVisitor(left, false); @@ -182,31 +183,27 @@ public class GlobalVisitor extends MysqlVisitor { } if (join.getOtherJoinOnFilter() != null) { - if (first) { - first = false; - } else { + if (!first) { joinOnFilterStr.append(" and "); } joinOnFilterStr.append(join.getOtherJoinOnFilter()); } sqlBuilder.append(joinOnFilterStr.toString()); - if (join.isSubQuery() || isTopQuery) { - buildWhere(join); - buildGroupBy(join); - buildHaving(join); - buildOrderBy(join); - buildLimit(join); - } + buildWhere(join); + buildGroupBy(join); + buildHaving(join); + buildOrderBy(join); + buildLimit(join); if (!isTopQuery) { sqlBuilder.append(" ) "); if (join.getAlias() != null) sqlBuilder.append(" ").append(join.getAlias()).append(" "); } - } + protected void buildSelect(PlanNode query) { sqlBuilder.append("select "); boolean hasDistinct = query.isDistinct(); diff --git a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/MysqlVisitor.java b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/MysqlVisitor.java index 58f4df5a0..b5adbaeac 100644 --- a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/MysqlVisitor.java +++ b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/MysqlVisitor.java @@ -40,8 +40,7 @@ public abstract class MysqlVisitor { // tmp sql protected StringBuilder sqlBuilder; protected StringPtr replaceableWhere = new StringPtr(""); - - + protected Item whereFilter = null; public MysqlVisitor(PlanNode query, boolean isTopQuery) { this.query = query; this.isTopQuery = isTopQuery; @@ -89,6 +88,7 @@ public abstract class MysqlVisitor { String pdName = visitUnSelPushDownName(filter, false); whereBuilder.append(" where ").append(pdName); } + replaceableWhere.set(whereBuilder.toString()); // refresh sqlbuilder sqlBuilder = replaceableSqlBuilder.getCurrentElement().getSb(); @@ -125,4 +125,9 @@ public abstract class MysqlVisitor { } return selName; } + + public Item getWhereFilter() { + return whereFilter; + } + } diff --git a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/PushDownVisitor.java b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/PushDownVisitor.java index db5e375c6..42ffb4d8d 100644 --- a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/PushDownVisitor.java +++ b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/builder/sqlvisitor/PushDownVisitor.java @@ -112,29 +112,10 @@ public class PushDownVisitor extends MysqlVisitor { rightVisitor.visit(); replaceableSqlBuilder.append(rightVisitor.getSql()); sqlBuilder = replaceableSqlBuilder.getCurrentElement().getSb(); - StringBuilder joinOnFilterStr = new StringBuilder(); - boolean first = true; - for (int i = 0; i < join.getJoinFilter().size(); i++) { - Item filter = join.getJoinFilter().get(i); - if (first) { - sqlBuilder.append(" on "); - first = false; - } else - joinOnFilterStr.append(" and "); - joinOnFilterStr.append(filter); - } - - if (join.getOtherJoinOnFilter() != null) { - if (first) { - first = false; - } else { - joinOnFilterStr.append(" and "); - } - joinOnFilterStr.append(join.getOtherJoinOnFilter()); - } + StringBuilder joinOnFilterStr = getJoinOn(join, leftVisitor, rightVisitor); sqlBuilder.append(joinOnFilterStr.toString()); if (join.isSubQuery() || isTopQuery) { - buildWhere(join); + buildWhere(join, leftVisitor.getWhereFilter(), rightVisitor.getWhereFilter()); buildGroupBy(join); // having may contains aggregate function, so it need to calc by middle-ware buildOrderBy(join); @@ -149,6 +130,75 @@ public class PushDownVisitor extends MysqlVisitor { } + private StringBuilder getJoinOn(JoinNode join, MysqlVisitor leftVisitor, MysqlVisitor rightVisitor) { + StringBuilder joinOnFilterStr = new StringBuilder(); + boolean first = true; + for (int i = 0; i < join.getJoinFilter().size(); i++) { + Item filter = join.getJoinFilter().get(i); + if (first) { + sqlBuilder.append(" on "); + first = false; + } else + joinOnFilterStr.append(" and "); + joinOnFilterStr.append(filter); + } + + if (join.getOtherJoinOnFilter() != null) { + if (!first) { + joinOnFilterStr.append(" and "); + } + joinOnFilterStr.append(join.getOtherJoinOnFilter()); + } + // is not left join + if (leftVisitor.getWhereFilter() != null && !join.getLeftOuter()) { + if (!first) { + joinOnFilterStr.append(" and "); + } + joinOnFilterStr.append("("); + joinOnFilterStr.append(leftVisitor.getWhereFilter()); + joinOnFilterStr.append(")"); + } + // is not right join + if (rightVisitor.getWhereFilter() != null && !join.getRightOuter()) { + if (!first) { + joinOnFilterStr.append(" and "); + } + joinOnFilterStr.append("("); + joinOnFilterStr.append(rightVisitor.getWhereFilter()); + joinOnFilterStr.append(")"); + } + return joinOnFilterStr; + } + + protected void buildWhere(JoinNode planNode, Item leftFilter, Item rightFilter) { + if (!visited) + replaceableSqlBuilder.getCurrentElement().setRepString(replaceableWhere); + StringBuilder whereBuilder = new StringBuilder(); + Item filter = planNode.getWhereFilter(); + if (filter != null) { + String pdName = visitUnSelPushDownName(filter, false); + whereBuilder.append(" where ").append(pdName); + } else { + whereBuilder.append(" where 1=1 "); + } + // left join + if (leftFilter != null && !planNode.getRightOuter() && planNode.getLeftOuter()) { + String pdName = visitUnSelPushDownName(leftFilter, false); + whereBuilder.append(" and ("); + whereBuilder.append(pdName); + whereBuilder.append(")"); + } + //right join + if (rightFilter != null && !planNode.getLeftOuter() && planNode.getRightOuter()) { + String pdName = visitUnSelPushDownName(rightFilter, false); + whereBuilder.append(" and ("); + whereBuilder.append(pdName); + whereBuilder.append(")"); + } + replaceableWhere.set(whereBuilder.toString()); + // refresh sqlbuilder + sqlBuilder = replaceableSqlBuilder.getCurrentElement().getSb(); + } protected void buildSelect(PlanNode query) { sqlBuilder.append("select "); List columns = query.getColumnsRefered(); diff --git a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/AbstractCommitNodesHandler.java b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/AbstractCommitNodesHandler.java index b892789fb..be92adddc 100644 --- a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/AbstractCommitNodesHandler.java +++ b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/AbstractCommitNodesHandler.java @@ -105,6 +105,11 @@ public abstract class AbstractCommitNodesHandler extends MultiNodeHandler implem } + @Override + public void reset(int initCount) { + nodeCount = initCount; + packetId = 0; + } public void debugCommitDelay() { diff --git a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/xa/XACommitNodesHandler.java b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/xa/XACommitNodesHandler.java index d02c1e7cd..a0a5e9b0a 100644 --- a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/xa/XACommitNodesHandler.java +++ b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/xa/XACommitNodesHandler.java @@ -88,7 +88,7 @@ public class XACommitNodesHandler extends AbstractCommitNodesHandler { public void run() { ErrorPacket error = new ErrorPacket(); error.setErrNo(ER_ERROR_DURING_COMMIT); - error.setMessage(errorMsg.getBytes()); + error.setMessage(errorMsg == null ? "unknow error".getBytes() : errorMsg.getBytes()); XAAutoRollbackNodesHandler nextHandler = new XAAutoRollbackNodesHandler(session, error.toBytes(), null, null); nextHandler.rollback(); } diff --git a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/xa/XARollbackNodesHandler.java b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/xa/XARollbackNodesHandler.java index 4c95cde46..d7a97c82a 100644 --- a/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/xa/XARollbackNodesHandler.java +++ b/src/main/java/com/actiontech/dble/backend/mysql/nio/handler/transaction/xa/XARollbackNodesHandler.java @@ -341,7 +341,8 @@ public class XARollbackNodesHandler extends AbstractRollbackNodesHandler { session.getSource().write(send); //partitionly commited,must commit again - } else if (session.getXaState() == TxState.TX_ROLLBACK_FAILED_STATE || session.getXaState() == TxState.TX_PREPARED_STATE) { + } else if (session.getXaState() == TxState.TX_ROLLBACK_FAILED_STATE || session.getXaState() == TxState.TX_PREPARED_STATE || + session.getXaState() == TxState.TX_PREPARE_UNCONNECT_STATE) { MySQLConnection errConn = session.releaseExcept(session.getXaState()); if (errConn != null) { XAStateLog.saveXARecoveryLog(session.getSessionXaID(), session.getXaState()); diff --git a/src/main/java/com/actiontech/dble/plan/optimizer/SubQueryProcessor.java b/src/main/java/com/actiontech/dble/plan/optimizer/SubQueryProcessor.java index 01b6bcd60..2ed14e426 100644 --- a/src/main/java/com/actiontech/dble/plan/optimizer/SubQueryProcessor.java +++ b/src/main/java/com/actiontech/dble/plan/optimizer/SubQueryProcessor.java @@ -127,7 +127,8 @@ public final class SubQueryProcessor { private static void mergeWhere(PlanNode parent, PlanNode child) { Item pWhere = parent.getWhereFilter(); Item pWhere0 = PlanUtil.pushDownItem(parent, pWhere, true); - Item mWhere = FilterUtils.and(pWhere0, child.getWhereFilter()); + Item childWhere = PlanUtil.pushDownItem(child, child.getWhereFilter(), true); + Item mWhere = FilterUtils.and(pWhere0, childWhere); child.setWhereFilter(mWhere); } diff --git a/src/main/java/com/actiontech/dble/plan/visitor/MySQLPlanNodeVisitor.java b/src/main/java/com/actiontech/dble/plan/visitor/MySQLPlanNodeVisitor.java index 423274d16..1aeee9b27 100644 --- a/src/main/java/com/actiontech/dble/plan/visitor/MySQLPlanNodeVisitor.java +++ b/src/main/java/com/actiontech/dble/plan/visitor/MySQLPlanNodeVisitor.java @@ -237,7 +237,7 @@ public class MySQLPlanNodeVisitor { this.tableNode.setSubQuery(true); if (subQueryTables.getAlias() != null) { tableNode.alias(subQueryTables.getAlias()); - if (tableNode.getSubAlias() == null) { + if (tableNode.getSubAlias() == null && tableNode.type() == PlanNode.PlanNodeType.TABLE) { tableNode.setSubAlias(tableNode.getAlias()); } }