From fe7476a2e696cc342c47476e724e99f259cadb82 Mon Sep 17 00:00:00 2001 From: beckhampu Date: Thu, 20 Sep 2018 16:52:11 +0800 Subject: [PATCH 1/6] use real schema instead of sharding_db in SHOW TABLES results --- .../merger/dal/show/ShowTablesMergedResult.java | 12 ++++++++++++ .../core/merger/dql/common/MemoryMergedResult.java | 5 +++++ .../proxy/backend/jdbc/JDBCBackendHandler.java | 13 +++++++++++++ .../command/query/ColumnDefinition41Packet.java | 4 +++- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/show/ShowTablesMergedResult.java b/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/show/ShowTablesMergedResult.java index 64f6b8862a171..3c5baeba16923 100644 --- a/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/show/ShowTablesMergedResult.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/show/ShowTablesMergedResult.java @@ -44,4 +44,16 @@ public final class ShowTablesMergedResult extends LogicTablesMergedResult { public ShowTablesMergedResult(final ShardingRule shardingRule, final List queryResults, final ShardingTableMetaData shardingTableMetaData) throws SQLException { super(LABEL_AND_INDEX_MAP, shardingRule, queryResults, shardingTableMetaData); } + + /** + * Reset column label. + * + * @param schema schema + */ + public void resetColumnLabel(final String schema) { + Map labelAndIndexMapnew = new HashMap<>(1, 1); + labelAndIndexMapnew.put(schema, 1); + resetLabelAndIndexMap(labelAndIndexMapnew); + } + } diff --git a/sharding-core/src/main/java/io/shardingsphere/core/merger/dql/common/MemoryMergedResult.java b/sharding-core/src/main/java/io/shardingsphere/core/merger/dql/common/MemoryMergedResult.java index 6ed1b76b7d2fa..136690577baac 100644 --- a/sharding-core/src/main/java/io/shardingsphere/core/merger/dql/common/MemoryMergedResult.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/merger/dql/common/MemoryMergedResult.java @@ -47,6 +47,11 @@ public abstract class MemoryMergedResult implements MergedResult { private boolean wasNull; + protected final void resetLabelAndIndexMap(final Map labelAndIndexMap) { + this.labelAndIndexMap.clear(); + this.labelAndIndexMap.putAll(labelAndIndexMap); + } + @Override public final Object getValue(final int columnIndex, final Class type) throws SQLException { if (Blob.class == type || Clob.class == type || Reader.class == type || InputStream.class == type || SQLXML.class == type) { diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/JDBCBackendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/JDBCBackendHandler.java index 8f644e7afaa1d..2745ec15008c9 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/JDBCBackendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/JDBCBackendHandler.java @@ -23,6 +23,7 @@ import io.shardingsphere.core.merger.MergeEngineFactory; import io.shardingsphere.core.merger.MergedResult; import io.shardingsphere.core.merger.dal.show.ShowDatabasesMergedResult; +import io.shardingsphere.core.merger.dal.show.ShowTablesMergedResult; import io.shardingsphere.core.metadata.table.executor.TableMetaDataLoader; import io.shardingsphere.core.parsing.parser.constant.DerivedColumn; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.UseStatement; @@ -81,12 +82,15 @@ public final class JDBCBackendHandler extends AbstractBackendHandler { private int currentSequenceId; + private String currentSchema; + @Override protected CommandResponsePackets execute0() throws SQLException { return execute(executeEngine.getJdbcExecutorWrapper().route(sql, DatabaseType.MySQL)); } private CommandResponsePackets execute(final SQLRouteResult routeResult) throws SQLException { + currentSchema = frontendHandler.getCurrentSchema(); if (routeResult.getSqlStatement() != null && routeResult.getSqlStatement() instanceof UseStatement) { return handleUseStatement((UseStatement) routeResult.getSqlStatement(), frontendHandler); } @@ -122,6 +126,9 @@ private CommandResponsePackets merge(final SQLStatement sqlStatement) throws SQL ruleRegistry.getShardingRule(), ((ExecuteQueryResponse) executeResponse).getQueryResults(), sqlStatement, ruleRegistry.getMetaData().getTable()).merge(); if (mergedResult instanceof ShowDatabasesMergedResult) { mergedResult = new ShowDatabasesMergedResult(PROXY_CONTEXT.getSchemaNames()); + } else if (mergedResult instanceof ShowTablesMergedResult) { + ((ShowTablesMergedResult) mergedResult).resetColumnLabel(currentSchema); + setResponseColumnLabelForShowTablesMergedResult(((ExecuteQueryResponse) executeResponse).getQueryResponsePackets()); } QueryResponsePackets result = getQueryResponsePacketsWithoutDerivedColumns(((ExecuteQueryResponse) executeResponse).getQueryResponsePackets()); currentSequenceId = result.getPackets().size(); @@ -141,6 +148,12 @@ private QueryResponsePackets getQueryResponsePacketsWithoutDerivedColumns(final return new QueryResponsePackets(fieldCountPacket, columnDefinition41Packets, new EofPacket(columnCount + 2)); } + private void setResponseColumnLabelForShowTablesMergedResult(final QueryResponsePackets queryResponsePackets) { + for (ColumnDefinition41Packet each : queryResponsePackets.getColumnDefinition41Packets()) { + each.setName("Tables_in_" + currentSchema); + } + } + @Override public boolean next() throws SQLException { return null != mergedResult && mergedResult.next(); diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/transport/mysql/packet/command/query/ColumnDefinition41Packet.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/transport/mysql/packet/command/query/ColumnDefinition41Packet.java index 8c3cfbc4242ec..04c78b26ebbaa 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/transport/mysql/packet/command/query/ColumnDefinition41Packet.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/transport/mysql/packet/command/query/ColumnDefinition41Packet.java @@ -23,6 +23,7 @@ import io.shardingsphere.proxy.transport.mysql.packet.MySQLPacket; import io.shardingsphere.proxy.transport.mysql.packet.MySQLPacketPayload; import lombok.Getter; +import lombok.Setter; import java.sql.ResultSetMetaData; import java.sql.SQLException; @@ -54,7 +55,8 @@ public final class ColumnDefinition41Packet implements MySQLPacket { private final String orgTable; @Getter - private final String name; + @Setter + private String name; private final String orgName; From 2b0d75cb477f6609afb7ce1f7515cc75fea08e58 Mon Sep 17 00:00:00 2001 From: beckhampu Date: Fri, 21 Sep 2018 17:25:52 +0800 Subject: [PATCH 2/6] adjust sql judge engine to support db_name --- .../core/parsing/SQLJudgeEngine.java | 82 +++++++++++++++++-- .../dialect/mysql/statement/SetStatement.java | 28 +++++++ .../parsing/parser/sql/tcl/TCLStatement.java | 2 +- 3 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/dialect/mysql/statement/SetStatement.java diff --git a/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java b/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java index 08757efab53d4..0b39353e574d2 100755 --- a/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java @@ -24,11 +24,15 @@ import io.shardingsphere.core.parsing.lexer.token.Assist; import io.shardingsphere.core.parsing.lexer.token.DefaultKeyword; import io.shardingsphere.core.parsing.lexer.token.Keyword; +import io.shardingsphere.core.parsing.lexer.token.Symbol; import io.shardingsphere.core.parsing.lexer.token.TokenType; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.DescribeStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.SetStatement; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowColumnsStatement; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowDatabasesStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowIndexStatement; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowOtherStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowTableStatusStatement; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowTablesStatement; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.UseStatement; import io.shardingsphere.core.parsing.parser.exception.SQLParsingException; @@ -41,6 +45,7 @@ import io.shardingsphere.core.parsing.parser.sql.dql.DQLStatement; import io.shardingsphere.core.parsing.parser.sql.dql.select.SelectStatement; import io.shardingsphere.core.parsing.parser.sql.tcl.TCLStatement; +import io.shardingsphere.core.parsing.parser.token.SchemaToken; import lombok.RequiredArgsConstructor; /** @@ -72,7 +77,7 @@ public SQLStatement judge() { return getDMLStatement(tokenType); } if (TCLStatement.isTCL(tokenType)) { - return getTCLStatement(); + return getTCLStatement(tokenType); } if (DALStatement.isDAL(tokenType)) { return getDALStatement(tokenType, lexerEngine); @@ -113,7 +118,10 @@ private SQLStatement getDCLStatement() { return new DCLStatement(); } - private SQLStatement getTCLStatement() { + private SQLStatement getTCLStatement(final TokenType tokenType) { + if (DefaultKeyword.SET == tokenType) { + return new SetStatement(); + } return new TCLStatement(); } @@ -130,15 +138,75 @@ private SQLStatement getDALStatement(final TokenType tokenType, final LexerEngin private SQLStatement getShowStatement(final LexerEngine lexerEngine) { lexerEngine.nextToken(); - if (MySQLKeyword.DATABASES == lexerEngine.getCurrentToken().getType()) { + lexerEngine.skipIfEqual(DefaultKeyword.FULL); + if (lexerEngine.equalAny(MySQLKeyword.DATABASES)) { return new ShowDatabasesStatement(); } - if (MySQLKeyword.TABLES == lexerEngine.getCurrentToken().getType()) { - return new ShowTablesStatement(); + if (lexerEngine.skipIfEqual(DefaultKeyword.TABLE, MySQLKeyword.STATUS)) { + return parseShowTableStatus(lexerEngine); + } + if (lexerEngine.skipIfEqual(MySQLKeyword.TABLES)) { + return parseShowTables(lexerEngine); + } + if (lexerEngine.skipIfEqual(MySQLKeyword.COLUMNS, MySQLKeyword.FIELDS)) { + return parseShowColumnsFields(lexerEngine); } - if (MySQLKeyword.COLUMNS == lexerEngine.getCurrentToken().getType()) { - return new ShowColumnsStatement(); + if (lexerEngine.skipIfEqual(DefaultKeyword.INDEX, MySQLKeyword.INDEXES, MySQLKeyword.KEYS)) { + return parseShowIndex(lexerEngine); } return new ShowOtherStatement(); } + + private DALStatement parseShowTables(final LexerEngine lexerEngine) { + DALStatement result = new ShowTablesStatement(); + if (lexerEngine.equalAny(DefaultKeyword.FROM, DefaultKeyword.IN)) { + int beginPosition = lexerEngine.getCurrentToken().getEndPosition() - lexerEngine.getCurrentToken().getLiterals().length(); + lexerEngine.nextToken(); + lexerEngine.nextToken(); + result.getSqlTokens().add(new SchemaToken(beginPosition, lexerEngine.getCurrentToken().getLiterals(), null)); + } + return result; + } + + private DALStatement parseShowColumnsFields(final LexerEngine lexerEngine) { + DALStatement result = new ShowColumnsStatement(); + lexerEngine.skipIfEqual(DefaultKeyword.FROM, DefaultKeyword.IN); + parseSingleTableWithSchema(lexerEngine, result); + if (lexerEngine.skipIfEqual(DefaultKeyword.FROM, DefaultKeyword.IN)) { + int beginPosition = lexerEngine.getCurrentToken().getEndPosition() - lexerEngine.getCurrentToken().getLiterals().length(); + result.getSqlTokens().add(new SchemaToken(beginPosition, lexerEngine.getCurrentToken().getLiterals(), null)); + } + return result; + } + + private void parseSingleTableWithSchema(final LexerEngine lexerEngine, final SQLStatement sqlStatement) { + int beginPosition = lexerEngine.getCurrentToken().getEndPosition() - lexerEngine.getCurrentToken().getLiterals().length(); + String literals = lexerEngine.getCurrentToken().getLiterals(); + lexerEngine.nextToken(); + if (lexerEngine.skipIfEqual(Symbol.DOT)) { + sqlStatement.getSqlTokens().add(new SchemaToken(beginPosition, literals, null)); + lexerEngine.nextToken(); + } + } + + private DALStatement parseShowIndex(final LexerEngine lexerEngine) { + DALStatement result = new ShowIndexStatement(); + lexerEngine.skipIfEqual(DefaultKeyword.FROM, DefaultKeyword.IN); + parseSingleTableWithSchema(lexerEngine, result); + if (lexerEngine.skipIfEqual(DefaultKeyword.FROM, DefaultKeyword.IN)) { + int beginPosition = lexerEngine.getCurrentToken().getEndPosition() - lexerEngine.getCurrentToken().getLiterals().length(); + result.getSqlTokens().add(new SchemaToken(beginPosition, lexerEngine.getCurrentToken().getLiterals(), null)); + } + return result; + } + + private DALStatement parseShowTableStatus(final LexerEngine lexerEngine) { + DALStatement result = new ShowTableStatusStatement(); + lexerEngine.nextToken(); + if (lexerEngine.skipIfEqual(DefaultKeyword.FROM, DefaultKeyword.IN)) { + int beginPosition = lexerEngine.getCurrentToken().getEndPosition() - lexerEngine.getCurrentToken().getLiterals().length(); + result.getSqlTokens().add(new SchemaToken(beginPosition, lexerEngine.getCurrentToken().getLiterals(), null)); + } + return result; + } } diff --git a/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/dialect/mysql/statement/SetStatement.java b/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/dialect/mysql/statement/SetStatement.java new file mode 100644 index 0000000000000..15aa72e196989 --- /dev/null +++ b/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/dialect/mysql/statement/SetStatement.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016-2018 shardingsphere.io. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *

+ */ + +package io.shardingsphere.core.parsing.parser.dialect.mysql.statement; + +import io.shardingsphere.core.parsing.parser.sql.tcl.TCLStatement; + +/** + * Set statement. + * + * @author chenqingyang + */ +public final class SetStatement extends TCLStatement { +} diff --git a/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/sql/tcl/TCLStatement.java b/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/sql/tcl/TCLStatement.java index ef735b7cadaca..f549f4c0aa65f 100644 --- a/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/sql/tcl/TCLStatement.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/sql/tcl/TCLStatement.java @@ -33,7 +33,7 @@ * @author zhangliang */ @ToString(callSuper = true) -public final class TCLStatement extends AbstractSQLStatement { +public class TCLStatement extends AbstractSQLStatement { private static final Collection STATEMENT_PREFIX = Arrays.asList( DefaultKeyword.SET, DefaultKeyword.COMMIT, DefaultKeyword.ROLLBACK, DefaultKeyword.SAVEPOINT, DefaultKeyword.BEGIN); From 63aa5366a7867009fcb0f2e041d484f1dcd80e95 Mon Sep 17 00:00:00 2001 From: beckhampu Date: Fri, 21 Sep 2018 20:24:45 +0800 Subject: [PATCH 3/6] remove default schema --- .../core/parsing/SQLJudgeEngine.java | 1 - .../proxy/backend/BackendHandlerFactory.java | 54 ++++++++++++++++++- .../backend/jdbc/JDBCBackendHandler.java | 13 +++-- .../jdbc/connection/BackendConnection.java | 8 +-- .../proxy/config/ProxyContext.java | 3 +- .../frontend/common/FrontendHandler.java | 4 -- .../frontend/mysql/MySQLFrontendHandler.java | 2 +- 7 files changed, 66 insertions(+), 19 deletions(-) diff --git a/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java b/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java index 0b39353e574d2..dd5cb5cc6f7fd 100755 --- a/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java @@ -162,7 +162,6 @@ private DALStatement parseShowTables(final LexerEngine lexerEngine) { if (lexerEngine.equalAny(DefaultKeyword.FROM, DefaultKeyword.IN)) { int beginPosition = lexerEngine.getCurrentToken().getEndPosition() - lexerEngine.getCurrentToken().getLiterals().length(); lexerEngine.nextToken(); - lexerEngine.nextToken(); result.getSqlTokens().add(new SchemaToken(beginPosition, lexerEngine.getCurrentToken().getLiterals(), null)); } return result; diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/BackendHandlerFactory.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/BackendHandlerFactory.java index 7ff060acf11bf..23680f586f292 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/BackendHandlerFactory.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/BackendHandlerFactory.java @@ -17,7 +17,21 @@ package io.shardingsphere.proxy.backend; +import com.google.common.base.Strings; import io.shardingsphere.core.constant.DatabaseType; +import io.shardingsphere.core.constant.SQLType; +import io.shardingsphere.core.parsing.SQLJudgeEngine; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.SetStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowColumnsStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowDatabasesStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowIndexStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowOtherStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowTableStatusStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowTablesStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.UseStatement; +import io.shardingsphere.core.parsing.parser.sql.SQLStatement; +import io.shardingsphere.core.parsing.parser.token.SQLToken; +import io.shardingsphere.core.parsing.parser.token.SchemaToken; import io.shardingsphere.proxy.backend.jdbc.JDBCBackendHandler; import io.shardingsphere.proxy.backend.jdbc.connection.BackendConnection; import io.shardingsphere.proxy.backend.jdbc.execute.JDBCExecuteEngine; @@ -30,6 +44,7 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; +import java.util.LinkedList; import java.util.List; /** @@ -56,7 +71,9 @@ public final class BackendHandlerFactory { */ public static BackendHandler newTextProtocolInstance( final int connectionId, final int sequenceId, final String sql, final BackendConnection backendConnection, final DatabaseType databaseType, final FrontendHandler frontendHandler) { - RuleRegistry ruleRegistry = PROXY_CONTEXT.getRuleRegistry(frontendHandler.getCurrentSchema()); + String schema = Strings.isNullOrEmpty(getSchemaBySql(sql)) ? frontendHandler.getCurrentSchema() : getSchemaBySql(sql); + RuleRegistry ruleRegistry = PROXY_CONTEXT.getRuleRegistry(schema); + backendConnection.setRuleRegistry(ruleRegistry); return PROXY_CONTEXT.isUseNIO() ? new NettyBackendHandler(frontendHandler, ruleRegistry, connectionId, sequenceId, sql, databaseType) : new JDBCBackendHandler( @@ -78,9 +95,42 @@ public static BackendHandler newTextProtocolInstance( public static BackendHandler newBinaryProtocolInstance( final int connectionId, final int sequenceId, final String sql, final List parameters, final BackendConnection backendConnection, final DatabaseType databaseType, final FrontendHandler frontendHandler) { - RuleRegistry ruleRegistry = PROXY_CONTEXT.getRuleRegistry(frontendHandler.getCurrentSchema()); + String schema = Strings.isNullOrEmpty(getSchemaBySql(sql)) ? frontendHandler.getCurrentSchema() : getSchemaBySql(sql); + RuleRegistry ruleRegistry = PROXY_CONTEXT.getRuleRegistry(schema); + backendConnection.setRuleRegistry(ruleRegistry); return PROXY_CONTEXT.isUseNIO() ? new NettyBackendHandler(frontendHandler, ruleRegistry, connectionId, sequenceId, sql, databaseType) : new JDBCBackendHandler(frontendHandler, ruleRegistry, sql, new JDBCExecuteEngine(backendConnection, new PreparedStatementExecutorWrapper(ruleRegistry, parameters))); } + + private static String getSchemaBySql(final String sql) { + String schema = ""; + SQLStatement sqlStatement = new SQLJudgeEngine(sql).judge(); + + if (SQLType.DCL == sqlStatement.getType()) { + //todo dcl syntax need instance broadcast + schema = PROXY_CONTEXT.getDefaultSchema(); + } + + if (SQLType.TCL == sqlStatement.getType() && sqlStatement instanceof SetStatement) { + //todo set syntax need instance broadcast + schema = PROXY_CONTEXT.getDefaultSchema(); + } + + if (SQLType.DAL == sqlStatement.getType()) { + if (!sqlStatement.getSqlTokens().isEmpty() + && (sqlStatement instanceof ShowTablesStatement || sqlStatement instanceof ShowColumnsStatement + || sqlStatement instanceof ShowIndexStatement || sqlStatement instanceof ShowTableStatusStatement)) { + LinkedList sqlTokens = new LinkedList<>(); + sqlTokens.addAll(sqlStatement.getSqlTokens()); + schema = ((SchemaToken) sqlTokens.getLast()).getOriginalLiterals(); + } + + if (sqlStatement instanceof ShowDatabasesStatement || sqlStatement instanceof ShowOtherStatement || sqlStatement instanceof UseStatement) { + schema = PROXY_CONTEXT.getDefaultSchema(); + } + } + + return schema; + } } diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/JDBCBackendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/JDBCBackendHandler.java index 2745ec15008c9..a27beaec59bee 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/JDBCBackendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/JDBCBackendHandler.java @@ -82,15 +82,14 @@ public final class JDBCBackendHandler extends AbstractBackendHandler { private int currentSequenceId; - private String currentSchema; - @Override protected CommandResponsePackets execute0() throws SQLException { - return execute(executeEngine.getJdbcExecutorWrapper().route(sql, DatabaseType.MySQL)); + return ruleRegistry == null + ? new CommandResponsePackets(new ErrPacket(1, ServerErrorCode.ER_NO_DB_ERROR)) + : execute(executeEngine.getJdbcExecutorWrapper().route(sql, DatabaseType.MySQL)); } private CommandResponsePackets execute(final SQLRouteResult routeResult) throws SQLException { - currentSchema = frontendHandler.getCurrentSchema(); if (routeResult.getSqlStatement() != null && routeResult.getSqlStatement() instanceof UseStatement) { return handleUseStatement((UseStatement) routeResult.getSqlStatement(), frontendHandler); } @@ -106,7 +105,7 @@ private CommandResponsePackets execute(final SQLRouteResult routeResult) throws if (!ruleRegistry.isMasterSlaveOnly() && SQLType.DDL == sqlStatement.getType() && !sqlStatement.getTables().isEmpty()) { String logicTableName = sqlStatement.getTables().getSingleTableName(); // TODO refresh table meta data by SQL parse result - TableMetaDataLoader tableMetaDataLoader = new TableMetaDataLoader(ruleRegistry.getMetaData().getDataSource(), BackendExecutorContext.getInstance().getExecuteEngine(), + TableMetaDataLoader tableMetaDataLoader = new TableMetaDataLoader(ruleRegistry.getMetaData().getDataSource(), BackendExecutorContext.getInstance().getExecuteEngine(), new ProxyTableMetaDataConnectionManager(ruleRegistry.getBackendDataSource()), PROXY_CONTEXT.getMaxConnectionsSizePerQuery()); ruleRegistry.getMetaData().getTable().put(logicTableName, tableMetaDataLoader.load(logicTableName, ruleRegistry.getShardingRule())); } @@ -127,7 +126,7 @@ private CommandResponsePackets merge(final SQLStatement sqlStatement) throws SQL if (mergedResult instanceof ShowDatabasesMergedResult) { mergedResult = new ShowDatabasesMergedResult(PROXY_CONTEXT.getSchemaNames()); } else if (mergedResult instanceof ShowTablesMergedResult) { - ((ShowTablesMergedResult) mergedResult).resetColumnLabel(currentSchema); + ((ShowTablesMergedResult) mergedResult).resetColumnLabel(ruleRegistry.getSchemaName()); setResponseColumnLabelForShowTablesMergedResult(((ExecuteQueryResponse) executeResponse).getQueryResponsePackets()); } QueryResponsePackets result = getQueryResponsePacketsWithoutDerivedColumns(((ExecuteQueryResponse) executeResponse).getQueryResponsePackets()); @@ -150,7 +149,7 @@ private QueryResponsePackets getQueryResponsePacketsWithoutDerivedColumns(final private void setResponseColumnLabelForShowTablesMergedResult(final QueryResponsePackets queryResponsePackets) { for (ColumnDefinition41Packet each : queryResponsePackets.getColumnDefinition41Packets()) { - each.setName("Tables_in_" + currentSchema); + each.setName("Tables_in_" + ruleRegistry.getSchemaName()); } } diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/connection/BackendConnection.java index 20d267cd3c664..95f8f8c8f4bc6 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/connection/BackendConnection.java @@ -29,7 +29,8 @@ import io.shardingsphere.core.routing.router.masterslave.MasterVisitedManager; import io.shardingsphere.proxy.config.RuleRegistry; import lombok.Getter; -import lombok.RequiredArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Setter; import java.sql.Connection; import java.sql.ResultSet; @@ -46,11 +47,12 @@ * @author zhaojun * @author zhangliang */ -@RequiredArgsConstructor +@NoArgsConstructor public final class BackendConnection implements AutoCloseable { @Getter - private final RuleRegistry ruleRegistry; + @Setter + private RuleRegistry ruleRegistry; private final Collection cachedConnections = new CopyOnWriteArrayList<>(); diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/config/ProxyContext.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/config/ProxyContext.java index 29786b86e84bf..2ec4ad47bc931 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/config/ProxyContext.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/config/ProxyContext.java @@ -17,6 +17,7 @@ package io.shardingsphere.proxy.config; +import com.google.common.base.Strings; import com.google.common.eventbus.Subscribe; import io.shardingsphere.core.constant.properties.ShardingProperties; import io.shardingsphere.core.constant.properties.ShardingPropertiesConstant; @@ -152,7 +153,7 @@ public boolean schemaExists(final String schema) { * @return rule registry of schema */ public RuleRegistry getRuleRegistry(final String schema) { - return ruleRegistryMap.get(schema); + return Strings.isNullOrEmpty(schema) ? null : ruleRegistryMap.get(schema); } /** diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/frontend/common/FrontendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/frontend/common/FrontendHandler.java index 5c20baf270ae0..d6b0b8dc03679 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/frontend/common/FrontendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/frontend/common/FrontendHandler.java @@ -21,7 +21,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.shardingsphere.proxy.backend.jdbc.connection.BackendConnection; -import io.shardingsphere.proxy.config.ProxyContext; import io.shardingsphere.proxy.frontend.common.executor.ChannelThreadExecutorGroup; import lombok.Getter; import lombok.Setter; @@ -55,9 +54,6 @@ public final void channelRead(final ChannelHandlerContext context, final Object if (!authorized) { auth(context, (ByteBuf) message); authorized = true; - if (null == currentSchema) { - currentSchema = ProxyContext.getInstance().getDefaultSchema(); - } } else { executeCommand(context, (ByteBuf) message); } diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/frontend/mysql/MySQLFrontendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/frontend/mysql/MySQLFrontendHandler.java index 98ce7efdcae23..3ce492acafd66 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/frontend/mysql/MySQLFrontendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/frontend/mysql/MySQLFrontendHandler.java @@ -116,7 +116,7 @@ class CommandExecutor implements Runnable { public void run() { ShardingEventBusInstance.getInstance().post(new RootInvokeEvent()); try (MySQLPacketPayload payload = new MySQLPacketPayload(message); - BackendConnection backendConnection = new BackendConnection(ProxyContext.getInstance().getRuleRegistry(frontendHandler.getCurrentSchema()))) { + BackendConnection backendConnection = new BackendConnection()) { setBackendConnection(backendConnection); CommandPacket commandPacket = getCommandPacket(payload, backendConnection, frontendHandler); Optional responsePackets = commandPacket.execute(); From b8537e210c70f4886771d1cce3bfaea671902a8f Mon Sep 17 00:00:00 2001 From: beckhampu Date: Sat, 22 Sep 2018 21:18:06 +0800 Subject: [PATCH 4/6] support rewrite sql to replace schema for master slave rule --- .../core/parsing/SQLJudgeEngine.java | 3 +- .../core/rewrite/SQLBuilder.java | 20 ++++ .../proxy/backend/BackendHandlerFactory.java | 2 +- .../PreparedStatementExecutorWrapper.java | 6 +- .../wrapper/StatementExecutorWrapper.java | 6 +- .../rewrite/MasterSlaveSQLRewriteEngine.java | 110 ++++++++++++++++++ 6 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 sharding-proxy/src/main/java/io/shardingsphere/proxy/rewrite/MasterSlaveSQLRewriteEngine.java diff --git a/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java b/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java index dd5cb5cc6f7fd..4dad01a143ae6 100755 --- a/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/parsing/SQLJudgeEngine.java @@ -159,9 +159,8 @@ private SQLStatement getShowStatement(final LexerEngine lexerEngine) { private DALStatement parseShowTables(final LexerEngine lexerEngine) { DALStatement result = new ShowTablesStatement(); - if (lexerEngine.equalAny(DefaultKeyword.FROM, DefaultKeyword.IN)) { + if (lexerEngine.skipIfEqual(DefaultKeyword.FROM, DefaultKeyword.IN)) { int beginPosition = lexerEngine.getCurrentToken().getEndPosition() - lexerEngine.getCurrentToken().getLiterals().length(); - lexerEngine.nextToken(); result.getSqlTokens().add(new SchemaToken(beginPosition, lexerEngine.getCurrentToken().getLiterals(), null)); } return result; diff --git a/sharding-core/src/main/java/io/shardingsphere/core/rewrite/SQLBuilder.java b/sharding-core/src/main/java/io/shardingsphere/core/rewrite/SQLBuilder.java index a2c24c05bb92b..ffa76147cd5fc 100644 --- a/sharding-core/src/main/java/io/shardingsphere/core/rewrite/SQLBuilder.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/rewrite/SQLBuilder.java @@ -29,6 +29,7 @@ import io.shardingsphere.core.routing.SQLUnit; import io.shardingsphere.core.routing.type.TableUnit; import io.shardingsphere.core.rule.DataNode; +import io.shardingsphere.core.rule.MasterSlaveRule; import io.shardingsphere.core.rule.ShardingRule; import java.util.ArrayList; @@ -118,6 +119,25 @@ public SQLUnit toSQL(final TableUnit tableUnit, final Map logicA return new SQLUnit(result.toString(), parameterSets); } + /** + * Convert to sql for master slave rule. + * + * @param masterSlaveRule master slave rule + * @param shardingDataSourceMetaData sharding data source meta data + * @return SQL + */ + public String toSQL(final MasterSlaveRule masterSlaveRule, final ShardingDataSourceMetaData shardingDataSourceMetaData) { + StringBuilder result = new StringBuilder(); + for (Object each : segments) { + if (each instanceof SchemaPlaceholder) { + result.append(shardingDataSourceMetaData.getActualDataSourceMetaData(masterSlaveRule.getMasterDataSourceName()).getSchemeName()); + } else { + result.append(each); + } + } + return result.toString(); + } + private void appendTablePlaceholder(final TablePlaceholder tablePlaceholder, final String actualTableName, final StringBuilder stringBuilder) { final String logicTableName = tablePlaceholder.getLogicTableName(); final String originalLiterals = tablePlaceholder.getOriginalLiterals(); diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/BackendHandlerFactory.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/BackendHandlerFactory.java index 23680f586f292..85eced6ec6721 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/BackendHandlerFactory.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/BackendHandlerFactory.java @@ -122,7 +122,7 @@ private static String getSchemaBySql(final String sql) { || sqlStatement instanceof ShowIndexStatement || sqlStatement instanceof ShowTableStatusStatement)) { LinkedList sqlTokens = new LinkedList<>(); sqlTokens.addAll(sqlStatement.getSqlTokens()); - schema = ((SchemaToken) sqlTokens.getLast()).getOriginalLiterals(); + schema = ((SchemaToken) sqlTokens.getLast()).getSchemaName(); } if (sqlStatement instanceof ShowDatabasesStatement || sqlStatement instanceof ShowOtherStatement || sqlStatement instanceof UseStatement) { diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/wrapper/PreparedStatementExecutorWrapper.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/wrapper/PreparedStatementExecutorWrapper.java index 09c8904e635f8..2767362723a4c 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/wrapper/PreparedStatementExecutorWrapper.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/wrapper/PreparedStatementExecutorWrapper.java @@ -27,6 +27,7 @@ import io.shardingsphere.core.routing.router.masterslave.MasterSlaveRouter; import io.shardingsphere.proxy.config.ProxyContext; import io.shardingsphere.proxy.config.RuleRegistry; +import io.shardingsphere.proxy.rewrite.MasterSlaveSQLRewriteEngine; import lombok.RequiredArgsConstructor; import java.sql.Connection; @@ -57,9 +58,10 @@ public SQLRouteResult route(final String sql, final DatabaseType databaseType) { private SQLRouteResult doMasterSlaveRoute(final String sql) { SQLStatement sqlStatement = new SQLJudgeEngine(sql).judge(); + String reWriteSql = new MasterSlaveSQLRewriteEngine(ruleRegistry.getMasterSlaveRule(), sql, sqlStatement, ruleRegistry.getMetaData()).rewrite(); SQLRouteResult result = new SQLRouteResult(sqlStatement); - for (String each : new MasterSlaveRouter(ruleRegistry.getMasterSlaveRule(), PROXY_CONTEXT.isShowSQL()).route(sql)) { - result.getRouteUnits().add(new RouteUnit(each, new SQLUnit(sql, Collections.>emptyList()))); + for (String each : new MasterSlaveRouter(ruleRegistry.getMasterSlaveRule(), PROXY_CONTEXT.isShowSQL()).route(reWriteSql)) { + result.getRouteUnits().add(new RouteUnit(each, new SQLUnit(reWriteSql, Collections.>emptyList()))); } return result; } diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/wrapper/StatementExecutorWrapper.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/wrapper/StatementExecutorWrapper.java index a102af9a35972..279b8dfc48b36 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/wrapper/StatementExecutorWrapper.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/jdbc/wrapper/StatementExecutorWrapper.java @@ -27,6 +27,7 @@ import io.shardingsphere.core.routing.router.masterslave.MasterSlaveRouter; import io.shardingsphere.proxy.config.ProxyContext; import io.shardingsphere.proxy.config.RuleRegistry; +import io.shardingsphere.proxy.rewrite.MasterSlaveSQLRewriteEngine; import lombok.RequiredArgsConstructor; import java.sql.Connection; @@ -54,9 +55,10 @@ public SQLRouteResult route(final String sql, final DatabaseType databaseType) { private SQLRouteResult doMasterSlaveRoute(final String sql) { SQLStatement sqlStatement = new SQLJudgeEngine(sql).judge(); + String reWriteSql = new MasterSlaveSQLRewriteEngine(ruleRegistry.getMasterSlaveRule(), sql, sqlStatement, ruleRegistry.getMetaData()).rewrite(); SQLRouteResult result = new SQLRouteResult(sqlStatement); - for (String each : new MasterSlaveRouter(ruleRegistry.getMasterSlaveRule(), PROXY_CONTEXT.isShowSQL()).route(sql)) { - result.getRouteUnits().add(new RouteUnit(each, new SQLUnit(sql, Collections.>emptyList()))); + for (String each : new MasterSlaveRouter(ruleRegistry.getMasterSlaveRule(), PROXY_CONTEXT.isShowSQL()).route(reWriteSql)) { + result.getRouteUnits().add(new RouteUnit(each, new SQLUnit(reWriteSql, Collections.>emptyList()))); } return result; } diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/rewrite/MasterSlaveSQLRewriteEngine.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/rewrite/MasterSlaveSQLRewriteEngine.java new file mode 100644 index 0000000000000..8283105afc0f1 --- /dev/null +++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/rewrite/MasterSlaveSQLRewriteEngine.java @@ -0,0 +1,110 @@ +/* + * Copyright 2016-2018 shardingsphere.io. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *

+ */ + +package io.shardingsphere.proxy.rewrite; + +import io.shardingsphere.core.metadata.ShardingMetaData; +import io.shardingsphere.core.parsing.parser.sql.SQLStatement; +import io.shardingsphere.core.parsing.parser.token.SQLToken; +import io.shardingsphere.core.parsing.parser.token.SchemaToken; +import io.shardingsphere.core.rewrite.SQLBuilder; +import io.shardingsphere.core.rewrite.placeholder.SchemaPlaceholder; +import io.shardingsphere.core.rule.MasterSlaveRule; + +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; + +/** + * SQL rewrite engine for master slave rule. + * + *

should rewrite schema name.

+ * + * @author chenqingyang + */ +public final class MasterSlaveSQLRewriteEngine { + + private final MasterSlaveRule masterSlaveRule; + + private final String originalSQL; + + private final List sqlTokens = new LinkedList<>(); + + private final SQLStatement sqlStatement; + + private final ShardingMetaData metaData; + + /** + * Constructs master slave SQL rewrite engine. + * + * @param masterSlaveRule master slave rule + * @param originalSQL original SQL + * @param sqlStatement sql statement + * @param metaData meta data + */ + public MasterSlaveSQLRewriteEngine(final MasterSlaveRule masterSlaveRule, final String originalSQL, + final SQLStatement sqlStatement, final ShardingMetaData metaData) { + this.masterSlaveRule = masterSlaveRule; + this.originalSQL = originalSQL; + this.sqlStatement = sqlStatement; + this.metaData = metaData; + sqlTokens.addAll(sqlStatement.getSqlTokens()); + } + + /** + * Rewrite SQL. + * + * @return SQL + */ + public String rewrite() { + if (sqlStatement.getSqlTokens().isEmpty()) { + return originalSQL; + } + SQLBuilder result = new SQLBuilder(null); + int count = 0; + sortByBeginPosition(); + for (SQLToken each : sqlStatement.getSqlTokens()) { + if (0 == count) { + result.appendLiterals(originalSQL.substring(0, each.getBeginPosition())); + } + if (each instanceof SchemaToken) { + appendSchemaPlaceholder(originalSQL, result, (SchemaToken) each, count, sqlStatement.getSqlTokens()); + } + count++; + } + return result.toSQL(masterSlaveRule, metaData.getDataSource()); + } + + private void appendSchemaPlaceholder(final String sql, final SQLBuilder sqlBuilder, final SchemaToken schemaToken, final int count, final List sqlTokens) { + sqlBuilder.appendPlaceholder(new SchemaPlaceholder(schemaToken.getSchemaName().toLowerCase(), null)); + int beginPosition = schemaToken.getBeginPosition() + schemaToken.getOriginalLiterals().length(); + int endPosition = sqlTokens.size() - 1 == count ? sql.length() : sqlTokens.get(count + 1).getBeginPosition(); + sqlBuilder.appendLiterals(sql.substring(beginPosition, endPosition)); + } + + private void sortByBeginPosition() { + Collections.sort(sqlTokens, new Comparator() { + + @Override + public int compare(final SQLToken o1, final SQLToken o2) { + return o1.getBeginPosition() - o2.getBeginPosition(); + } + }); + } + +} From ffdb571143ba83b201296c662d86c623e54b654c Mon Sep 17 00:00:00 2001 From: beckhampu Date: Sun, 23 Sep 2018 16:42:50 +0800 Subject: [PATCH 5/6] support db_name on SHOW TABLE STATUS syntax --- .../core/merger/dal/DALMergeEngine.java | 5 ++ .../dal/show/ShowIndexMergedResult.java | 57 +++++++++++++++++++ .../clause/TableReferencesClauseParser.java | 1 + .../dialect/mysql/sql/MySQLShowParser.java | 20 ++++++- .../core/rewrite/SQLRewriteEngine.java | 3 + 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 sharding-core/src/main/java/io/shardingsphere/core/merger/dal/show/ShowIndexMergedResult.java diff --git a/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/DALMergeEngine.java b/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/DALMergeEngine.java index 1f778f74af949..4cc0737350615 100644 --- a/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/DALMergeEngine.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/DALMergeEngine.java @@ -22,12 +22,14 @@ import io.shardingsphere.core.merger.QueryResult; import io.shardingsphere.core.merger.dal.show.ShowCreateTableMergedResult; import io.shardingsphere.core.merger.dal.show.ShowDatabasesMergedResult; +import io.shardingsphere.core.merger.dal.show.ShowIndexMergedResult; import io.shardingsphere.core.merger.dal.show.ShowOtherMergedResult; import io.shardingsphere.core.merger.dal.show.ShowTableStatusMergedResult; import io.shardingsphere.core.merger.dal.show.ShowTablesMergedResult; import io.shardingsphere.core.metadata.table.ShardingTableMetaData; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowCreateTableStatement; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowDatabasesStatement; +import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowIndexStatement; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowTableStatusStatement; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowTablesStatement; import io.shardingsphere.core.parsing.parser.sql.dal.DALStatement; @@ -68,6 +70,9 @@ public MergedResult merge() throws SQLException { if (dalStatement instanceof ShowCreateTableStatement) { return new ShowCreateTableMergedResult(shardingRule, queryResults, shardingTableMetaData); } + if (dalStatement instanceof ShowIndexStatement) { + return new ShowIndexMergedResult(shardingRule, queryResults, shardingTableMetaData); + } return new ShowOtherMergedResult(queryResults.get(0)); } } diff --git a/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/show/ShowIndexMergedResult.java b/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/show/ShowIndexMergedResult.java new file mode 100644 index 0000000000000..bc856fb7106bf --- /dev/null +++ b/sharding-core/src/main/java/io/shardingsphere/core/merger/dal/show/ShowIndexMergedResult.java @@ -0,0 +1,57 @@ +/* + * Copyright 2016-2018 shardingsphere.io. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *

+ */ + +package io.shardingsphere.core.merger.dal.show; + +import io.shardingsphere.core.merger.QueryResult; +import io.shardingsphere.core.metadata.table.ShardingTableMetaData; +import io.shardingsphere.core.rule.ShardingRule; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Merged result for show index. + * + * @author chenqingyang + */ +public final class ShowIndexMergedResult extends LogicTablesMergedResult { + + private static final Map LABEL_AND_INDEX_MAP = new HashMap<>(13, 1); + + static { + LABEL_AND_INDEX_MAP.put("Table", 1); + LABEL_AND_INDEX_MAP.put("Non_unique", 2); + LABEL_AND_INDEX_MAP.put("Key_name", 3); + LABEL_AND_INDEX_MAP.put("Seq_in_index", 4); + LABEL_AND_INDEX_MAP.put("Column_name", 5); + LABEL_AND_INDEX_MAP.put("Collation", 6); + LABEL_AND_INDEX_MAP.put("Cardinality", 7); + LABEL_AND_INDEX_MAP.put("Sub_part", 8); + LABEL_AND_INDEX_MAP.put("Packed", 9); + LABEL_AND_INDEX_MAP.put("Null", 10); + LABEL_AND_INDEX_MAP.put("Index_type", 11); + LABEL_AND_INDEX_MAP.put("Comment", 12); + LABEL_AND_INDEX_MAP.put("Index_comment", 13); + } + + public ShowIndexMergedResult(final ShardingRule shardingRule, final List queryResults, final ShardingTableMetaData shardingTableMetaData) throws SQLException { + super(LABEL_AND_INDEX_MAP, shardingRule, queryResults, shardingTableMetaData); + } +} diff --git a/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/clause/TableReferencesClauseParser.java b/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/clause/TableReferencesClauseParser.java index 8efe991ac6c12..39b7bf459c415 100644 --- a/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/clause/TableReferencesClauseParser.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/clause/TableReferencesClauseParser.java @@ -95,6 +95,7 @@ protected final void parseTableFactor(final SQLStatement sqlStatement, final boo if (lexerEngine.skipIfEqual(Symbol.DOT)) { skippedSchemaNameLength = literals.length() + Symbol.DOT.getLiterals().length(); literals = lexerEngine.getCurrentToken().getLiterals(); + lexerEngine.nextToken(); } String tableName = SQLUtil.getExactlyValue(literals); if (Strings.isNullOrEmpty(tableName)) { diff --git a/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/dialect/mysql/sql/MySQLShowParser.java b/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/dialect/mysql/sql/MySQLShowParser.java index 35a820556e726..391a578e0b5bc 100644 --- a/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/dialect/mysql/sql/MySQLShowParser.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/parsing/parser/dialect/mysql/sql/MySQLShowParser.java @@ -17,10 +17,12 @@ package io.shardingsphere.core.parsing.parser.dialect.mysql.sql; +import com.google.common.base.Optional; import io.shardingsphere.core.parsing.lexer.LexerEngine; import io.shardingsphere.core.parsing.lexer.dialect.mysql.MySQLKeyword; import io.shardingsphere.core.parsing.lexer.token.DefaultKeyword; import io.shardingsphere.core.parsing.parser.clause.TableReferencesClauseParser; +import io.shardingsphere.core.parsing.parser.context.table.Table; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowColumnsStatement; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowCreateTableStatement; import io.shardingsphere.core.parsing.parser.dialect.mysql.statement.ShowDatabasesStatement; @@ -32,7 +34,9 @@ import io.shardingsphere.core.parsing.parser.sql.dal.show.AbstractShowParser; import io.shardingsphere.core.parsing.parser.token.RemoveToken; import io.shardingsphere.core.parsing.parser.token.SchemaToken; +import io.shardingsphere.core.parsing.parser.token.TableToken; import io.shardingsphere.core.rule.ShardingRule; +import io.shardingsphere.core.util.SQLUtil; import lombok.RequiredArgsConstructor; /** @@ -82,7 +86,21 @@ private DALStatement showDatabases() { } private DALStatement parseShowTableStatus() { - return new ShowTableStatusStatement(); + DALStatement result = new ShowTableStatusStatement(); + lexerEngine.nextToken(); + if (lexerEngine.equalAny(DefaultKeyword.FROM, DefaultKeyword.IN)) { + int beginPosition = lexerEngine.getCurrentToken().getEndPosition() - lexerEngine.getCurrentToken().getLiterals().length(); + lexerEngine.nextToken(); + result.getSqlTokens().add(new RemoveToken(beginPosition, lexerEngine.getCurrentToken().getEndPosition())); + } + lexerEngine.nextToken(); + if (lexerEngine.skipIfEqual(DefaultKeyword.LIKE)) { + int beginPosition = lexerEngine.getCurrentToken().getEndPosition() - lexerEngine.getCurrentToken().getLiterals().length() - 1; + String literals = lexerEngine.getCurrentToken().getLiterals(); + result.getSqlTokens().add(new TableToken(beginPosition, 0, literals)); + result.getTables().add(new Table(SQLUtil.getExactlyValue(literals), Optional.absent())); + } + return result; } private DALStatement parseShowTables() { diff --git a/sharding-core/src/main/java/io/shardingsphere/core/rewrite/SQLRewriteEngine.java b/sharding-core/src/main/java/io/shardingsphere/core/rewrite/SQLRewriteEngine.java index 140faaa2efaf0..79900f957a629 100644 --- a/sharding-core/src/main/java/io/shardingsphere/core/rewrite/SQLRewriteEngine.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/rewrite/SQLRewriteEngine.java @@ -33,6 +33,7 @@ import io.shardingsphere.core.parsing.parser.token.ItemsToken; import io.shardingsphere.core.parsing.parser.token.OffsetToken; import io.shardingsphere.core.parsing.parser.token.OrderByToken; +import io.shardingsphere.core.parsing.parser.token.RemoveToken; import io.shardingsphere.core.parsing.parser.token.RowCountToken; import io.shardingsphere.core.parsing.parser.token.SQLToken; import io.shardingsphere.core.parsing.parser.token.SchemaToken; @@ -138,6 +139,8 @@ public SQLBuilder rewrite(final boolean isRewriteLimit) { appendOrderByToken(result, count, sqlTokens); } else if (each instanceof InsertColumnToken) { appendSymbolToken(result, (InsertColumnToken) each, count, sqlTokens); + } else if (each instanceof RemoveToken) { + appendRest(result, count, sqlTokens, ((RemoveToken) each).getEndPosition()); } count++; } From 8579546b46aa9d7c8baef49fbe6a6c9684a2827d Mon Sep 17 00:00:00 2001 From: beckhampu Date: Sun, 23 Sep 2018 17:50:48 +0800 Subject: [PATCH 6/6] fix test case --- .../mysql/packet/command/CommandPacketFactoryTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/proxy/transport/mysql/packet/command/CommandPacketFactoryTest.java b/sharding-proxy/src/test/java/io/shardingsphere/proxy/transport/mysql/packet/command/CommandPacketFactoryTest.java index 22c40def664fd..d0660f444c688 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/proxy/transport/mysql/packet/command/CommandPacketFactoryTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/proxy/transport/mysql/packet/command/CommandPacketFactoryTest.java @@ -105,6 +105,7 @@ public void assertNewInstanceWithComFieldListPacket() throws SQLException { @Test public void assertNewInstanceWithComQueryPacket() throws SQLException { when(payload.readInt1()).thenReturn(CommandPacketType.COM_QUERY.getValue()); + when(payload.readStringEOF()).thenReturn("show tables"); assertThat(CommandPacketFactory.newInstance(1, 1000, payload, backendConnection, frontendHandler), instanceOf(ComQueryPacket.class)); } @@ -119,7 +120,7 @@ public void assertNewInstanceWithComStmtPreparePacket() throws SQLException { public void assertNewInstanceWithComStmtExecutePacket() throws SQLException { when(payload.readInt1()).thenReturn(CommandPacketType.COM_STMT_EXECUTE.getValue(), NewParametersBoundFlag.PARAMETER_TYPE_EXIST.getValue()); when(payload.readInt4()).thenReturn(1); - BinaryStatementRegistry.getInstance().register("", 1); + BinaryStatementRegistry.getInstance().register("select * from t_order", 1); assertThat(CommandPacketFactory.newInstance(1, 1000, payload, backendConnection, frontendHandler), instanceOf(ComStmtExecutePacket.class)); }