mirror of
https://github.com/actiontech/dble.git
synced 2026-01-06 04:40:17 -06:00
refactor code of set variables (#2149)
* refactor code of set * fix value of user variables is null * revert version.txt * revert version.txt
This commit is contained in:
@@ -74,7 +74,7 @@ public class ShowTablesHandler extends SingleNodeHandler {
|
||||
bufInf = ShowTables.writeFullTablesHeader(buffer, shardingService, schemaColumn, fieldPackets);
|
||||
buffer = bufInf.getBuffer();
|
||||
if (info.getWhere() != null) {
|
||||
MySQLItemVisitor mev = new MySQLItemVisitor(shardingService.getSchema(), shardingService.getCharset().getResultsIndex(), ProxyMeta.getInstance().getTmManager(), shardingService.equivalentUsrVarMap());
|
||||
MySQLItemVisitor mev = new MySQLItemVisitor(shardingService.getSchema(), shardingService.getCharset().getResultsIndex(), ProxyMeta.getInstance().getTmManager(), shardingService.getUsrVariables());
|
||||
info.getWhereExpr().accept(mev);
|
||||
sourceFields = HandlerTool.createFields(fieldPackets);
|
||||
whereItem = HandlerTool.createItem(mev.getItem(), sourceFields, 0, false, DMLResponseHandler.HandlerType.WHERE);
|
||||
|
||||
@@ -18,7 +18,7 @@ public class ShowVariablesHandler extends SingleNodeHandler {
|
||||
|
||||
public ShowVariablesHandler(RouteResultset rrs, NonBlockingSession session) {
|
||||
super(rrs, session);
|
||||
shadowVars = session.getShardingService().equivalentSysVarMap();
|
||||
shadowVars = session.getShardingService().getSysVariables();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,7 +51,11 @@ public class CommitStage implements TransactionStage {
|
||||
} else {
|
||||
session.setFinishedCommitTime();
|
||||
session.setResponseTime(true);
|
||||
session.getShardingService().write(sendData != null ? sendData : session.getShardingService().getSession2().getOKPacket());
|
||||
if (sendData != null) {
|
||||
session.getShardingService().write(sendData);
|
||||
} else {
|
||||
session.getShardingService().writeOkPacket();
|
||||
}
|
||||
}
|
||||
session.clearSavepoint();
|
||||
return null;
|
||||
|
||||
@@ -52,7 +52,7 @@ public class RollbackStage implements TransactionStage {
|
||||
if (sendData != null) {
|
||||
sendData.write(session.getSource());
|
||||
} else {
|
||||
session.getShardingService().write(session.getShardingService().getSession2().getOKPacket());
|
||||
session.getShardingService().writeOkPacket();
|
||||
}
|
||||
session.clearSavepoint();
|
||||
return null;
|
||||
|
||||
@@ -58,7 +58,7 @@ public class SavePointHandler extends MultiNodeHandler {
|
||||
SavePoint newSp = new SavePoint(spName);
|
||||
if (session.getTargetCount() <= 0) {
|
||||
addSavePoint(newSp);
|
||||
session.getSource().write(OkPacket.OK);
|
||||
session.getShardingService().writeOkPacket();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ public class SavePointHandler extends MultiNodeHandler {
|
||||
|
||||
if (session.getTargetCount() <= 0) {
|
||||
rollbackToSavepoint(sp);
|
||||
session.getSource().write(OkPacket.OK);
|
||||
session.getShardingService().writeOkPacket();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ public class SavePointHandler extends MultiNodeHandler {
|
||||
savepoints.setPrev(sp.getPrev());
|
||||
sp.setPrev(null);
|
||||
}
|
||||
session.getSource().write(OkPacket.OK);
|
||||
session.getShardingService().writeOkPacket();
|
||||
}
|
||||
|
||||
// find savepoint after named savepoint
|
||||
|
||||
@@ -32,7 +32,7 @@ public class XAHandler extends AbstractXAHandler implements TransactionHandler {
|
||||
implicitCommitHandler.next();
|
||||
return;
|
||||
}
|
||||
session.getShardingService().write(session.getShardingService().getSession2().getOKPacket());
|
||||
session.getShardingService().writeOkPacket();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class XAHandler extends AbstractXAHandler implements TransactionHandler {
|
||||
@Override
|
||||
public void rollback() {
|
||||
if (session.getTargetCount() <= 0) {
|
||||
session.getShardingService().write(session.getShardingService().getSession2().getOKPacket());
|
||||
session.getShardingService().writeOkPacket();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public abstract class XAStage implements TransactionStage {
|
||||
if (sendData != null) {
|
||||
sendData.write(session.getSource());
|
||||
} else {
|
||||
session.getShardingService().write(session.getShardingService().getSession2().getOKPacket());
|
||||
session.getShardingService().writeOkPacket();
|
||||
}
|
||||
xaHandler.clearResources();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2020 ActionTech.
|
||||
* based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
|
||||
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
|
||||
*/
|
||||
* Copyright (C) 2016-2020 ActionTech.
|
||||
* based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
|
||||
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
|
||||
*/
|
||||
package com.actiontech.dble.config;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2020 ActionTech.
|
||||
* based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
|
||||
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
|
||||
*/
|
||||
* Copyright (C) 2016-2020 ActionTech.
|
||||
* based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
|
||||
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
|
||||
*/
|
||||
package com.actiontech.dble.net.handler;
|
||||
|
||||
/**
|
||||
@@ -14,7 +14,4 @@ public interface FrontendQueryHandler {
|
||||
|
||||
void query(String sql);
|
||||
|
||||
void setReadOnly(Boolean readOnly);
|
||||
|
||||
void setSessionReadOnly(boolean sessionReadOnly);
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ abstract class DruidModifyParser extends DefaultDruidParser {
|
||||
String tableName = schemaInfo.getTable();
|
||||
String schemaName = schema == null ? null : schema.getName();
|
||||
|
||||
MySQLPlanNodeVisitor pvisitor = new MySQLPlanNodeVisitor(service.getSchema(), service.getCharset().getResultsIndex(), ProxyMeta.getInstance().getTmManager(), false, service.equivalentUsrVarMap());
|
||||
MySQLPlanNodeVisitor pvisitor = new MySQLPlanNodeVisitor(service.getSchema(), service.getCharset().getResultsIndex(), ProxyMeta.getInstance().getTmManager(), false, service.getUsrVariables());
|
||||
pvisitor.visit(select);
|
||||
PlanNode node = pvisitor.getTableNode();
|
||||
node.setSql(rrs.getStatement());
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.actiontech.dble.rwsplit;
|
||||
|
||||
import com.actiontech.dble.backend.datasource.PhysicalDbGroup;
|
||||
import com.actiontech.dble.backend.datasource.PhysicalDbInstance;
|
||||
import com.actiontech.dble.config.ErrorCode;
|
||||
import com.actiontech.dble.net.connection.BackendConnection;
|
||||
import com.actiontech.dble.services.rwsplit.Callback;
|
||||
import com.actiontech.dble.services.rwsplit.RWSplitHandler;
|
||||
@@ -10,6 +11,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLSyntaxErrorException;
|
||||
|
||||
public class RWSplitNonBlockingSession {
|
||||
|
||||
@@ -23,21 +25,49 @@ public class RWSplitNonBlockingSession {
|
||||
this.rwSplitService = service;
|
||||
}
|
||||
|
||||
public void execute(boolean master, Callback callback) throws IOException {
|
||||
public void execute(boolean master, Callback callback) {
|
||||
execute(master, null, callback);
|
||||
}
|
||||
|
||||
public void execute(boolean master, byte[] originPacket, Callback callback) throws IOException {
|
||||
RWSplitHandler handler = new RWSplitHandler(rwSplitService, originPacket, callback);
|
||||
if (conn != null && !conn.isClosed()) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("select bind conn[id={}]", conn.getId());
|
||||
public void execute(boolean master, byte[] originPacket, Callback callback) {
|
||||
try {
|
||||
RWSplitHandler handler = new RWSplitHandler(rwSplitService, originPacket, callback);
|
||||
if (conn != null && !conn.isClosed()) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("select bind conn[id={}]", conn.getId());
|
||||
}
|
||||
checkDest(!conn.getInstance().isReadInstance());
|
||||
handler.execute(conn);
|
||||
return;
|
||||
}
|
||||
handler.execute(conn);
|
||||
|
||||
PhysicalDbInstance instance = rwGroup.select(master);
|
||||
checkDest(!instance.isReadInstance());
|
||||
instance.getConnection(rwSplitService.getSchema(), handler, null, false);
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("select conn error", e);
|
||||
rwSplitService.writeErrMessage(ErrorCode.ER_UNKNOWN_ERROR, e.getMessage());
|
||||
} catch (SQLSyntaxErrorException se) {
|
||||
rwSplitService.writeErrMessage(ErrorCode.ER_UNKNOWN_ERROR, se.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkDest(boolean isMaster) throws SQLSyntaxErrorException {
|
||||
String dest = rwSplitService.getExpectedDest();
|
||||
if (dest == null) {
|
||||
return;
|
||||
}
|
||||
PhysicalDbInstance instance = rwGroup.select(master);
|
||||
instance.getConnection(rwSplitService.getSchema(), handler, null, false);
|
||||
if (dest.equalsIgnoreCase("M") && isMaster) {
|
||||
return;
|
||||
}
|
||||
if (dest.equalsIgnoreCase("S") && !isMaster) {
|
||||
return;
|
||||
}
|
||||
throw new SQLSyntaxErrorException("unexpected dble_dest_expect,real[" + (isMaster ? "M" : "S") + "],expect[" + dest + "]");
|
||||
}
|
||||
|
||||
public PhysicalDbGroup getRwGroup() {
|
||||
return rwGroup;
|
||||
}
|
||||
|
||||
public void setRwGroup(PhysicalDbGroup rwGroup) {
|
||||
@@ -51,8 +81,17 @@ public class RWSplitNonBlockingSession {
|
||||
this.conn = bindConn;
|
||||
}
|
||||
|
||||
public void unbindIfSafe(boolean safe) {
|
||||
if (safe) {
|
||||
this.conn.release();
|
||||
this.conn = null;
|
||||
} else {
|
||||
unbindIfSafe();
|
||||
}
|
||||
}
|
||||
|
||||
public void unbindIfSafe() {
|
||||
if (rwSplitService.isAutocommit() && !rwSplitService.isLocked() &&
|
||||
if (rwSplitService.isAutocommit() && !rwSplitService.isTxStart() && !rwSplitService.isLocked() &&
|
||||
!rwSplitService.isTxStart() &&
|
||||
!rwSplitService.isInLoadData() &&
|
||||
!rwSplitService.isInPrepare()) {
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.actiontech.dble.net.connection.BackendConnection;
|
||||
import com.actiontech.dble.net.connection.FrontendConnection;
|
||||
import com.actiontech.dble.net.handler.BackEndDataCleaner;
|
||||
import com.actiontech.dble.net.mysql.MySQLPacket;
|
||||
import com.actiontech.dble.net.mysql.OkPacket;
|
||||
import com.actiontech.dble.net.mysql.StatusFlags;
|
||||
import com.actiontech.dble.plan.common.exception.MySQLOutPutException;
|
||||
import com.actiontech.dble.plan.node.PlanNode;
|
||||
@@ -608,7 +607,7 @@ public class NonBlockingSession extends Session {
|
||||
TraceManager.TraceObject traceObject = TraceManager.serviceTrace(shardingService, "try-complex-query");
|
||||
try {
|
||||
SQLSelectStatement ast = (SQLSelectStatement) rrs.getSqlStatement();
|
||||
MySQLPlanNodeVisitor visitor = new MySQLPlanNodeVisitor(shardingService.getSchema(), shardingService.getCharset().getResultsIndex(), ProxyMeta.getInstance().getTmManager(), false, shardingService.equivalentUsrVarMap());
|
||||
MySQLPlanNodeVisitor visitor = new MySQLPlanNodeVisitor(shardingService.getSchema(), shardingService.getCharset().getResultsIndex(), ProxyMeta.getInstance().getTmManager(), false, shardingService.getUsrVariables());
|
||||
visitor.visit(ast);
|
||||
PlanNode node = visitor.getTableNode();
|
||||
if (node.isCorrelatedSubQuery()) {
|
||||
@@ -1030,15 +1029,6 @@ public class NonBlockingSession extends Session {
|
||||
return false;
|
||||
}
|
||||
|
||||
public OkPacket getOKPacket() {
|
||||
OkPacket ok = new OkPacket();
|
||||
byte packet = (byte) this.getPacketId().incrementAndGet();
|
||||
ok.read(OkPacket.OK);
|
||||
ok.setPacketId(packet);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
public void queryCount() {
|
||||
queriesCounter.incrementAndGet();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2020 ActionTech.
|
||||
* based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
|
||||
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
|
||||
*/
|
||||
* Copyright (C) 2016-2020 ActionTech.
|
||||
* based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
|
||||
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
|
||||
*/
|
||||
package com.actiontech.dble.server;
|
||||
|
||||
import com.actiontech.dble.config.ErrorCode;
|
||||
@@ -27,12 +27,10 @@ public class ServerQueryHandler implements FrontendQueryHandler {
|
||||
private Boolean readOnly = true;
|
||||
private boolean sessionReadOnly = true;
|
||||
|
||||
@Override
|
||||
public void setReadOnly(Boolean readOnly) {
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionReadOnly(boolean sessionReadOnly) {
|
||||
this.sessionReadOnly = sessionReadOnly;
|
||||
}
|
||||
@@ -143,10 +141,8 @@ public class ServerQueryHandler implements FrontendQueryHandler {
|
||||
service.writeErrMessage(ErrorCode.ER_SYNTAX_ERROR, "Unsupported command");
|
||||
break;
|
||||
case ServerParse.MYSQL_CMD_COMMENT:
|
||||
service.write(service.getSession2().getOKPacket());
|
||||
break;
|
||||
case ServerParse.MYSQL_COMMENT:
|
||||
service.write(service.getSession2().getOKPacket());
|
||||
service.writeOkPacket();
|
||||
break;
|
||||
case ServerParse.LOAD_DATA_INFILE_SQL:
|
||||
service.loadDataInfileStart(sql);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2020 ActionTech.
|
||||
* based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
|
||||
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
|
||||
*/
|
||||
* Copyright (C) 2016-2020 ActionTech.
|
||||
* based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
|
||||
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
|
||||
*/
|
||||
package com.actiontech.dble.server;
|
||||
|
||||
import com.actiontech.dble.services.mysqlsharding.ShardingService;
|
||||
@@ -57,7 +57,7 @@ public final class ServerSptPrepare {
|
||||
/* In user variable, the string is primordial, so we have to truncate the quotes */
|
||||
private String getStmtFromUserVar() {
|
||||
String key = "@" + sptStmt;
|
||||
String stmt = service.equivalentUsrVarMap().get(key);
|
||||
String stmt = service.getUsrVariables().get(key);
|
||||
String rstmt = null;
|
||||
|
||||
if (stmt != null) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2020 ActionTech.
|
||||
* based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
|
||||
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
|
||||
*/
|
||||
* Copyright (C) 2016-2020 ActionTech.
|
||||
* based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
|
||||
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
|
||||
*/
|
||||
package com.actiontech.dble.server.handler;
|
||||
|
||||
import com.actiontech.dble.log.transaction.TxnLogHelper;
|
||||
@@ -18,7 +18,7 @@ public final class BeginHandler {
|
||||
} else {
|
||||
service.setTxStarted(true);
|
||||
TxnLogHelper.putTxnLog(service, stmt);
|
||||
service.write(service.getSession2().getOKPacket());
|
||||
service.writeOkPacket();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ public final class ExplainHandler {
|
||||
|
||||
private static BaseHandlerBuilder buildNodes(RouteResultset rrs, ShardingService service) {
|
||||
SQLSelectStatement ast = (SQLSelectStatement) rrs.getSqlStatement();
|
||||
MySQLPlanNodeVisitor visitor = new MySQLPlanNodeVisitor(service.getSchema(), service.getCharset().getResultsIndex(), ProxyMeta.getInstance().getTmManager(), false, service.equivalentUsrVarMap());
|
||||
MySQLPlanNodeVisitor visitor = new MySQLPlanNodeVisitor(service.getSchema(), service.getCharset().getResultsIndex(), ProxyMeta.getInstance().getTmManager(), false, service.getUsrVariables());
|
||||
visitor.visit(ast);
|
||||
PlanNode node = visitor.getTableNode();
|
||||
node.setSql(rrs.getStatement());
|
||||
|
||||
@@ -5,32 +5,27 @@
|
||||
|
||||
package com.actiontech.dble.server.handler;
|
||||
|
||||
import com.actiontech.dble.services.mysqlsharding.ShardingService;
|
||||
import com.actiontech.dble.services.MySQLVariablesService;
|
||||
import com.actiontech.dble.sqlengine.SQLQueryResult;
|
||||
import com.actiontech.dble.sqlengine.SQLQueryResultListener;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SetCallBack implements SQLQueryResultListener<SQLQueryResult<Map<String, String>>> {
|
||||
private ShardingService service;
|
||||
private boolean backToOtherThread;
|
||||
private final MySQLVariablesService service;
|
||||
private final SetHandler.SetItem[] items;
|
||||
|
||||
SetCallBack(ShardingService service) {
|
||||
SetCallBack(MySQLVariablesService service, SetHandler.SetItem[] items) {
|
||||
this.service = service;
|
||||
this.items = items;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResult(SQLQueryResult<Map<String, String>> result) {
|
||||
if (result.isSuccess()) {
|
||||
service.executeContextSetTask();
|
||||
backToOtherThread = service.executeInnerSetTask();
|
||||
} else {
|
||||
service.getContextTask().clear();
|
||||
service.getInnerSetTask().clear();
|
||||
service.executeContextSetTask(items);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBackToOtherThread() {
|
||||
return backToOtherThread;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,36 +5,26 @@
|
||||
*/
|
||||
package com.actiontech.dble.server.handler;
|
||||
|
||||
import com.actiontech.dble.DbleServer;
|
||||
import com.actiontech.dble.backend.mysql.CharsetUtil;
|
||||
import com.actiontech.dble.backend.mysql.VersionUtil;
|
||||
import com.actiontech.dble.config.ErrorCode;
|
||||
import com.actiontech.dble.config.Isolations;
|
||||
import com.actiontech.dble.config.model.SystemConfig;
|
||||
import com.actiontech.dble.route.parser.util.Pair;
|
||||
import com.actiontech.dble.route.parser.util.ParseUtil;
|
||||
import com.actiontech.dble.server.util.SetItemUtil;
|
||||
import com.actiontech.dble.services.MySQLVariablesService;
|
||||
import com.actiontech.dble.services.mysqlsharding.ShardingService;
|
||||
import com.actiontech.dble.sqlengine.OneRawSQLQueryResultHandler;
|
||||
import com.actiontech.dble.sqlengine.SetTestJob;
|
||||
import com.actiontech.dble.util.StringUtil;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetTransactionStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
|
||||
import java.sql.SQLSyntaxErrorException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
@@ -66,25 +56,166 @@ public final class SetHandler {
|
||||
TRACE
|
||||
}
|
||||
|
||||
public static void handle(String stmt, ShardingService shardingService, int offset) {
|
||||
public static void handle(String stmt, MySQLVariablesService frontService, int offset) {
|
||||
if (!ParseUtil.isSpace(stmt.charAt(offset))) {
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_WRONG_USED, stmt + " is not supported");
|
||||
frontService.writeErrMessage(ErrorCode.ERR_WRONG_USED, stmt + " is not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
stmt = convertCharsetKeyWord(stmt);
|
||||
|
||||
try {
|
||||
String smt = convertCharsetKeyWord(stmt);
|
||||
List<Pair<KeyType, Pair<String, String>>> contextTask = new ArrayList<>();
|
||||
List<Pair<KeyType, Pair<String, String>>> innerSetTask = new ArrayList<>();
|
||||
StringBuilder contextSetSQL = new StringBuilder();
|
||||
if (handleSetStatement(smt, shardingService, contextTask, innerSetTask, contextSetSQL) && contextTask.size() > 0) {
|
||||
setStmtCallback(contextSetSQL.toString(), shardingService, contextTask, innerSetTask);
|
||||
} else if (innerSetTask.size() > 0) {
|
||||
shardingService.setInnerSetTask(innerSetTask);
|
||||
if (!shardingService.executeInnerSetTask()) {
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
SetItem[] items;
|
||||
StringBuilder setSQL = new StringBuilder("set ");
|
||||
StringBuilder selectSQL = new StringBuilder("select ");
|
||||
int userVariableSize = 0;
|
||||
// parse set sql
|
||||
SQLStatement statement = parseSQL(stmt);
|
||||
if (statement instanceof SQLSetStatement) {
|
||||
List<SQLAssignItem> assignItems = ((SQLSetStatement) statement).getItems();
|
||||
String key;
|
||||
int systemVariableIndex = assignItems.size() - 1;
|
||||
items = new SetItem[assignItems.size()];
|
||||
|
||||
for (SQLAssignItem sqlAssignItem : assignItems) {
|
||||
// new set item
|
||||
key = handleSetKey(sqlAssignItem.getTarget());
|
||||
SetItem item = newSetItem(key, sqlAssignItem.getValue());
|
||||
if (item.getType() == KeyType.USER_VARIABLES) {
|
||||
if (setSQL.length() > 4) {
|
||||
setSQL.append(",");
|
||||
}
|
||||
if (selectSQL.length() > 7) {
|
||||
selectSQL.append(",");
|
||||
}
|
||||
setSQL.append(SQLUtils.toMySqlString(sqlAssignItem));
|
||||
selectSQL.append(item.getName());
|
||||
|
||||
items[userVariableSize++] = item;
|
||||
} else if (item.getType() == KeyType.SYSTEM_VARIABLES) {
|
||||
if (setSQL.length() > 4) {
|
||||
setSQL.append(",");
|
||||
}
|
||||
setSQL.append(SQLUtils.toMySqlString(sqlAssignItem));
|
||||
items[systemVariableIndex--] = item;
|
||||
} else if (item.getType() == KeyType.XA) {
|
||||
if (frontService instanceof ShardingService) {
|
||||
boolean val = Boolean.parseBoolean(item.getValue());
|
||||
((ShardingService) frontService).checkXaStatus(val);
|
||||
items[systemVariableIndex--] = item;
|
||||
} else {
|
||||
throw new SQLSyntaxErrorException("unsupported set xa");
|
||||
}
|
||||
} else {
|
||||
items[systemVariableIndex--] = item;
|
||||
}
|
||||
}
|
||||
} else if (statement instanceof MySqlSetTransactionStatement) {
|
||||
items = new SetItem[1];
|
||||
items[0] = handleTransaction((MySqlSetTransactionStatement) statement);
|
||||
} else {
|
||||
frontService.writeErrMessage(ErrorCode.ERR_WRONG_USED, stmt + " is not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
// check user variables and system variables unused in dble
|
||||
if (setSQL.length() > 4) {
|
||||
if (userVariableSize > 0) {
|
||||
setSQL.append(";").append(selectSQL);
|
||||
}
|
||||
checkVariables(frontService, setSQL.toString(), items, userVariableSize);
|
||||
} else {
|
||||
frontService.executeContextSetTask(items);
|
||||
}
|
||||
|
||||
} catch (SQLSyntaxErrorException e) {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_PARSE_ERROR, e.toString());
|
||||
frontService.writeErrMessage(ErrorCode.ER_PARSE_ERROR, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static SetItem handleTransaction(MySqlSetTransactionStatement setStatement) throws SQLSyntaxErrorException {
|
||||
//always single
|
||||
SetItem item;
|
||||
if (setStatement.getGlobal() == null) {
|
||||
throw new SQLSyntaxErrorException("setting transaction without any SESSION or GLOBAL keyword is not supported now");
|
||||
} else if (setStatement.getGlobal()) {
|
||||
throw new SQLSyntaxErrorException("setting GLOBAL value is not supported");
|
||||
} else if (setStatement.getAccessModel() != null) {
|
||||
if (setStatement.getAccessModel().equals("ONLY")) {
|
||||
item = newSetItem(VersionUtil.TX_READ_ONLY, new SQLBooleanExpr(true));
|
||||
} else {
|
||||
item = newSetItem(VersionUtil.TX_READ_ONLY, new SQLBooleanExpr(false));
|
||||
}
|
||||
} else {
|
||||
item = newSetItem(VersionUtil.TRANSACTION_ISOLATION, new SQLCharExpr(setStatement.getIsolationLevel()));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
//execute multiStmt and callback to reset conn
|
||||
private static void checkVariables(MySQLVariablesService service, String setSql, SetItem[] items, int userVariableSize) {
|
||||
OneRawSQLQueryResultHandler resultHandler = new OneRawSQLQueryResultHandler(new String[0], new SetCallBack(service, items));
|
||||
SetTestJob sqlJob = new SetTestJob(setSql, resultHandler, items, userVariableSize, service);
|
||||
sqlJob.run();
|
||||
}
|
||||
|
||||
private static String handleSetKey(SQLExpr key) throws SQLSyntaxErrorException {
|
||||
if (key instanceof SQLPropertyExpr) {
|
||||
SQLPropertyExpr target = (SQLPropertyExpr) key;
|
||||
if (!(target.getOwner() instanceof SQLVariantRefExpr)) {
|
||||
throw new SQLSyntaxErrorException("unsupport global");
|
||||
}
|
||||
SQLVariantRefExpr owner = (SQLVariantRefExpr) target.getOwner();
|
||||
if (owner.isGlobal()) {
|
||||
throw new SQLSyntaxErrorException("unsupport global");
|
||||
}
|
||||
return target.getName();
|
||||
} else if (key instanceof SQLVariantRefExpr) {
|
||||
SQLVariantRefExpr target = (SQLVariantRefExpr) key;
|
||||
if (target.isGlobal()) {
|
||||
throw new SQLSyntaxErrorException("unsupport global");
|
||||
}
|
||||
return target.getName();
|
||||
} else if (key instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr target = (SQLIdentifierExpr) key;
|
||||
return target.getLowerName();
|
||||
}
|
||||
throw new SQLSyntaxErrorException("unknown key type");
|
||||
}
|
||||
|
||||
private static SetItem newSetItem(String key, SQLExpr valueExpr) throws SQLSyntaxErrorException {
|
||||
switch (key.toLowerCase()) {
|
||||
case "xa":
|
||||
return new SetItem("xa", SetItemUtil.getBooleanVal(valueExpr), SetHandler.KeyType.XA);
|
||||
case "trace":
|
||||
return new SetItem("trace", SetItemUtil.getBooleanVal(valueExpr), SetHandler.KeyType.TRACE);
|
||||
case "autocommit":
|
||||
return new SetItem("autocommit", SetItemUtil.getBooleanVal(valueExpr), SetHandler.KeyType.AUTOCOMMIT);
|
||||
case "collation_connection":
|
||||
return new SetItem("collation_connection", SetItemUtil.getCollationVal(valueExpr), SetHandler.KeyType.COLLATION_CONNECTION);
|
||||
case "character_set_client":
|
||||
return new SetItem("character_set_client", SetItemUtil.getCharsetClientVal(valueExpr), SetHandler.KeyType.CHARACTER_SET_CLIENT);
|
||||
case "character_set_results":
|
||||
return new SetItem("character_set_results", SetItemUtil.getCharsetResultsVal(valueExpr), SetHandler.KeyType.CHARACTER_SET_RESULTS);
|
||||
case "character_set_connection":
|
||||
return new SetItem("character_set_connection", SetItemUtil.getCharsetConnectionVal(valueExpr), SetHandler.KeyType.CHARACTER_SET_CONNECTION);
|
||||
case "character set":
|
||||
return new SetItem(key, SetItemUtil.getCharsetVal(valueExpr), SetHandler.KeyType.CHARSET);
|
||||
case "names":
|
||||
return new SetItem(key, SetItemUtil.getNamesVal(valueExpr), SetHandler.KeyType.NAMES);
|
||||
case VersionUtil.TRANSACTION_ISOLATION:
|
||||
case VersionUtil.TX_ISOLATION:
|
||||
return new SetItem(key, SetItemUtil.getIsolationVal(valueExpr), SetHandler.KeyType.TX_ISOLATION);
|
||||
case VersionUtil.TRANSACTION_READ_ONLY:
|
||||
case VersionUtil.TX_READ_ONLY:
|
||||
return new SetItem(key, SetItemUtil.getBooleanVal(valueExpr), SetHandler.KeyType.TX_READ_ONLY);
|
||||
default:
|
||||
if (key.startsWith("@@")) {
|
||||
return new SetItem(key.substring(2), SetItemUtil.parseVariablesValue(valueExpr), KeyType.SYSTEM_VARIABLES);
|
||||
} else if (key.startsWith("@")) {
|
||||
return new SetItem(key.toUpperCase(), null, KeyType.USER_VARIABLES);
|
||||
}
|
||||
return new SetItem(key, SetItemUtil.parseVariablesValue(valueExpr), KeyType.SYSTEM_VARIABLES);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,465 +224,10 @@ public final class SetHandler {
|
||||
try {
|
||||
return parser.parseStatement();
|
||||
} catch (Exception t) {
|
||||
if (t.getMessage() != null) {
|
||||
throw new SQLSyntaxErrorException(t.getMessage());
|
||||
} else {
|
||||
throw new SQLSyntaxErrorException(t);
|
||||
}
|
||||
throw new SQLSyntaxErrorException(t);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleSetStatement(String stmt, ShardingService service, List<Pair<KeyType, Pair<String, String>>> contextTask,
|
||||
List<Pair<KeyType, Pair<String, String>>> innerSetTask, StringBuilder contextSetSQL) throws SQLSyntaxErrorException {
|
||||
SQLStatement statement = parseSQL(stmt);
|
||||
if (statement instanceof SQLSetStatement) {
|
||||
List<SQLAssignItem> assignItems = ((SQLSetStatement) statement).getItems();
|
||||
if (assignItems.size() == 1) {
|
||||
contextSetSQL.append(statement.toString());
|
||||
return handleSingleVariable(stmt, assignItems.get(0), service, contextTask);
|
||||
} else {
|
||||
boolean result = handleSetMultiStatement(assignItems, service, contextTask, innerSetTask);
|
||||
contextSetSQL.append(statement.toString());
|
||||
return result;
|
||||
}
|
||||
} else if (statement instanceof MySqlSetTransactionStatement) {
|
||||
return handleTransaction(service, (MySqlSetTransactionStatement) statement);
|
||||
} else {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, stmt + " is not recognized and ignored");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleSetNamesInMultiStmt(ShardingService service, String stmt, String charset, String collate, List<Pair<KeyType, Pair<String, String>>> contextTask) {
|
||||
NamesInfo charsetInfo = checkSetNames(stmt, charset, collate);
|
||||
if (charsetInfo != null) {
|
||||
if (charsetInfo.charset == null) {
|
||||
service.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set '" + charset + " or collate '" + collate + "'");
|
||||
return false;
|
||||
} else if (charsetInfo.collation == null) {
|
||||
service.writeErrMessage(ErrorCode.ER_COLLATION_CHARSET_MISMATCH, "COLLATION '" + collate + "' is not valid for CHARACTER SET '" + charset + "'");
|
||||
return false;
|
||||
} else if (!charsetInfo.isSupport) {
|
||||
service.writeErrMessage(ErrorCode.ER_WRONG_VALUE_FOR_VAR, "Variable 'character_set_client' can't be set to the value of '" + charsetInfo.charset + "'");
|
||||
return false;
|
||||
} else {
|
||||
contextTask.add(new Pair<>(KeyType.NAMES, new Pair<>(charsetInfo.charset, charsetInfo.collation)));
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
service.writeErrMessage(ErrorCode.ER_PARSE_ERROR, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the SQL: " + stmt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleSingleSetNames(String stmt, ShardingService shardingService, SQLExpr valueExpr) {
|
||||
String[] charsetAndCollate = parseNamesValue(valueExpr);
|
||||
NamesInfo charsetInfo = checkSetNames(stmt, charsetAndCollate[0], charsetAndCollate[1]);
|
||||
if (charsetInfo != null) {
|
||||
if (charsetInfo.charset == null) {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set in statement '" + stmt + "'");
|
||||
return false;
|
||||
} else if (charsetInfo.collation == null) {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_COLLATION_CHARSET_MISMATCH, "COLLATION '" + charsetAndCollate[1] + "' is not valid for CHARACTER SET '" + charsetAndCollate[0] + "'");
|
||||
return false;
|
||||
} else if (!charsetInfo.isSupport) {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_WRONG_VALUE_FOR_VAR, "Variable 'character_set_client' can't be set to the value of '" + charsetInfo.charset + "'");
|
||||
return false;
|
||||
} else {
|
||||
shardingService.setNames(charsetInfo.charset, charsetInfo.collation);
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_PARSE_ERROR, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the SQL: " + stmt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleSingleSetCharset(String stmt, ShardingService shardingService, SQLExpr valueExpr) {
|
||||
String charsetValue = SetInnerHandler.parseStringValue(valueExpr);
|
||||
if (charsetValue == null || charsetValue.equalsIgnoreCase("null")) {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set null");
|
||||
return false;
|
||||
}
|
||||
String charset = getCharset(charsetValue);
|
||||
if (charset != null) {
|
||||
if (!CharsetUtil.checkCharsetClient(charset)) {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_WRONG_VALUE_FOR_VAR, "Variable 'character_set_client' can't be set to the value of '" + charset + "'");
|
||||
return false;
|
||||
} else {
|
||||
shardingService.setCharacterSet(charset);
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set in statement '" + stmt + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleSetMultiStatement(List<SQLAssignItem> assignItems, ShardingService service, List<Pair<KeyType, Pair<String, String>>> contextTask, List<Pair<KeyType, Pair<String, String>>> innerSetTask) {
|
||||
Set<SQLAssignItem> objSet = new HashSet<>();
|
||||
for (SQLAssignItem assignItem : assignItems) {
|
||||
if (!handleVariableInMultiStmt(assignItem, service, contextTask, innerSetTask, objSet)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (SQLAssignItem assignItem : objSet) {
|
||||
assignItems.remove(assignItem);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//execute multiStmt and callback to reset conn
|
||||
private static void setStmtCallback(String multiStmt, ShardingService service, List<Pair<KeyType, Pair<String, String>>> contextTask, List<Pair<KeyType, Pair<String, String>>> innerSetTask) {
|
||||
service.setContextTask(contextTask);
|
||||
service.setInnerSetTask(innerSetTask);
|
||||
OneRawSQLQueryResultHandler resultHandler = new OneRawSQLQueryResultHandler(new String[0], new SetCallBack(service));
|
||||
SetTestJob sqlJob = new SetTestJob(multiStmt, null, resultHandler, service);
|
||||
sqlJob.run();
|
||||
}
|
||||
|
||||
private static boolean handleVariableInMultiStmt(SQLAssignItem assignItem, ShardingService service, List<Pair<KeyType, Pair<String, String>>> contextTask, List<Pair<KeyType, Pair<String, String>>> innerSetTask, Set<SQLAssignItem> objSet) {
|
||||
String key = handleSetKey(assignItem, service);
|
||||
if (key == null) {
|
||||
return false;
|
||||
}
|
||||
SQLExpr valueExpr = assignItem.getValue();
|
||||
KeyType keyType = parseKeyType(key, true, KeyType.SYSTEM_VARIABLES);
|
||||
if (!checkValue(valueExpr, keyType)) {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "setting target is not supported for '" + assignItem.getValue() + "'");
|
||||
return false;
|
||||
}
|
||||
switch (keyType) {
|
||||
case XA:
|
||||
if (!SetInnerHandler.preHandleSingleXA(service, valueExpr, innerSetTask)) {
|
||||
return false;
|
||||
}
|
||||
objSet.add(assignItem);
|
||||
break;
|
||||
case TRACE:
|
||||
if (!SetInnerHandler.preHandleSingleTrace(service, valueExpr, innerSetTask)) {
|
||||
return false;
|
||||
}
|
||||
objSet.add(assignItem);
|
||||
break;
|
||||
case AUTOCOMMIT:
|
||||
if (!SetInnerHandler.preHandleAutocommit(service, valueExpr, innerSetTask)) {
|
||||
return false;
|
||||
}
|
||||
objSet.add(assignItem);
|
||||
break;
|
||||
case NAMES: {
|
||||
String charset = SetInnerHandler.parseStringValue(valueExpr);
|
||||
//TODO:druid lost collation info
|
||||
if (!handleSetNamesInMultiStmt(service, "SET NAMES " + charset, charset, null, contextTask))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case CHARSET: {
|
||||
String charset = SetInnerHandler.parseStringValue(valueExpr);
|
||||
if (!handleCharsetInMultiStmt(service, charset, contextTask)) return false;
|
||||
break;
|
||||
}
|
||||
case CHARACTER_SET_CLIENT:
|
||||
if (!handleCharsetClientInMultiStmt(service, contextTask, valueExpr)) return false;
|
||||
break;
|
||||
case CHARACTER_SET_CONNECTION:
|
||||
if (!handleCharsetConnInMultiStmt(service, contextTask, valueExpr)) return false;
|
||||
break;
|
||||
case CHARACTER_SET_RESULTS:
|
||||
if (!handleCharsetResultsInMultiStmt(service, contextTask, valueExpr)) return false;
|
||||
break;
|
||||
case COLLATION_CONNECTION:
|
||||
if (!handleCollationConnInMultiStmt(service, contextTask, valueExpr)) return false;
|
||||
break;
|
||||
case TX_READ_ONLY:
|
||||
if (!handleReadOnlyInMultiStmt(service, contextTask, valueExpr)) return false;
|
||||
break;
|
||||
case TX_ISOLATION:
|
||||
if (!handleTxIsolationInMultiStmt(service, contextTask, valueExpr)) return false;
|
||||
break;
|
||||
case SYSTEM_VARIABLES:
|
||||
if (key.startsWith("@@")) {
|
||||
key = key.substring(2);
|
||||
}
|
||||
if (DbleServer.getInstance().getSystemVariables().getDefaultValue(key) == null) {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "system variable " + key + " is not supported");
|
||||
}
|
||||
contextTask.add(new Pair<>(KeyType.SYSTEM_VARIABLES, new Pair<>(key, parseVariablesValue(valueExpr))));
|
||||
break;
|
||||
case USER_VARIABLES:
|
||||
contextTask.add(new Pair<>(KeyType.USER_VARIABLES, new Pair<>(key.toUpperCase(), parseVariablesValue(valueExpr))));
|
||||
break;
|
||||
default:
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, key + " is not supported");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean handleCharsetInMultiStmt(ShardingService service, String charset, List<Pair<KeyType, Pair<String, String>>> contextTask) {
|
||||
String charsetInfo = getCharset(charset);
|
||||
if (charsetInfo != null) {
|
||||
if (!CharsetUtil.checkCharsetClient(charsetInfo)) {
|
||||
service.writeErrMessage(ErrorCode.ER_WRONG_VALUE_FOR_VAR, "Variable 'character_set_client' can't be set to the value of '" + charsetInfo + "'");
|
||||
return false;
|
||||
} else {
|
||||
contextTask.add(new Pair<>(KeyType.CHARSET, new Pair<String, String>(charsetInfo, null)));
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
service.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set '" + charset + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleTxIsolationInMultiStmt(ShardingService service, List<Pair<KeyType, Pair<String, String>>> contextTask, SQLExpr valueExpr) {
|
||||
String value = SetInnerHandler.parseStringValue(valueExpr);
|
||||
Integer txIsolation = getIsolationLevel(value);
|
||||
if (txIsolation == null) {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "Variable 'tx_isolation|transaction_isolation' can't be set to the value of '" + value + "'");
|
||||
return false;
|
||||
}
|
||||
contextTask.add(new Pair<>(KeyType.TX_ISOLATION, new Pair<String, String>(String.valueOf(txIsolation), null)));
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean handleReadOnlyInMultiStmt(ShardingService service, List<Pair<KeyType, Pair<String, String>>> contextTask, SQLExpr valueExpr) {
|
||||
Boolean switchStatus = SetInnerHandler.isSwitchOn(valueExpr);
|
||||
if (switchStatus == null) {
|
||||
service.writeErrMessage(ErrorCode.ER_WRONG_TYPE_FOR_VAR, "Incorrect argument type to variable 'tx_read_only|transaction_read_only'");
|
||||
return false;
|
||||
} else if (switchStatus) {
|
||||
contextTask.add(new Pair<>(KeyType.TX_READ_ONLY, new Pair<String, String>("true", null)));
|
||||
} else {
|
||||
contextTask.add(new Pair<>(KeyType.TX_READ_ONLY, new Pair<String, String>("false", null)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean handleCollationConnInMultiStmt(ShardingService service, List<Pair<KeyType, Pair<String, String>>> contextTask, SQLExpr valueExpr) {
|
||||
String collation = SetInnerHandler.parseStringValue(valueExpr);
|
||||
if (checkCollation(collation)) {
|
||||
contextTask.add(new Pair<>(KeyType.COLLATION_CONNECTION, new Pair<String, String>(collation, null)));
|
||||
return true;
|
||||
} else {
|
||||
service.writeErrMessage(ErrorCode.ER_UNKNOWN_COLLATION, "Unknown collation '" + collation + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleCharsetResultsInMultiStmt(ShardingService service, List<Pair<KeyType, Pair<String, String>>> contextTask, SQLExpr valueExpr) {
|
||||
String charsetResult = SetInnerHandler.parseStringValue(valueExpr);
|
||||
if (charsetResult.equalsIgnoreCase("NULL") || checkCharset(charsetResult)) {
|
||||
contextTask.add(new Pair<>(KeyType.CHARACTER_SET_RESULTS, new Pair<String, String>(charsetResult, null)));
|
||||
return true;
|
||||
} else {
|
||||
service.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set '" + charsetResult + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleCharsetConnInMultiStmt(ShardingService service, List<Pair<KeyType, Pair<String, String>>> contextTask, SQLExpr valueExpr) {
|
||||
String charsetConnection = SetInnerHandler.parseStringValue(valueExpr);
|
||||
if (charsetConnection.equals("null")) {
|
||||
service.writeErrMessage(ErrorCode.ER_WRONG_VALUE_FOR_VAR, "Variable 'character_set_connection' can't be set to the value of 'NULL'");
|
||||
return false;
|
||||
}
|
||||
String collationName = CharsetUtil.getDefaultCollation(charsetConnection);
|
||||
if (collationName != null) {
|
||||
contextTask.add(new Pair<>(KeyType.CHARACTER_SET_CONNECTION, new Pair<String, String>(collationName, null)));
|
||||
return true;
|
||||
} else {
|
||||
service.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set '" + charsetConnection + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleCharsetClientInMultiStmt(ShardingService service, List<Pair<KeyType, Pair<String, String>>> contextTask, SQLExpr valueExpr) {
|
||||
String charsetClient = SetInnerHandler.parseStringValue(valueExpr);
|
||||
if (charsetClient.equalsIgnoreCase("null")) {
|
||||
service.writeErrMessage(ErrorCode.ER_WRONG_VALUE_FOR_VAR, "Variable 'character_set_client' can't be set to the value of 'NULL'");
|
||||
return false;
|
||||
} else if (checkCharset(charsetClient)) {
|
||||
if (!CharsetUtil.checkCharsetClient(charsetClient)) {
|
||||
service.writeErrMessage(ErrorCode.ER_WRONG_VALUE_FOR_VAR, "Variable 'character_set_client' can't be set to the value of '" + charsetClient + "'");
|
||||
return false;
|
||||
} else {
|
||||
contextTask.add(new Pair<>(KeyType.CHARACTER_SET_CLIENT, new Pair<String, String>(charsetClient, null)));
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
service.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set '" + charsetClient + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleSingleVariable(String stmt, SQLAssignItem assignItem, ShardingService shardingService, List<Pair<KeyType, Pair<String, String>>> contextTask) {
|
||||
String key = handleSetKey(assignItem, shardingService);
|
||||
if (key == null) return false;
|
||||
SQLExpr valueExpr = assignItem.getValue();
|
||||
KeyType keyType = parseKeyType(key, true, KeyType.SYSTEM_VARIABLES);
|
||||
if (!checkValue(valueExpr, keyType)) {
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "setting target is not supported for '" + SQLUtils.toMySqlString(assignItem.getValue()) + "'");
|
||||
return false;
|
||||
}
|
||||
switch (keyType) {
|
||||
case NAMES:
|
||||
return handleSingleSetNames(stmt, shardingService, valueExpr);
|
||||
case CHARSET:
|
||||
return handleSingleSetCharset(stmt, shardingService, valueExpr);
|
||||
case XA:
|
||||
return SetInnerHandler.handleSingleXA(shardingService, valueExpr);
|
||||
case TRACE:
|
||||
return SetInnerHandler.handleSingleTrace(shardingService, valueExpr);
|
||||
case AUTOCOMMIT:
|
||||
return SetInnerHandler.handleSingleAutocommit(stmt, shardingService, valueExpr);
|
||||
case CHARACTER_SET_CLIENT:
|
||||
return handleSingleCharsetClient(shardingService, valueExpr);
|
||||
case CHARACTER_SET_CONNECTION:
|
||||
return handleSingleCharsetConnection(shardingService, valueExpr);
|
||||
case CHARACTER_SET_RESULTS:
|
||||
return handleSingleCharsetResults(shardingService, valueExpr);
|
||||
case COLLATION_CONNECTION:
|
||||
return handleCollationConnection(shardingService, valueExpr);
|
||||
case TX_READ_ONLY:
|
||||
if (!stmt.toLowerCase().contains("session")) {
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "setting transaction without any SESSION or GLOBAL keyword is not supported now");
|
||||
return false;
|
||||
}
|
||||
return handleTxReadOnly(shardingService, valueExpr);
|
||||
case TX_ISOLATION:
|
||||
if (!stmt.toLowerCase().contains("session")) {
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "setting transaction without any SESSION or GLOBAL keyword is not supported now");
|
||||
return false;
|
||||
}
|
||||
return handleTxIsolation(shardingService, valueExpr);
|
||||
case SYSTEM_VARIABLES:
|
||||
if (key.startsWith("@@")) {
|
||||
key = key.substring(2);
|
||||
}
|
||||
if (DbleServer.getInstance().getSystemVariables().getDefaultValue(key) == null) {
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "system variable " + key + " is not supported");
|
||||
return false;
|
||||
}
|
||||
contextTask.add(new Pair<>(KeyType.SYSTEM_VARIABLES, new Pair<>(key, parseVariablesValue(valueExpr))));
|
||||
return true;
|
||||
case USER_VARIABLES:
|
||||
contextTask.add(new Pair<>(KeyType.USER_VARIABLES, new Pair<>(key.toUpperCase(), parseVariablesValue(valueExpr))));
|
||||
return true;
|
||||
default:
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, stmt + " is not supported");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleTxReadOnly(ShardingService shardingService, SQLExpr valueExpr) {
|
||||
Boolean switchStatus = SetInnerHandler.isSwitchOn(valueExpr);
|
||||
if (switchStatus == null) {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_WRONG_TYPE_FOR_VAR, "Incorrect argument type to variable 'tx_read_only|transaction_read_only'");
|
||||
return false;
|
||||
} else if (switchStatus) {
|
||||
shardingService.setSessionReadOnly(true);
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
} else {
|
||||
shardingService.setSessionReadOnly(false);
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean handleTxIsolation(ShardingService service, SQLExpr valueExpr) {
|
||||
String value = SetInnerHandler.parseStringValue(valueExpr);
|
||||
Integer txIsolation = getIsolationLevel(value);
|
||||
if (txIsolation == null) {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "Variable 'tx_isolation|transaction_isolation' can't be set to the value of '" + value + "'");
|
||||
return false;
|
||||
}
|
||||
service.setTxIsolation(txIsolation);
|
||||
service.write(service.getSession2().getOKPacket());
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Integer getIsolationLevel(String value) {
|
||||
switch (value) {
|
||||
case "read-uncommitted":
|
||||
return Isolations.READ_UNCOMMITTED;
|
||||
case "read-committed":
|
||||
return Isolations.READ_COMMITTED;
|
||||
case "repeatable-read":
|
||||
return Isolations.REPEATABLE_READ;
|
||||
case "serializable":
|
||||
return Isolations.SERIALIZABLE;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleCollationConnection(ShardingService service, SQLExpr valueExpr) {
|
||||
String collation = SetInnerHandler.parseStringValue(valueExpr);
|
||||
if (checkCollation(collation)) {
|
||||
service.setCollationConnection(collation);
|
||||
service.write(service.getSession2().getOKPacket());
|
||||
return true;
|
||||
} else {
|
||||
service.writeErrMessage(ErrorCode.ER_UNKNOWN_COLLATION, "Unknown collation '" + collation + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleSingleCharsetResults(ShardingService shardingService, SQLExpr valueExpr) {
|
||||
String charsetResult = SetInnerHandler.parseStringValue(valueExpr);
|
||||
if (charsetResult.equalsIgnoreCase("NULL") || checkCharset(charsetResult)) {
|
||||
shardingService.setCharacterResults(charsetResult);
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
return true;
|
||||
} else {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set '" + charsetResult + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleSingleCharsetConnection(ShardingService shardingService, SQLExpr valueExpr) {
|
||||
String charsetConnection = SetInnerHandler.parseStringValue(valueExpr);
|
||||
if (charsetConnection.equals("null")) {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_WRONG_VALUE_FOR_VAR, "Variable 'character_set_connection' can't be set to the value of 'NULL'");
|
||||
return false;
|
||||
}
|
||||
String collationName = CharsetUtil.getDefaultCollation(charsetConnection);
|
||||
if (collationName != null) {
|
||||
shardingService.setCharacterConnection(collationName);
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
return true;
|
||||
} else {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set '" + charsetConnection + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean handleSingleCharsetClient(ShardingService service, SQLExpr valueExpr) {
|
||||
String charsetClient = SetInnerHandler.parseStringValue(valueExpr);
|
||||
if (charsetClient.equalsIgnoreCase("null")) {
|
||||
service.writeErrMessage(ErrorCode.ER_WRONG_VALUE_FOR_VAR, "Variable 'character_set_client' can't be set to the value of 'NULL'");
|
||||
return false;
|
||||
}
|
||||
if (checkCharset(charsetClient)) {
|
||||
if (!CharsetUtil.checkCharsetClient(charsetClient)) {
|
||||
service.writeErrMessage(ErrorCode.ER_WRONG_VALUE_FOR_VAR, "Variable 'character_set_client' can't be set to the value of '" + charsetClient + "'");
|
||||
return false;
|
||||
} else {
|
||||
service.setCharacterClient(charsetClient);
|
||||
service.write(service.getSession2().getOKPacket());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
service.writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown character set '" + charsetClient + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// druid not support 'set charset' ,change to 'set character set'
|
||||
private static String convertCharsetKeyWord(String stmt) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
@@ -562,7 +238,7 @@ public final class SetHandler {
|
||||
char before = toCheck.charAt(index - 1);
|
||||
char after = toCheck.charAt(index + 7);
|
||||
if ((ParseUtil.isSpace(before) || ',' == before) && ParseUtil.isSpace(after)) {
|
||||
result.append(stmt.substring(tailStart, index));
|
||||
result.append(stmt, tailStart, index);
|
||||
result.append("character set");
|
||||
}
|
||||
tailStart = index + 7;
|
||||
@@ -575,234 +251,40 @@ public final class SetHandler {
|
||||
return stmt;
|
||||
}
|
||||
|
||||
private static String handleSetKey(SQLAssignItem assignItem, ShardingService service) {
|
||||
if (assignItem.getTarget() instanceof SQLPropertyExpr) {
|
||||
SQLPropertyExpr target = (SQLPropertyExpr) assignItem.getTarget();
|
||||
if (!(target.getOwner() instanceof SQLVariantRefExpr)) {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "setting target is not supported for '" + target + "'");
|
||||
return null;
|
||||
}
|
||||
SQLVariantRefExpr owner = (SQLVariantRefExpr) target.getOwner();
|
||||
if (owner.isGlobal()) {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "setting GLOBAL value is not supported");
|
||||
return null;
|
||||
}
|
||||
return target.getName();
|
||||
} else if (assignItem.getTarget() instanceof SQLVariantRefExpr) {
|
||||
SQLVariantRefExpr target = (SQLVariantRefExpr) assignItem.getTarget();
|
||||
if (target.isGlobal()) {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "setting GLOBAL value is not supported");
|
||||
return null;
|
||||
}
|
||||
return target.getName();
|
||||
} else if (assignItem.getTarget() instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr target = (SQLIdentifierExpr) assignItem.getTarget();
|
||||
return target.getLowerName();
|
||||
} else {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "setting target is not supported for '" + assignItem.getTarget() + "'");
|
||||
return null;
|
||||
public static class SetItem {
|
||||
private String name;
|
||||
private String value;
|
||||
private SetHandler.KeyType type;
|
||||
|
||||
public SetItem(String name, String value, SetHandler.KeyType type) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public KeyType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(KeyType type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkValue(SQLExpr valueExpr, KeyType keyType) {
|
||||
if (keyType == KeyType.USER_VARIABLES) {
|
||||
return !(valueExpr instanceof SQLQueryExpr);
|
||||
}
|
||||
return (valueExpr instanceof MySqlCharExpr) || (valueExpr instanceof SQLCharExpr) ||
|
||||
(valueExpr instanceof SQLIdentifierExpr) || (valueExpr instanceof SQLIntegerExpr) ||
|
||||
(valueExpr instanceof SQLNumberExpr) || (valueExpr instanceof SQLBooleanExpr) ||
|
||||
(valueExpr instanceof SQLDefaultExpr) || (valueExpr instanceof SQLNullExpr);
|
||||
}
|
||||
|
||||
private static KeyType parseKeyType(String key, boolean origin, KeyType defaultVariables) {
|
||||
switch (key.toLowerCase()) {
|
||||
case "xa":
|
||||
return KeyType.XA;
|
||||
case "trace":
|
||||
return KeyType.TRACE;
|
||||
case "autocommit":
|
||||
return KeyType.AUTOCOMMIT;
|
||||
case "collation_connection":
|
||||
return KeyType.COLLATION_CONNECTION;
|
||||
case "character_set_client":
|
||||
return KeyType.CHARACTER_SET_CLIENT;
|
||||
case "character_set_results":
|
||||
return KeyType.CHARACTER_SET_RESULTS;
|
||||
case "character_set_connection":
|
||||
return KeyType.CHARACTER_SET_CONNECTION;
|
||||
case VersionUtil.TRANSACTION_ISOLATION:
|
||||
case VersionUtil.TX_ISOLATION:
|
||||
return KeyType.TX_ISOLATION;
|
||||
case VersionUtil.TRANSACTION_READ_ONLY:
|
||||
case VersionUtil.TX_READ_ONLY:
|
||||
return KeyType.TX_READ_ONLY;
|
||||
case "names":
|
||||
return KeyType.NAMES;
|
||||
case "character set":
|
||||
return KeyType.CHARSET;
|
||||
default:
|
||||
if (!origin && key.startsWith("@")) {
|
||||
return KeyType.SYNTAX_ERROR;
|
||||
} else if (key.startsWith("@@")) {
|
||||
return parseKeyType(key.substring(2), false, KeyType.SYSTEM_VARIABLES);
|
||||
} else if (key.startsWith("@")) {
|
||||
return parseKeyType(key.substring(1), false, KeyType.USER_VARIABLES);
|
||||
} else {
|
||||
return defaultVariables;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String parseVariablesValue(SQLExpr valueExpr) {
|
||||
String strValue;
|
||||
if (valueExpr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr value = (SQLIdentifierExpr) valueExpr;
|
||||
strValue = "'" + StringUtil.removeBackQuote(value.getSimpleName().toLowerCase()) + "'";
|
||||
} else if (valueExpr instanceof SQLCharExpr) {
|
||||
SQLCharExpr value = (SQLCharExpr) valueExpr;
|
||||
strValue = "'" + value.getText().toLowerCase() + "'";
|
||||
} else if (valueExpr instanceof SQLIntegerExpr) {
|
||||
SQLIntegerExpr value = (SQLIntegerExpr) valueExpr;
|
||||
strValue = value.getNumber().toString();
|
||||
} else if (valueExpr instanceof SQLNumberExpr) {
|
||||
SQLNumberExpr value = (SQLNumberExpr) valueExpr;
|
||||
strValue = value.getNumber().toString();
|
||||
} else if (valueExpr instanceof SQLBooleanExpr) {
|
||||
SQLBooleanExpr value = (SQLBooleanExpr) valueExpr;
|
||||
strValue = String.valueOf(value.getValue());
|
||||
} else if (valueExpr instanceof SQLDefaultExpr || valueExpr instanceof SQLNullExpr) {
|
||||
strValue = valueExpr.toString();
|
||||
} else {
|
||||
strValue = SQLUtils.toMySqlString(valueExpr);
|
||||
}
|
||||
return strValue;
|
||||
}
|
||||
|
||||
private static String[] parseNamesValue(SQLExpr valueExpr) {
|
||||
if (valueExpr instanceof MySqlCharExpr) {
|
||||
MySqlCharExpr value = (MySqlCharExpr) valueExpr;
|
||||
return new String[]{value.getText().toLowerCase(), StringUtil.removeBackQuote(value.getCollate()).toLowerCase()};
|
||||
} else {
|
||||
String charset = SetInnerHandler.parseStringValue(valueExpr);
|
||||
return new String[]{charset, null};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static boolean handleTransaction(ShardingService service, MySqlSetTransactionStatement setStatement) {
|
||||
//always single
|
||||
if (setStatement.getGlobal() == null) {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "setting transaction without any SESSION or GLOBAL keyword is not supported now");
|
||||
return false;
|
||||
} else if (setStatement.getGlobal()) {
|
||||
service.writeErrMessage(ErrorCode.ERR_NOT_SUPPORTED, "setting GLOBAL value is not supported");
|
||||
return false;
|
||||
} else if (setStatement.getAccessModel() != null) {
|
||||
if (setStatement.getAccessModel().equals("ONLY")) {
|
||||
service.setSessionReadOnly(true);
|
||||
} else {
|
||||
service.setSessionReadOnly(false);
|
||||
}
|
||||
service.write(service.getSession2().getOKPacket());
|
||||
return true;
|
||||
} else {
|
||||
int txIsolation = Isolations.REPEATABLE_READ;
|
||||
switch (setStatement.getIsolationLevel()) {
|
||||
case "READ UNCOMMITTED":
|
||||
txIsolation = Isolations.READ_UNCOMMITTED;
|
||||
break;
|
||||
case "READ COMMITTED":
|
||||
txIsolation = Isolations.READ_COMMITTED;
|
||||
break;
|
||||
case "REPEATABLE READ":
|
||||
txIsolation = Isolations.REPEATABLE_READ;
|
||||
break;
|
||||
case "SERIALIZABLE":
|
||||
txIsolation = Isolations.SERIALIZABLE;
|
||||
break;
|
||||
default:
|
||||
// can't be happened
|
||||
break;
|
||||
}
|
||||
service.setTxIsolation(txIsolation);
|
||||
service.write(service.getSession2().getOKPacket());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkCollation(String collation) {
|
||||
int ci = CharsetUtil.getCollationIndex(collation);
|
||||
return ci > 0;
|
||||
}
|
||||
|
||||
private static boolean checkCharset(String name) {
|
||||
int ci = CharsetUtil.getCharsetDefaultIndex(name);
|
||||
return ci > 0;
|
||||
}
|
||||
|
||||
private static String getCharset(String charset) {
|
||||
if (charset.toLowerCase().equals("default")) {
|
||||
charset = SystemConfig.getInstance().getCharset();
|
||||
}
|
||||
charset = StringUtil.removeApostropheOrBackQuote(charset.toLowerCase());
|
||||
if (checkCharset(charset)) {
|
||||
return charset;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static boolean checkSetNamesSyntax(String stmt) {
|
||||
//druid parser can't find syntax error,use regex to check again, but it is not strict
|
||||
String regex = "set\\s+names\\s+[`']?[a-zA-Z_0-9]+[`']?(\\s+collate\\s+[`']?[a-zA-Z_0-9]+[`']?)?;?\\s*$";
|
||||
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
|
||||
Matcher ma = pattern.matcher(stmt);
|
||||
return ma.find();
|
||||
}
|
||||
|
||||
private static NamesInfo checkSetNames(String stmt, String charset, String collate) {
|
||||
if (collate == null && !(checkSetNamesSyntax(stmt))) {
|
||||
return null;
|
||||
}
|
||||
if (charset.toLowerCase().equals("default")) {
|
||||
charset = SystemConfig.getInstance().getCharset();
|
||||
} else {
|
||||
charset = StringUtil.removeApostropheOrBackQuote(charset.toLowerCase());
|
||||
if (!checkCharset(charset)) {
|
||||
return new NamesInfo(null, null);
|
||||
}
|
||||
}
|
||||
if (collate == null) {
|
||||
collate = CharsetUtil.getDefaultCollation(charset);
|
||||
} else {
|
||||
collate = collate.toLowerCase();
|
||||
if (collate.equals("default")) {
|
||||
collate = CharsetUtil.getDefaultCollation(charset);
|
||||
} else {
|
||||
int collateIndex = CharsetUtil.getCollationIndexByCharset(charset, collate);
|
||||
if (collateIndex == 0) {
|
||||
return new NamesInfo(null, null);
|
||||
} else if (collateIndex < 0) {
|
||||
return new NamesInfo(charset, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
NamesInfo namesInfo = new NamesInfo(charset, collate);
|
||||
if (!CharsetUtil.checkCharsetClient(charset)) {
|
||||
namesInfo.isSupport = false;
|
||||
}
|
||||
return namesInfo;
|
||||
}
|
||||
|
||||
private static class NamesInfo {
|
||||
private String charset;
|
||||
private String collation;
|
||||
private boolean isSupport = true;
|
||||
|
||||
NamesInfo(String charset, String collation) {
|
||||
this.charset = charset;
|
||||
this.collation = collation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
package com.actiontech.dble.server.handler;
|
||||
|
||||
import com.actiontech.dble.config.ErrorCode;
|
||||
import com.actiontech.dble.log.transaction.TxnLogHelper;
|
||||
import com.actiontech.dble.route.parser.util.Pair;
|
||||
import com.actiontech.dble.services.mysqlsharding.ShardingService;
|
||||
import com.actiontech.dble.util.StringUtil;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by szf on 2020/3/24.
|
||||
*/
|
||||
public final class SetInnerHandler {
|
||||
|
||||
|
||||
private SetInnerHandler() {
|
||||
|
||||
}
|
||||
|
||||
public static boolean handleSingleXA(ShardingService shardingService, SQLExpr valueExpr) {
|
||||
List<Pair<SetHandler.KeyType, Pair<String, String>>> innerSetTask = new ArrayList<>();
|
||||
if (preHandleSingleXA(shardingService, valueExpr, innerSetTask)) {
|
||||
String key = innerSetTask.get(0).getValue().getKey();
|
||||
shardingService.getSession2().getTransactionManager().setXaTxEnabled(Boolean.valueOf(key), shardingService);
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean preHandleSingleXA(ShardingService shardingService, SQLExpr valueExpr, List<Pair<SetHandler.KeyType, Pair<String, String>>> innerSetTask) {
|
||||
Boolean switchStatus = isSwitchOn(valueExpr);
|
||||
if (switchStatus == null) {
|
||||
shardingService.writeErrMessage(ErrorCode.ER_WRONG_TYPE_FOR_VAR, "Incorrect argument type to variable 'XA'");
|
||||
return false;
|
||||
} else if (switchStatus) {
|
||||
if (shardingService.getSession2().getTargetMap().size() > 0 && shardingService.getSession2().getSessionXaID() == null) {
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_WRONG_USED, "you can't set xa cmd on when there are unfinished operation in the session.");
|
||||
return false;
|
||||
}
|
||||
innerSetTask.add(new Pair<>(SetHandler.KeyType.XA, new Pair<String, String>("true", null)));
|
||||
return true;
|
||||
} else {
|
||||
if (shardingService.getSession2().getTargetMap().size() > 0 && shardingService.getSession2().getSessionXaID() != null) {
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_WRONG_USED, "you can't set xa cmd off when a transaction is in progress.");
|
||||
return false;
|
||||
}
|
||||
innerSetTask.add(new Pair<>(SetHandler.KeyType.XA, new Pair<String, String>("false", null)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean handleSingleTrace(ShardingService shardingService, SQLExpr valueExpr) {
|
||||
List<Pair<SetHandler.KeyType, Pair<String, String>>> innerSetTask = new ArrayList<>();
|
||||
if (preHandleSingleTrace(shardingService, valueExpr, innerSetTask)) {
|
||||
String key = innerSetTask.get(0).getValue().getKey();
|
||||
shardingService.getSession2().setTrace(Boolean.valueOf(key));
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static boolean preHandleSingleTrace(ShardingService service, SQLExpr valueExpr, List<Pair<SetHandler.KeyType, Pair<String, String>>> innerSetTask) {
|
||||
Boolean switchStatus = isSwitchOn(valueExpr);
|
||||
if (switchStatus == null) {
|
||||
service.writeErrMessage(ErrorCode.ER_WRONG_TYPE_FOR_VAR, "Incorrect argument type to variable 'TRACE'");
|
||||
return false;
|
||||
} else {
|
||||
innerSetTask.add(new Pair<>(SetHandler.KeyType.TRACE, new Pair<String, String>("" + switchStatus, null)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean handleSingleAutocommit(String stmt, ShardingService service, SQLExpr valueExpr) {
|
||||
List<Pair<SetHandler.KeyType, Pair<String, String>>> innerSetTask = new ArrayList<>();
|
||||
if (preHandleAutocommit(service, valueExpr, innerSetTask)) {
|
||||
String key = innerSetTask.get(0).getValue().getKey();
|
||||
if (!execSetAutoCommit(stmt, service, Boolean.valueOf(key))) {
|
||||
service.write(service.getSession2().getOKPacket());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static boolean preHandleAutocommit(ShardingService service, SQLExpr valueExpr, List<Pair<SetHandler.KeyType,
|
||||
Pair<String, String>>> innerSetTask) {
|
||||
Boolean switchStatus = isSwitchOn(valueExpr);
|
||||
if (switchStatus == null) {
|
||||
service.writeErrMessage(ErrorCode.ER_WRONG_TYPE_FOR_VAR, "Incorrect argument type to variable 'AUTOCOMMIT'");
|
||||
return false;
|
||||
} else {
|
||||
innerSetTask.add(new Pair<>(SetHandler.KeyType.AUTOCOMMIT, new Pair<String, String>("" + switchStatus, null)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean execSetAutoCommit(String stmt, ShardingService shardingService, boolean setValue) {
|
||||
if (setValue) {
|
||||
if (!shardingService.isAutocommit() && shardingService.getSession2().getTargetCount() > 0) {
|
||||
shardingService.getSession2().implicitCommit(() -> {
|
||||
shardingService.setAutocommit(true);
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
});
|
||||
return true;
|
||||
}
|
||||
shardingService.setAutocommit(true);
|
||||
} else {
|
||||
if (shardingService.isAutocommit()) {
|
||||
shardingService.setAutocommit(false);
|
||||
TxnLogHelper.putTxnLog(shardingService, stmt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static Boolean isSwitchOn(SQLExpr valueExpr) {
|
||||
if (valueExpr instanceof SQLIntegerExpr) {
|
||||
SQLIntegerExpr value = (SQLIntegerExpr) valueExpr;
|
||||
int iValue = value.getNumber().intValue();
|
||||
if (iValue < 0 || iValue > 1) {
|
||||
return null;
|
||||
}
|
||||
return (iValue == 1);
|
||||
} else if (valueExpr instanceof SQLBooleanExpr) {
|
||||
SQLBooleanExpr value = (SQLBooleanExpr) valueExpr;
|
||||
return value.getValue();
|
||||
}
|
||||
String strValue = parseStringValue(valueExpr);
|
||||
switch (strValue) {
|
||||
case "on":
|
||||
return true;
|
||||
case "off":
|
||||
return false;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String parseStringValue(SQLExpr valueExpr) {
|
||||
String strValue = "";
|
||||
if (valueExpr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr value = (SQLIdentifierExpr) valueExpr;
|
||||
strValue = StringUtil.removeBackQuote(value.getSimpleName().toLowerCase());
|
||||
} else if (valueExpr instanceof SQLCharExpr) {
|
||||
SQLCharExpr value = (SQLCharExpr) valueExpr;
|
||||
strValue = value.getText().toLowerCase();
|
||||
} else if (valueExpr instanceof SQLIntegerExpr) {
|
||||
SQLIntegerExpr value = (SQLIntegerExpr) valueExpr;
|
||||
strValue = value.getNumber().toString();
|
||||
} else if (valueExpr instanceof SQLDefaultExpr || valueExpr instanceof SQLNullExpr) {
|
||||
strValue = valueExpr.toString();
|
||||
}
|
||||
return strValue;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public final class UseHandler {
|
||||
service.setSchema(schema);
|
||||
service.getSession2().setRowCount(0);
|
||||
|
||||
service.write(service.getSession2().getOKPacket());
|
||||
service.writeOkPacket();
|
||||
}
|
||||
|
||||
public static String getSchemaName(String sql, int offset) {
|
||||
|
||||
@@ -126,7 +126,7 @@ public final class ShowTables {
|
||||
List<FieldPacket> fieldPackets = new ArrayList<>(2);
|
||||
bufInf = writeFullTablesHeader(buffer, shardingService, schemaColumn, fieldPackets);
|
||||
if (info.getWhere() != null) {
|
||||
MySQLItemVisitor mev = new MySQLItemVisitor(shardingService.getSchema(), shardingService.getCharset().getResultsIndex(), ProxyMeta.getInstance().getTmManager(), shardingService.equivalentUsrVarMap());
|
||||
MySQLItemVisitor mev = new MySQLItemVisitor(shardingService.getSchema(), shardingService.getCharset().getResultsIndex(), ProxyMeta.getInstance().getTmManager(), shardingService.getUsrVariables());
|
||||
info.getWhereExpr().accept(mev);
|
||||
List<Field> sourceFields = HandlerTool.createFields(fieldPackets);
|
||||
Item whereItem = HandlerTool.createItem(mev.getItem(), sourceFields, 0, false, DMLResponseHandler.HandlerType.WHERE);
|
||||
|
||||
@@ -17,7 +17,7 @@ public final class SptExecute {
|
||||
|
||||
public static String queryUserVar(String name, ShardingService service) {
|
||||
String key = "@" + name;
|
||||
return service.equivalentUsrVarMap().get(key);
|
||||
return service.getUsrVariables().get(key);
|
||||
}
|
||||
|
||||
public static void response(ShardingService service) {
|
||||
|
||||
227
src/main/java/com/actiontech/dble/server/util/SetItemUtil.java
Normal file
227
src/main/java/com/actiontech/dble/server/util/SetItemUtil.java
Normal file
@@ -0,0 +1,227 @@
|
||||
package com.actiontech.dble.server.util;
|
||||
|
||||
import com.actiontech.dble.backend.mysql.CharsetUtil;
|
||||
import com.actiontech.dble.config.Isolations;
|
||||
import com.actiontech.dble.config.model.SystemConfig;
|
||||
import com.actiontech.dble.util.StringUtil;
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
|
||||
|
||||
import java.sql.SQLSyntaxErrorException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class SetItemUtil {
|
||||
|
||||
private SetItemUtil() {
|
||||
}
|
||||
|
||||
public static String getBooleanVal(SQLExpr valueExpr) throws SQLSyntaxErrorException {
|
||||
String strValue = parseStringValue(valueExpr);
|
||||
switch (strValue) {
|
||||
case "1":
|
||||
case "on":
|
||||
return "true";
|
||||
case "0":
|
||||
case "off":
|
||||
return "false";
|
||||
default:
|
||||
throw new SQLSyntaxErrorException("illegal value[" + strValue + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public static String getIsolationVal(SQLExpr valueExpr) throws SQLSyntaxErrorException {
|
||||
String value = parseStringValue(valueExpr);
|
||||
switch (value) {
|
||||
case "read-uncommitted":
|
||||
case "read uncommitted":
|
||||
return Isolations.READ_UNCOMMITTED + "";
|
||||
case "read-committed":
|
||||
case "read committed":
|
||||
return Isolations.READ_COMMITTED + "";
|
||||
case "repeatable-read":
|
||||
case "repeatable read":
|
||||
return Isolations.REPEATABLE_READ + "";
|
||||
case "serializable":
|
||||
return Isolations.SERIALIZABLE + "";
|
||||
default:
|
||||
throw new SQLSyntaxErrorException("Variable 'tx_isolation|transaction_isolation' can't be set to the value of '" + value + "'");
|
||||
}
|
||||
}
|
||||
|
||||
public static String getCharsetClientVal(SQLExpr valueExpr) throws SQLSyntaxErrorException {
|
||||
String charsetClient = parseStringValue(valueExpr);
|
||||
if (charsetClient == null || charsetClient.equalsIgnoreCase("null")) {
|
||||
throw new SQLSyntaxErrorException("Variable 'character_set_client' can't be set to the value of 'NULL'");
|
||||
} else if (checkCharset(charsetClient)) {
|
||||
if (!CharsetUtil.checkCharsetClient(charsetClient)) {
|
||||
throw new SQLSyntaxErrorException("Variable 'character_set_client' can't be set to the value of '" + charsetClient + "'");
|
||||
}
|
||||
} else {
|
||||
throw new SQLSyntaxErrorException("Unknown character set '" + charsetClient + "'");
|
||||
}
|
||||
return charsetClient;
|
||||
}
|
||||
|
||||
public static String getCharsetResultsVal(SQLExpr valueExpr) throws SQLSyntaxErrorException {
|
||||
String charsetResult = parseStringValue(valueExpr);
|
||||
if (!charsetResult.equalsIgnoreCase("NULL") && !checkCharset(charsetResult)) {
|
||||
throw new SQLSyntaxErrorException("Unknown character set '" + charsetResult + "'");
|
||||
}
|
||||
return charsetResult;
|
||||
}
|
||||
|
||||
public static String getCollationVal(SQLExpr valueExpr) throws SQLSyntaxErrorException {
|
||||
String collation = parseStringValue(valueExpr);
|
||||
if (!checkCollation(collation)) {
|
||||
throw new SQLSyntaxErrorException("Unknown collation '" + collation + "'");
|
||||
}
|
||||
return collation;
|
||||
}
|
||||
|
||||
public static String getCharsetConnectionVal(SQLExpr valueExpr) throws SQLSyntaxErrorException {
|
||||
String charsetConnection = parseStringValue(valueExpr);
|
||||
if (charsetConnection.equals("null")) {
|
||||
throw new SQLSyntaxErrorException("Variable 'character_set_connection' can't be set to the value of 'NULL'");
|
||||
}
|
||||
String collationName = CharsetUtil.getDefaultCollation(charsetConnection);
|
||||
if (collationName == null) {
|
||||
throw new SQLSyntaxErrorException("Unknown character set '" + charsetConnection + "'");
|
||||
}
|
||||
return charsetConnection;
|
||||
}
|
||||
|
||||
public static String getCharsetVal(SQLExpr valueExpr) throws SQLSyntaxErrorException {
|
||||
String charsetValue = parseStringValue(valueExpr);
|
||||
if (charsetValue == null || charsetValue.equalsIgnoreCase("null")) {
|
||||
throw new SQLSyntaxErrorException("Unknown character set null");
|
||||
}
|
||||
String charset = getCharset(charsetValue);
|
||||
if (charset != null) {
|
||||
if (!CharsetUtil.checkCharsetClient(charset)) {
|
||||
throw new SQLSyntaxErrorException("Variable 'character set' can't be set to the value of '" + charset + "'");
|
||||
}
|
||||
} else {
|
||||
throw new SQLSyntaxErrorException("Unknown character set");
|
||||
}
|
||||
return charset;
|
||||
}
|
||||
|
||||
private static boolean checkSetNamesSyntax(String stmt) {
|
||||
//druid parser can't find syntax error,use regex to check again, but it is not strict
|
||||
String regex = "set\\s+names\\s+[`']?[a-zA-Z_0-9]+[`']?(\\s+collate\\s+[`']?[a-zA-Z_0-9]+[`']?)?;?\\s*$";
|
||||
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
|
||||
Matcher ma = pattern.matcher(stmt);
|
||||
return ma.find();
|
||||
}
|
||||
|
||||
public static String getNamesVal(SQLExpr valueExpr) throws SQLSyntaxErrorException {
|
||||
String charset;
|
||||
String collate = null;
|
||||
if (valueExpr instanceof MySqlCharExpr) {
|
||||
MySqlCharExpr value = (MySqlCharExpr) valueExpr;
|
||||
charset = value.getText().toLowerCase();
|
||||
collate = StringUtil.removeBackQuote(value.getCollate()).toLowerCase();
|
||||
} else {
|
||||
charset = parseStringValue(valueExpr);
|
||||
}
|
||||
|
||||
if (charset.toLowerCase().equals("default")) {
|
||||
charset = SystemConfig.getInstance().getCharset();
|
||||
} else {
|
||||
charset = StringUtil.removeApostropheOrBackQuote(charset.toLowerCase());
|
||||
if (!checkCharset(charset)) {
|
||||
throw new SQLSyntaxErrorException("Unknown character set '" + charset + " or collate '" + collate + "'");
|
||||
}
|
||||
}
|
||||
if (collate == null) {
|
||||
collate = CharsetUtil.getDefaultCollation(charset);
|
||||
} else {
|
||||
collate = collate.toLowerCase();
|
||||
if (collate.equals("default")) {
|
||||
collate = CharsetUtil.getDefaultCollation(charset);
|
||||
} else {
|
||||
int collateIndex = CharsetUtil.getCollationIndexByCharset(charset, collate);
|
||||
if (collateIndex == 0) {
|
||||
throw new SQLSyntaxErrorException("Unknown character set '" + charset + " or collate '" + collate + "'");
|
||||
} else if (collateIndex < 0) {
|
||||
throw new SQLSyntaxErrorException("COLLATION '" + collate + "' is not valid for CHARACTER SET '" + charset + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CharsetUtil.checkCharsetClient(charset)) {
|
||||
throw new SQLSyntaxErrorException("Variable 'names' can't be set to the value of '" + charset + "'");
|
||||
}
|
||||
|
||||
return charset + ":" + collate;
|
||||
}
|
||||
|
||||
private static String getCharset(String charset) {
|
||||
if (charset.toLowerCase().equals("default")) {
|
||||
charset = SystemConfig.getInstance().getCharset();
|
||||
}
|
||||
charset = StringUtil.removeApostropheOrBackQuote(charset.toLowerCase());
|
||||
if (checkCharset(charset)) {
|
||||
return charset;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean checkCharset(String name) {
|
||||
int ci = CharsetUtil.getCharsetDefaultIndex(name);
|
||||
return ci > 0;
|
||||
}
|
||||
|
||||
private static boolean checkCollation(String collation) {
|
||||
int ci = CharsetUtil.getCollationIndex(collation);
|
||||
return ci > 0;
|
||||
}
|
||||
|
||||
private static String parseStringValue(SQLExpr valueExpr) {
|
||||
String strValue = null;
|
||||
if (valueExpr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr value = (SQLIdentifierExpr) valueExpr;
|
||||
strValue = StringUtil.removeBackQuote(value.getSimpleName().toLowerCase());
|
||||
} else if (valueExpr instanceof SQLCharExpr) {
|
||||
SQLCharExpr value = (SQLCharExpr) valueExpr;
|
||||
strValue = value.getText().toLowerCase();
|
||||
} else if (valueExpr instanceof SQLIntegerExpr) {
|
||||
SQLIntegerExpr value = (SQLIntegerExpr) valueExpr;
|
||||
strValue = value.getNumber().toString();
|
||||
} else if (valueExpr instanceof SQLDefaultExpr || valueExpr instanceof SQLNullExpr) {
|
||||
strValue = valueExpr.toString();
|
||||
} else if (valueExpr instanceof SQLBooleanExpr) {
|
||||
strValue = valueExpr.toString();
|
||||
}
|
||||
return strValue;
|
||||
}
|
||||
|
||||
public static String parseVariablesValue(SQLExpr valueExpr) {
|
||||
String strValue;
|
||||
if (valueExpr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr value = (SQLIdentifierExpr) valueExpr;
|
||||
strValue = "'" + StringUtil.removeBackQuote(value.getSimpleName().toLowerCase()) + "'";
|
||||
} else if (valueExpr instanceof SQLCharExpr) {
|
||||
SQLCharExpr value = (SQLCharExpr) valueExpr;
|
||||
strValue = "'" + value.getText().toLowerCase() + "'";
|
||||
} else if (valueExpr instanceof SQLIntegerExpr) {
|
||||
SQLIntegerExpr value = (SQLIntegerExpr) valueExpr;
|
||||
strValue = value.getNumber().toString();
|
||||
} else if (valueExpr instanceof SQLNumberExpr) {
|
||||
SQLNumberExpr value = (SQLNumberExpr) valueExpr;
|
||||
strValue = value.getNumber().toString();
|
||||
} else if (valueExpr instanceof SQLBooleanExpr) {
|
||||
SQLBooleanExpr value = (SQLBooleanExpr) valueExpr;
|
||||
strValue = String.valueOf(value.getValue());
|
||||
} else if (valueExpr instanceof SQLDefaultExpr || valueExpr instanceof SQLNullExpr) {
|
||||
strValue = valueExpr.toString();
|
||||
} else {
|
||||
strValue = SQLUtils.toMySqlString(valueExpr);
|
||||
}
|
||||
return strValue;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,17 +3,14 @@ package com.actiontech.dble.services;
|
||||
import com.actiontech.dble.DbleServer;
|
||||
import com.actiontech.dble.config.model.user.UserConfig;
|
||||
import com.actiontech.dble.net.connection.AbstractConnection;
|
||||
import com.actiontech.dble.net.mysql.CharsetNames;
|
||||
import com.actiontech.dble.net.mysql.ErrorPacket;
|
||||
import com.actiontech.dble.net.mysql.OkPacket;
|
||||
import com.actiontech.dble.net.service.AbstractService;
|
||||
import com.actiontech.dble.net.service.ServiceTask;
|
||||
import com.actiontech.dble.util.CompressUtil;
|
||||
import com.actiontech.dble.util.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
/**
|
||||
@@ -23,9 +20,6 @@ public abstract class MySQLBasedService extends AbstractService {
|
||||
|
||||
protected UserConfig userConfig;
|
||||
|
||||
protected volatile List<Map<String, String>> usrVariables = new ArrayList<>();
|
||||
protected volatile List<Map<String, String>> sysVariables = new ArrayList<>();
|
||||
|
||||
public MySQLBasedService(AbstractConnection connection) {
|
||||
super(connection);
|
||||
}
|
||||
@@ -40,7 +34,6 @@ public abstract class MySQLBasedService extends AbstractService {
|
||||
DbleServer.getInstance().getFrontHandlerQueue().offer(task);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleData(ServiceTask task) {
|
||||
ServiceTask executeTask = null;
|
||||
@@ -87,8 +80,12 @@ public abstract class MySQLBasedService extends AbstractService {
|
||||
return userConfig;
|
||||
}
|
||||
|
||||
public CharsetNames getCharset() {
|
||||
return connection.getCharsetName();
|
||||
public void writeOkPacket() {
|
||||
OkPacket ok = new OkPacket();
|
||||
byte packet = (byte) this.getPacketId().incrementAndGet();
|
||||
ok.read(OkPacket.OK);
|
||||
ok.setPacketId(packet);
|
||||
write(ok);
|
||||
}
|
||||
|
||||
public void writeErrMessage(String code, String msg, int vendorCode) {
|
||||
@@ -113,62 +110,4 @@ public abstract class MySQLBasedService extends AbstractService {
|
||||
err.write(connection);
|
||||
}
|
||||
|
||||
public String getStringOfSysVariables() {
|
||||
StringBuilder sbSysVariables = new StringBuilder();
|
||||
int cnt = 0;
|
||||
if (sysVariables != null) {
|
||||
for (Map<String, String> oneLineVar : sysVariables) {
|
||||
for (Map.Entry sysVariable : oneLineVar.entrySet()) {
|
||||
if (cnt > 0) {
|
||||
sbSysVariables.append(",");
|
||||
}
|
||||
sbSysVariables.append(sysVariable.getKey());
|
||||
sbSysVariables.append("=");
|
||||
sbSysVariables.append(sysVariable.getValue());
|
||||
cnt++;
|
||||
}
|
||||
sbSysVariables.append(";");
|
||||
}
|
||||
}
|
||||
return sbSysVariables.toString();
|
||||
}
|
||||
|
||||
public String getStringOfUsrVariables() {
|
||||
StringBuilder sbUsrVariables = new StringBuilder();
|
||||
int cnt = 0;
|
||||
if (usrVariables != null) {
|
||||
for (Map<String, String> oneLineVar : usrVariables) {
|
||||
for (Map.Entry usrVariable : oneLineVar.entrySet()) {
|
||||
if (cnt > 0) {
|
||||
sbUsrVariables.append(",");
|
||||
}
|
||||
sbUsrVariables.append(usrVariable.getKey());
|
||||
sbUsrVariables.append("=");
|
||||
sbUsrVariables.append(usrVariable.getValue());
|
||||
cnt++;
|
||||
}
|
||||
sbUsrVariables.append(";");
|
||||
}
|
||||
}
|
||||
return sbUsrVariables.toString();
|
||||
}
|
||||
|
||||
|
||||
public Map<String, String> equivalentUsrVarMap() {
|
||||
Map<String, String> result = new LinkedHashMap<>();
|
||||
for (int i = 0; i < usrVariables.size(); i++) {
|
||||
result.putAll(usrVariables.get(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, String> equivalentSysVarMap() {
|
||||
Map<String, String> result = new LinkedHashMap<>();
|
||||
for (int i = 0; i < sysVariables.size(); i++) {
|
||||
result.putAll(sysVariables.get(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
package com.actiontech.dble.services;
|
||||
|
||||
import com.actiontech.dble.net.connection.AbstractConnection;
|
||||
import com.actiontech.dble.net.mysql.CharsetNames;
|
||||
import com.actiontech.dble.server.handler.SetHandler;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by szf on 2020/6/28.
|
||||
*/
|
||||
public abstract class MySQLVariablesService extends MySQLBasedService {
|
||||
|
||||
protected volatile Map<String, String> usrVariables = new LinkedHashMap<>();
|
||||
protected volatile Map<String, String> sysVariables = new LinkedHashMap<>();
|
||||
|
||||
protected volatile int txIsolation;
|
||||
protected volatile boolean autocommit;
|
||||
|
||||
public MySQLVariablesService(AbstractConnection connection) {
|
||||
super(connection);
|
||||
}
|
||||
|
||||
public void executeContextSetTask(SetHandler.SetItem[] contextTask) {
|
||||
SetHandler.SetItem autocommitItem = null;
|
||||
for (SetHandler.SetItem setItem : contextTask) {
|
||||
switch (setItem.getType()) {
|
||||
case CHARACTER_SET_CLIENT:
|
||||
String charsetClient = setItem.getValue();
|
||||
this.setCharacterClient(charsetClient);
|
||||
break;
|
||||
case CHARACTER_SET_CONNECTION:
|
||||
String collationName = setItem.getValue();
|
||||
this.setCharacterConnection(collationName);
|
||||
break;
|
||||
case CHARACTER_SET_RESULTS:
|
||||
String charsetResult = setItem.getValue();
|
||||
this.setCharacterResults(charsetResult);
|
||||
break;
|
||||
case COLLATION_CONNECTION:
|
||||
String collation = setItem.getValue();
|
||||
this.setCollationConnection(collation);
|
||||
break;
|
||||
case TX_ISOLATION:
|
||||
String isolationLevel = setItem.getValue();
|
||||
this.setTxIsolation(Integer.parseInt(isolationLevel));
|
||||
break;
|
||||
case SYSTEM_VARIABLES:
|
||||
this.sysVariables.put(setItem.getName(), setItem.getValue());
|
||||
break;
|
||||
case USER_VARIABLES:
|
||||
if (setItem.getValue() != null) {
|
||||
this.usrVariables.put(setItem.getName(), setItem.getValue());
|
||||
}
|
||||
break;
|
||||
case CHARSET:
|
||||
this.setCharacterSet(setItem.getValue());
|
||||
break;
|
||||
case NAMES:
|
||||
String[] charsetAndCollate = setItem.getValue().split(":");
|
||||
this.setNames(charsetAndCollate[0], charsetAndCollate[1]);
|
||||
break;
|
||||
case AUTOCOMMIT:
|
||||
autocommitItem = setItem;
|
||||
break;
|
||||
default:
|
||||
handleSetItem(setItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (autocommitItem == null) {
|
||||
writeOkPacket();
|
||||
} else {
|
||||
handleSetItem(autocommitItem);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void handleSetItem(SetHandler.SetItem setItem);
|
||||
|
||||
public void setCollationConnection(String collation) {
|
||||
connection.getCharsetName().setCollation(collation);
|
||||
}
|
||||
|
||||
public void setCharacterResults(String name) {
|
||||
connection.getCharsetName().setResults(name);
|
||||
}
|
||||
|
||||
public void setCharacterConnection(String collationName) {
|
||||
connection.getCharsetName().setCollation(collationName);
|
||||
}
|
||||
|
||||
public void setNames(String name, String collationName) {
|
||||
connection.getCharsetName().setNames(name, collationName);
|
||||
}
|
||||
|
||||
public void setCharacterClient(String name) {
|
||||
connection.getCharsetName().setClient(name);
|
||||
}
|
||||
|
||||
public int getTxIsolation() {
|
||||
return txIsolation;
|
||||
}
|
||||
|
||||
public void setTxIsolation(int txIsolation) {
|
||||
this.txIsolation = txIsolation;
|
||||
}
|
||||
|
||||
public void setCharacterSet(String name) {
|
||||
connection.setCharacterSet(name);
|
||||
}
|
||||
|
||||
public CharsetNames getCharset() {
|
||||
return connection.getCharsetName();
|
||||
}
|
||||
|
||||
public boolean isAutocommit() {
|
||||
return autocommit;
|
||||
}
|
||||
|
||||
public void setAutocommit(boolean autocommit) {
|
||||
this.autocommit = autocommit;
|
||||
}
|
||||
|
||||
public Map<String, String> getSysVariables() {
|
||||
return sysVariables;
|
||||
}
|
||||
|
||||
public Map<String, String> getUsrVariables() {
|
||||
return usrVariables;
|
||||
}
|
||||
|
||||
public String getStringOfSysVariables() {
|
||||
StringBuilder sbSysVariables = new StringBuilder();
|
||||
int cnt = 0;
|
||||
if (sysVariables != null) {
|
||||
for (Map.Entry<String, String> entry : sysVariables.entrySet()) {
|
||||
if (cnt > 0) {
|
||||
sbSysVariables.append(",");
|
||||
}
|
||||
sbSysVariables.append(entry.getKey());
|
||||
sbSysVariables.append("=");
|
||||
sbSysVariables.append(entry.getValue());
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
return sbSysVariables.toString();
|
||||
}
|
||||
|
||||
public String getStringOfUsrVariables() {
|
||||
StringBuilder sbUsrVariables = new StringBuilder();
|
||||
int cnt = 0;
|
||||
if (usrVariables != null) {
|
||||
for (Map.Entry<String, String> entry : usrVariables.entrySet()) {
|
||||
if (cnt > 0) {
|
||||
sbUsrVariables.append(",");
|
||||
}
|
||||
sbUsrVariables.append(entry.getKey());
|
||||
sbUsrVariables.append("=");
|
||||
sbUsrVariables.append(entry.getValue());
|
||||
cnt++;
|
||||
|
||||
}
|
||||
}
|
||||
return sbUsrVariables.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -12,7 +12,8 @@ import com.actiontech.dble.net.connection.FrontendConnection;
|
||||
import com.actiontech.dble.net.mysql.*;
|
||||
import com.actiontech.dble.net.service.AuthResultInfo;
|
||||
import com.actiontech.dble.net.service.FrontEndService;
|
||||
import com.actiontech.dble.services.MySQLBasedService;
|
||||
import com.actiontech.dble.server.handler.SetHandler;
|
||||
import com.actiontech.dble.services.MySQLVariablesService;
|
||||
import com.actiontech.dble.services.manager.information.ManagerSchemaInfo;
|
||||
import com.actiontech.dble.singleton.FrontendUserManager;
|
||||
import com.actiontech.dble.singleton.TraceManager;
|
||||
@@ -23,7 +24,7 @@ import java.io.UnsupportedEncodingException;
|
||||
/**
|
||||
* Created by szf on 2020/6/28.
|
||||
*/
|
||||
public class ManagerService extends MySQLBasedService implements FrontEndService {
|
||||
public class ManagerService extends MySQLVariablesService implements FrontEndService {
|
||||
|
||||
private final ManagerQueryHandler handler;
|
||||
|
||||
@@ -44,6 +45,11 @@ public class ManagerService extends MySQLBasedService implements FrontEndService
|
||||
this.commands = connection.getProcessor().getCommands();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSetItem(SetHandler.SetItem setItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
public void initFromAuthInfo(AuthResultInfo info) {
|
||||
AuthPacket auth = info.getMysqlAuthPacket();
|
||||
this.user = new UserName(auth.getUser(), auth.getTenant());
|
||||
|
||||
@@ -12,10 +12,9 @@ import com.actiontech.dble.config.Fields;
|
||||
import com.actiontech.dble.net.IOProcessor;
|
||||
import com.actiontech.dble.net.connection.FrontendConnection;
|
||||
import com.actiontech.dble.net.mysql.*;
|
||||
import com.actiontech.dble.services.MySQLBasedService;
|
||||
import com.actiontech.dble.services.manager.ManagerService;
|
||||
import com.actiontech.dble.route.factory.RouteStrategyFactory;
|
||||
|
||||
import com.actiontech.dble.services.MySQLVariablesService;
|
||||
import com.actiontech.dble.services.manager.ManagerService;
|
||||
import com.actiontech.dble.services.mysqlsharding.ShardingService;
|
||||
import com.actiontech.dble.util.IntegerUtil;
|
||||
import com.actiontech.dble.util.LongUtil;
|
||||
@@ -247,8 +246,8 @@ public final class ShowConnection {
|
||||
}
|
||||
row.add(txLevel.getBytes());
|
||||
row.add(autocommit.getBytes());
|
||||
row.add(StringUtil.encode(((MySQLBasedService) c.getService()).getStringOfSysVariables(), charset));
|
||||
row.add(StringUtil.encode(((MySQLBasedService) c.getService()).getStringOfUsrVariables(), charset));
|
||||
row.add(StringUtil.encode(((MySQLVariablesService) c.getService()).getStringOfSysVariables(), charset));
|
||||
row.add(StringUtil.encode(((MySQLVariablesService) c.getService()).getStringOfUsrVariables(), charset));
|
||||
return row;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,9 @@ import com.actiontech.dble.net.service.ServiceTask;
|
||||
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.handler.SetHandler;
|
||||
import com.actiontech.dble.server.parser.ServerParse;
|
||||
import com.actiontech.dble.services.MySQLBasedService;
|
||||
import com.actiontech.dble.services.MySQLVariablesService;
|
||||
import com.actiontech.dble.services.rwsplit.MysqlPrepareLogicHandler;
|
||||
import com.actiontech.dble.services.rwsplit.RWSplitService;
|
||||
import com.actiontech.dble.singleton.TraceManager;
|
||||
@@ -33,6 +34,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -45,7 +47,7 @@ import java.util.concurrent.locks.LockSupport;
|
||||
/**
|
||||
* Created by szf on 2020/6/29.
|
||||
*/
|
||||
public class MySQLResponseService extends MySQLBasedService {
|
||||
public class MySQLResponseService extends MySQLVariablesService {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MySQLResponseService.class);
|
||||
|
||||
private ResponseHandler responseHandler;
|
||||
@@ -66,8 +68,6 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
private volatile boolean prepareOK = false;
|
||||
private volatile boolean testing = false;
|
||||
private volatile StatusSync statusSync;
|
||||
private volatile boolean autocommit;
|
||||
private volatile int txIsolation;
|
||||
private volatile boolean isRowDataFlowing = false;
|
||||
private volatile BackEndCleaner recycler = null;
|
||||
private volatile TxState xaStatus = TxState.TX_INITIALIZE_STATE;
|
||||
@@ -101,6 +101,10 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
this.prepareLogicHandler = new MysqlPrepareLogicHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSetItem(SetHandler.SetItem setItem) {
|
||||
}
|
||||
|
||||
private void initFromConfig() {
|
||||
this.autocommitSynced = connection.getInstance().isAutocommitSynced();
|
||||
boolean sysAutocommit = SystemConfig.getInstance().getAutocommit() == 1;
|
||||
@@ -112,8 +116,8 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
this.txIsolation = -1;
|
||||
}
|
||||
this.complexQuery = false;
|
||||
this.usrVariables = new ArrayList<>();
|
||||
this.sysVariables = new ArrayList<>();
|
||||
this.usrVariables = new LinkedHashMap<>();
|
||||
this.sysVariables = new LinkedHashMap<>();
|
||||
this.dbuser = connection.getInstance().getConfig().getUser();
|
||||
}
|
||||
|
||||
@@ -327,44 +331,8 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
}
|
||||
}
|
||||
|
||||
private StringBuilder getSynSql(CharsetNames clientCharset, int clientTxIsolation, boolean expectAutocommit) {
|
||||
int schemaSyn = StringUtil.equals(connection.getSchema(), connection.getOldSchema()) || connection.getSchema() == null ? 0 : 1;
|
||||
int charsetSyn = (this.getConnection().getCharsetName().equals(clientCharset)) ? 0 : 1;
|
||||
int txIsolationSyn = (this.txIsolation == clientTxIsolation) ? 0 : 1;
|
||||
int autoCommitSyn = (this.autocommit == expectAutocommit) ? 0 : 1;
|
||||
int synCount = schemaSyn + charsetSyn + txIsolationSyn + autoCommitSyn;
|
||||
if (synCount == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (schemaSyn == 1) {
|
||||
getChangeSchemaCommand(sb, connection.getSchema());
|
||||
}
|
||||
if (charsetSyn == 1) {
|
||||
getCharsetCommand(sb, clientCharset);
|
||||
}
|
||||
if (txIsolationSyn == 1) {
|
||||
getTxIsolationCommand(sb, clientTxIsolation);
|
||||
}
|
||||
if (autoCommitSyn == 1) {
|
||||
getAutocommitCommand(sb, expectAutocommit);
|
||||
}
|
||||
|
||||
metaDataSynced = false;
|
||||
statusSync = new StatusSync(connection.getSchema(),
|
||||
clientCharset, clientTxIsolation, expectAutocommit,
|
||||
synCount, Collections.emptyList(), Collections.emptyList());
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
private StringBuilder getSynSql(String xaTxID, RouteResultsetNode rrn,
|
||||
CharsetNames clientCharset, int clientTxIsolation,
|
||||
boolean expectAutocommit, List<Map<String, String>> usrVariables, List<Map<String, String>> sysVariables) {
|
||||
if (rrn.getSqlType() == ServerParse.DDL) {
|
||||
isDDL = true;
|
||||
}
|
||||
private StringBuilder getSynSql(String xaTxID, RouteResultsetNode rrn, CharsetNames clientCharset, int clientTxIsolation,
|
||||
boolean expectAutocommit, Map<String, String> usrVariables, Map<String, String> sysVariables) {
|
||||
|
||||
int xaSyn = 0;
|
||||
if (!expectAutocommit && xaTxID != null && xaStatus == TxState.TX_INITIALIZE_STATE && !isDDL) {
|
||||
@@ -372,10 +340,11 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
xaSyn = 1;
|
||||
}
|
||||
|
||||
StringBuilder setSql = new StringBuilder();
|
||||
int setSqlFlag = getSetSQL(usrVariables, sysVariables, setSql);
|
||||
Set<String> toResetSys = new HashSet<>();
|
||||
String setSql = getSetSQL(usrVariables, sysVariables, toResetSys);
|
||||
int setSqlFlag = setSql == null ? 0 : 1;
|
||||
int schemaSyn = StringUtil.equals(connection.getSchema(), connection.getOldSchema()) || connection.getSchema() == null ? 0 : 1;
|
||||
int charsetSyn = (this.getConnection().getCharsetName().equals(clientCharset)) ? 0 : 1;
|
||||
int charsetSyn = this.getConnection().getCharsetName().equals(clientCharset) ? 0 : 1;
|
||||
int txIsolationSyn = (this.txIsolation == clientTxIsolation) ? 0 : 1;
|
||||
int autoCommitSyn = (this.autocommit == expectAutocommit) ? 0 : 1;
|
||||
int synCount = schemaSyn + charsetSyn + txIsolationSyn + autoCommitSyn + xaSyn + setSqlFlag;
|
||||
@@ -396,7 +365,7 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
if (autoCommitSyn == 1) {
|
||||
getAutocommitCommand(sb, expectAutocommit);
|
||||
}
|
||||
if (setSqlFlag > 0) {
|
||||
if (setSqlFlag == 1) {
|
||||
sb.append(setSql);
|
||||
}
|
||||
if (xaSyn == 1) {
|
||||
@@ -412,7 +381,7 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
metaDataSynced = false;
|
||||
statusSync = new StatusSync(connection.getSchema(),
|
||||
clientCharset, clientTxIsolation, expectAutocommit,
|
||||
synCount, usrVariables, sysVariables);
|
||||
synCount, usrVariables, sysVariables, toResetSys);
|
||||
return sb;
|
||||
}
|
||||
|
||||
@@ -461,61 +430,60 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
}
|
||||
}
|
||||
|
||||
private int getSetSQL(List<Map<String, String>> usrVars, List<Map<String, String>> sysVars, StringBuilder setSQL) {
|
||||
int totalSize = 0;
|
||||
Map<String, String> tmpSysVars = new HashMap<>(this.equivalentSysVarMap());
|
||||
for (int i = 0; i < usrVars.size(); i++) {
|
||||
//new final var for single set statement from sharding service
|
||||
List<Pair<String, String>> setVars = new ArrayList<>();
|
||||
|
||||
Map<String, String> singleStatementSysVar = sysVars.get(i);
|
||||
Map<String, String> singleStatementUsrVar = usrVars.get(i);
|
||||
if (usrVariables.size() <= i) {
|
||||
//if the backend service has the userVars, means that the connection is hold by the front session till now
|
||||
//the index of the object in the usrVariables must has the same order
|
||||
for (Map.Entry<String, String> entry : singleStatementUsrVar.entrySet()) {
|
||||
private String getSetSQL(Map<String, String> usrVars, Map<String, String> sysVars, Set<String> toResetSys) {
|
||||
//new final var
|
||||
List<Pair<String, String>> setVars = new ArrayList<>();
|
||||
//tmp add all backend sysVariables
|
||||
Map<String, String> tmpSysVars = new HashMap<>(sysVariables);
|
||||
//for all front end sysVariables
|
||||
for (Map.Entry<String, String> entry : sysVars.entrySet()) {
|
||||
if (!tmpSysVars.containsKey(entry.getKey())) {
|
||||
setVars.add(new Pair<>(entry.getKey(), entry.getValue()));
|
||||
} else {
|
||||
String value = tmpSysVars.remove(entry.getKey());
|
||||
//if backend is not equal frontend, need to reset
|
||||
if (!StringUtil.equalsIgnoreCase(entry.getValue(), value)) {
|
||||
setVars.add(new Pair<>(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
if (sysVariables.size() <= i || sysVariables.get(i) != singleStatementSysVar) {
|
||||
//if the sysVariables object has the same, means that the sysVar has been Synchronized
|
||||
//otherwise the all sysVariables should be set to the backend
|
||||
//the benchmark is the tmpSysVars, statement-level-system-vars
|
||||
for (Map.Entry<String, String> entry : singleStatementSysVar.entrySet()) {
|
||||
if (!tmpSysVars.containsKey(entry.getKey())) {
|
||||
setVars.add(new Pair<>(entry.getKey(), entry.getValue()));
|
||||
tmpSysVars.put(entry.getKey(), entry.getValue());
|
||||
} else {
|
||||
String value = tmpSysVars.get(entry.getKey());
|
||||
//if backend is not equal frontend, need to reset
|
||||
if (!StringUtil.equalsIgnoreCase(entry.getValue(), value)) {
|
||||
setVars.add(new Pair<>(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
tmpSysVars.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (setVars.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
totalSize++;
|
||||
setSQL.append("set ");
|
||||
int cnt = 0;
|
||||
for (Pair<String, String> var : setVars) {
|
||||
if (cnt > 0) {
|
||||
setSQL.append(",");
|
||||
}
|
||||
setSQL.append(var.getKey());
|
||||
setSQL.append("=");
|
||||
setSQL.append(var.getValue());
|
||||
cnt++;
|
||||
}
|
||||
setSQL.append(";");
|
||||
}
|
||||
return totalSize;
|
||||
//tmp now = backend -(backend &&frontend)
|
||||
for (Map.Entry<String, String> entry : tmpSysVars.entrySet()) {
|
||||
String value = DbleServer.getInstance().getSystemVariables().getDefaultValue(entry.getKey());
|
||||
try {
|
||||
BigDecimal vl = new BigDecimal(value);
|
||||
} catch (NumberFormatException e) {
|
||||
value = "`" + value + "`";
|
||||
}
|
||||
setVars.add(new Pair<>(entry.getKey(), value));
|
||||
toResetSys.add(entry.getKey());
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : usrVars.entrySet()) {
|
||||
if (!usrVariables.containsKey(entry.getKey())) {
|
||||
setVars.add(new Pair<>(entry.getKey(), entry.getValue()));
|
||||
} else {
|
||||
if (!StringUtil.equalsIgnoreCase(entry.getValue(), usrVariables.get(entry.getKey()))) {
|
||||
setVars.add(new Pair<>(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (setVars.size() == 0)
|
||||
return null;
|
||||
StringBuilder sb = new StringBuilder("set ");
|
||||
int cnt = 0;
|
||||
for (Pair<String, String> var : setVars) {
|
||||
if (cnt > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(var.getKey());
|
||||
sb.append("=");
|
||||
sb.append(var.getValue());
|
||||
cnt++;
|
||||
}
|
||||
sb.append(";");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -587,8 +555,7 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
return "MySQLConnection host=" + connection.getHost() + ", port=" + connection.getPort() + ", schema=" + connection.getSchema();
|
||||
}
|
||||
|
||||
public void executeMultiNode(RouteResultsetNode rrn, ShardingService service,
|
||||
boolean isAutoCommit) {
|
||||
public void executeMultiNode(RouteResultsetNode rrn, ShardingService service, boolean isAutoCommit) {
|
||||
TraceManager.TraceObject traceObject = TraceManager.serviceTrace(this, "execute-route-multi-result");
|
||||
TraceManager.log(ImmutableMap.of("route-result-set", rrn.toString(), "service-detail", this.toString()), traceObject);
|
||||
try {
|
||||
@@ -596,7 +563,11 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
if (!service.isAutocommit() && !service.isTxStart() && rrn.isModifySQL()) {
|
||||
service.setTxStarted(true);
|
||||
}
|
||||
StringBuilder synSQL = getSynSql(xaTxId, rrn, service.getCharset(), service.getTxIsolation(), isAutoCommit, service.getUsrVariables(), service.getSysVariables());
|
||||
if (rrn.getSqlType() == ServerParse.DDL) {
|
||||
isDDL = true;
|
||||
}
|
||||
StringBuilder synSQL = getSynSql(xaTxId, rrn, service.getCharset(),
|
||||
service.getTxIsolation(), isAutoCommit, service.getUsrVariables(), service.getSysVariables());
|
||||
synAndDoExecuteMultiNode(synSQL, rrn, service.getCharset());
|
||||
} finally {
|
||||
TraceManager.finishSpan(this, traceObject);
|
||||
@@ -611,30 +582,31 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
if (!service.isAutocommit() && !service.isTxStart() && rrn.isModifySQL()) {
|
||||
service.setTxStarted(true);
|
||||
}
|
||||
StringBuilder synSQL = getSynSql(xaTxId, rrn, service.getCharset(), service.getTxIsolation(), isAutoCommit, service.getUsrVariables(), service.getSysVariables());
|
||||
if (rrn.getSqlType() == ServerParse.DDL) {
|
||||
isDDL = true;
|
||||
}
|
||||
StringBuilder synSQL = getSynSql(xaTxId, rrn,
|
||||
service.getCharset(), service.getTxIsolation(), isAutoCommit, service.getUsrVariables(), service.getSysVariables());
|
||||
synAndDoExecute(synSQL, rrn.getStatement(), service.getCharset());
|
||||
} finally {
|
||||
TraceManager.finishSpan(this, traceObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void execute(RWSplitService service) {
|
||||
StringBuilder synSQL = getSynSql(service.getCharset(), service.getTxIsolation(), service.isAutocommit());
|
||||
synAndDoExecute(synSQL, service.getExecuteSql(), service.getCharset());
|
||||
public void execute(MySQLVariablesService service, String sql) {
|
||||
StringBuilder synSQL = getSynSql(null, null,
|
||||
service.getCharset(), service.getTxIsolation(), service.isAutocommit(), service.getUsrVariables(), service.getSysVariables());
|
||||
synAndDoExecute(synSQL, sql, service.getCharset());
|
||||
}
|
||||
|
||||
public void execute(RWSplitService service, byte[] originPacket) {
|
||||
if (service != null) {
|
||||
StringBuilder synSQL = getSynSql(service.getCharset(), service.getTxIsolation(), service.isAutocommit());
|
||||
if (synSQL != null) {
|
||||
sendQueryCmd(synSQL.toString(), service.getCharset());
|
||||
}
|
||||
}
|
||||
if (originPacket[4] == MySQLPacket.COM_STMT_PREPARE) {
|
||||
prepareOK = true;
|
||||
} else {
|
||||
prepareOK = false;
|
||||
StringBuilder synSQL = getSynSql(null, null,
|
||||
service.getCharset(), service.getTxIsolation(), service.isAutocommit(), service.getUsrVariables(), service.getSysVariables());
|
||||
if (synSQL != null) {
|
||||
sendQueryCmd(synSQL.toString(), service.getCharset());
|
||||
}
|
||||
|
||||
prepareOK = originPacket[4] == MySQLPacket.COM_STMT_PREPARE;
|
||||
writeDirectly(originPacket);
|
||||
}
|
||||
|
||||
@@ -675,11 +647,8 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
this.autocommit = sysAutocommit == autocommitSynced; // T + T-> T, T + F-> F, F +T ->F, F + F->T
|
||||
this.connection.initCharacterSet(SystemConfig.getInstance().getCharset());
|
||||
this.usrVariables.clear();
|
||||
this.usrVariables.add(new LinkedHashMap<>());
|
||||
this.sysVariables.clear();
|
||||
Map<String, String> sysRest = new LinkedHashMap<>();
|
||||
sysRest.put("sql_mode", null);
|
||||
this.sysVariables.add(sysRest);
|
||||
this.sysVariables.put("sql_mode", null);
|
||||
}
|
||||
|
||||
private WriteToBackendTask sendQueryCmdTask(String query, CharsetNames clientCharset) {
|
||||
@@ -711,14 +680,13 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
}
|
||||
|
||||
public BackendConnection getConnection() {
|
||||
return (BackendConnection) connection;
|
||||
return connection;
|
||||
}
|
||||
|
||||
public void setResponseHandler(ResponseHandler handler) {
|
||||
this.responseHandler = handler;
|
||||
}
|
||||
|
||||
|
||||
public Object getAttachment() {
|
||||
return attachment;
|
||||
}
|
||||
@@ -727,7 +695,6 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
|
||||
public NonBlockingSession getSession() {
|
||||
return session;
|
||||
}
|
||||
@@ -736,12 +703,10 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
|
||||
public ResponseHandler getResponseHandler() {
|
||||
return responseHandler;
|
||||
}
|
||||
|
||||
|
||||
public boolean isRowDataFlowing() {
|
||||
return isRowDataFlowing;
|
||||
}
|
||||
@@ -790,22 +755,6 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
this.statusSync = statusSync;
|
||||
}
|
||||
|
||||
public boolean isAutocommit() {
|
||||
return autocommit;
|
||||
}
|
||||
|
||||
public void setAutocommit(boolean autocommit) {
|
||||
this.autocommit = autocommit;
|
||||
}
|
||||
|
||||
public int getTxIsolation() {
|
||||
return txIsolation;
|
||||
}
|
||||
|
||||
public void setTxIsolation(int txIsolation) {
|
||||
this.txIsolation = txIsolation;
|
||||
}
|
||||
|
||||
public void setRecycler(BackEndCleaner recycler) {
|
||||
this.recycler = recycler;
|
||||
}
|
||||
@@ -847,20 +796,22 @@ public class MySQLResponseService extends MySQLBasedService {
|
||||
private final Integer txtIsolation;
|
||||
private final Boolean autocommit;
|
||||
private final AtomicInteger synCmdCount;
|
||||
private final List<Map<String, String>> usrVariables = new ArrayList<>();
|
||||
private final List<Map<String, String>> sysVariables = new ArrayList<>();
|
||||
private final Map<String, String> usrVariables = new LinkedHashMap<>();
|
||||
private final Map<String, String> sysVariables = new LinkedHashMap<>();
|
||||
|
||||
StatusSync(String schema,
|
||||
CharsetNames clientCharset, Integer txtIsolation, Boolean autocommit,
|
||||
int synCount, List<Map<String, String>> usrVariables, List<Map<String, String>> sysVariables) {
|
||||
super();
|
||||
int synCount, Map<String, String> usrVariables, Map<String, String> sysVariables, Set<String> toResetSys) {
|
||||
this.schema = schema;
|
||||
this.clientCharset = clientCharset;
|
||||
this.txtIsolation = txtIsolation;
|
||||
this.autocommit = autocommit;
|
||||
this.synCmdCount = new AtomicInteger(synCount);
|
||||
this.usrVariables.addAll(usrVariables);
|
||||
this.sysVariables.addAll(sysVariables);
|
||||
this.usrVariables.putAll(usrVariables);
|
||||
this.sysVariables.putAll(sysVariables);
|
||||
for (String sysVariable : toResetSys) {
|
||||
this.sysVariables.remove(sysVariable);
|
||||
}
|
||||
}
|
||||
|
||||
boolean synAndExecuted(MySQLResponseService service) {
|
||||
|
||||
@@ -20,20 +20,18 @@ import com.actiontech.dble.net.service.AuthResultInfo;
|
||||
import com.actiontech.dble.net.service.FrontEndService;
|
||||
import com.actiontech.dble.net.service.ServiceTask;
|
||||
import com.actiontech.dble.route.RouteResultset;
|
||||
import com.actiontech.dble.route.parser.util.Pair;
|
||||
import com.actiontech.dble.server.NonBlockingSession;
|
||||
import com.actiontech.dble.server.ServerQueryHandler;
|
||||
import com.actiontech.dble.server.ServerSptPrepare;
|
||||
import com.actiontech.dble.server.handler.ServerLoadDataInfileHandler;
|
||||
import com.actiontech.dble.server.handler.ServerPrepareHandler;
|
||||
import com.actiontech.dble.server.handler.SetHandler;
|
||||
import com.actiontech.dble.server.handler.SetInnerHandler;
|
||||
import com.actiontech.dble.server.parser.ServerParse;
|
||||
import com.actiontech.dble.server.response.Heartbeat;
|
||||
import com.actiontech.dble.server.response.InformationSchemaProfiling;
|
||||
import com.actiontech.dble.server.response.Ping;
|
||||
import com.actiontech.dble.server.util.SchemaUtil;
|
||||
import com.actiontech.dble.services.MySQLBasedService;
|
||||
import com.actiontech.dble.services.MySQLVariablesService;
|
||||
import com.actiontech.dble.services.mysqlsharding.handler.LoadDataProtoHandlerImpl;
|
||||
import com.actiontech.dble.singleton.*;
|
||||
import com.actiontech.dble.statistic.CommandCount;
|
||||
@@ -47,7 +45,9 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.sql.SQLSyntaxErrorException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@@ -55,7 +55,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
/**
|
||||
* Created by szf on 2020/6/18.
|
||||
*/
|
||||
public class ShardingService extends MySQLBasedService implements FrontEndService {
|
||||
public class ShardingService extends MySQLVariablesService implements FrontEndService {
|
||||
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(ShardingService.class);
|
||||
|
||||
@@ -76,33 +76,19 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
protected String executeSql;
|
||||
protected UserName user;
|
||||
private long clientFlags;
|
||||
private volatile boolean autocommit;
|
||||
private volatile boolean txStarted;
|
||||
private volatile boolean txChainBegin;
|
||||
private volatile boolean txInterrupted;
|
||||
private volatile String txInterruptMsg = "";
|
||||
|
||||
protected long lastReadTime;
|
||||
|
||||
private volatile int txIsolation;
|
||||
|
||||
private AtomicLong txID = new AtomicLong(1);
|
||||
|
||||
private volatile boolean isLocked = false;
|
||||
|
||||
private long lastInsertId;
|
||||
|
||||
protected String schema;
|
||||
|
||||
private volatile boolean multiStatementAllow = false;
|
||||
|
||||
private final NonBlockingSession session;
|
||||
|
||||
private boolean sessionReadOnly = false;
|
||||
|
||||
private List<Pair<SetHandler.KeyType, Pair<String, String>>> contextTask = new ArrayList<>();
|
||||
private List<Pair<SetHandler.KeyType, Pair<String, String>>> innerSetTask = new ArrayList<>();
|
||||
|
||||
private ServerSptPrepare sptprepare;
|
||||
|
||||
public ShardingService(AbstractConnection connection) {
|
||||
@@ -120,6 +106,54 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
this.autocommit = SystemConfig.getInstance().getAutocommit() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSetItem(SetHandler.SetItem setItem) {
|
||||
String val = setItem.getValue();
|
||||
switch (setItem.getType()) {
|
||||
case XA:
|
||||
session.getTransactionManager().setXaTxEnabled(Boolean.parseBoolean(val), this);
|
||||
break;
|
||||
case TRACE:
|
||||
session.setTrace(Boolean.parseBoolean(val));
|
||||
break;
|
||||
case TX_READ_ONLY:
|
||||
sessionReadOnly = Boolean.parseBoolean(val);
|
||||
break;
|
||||
case AUTOCOMMIT:
|
||||
if (Boolean.parseBoolean(val)) {
|
||||
if (!autocommit && session.getTargetCount() > 0) {
|
||||
session.implicitCommit(() -> {
|
||||
autocommit = true;
|
||||
writeOkPacket();
|
||||
});
|
||||
return;
|
||||
}
|
||||
autocommit = true;
|
||||
} else {
|
||||
if (autocommit) {
|
||||
autocommit = false;
|
||||
TxnLogHelper.putTxnLog(this, executeSql);
|
||||
}
|
||||
}
|
||||
writeOkPacket();
|
||||
break;
|
||||
default:
|
||||
// IGNORE
|
||||
}
|
||||
}
|
||||
|
||||
public void checkXaStatus(boolean val) throws SQLSyntaxErrorException {
|
||||
if (val) {
|
||||
if (session.getTargetMap().size() > 0 && session.getSessionXaID() == null) {
|
||||
throw new SQLSyntaxErrorException("you can't set xa cmd on when there are unfinished operation in the session.");
|
||||
}
|
||||
} else {
|
||||
if (session.getTargetMap().size() > 0 && session.getSessionXaID() != null) {
|
||||
throw new SQLSyntaxErrorException("you can't set xa cmd off when a transaction is in progress.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void query(String sql) {
|
||||
sql = sql.trim();
|
||||
// remove last ';'
|
||||
@@ -145,7 +179,6 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
readOnly = ((ShardingUserConfig) userConfig).isReadOnly();
|
||||
}
|
||||
|
||||
|
||||
this.handler.setReadOnly(readOnly);
|
||||
this.handler.setSessionReadOnly(sessionReadOnly);
|
||||
this.handler.query(sql);
|
||||
@@ -391,7 +424,6 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void writeErrMessage(byte id, int vendorCode, String sqlState, String msg) {
|
||||
markFinished();
|
||||
@@ -404,84 +436,6 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
}
|
||||
}
|
||||
|
||||
public void executeContextSetTask() {
|
||||
Map<String, String> singleUsrVariables = new LinkedHashMap<>();
|
||||
Map<String, String> singleSysVariables = new LinkedHashMap<>();
|
||||
for (Pair<SetHandler.KeyType, Pair<String, String>> task : contextTask) {
|
||||
switch (task.getKey()) {
|
||||
case CHARACTER_SET_CLIENT:
|
||||
String charsetClient = task.getValue().getKey();
|
||||
this.setCharacterClient(charsetClient);
|
||||
break;
|
||||
case CHARACTER_SET_CONNECTION:
|
||||
String collationName = task.getValue().getKey();
|
||||
this.setCharacterConnection(collationName);
|
||||
break;
|
||||
case CHARACTER_SET_RESULTS:
|
||||
String charsetResult = task.getValue().getKey();
|
||||
this.setCharacterResults(charsetResult);
|
||||
break;
|
||||
case COLLATION_CONNECTION:
|
||||
String collation = task.getValue().getKey();
|
||||
this.setCollationConnection(collation);
|
||||
break;
|
||||
case TX_ISOLATION:
|
||||
String isolationLevel = task.getValue().getKey();
|
||||
this.setTxIsolation(Integer.parseInt(isolationLevel));
|
||||
break;
|
||||
case TX_READ_ONLY:
|
||||
String enable = task.getValue().getKey();
|
||||
this.setSessionReadOnly(Boolean.parseBoolean(enable));
|
||||
break;
|
||||
case SYSTEM_VARIABLES:
|
||||
singleSysVariables.put(task.getValue().getKey(), task.getValue().getValue());
|
||||
break;
|
||||
case USER_VARIABLES:
|
||||
singleUsrVariables.put(task.getValue().getKey(), task.getValue().getValue());
|
||||
break;
|
||||
case CHARSET:
|
||||
this.setCharacterSet(task.getValue().getKey());
|
||||
break;
|
||||
case NAMES:
|
||||
this.setNames(task.getValue().getKey(), task.getValue().getValue());
|
||||
break;
|
||||
default:
|
||||
//can't happen
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (singleUsrVariables.size() > 0 || singleSysVariables.size() > 0) {
|
||||
//make sure the var map appear as pair
|
||||
this.usrVariables.add(singleUsrVariables);
|
||||
this.sysVariables.add(singleSysVariables);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean executeInnerSetTask() {
|
||||
Pair<SetHandler.KeyType, Pair<String, String>> autoCommitTask = null;
|
||||
for (Pair<SetHandler.KeyType, Pair<String, String>> task : innerSetTask) {
|
||||
switch (task.getKey()) {
|
||||
case XA:
|
||||
session.getTransactionManager().setXaTxEnabled(Boolean.valueOf(task.getValue().getKey()), this);
|
||||
break;
|
||||
case AUTOCOMMIT:
|
||||
autoCommitTask = task;
|
||||
break;
|
||||
case TRACE:
|
||||
session.setTrace(Boolean.valueOf(task.getValue().getKey()));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
if (autoCommitTask != null) {
|
||||
return SetInnerHandler.execSetAutoCommit(executeSql, this, Boolean.valueOf(autoCommitTask.getValue().getKey()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void beginInTx(String stmt) {
|
||||
if (txInterrupted) {
|
||||
writeErrMessage(ErrorCode.ER_YES, txInterruptMsg);
|
||||
@@ -604,7 +558,6 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(MySQLPacket packet) {
|
||||
boolean multiQueryFlag = session.multiStatementPacket(packet);
|
||||
@@ -687,35 +640,6 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
TraceManager.sessionStart(this, "sharding-server-start");
|
||||
}
|
||||
|
||||
|
||||
public void setCollationConnection(String collation) {
|
||||
connection.getCharsetName().setCollation(collation);
|
||||
}
|
||||
|
||||
public void setCharacterResults(String name) {
|
||||
connection.getCharsetName().setResults(name);
|
||||
}
|
||||
|
||||
public void setCharacterConnection(String collationName) {
|
||||
connection.getCharsetName().setCollation(collationName);
|
||||
}
|
||||
|
||||
public void setNames(String name, String collationName) {
|
||||
connection.getCharsetName().setNames(name, collationName);
|
||||
}
|
||||
|
||||
public void setCharacterClient(String name) {
|
||||
connection.getCharsetName().setClient(name);
|
||||
}
|
||||
|
||||
public int getTxIsolation() {
|
||||
return txIsolation;
|
||||
}
|
||||
|
||||
public void setTxIsolation(int txIsolation) {
|
||||
this.txIsolation = txIsolation;
|
||||
}
|
||||
|
||||
public boolean isTxStarted() {
|
||||
return txStarted;
|
||||
}
|
||||
@@ -748,14 +672,6 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
this.txInterruptMsg = txInterruptMsg;
|
||||
}
|
||||
|
||||
public boolean isAutocommit() {
|
||||
return autocommit;
|
||||
}
|
||||
|
||||
public void setAutocommit(boolean autocommit) {
|
||||
this.autocommit = autocommit;
|
||||
}
|
||||
|
||||
public boolean isTxStart() {
|
||||
return txStarted;
|
||||
}
|
||||
@@ -797,7 +713,6 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
return (ShardingUserConfig) userConfig;
|
||||
}
|
||||
|
||||
|
||||
public String getSchema() {
|
||||
return schema;
|
||||
}
|
||||
@@ -806,11 +721,6 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
this.schema = schema;
|
||||
}
|
||||
|
||||
public void setCharacterSet(String name) {
|
||||
connection.setCharacterSet(name);
|
||||
}
|
||||
|
||||
|
||||
public boolean isLocked() {
|
||||
return isLocked;
|
||||
}
|
||||
@@ -827,12 +737,6 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
return txID.get();
|
||||
}
|
||||
|
||||
|
||||
public List<Map<String, String>> getUsrVariables() {
|
||||
return usrVariables;
|
||||
}
|
||||
|
||||
|
||||
public long getLastInsertId() {
|
||||
return lastInsertId;
|
||||
}
|
||||
@@ -853,31 +757,10 @@ public class ShardingService extends MySQLBasedService implements FrontEndServic
|
||||
return sessionReadOnly;
|
||||
}
|
||||
|
||||
|
||||
public ServerLoadDataInfileHandler getLoadDataInfileHandler() {
|
||||
return loadDataInfileHandler;
|
||||
}
|
||||
|
||||
public List<Map<String, String>> getSysVariables() {
|
||||
return sysVariables;
|
||||
}
|
||||
|
||||
public List<Pair<SetHandler.KeyType, Pair<String, String>>> getContextTask() {
|
||||
return contextTask;
|
||||
}
|
||||
|
||||
public void setContextTask(List<Pair<SetHandler.KeyType, Pair<String, String>>> contextTask) {
|
||||
this.contextTask = contextTask;
|
||||
}
|
||||
|
||||
public List<Pair<SetHandler.KeyType, Pair<String, String>>> getInnerSetTask() {
|
||||
return innerSetTask;
|
||||
}
|
||||
|
||||
public void setInnerSetTask(List<Pair<SetHandler.KeyType, Pair<String, String>>> innerSetTask) {
|
||||
this.innerSetTask = innerSetTask;
|
||||
}
|
||||
|
||||
public ServerSptPrepare getSptPrepare() {
|
||||
return sptprepare;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class RWSplitHandler implements ResponseHandler, LoadDataResponseHandler,
|
||||
if (originPacket != null) {
|
||||
mysqlService.execute(rwSplitService, originPacket);
|
||||
} else {
|
||||
mysqlService.execute(rwSplitService);
|
||||
mysqlService.execute(rwSplitService, rwSplitService.getExecuteSql());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,41 +2,21 @@ package com.actiontech.dble.services.rwsplit;
|
||||
|
||||
import com.actiontech.dble.config.ErrorCode;
|
||||
import com.actiontech.dble.net.handler.FrontendQueryHandler;
|
||||
import com.actiontech.dble.net.mysql.OkPacket;
|
||||
import com.actiontech.dble.rwsplit.RWSplitNonBlockingSession;
|
||||
import com.actiontech.dble.server.ServerQueryHandler;
|
||||
import com.actiontech.dble.server.handler.SetHandler;
|
||||
import com.actiontech.dble.server.handler.UseHandler;
|
||||
import com.actiontech.dble.server.parser.ServerParse;
|
||||
import com.actiontech.dble.singleton.TraceManager;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class RWSplitQueryHandler implements FrontendQueryHandler {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ServerQueryHandler.class);
|
||||
|
||||
private final RWSplitNonBlockingSession session;
|
||||
//private Boolean readOnly = true;
|
||||
//private boolean sessionReadOnly = true;
|
||||
|
||||
@Override
|
||||
public void setReadOnly(Boolean readOnly) {
|
||||
//this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionReadOnly(boolean sessionReadOnly) {
|
||||
// this.sessionReadOnly = sessionReadOnly;
|
||||
}
|
||||
|
||||
public RWSplitQueryHandler(RWSplitNonBlockingSession session) {
|
||||
this.session = session;
|
||||
@@ -59,7 +39,7 @@ public class RWSplitQueryHandler implements FrontendQueryHandler {
|
||||
session.execute(false, null);
|
||||
break;
|
||||
case ServerParse.SET:
|
||||
parseSet(sql);
|
||||
SetHandler.handle(sql, session.getService(), rs >>> 8);
|
||||
break;
|
||||
case ServerParse.LOCK:
|
||||
session.execute(true, rwSplitService -> rwSplitService.setLocked(true));
|
||||
@@ -74,8 +54,7 @@ public class RWSplitQueryHandler implements FrontendQueryHandler {
|
||||
case ServerParse.COMMIT:
|
||||
case ServerParse.ROLLBACK:
|
||||
session.execute(true, rwSplitService -> {
|
||||
rwSplitService.getSession().unbindIfSafe();
|
||||
rwSplitService.setTxStart(false);
|
||||
rwSplitService.getSession().unbindIfSafe(true);
|
||||
});
|
||||
break;
|
||||
case ServerParse.LOAD_DATA_INFILE_SQL:
|
||||
@@ -98,46 +77,4 @@ public class RWSplitQueryHandler implements FrontendQueryHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// private boolean parseSelectQuery(String sql) {
|
||||
// boolean canSelectSlave = true;
|
||||
// SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
// SQLStatement statement = parser.parseStatement(true);
|
||||
// if (statement instanceof SQLSelectStatement) {
|
||||
// if (!((SQLSelectStatement) statement).getSelect().getQueryBlock().isForUpdate()) {
|
||||
// canSelectSlave = true;
|
||||
// }
|
||||
// } else {
|
||||
// LOGGER.warn("unknown select");
|
||||
// throw new UnsupportedOperationException("unknown");
|
||||
// }
|
||||
//
|
||||
// return canSelectSlave;
|
||||
// }
|
||||
|
||||
private void parseSet(String sql) throws IOException {
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement statement = parser.parseStatement(true);
|
||||
if (statement instanceof SQLSetStatement) {
|
||||
List<SQLAssignItem> assignItems = ((SQLSetStatement) statement).getItems();
|
||||
if (assignItems.size() == 1) {
|
||||
SQLAssignItem item = assignItems.get(0);
|
||||
if (item.getTarget().toString().equalsIgnoreCase("autocommit")) {
|
||||
if (session.getService().isAutocommit() && item.getValue().toString().equalsIgnoreCase("0")) {
|
||||
session.getService().setAutocommit(false);
|
||||
session.getService().writeDirectly(OkPacket.OK);
|
||||
}
|
||||
if (!session.getService().isAutocommit() && item.getValue().toString().equalsIgnoreCase("1")) {
|
||||
session.execute(false, rwSplitService -> rwSplitService.setAutocommit(true));
|
||||
}
|
||||
}
|
||||
session.execute(true, null);
|
||||
} else {
|
||||
// throw new UnsupportedOperationException("unknown");
|
||||
session.execute(true, null);
|
||||
}
|
||||
} else {
|
||||
session.execute(true, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,10 +14,11 @@ import com.actiontech.dble.net.service.AuthResultInfo;
|
||||
import com.actiontech.dble.net.service.FrontEndService;
|
||||
import com.actiontech.dble.net.service.ServiceTask;
|
||||
import com.actiontech.dble.rwsplit.RWSplitNonBlockingSession;
|
||||
import com.actiontech.dble.server.handler.SetHandler;
|
||||
import com.actiontech.dble.server.parser.ServerParse;
|
||||
import com.actiontech.dble.server.response.Heartbeat;
|
||||
import com.actiontech.dble.server.response.Ping;
|
||||
import com.actiontech.dble.services.MySQLBasedService;
|
||||
import com.actiontech.dble.services.MySQLVariablesService;
|
||||
import com.actiontech.dble.singleton.FrontendUserManager;
|
||||
import com.actiontech.dble.statistic.CommandCount;
|
||||
import org.slf4j.Logger;
|
||||
@@ -25,20 +26,23 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class RWSplitService extends MySQLBasedService implements FrontEndService {
|
||||
public class RWSplitService extends MySQLVariablesService implements FrontEndService {
|
||||
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(RWSplitService.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RWSplitService.class);
|
||||
private static final Pattern HINT_DEST = Pattern.compile(".*/\\*\\s*dble_dest_expect\\s*:\\s*([M|S])\\s*\\*/", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private volatile String schema;
|
||||
private volatile int txIsolation;
|
||||
private volatile boolean autocommit;
|
||||
private volatile boolean isLocked;
|
||||
private volatile boolean txStart;
|
||||
private volatile boolean inLoadData;
|
||||
private volatile boolean inPrepare;
|
||||
|
||||
private volatile String executeSql;
|
||||
// only for test
|
||||
private volatile String expectedDest;
|
||||
private UserName user;
|
||||
|
||||
private final CommandCount commands;
|
||||
@@ -52,6 +56,26 @@ public class RWSplitService extends MySQLBasedService implements FrontEndService
|
||||
this.queryHandler = new RWSplitQueryHandler(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSetItem(SetHandler.SetItem setItem) {
|
||||
switch (setItem.getType()) {
|
||||
case AUTOCOMMIT:
|
||||
String ac = setItem.getValue();
|
||||
if (autocommit && !Boolean.parseBoolean(ac)) {
|
||||
autocommit = false;
|
||||
writeOkPacket();
|
||||
}
|
||||
if (!autocommit && Boolean.parseBoolean(ac)) {
|
||||
session.execute(false, rwSplitService -> {
|
||||
rwSplitService.setAutocommit(true);
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void initFromAuthInfo(AuthResultInfo info) {
|
||||
AuthPacket auth = info.getMysqlAuthPacket();
|
||||
this.user = new UserName(auth.getUser(), auth.getTenant());
|
||||
@@ -86,11 +110,7 @@ public class RWSplitService extends MySQLBasedService implements FrontEndService
|
||||
protected void handleInnerData(byte[] data) {
|
||||
// if the statement is load data, directly push down
|
||||
if (inLoadData) {
|
||||
try {
|
||||
session.execute(true, data, null);
|
||||
} catch (IOException e) {
|
||||
writeErrMessage(ErrorCode.ER_UNKNOWN_COM_ERROR, e.getMessage());
|
||||
}
|
||||
session.execute(true, data, null);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -122,12 +142,7 @@ public class RWSplitService extends MySQLBasedService implements FrontEndService
|
||||
break;
|
||||
case MySQLPacket.COM_STMT_CLOSE:
|
||||
commands.doStmtClose();
|
||||
try {
|
||||
session.getService().setInPrepare(false);
|
||||
session.execute(true, data, null);
|
||||
} catch (IOException e) {
|
||||
writeErrMessage(ErrorCode.ER_UNKNOWN_COM_ERROR, e.getMessage());
|
||||
}
|
||||
session.execute(true, data, rwSplitService -> rwSplitService.setInPrepare(false));
|
||||
break;
|
||||
// connection
|
||||
case MySQLPacket.COM_QUIT:
|
||||
@@ -163,8 +178,6 @@ public class RWSplitService extends MySQLBasedService implements FrontEndService
|
||||
session.execute(true, data, rwSplitService -> rwSplitService.setSchema(switchSchema));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
writeErrMessage(ErrorCode.ER_UNKNOWN_CHARACTER_SET, "Unknown charset '" + getCharset().getClient() + "'");
|
||||
} catch (IOException e) {
|
||||
writeErrMessage(ErrorCode.ER_UNKNOWN_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +186,14 @@ public class RWSplitService extends MySQLBasedService implements FrontEndService
|
||||
mm.position(5);
|
||||
try {
|
||||
String sql = mm.readString(getCharset().getClient());
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
Matcher match = HINT_DEST.matcher(sql);
|
||||
if (match.matches()) {
|
||||
expectedDest = match.group(1);
|
||||
} else {
|
||||
expectedDest = null;
|
||||
}
|
||||
}
|
||||
executeSql = sql;
|
||||
queryHandler.query(sql);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
@@ -202,11 +223,7 @@ public class RWSplitService extends MySQLBasedService implements FrontEndService
|
||||
}
|
||||
|
||||
private void execute(byte[] data) {
|
||||
try {
|
||||
session.execute(true, data, null);
|
||||
} catch (IOException e) {
|
||||
writeErrMessage(ErrorCode.ER_UNKNOWN_COM_ERROR, e.getMessage());
|
||||
}
|
||||
session.execute(true, data, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -244,18 +261,6 @@ public class RWSplitService extends MySQLBasedService implements FrontEndService
|
||||
isLocked = locked;
|
||||
}
|
||||
|
||||
public int getTxIsolation() {
|
||||
return txIsolation;
|
||||
}
|
||||
|
||||
public boolean isAutocommit() {
|
||||
return autocommit;
|
||||
}
|
||||
|
||||
public void setAutocommit(boolean autocommit) {
|
||||
this.autocommit = autocommit;
|
||||
}
|
||||
|
||||
public boolean isTxStart() {
|
||||
return txStart;
|
||||
}
|
||||
@@ -280,6 +285,10 @@ public class RWSplitService extends MySQLBasedService implements FrontEndService
|
||||
this.inPrepare = inPrepare;
|
||||
}
|
||||
|
||||
public String getExpectedDest() {
|
||||
return expectedDest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void killAndClose(String reason) {
|
||||
session.close(reason);
|
||||
|
||||
@@ -10,18 +10,22 @@ import com.actiontech.dble.backend.datasource.PhysicalDbGroup;
|
||||
import com.actiontech.dble.backend.mysql.nio.handler.ResetConnHandler;
|
||||
import com.actiontech.dble.backend.mysql.nio.handler.ResponseHandler;
|
||||
import com.actiontech.dble.config.ErrorCode;
|
||||
import com.actiontech.dble.config.Fields;
|
||||
import com.actiontech.dble.net.connection.BackendConnection;
|
||||
import com.actiontech.dble.net.mysql.ErrorPacket;
|
||||
import com.actiontech.dble.net.mysql.FieldPacket;
|
||||
import com.actiontech.dble.net.mysql.ResetConnectionPacket;
|
||||
import com.actiontech.dble.net.mysql.RowDataPacket;
|
||||
import com.actiontech.dble.net.service.AbstractService;
|
||||
import com.actiontech.dble.server.handler.SetCallBack;
|
||||
import com.actiontech.dble.server.handler.SetHandler;
|
||||
import com.actiontech.dble.services.MySQLVariablesService;
|
||||
import com.actiontech.dble.services.mysqlsharding.MySQLResponseService;
|
||||
import com.actiontech.dble.services.mysqlsharding.ShardingService;
|
||||
import com.actiontech.dble.services.rwsplit.RWSplitService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -30,43 +34,54 @@ public class SetTestJob implements ResponseHandler, Runnable {
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(SQLJob.class);
|
||||
|
||||
private final String sql;
|
||||
private final String databaseName;
|
||||
private final SQLJobHandler jobHandler;
|
||||
private final ShardingService shardingService;
|
||||
private final AtomicBoolean hasReturn = new AtomicBoolean(false);
|
||||
private final MySQLVariablesService frontService;
|
||||
private final SetHandler.SetItem[] setItems;
|
||||
private volatile List<FieldPacket> fieldPackets;
|
||||
private final int userVariableSize;
|
||||
private final AtomicBoolean hasReturn;
|
||||
|
||||
public SetTestJob(String sql, String databaseName, SQLJobHandler jobHandler, ShardingService service) {
|
||||
super();
|
||||
public SetTestJob(String sql, SQLJobHandler jobHandler, SetHandler.SetItem[] setItems, int userVariableSize, MySQLVariablesService frontService) {
|
||||
this.sql = sql;
|
||||
this.databaseName = databaseName;
|
||||
this.jobHandler = jobHandler;
|
||||
this.shardingService = service;
|
||||
this.frontService = frontService;
|
||||
this.setItems = setItems;
|
||||
this.userVariableSize = userVariableSize;
|
||||
this.fieldPackets = new ArrayList<>(userVariableSize);
|
||||
this.hasReturn = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
boolean sendTest = false;
|
||||
try {
|
||||
Map<String, PhysicalDbGroup> dbGroups = DbleServer.getInstance().getConfig().getDbGroups();
|
||||
for (PhysicalDbGroup dbGroup : dbGroups.values()) {
|
||||
if (dbGroup.getWriteDbInstance().isAlive()) {
|
||||
dbGroup.getWriteDbInstance().getConnection(databaseName, this, null, false);
|
||||
sendTest = true;
|
||||
break;
|
||||
|
||||
if (frontService instanceof ShardingService) {
|
||||
Map<String, PhysicalDbGroup> dbGroups = DbleServer.getInstance().getConfig().getDbGroups();
|
||||
for (PhysicalDbGroup dbGroup : dbGroups.values()) {
|
||||
if (dbGroup.getWriteDbInstance().isAlive()) {
|
||||
dbGroup.getWriteDbInstance().getConnection(null, this, null, false);
|
||||
sendTest = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
((RWSplitService) frontService).getSession().getRwGroup().getWriteDbInstance().getConnection(null, this, null, false);
|
||||
sendTest = true;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
if (hasReturn.compareAndSet(false, true)) {
|
||||
String reason = "can't get backend connection for sql :" + sql + " " + e.getMessage();
|
||||
LOGGER.info(reason, e);
|
||||
LOGGER.warn(reason, e);
|
||||
doFinished(true);
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_HANDLE_DATA, reason);
|
||||
frontService.writeErrMessage(ErrorCode.ERR_HANDLE_DATA, reason);
|
||||
}
|
||||
}
|
||||
if (!sendTest && hasReturn.compareAndSet(false, true)) {
|
||||
String reason = "can't get backend connection for sql :" + sql + " all datasrouce dead";
|
||||
LOGGER.info(reason);
|
||||
String reason = "can't get backend connection for sql[" + sql + "],because all dbInstances are dead.";
|
||||
LOGGER.warn(reason);
|
||||
doFinished(true);
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_HANDLE_DATA, reason);
|
||||
frontService.writeErrMessage(ErrorCode.ERR_HANDLE_DATA, reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,11 +92,11 @@ public class SetTestJob implements ResponseHandler, Runnable {
|
||||
}
|
||||
conn.getBackendService().setResponseHandler(this);
|
||||
conn.getBackendService().setComplexQuery(true);
|
||||
conn.getBackendService().sendQueryCmd(sql, shardingService.getCharset());
|
||||
conn.getBackendService().execute(frontService, sql);
|
||||
}
|
||||
|
||||
private void doFinished(boolean failed) {
|
||||
jobHandler.finished(databaseName, failed);
|
||||
jobHandler.finished(null, failed);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,7 +105,7 @@ public class SetTestJob implements ResponseHandler, Runnable {
|
||||
String reason = "can't get backend connection for sql :" + sql + " " + e.getMessage();
|
||||
LOGGER.info(reason);
|
||||
doFinished(true);
|
||||
shardingService.writeErrMessage(ErrorCode.ERR_HANDLE_DATA, reason);
|
||||
frontService.writeErrMessage(ErrorCode.ERR_HANDLE_DATA, reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +114,7 @@ public class SetTestJob implements ResponseHandler, Runnable {
|
||||
if (hasReturn.compareAndSet(false, true)) {
|
||||
LOGGER.info("connectionClose sql :" + sql);
|
||||
doFinished(true);
|
||||
this.shardingService.writeErrMessage(ErrorCode.ERR_HANDLE_DATA, "connectionClose:" + reason);
|
||||
this.frontService.writeErrMessage(ErrorCode.ERR_HANDLE_DATA, "connectionClose:" + reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,18 +125,19 @@ public class SetTestJob implements ResponseHandler, Runnable {
|
||||
errPg.read(err);
|
||||
doFinished(true);
|
||||
((MySQLResponseService) service).release(); //conn context not change
|
||||
this.shardingService.writeErrMessage(errPg.getErrNo(), new String(errPg.getMessage()));
|
||||
this.frontService.writeErrMessage(errPg.getErrNo(), new String(errPg.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void okResponse(byte[] ok, AbstractService service) {
|
||||
if (userVariableSize > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
MySQLResponseService responseService = (MySQLResponseService) service;
|
||||
if (hasReturn.compareAndSet(false, true)) {
|
||||
doFinished(false);
|
||||
if (!((SetCallBack) ((OneRawSQLQueryResultHandler) jobHandler).getCallback()).isBackToOtherThread()) {
|
||||
shardingService.write(shardingService.getSession2().getOKPacket());
|
||||
}
|
||||
ResetConnHandler handler = new ResetConnHandler();
|
||||
responseService.setResponseHandler(handler);
|
||||
responseService.setComplexQuery(true);
|
||||
@@ -130,27 +146,50 @@ public class SetTestJob implements ResponseHandler, Runnable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fieldEofResponse(byte[] header, List<byte[]> fields, List<FieldPacket> fieldPackets, byte[] eof,
|
||||
public void fieldEofResponse(byte[] header, List<byte[]> fields, List<FieldPacket> fps, byte[] eof,
|
||||
boolean isLeft, AbstractService service) {
|
||||
//will not happen
|
||||
|
||||
for (byte[] field : fields) {
|
||||
// save field
|
||||
FieldPacket fieldPk = new FieldPacket();
|
||||
fieldPk.read(field);
|
||||
fieldPackets.add(fieldPk);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean rowResponse(byte[] row, RowDataPacket rowPacket, boolean isLeft, AbstractService service) {
|
||||
//will not happen
|
||||
RowDataPacket rowDataPk = new RowDataPacket(fieldPackets.size());
|
||||
rowDataPk.read(row);
|
||||
for (int i = 0; i < userVariableSize; i++) {
|
||||
if (rowDataPk.getValue(i) == null) {
|
||||
continue;
|
||||
}
|
||||
int type = fieldPackets.get(i).getType();
|
||||
if (type == Fields.FIELD_TYPE_LONG || type == Fields.FIELD_TYPE_LONGLONG || type == Fields.FIELD_TYPE_NEW_DECIMAL ||
|
||||
type == Fields.FIELD_TYPE_FLOAT | type == Fields.FIELD_TYPE_DOUBLE) {
|
||||
setItems[i].setValue(new String(rowDataPk.getValue(i)));
|
||||
} else {
|
||||
setItems[i].setValue("'" + new String(rowDataPk.getValue(i)) + "'");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rowEofResponse(byte[] eof, boolean isLeft, AbstractService service) {
|
||||
//will not happen
|
||||
MySQLResponseService responseService = (MySQLResponseService) service;
|
||||
if (hasReturn.compareAndSet(false, true)) {
|
||||
doFinished(false);
|
||||
ResetConnHandler handler = new ResetConnHandler();
|
||||
responseService.setResponseHandler(handler);
|
||||
responseService.setComplexQuery(true);
|
||||
responseService.writeDirectly(responseService.writeToBuffer(ResetConnectionPacket.RESET, responseService.allocate()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SQLJob [Database=" +
|
||||
databaseName + ",sql=" + sql + ", jobHandler=" +
|
||||
return "SQLJob [sql=" + sql + ", jobHandler=" +
|
||||
jobHandler + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,24 +22,24 @@ public class SetHandlerTest {
|
||||
Assert.assertEquals("SET names utf8,character set UTF8,character set gbk,@@tx_readonly=1", convertCharsetKeyWord.invoke(null, "SET names utf8,CHARSET UTF8,CHARSET gbk,@@tx_readonly=1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckSetNamesSyntax() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
Method checkSetNamesSyntax = SetHandler.class.getDeclaredMethod("checkSetNamesSyntax", String.class);
|
||||
checkSetNamesSyntax.setAccessible(true);
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "SET NAMES utf8"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names utf8"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names 'utf8'"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names `utf8`"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names DEFAULT"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names utf8 COLLATE utf8_bin"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names utf8 COLLATE default"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names 'utf8' COLLATE utf8_bin"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names `utf8` COLLATE default"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names utf8 COLLATE 'utf8_bin'"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names utf8 COLLATE `utf8_bin`"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names 'utf8' COLLATE 'utf8_bin'"));
|
||||
Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names `utf8` COLLATE `utf8_bin`"));
|
||||
Assert.assertEquals(false, checkSetNamesSyntax.invoke(null, "set names utf8 2"));
|
||||
Assert.assertEquals(false, checkSetNamesSyntax.invoke(null, "set names utf8 COLLATION utf8_bin"));
|
||||
}
|
||||
// @Test
|
||||
// public void testCheckSetNamesSyntax() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
// Method checkSetNamesSyntax = SetHandler.class.getDeclaredMethod("checkSetNamesSyntax", String.class);
|
||||
// checkSetNamesSyntax.setAccessible(true);
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "SET NAMES utf8"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names utf8"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names 'utf8'"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names `utf8`"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names DEFAULT"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names utf8 COLLATE utf8_bin"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names utf8 COLLATE default"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names 'utf8' COLLATE utf8_bin"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names `utf8` COLLATE default"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names utf8 COLLATE 'utf8_bin'"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names utf8 COLLATE `utf8_bin`"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names 'utf8' COLLATE 'utf8_bin'"));
|
||||
// Assert.assertEquals(true, checkSetNamesSyntax.invoke(null, "set names `utf8` COLLATE `utf8_bin`"));
|
||||
// Assert.assertEquals(false, checkSetNamesSyntax.invoke(null, "set names utf8 2"));
|
||||
// Assert.assertEquals(false, checkSetNamesSyntax.invoke(null, "set names utf8 COLLATION utf8_bin"));
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,744 +1,36 @@
|
||||
package demo.test;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUnique;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import java.sql.*;
|
||||
|
||||
public class Testparser {
|
||||
public static void main(String args[]) {
|
||||
public static void main(String args[]) throws ClassNotFoundException, SQLException {
|
||||
|
||||
Testparser obj = new Testparser();
|
||||
// obj.test("CREATE TABLE `char_columns_test` (`id` int(11) NOT NULL,`c_char` char(255) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
|
||||
// obj.test("CREATE TABLE `xx`.`char_columns_test` (`id` int(11) NOT NULL,`c_char` char(255) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
|
||||
obj.test("CREATE TABLE `xx`.`char_columns_test` (`id` int(11) NOT NULL,`c_char` char(255) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY c_charx (c_char) COMMENT '唯一性' ) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
|
||||
// obj.test("drop table char_columns_test;");
|
||||
// obj.test("truncate table char_columns_test;");
|
||||
String strSetSql = "SELECT\n" +
|
||||
"\t@@SESSION .auto_increment_increment AS auto_increment_increment,\n" +
|
||||
"\t@@character_set_client AS character_set_client,\n" +
|
||||
"\t@@character_set_connection AS character_set_connection,\n" +
|
||||
"\t@@character_set_results AS character_set_results,\n" +
|
||||
"\t@@character_set_server AS character_set_server,\n" +
|
||||
"\t@@init_connect AS init_connect,\n" +
|
||||
"\t@@interactive_timeout AS interactive_timeout,\n" +
|
||||
"\t@@license AS license,\n" +
|
||||
"\t@@lower_case_table_names AS lower_case_table_names,\n" +
|
||||
"\t@@max_allowed_packet AS max_allowed_packet,\n" +
|
||||
"\t@@net_buffer_length AS net_buffer_length,\n" +
|
||||
"\t@@net_write_timeout AS net_write_timeout,\n" +
|
||||
"\t@@query_cache_size AS query_cache_size,\n" +
|
||||
"\t@@query_cache_type AS query_cache_type,\n" +
|
||||
"\t@@sql_mode AS sql_mode,\n" +
|
||||
"\t@@system_time_zone AS system_time_zone,\n" +
|
||||
"\t@@time_zone AS time_zone,\n" +
|
||||
"\t@@tx_isolation AS tx_isolation,\n" +
|
||||
"\t@@wait_timeout AS wait_timeout;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET SESSION sql_mode = 'TRADITIONAL';";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET SESSION sql_mode = `TRADITIONAL`;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET SESSION sql_mode = \"TRADITIONAL\";";
|
||||
// obj.test(strSetSql);
|
||||
//todo not support
|
||||
// strSetSql = "SET CHARSET utf8;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET CHARSET `utf8`;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET CHARSET 'UTF8';";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET CHARSET \"UTF8\";";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET CHARSET DEFAULT;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET names \"UTF8\";";
|
||||
// obj.test(strSetSql);
|
||||
|
||||
// strSetSql = "set @@tx_read_only =0,names utf8,charset utf8;";
|
||||
// obj.test(strSetSql);
|
||||
|
||||
strSetSql = "SET CHARACTER SET utf8;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET CHARACTER SET `utf8`;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET CHARACTER SET 'UTF8';";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET CHARACTER SET \"UTF8\";";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET CHARACTER SET DEFAULT;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET names utf8;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET names `utf8`;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET names 'UTF8';";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET names utf8 COLLATE default;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET names utf8 COLLATE utf8_general_ci;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET names utf8 COLLATE `utf8_general_ci`;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET names utf8 COLLATE 'utf8_general_ci';";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET names default;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set names utf8,@@tx_read_only =0;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set @@tx_read_only =0,names utf8,character set utf8;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set @@tx_read_only =0,names utf8;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set @@tx_read_only =0,names utf8 collation default;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set @@tx_read_only =0;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set @@GLOBAL.tx_read_only =0;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set @@session.tx_read_only =0;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set tx_read_only =0;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set GLOBAL tx_read_only =0;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set Session tx_read_only =0;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set Session tx_isolation ='READ-COMMITTED';";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set Session tx_isolation =`READ-COMMITTED`;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "set Session tx_isolation =\"READ-COMMITTED\";";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET TRANSACTION ISOLATION LEVEL READ COMMITTED ;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET TRANSACTION READ WRITE;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET TRANSACTION read only;";
|
||||
obj.test(strSetSql);
|
||||
strSetSql = "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;";
|
||||
obj.test(strSetSql);
|
||||
// strSetSql = "SET @total_tax = (SELECT SUM(tax) FROM taxable_transactions);";
|
||||
// obj.test(strSetSql);
|
||||
//
|
||||
// strSetSql = "SET @@session.sql_mode = 'TRADITIONAL';";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET @@global.sql_mode = 'TRADITIONAL';";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET @@sql_mode = 'TRADITIONAL';";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET GLOBAL sql_log_bin = ON;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET max_connections = 1000;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET @x = 1;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET @x = 1, SESSION sql_mode = '';";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET GLOBAL sort_buffer_size = 1000000, SESSION sort_buffer_size = 1000000;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET GLOBAL max_connections = 1000, sort_buffer_size = 1000000;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET xa =0 ;";
|
||||
// obj.test(strSetSql);
|
||||
// strSetSql = "SET xa = off ;";
|
||||
// obj.test(strSetSql);
|
||||
//String strShowSql = "";
|
||||
//strShowSql = "show create table a;";
|
||||
//obj.test(strShowSql);
|
||||
// strShowSql ="show full columns from char_columns2 from ares_test like 'i%';";
|
||||
// obj.test(strShowSql);
|
||||
// strShowSql ="show full columns from char_columns2 from ares_test where Field='id';";
|
||||
// obj.test(strShowSql);
|
||||
// strShowSql ="show full fields from char_columns2 from ares_test like 'i%';";
|
||||
// obj.test(strShowSql);
|
||||
// strShowSql ="show full columns from ares_test.char_columns2;";
|
||||
// obj.test(strShowSql);
|
||||
//
|
||||
// strShowSql ="show index from char_columns2 from ares_test where Key_name = 'PRIMARY';";
|
||||
// obj.test(strShowSql);
|
||||
// strShowSql ="show indexes from char_columns2 from ares_test where Key_name = 'PRIMARY';";
|
||||
// obj.test(strShowSql);
|
||||
// strShowSql ="show keys from char_columns2 from ares_test where Key_name = 'PRIMARY';";
|
||||
// obj.test(strShowSql);
|
||||
// strShowSql ="show keys from ares_test.char_columns2 where Key_name = 'PRIMARY';";
|
||||
// obj.test(strShowSql);
|
||||
// String strULSql ="";
|
||||
// strULSql ="desc a;";
|
||||
// obj.test(strULSql);
|
||||
// strULSql ="describe a;";
|
||||
// obj.test(strULSql);
|
||||
// strULSql ="describe a.b;";
|
||||
// obj.test(strULSql);
|
||||
// strULSql ="desc a b;";
|
||||
// obj.test(strULSql);
|
||||
//
|
||||
// strULSql ="explain a;";
|
||||
// obj.test(strULSql);
|
||||
//
|
||||
// strULSql ="explain select * from a;";
|
||||
// obj.test(strULSql);
|
||||
|
||||
// obj.test("create index idx_test on char_columns_test(id) ;");
|
||||
// obj.test("drop index idx_test on char_columns_test;");
|
||||
String strAlterSql = "";
|
||||
strAlterSql ="alter table char_columns_test add column id2 int(11) NOT NULL after x ALGORITHM = default LOCK =default;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql ="alter table char_columns_test add column id2 int(11) NOT NULL after x;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql ="alter table char_columns_test add column id2 int(11) NOT NULL,id3 int(11) NOT NULL;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql="alter table char_columns_test add index idx_test(id) ;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql="alter table char_columns_test add key idx_test(id) ;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql="alter table char_columns_test unique key idx_test(id) ;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 ADD CONSTRAINT MyPrimaryKey PRIMARY KEY (id);";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 ADD CONSTRAINT MyUniqueConstraint UNIQUE(c_char);";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 drop index idex_test;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 drop key idex_test;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 CHANGE COLUMN c_char c_varchar varchar(255) DEFAULT NULL ;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 CHANGE COLUMN c_char c_varchar varchar(255) DEFAULT NULL FIRST;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 CHANGE COLUMN c_char c_varchar varchar(255) DEFAULT NULL AFTER id ;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 modify COLUMN c_char varchar(255) DEFAULT NULL ;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 modify COLUMN c_char varchar(255) DEFAULT NULL FIRST;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 modify COLUMN c_char varchar(255) DEFAULT NULL AFTER id ;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 DROP COLUMN c_char;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 DROP PRIMARY KEY;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE char_columns1 RENAME TO char_columns1_1;";
|
||||
// obj.test(strAlterSql);
|
||||
// strAlterSql = "ALTER TABLE test_yhq.char_columns1 RENAME AS test_yhq2.char_columns1_1;";
|
||||
// obj.test(strAlterSql);
|
||||
|
||||
String strDeleteSql = "";
|
||||
// strDeleteSql = "delete a from test_yhq.char_columns1 a where 1=1;";
|
||||
// obj.test(strDeleteSql);
|
||||
// strDeleteSql = "delete from test_yhq.char_columns1 where 1=1;";
|
||||
// obj.test(strDeleteSql);
|
||||
// strDeleteSql = "delete a from test_yhq.char_columns1 a inner join test_yhq.char_columns1 b on a.id =b.id where 1=1;";
|
||||
// obj.test(strDeleteSql);
|
||||
// strDeleteSql = "delete a,b from test_yhq.char_columns1 a inner join test_yhq.char_columns1 b on a.id =b.id where 1=1;";
|
||||
// obj.test(strDeleteSql);
|
||||
// strDeleteSql = "DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;";
|
||||
// obj.test(strDeleteSql);
|
||||
// strDeleteSql = "DELETE a, b FROM t1 a INNER JOIN t2 b INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;";
|
||||
// obj.test(strDeleteSql);
|
||||
// strDeleteSql = "DELETE t1, t2 FROM t1 ,t2 using(id) where 1=1;";
|
||||
// obj.test(strDeleteSql);
|
||||
Class.forName("com.mysql.jdbc.Driver");
|
||||
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:8066/test?useServerPrepStmts=true&&useAffectedRows=true", "rw", "123456");
|
||||
|
||||
|
||||
// String strUpdateSql = "";
|
||||
// strUpdateSql = "UPDATE t1 SET col1 = col1 + 1,col2 = col1 ;";
|
||||
// obj.test(strUpdateSql);
|
||||
// strUpdateSql = "UPDATE t SET id = id + 1 ORDER BY id DESC;";
|
||||
// obj.test(strUpdateSql);
|
||||
// strUpdateSql = "UPDATE items,month SET items.price=month.price WHERE items.id=month.id;";
|
||||
// obj.test(strUpdateSql);
|
||||
// strUpdateSql = "UPDATE items inner join month on items.id=month.id SET items.price=month.price;";
|
||||
// obj.test(strUpdateSql);
|
||||
// strUpdateSql = "UPDATE EmployeeS AS P SET P.LEAGUENO = '2000' WHERE P.EmployeeNO = 95;";
|
||||
// obj.test(strUpdateSql);
|
||||
// String strCreateIndex = "";
|
||||
// strCreateIndex = "CREATE INDEX part_of_name ON customer (name(10));";
|
||||
// obj.test(strCreateIndex);
|
||||
// strCreateIndex = "CREATE UNIQUE INDEX part_of_name ON customer (name(10));";
|
||||
// obj.test(strCreateIndex);
|
||||
String selectSQl = "select avg(char_columns.id), BIT_AND(char_columns.ID),BIT_OR(char_columns.ID),bit_xor(char_columns.ID),"
|
||||
+ "COUNT(char_columns.ID),MAX(distinct char_columns.ID),MIN(distinct char_columns.ID),"
|
||||
+ "STD(char_columns.ID),STDDEV(char_columns.ID),STDDEV_POP(char_columns.ID),STDDEV_SAMP(char_columns.ID), "
|
||||
+ "sum(id),VAR_POP(char_columns.ID),VAR_SAMP(char_columns.ID),VARIANCE(char_columns.ID)"
|
||||
+ " from char_columns where id =1 and name = 'x';";
|
||||
// Connection conn = DriverManager.getConnection("jdbc:mysql://10.186.61.151:33306/test?useServerPrepStmts=true&&useAffectedRows=true", "root", "123456");
|
||||
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from constant_one where id > SOME(select name from constant_two);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from constant_one where id > ANY(select name from constant_two);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from constant_one where id > ALL(select name from constant_two);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from constant_one where id <> ALL(select name from constant_two);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT BINARY 'a' = 'A';";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT b'1000001';";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT GET_FORMAT(DATE);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select CURRENT_DATE;";//not support
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT student_name, GROUP_CONCAT(test_score) "
|
||||
// + "FROM student GROUP BY student_name;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select @@tx_read_only;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT ABS(-1);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT NOT 10,1 AND 1,IF(1<2,'yes','no'),'Monty!' REGEXP '.*';";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select 'David_' LIKE 'David|_' ESCAPE '|','a' LIKE 'ae' COLLATE utf8_general_ci";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT 1 IS NULL,1 IS NOT UNKNOWN,1 IS TRUE, 0 IS FALSE,2 IN (0,3,5,7), 2 >= 2,1 = 0,2 BETWEEN 1 AND 3;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select CAST(expr AS datetime(6) ), CAST(expr AS date ), CAST(expr AS time(6) ) from char_columns where id =1 and name = 'x';";
|
||||
selectSQl = "SELECT CHARSET(CHAR(X'65')), CHARSET(CHAR(X'65' USING utf8));";
|
||||
obj.test(selectSQl);
|
||||
selectSQl = "select CAST(expr AS nchar(2) CHARACTER SET utf8),CAST(expr AS char(2)), CAST(expr AS char(2) CHARACTER SET utf8 ),CAST(expr AS char(2) CHARACTER SET latin1 ) from char_columns where id =1 and name = 'x';";
|
||||
obj.test(selectSQl);
|
||||
selectSQl = "select CAST(expr AS char(2) CHARACTER SET utf8 ),CAST(expr AS SIGNED ),CAST(expr AS unSIGNED ) from char_columns where id =1 and name = 'x';";
|
||||
obj.test(selectSQl);
|
||||
// // TODO:NOT SUPPORTED
|
||||
// selectSQl = "select CAST(expr AS char(2) CHARACTER SET utf8 ),CAST(expr AS SIGNED INT ),CAST(expr AS unSIGNED INT ) from char_columns where id =1 and name = 'x';";
|
||||
// obj.test(selectSQl);
|
||||
selectSQl = "select CONVERT(expr , char(2)) from char_columns where id =1 and name = 'x';";
|
||||
obj.test(selectSQl);
|
||||
// selectSQl = "SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END, CASE WHEN 1>0 THEN 'true' ELSE 'false' END;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT 3 DIV 5, - (2), 3/5;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT ~5 , SELECT 29 & 15;";
|
||||
// obj.test(selectSQl);
|
||||
selectSQl = "SELECT LTRIM(' barbar'),TRIM(LEADING 'x' FROM 'xxxbarxxx'),TRIM('x' FROM 'xxxbarxxx'),SOUNDEX('Hello'), CONVERT('abc' USING utf8);";
|
||||
obj.test(selectSQl);
|
||||
// selectSQl = "SELECT SOUNDEX('Hello'),CHAR(77,121,83,81,'76');";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT student_name, GROUP_CONCAT(DISTINCT test_score order by id asc,test_score2 DESC SEPARATOR \",,\") FROM student GROUP BY student_name;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select char_columns.id from char_columns where id =1 order by id desc;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from (select * from char_columns where id =1 order by id) x;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from char_columns where id in(select id from char_columns where id =1 ) ;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) */ f1 FROM t3 WHERE f1 > 30 AND f1 < 33;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT * FROM t1 inner join t2 on t1.id =t2.id WHERE t1.f1 > 30;";
|
||||
// obj.test(selectSQl);
|
||||
// Statement stmt = conn.createStatement();
|
||||
// stmt.execute("/*#dble:db_type=master*/select * from testdb.tb_enum_sharding;");
|
||||
// stmt.close();
|
||||
// conn.close();
|
||||
|
||||
// selectSQl = "SELECT id,sum(x),(select * from id) FROM t1 group by id desc having count(*)<3 limit 1;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT id FROM (select id,name from tb) x where id =1;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT id FROM x where id =1 union all SELECT id FROM y where id =1 ;";
|
||||
// obj.test(selectSQl);
|
||||
//
|
||||
// selectSQl = "SELECT TIMESTAMPADD(WEEK,1,'2003-01-02'), TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01'),DATE_ADD(OrderDate,INTERVAL 2 DAY) AS OrderPayDate,ADDDATE('2008-01-02', INTERVAL 31 DAY),ADDDATE('2008-01-02', 31),EXTRACT(YEAR FROM '2009-07-02') FROM Orders;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT * FROM Orders as t;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select 1,null,'x','xxx';";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from table1 a inner join table2 b on a.id =b.id "
|
||||
// + "inner join table3 c on b.id =c.id;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from table1 a inner join table2 b on a.id =b.id "
|
||||
// + "inner join table3 c on a.id =c.id;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from table1 a left join table2 b on a.id =b.id "
|
||||
// + "left join table3 c on a.id =c.id;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from table1 a left join table2 b on a.id =b.id "
|
||||
// + "inner join table3 c on a.id =c.id;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select CONCAT(A,b),count(*) from table1 GROUP BY CONCAT(A,b);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select id,count(*) from table1 GROUP BY id having count(*)>1;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select id,count(*) from table1 GROUP BY table.id having count(*)>1;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select id,count(*) from table1 GROUP BY id order by count(*);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select id from db.table1 GROUP BY db.table1.id;";
|
||||
// obj.test(selectSQl);
|
||||
PreparedStatement stmt = conn.prepareStatement("select * from test where id=?");
|
||||
stmt.setInt(1, 1);
|
||||
|
||||
// selectSQl = "select id,'abc' from db.table1 GROUP BY db.table1.id;";
|
||||
// selectSQl = "select * from sharding_two_node a natural join sharding_four_node b ;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from sharding_two_node a where id = (select min(id) from sharding_two_node) ;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT column1 FROM t1 AS x WHERE x.column1 = (SELECT column1 FROM t2 AS x "
|
||||
// + "WHERE x.column1 = (SELECT column1 FROM t3 "
|
||||
// + "WHERE x.column2 = t3.column1));";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT s1 FROM t1 WHERE s1 = SOME (SELECT s1 FROM t2);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT * FROM t1 WHERE (col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT column1 FROM t1 WHERE Not EXISTS (SELECT * FROM t2);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT (SELECT s2 FROM t1);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "SELECT 1 + 1 FROM DUAL;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from sharding_two_node where id in(select id from sharding_four_node);";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select * from t1 where s1 in(1,(select s1 from t2));";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select distinct pad from sbtest1;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select distinctrow pad from sbtest1;";
|
||||
// obj.test(selectSQl);
|
||||
// selectSQl = "select distinct sql_big_result pad from sbtest1;";
|
||||
// obj.test(selectSQl);
|
||||
// //not support
|
||||
// selectSQl = "select sql_big_result distinct pad from sbtest1;";
|
||||
// obj.test(selectSQl);
|
||||
String insertSQl = "insert into test_shard values(1,1,'a\\%string','test001');";
|
||||
obj.test(insertSQl);
|
||||
|
||||
}
|
||||
|
||||
public void test(String sql) {
|
||||
System.out.println("-----------------------------------------------------------");
|
||||
System.out.println("-----------------------------------------------------------");
|
||||
System.out.println(sql);
|
||||
SQLStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement statement = parser.parseStatement();
|
||||
if (statement instanceof MySqlExplainStatement) {
|
||||
System.out.println("MySqlExplainStatement" + statement.toString());
|
||||
} else if (statement instanceof MySqlCreateTableStatement) {
|
||||
MySqlCreateTableStatement createStment = (MySqlCreateTableStatement) statement;
|
||||
SQLExpr expr = createStment.getTableSource().getExpr();
|
||||
if (expr instanceof SQLPropertyExpr) {
|
||||
SQLPropertyExpr propertyExpr = (SQLPropertyExpr) expr;
|
||||
System.out.println((propertyExpr.getOwner().toString()));
|
||||
System.out.println(propertyExpr.getName());
|
||||
} else if (expr instanceof SQLIdentifierExpr) {
|
||||
SQLIdentifierExpr identifierExpr = (SQLIdentifierExpr) expr;
|
||||
System.out.println(identifierExpr.getName());
|
||||
} else {
|
||||
System.out.println(expr.getClass() + "\n");
|
||||
}
|
||||
|
||||
} else if (statement instanceof SQLAlterTableStatement) {
|
||||
SQLAlterTableStatement alterStatement = (SQLAlterTableStatement) statement;
|
||||
SQLExprTableSource tableSource = alterStatement.getTableSource();
|
||||
for (SQLAlterTableItem alterItem : alterStatement.getItems()) {
|
||||
if (alterItem instanceof SQLAlterTableAddColumn) {
|
||||
SQLAlterTableAddColumn addColumn = (SQLAlterTableAddColumn) alterItem;
|
||||
boolean isFirst = addColumn.isFirst();
|
||||
SQLName afterColumn = addColumn.getAfterColumn();
|
||||
if (afterColumn != null) {
|
||||
System.out.println(sql + ": afterColumns:\n" + afterColumn.getClass().toString() + "\n");
|
||||
}
|
||||
for (SQLColumnDefinition columnDef : addColumn.getColumns()) {
|
||||
|
||||
}
|
||||
} else if (alterItem instanceof SQLAlterTableAddIndex) {
|
||||
SQLAlterTableAddIndex addIndex = (SQLAlterTableAddIndex) alterItem;
|
||||
SQLName name = addIndex.getName();
|
||||
System.out.println(sql + ":indexname:\n" + name.getClass().toString() + "\n");
|
||||
String type = addIndex.getType();
|
||||
addIndex.isUnique();// ??
|
||||
for (SQLSelectOrderByItem item : addIndex.getItems()) {
|
||||
System.out.println(sql + ": item.getExpr():\n" + item.getExpr().getClass().toString() + "\n");
|
||||
}
|
||||
} else if (alterItem instanceof SQLAlterTableAddConstraint) {
|
||||
SQLAlterTableAddConstraint addConstraint = (SQLAlterTableAddConstraint) alterItem;
|
||||
SQLConstraint constraint = addConstraint.getConstraint();
|
||||
if (constraint instanceof MySqlUnique) {
|
||||
MySqlUnique unique = (MySqlUnique) constraint;
|
||||
unique.getName();
|
||||
} else if (constraint instanceof MySqlPrimaryKey) {
|
||||
|
||||
} else if (constraint instanceof MysqlForeignKey) {
|
||||
System.out.println("NOT SUPPORT\n");
|
||||
}
|
||||
|
||||
System.out.println(sql + ": constraint:\n" + constraint.getClass().toString() + "\n");
|
||||
} else if (alterItem instanceof SQLAlterTableDropIndex) {
|
||||
SQLAlterTableDropIndex dropIndex = (SQLAlterTableDropIndex) alterItem;
|
||||
SQLIdentifierExpr indexName = (SQLIdentifierExpr) dropIndex.getIndexName();
|
||||
String strIndexName = indexName.getName();
|
||||
} else if (alterItem instanceof SQLAlterTableDropKey) {
|
||||
SQLAlterTableDropKey dropIndex = (SQLAlterTableDropKey) alterItem;
|
||||
SQLIdentifierExpr indexName = (SQLIdentifierExpr) dropIndex.getKeyName();
|
||||
String strIndexName = indexName.getName();
|
||||
} else if (alterItem instanceof MySqlAlterTableChangeColumn) {
|
||||
MySqlAlterTableChangeColumn changeColumn = (MySqlAlterTableChangeColumn) alterItem;
|
||||
boolean isFirst = changeColumn.isFirst();
|
||||
SQLIdentifierExpr afterColumn = (SQLIdentifierExpr) changeColumn.getAfterColumn();
|
||||
// SQLExpr afterColumn = changeColumn.getAfterColumn();
|
||||
if (afterColumn != null) {
|
||||
String strAfterColumn = afterColumn.getName();
|
||||
}
|
||||
SQLColumnDefinition columnDef = changeColumn.getNewColumnDefinition();
|
||||
} else if (alterItem instanceof MySqlAlterTableModifyColumn) {
|
||||
MySqlAlterTableModifyColumn modifyColumn = (MySqlAlterTableModifyColumn) alterItem;
|
||||
boolean isFirst = modifyColumn.isFirst();
|
||||
SQLExpr afterColumn = modifyColumn.getAfterColumn();
|
||||
if (afterColumn != null) {
|
||||
System.out.println(sql + ": afterColumns:\n" + afterColumn.getClass().toString() + "\n");
|
||||
}
|
||||
SQLColumnDefinition columnDef = modifyColumn.getNewColumnDefinition();
|
||||
} else if (alterItem instanceof SQLAlterTableDropColumnItem) {
|
||||
SQLAlterTableDropColumnItem dropColumn = (SQLAlterTableDropColumnItem) alterItem;
|
||||
for (SQLName dropName : dropColumn.getColumns()) {
|
||||
System.out.println(sql + ":dropName:\n" + dropName.getClass().toString() + "\n");
|
||||
}
|
||||
} else if (alterItem instanceof SQLAlterTableDropPrimaryKey) {
|
||||
SQLAlterTableDropPrimaryKey dropPrimary = (SQLAlterTableDropPrimaryKey) alterItem;
|
||||
} else {
|
||||
System.out.println(sql + ":\n" + alterItem.getClass().toString() + "\n");
|
||||
}
|
||||
System.out.println("\n" + statement.toString());
|
||||
}
|
||||
} else if (statement instanceof SQLDropTableStatement) {
|
||||
} else if (statement instanceof SQLTruncateStatement) {
|
||||
//TODO:Sequence?
|
||||
} else if (statement instanceof SQLDropIndexStatement) {
|
||||
//TODO
|
||||
} else if (statement instanceof MySqlDeleteStatement) {
|
||||
MySqlDeleteStatement deleteStatement = (MySqlDeleteStatement) statement;
|
||||
SQLTableSource tableSource = deleteStatement.getTableSource();
|
||||
|
||||
System.out.println(sql + ":getTableSource:" + tableSource.getClass().toString() + "\n");
|
||||
if (deleteStatement.getFrom() != null) {
|
||||
System.out.println(sql + ":getSchema:" + deleteStatement.getFrom().getClass().toString() + "\n");
|
||||
}
|
||||
System.out.println("\n");
|
||||
} else if (statement instanceof MySqlUpdateStatement) {
|
||||
MySqlUpdateStatement updateStatement = (MySqlUpdateStatement) statement;
|
||||
SQLTableSource tableSource = updateStatement.getTableSource();
|
||||
|
||||
System.out.println(sql + ":getTableSource:" + tableSource.getClass().toString() + "\n");
|
||||
System.out.println("\n" + statement.toString());
|
||||
|
||||
} else if (statement instanceof SQLCreateIndexStatement) {
|
||||
SQLCreateIndexStatement stament = (SQLCreateIndexStatement) statement;
|
||||
SQLTableSource tableSource = stament.getTable();
|
||||
System.out.println(sql + ":getTableSource:" + tableSource.getClass().toString() + "\n");
|
||||
System.out.println(sql + stament.getType());
|
||||
} else if (statement instanceof SQLSelectStatement) {
|
||||
SQLSelectStatement stament = (SQLSelectStatement) statement;
|
||||
SQLSelectQuery sqlSelectQuery = stament.getSelect().getQuery();
|
||||
if (sqlSelectQuery instanceof MySqlSelectQueryBlock) {
|
||||
MySqlSelectQueryBlock selectQueryBlock = (MySqlSelectQueryBlock) sqlSelectQuery;
|
||||
SQLTableSource fromSource = selectQueryBlock.getFrom();
|
||||
if (fromSource instanceof SQLJoinTableSource) {
|
||||
SQLJoinTableSource fromJoinSource = (SQLJoinTableSource) fromSource;
|
||||
System.out.println("SQLJoinTableSource:");
|
||||
System.out.println("all:" + fromJoinSource.toString());
|
||||
System.out.println("left:" + fromJoinSource.getLeft().toString() + ",class" + fromJoinSource.getLeft().getClass());
|
||||
System.out.println("right:" + fromJoinSource.getRight().toString() + ",class" + fromJoinSource.getRight().getClass());
|
||||
System.out.println("---------------------------");
|
||||
}
|
||||
for (SQLSelectItem item : selectQueryBlock.getSelectList()) {
|
||||
if (item.getExpr() != null) {
|
||||
SQLExpr func = item.getExpr();
|
||||
if (func instanceof SQLAggregateExpr) {
|
||||
System.out.println("SQLAggregateExpr:");
|
||||
SQLAggregateExpr agg = (SQLAggregateExpr) func;
|
||||
System.out.println("MethodName:" + agg.getMethodName() + ",getArguments size =" + agg.getArguments().size() + ",Option:" + agg.getOption());
|
||||
System.out.println("---------------------------");
|
||||
} else if (func instanceof SQLMethodInvokeExpr) {
|
||||
System.out.println("SQLMethodInvokeExpr:");
|
||||
SQLMethodInvokeExpr method = (SQLMethodInvokeExpr) func;
|
||||
System.out.println("MethodName:" + method.getMethodName() + ",getArguments size =" + method.getParameters().size() + ",OWNER:" + method.getOwner());
|
||||
System.out.println("---------------------------");
|
||||
} else if (func instanceof SQLCastExpr) {
|
||||
SQLCastExpr cast = (SQLCastExpr) func;
|
||||
System.out.println("SQLCastExpr:");
|
||||
System.out.println("Expr:" + cast.getExpr().getClass() + ",getDataType:" + cast.getDataType());
|
||||
System.out.println("---------------------------");
|
||||
} else if (func instanceof SQLBinaryOpExpr) {
|
||||
SQLBinaryOpExpr Op = (SQLBinaryOpExpr) func;
|
||||
System.out.println("SQLBinaryOpExpr:");
|
||||
System.out.println("left:" + Op.getLeft().getClass());
|
||||
System.out.println("right:" + Op.getRight().getClass());
|
||||
System.out.println("operator:" + Op.getOperator().getClass());
|
||||
System.out.println("dbtype:" + Op.getDbType());
|
||||
System.out.println("---------------------------");
|
||||
} else if (func instanceof SQLUnaryExpr) {
|
||||
SQLUnaryExpr Op = (SQLUnaryExpr) func;
|
||||
System.out.println("SQLUnaryExpr:");
|
||||
System.out.println("EXPR:" + Op.getExpr().getClass());
|
||||
System.out.println("operator:" + Op.getOperator().getClass());
|
||||
System.out.println("---------------------------");
|
||||
} else if (func instanceof SQLBetweenExpr) {
|
||||
SQLBetweenExpr between = (SQLBetweenExpr) func;
|
||||
System.out.println("SQLBetweenExpr:");
|
||||
System.out.println("begin EXPR:" + between.getBeginExpr());
|
||||
System.out.println("end EXPR:" + between.getEndExpr());
|
||||
System.out.println("isnot :" + between.isNot());
|
||||
System.out.println("test :" + between.getTestExpr());
|
||||
System.out.println("---------------------------");
|
||||
} else if (func instanceof SQLInListExpr) {
|
||||
SQLInListExpr in = (SQLInListExpr) func;
|
||||
System.out.println("SQLInListExpr:");
|
||||
System.out.println("EXPR:" + in.getExpr());
|
||||
System.out.println("isnot :" + in.isNot());
|
||||
System.out.println("getTargetList size :" + in.getTargetList().size());
|
||||
System.out.println("---------------------------");
|
||||
} else if (func instanceof SQLNotExpr) {
|
||||
SQLNotExpr not = (SQLNotExpr) func;
|
||||
System.out.println("SQLNotExpr:");
|
||||
System.out.println("EXPR:" + not.getExpr());
|
||||
System.out.println("---------------------------");
|
||||
} else if (func instanceof MySqlExtractExpr) {
|
||||
MySqlExtractExpr extract = (MySqlExtractExpr) func;
|
||||
System.out.println("MySqlExtractExpr:");
|
||||
System.out.println("value:" + extract.getValue());
|
||||
System.out.println("unit:" + extract.getUnit());
|
||||
System.out.println("---------------------------");
|
||||
} else if (func instanceof SQLCaseExpr) {
|
||||
SQLCaseExpr Case = (SQLCaseExpr) func;
|
||||
System.out.println("SQLCaseExpr:");
|
||||
System.out.println("value:" + Case.getValueExpr());
|
||||
System.out.println("else:" + Case.getElseExpr());
|
||||
System.out.println("items size:" + Case.getItems().size());
|
||||
System.out.println("---------------------------");
|
||||
} else if (func instanceof SQLVariantRefExpr) {
|
||||
SQLVariantRefExpr variant = (SQLVariantRefExpr) func;
|
||||
System.out.println("SQLVariantRefExpr:");
|
||||
System.out.println("name:" + variant.getName());
|
||||
System.out.println("Global:" + variant.isGlobal());
|
||||
System.out.println("index:" + variant.getIndex());
|
||||
System.out.println("---------------------------");
|
||||
}
|
||||
// SQLAllColumnExpr
|
||||
else {
|
||||
// MySqlOutputVisitor
|
||||
System.out.println("item.getExpr(): :" + item.getExpr().getClass().toString() + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
// SQLBinaryOpExpr
|
||||
// MySqlIntervalUnit
|
||||
// SQLIntegerExpr
|
||||
// SQLOrderBy
|
||||
// SQLSelect
|
||||
// SQLInSubQueryExpr
|
||||
if (selectQueryBlock.getGroupBy() != null) {
|
||||
SQLSelectGroupByClause groupBy = selectQueryBlock.getGroupBy();
|
||||
for (SQLExpr groupByItem : groupBy.getItems()) {
|
||||
System.out.println("groupByItem:");
|
||||
System.out.println("class :" + groupByItem.getClass());
|
||||
System.out.println("---------------------------");
|
||||
}
|
||||
|
||||
if (groupBy.getHaving() != null) {
|
||||
SQLExpr having = groupBy.getHaving();
|
||||
System.out.println("having:");
|
||||
System.out.println("class :" + having.getClass());
|
||||
System.out.println("---------------------------");
|
||||
}
|
||||
//with rollup...
|
||||
}
|
||||
if (selectQueryBlock.getOrderBy() != null) {
|
||||
for (SQLSelectOrderByItem orderItem : selectQueryBlock.getOrderBy().getItems()) {
|
||||
System.out.println("OrderBy:");
|
||||
System.out.println("class :" + orderItem.getExpr().getClass());
|
||||
System.out.println("---------------------------");
|
||||
}
|
||||
}
|
||||
if (selectQueryBlock.getWhere() != null) {
|
||||
if(selectQueryBlock.getWhere() instanceof SQLBinaryOpExpr){
|
||||
SQLBinaryOpExpr where = (SQLBinaryOpExpr)(selectQueryBlock.getWhere());
|
||||
System.out.println("where right:");
|
||||
System.out.println("class :" + where.getRight().getClass());
|
||||
System.out.println("---------------------------");
|
||||
}
|
||||
else{
|
||||
System.out.println("where:");
|
||||
System.out.println("class :" + selectQueryBlock.getWhere().getClass());
|
||||
System.out.println("---------------------------");
|
||||
}
|
||||
}
|
||||
} else if (sqlSelectQuery instanceof SQLUnionQuery) {
|
||||
}
|
||||
|
||||
} else if (statement instanceof MySqlShowColumnsStatement) {
|
||||
MySqlShowColumnsStatement showColumnsStatement = (MySqlShowColumnsStatement) statement;
|
||||
showColumnsStatement.setDatabase(null);
|
||||
showColumnsStatement.toString();
|
||||
System.out.println("change to->" + showColumnsStatement.toString());
|
||||
} else if (statement instanceof MySqlShowIndexesStatement) {
|
||||
MySqlShowIndexesStatement mySqlShowIndexesStatement = (MySqlShowIndexesStatement) statement;
|
||||
mySqlShowIndexesStatement.setDatabase(null);
|
||||
mySqlShowIndexesStatement.toString();
|
||||
System.out.println("change to 1->" + mySqlShowIndexesStatement.toString());
|
||||
System.out.println("change to 2->" + SQLUtils.toMySqlString(mySqlShowIndexesStatement));
|
||||
} else if (statement instanceof MySqlShowKeysStatement) {
|
||||
MySqlShowKeysStatement mySqlShowKeysStatement = (MySqlShowKeysStatement) statement;
|
||||
mySqlShowKeysStatement.setDatabase(null);
|
||||
mySqlShowKeysStatement.toString();
|
||||
System.out.println("change to 1->" + mySqlShowKeysStatement.toString());
|
||||
System.out.println("change to 2->" + SQLUtils.toMySqlString(mySqlShowKeysStatement));
|
||||
} else if (statement instanceof SQLSetStatement) {
|
||||
SQLSetStatement setStatement = (SQLSetStatement) statement;
|
||||
for(SQLAssignItem assignItem:setStatement.getItems()){
|
||||
if(assignItem.getTarget() instanceof SQLVariantRefExpr){
|
||||
SQLVariantRefExpr target = (SQLVariantRefExpr)assignItem.getTarget();
|
||||
System.out.println("target is " + target + ", global is " + target.isGlobal() + ", session is " + target.isSession());
|
||||
}else if(assignItem.getTarget() instanceof SQLPropertyExpr){
|
||||
SQLPropertyExpr target = (SQLPropertyExpr)assignItem.getTarget();
|
||||
System.out.println("target is " + target.getName() + ", Owner is " + target.getOwner());
|
||||
} else if(assignItem.getTarget() instanceof SQLIdentifierExpr){
|
||||
SQLIdentifierExpr target = (SQLIdentifierExpr)assignItem.getTarget();
|
||||
System.out.println("target is " + target.getName());
|
||||
} else {
|
||||
System.out.println("target is " + assignItem.getTarget() + ", class is " + assignItem.getTarget().getClass());
|
||||
}
|
||||
if(assignItem.getValue() instanceof SQLIdentifierExpr ){
|
||||
SQLIdentifierExpr value = (SQLIdentifierExpr)assignItem.getValue();
|
||||
System.out.println("value is " + value.getName() + ", class is " + assignItem.getValue().getClass());
|
||||
} else if (assignItem.getValue() instanceof MySqlCharExpr) {
|
||||
MySqlCharExpr value = (MySqlCharExpr) assignItem.getValue();
|
||||
System.out.println("value is " + value.getText() + ",charset is " + value.getCharset() + ",collate is " + value.getCollate() + ", class is " + assignItem.getValue().getClass());
|
||||
} else if (assignItem.getValue() instanceof SQLCharExpr) {
|
||||
SQLCharExpr value = (SQLCharExpr) assignItem.getValue();
|
||||
System.out.println("value is " + value.getText() + ", class is " + assignItem.getValue().getClass());
|
||||
} else if (assignItem.getValue() instanceof SQLDefaultExpr) {
|
||||
SQLDefaultExpr value = (SQLDefaultExpr) assignItem.getValue();
|
||||
System.out.println("value is " + value.toString() + ", class is " + assignItem.getValue().getClass());
|
||||
}else {
|
||||
System.out.println("value is " + assignItem.getValue() + ", class is " + assignItem.getValue().getClass());
|
||||
}
|
||||
}
|
||||
// } else if (statement instanceof MySqlSetNamesStatement) {
|
||||
// MySqlSetNamesStatement setStatement = (MySqlSetNamesStatement) statement;
|
||||
// System.out.println("charset ="+setStatement.getCharSet()+ ",Collate ="+setStatement.getCollate()+",default ="+setStatement.isDefault());
|
||||
// } else if (statement instanceof MySqlSetCharSetStatement) {
|
||||
// MySqlSetCharSetStatement setStatement = (MySqlSetCharSetStatement) statement;
|
||||
// System.out.println("charset ="+setStatement.getCharSet()+ ",Collate ="+setStatement.getCollate()+",default ="+setStatement.isDefault());
|
||||
} else if (statement instanceof MySqlSetTransactionStatement) {
|
||||
MySqlSetTransactionStatement setStatement = (MySqlSetTransactionStatement) statement;
|
||||
System.out.println("global"+setStatement.getGlobal()+",IsolationLevel="+ setStatement.getIsolationLevel()+",access mode"+setStatement.getAccessModel());
|
||||
} else {
|
||||
System.out.println("statement:" + statement + "," + statement.getClass().toString());
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
System.out.println(rs.getInt(1));
|
||||
}
|
||||
rs = stmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
System.out.println(rs.getInt(1));
|
||||
}
|
||||
|
||||
rs.close();
|
||||
stmt.close();
|
||||
conn.close();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<<<<<<< HEAD
|
||||
GitVersion xxxxxx
|
||||
BuildTime yyyyMMddHHmmss
|
||||
=======
|
||||
GitVersion 1d36a5b3fc33294e3318343411bb9d2517733a1d
|
||||
BuildTime 20200724174006
|
||||
>>>>>>> #1880 fix packetId usage in show tables
|
||||
MavenVersion 9.9.9.9
|
||||
GitUrl https://github.com/actiontech/dble
|
||||
WebSite https://opensource.actionsky.com/
|
||||
|
||||
Reference in New Issue
Block a user