diff --git a/extensions/open-mysql-db/src/main/java/cn/paxos/mysql/MySqlListener.java b/extensions/open-mysql-db/src/main/java/cn/paxos/mysql/MySqlListener.java index 700c1c38abd..a775a3ac78f 100644 --- a/extensions/open-mysql-db/src/main/java/cn/paxos/mysql/MySqlListener.java +++ b/extensions/open-mysql-db/src/main/java/cn/paxos/mysql/MySqlListener.java @@ -41,18 +41,21 @@ public class MySqlListener implements AutoCloseable { public static final String VERSION = "8.0.29"; public static final String VERSION_COMMENT = ""; + public static final String CHARACTER_SET_UTF8MB4 = "utf8mb4"; + public static final String COLLATION_UTF8MB4_0900_AI_CI = "utf8mb4_0900_ai_ci"; + public static final String SETTINGS_LOWER_CASE_TABLE_NAMES = "2"; + public static final String SETTINGS_INTERACTIVE_TIMEOUT = "28800"; + public static final String SETTINGS_WAIT_TIMEOUT = "28800"; private static final Pattern SETTINGS_PATTERN = Pattern.compile("@@([\\w.]+)(?:\\sAS\\s)?(\\w+)?"); private static final Pattern USE_DB_PATTERN = Pattern.compile("(?i)use (.+)"); private final SqlEngine sqlEngine; - private final int port; private final Channel channel; private final io.netty.channel.EventLoopGroup parentGroup; private final EventLoopGroup childGroup; private final EventExecutorGroup eventExecutorGroup; public MySqlListener(int port, int executorGroupSize, SqlEngine sqlEngine) { - this.port = port; this.sqlEngine = sqlEngine; parentGroup = new NioEventLoopGroup(); @@ -87,7 +90,7 @@ public MySqlListener(int port, int executorGroupSize, SqlEngine sqlEngine) { .childHandler( new ChannelInitializer() { @Override - protected void initChannel(NioSocketChannel ch) throws Exception { + protected void initChannel(NioSocketChannel ch) { System.out.println("[mysql-protocol] Initializing child channel"); final ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new MysqlServerPacketEncoder()); @@ -160,14 +163,21 @@ private void handleHandshakeResponse( Throwable cause = e.getCause(); int errorCode; byte[] sqlState; - String errMsg = - Utils.getLocalDateTimeNow() - + " " - + Objects.requireNonNullElse(cause.getMessage(), e.getMessage()); - if (cause instanceof IllegalAccessException) { - errorCode = 1045; - sqlState = "#28000".getBytes(StandardCharsets.US_ASCII); + String errMsg; + if (cause != null) { + errMsg = + Utils.getLocalDateTimeNow() + + " " + + Objects.requireNonNullElse(cause.getMessage(), e.getMessage()); + if (cause instanceof IllegalAccessException) { + errorCode = 1045; + sqlState = "#28000".getBytes(StandardCharsets.US_ASCII); + } else { + errorCode = 1105; + sqlState = "#HY000".getBytes(StandardCharsets.US_ASCII); + } } else { + errMsg = Utils.getLocalDateTimeNow() + " " + Objects.requireNonNullElse(e.getMessage(), ""); errorCode = 1105; sqlState = "#HY000".getBytes(StandardCharsets.US_ASCII); } @@ -197,17 +207,14 @@ private void handleQuery( + userName + ", scramble411: " + scramble411.length); - Matcher useDbMatcher = - USE_DB_PATTERN.matcher(queryString.replaceAll("/\\*.*\\*/", "").toLowerCase().trim()); + String queryStringWithoutComment = + queryString.replaceAll("/\\*.*\\*/", "").toLowerCase().trim(); + Matcher useDbMatcher = USE_DB_PATTERN.matcher(queryStringWithoutComment); if (isServerSettingsQuery(queryString)) { sendSettingsResponse(ctx, query, remoteAddr); - } else if (queryString.replaceAll("/\\*.*\\*/", "").toLowerCase().trim().startsWith("set ") - && !queryString - .replaceAll("/\\*.*\\*/", "") - .toLowerCase() - .trim() - .startsWith("set @@execute_mode=")) { + } else if (queryStringWithoutComment.startsWith("set ") + && !queryStringWithoutComment.startsWith("set @@execute_mode=")) { // ignore SET command ctx.writeAndFlush(OkResponse.builder().sequenceId(query.getSequenceId() + 1).build()); } else if (useDbMatcher.matches()) { @@ -218,12 +225,9 @@ private void handleQuery( } else { // Generic response int[] sequenceId = new int[] {query.getSequenceId()}; - boolean[] columnsWritten = new boolean[1]; - ResultSetWriter resultSetWriter = new ResultSetWriter() { - @Override public void writeColumns(List columns) { ctx.write(new ColumnCount(++sequenceId[0], columns.size())); @@ -272,9 +276,7 @@ public void writeColumns(List columns) { .build()); } ctx.write(new EofResponse(++sequenceId[0], 0)); - System.out.println("[mysql-protocol] Columns done"); - columnsWritten[0] = !columns.isEmpty(); } @@ -290,7 +292,6 @@ public void writeRow(List row) { @Override public void finish() { ctx.writeAndFlush(new EofResponse(++sequenceId[0], 0)); - System.out.println("[mysql-protocol] All done"); } }; @@ -311,22 +312,29 @@ public void finish() { Throwable cause = e.getCause(); int errorCode; byte[] sqlState; - String errMsg = - Utils.getLocalDateTimeNow() - + " " - + Objects.requireNonNullElse(cause.getMessage(), e.getMessage()); - if (cause instanceof IllegalAccessException) { - errorCode = 1045; - sqlState = "#28000".getBytes(StandardCharsets.US_ASCII); - } else if (cause instanceof IllegalArgumentException) { - errorCode = 1064; - sqlState = "#42000".getBytes(StandardCharsets.US_ASCII); - } else if (e.getMessage() - .equalsIgnoreCase( - "java.sql.SQLException: executeSQL fail: [2000] please enter database first")) { - errorCode = 1046; - sqlState = "#3D000".getBytes(StandardCharsets.US_ASCII); + String errMsg; + if (cause != null) { + errMsg = + Utils.getLocalDateTimeNow() + + " " + + Objects.requireNonNullElse(cause.getMessage(), e.getMessage()); + if (cause instanceof IllegalAccessException) { + errorCode = 1045; + sqlState = "#28000".getBytes(StandardCharsets.US_ASCII); + } else if (cause instanceof IllegalArgumentException) { + errorCode = 1064; + sqlState = "#42000".getBytes(StandardCharsets.US_ASCII); + } else if (e.getMessage() + .equalsIgnoreCase( + "java.sql.SQLException: executeSQL fail: [2000] please enter database first")) { + errorCode = 1046; + sqlState = "#3D000".getBytes(StandardCharsets.US_ASCII); + } else { + errorCode = 1105; + sqlState = "#HY000".getBytes(StandardCharsets.US_ASCII); + } } else { + errMsg = Utils.getLocalDateTimeNow() + " " + e.getMessage(); errorCode = 1105; sqlState = "#HY000".getBytes(StandardCharsets.US_ASCII); } @@ -435,16 +443,18 @@ private void sendSettingsResponse( columnDefinitions.add( newColumnDefinition( ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_VAR_STRING, 12)); - values.add("utf8mb4"); + values.add(CHARACTER_SET_UTF8MB4); break; case "collation_server": case "GLOBAL.collation_server": + case "collation_connection": columnDefinitions.add( newColumnDefinition( ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_VAR_STRING, 63)); - values.add("utf8mb4_0900_ai_ci"); + values.add(COLLATION_UTF8MB4_0900_AI_CI); break; case "init_connect": + case "language": columnDefinitions.add( newColumnDefinition( ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_VAR_STRING, 0)); @@ -454,13 +464,7 @@ private void sendSettingsResponse( columnDefinitions.add( newColumnDefinition( ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_VAR_STRING, 21)); - values.add("28800"); - break; - case "language": - columnDefinitions.add( - newColumnDefinition( - ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_VAR_STRING, 0)); - values.add(""); + values.add(SETTINGS_INTERACTIVE_TIMEOUT); break; case "license": columnDefinitions.add( @@ -472,7 +476,7 @@ private void sendSettingsResponse( columnDefinitions.add( newColumnDefinition( ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_LONGLONG, 63)); - values.add("2"); + values.add(SETTINGS_LOWER_CASE_TABLE_NAMES); break; case "max_allowed_packet": case "global.max_allowed_packet": @@ -528,7 +532,7 @@ private void sendSettingsResponse( columnDefinitions.add( newColumnDefinition( ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_LONGLONG, 12)); - values.add("28800"); + values.add(SETTINGS_WAIT_TIMEOUT); break; case "query_cache_type": columnDefinitions.add( @@ -542,12 +546,6 @@ private void sendSettingsResponse( ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_VAR_STRING, 0)); values.add(VERSION_COMMENT); break; - case "collation_connection": - columnDefinitions.add( - newColumnDefinition( - ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_VAR_STRING, 63)); - values.add("utf8mb4_0900_ai_ci"); - break; case "query_cache_size": columnDefinitions.add( newColumnDefinition( @@ -578,14 +576,12 @@ private void sendSettingsResponse( newColumnDefinition( ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_VAR_STRING, 63)); values.add("REPEATABLE-READ"); - // values.add("READ-UNCOMMITTED"); break; case "session.transaction_read_only": columnDefinitions.add( newColumnDefinition( ++sequenceId, fieldName, systemVariable, ColumnType.MYSQL_TYPE_TINY, 1)); values.add("0"); - // values.add("READ-UNCOMMITTED"); break; default: System.err.println("[mysql-protocol] Unknown system variable: " + systemVariable); @@ -632,7 +628,7 @@ public ServerHandler() { } @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { + public void channelActive(ChannelHandlerContext ctx) { // todo may java.lang.NullPointerException this.remoteAddr = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress(); @@ -650,7 +646,7 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception { } @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { + public void channelInactive(ChannelHandlerContext ctx) { System.out.println("[mysql-protocol] Server channel inactive: " + new Date()); sqlEngine.close(getConnectionId(ctx)); } @@ -682,6 +678,8 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception } else if (command.equals(Command.COM_PING)) { ctx.writeAndFlush(OkResponse.builder().sequenceId(sequenceId + 1).build()); } else if (command.equals(Command.COM_FIELD_LIST)) { + // ToDo: + // https://dev.mysql.com/doc/dev/mysql-server/8.0.34/page_protocol_com_field_list.html ctx.writeAndFlush(new EofResponse(sequenceId + 1, 0)); } else if (command.equals(Command.COM_STATISTICS)) { String statString = @@ -696,10 +694,10 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception } @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); - ctx.close(); sqlEngine.close(getConnectionId(ctx)); + ctx.close(); } } } diff --git a/extensions/open-mysql-db/src/main/java/cn/paxos/mysql/engine/SqlEngine.java b/extensions/open-mysql-db/src/main/java/cn/paxos/mysql/engine/SqlEngine.java index e1c48f6b8c6..a971c4add4a 100644 --- a/extensions/open-mysql-db/src/main/java/cn/paxos/mysql/engine/SqlEngine.java +++ b/extensions/open-mysql-db/src/main/java/cn/paxos/mysql/engine/SqlEngine.java @@ -21,11 +21,22 @@ /** An interface to callback events received from the MySQL server. */ public interface SqlEngine { + /** + * Execute query use database + * + * @param connectionId Connection id + * @param database Database name + * @throws IOException Thrown with SQLTimeoutException as the inner cause if when the driver has + * determined that the timeout value that was specified by the setQueryTimeout method has been + * exceeded and has at least attempted to cancel the currently running Statement, or + * SQLException as the inner cause if a database access error occurs. + */ void useDatabase(int connectionId, String database) throws IOException; /** * Authenticating the user and password. * + * @param connectionId Connection id * @param database Database name * @param userName User name * @param scramble411 Encoded password @@ -40,6 +51,7 @@ void authenticate( /** * Querying the SQL. * + * @param connectionId Connection id * @param resultSetWriter Response writer * @param database Database name * @param userName User name @@ -59,5 +71,10 @@ void query( String sql) throws IOException; - void close(int connectionId) throws IOException; + /** + * Close resources of connection + * + * @param connectionId Connection id + */ + void close(int connectionId); } diff --git a/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/mock/MockResult.java b/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/mock/MockResult.java index f62b4f62d89..ab51b6694e6 100644 --- a/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/mock/MockResult.java +++ b/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/mock/MockResult.java @@ -9,13 +9,15 @@ import java.util.Map; public class MockResult { + public static final String DEFAULT_STORAGE_ENGINE = "InnoDB"; + public static final String VARIABLE_VALUE_SQL_MODE = + "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"; + public static final String VARIABLE_VALUE_SSL_CIPHER = "TLS_AES_256_GCM_SHA384"; public static Map, List>>> mockResults = new HashMap<>(); public static Map, List>>> mockPatternResults = new HashMap<>(); - public static Map mockVariables = new HashMap<>(); - public static Map mockSessionStatusVariables = new HashMap<>(); public static Map mockSessionVariablesVariables = new HashMap<>(); @@ -25,12 +27,13 @@ public class MockResult { List> rows; List row; - mockVariables.put("character_set_database", "utf8mb4"); - mockVariables.put("collation_database", "utf8mb4_0900_ai_ci"); - mockVariables.put("default_storage_engine", "InnoDB"); + mockVariables.put("character_set_database", MySqlListener.CHARACTER_SET_UTF8MB4); + mockVariables.put("collation_database", MySqlListener.COLLATION_UTF8MB4_0900_AI_CI); + mockVariables.put("default_storage_engine", DEFAULT_STORAGE_ENGINE); mockVariables.put("skip_show_database", "OFF"); mockVariables.put("version", MySqlListener.VERSION); mockVariables.put("version_comment", MySqlListener.VERSION_COMMENT); + mockVariables.put("lower_case_table_names", MySqlListener.SETTINGS_LOWER_CASE_TABLE_NAMES); for (String variable : MockResult.mockVariables.keySet()) { query = "show variables like '" + variable.toLowerCase() + "'"; columns = new ArrayList<>(); @@ -44,64 +47,58 @@ public class MockResult { mockResults.put(query, new Pair<>(columns, rows)); } + List characterSetUtf8mb4Columns = new ArrayList<>(); + characterSetUtf8mb4Columns.add(new QueryResultColumn("Charset", "VARCHAR(255)")); + characterSetUtf8mb4Columns.add(new QueryResultColumn("Description", "VARCHAR(255)")); + characterSetUtf8mb4Columns.add(new QueryResultColumn("Default collation", "VARCHAR(255)")); + characterSetUtf8mb4Columns.add(new QueryResultColumn("Maxlen", "VARCHAR(255)")); + + List> characterSetUtf8mb4Rows = new ArrayList<>(); + List characterSetUtf8mb4Row = new ArrayList<>(); + characterSetUtf8mb4Row.add(MySqlListener.CHARACTER_SET_UTF8MB4); + characterSetUtf8mb4Row.add("UTF-8 Unicode"); + characterSetUtf8mb4Row.add(MySqlListener.COLLATION_UTF8MB4_0900_AI_CI); + characterSetUtf8mb4Row.add("4"); + characterSetUtf8mb4Rows.add(characterSetUtf8mb4Row); + query = "show character set"; - columns = new ArrayList<>(); - columns.add(new QueryResultColumn("Charset", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Description", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Default collation", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Maxlen", "VARCHAR(255)")); - rows = new ArrayList<>(); - row = new ArrayList<>(); - row.add("utf8mb4"); - row.add("UTF-8 Unicode"); - row.add("utf8mb4_0900_ai_ci"); - row.add("4"); - rows.add(row); - mockResults.put(query, new Pair<>(columns, rows)); + mockResults.put(query, new Pair<>(characterSetUtf8mb4Columns, characterSetUtf8mb4Rows)); query = "show charset"; - columns = new ArrayList<>(); - columns.add(new QueryResultColumn("Charset", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Description", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Default collation", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Maxlen", "VARCHAR(255)")); - rows = new ArrayList<>(); - row = new ArrayList<>(); - row.add("utf8mb4"); - row.add("UTF-8 Unicode"); - row.add("utf8mb4_0900_ai_ci"); - row.add("4"); - rows.add(row); - mockResults.put(query, new Pair<>(columns, rows)); - - query = "show variables like 'lower_case_table_names'"; - // Variable_name Value - // lower_case_table_names 2 - columns = new ArrayList<>(); - columns.add(new QueryResultColumn("Variable_name", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Value", "VARCHAR(255)")); - rows = new ArrayList<>(); - row = new ArrayList<>(); - row.add("lower_case_table_names"); - row.add("2"); - rows.add(row); - mockResults.put(query, new Pair<>(columns, rows)); + mockResults.put(query, new Pair<>(characterSetUtf8mb4Columns, characterSetUtf8mb4Rows)); query = "show character set where charset = 'utf8mb4'"; + mockResults.put(query, new Pair<>(characterSetUtf8mb4Columns, characterSetUtf8mb4Rows)); + + query = "select * from `information_schema`.`character_sets` order by `character_set_name` asc"; columns = new ArrayList<>(); - columns.add(new QueryResultColumn("Charset", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Description", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Default collation", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Maxlen", "VARCHAR(255)")); + columns.add(new QueryResultColumn("CHARACTER_SET_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("DEFAULT_COLLATE_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("DESCRIPTION", "VARCHAR(255)")); + columns.add(new QueryResultColumn("MAXLEN", "VARCHAR(255)")); rows = new ArrayList<>(); + // # CHARACTER_SET_NAME, DEFAULT_COLLATE_NAME, DESCRIPTION, MAXLEN + // latin1, latin1_swedish_ci, cp1252 West European, 1 row = new ArrayList<>(); - row.add("utf8mb4"); - row.add("UTF-8 Unicode"); - row.add("utf8mb4_0900_ai_ci"); - row.add("4"); + row.add("latin1"); + row.add("latin1_swedish_ci"); + row.add("cp1252 West European"); + row.add("1"); rows.add(row); + // # CHARACTER_SET_NAME, DEFAULT_COLLATE_NAME, DESCRIPTION, MAXLEN + // utf8mb4, utf8mb4_0900_ai_ci, UTF-8 Unicode, 4 + rows.add(characterSetUtf8mb4Row); mockResults.put(query, new Pair<>(columns, rows)); + List collationUtf8mb4Row = new ArrayList<>(); + row.add(MySqlListener.COLLATION_UTF8MB4_0900_AI_CI); + row.add(MySqlListener.CHARACTER_SET_UTF8MB4); + row.add("255"); + row.add("Yes"); + row.add("Yes"); + row.add("0"); + row.add("NO PAD"); + query = "show collation"; // Collation Charset Id Default Compiled Sortlen Pad_attribute // utf8mb4_0900_ai_ci utf8mb4 255 Yes Yes 0 NO PAD @@ -114,17 +111,50 @@ public class MockResult { columns.add(new QueryResultColumn("Sortlen", "VARCHAR(255)")); columns.add(new QueryResultColumn("Pad_attribute", "VARCHAR(255)")); rows = new ArrayList<>(); + rows.add(collationUtf8mb4Row); + mockResults.put(query, new Pair<>(columns, rows)); + + query = + "select * from `information_schema`.`collations` where character_set_name = 'latin1' order by `collation_name` asc"; + columns = new ArrayList<>(); + columns.add(new QueryResultColumn("COLLATION_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("CHARACTER_SET_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("ID", "VARCHAR(255)")); + columns.add(new QueryResultColumn("IS_DEFAULT", "VARCHAR(255)")); + columns.add(new QueryResultColumn("IS_COMPILED", "VARCHAR(255)")); + columns.add(new QueryResultColumn("SORTLEN", "VARCHAR(255)")); + columns.add(new QueryResultColumn("PAD_ATTRIBUTE", "VARCHAR(255)")); + rows = new ArrayList<>(); + // # COLLATION_NAME, CHARACTER_SET_NAME, ID, IS_DEFAULT, IS_COMPILED, SORTLEN, PAD_ATTRIBUTE + // latin1_swedish_ci, latin1, 8, Yes, Yes, 1, PAD SPACE row = new ArrayList<>(); - row.add("utf8mb4_0900_ai_ci"); - row.add("utf8mb4"); - row.add("255"); + row.add("latin1_swedish_ci"); + row.add("latin1"); + row.add("8"); row.add("Yes"); row.add("Yes"); - row.add("0"); - row.add("NO PAD"); + row.add("1"); + row.add("PAD SPACE"); rows.add(row); mockResults.put(query, new Pair<>(columns, rows)); + // COLLATION_NAME, CHARACTER_SET_NAME, ID, IS_DEFAULT, IS_COMPILED, SORTLEN, PAD_ATTRIBUTE + query = + "select * from `information_schema`.`collations` where character_set_name = 'utf8mb4' order by `collation_name` asc"; + // # COLLATION_NAME, CHARACTER_SET_NAME, ID, IS_DEFAULT, IS_COMPILED, SORTLEN, PAD_ATTRIBUTE + // utf8mb4_0900_ai_ci, utf8mb4, 255, Yes, Yes, 0, NO PAD + columns = new ArrayList<>(); + columns.add(new QueryResultColumn("COLLATION_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("CHARACTER_SET_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("ID", "VARCHAR(255)")); + columns.add(new QueryResultColumn("IS_DEFAULT", "VARCHAR(255)")); + columns.add(new QueryResultColumn("IS_COMPILED", "VARCHAR(255)")); + columns.add(new QueryResultColumn("SORTLEN", "VARCHAR(255)")); + columns.add(new QueryResultColumn("PAD_ATTRIBUTE", "VARCHAR(255)")); + rows = new ArrayList<>(); + rows.add(collationUtf8mb4Row); + mockResults.put(query, new Pair<>(columns, rows)); + query = "show engines"; // Engine Support Comment Transactions XA Savepoints // InnoDB DEFAULT Supports transactions, row-level locking, and foreign keys YES YES YES @@ -137,7 +167,7 @@ public class MockResult { columns.add(new QueryResultColumn("Savepoints", "VARCHAR(255)")); rows = new ArrayList<>(); row = new ArrayList<>(); - row.add("InnoDB"); + row.add(DEFAULT_STORAGE_ENGINE); row.add("DEFAULT"); row.add("Supports transactions, row-level locking, and foreign keys"); row.add("YES"); @@ -153,6 +183,14 @@ public class MockResult { rows = new ArrayList<>(); mockResults.put(query, new Pair<>(columns, rows)); + query = "show status"; + // Variable_name Value + columns = new ArrayList<>(); + columns.add(new QueryResultColumn("Variable_name", "VARCHAR(255)")); + columns.add(new QueryResultColumn("Value", "VARCHAR(255)")); + rows = new ArrayList<>(); + mockResults.put(query, new Pair<>(columns, rows)); + query = "show variables like 'lower_case_%'; show variables like 'sql_mode'; select count(*) as support_ndb from information_schema.engines where engine = 'ndbcluster'"; columns = new ArrayList<>(); @@ -165,10 +203,8 @@ public class MockResult { rows.add(row); mockResults.put(query, new Pair<>(columns, rows)); - mockSessionStatusVariables.put( - "sql_mode", - "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"); - mockSessionStatusVariables.put("Ssl_cipher", "TLS_AES_256_GCM_SHA384"); + mockSessionStatusVariables.put("sql_mode", VARIABLE_VALUE_SQL_MODE); + mockSessionStatusVariables.put("Ssl_cipher", VARIABLE_VALUE_SSL_CIPHER); mockSessionStatusVariables.put("version_comment", MySqlListener.VERSION_COMMENT); mockSessionStatusVariables.put("version", MySqlListener.VERSION); for (String sessionVariable : MockResult.mockSessionStatusVariables.keySet()) { @@ -184,18 +220,18 @@ public class MockResult { mockResults.put(query, new Pair<>(columns, rows)); } - mockSessionVariablesVariables.put( - "sql_mode", - "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"); + mockSessionVariablesVariables.put("sql_mode", VARIABLE_VALUE_SQL_MODE); mockSessionVariablesVariables.put("version_comment", MySqlListener.VERSION_COMMENT); mockSessionVariablesVariables.put("version", MySqlListener.VERSION); // Variable_name Value // version_compile_os macos12 mockSessionVariablesVariables.put("version_compile_os", ""); mockSessionVariablesVariables.put("offline_mode", "OFF"); - mockSessionVariablesVariables.put("wait_timeout", "28800"); - mockSessionVariablesVariables.put("interactive_timeout", "28800"); - mockSessionVariablesVariables.put("lower_case_table_names", "2"); + mockSessionVariablesVariables.put("wait_timeout", MySqlListener.SETTINGS_WAIT_TIMEOUT); + mockSessionVariablesVariables.put( + "interactive_timeout", MySqlListener.SETTINGS_INTERACTIVE_TIMEOUT); + mockSessionVariablesVariables.put( + "lower_case_table_names", MySqlListener.SETTINGS_LOWER_CASE_TABLE_NAMES); for (String sessionVariable : MockResult.mockSessionVariablesVariables.keySet()) { query = "show session variables like '" + sessionVariable.toLowerCase() + "'"; columns = new ArrayList<>(); @@ -230,14 +266,6 @@ public class MockResult { rows.add(row); mockResults.put(query, new Pair<>(columns, rows)); - query = "show status"; - // Variable_name Value - columns = new ArrayList<>(); - columns.add(new QueryResultColumn("Variable_name", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Value", "VARCHAR(255)")); - rows = new ArrayList<>(); - mockResults.put(query, new Pair<>(columns, rows)); - query = "select query_id, sum(duration) as sum_duration from information_schema.profiling group by query_id"; // QUERY_ID SUM_DURATION @@ -312,7 +340,7 @@ public class MockResult { // row.add("YES"); // rows.add(row); row = new ArrayList<>(); - row.add("InnoDB"); + row.add(DEFAULT_STORAGE_ENGINE); row.add("DEFAULT"); rows.add(row); // row = new ArrayList<>(); @@ -325,80 +353,6 @@ public class MockResult { // rows.add(row); mockResults.put(query, new Pair<>(columns, rows)); - query = "select * from `information_schema`.`character_sets` order by `character_set_name` asc"; - columns = new ArrayList<>(); - columns.add(new QueryResultColumn("CHARACTER_SET_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("DEFAULT_COLLATE_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("DESCRIPTION", "VARCHAR(255)")); - columns.add(new QueryResultColumn("MAXLEN", "VARCHAR(255)")); - rows = new ArrayList<>(); - // # CHARACTER_SET_NAME, DEFAULT_COLLATE_NAME, DESCRIPTION, MAXLEN - // latin1, latin1_swedish_ci, cp1252 West European, 1 - row = new ArrayList<>(); - row.add("latin1"); - row.add("latin1_swedish_ci"); - row.add("cp1252 West European"); - row.add("1"); - rows.add(row); - // # CHARACTER_SET_NAME, DEFAULT_COLLATE_NAME, DESCRIPTION, MAXLEN - // utf8mb4, utf8mb4_0900_ai_ci, UTF-8 Unicode, 4 - row = new ArrayList<>(); - row.add("utf8mb4"); - row.add("utf8mb4_0900_ai_ci"); - row.add("UTF-8 Unicode"); - row.add("4"); - rows.add(row); - mockResults.put(query, new Pair<>(columns, rows)); - - query = - "select * from `information_schema`.`collations` where character_set_name = 'latin1' order by `collation_name` asc"; - columns = new ArrayList<>(); - columns.add(new QueryResultColumn("COLLATION_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("CHARACTER_SET_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("ID", "VARCHAR(255)")); - columns.add(new QueryResultColumn("IS_DEFAULT", "VARCHAR(255)")); - columns.add(new QueryResultColumn("IS_COMPILED", "VARCHAR(255)")); - columns.add(new QueryResultColumn("SORTLEN", "VARCHAR(255)")); - columns.add(new QueryResultColumn("PAD_ATTRIBUTE", "VARCHAR(255)")); - rows = new ArrayList<>(); - // # COLLATION_NAME, CHARACTER_SET_NAME, ID, IS_DEFAULT, IS_COMPILED, SORTLEN, PAD_ATTRIBUTE - // latin1_swedish_ci, latin1, 8, Yes, Yes, 1, PAD SPACE - row = new ArrayList<>(); - row.add("latin1_swedish_ci"); - row.add("latin1"); - row.add("8"); - row.add("Yes"); - row.add("Yes"); - row.add("1"); - row.add("PAD SPACE"); - rows.add(row); - mockResults.put(query, new Pair<>(columns, rows)); - - // COLLATION_NAME, CHARACTER_SET_NAME, ID, IS_DEFAULT, IS_COMPILED, SORTLEN, PAD_ATTRIBUTE - query = - "select * from `information_schema`.`collations` where character_set_name = 'utf8mb4' order by `collation_name` asc"; - // # COLLATION_NAME, CHARACTER_SET_NAME, ID, IS_DEFAULT, IS_COMPILED, SORTLEN, PAD_ATTRIBUTE - // utf8mb4_0900_ai_ci, utf8mb4, 255, Yes, Yes, 0, NO PAD - columns = new ArrayList<>(); - columns.add(new QueryResultColumn("COLLATION_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("CHARACTER_SET_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("ID", "VARCHAR(255)")); - columns.add(new QueryResultColumn("IS_DEFAULT", "VARCHAR(255)")); - columns.add(new QueryResultColumn("IS_COMPILED", "VARCHAR(255)")); - columns.add(new QueryResultColumn("SORTLEN", "VARCHAR(255)")); - columns.add(new QueryResultColumn("PAD_ATTRIBUTE", "VARCHAR(255)")); - rows = new ArrayList<>(); - row = new ArrayList<>(); - row.add("utf8mb4_0900_ai_ci"); - row.add("utf8mb4"); - row.add("255"); - row.add("Yes"); - row.add("Yes"); - row.add("0"); - row.add("NO PAD"); - rows.add(row); - mockResults.put(query, new Pair<>(columns, rows)); - query = "select word from information_schema.keywords where reserved=1 order by word"; columns = new ArrayList<>(); columns.add(new QueryResultColumn("WORD", "VARCHAR(255)")); diff --git a/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/server/OpenmldbMysqlServer.java b/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/server/OpenmldbMysqlServer.java index 9128cfb7486..0e9a0ce8ec3 100644 --- a/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/server/OpenmldbMysqlServer.java +++ b/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/server/OpenmldbMysqlServer.java @@ -18,6 +18,7 @@ import com.google.common.base.Strings; import java.io.IOException; import java.sql.SQLException; +import java.sql.Statement; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; @@ -67,8 +68,7 @@ public class OpenmldbMysqlServer { private final Pattern createDatabasePattern = Pattern.compile("(?i)(CREATE DATABASE `.+`).*"); - private final Pattern selectLimitPattern = - Pattern.compile("(?i)(SELECT .+) limit (?:\\d)+,(?:\\d)+"); + private final Pattern selectLimitPattern = Pattern.compile("(?i)(SELECT .+) limit \\d+,\\s*\\d+"); // SELECT * FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='demo_db' private final Pattern selectSchemaTaPattern = @@ -77,12 +77,8 @@ public class OpenmldbMysqlServer { // SHOW FULL TABLES FROM demo_db private final Pattern showTablesFromDbPattern = Pattern.compile("(?i)SHOW FULL TABLES FROM (.+)"); - // private final Pattern crateTableResultPattern = - // Pattern.compile( - // "(?i)(?s)(?m)CREATE TABLE `(.+)` \\([\\s\\r\\n]+(?:`(.+)` (.+),[\\s\\r\\n]+)+.*\\) - // OPTIONS .*"); - - public OpenmldbMysqlServer(int port, String zkCluster, String zkRootPath) { + public OpenmldbMysqlServer( + int port, String zkCluster, String zkRootPath, long sessionTimeout, long requestTimeout) { new MySqlListener( port, 100, @@ -108,7 +104,6 @@ public void authenticate( byte[] scramble411, byte[] authSeed) throws IOException { - // mocked username String validUser = ServerConfig.getOpenmldbUser(); if (!userName.equals(validUser)) { @@ -135,9 +130,8 @@ public void authenticate( SdkOption option = new SdkOption(); option.setZkCluster(zkCluster); option.setZkPath(zkRootPath); - // TODO: Make these configurable - option.setSessionTimeout(10000); - option.setRequestTimeout(60000); + option.setSessionTimeout(sessionTimeout); + option.setRequestTimeout(requestTimeout); option.setUser(userName); option.setPassword(validPassword); SqlClusterExecutor sqlExecutor = new SqlClusterExecutor(option); @@ -184,411 +178,501 @@ public void query( this.authenticate(connectionId, database, userName, scramble411, authSeed); try { - if (MockResult.mockResults.containsKey(sql.toLowerCase())) { - Pair, List>> pair = - MockResult.mockResults.get(sql.toLowerCase()); - resultSetWriter.writeColumns(pair.getKey()); - for (List row : pair.getValue()) { - resultSetWriter.writeRow(row); + if (mockPlainQuery(resultSetWriter, sql)) { + return; + } + + // This mock must execute before mockPatternQuery + // SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'demo_db' + // UNION SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = + // 'demo_db' UNION SELECT COUNT(*) FROM information_schema.ROUTINES WHERE + // ROUTINE_SCHEMA = 'demo_db' + if (mockSelectCountUnion(connectionId, resultSetWriter, sql)) { + return; + } + + if (mockPatternQuery(resultSetWriter, sql)) { + return; + } + + // mock SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM + // information_schema.SCHEMATA + if (mockInformationSchemaSchemaTa(connectionId, resultSetWriter, sql)) { + return; + } + + // mock SELECT DATABASE() + if (mockSelectDatabase(connectionId, resultSetWriter, sql)) { + return; + } + + // mock SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE FROM information_schema.TABLES + // WHERE TABLE_SCHEMA = 'demo_db' ORDER BY TABLE_SCHEMA, TABLE_TYPE + if (mockSelectTables(connectionId, resultSetWriter, sql)) { + return; + } + + // mock SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_TYPE FROM + // information_schema.COLUMNS WHERE TABLE_SCHEMA = 'demo_db' ORDER BY TABLE_SCHEMA, + // TABLE_NAME + if (mockSelectColumns(connectionId, resultSetWriter, sql)) { + return; + } + + // mock SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='xzs' AND + // TABLE_NAME='t_exam_paper' ORDER BY ORDINAL_POSITION + if (mockSelectColumns4Dbeaver(connectionId, resultSetWriter, sql)) { + return; + } + + // mock SELECT * FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='demo_db' + if (mockSchemaTa(resultSetWriter, sql)) { + return; + } + + java.sql.Statement stmt = sqlClusterExecutorMap.get(connectionId).getStatement(); + + if (!Strings.isNullOrEmpty(database)) { + stmt.execute("use " + database); + } + + if (mockShowColumns(resultSetWriter, sql, stmt)) { + return; + } + + if (sql.startsWith("SHOW FULL TABLES")) { + // SHOW FULL TABLES WHERE Table_type != 'VIEW' + Matcher showTablesFromDbMatcher = showTablesFromDbPattern.matcher(sql); + if (showTablesFromDbMatcher.matches()) { + String dbName = showTablesFromDbMatcher.group(1); + stmt.execute("use " + dbName); + sql = "SHOW TABLES FROM " + dbName; + } else { + sql = "SHOW TABLES"; } - resultSetWriter.finish(); } else { - // SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'demo_db' - // UNION SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = - // 'demo_db' UNION SELECT COUNT(*) FROM information_schema.ROUTINES WHERE - // ROUTINE_SCHEMA = 'demo_db' - Matcher selectCountUnionMatcher = selectCountUnionPattern.matcher(sql); - if (selectCountUnionMatcher.matches()) { - // COUNT(*) - List columns = new ArrayList<>(); - columns.add(new QueryResultColumn("COUNT(*)", "VARCHAR(255)")); - resultSetWriter.writeColumns(columns); - List row; - for (int i = 1; i <= selectCountUnionMatcher.groupCount(); ++i) { - String unionSql = selectCountUnionMatcher.group(i); - - Matcher selectCountTablesMatcher = selectCountTablesPattern.matcher(unionSql); - Matcher selectCountColumnsMatcher = selectCountColumnsPattern.matcher(unionSql); - Matcher selectCountRoutinesMatcher = - selectCountRoutinesPattern.matcher(unionSql); - if (selectCountTablesMatcher.matches()) { - String dbName = selectCountTablesMatcher.group(1); - row = new ArrayList<>(); - row.add( - Integer.toString( - sqlClusterExecutorMap - .get(connectionId) - .getTableNames(dbName) - .size())); - resultSetWriter.writeRow(row); - } else if (selectCountColumnsMatcher.matches()) { - String dbName = selectCountTablesMatcher.group(1); - int columnCount = 0; - for (String tableName : - sqlClusterExecutorMap.get(connectionId).getTableNames(dbName)) { - columnCount += - sqlClusterExecutorMap - .get(connectionId) - .getTableSchema(dbName, tableName) - .getColumnList() - .size(); - } - row = new ArrayList<>(); - row.add(Integer.toString(columnCount)); - resultSetWriter.writeRow(row); - } else if (selectCountRoutinesMatcher.matches()) { - row = new ArrayList<>(); - row.add(Integer.toString(0)); - resultSetWriter.writeRow(row); - } - } - resultSetWriter.finish(); - return; + Matcher crateDatabaseMatcher = createDatabasePattern.matcher(sql); + Matcher selectLimitMatcher = selectLimitPattern.matcher(sql); + if (crateDatabaseMatcher.matches()) { + sql = crateDatabaseMatcher.group(1); + } else if (selectLimitMatcher.matches()) { + sql = selectLimitMatcher.group(1); } + } + sql = sql.replaceAll("(?i)\\s*limit\\s*\\d+\\s*,\\s*\\d+", ""); + stmt.execute(sql); - for (String patternStr : MockResult.mockPatternResults.keySet()) { - Pattern pattern = Pattern.compile(patternStr); - if (pattern.matcher(sql).matches()) { - Pair, List>> pair = - MockResult.mockPatternResults.get(patternStr); - resultSetWriter.writeColumns(pair.getKey()); - for (List row : pair.getValue()) { - resultSetWriter.writeRow(row); - } - resultSetWriter.finish(); - return; - } - } + if (sql.toLowerCase().startsWith("select") || sql.toLowerCase().startsWith("show")) { + SQLResultSet resultSet = (SQLResultSet) stmt.getResultSet(); + outputResultSet(resultSetWriter, resultSet, sql); + } - // mock SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM - // information_schema.SCHEMATA - if (sql.equalsIgnoreCase( - "SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA")) { - List dbs = sqlClusterExecutorMap.get(connectionId).showDatabases(); - // SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME - // mysql utf8mb4 utf8mb4_0900_ai_ci - List columns = new ArrayList<>(); - columns.add(new QueryResultColumn("SCHEMA_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("DEFAULT_CHARACTER_SET_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("DEFAULT_COLLATION_NAME", "VARCHAR(255)")); - resultSetWriter.writeColumns(columns); - List row; - for (String db : dbs) { - row = new ArrayList<>(); - row.add(db); - row.add("utf8mb4"); - row.add("utf8mb4_0900_ai_ci"); - resultSetWriter.writeRow(row); - } - resultSetWriter.finish(); - return; - } + System.out.println("Success to execute OpenMLDB SQL: " + sql); - // mock SELECT DATABASE() - if (sql.equalsIgnoreCase("SELECT DATABASE()")) { - java.sql.Statement stmt = sqlClusterExecutorMap.get(connectionId).getStatement(); - stmt.execute("show table status"); - - // DATABASE() - // demo_db - List columns = new ArrayList<>(); - columns.add(new QueryResultColumn("DATABASE()", "VARCHAR(255)")); - resultSetWriter.writeColumns(columns); - SQLResultSet resultSet = (SQLResultSet) stmt.getResultSet(); - Schema schema = resultSet.GetInternalSchema(); - int columnCount = schema.getColumnList().size(); - int dbNameIndex = -1; - for (int i = 0; i < columnCount; i++) { - if (schema.getColumnName(i).equalsIgnoreCase("Database_name")) { - dbNameIndex = i; - break; - } - } + // Close resources + stmt.close(); + } catch (Exception e) { + e.printStackTrace(); + throw new IOException(e); + } + } - if (dbNameIndex != -1) { - while (resultSet.next()) { - // Build and respond rows - List row = new ArrayList<>(); - for (int i = 0; i < columnCount; i++) { - if (i == dbNameIndex) { - int type = schema.getColumnType(i); - String columnValue = - TypeUtil.getResultSetStringColumn(resultSet, i + 1, type); - row.add(columnValue); - break; - } - } - resultSetWriter.writeRow(row); - } - } + private boolean mockPlainQuery(ResultSetWriter resultSetWriter, String sql) { + if (MockResult.mockResults.containsKey(sql.toLowerCase())) { + Pair, List>> pair = + MockResult.mockResults.get(sql.toLowerCase()); + resultSetWriter.writeColumns(pair.getKey()); + for (List row : pair.getValue()) { + resultSetWriter.writeRow(row); + } + resultSetWriter.finish(); + return true; + } + return false; + } - resultSetWriter.finish(); - stmt.close(); - return; + private boolean mockShowColumns( + ResultSetWriter resultSetWriter, String sql, Statement stmt) throws SQLException { + Matcher showFullColumnsMatcher = showFullColumnsPattern.matcher(sql); + Matcher showColumnsMatcher = showColumnsPattern.matcher(sql); + boolean showFullColumnsMatch = showFullColumnsMatcher.matches(); + boolean showColumnsMatch = showColumnsMatcher.matches(); + if (showFullColumnsMatch || showColumnsMatch) { + String tableName; + String databaseName; + if (showFullColumnsMatch) { + tableName = showFullColumnsMatcher.group(1); + databaseName = showFullColumnsMatcher.group(2); + } else { + tableName = showColumnsMatcher.group(1); + databaseName = showColumnsMatcher.group(2); + } + String selectStarSql = "select * from `" + databaseName + "`.`" + tableName + "`"; + stmt.execute(selectStarSql); + + List columns = new ArrayList<>(); + // # Field, Type, Collation, Null, Key, Default, Extra, Privileges, Comment + // id, int, , NO, PRI, , auto_increment, select,insert,update,references, + columns.add(new QueryResultColumn("Field", "VARCHAR(255)")); + columns.add(new QueryResultColumn("Type", "VARCHAR(255)")); + if (showFullColumnsMatch) { + columns.add(new QueryResultColumn("Collation", "VARCHAR(255)")); + } + columns.add(new QueryResultColumn("Null", "VARCHAR(255)")); + columns.add(new QueryResultColumn("Key", "VARCHAR(255)")); + columns.add(new QueryResultColumn("Default", "VARCHAR(255)")); + columns.add(new QueryResultColumn("Extra", "VARCHAR(255)")); + if (showFullColumnsMatch) { + columns.add(new QueryResultColumn("Privileges", "VARCHAR(255)")); + columns.add(new QueryResultColumn("Comment", "VARCHAR(255)")); + } + resultSetWriter.writeColumns(columns); + + SQLResultSet resultSet = (SQLResultSet) stmt.getResultSet(); + Schema schema = resultSet.GetInternalSchema(); + // int columnCount = schema.GetColumnCnt(); + int columnCount = schema.getColumnList().size(); + // Add schema + for (int i = 0; i < columnCount; i++) { + List row = new ArrayList<>(); + row.add(schema.getColumnName(i)); + row.add(TypeUtil.openmldbTypeToMysqlTypeString(schema.getColumnType(i))); + if (showFullColumnsMatch) { + row.add(""); } - - // mock SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE FROM information_schema.TABLES - // WHERE TABLE_SCHEMA = 'demo_db' ORDER BY TABLE_SCHEMA, TABLE_TYPE - Matcher selectTablesMatcher = selectTablesPattern.matcher(sql); - if (selectTablesMatcher.matches()) { - String dbName = selectTablesMatcher.group(1); - List tableNames = - sqlClusterExecutorMap.get(connectionId).getTableNames(dbName); - // TABLE_SCHEMA TABLE_NAME TABLE_TYPE - List columns = new ArrayList<>(); - columns.add(new QueryResultColumn("TABLE_SCHEMA", "VARCHAR(255)")); - columns.add(new QueryResultColumn("TABLE_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("TABLE_TYPE", "VARCHAR(255)")); - resultSetWriter.writeColumns(columns); - List row; - for (String tableName : tableNames) { - row = new ArrayList<>(); - row.add(dbName); - row.add(tableName); - row.add("BASE TABLE"); - resultSetWriter.writeRow(row); - } - resultSetWriter.finish(); - return; + row.add(""); + row.add(""); + row.add(""); + row.add(""); + if (showFullColumnsMatch) { + row.add(""); + row.add(""); } + resultSetWriter.writeRow(row); + } + resultSetWriter.finish(); + stmt.close(); + return true; + } + return false; + } - // mock SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_TYPE FROM - // information_schema.COLUMNS WHERE TABLE_SCHEMA = 'demo_db' ORDER BY TABLE_SCHEMA, - // TABLE_NAME - Matcher selectColumnsMatcher = selectColumnsPattern.matcher(sql); - if (selectColumnsMatcher.matches()) { - String dbName = selectColumnsMatcher.group(1); - List tableNames = - sqlClusterExecutorMap.get(connectionId).getTableNames(dbName); - // TABLE_SCHEMA TABLE_NAME COLUMN_NAME COLUMN_TYPE - List columns = new ArrayList<>(); - columns.add(new QueryResultColumn("TABLE_SCHEMA", "VARCHAR(255)")); - columns.add(new QueryResultColumn("TABLE_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("COLUMN_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("COLUMN_TYPE", "VARCHAR(255)")); - resultSetWriter.writeColumns(columns); - List row; - Collections.sort(tableNames); - for (String tableName : tableNames) { - Schema tableSchema = - sqlClusterExecutorMap.get(connectionId).getTableSchema(dbName, tableName); - for (Column column : tableSchema.getColumnList()) { - row = new ArrayList<>(); - row.add(dbName); - row.add(tableName); - row.add(column.getColumnName()); - row.add(TypeUtil.openmldbTypeToMysqlTypeString(column.getSqlType())); - resultSetWriter.writeRow(row); - } - } - resultSetWriter.finish(); - return; - } + private boolean mockSchemaTa(ResultSetWriter resultSetWriter, String sql) { + // mock SELECT * FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='demo_db' + Matcher selectSchemaTaMatcher = selectSchemaTaPattern.matcher(sql); + if (selectSchemaTaMatcher.matches()) { + String dbName = selectSchemaTaMatcher.group(1); + // CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME + // SQL_PATH DEFAULT_ENCRYPTION + List columns = new ArrayList<>(); + columns.add(new QueryResultColumn("CATALOG_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("SCHEMA_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("DEFAULT_CHARACTER_SET_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("DEFAULT_COLLATION_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("SQL_PATH", "VARCHAR(255)")); + columns.add(new QueryResultColumn("DEFAULT_ENCRYPTION", "VARCHAR(255)")); + resultSetWriter.writeColumns(columns); + List row; + // def xzs utf8mb4 utf8mb4_0900_ai_ci NO + row = new ArrayList<>(); + row.add("def"); + row.add(dbName); + row.add("utf8mb4"); + row.add("utf8mb4_0900_ai_ci"); + row.add(null); + row.add("NO"); + resultSetWriter.writeRow(row); + resultSetWriter.finish(); + return true; + } + return false; + } - // mock SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='xzs' AND - // TABLE_NAME='t_exam_paper' ORDER BY ORDINAL_POSITION - Matcher selectColumns4DbeaverMatcher = selectColumns4DbeaverPattern.matcher(sql); - if (selectColumns4DbeaverMatcher.matches()) { - String dbName = selectColumns4DbeaverMatcher.group(1); - String tableName = selectColumns4DbeaverMatcher.group(2); - // TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION - // COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH - // CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION - // CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES - // COLUMN_COMMENT GENERATION_EXPRESSION SRS_ID - // def xzs t_exam_paper id 1 NO int 10 0 int PRI auto_increment - // select,insert,update,references - List columns = new ArrayList<>(); - columns.add(new QueryResultColumn("TABLE_CATALOG", "VARCHAR(255)")); - columns.add(new QueryResultColumn("TABLE_SCHEMA", "VARCHAR(255)")); - columns.add(new QueryResultColumn("TABLE_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("COLUMN_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("ORDINAL_POSITION", "VARCHAR(255)")); - columns.add(new QueryResultColumn("COLUMN_DEFAULT", "VARCHAR(255)")); - columns.add(new QueryResultColumn("IS_NULLABLE", "VARCHAR(255)")); - columns.add(new QueryResultColumn("DATA_TYPE", "VARCHAR(255)")); - columns.add(new QueryResultColumn("CHARACTER_MAXIMUM_LENGTH", "VARCHAR(255)")); - columns.add(new QueryResultColumn("CHARACTER_OCTET_LENGTH", "VARCHAR(255)")); - columns.add(new QueryResultColumn("NUMERIC_PRECISION", "VARCHAR(255)")); - columns.add(new QueryResultColumn("NUMERIC_SCALE", "VARCHAR(255)")); - columns.add(new QueryResultColumn("DATETIME_PRECISION", "VARCHAR(255)")); - columns.add(new QueryResultColumn("CHARACTER_SET_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("COLLATION_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("COLUMN_TYPE", "VARCHAR(255)")); - columns.add(new QueryResultColumn("COLUMN_KEY", "VARCHAR(255)")); - columns.add(new QueryResultColumn("EXTRA", "VARCHAR(255)")); - columns.add(new QueryResultColumn("PRIVILEGES", "VARCHAR(255)")); - columns.add(new QueryResultColumn("COLUMN_COMMENT", "VARCHAR(255)")); - columns.add(new QueryResultColumn("GENERATION_EXPRESSION", "VARCHAR(255)")); - columns.add(new QueryResultColumn("SRS_ID", "VARCHAR(255)")); - resultSetWriter.writeColumns(columns); - List row; - Schema tableSchema = - sqlClusterExecutorMap.get(connectionId).getTableSchema(dbName, tableName); - int ordinalPosition = 1; - for (Column column : tableSchema.getColumnList()) { - row = new ArrayList<>(); - row.add("def"); - row.add(dbName); - row.add(tableName); - row.add(column.getColumnName()); - row.add(Integer.toString(ordinalPosition++)); - row.add(null); - row.add("NO"); - row.add(TypeUtil.openmldbTypeToMysqlTypeString(column.getSqlType())); - row.add(null); - row.add(null); - row.add(null); - row.add(null); - row.add(null); - row.add(null); - row.add(null); - row.add(TypeUtil.openmldbTypeToMysqlTypeString(column.getSqlType())); - row.add(null); - row.add(null); - row.add("select,insert,update,references"); - row.add(null); - row.add(null); - row.add(null); - resultSetWriter.writeRow(row); - } + private boolean mockSelectColumns4Dbeaver( + int connectionId, ResultSetWriter resultSetWriter, String sql) throws SQLException { + // mock SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='xzs' AND + // TABLE_NAME='t_exam_paper' ORDER BY ORDINAL_POSITION + Matcher selectColumns4DbeaverMatcher = selectColumns4DbeaverPattern.matcher(sql); + if (selectColumns4DbeaverMatcher.matches()) { + String dbName = selectColumns4DbeaverMatcher.group(1); + String tableName = selectColumns4DbeaverMatcher.group(2); + // TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION + // COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH + // CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION + // CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES + // COLUMN_COMMENT GENERATION_EXPRESSION SRS_ID + // def xzs t_exam_paper id 1 NO int 10 0 int PRI auto_increment + // select,insert,update,references + List columns = new ArrayList<>(); + columns.add(new QueryResultColumn("TABLE_CATALOG", "VARCHAR(255)")); + columns.add(new QueryResultColumn("TABLE_SCHEMA", "VARCHAR(255)")); + columns.add(new QueryResultColumn("TABLE_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("COLUMN_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("ORDINAL_POSITION", "VARCHAR(255)")); + columns.add(new QueryResultColumn("COLUMN_DEFAULT", "VARCHAR(255)")); + columns.add(new QueryResultColumn("IS_NULLABLE", "VARCHAR(255)")); + columns.add(new QueryResultColumn("DATA_TYPE", "VARCHAR(255)")); + columns.add(new QueryResultColumn("CHARACTER_MAXIMUM_LENGTH", "VARCHAR(255)")); + columns.add(new QueryResultColumn("CHARACTER_OCTET_LENGTH", "VARCHAR(255)")); + columns.add(new QueryResultColumn("NUMERIC_PRECISION", "VARCHAR(255)")); + columns.add(new QueryResultColumn("NUMERIC_SCALE", "VARCHAR(255)")); + columns.add(new QueryResultColumn("DATETIME_PRECISION", "VARCHAR(255)")); + columns.add(new QueryResultColumn("CHARACTER_SET_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("COLLATION_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("COLUMN_TYPE", "VARCHAR(255)")); + columns.add(new QueryResultColumn("COLUMN_KEY", "VARCHAR(255)")); + columns.add(new QueryResultColumn("EXTRA", "VARCHAR(255)")); + columns.add(new QueryResultColumn("PRIVILEGES", "VARCHAR(255)")); + columns.add(new QueryResultColumn("COLUMN_COMMENT", "VARCHAR(255)")); + columns.add(new QueryResultColumn("GENERATION_EXPRESSION", "VARCHAR(255)")); + columns.add(new QueryResultColumn("SRS_ID", "VARCHAR(255)")); + resultSetWriter.writeColumns(columns); + List row; + Schema tableSchema = + sqlClusterExecutorMap.get(connectionId).getTableSchema(dbName, tableName); + int ordinalPosition = 1; + for (Column column : tableSchema.getColumnList()) { + row = new ArrayList<>(); + row.add("def"); + row.add(dbName); + row.add(tableName); + row.add(column.getColumnName()); + row.add(Integer.toString(ordinalPosition++)); + row.add(null); + row.add("NO"); + row.add(TypeUtil.openmldbTypeToMysqlTypeString(column.getSqlType())); + row.add(null); + row.add(null); + row.add(null); + row.add(null); + row.add(null); + row.add(null); + row.add(null); + row.add(TypeUtil.openmldbTypeToMysqlTypeString(column.getSqlType())); + row.add(null); + row.add(null); + row.add("select,insert,update,references"); + row.add(null); + row.add(null); + row.add(null); + resultSetWriter.writeRow(row); + } - resultSetWriter.finish(); - return; - } + resultSetWriter.finish(); + return true; + } + return false; + } - // mock SELECT * FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='demo_db' - Matcher selectSchemaTaMatcher = selectSchemaTaPattern.matcher(sql); - if (selectSchemaTaMatcher.matches()) { - String dbName = selectSchemaTaMatcher.group(1); - // CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME - // SQL_PATH DEFAULT_ENCRYPTION - List columns = new ArrayList<>(); - columns.add(new QueryResultColumn("CATALOG_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("SCHEMA_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("DEFAULT_CHARACTER_SET_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("DEFAULT_COLLATION_NAME", "VARCHAR(255)")); - columns.add(new QueryResultColumn("SQL_PATH", "VARCHAR(255)")); - columns.add(new QueryResultColumn("DEFAULT_ENCRYPTION", "VARCHAR(255)")); - resultSetWriter.writeColumns(columns); - List row; - // def xzs utf8mb4 utf8mb4_0900_ai_ci NO + private boolean mockSelectColumns( + int connectionId, ResultSetWriter resultSetWriter, String sql) throws SQLException { + // mock SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_TYPE FROM + // information_schema.COLUMNS WHERE TABLE_SCHEMA = 'demo_db' ORDER BY TABLE_SCHEMA, + // TABLE_NAME + Matcher selectColumnsMatcher = selectColumnsPattern.matcher(sql); + if (selectColumnsMatcher.matches()) { + String dbName = selectColumnsMatcher.group(1); + List tableNames = + sqlClusterExecutorMap.get(connectionId).getTableNames(dbName); + // TABLE_SCHEMA TABLE_NAME COLUMN_NAME COLUMN_TYPE + List columns = new ArrayList<>(); + columns.add(new QueryResultColumn("TABLE_SCHEMA", "VARCHAR(255)")); + columns.add(new QueryResultColumn("TABLE_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("COLUMN_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("COLUMN_TYPE", "VARCHAR(255)")); + resultSetWriter.writeColumns(columns); + List row; + Collections.sort(tableNames); + for (String tableName : tableNames) { + Schema tableSchema = + sqlClusterExecutorMap.get(connectionId).getTableSchema(dbName, tableName); + for (Column column : tableSchema.getColumnList()) { row = new ArrayList<>(); - row.add("def"); row.add(dbName); - row.add("utf8mb4"); - row.add("utf8mb4_0900_ai_ci"); - row.add(null); - row.add("NO"); + row.add(tableName); + row.add(column.getColumnName()); + row.add(TypeUtil.openmldbTypeToMysqlTypeString(column.getSqlType())); resultSetWriter.writeRow(row); - resultSetWriter.finish(); - return; } + } + resultSetWriter.finish(); + return true; + } + return false; + } - java.sql.Statement stmt = sqlClusterExecutorMap.get(connectionId).getStatement(); - - Matcher showFullColumnsMatcher = showFullColumnsPattern.matcher(sql); - Matcher showColumnsMatcher = showColumnsPattern.matcher(sql); - boolean showFullColumnsMatch = showFullColumnsMatcher.matches(); - boolean showColumnsMatch = showColumnsMatcher.matches(); - if (showFullColumnsMatch || showColumnsMatch) { - String tableName; - String databaseName; - if (showFullColumnsMatch) { - tableName = showFullColumnsMatcher.group(1); - databaseName = showFullColumnsMatcher.group(2); - } else { - tableName = showColumnsMatcher.group(1); - databaseName = showColumnsMatcher.group(2); - } - String selectStarSql = "select * from `" + databaseName + "`.`" + tableName + "`"; - stmt.execute(selectStarSql); - - List columns = new ArrayList<>(); - // # Field, Type, Collation, Null, Key, Default, Extra, Privileges, Comment - // id, int, , NO, PRI, , auto_increment, select,insert,update,references, - columns.add(new QueryResultColumn("Field", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Type", "VARCHAR(255)")); - if (showFullColumnsMatch) { - columns.add(new QueryResultColumn("Collation", "VARCHAR(255)")); - } - columns.add(new QueryResultColumn("Null", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Key", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Default", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Extra", "VARCHAR(255)")); - if (showFullColumnsMatch) { - columns.add(new QueryResultColumn("Privileges", "VARCHAR(255)")); - columns.add(new QueryResultColumn("Comment", "VARCHAR(255)")); - } - resultSetWriter.writeColumns(columns); + private boolean mockSelectTables( + int connectionId, ResultSetWriter resultSetWriter, String sql) { + // mock SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE FROM information_schema.TABLES + // WHERE TABLE_SCHEMA = 'demo_db' ORDER BY TABLE_SCHEMA, TABLE_TYPE + Matcher selectTablesMatcher = selectTablesPattern.matcher(sql); + if (selectTablesMatcher.matches()) { + String dbName = selectTablesMatcher.group(1); + List tableNames = + sqlClusterExecutorMap.get(connectionId).getTableNames(dbName); + // TABLE_SCHEMA TABLE_NAME TABLE_TYPE + List columns = new ArrayList<>(); + columns.add(new QueryResultColumn("TABLE_SCHEMA", "VARCHAR(255)")); + columns.add(new QueryResultColumn("TABLE_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("TABLE_TYPE", "VARCHAR(255)")); + resultSetWriter.writeColumns(columns); + List row; + for (String tableName : tableNames) { + row = new ArrayList<>(); + row.add(dbName); + row.add(tableName); + row.add("BASE TABLE"); + resultSetWriter.writeRow(row); + } + resultSetWriter.finish(); + return true; + } + return false; + } - SQLResultSet resultSet = (SQLResultSet) stmt.getResultSet(); - Schema schema = resultSet.GetInternalSchema(); - // int columnCount = schema.GetColumnCnt(); - int columnCount = schema.getColumnList().size(); - // Add schema + private boolean mockSelectDatabase( + int connectionId, ResultSetWriter resultSetWriter, String sql) throws SQLException { + // mock SELECT DATABASE() + if (sql.equalsIgnoreCase("SELECT DATABASE()")) { + java.sql.Statement stmt = sqlClusterExecutorMap.get(connectionId).getStatement(); + stmt.execute("show table status"); + + // DATABASE() + // demo_db + List columns = new ArrayList<>(); + columns.add(new QueryResultColumn("DATABASE()", "VARCHAR(255)")); + resultSetWriter.writeColumns(columns); + SQLResultSet resultSet = (SQLResultSet) stmt.getResultSet(); + Schema schema = resultSet.GetInternalSchema(); + int columnCount = schema.getColumnList().size(); + int dbNameIndex = -1; + for (int i = 0; i < columnCount; i++) { + if (schema.getColumnName(i).equalsIgnoreCase("Database_name")) { + dbNameIndex = i; + break; + } + } + + if (dbNameIndex != -1) { + while (resultSet.next()) { + // Build and respond rows + List row = new ArrayList<>(); for (int i = 0; i < columnCount; i++) { - List row = new ArrayList<>(); - row.add(schema.getColumnName(i)); - row.add(TypeUtil.openmldbTypeToMysqlTypeString(schema.getColumnType(i))); - if (showFullColumnsMatch) { - row.add(""); - } - row.add(""); - row.add(""); - row.add(""); - row.add(""); - if (showFullColumnsMatch) { - row.add(""); - row.add(""); + if (i == dbNameIndex) { + int type = schema.getColumnType(i); + String columnValue = + TypeUtil.getResultSetStringColumn(resultSet, i + 1, type); + row.add(columnValue); + break; } - resultSetWriter.writeRow(row); } - resultSetWriter.finish(); - stmt.close(); - return; + resultSetWriter.writeRow(row); } + } - if (!Strings.isNullOrEmpty(database)) { - stmt.execute("use " + database); - } - if (sql.startsWith("SHOW FULL TABLES")) { - // SHOW FULL TABLES WHERE Table_type != 'VIEW' - Matcher showTablesFromDbMatcher = showTablesFromDbPattern.matcher(sql); - if (showTablesFromDbMatcher.matches()) { - String dbName = showTablesFromDbMatcher.group(1); - stmt.execute("use " + dbName); - sql = "SHOW TABLES FROM " + dbName; - } else { - sql = "SHOW TABLES"; - } - } else { - Matcher crateDatabaseMatcher = createDatabasePattern.matcher(sql); - Matcher selectLimitMatcher = selectLimitPattern.matcher(sql); - if (crateDatabaseMatcher.matches()) { - sql = crateDatabaseMatcher.group(1); - } else if (selectLimitMatcher.matches()) { - sql = selectLimitMatcher.group(1); - } - } - sql = sql.replaceAll("(?i)\\s*limit\\s*\\d+\\s*,\\s*\\d+", ""); - stmt.execute(sql); + resultSetWriter.finish(); + stmt.close(); + return true; + } + return false; + } - if (sql.toLowerCase().startsWith("select") - || sql.toLowerCase().startsWith("show")) { - SQLResultSet resultSet = (SQLResultSet) stmt.getResultSet(); - outputResultSet(resultSetWriter, resultSet, sql); - } + private boolean mockInformationSchemaSchemaTa( + int connectionId, ResultSetWriter resultSetWriter, String sql) { + // mock SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM + // information_schema.SCHEMATA + if (sql.equalsIgnoreCase( + "SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA")) { + List dbs = sqlClusterExecutorMap.get(connectionId).showDatabases(); + // SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME + // mysql utf8mb4 utf8mb4_0900_ai_ci + List columns = new ArrayList<>(); + columns.add(new QueryResultColumn("SCHEMA_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("DEFAULT_CHARACTER_SET_NAME", "VARCHAR(255)")); + columns.add(new QueryResultColumn("DEFAULT_COLLATION_NAME", "VARCHAR(255)")); + resultSetWriter.writeColumns(columns); + List row; + for (String db : dbs) { + row = new ArrayList<>(); + row.add(db); + row.add("utf8mb4"); + row.add("utf8mb4_0900_ai_ci"); + resultSetWriter.writeRow(row); + } + resultSetWriter.finish(); + return true; + } + return false; + } - System.out.println("Success to execute OpenMLDB SQL: " + sql); + private boolean mockPatternQuery(ResultSetWriter resultSetWriter, String sql) { + for (String patternStr : MockResult.mockPatternResults.keySet()) { + Pattern pattern = Pattern.compile(patternStr); + if (pattern.matcher(sql).matches()) { + Pair, List>> pair = + MockResult.mockPatternResults.get(patternStr); + resultSetWriter.writeColumns(pair.getKey()); + for (List row : pair.getValue()) { + resultSetWriter.writeRow(row); + } + resultSetWriter.finish(); + return true; + } + } + return false; + } - // Close resources - stmt.close(); + private boolean mockSelectCountUnion( + int connectionId, ResultSetWriter resultSetWriter, String sql) throws SQLException { + // SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'demo_db' + // UNION SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = + // 'demo_db' UNION SELECT COUNT(*) FROM information_schema.ROUTINES WHERE + // ROUTINE_SCHEMA = 'demo_db' + Matcher selectCountUnionMatcher = selectCountUnionPattern.matcher(sql); + if (selectCountUnionMatcher.matches()) { + // COUNT(*) + List columns = new ArrayList<>(); + columns.add(new QueryResultColumn("COUNT(*)", "VARCHAR(255)")); + resultSetWriter.writeColumns(columns); + List row; + for (int i = 1; i <= selectCountUnionMatcher.groupCount(); ++i) { + String unionSql = selectCountUnionMatcher.group(i); + + Matcher selectCountTablesMatcher = selectCountTablesPattern.matcher(unionSql); + Matcher selectCountColumnsMatcher = selectCountColumnsPattern.matcher(unionSql); + Matcher selectCountRoutinesMatcher = selectCountRoutinesPattern.matcher(unionSql); + if (selectCountTablesMatcher.matches()) { + String dbName = selectCountTablesMatcher.group(1); + row = new ArrayList<>(); + row.add( + Integer.toString( + sqlClusterExecutorMap.get(connectionId).getTableNames(dbName).size())); + resultSetWriter.writeRow(row); + } else if (selectCountColumnsMatcher.matches()) { + String dbName = selectCountTablesMatcher.group(1); + int columnCount = 0; + for (String tableName : + sqlClusterExecutorMap.get(connectionId).getTableNames(dbName)) { + columnCount += + sqlClusterExecutorMap + .get(connectionId) + .getTableSchema(dbName, tableName) + .getColumnList() + .size(); + } + row = new ArrayList<>(); + row.add(Integer.toString(columnCount)); + resultSetWriter.writeRow(row); + } else if (selectCountRoutinesMatcher.matches()) { + row = new ArrayList<>(); + row.add(Integer.toString(0)); + resultSetWriter.writeRow(row); + } } - } catch (Exception e) { - e.printStackTrace(); - throw new IOException(e); + resultSetWriter.finish(); + return true; } + return false; } @Override @@ -602,9 +686,13 @@ public static void main(String[] args) { int serverPort = ServerConfig.getPort(); String zkCluster = ServerConfig.getZkCluster(); String zkRootPath = ServerConfig.getZkRootPath(); + long sessionTimeout = ServerConfig.getSessionTimeout(); + long requestTimeout = ServerConfig.getRequestTimeout(); try { - OpenmldbMysqlServer server = new OpenmldbMysqlServer(serverPort, zkCluster, zkRootPath); + OpenmldbMysqlServer server = + new OpenmldbMysqlServer( + serverPort, zkCluster, zkRootPath, sessionTimeout, requestTimeout); server.start(); // Conenct with mysql client, mysql -h127.0.0.1 -P3307 } catch (Exception e) { diff --git a/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/server/ServerConfig.java b/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/server/ServerConfig.java index 9127e963ad3..d343bf996d4 100644 --- a/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/server/ServerConfig.java +++ b/extensions/open-mysql-db/src/main/java/com/_4paradigm/openmldb/mysql/server/ServerConfig.java @@ -25,12 +25,6 @@ public class ServerConfig { e1.printStackTrace(); } } - - // try (FileInputStream input = new FileInputStream(CONFIG_FILE_PATH)) { - // properties.load(input); - // } catch (IOException e) { - // e.printStackTrace(); - // } } public static int getPort() { @@ -52,4 +46,12 @@ public static String getOpenmldbUser() { public static String getOpenmldbPassword() { return properties.getProperty("openmldb.password", "root"); } + + public static long getSessionTimeout() { + return Long.parseLong(properties.getProperty("openmldb.sessionTimeout", "10000")); + } + + public static long getRequestTimeout() { + return Long.parseLong(properties.getProperty("openmldb.requestTimeout", "60000")); + } } diff --git a/extensions/open-mysql-db/src/main/resources/server.properties b/extensions/open-mysql-db/src/main/resources/server.properties index 0c7b271bd12..2e0699d5c7e 100644 --- a/extensions/open-mysql-db/src/main/resources/server.properties +++ b/extensions/open-mysql-db/src/main/resources/server.properties @@ -7,3 +7,5 @@ zookeeper.cluster=0.0.0.0:2181 zookeeper.root_path=/openmldb openmldb.user=root openmldb.password=root +openmldb.sessionTimeout=10000 +openmldb.requestTimeout=60000