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:
Collapsar
2020-09-25 13:30:34 +08:00
committed by GitHub
parent 31754f70e3
commit 3b9a44387c
36 changed files with 1024 additions and 2240 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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
*/

View File

@@ -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);
}

View File

@@ -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());

View File

@@ -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()) {

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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();
}
}
}

View File

@@ -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());

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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) {

View 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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());

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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());
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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 + "]";
}
}

View File

@@ -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"));
// }
}

View File

@@ -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();
}
}

View File

@@ -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/