fix jdbc compatible pre-delivery statements error inner 2212

fix
This commit is contained in:
ylinzhu
2023-05-18 13:29:52 +08:00
committed by ylz
parent 21f97d2055
commit 3baaf021ae
3 changed files with 98 additions and 2 deletions

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2016-2021 ActionTech.
* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
*/
package com.actiontech.dble.backend.mysql.nio.handler;
import com.actiontech.dble.net.mysql.CharsetNames;
import com.actiontech.dble.net.mysql.FieldPacket;
import com.actiontech.dble.net.mysql.RowDataPacket;
import com.actiontech.dble.net.service.AbstractService;
import com.actiontech.dble.services.rwsplit.Callback;
import com.actiontech.dble.services.rwsplit.RWSplitHandler;
import com.actiontech.dble.services.rwsplit.RWSplitService;
import com.actiontech.dble.util.StringUtil;
import java.util.*;
public class RwSplitSelectVariablesHandler extends RWSplitHandler {
private CharsetNames charsetName;
private List<String> columnNames = new ArrayList<>();
public RwSplitSelectVariablesHandler(RWSplitService service, boolean isUseOriginPacket, byte[] originPacket, Callback callback) {
super(service, isUseOriginPacket, originPacket, callback);
charsetName = service.getCharset();
}
@Override
public void fieldEofResponse(byte[] header, List<byte[]> fields, List<FieldPacket> fieldPacketsNull, byte[] eof,
boolean isLeft, AbstractService service) {
for (byte[] field : fields) {
FieldPacket fieldPacket = new FieldPacket();
fieldPacket.read(field);
String columnName = StringUtil.decode(fieldPacket.getName(), charsetName.getResults());
columnNames.add(columnName);
}
super.fieldEofResponse(header, fields, fieldPacketsNull, eof, isLeft, service);
}
@Override
public boolean rowResponse(byte[] row, RowDataPacket rowPacket, boolean isLeft, AbstractService service) {
int index = columnNames.size();
RowDataPacket rowDataPacket = new RowDataPacket(index);
String charset = charsetName.getResults();
rowDataPacket.read(row);
Map<String, String> variables = getVariables();
for (int i = 0; i < index; i++) {
String columnName = columnNames.get(i);
if (variables.containsKey(columnName)) {
rowDataPacket.setValue(i, StringUtil.encode(variables.get(columnName), charset));
}
}
return super.rowResponse(rowDataPacket.toBytes(), rowPacket, isLeft, service);
}
private Map<String, String> getVariables() {
Map<String, String> variables = new HashMap<>();
variables.put("character_set_client", charsetName.getClient());
variables.put("collation_connection", charsetName.getCollation());
variables.put("character_set_results", charsetName.getResults());
variables.put("character_set_connection", charsetName.getCollation());
return variables;
}
}

View File

@@ -9,6 +9,7 @@ import com.actiontech.dble.DbleServer;
import com.actiontech.dble.backend.datasource.PhysicalDbGroup;
import com.actiontech.dble.backend.datasource.PhysicalDbInstance;
import com.actiontech.dble.backend.mysql.ByteUtil;
import com.actiontech.dble.backend.mysql.nio.handler.RwSplitSelectVariablesHandler;
import com.actiontech.dble.config.ErrorCode;
import com.actiontech.dble.config.model.SystemConfig;
import com.actiontech.dble.config.util.ConfigException;
@@ -219,6 +220,38 @@ public class RWSplitNonBlockingSession extends Session {
return writeStatistical;
}
/**
* jdbc compatible pre-delivery statements
* @param master
* @param originPacket
* @param callback
* @param writeStatistical
* @param localRead
*/
public void selectCompatibilityVariables(Boolean master, byte[] originPacket, Callback callback, boolean writeStatistical, boolean localRead) {
try {
RWSplitHandler handler = getRwSplitSelectVariablesHandler(originPacket != null ? originPacket : getService().getExecuteSqlBytes(), callback);
if (handler == null) return;
getConnection(handler, master, isWriteStatistical(writeStatistical), localRead);
} catch (SQLSyntaxErrorException | IOException se) {
rwSplitService.writeErrMessage(ErrorCode.ER_UNKNOWN_ERROR, se.getMessage());
}
}
@Nullable
private RWSplitHandler getRwSplitSelectVariablesHandler(byte[] originPacket, Callback callback) throws SQLSyntaxErrorException, IOException {
if (conn != null && !conn.isClosed()) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("select bind conn[id={}]", conn.getId());
}
RWSplitHandler handler = new RwSplitSelectVariablesHandler(rwSplitService, true, originPacket, callback);
checkDest(!conn.getInstance().isReadInstance());
handler.execute(conn);
return null;
}
return new RwSplitSelectVariablesHandler(rwSplitService, true, originPacket, callback);
}
private Boolean canRunOnMaster(Boolean master) {
if ((rwSplitService.isInTransaction() && !rwSplitService.isReadOnly()) || rwSplitService.isUsingTmpTable()) {
return true;

View File

@@ -6,7 +6,6 @@
package com.actiontech.dble.services.rwsplit.handle;
import com.actiontech.dble.server.parser.RwSplitServerParseSelect;
import com.actiontech.dble.server.response.SelectVariables;
import com.actiontech.dble.services.rwsplit.RWSplitService;
@@ -20,7 +19,7 @@ public final class RwSplitSelectHandler {
public static void handle(String stmt, RWSplitService service, int offset) {
switch (RwSplitServerParseSelect.parse(stmt, offset)) {
case RwSplitServerParseSelect.SELECT_VAR_ALL:
SelectVariables.execute(service, stmt);
service.getSession2().selectCompatibilityVariables(true, null, null, false, false);
break;
default: {
int rs2 = RwSplitServerParseSelect.parseSpecial(stmt);