From 2b859a6454d3c829d6679104da72f62422791f80 Mon Sep 17 00:00:00 2001 From: = <=> Date: Mon, 8 Jan 2024 17:03:10 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=89=A7=E8=A1=8C=E5=AE=8C=E5=90=8E?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E7=BB=A7=E7=BB=AD=E6=89=A7=E8=A1=8C=E9=98=9F?= =?UTF-8?q?=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/io/mycat/backend/jdbc/ShowVariables.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/io/mycat/backend/jdbc/ShowVariables.java b/src/main/java/io/mycat/backend/jdbc/ShowVariables.java index 5cb967c79..fb1920c50 100644 --- a/src/main/java/io/mycat/backend/jdbc/ShowVariables.java +++ b/src/main/java/io/mycat/backend/jdbc/ShowVariables.java @@ -31,6 +31,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import io.mycat.backend.mysql.listener.SqlExecuteStage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.mycat.backend.BackendConnection; @@ -189,10 +190,12 @@ public static void execute(ServerConnection sc, String orgin, BackendConnection execute(sc, orgin); NonBlockingSession session = sc.getSession2(); session.releaseConnectionIfSafe(jdbcConnection, LOGGER.isDebugEnabled(), false); + session.getSource().getListener().fireEvent(SqlExecuteStage.END); } public static void justReturnValue(ServerConnection sc, String orgin, BackendConnection jdbcConnection) { justReturnValue(sc, orgin); NonBlockingSession session = sc.getSession2(); session.releaseConnectionIfSafe(jdbcConnection, LOGGER.isDebugEnabled(), false); + session.getSource().getListener().fireEvent(SqlExecuteStage.END); } } \ No newline at end of file From 41d83f6519a0125b8ba9a6a1000fb3aadd3feb10 Mon Sep 17 00:00:00 2001 From: = <=> Date: Fri, 12 Jan 2024 23:12:02 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=94=AF=E6=8C=81sqlite=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E6=96=B0=E7=89=88mysql=20java=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/mycat/backend/jdbc/JDBCConnection.java | 8 +- .../io/mycat/backend/jdbc/ShowVariables.java | 74 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/mycat/backend/jdbc/JDBCConnection.java b/src/main/java/io/mycat/backend/jdbc/JDBCConnection.java index 7f94afe91..f6dc3104e 100644 --- a/src/main/java/io/mycat/backend/jdbc/JDBCConnection.java +++ b/src/main/java/io/mycat/backend/jdbc/JDBCConnection.java @@ -372,7 +372,13 @@ private void executeSQL(RouteResultsetNode rrn, ServerConnection sc, //ShowVariables.justReturnValue(sc,String.valueOf(sc.getId())); ShowVariables.justReturnValue(sc,String.valueOf(sc.getId()),this); } else { - ouputResultSet(sc, orgin); + if (sqlType == ServerParse.SELECT && dbType.equals("SQLITE") && orgin.contains("@@")) { + if (!ShowVariables.executeSelectVar(sc, orgin, this)) { + ouputResultSet(sc, orgin); + } + } else { + ouputResultSet(sc, orgin); + } } } else { executeddl(sc, orgin); diff --git a/src/main/java/io/mycat/backend/jdbc/ShowVariables.java b/src/main/java/io/mycat/backend/jdbc/ShowVariables.java index fb1920c50..195b62594 100644 --- a/src/main/java/io/mycat/backend/jdbc/ShowVariables.java +++ b/src/main/java/io/mycat/backend/jdbc/ShowVariables.java @@ -31,7 +31,12 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.ast.statement.SQLSelectItem; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import io.mycat.backend.mysql.listener.SqlExecuteStage; +import io.mycat.route.parser.druid.MycatStatementParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.mycat.backend.BackendConnection; @@ -184,6 +189,9 @@ private static RowDataPacket getRow(String name, String value, String charset) { variables.put("time_zone", "SYSTEM"); variables.put("tx_isolation", "REPEATABLE-READ"); variables.put("wait_timeout", "172800"); + + //add by = + variables.put("auto_increment_increment", "1"); } public static void execute(ServerConnection sc, String orgin, BackendConnection jdbcConnection) { @@ -198,4 +206,70 @@ public static void justReturnValue(ServerConnection sc, String orgin, BackendCon session.releaseConnectionIfSafe(jdbcConnection, LOGGER.isDebugEnabled(), false); session.getSource().getListener().fireEvent(SqlExecuteStage.END); } + + public static boolean executeSelectVar(ServerConnection c, String sql, BackendConnection jdbcConnection) { + MycatStatementParser parser = new MycatStatementParser(sql); + SQLSelectStatement sss = parser.parseSelect(); + SQLSelect ss = sss.getSelect(); + SQLSelectQueryBlock qry = ss.getQueryBlock(); + if (null != qry.getFrom() && !"dual".equalsIgnoreCase(qry.getFrom().toString())) { + return false; + } + + List ssis = qry.getSelectList(); + int FIELD_COUNT = ssis.size(); + ResultSetHeaderPacket header = PacketUtil.getHeader(FIELD_COUNT); + FieldPacket[] fields = new FieldPacket[FIELD_COUNT]; + EOFPacket eof = new EOFPacket(); + + int i = 0; + byte packetId = 0; + header.packetId = ++packetId; + + for(; i < FIELD_COUNT; i++) { + SQLSelectItem ssi = ssis.get(i); + if (null == ssi.getAlias() || null == ssi.getExpr() || !ssi.getExpr().toString().startsWith("@@")) { + return false; + } + fields[i] = PacketUtil.getField(ssi.getAlias(), Fields.FIELD_TYPE_VAR_STRING); + fields[i].packetId = ++packetId; + } + + eof.packetId = ++packetId; + + ByteBuffer buffer = c.allocate(); + + // write header + buffer = header.write(buffer, c,true); + + // write fields + for (FieldPacket field : fields) { + buffer = field.write(buffer, c,true); + } + + // write eof + buffer = eof.write(buffer, c,true); + + + RowDataPacket row = new RowDataPacket(FIELD_COUNT); + ssis.forEach(ssi -> { + String val = variables.get(ssi.getAlias()); + row.add(StringUtil.encode(val, c.getCharset())); + }); + row.packetId = ++packetId; + buffer = row.write(buffer, c,true); + + // write lastEof + EOFPacket lastEof = new EOFPacket(); + lastEof.packetId = ++packetId; + buffer = lastEof.write(buffer, c,true); + + // write buffer + c.write(buffer); + + NonBlockingSession session = c.getSession2(); + session.releaseConnectionIfSafe(jdbcConnection, LOGGER.isDebugEnabled(), false); + session.getSource().getListener().fireEvent(SqlExecuteStage.END); + return true; + } } \ No newline at end of file From 4330c84cf3df83045cce52411c62959e26d628a7 Mon Sep 17 00:00:00 2001 From: = <=> Date: Mon, 15 Jan 2024 14:15:06 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=94=AF=E6=8C=81sqlite=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E6=96=B0=E7=89=88mysql=20java=E9=A9=B1=E5=8A=A8-=E6=94=AF?= =?UTF-8?q?=E6=8C=81set=E5=85=A8=E5=B1=80=E5=8F=98=E9=87=8F=EF=BC=88?= =?UTF-8?q?=E4=B8=8D=E6=A0=A1=E9=AA=8C=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/mycat/backend/jdbc/JDBCConnection.java | 16 ++- .../io/mycat/backend/jdbc/ShowVariables.java | 133 +++++++++++------- .../backend/jdbc/UnExecutedException.java | 16 +++ 3 files changed, 114 insertions(+), 51 deletions(-) create mode 100644 src/main/java/io/mycat/backend/jdbc/UnExecutedException.java diff --git a/src/main/java/io/mycat/backend/jdbc/JDBCConnection.java b/src/main/java/io/mycat/backend/jdbc/JDBCConnection.java index f6dc3104e..d4e776540 100644 --- a/src/main/java/io/mycat/backend/jdbc/JDBCConnection.java +++ b/src/main/java/io/mycat/backend/jdbc/JDBCConnection.java @@ -373,7 +373,10 @@ private void executeSQL(RouteResultsetNode rrn, ServerConnection sc, ShowVariables.justReturnValue(sc,String.valueOf(sc.getId()),this); } else { if (sqlType == ServerParse.SELECT && dbType.equals("SQLITE") && orgin.contains("@@")) { - if (!ShowVariables.executeSelectVar(sc, orgin, this)) { + try{ + ShowVariables.executeSelectVar(sc, orgin, this); + } catch (UnExecutedException e) { + LOGGER.error("sql parser error, will try backend." , e); ouputResultSet(sc, orgin); } } else { @@ -381,7 +384,16 @@ private void executeSQL(RouteResultsetNode rrn, ServerConnection sc, } } } else { - executeddl(sc, orgin); + if (sqlType == ServerParse.UPDATE && dbType.equals("SQLITE") && orgin.contains("@@")) { + try{ + ShowVariables.executeSetVar(sc, orgin, this); + } catch (UnExecutedException e) { + LOGGER.error("sql parser error, will try backend." , e); + executeddl(sc, orgin); + } + } else { + executeddl(sc, orgin); + } } } catch (SQLException e) { diff --git a/src/main/java/io/mycat/backend/jdbc/ShowVariables.java b/src/main/java/io/mycat/backend/jdbc/ShowVariables.java index 195b62594..a7981ac18 100644 --- a/src/main/java/io/mycat/backend/jdbc/ShowVariables.java +++ b/src/main/java/io/mycat/backend/jdbc/ShowVariables.java @@ -31,21 +31,19 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.alibaba.druid.sql.ast.statement.SQLSelect; -import com.alibaba.druid.sql.ast.statement.SQLSelectItem; -import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; -import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.expr.SQLCharExpr; +import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; +import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.ast.statement.*; import io.mycat.backend.mysql.listener.SqlExecuteStage; +import io.mycat.net.mysql.*; import io.mycat.route.parser.druid.MycatStatementParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.mycat.backend.BackendConnection; import io.mycat.backend.mysql.PacketUtil; import io.mycat.config.Fields; -import io.mycat.net.mysql.EOFPacket; -import io.mycat.net.mysql.FieldPacket; -import io.mycat.net.mysql.ResultSetHeaderPacket; -import io.mycat.net.mysql.RowDataPacket; import io.mycat.server.NonBlockingSession; import io.mycat.server.ServerConnection; import io.mycat.util.StringUtil; @@ -207,69 +205,106 @@ public static void justReturnValue(ServerConnection sc, String orgin, BackendCon session.getSource().getListener().fireEvent(SqlExecuteStage.END); } - public static boolean executeSelectVar(ServerConnection c, String sql, BackendConnection jdbcConnection) { - MycatStatementParser parser = new MycatStatementParser(sql); - SQLSelectStatement sss = parser.parseSelect(); - SQLSelect ss = sss.getSelect(); - SQLSelectQueryBlock qry = ss.getQueryBlock(); - if (null != qry.getFrom() && !"dual".equalsIgnoreCase(qry.getFrom().toString())) { - return false; - } + public static void executeSelectVar(ServerConnection c, String sql, BackendConnection jdbcConnection) throws UnExecutedException { + + ResultSetHeaderPacket header; + FieldPacket[] fields; + EOFPacket eof; + RowDataPacket row; + EOFPacket lastEof; + + try { + MycatStatementParser parser = new MycatStatementParser(sql); + SQLSelectStatement sss = parser.parseSelect(); + SQLSelect ss = sss.getSelect(); + SQLSelectQueryBlock qry = ss.getQueryBlock(); + if (null != qry.getFrom() && !"dual".equalsIgnoreCase(qry.getFrom().toString())) { + throw new UnExecutedException("format error"); + } - List ssis = qry.getSelectList(); - int FIELD_COUNT = ssis.size(); - ResultSetHeaderPacket header = PacketUtil.getHeader(FIELD_COUNT); - FieldPacket[] fields = new FieldPacket[FIELD_COUNT]; - EOFPacket eof = new EOFPacket(); + List ssis = qry.getSelectList(); + int FIELD_COUNT = ssis.size(); - int i = 0; - byte packetId = 0; - header.packetId = ++packetId; + byte packetId = 0; - for(; i < FIELD_COUNT; i++) { - SQLSelectItem ssi = ssis.get(i); - if (null == ssi.getAlias() || null == ssi.getExpr() || !ssi.getExpr().toString().startsWith("@@")) { - return false; + header = PacketUtil.getHeader(FIELD_COUNT); + header.packetId = ++packetId; + + fields = new FieldPacket[FIELD_COUNT]; + for(int i = 0; i < FIELD_COUNT; i++) { + SQLSelectItem ssi = ssis.get(i); + if (null == ssi.getAlias() || null == ssi.getExpr() || !ssi.getExpr().toString().startsWith("@@")) { + throw new UnExecutedException("format error"); + } + fields[i] = PacketUtil.getField(ssi.getAlias(), Fields.FIELD_TYPE_VAR_STRING); + fields[i].packetId = ++packetId; } - fields[i] = PacketUtil.getField(ssi.getAlias(), Fields.FIELD_TYPE_VAR_STRING); - fields[i].packetId = ++packetId; - } - eof.packetId = ++packetId; + eof = new EOFPacket(); + eof.packetId = ++packetId; - ByteBuffer buffer = c.allocate(); + row = new RowDataPacket(FIELD_COUNT); + for (SQLSelectItem ssi: ssis) { + String val = variables.get(ssi.getAlias()); + row.add(StringUtil.encode(val, c.getCharset())); + } + row.packetId = ++packetId; + + // write lastEof + lastEof = new EOFPacket(); + lastEof.packetId = ++packetId; + + } catch (Throwable e) { + throw new UnExecutedException(e); + } + ByteBuffer buffer = c.allocate(); // write header buffer = header.write(buffer, c,true); - // write fields for (FieldPacket field : fields) { buffer = field.write(buffer, c,true); } - // write eof buffer = eof.write(buffer, c,true); - - - RowDataPacket row = new RowDataPacket(FIELD_COUNT); - ssis.forEach(ssi -> { - String val = variables.get(ssi.getAlias()); - row.add(StringUtil.encode(val, c.getCharset())); - }); - row.packetId = ++packetId; buffer = row.write(buffer, c,true); - - // write lastEof - EOFPacket lastEof = new EOFPacket(); - lastEof.packetId = ++packetId; buffer = lastEof.write(buffer, c,true); - // write buffer c.write(buffer); NonBlockingSession session = c.getSession2(); session.releaseConnectionIfSafe(jdbcConnection, LOGGER.isDebugEnabled(), false); session.getSource().getListener().fireEvent(SqlExecuteStage.END); - return true; + } + + public static void executeSetVar(ServerConnection c, String sql, BackendConnection jdbcConnection) throws UnExecutedException { + + try { + MycatStatementParser parser = new MycatStatementParser(sql); + SQLSetStatement ss = (SQLSetStatement)parser.parseSet(); + for (SQLAssignItem item : ss.getItems()) { + String tagert = ((SQLVariantRefExpr)item.getTarget()).getName(); + String value = null; + if (item.getValue() instanceof SQLCharExpr){ + value = ((SQLCharExpr) item.getValue()).getText(); + } else if (item.getValue() instanceof SQLIntegerExpr) { + value = ((SQLIntegerExpr) item.getValue()).getNumber().toString(); + } + if (tagert.startsWith("@@") && null != value) { + tagert = tagert.substring(2); + variables.put(tagert, value); + } else { + throw new UnExecutedException("format error"); + } + } + } catch (Throwable e) { + throw new UnExecutedException(e); + } + + c.write(c.writeToBuffer(OkPacket.OK, c.allocate())); + + NonBlockingSession session = c.getSession2(); + session.releaseConnectionIfSafe(jdbcConnection, LOGGER.isDebugEnabled(), false); + session.getSource().getListener().fireEvent(SqlExecuteStage.END); } } \ No newline at end of file diff --git a/src/main/java/io/mycat/backend/jdbc/UnExecutedException.java b/src/main/java/io/mycat/backend/jdbc/UnExecutedException.java new file mode 100644 index 000000000..39d0eee5b --- /dev/null +++ b/src/main/java/io/mycat/backend/jdbc/UnExecutedException.java @@ -0,0 +1,16 @@ +package io.mycat.backend.jdbc; + +public class UnExecutedException extends Exception { + public UnExecutedException() {} + public UnExecutedException(String message) { + super(message); + } + + public UnExecutedException(String message, Throwable cause) { + super(message, cause); + } + + public UnExecutedException(Throwable cause) { + super(cause); + } +} From f2cd604e12fc64cffae398e9033e7ca9f1bb4137 Mon Sep 17 00:00:00 2001 From: = <=> Date: Mon, 15 Jan 2024 14:16:40 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=94=AF=E6=8C=81sqlite=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E6=96=B0=E7=89=88mysql=20java=E9=A9=B1=E5=8A=A8-=E6=94=AF?= =?UTF-8?q?=E6=8C=81set=E5=85=A8=E5=B1=80=E5=8F=98=E9=87=8F=EF=BC=88?= =?UTF-8?q?=E4=B8=8D=E6=A0=A1=E9=AA=8C=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/io/mycat/backend/jdbc/ShowVariables.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/io/mycat/backend/jdbc/ShowVariables.java b/src/main/java/io/mycat/backend/jdbc/ShowVariables.java index a7981ac18..c90bc668d 100644 --- a/src/main/java/io/mycat/backend/jdbc/ShowVariables.java +++ b/src/main/java/io/mycat/backend/jdbc/ShowVariables.java @@ -31,7 +31,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLCharExpr; import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;