From 0a2ea26dd36f425c3a8ad79c014a5b9ce497707a Mon Sep 17 00:00:00 2001 From: daidai <2017501503@qq.com> Date: Wed, 5 Jun 2024 10:35:29 +0800 Subject: [PATCH 1/2] [Test](manager_interface)append manager interface test. --- .../data/manager/test_manager_interface_1.out | 15 + .../manager/test_manager_interface_1.groovy | 724 ++++++++++++++++++ .../manager/test_manager_interface_2.groovy | 319 ++++++++ .../manager/test_manager_interface_3.groovy | 616 +++++++++++++++ 4 files changed, 1674 insertions(+) create mode 100644 regression-test/data/manager/test_manager_interface_1.out create mode 100644 regression-test/suites/manager/test_manager_interface_1.groovy create mode 100644 regression-test/suites/manager/test_manager_interface_2.groovy create mode 100644 regression-test/suites/manager/test_manager_interface_3.groovy diff --git a/regression-test/data/manager/test_manager_interface_1.out b/regression-test/data/manager/test_manager_interface_1.out new file mode 100644 index 00000000000000..182dae7bea530e --- /dev/null +++ b/regression-test/data/manager/test_manager_interface_1.out @@ -0,0 +1,15 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !tables_1 -- +k1 TINYINT Yes true \N +k2 DECIMAL(10, 2) Yes true 10.05 +k3 CHAR(10) Yes true \N BLOOM_FILTER +k4 INT No false 1 NONE +k5 TEXT Yes false \N NONE,BLOOM_FILTER + +-- !tables_2 -- +test_manager_tb_1 DUP_KEYS k1 TINYINT TINYINT Yes true \N true + k2 DECIMAL(10, 2) DECIMALV3(10, 2) Yes true 10.05 true + k3 CHAR(10) CHAR(10) Yes true \N BLOOM_FILTER true + k4 INT INT No false 1 NONE true + k5 TEXT TEXT Yes false \N NONE,BLOOM_FILTER true + diff --git a/regression-test/suites/manager/test_manager_interface_1.groovy b/regression-test/suites/manager/test_manager_interface_1.groovy new file mode 100644 index 00000000000000..44f0e478a4e570 --- /dev/null +++ b/regression-test/suites/manager/test_manager_interface_1.groovy @@ -0,0 +1,724 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +import org.apache.doris.regression.suite.ClusterOptions +import org.apache.doris.regression.util.NodeType + +import java.time.LocalDateTime +import java.time.Duration +import java.time.format.DateTimeFormatter + + + +suite('test_manager_interface_1',"p0") { + + + + logger.info("test_manager_interface_1 start") + + sql """ switch internal """ + + + String jdbcUrl = context.config.jdbcUrl + def tokens = context.config.jdbcUrl.split('/') + jdbcUrl=tokens[0] + "//" + tokens[2] + "/" + "?" + String jdbcUser = context.config.jdbcUser + String jdbcPassword = context.config.jdbcPassword + String s3_endpoint = getS3Endpoint() + String bucket = getS3BucketName() + String driver_url = "https://${bucket}.${s3_endpoint}/regression/jdbc_driver/mysql-connector-java-8.0.25.jar" + + + +//select * from internal.information_schema.schemata + def test_schemata = { + logger.info("TEST select * from internal.information_schema.schemata"); + + List> schemata = sql """select * from internal.information_schema.schemata""" + for (int i = 0; i < schemata.size(); i++) { + assertTrue(!schemata[i][0].isEmpty()) // CATALOG_NAME + assertTrue(schemata[i][0].toLowerCase() != "null") + + assertTrue(!schemata[i][1].isEmpty()) // SCHEMA_NAME + assertTrue(schemata[i][1].toLowerCase() != "null") + } + List> schemata2 = sql """select * from internal.information_schema.schemata where CATALOG_NAME = "internal" and SCHEMA_NAME = "__internal_schema" """ + assertTrue(schemata2.size() == 1) + + sql """ drop database if exists internal.test_information_schemata_1; """ + sql """ create database internal.test_information_schemata_1; """ + List> schemata3 = sql """select * from internal.information_schema.schemata where CATALOG_NAME = "internal" and SCHEMA_NAME = "test_information_schemata_1" """ + assertTrue(schemata3.size() == 1) + + sql """ drop database internal.test_information_schemata_1; """ + List> schemata4 = sql """select * from internal.information_schema.schemata where CATALOG_NAME = "internal" and SCHEMA_NAME = "test_information_schemata_1" """ + assertTrue(schemata4.size() == 0) + } + test_schemata() + + +//select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE from information_schema.tables + def test_information_tables = { + logger.info("TEST select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE from information_schema.tables") + + List> result = sql """select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE from information_schema.tables""" + for(int i = 0;i> result = sql """select * from information_schema.metadata_name_ids """ + } + + + +//show catalogs +//alter catalog $old_name rename $new_name +//drop catalog $catalog_name + def test_catalogs = { + logger.info("TEST show/rename/drop catalogs") + def catalog_name = "test_manager_catalogs_case" + // println jdbcUrl + sql """ drop catalog if exists ${catalog_name}""" + sql """ CREATE CATALOG `${catalog_name}` PROPERTIES( + "user" = "${jdbcUser}", + "type" = "jdbc", + "password" = "${jdbcPassword}", + "jdbc_url" = "${jdbcUrl}", + "driver_url" = "${driver_url}", + "driver_class" = "com.mysql.cj.jdbc.Driver" + )""" + + List> result = sql """ show catalogs """ + //CatalogName + def x = 0 + for( int i =0 ;i < result.size();i++ ) { + assertTrue(result[i][1].toLowerCase() != "null") + if ( result[i][1].toLowerCase() == catalog_name) { + x = 1 + } + } + assertTrue(x == 1) + + x = 0 + sql """ alter catalog ${catalog_name} rename ${catalog_name}_rename """ + result = sql """ show catalogs """ + for( int i =0 ;i < result.size();i++ ) { + assertTrue(result[i][1].toLowerCase() != "null") + if ( result[i][1].toLowerCase() == catalog_name + "_rename") { + x = 1 + } + } + assertTrue(x == 1) + + x = 0 + sql """ drop catalog ${catalog_name}_rename""" + result = sql """ show catalogs """ + for( int i =0 ;i < result.size();i++ ) { + assertTrue(result[i][1].toLowerCase() != "null") + if ( result[i][1].toLowerCase() == catalog_name + "_rename") { + x = 1 + } + } + assertTrue(x == 0) + } + test_catalogs() + + + +//show databases +//alter database $old_name rename $new_name +//create database $database_name + def test_databases = { + logger.info("TEST show/rename/drop databases") + def databases_name = "test_manager_db_case" + + + sql """ switch internal """ + sql """ drop database if exists ${databases_name} """ + sql """ drop database if exists ${databases_name}_rename """ + + sql """ create database ${databases_name} """ + List> result = sql """ show databases """ + + def x = 0 + for( int i =0 ;i < result.size();i++ ) { + assert(result[i].size() == 1) + assertTrue(result[i][0].toLowerCase() != "null") //Database + if ( result[i][0].toLowerCase() == databases_name) { + x = 1 + } + } + assertTrue(x == 1) + + x = 0 + sql """ alter database ${databases_name} rename ${databases_name}_rename """ + result = sql """ show databases """ + for( int i =0 ;i < result.size();i++ ) { + assertTrue(result[i][0].toLowerCase() != "null") + if ( result[i][0].toLowerCase() == databases_name + "_rename") { + x = 1 + } + } + assertTrue(x == 1) + + x = 0 + sql """ drop database ${databases_name}_rename""" + result = sql """ show databases """ + for( int i =0 ;i < result.size();i++ ) { + assertTrue(result[i][0].toLowerCase() != "null") + if ( result[i][0].toLowerCase() == databases_name + "_rename") { + x = 1 + } + } + assertTrue(x == 0) + } + test_databases() + + + + +// show tables && show tables like '$table_name' +//desc $table_name && desc $table_name all +//show create table '$table_name' +//drop tables + def test_show_tables = { + sql """ drop database if exists test_manager_tb_case """ + sql """create database test_manager_tb_case""" + sql """ use test_manager_tb_case """ + + List> result = sql """ show tables """ + assertTrue(result.size() == 0) + result = sql """ show tables like 'test_manager_tb%' """ + assertTrue(result.size() == 0) + + sql """ + create table test_manager_tb_1 + ( + k1 TINYINT, + k2 DECIMAL(10, 2) DEFAULT "10.05", + k3 CHAR(10) COMMENT "string column", + k4 INT NOT NULL DEFAULT "1" COMMENT "int column", + k5 STRING + ) COMMENT "manager_test_table" + DISTRIBUTED BY HASH(k1) BUCKETS 1 + PROPERTIES ('replication_num' = '1', + "bloom_filter_columns" = "k3,k5" + );""" + + qt_tables_1 """ desc test_manager_tb_1 """ + qt_tables_2 """ desc test_manager_tb_1 all""" + + + result = sql """ show tables """ + assertTrue(result.size() == 1) + assertTrue(result[0].size() == 1) + assertTrue(result[0][0].toLowerCase() == "test_manager_tb_1") + result = sql """ show tables like 'test_manager_tb%' """ + assertTrue(result.size() == 1) + assertTrue(result[0].size() == 1) + assertTrue(result[0][0].toLowerCase() == "test_manager_tb_1") + + + result = sql """ show create table test_manager_tb_1""" + assertTrue(result[0][0] == "test_manager_tb_1") // TABLE NAME + // assertTrue(result[0][1].substring() == "test_manager_tb_1") //DDL + def ddl_str = result[0][1] + def idx = ddl_str.indexOf("PROPERTIES") + assertTrue(idx != -1 ); + assertTrue( ddl_str.startsWith("""CREATE TABLE `test_manager_tb_1` ( + `k1` TINYINT NULL, + `k2` DECIMAL(10, 2) NULL DEFAULT "10.05", + `k3` CHAR(10) NULL COMMENT 'string column', + `k4` INT NOT NULL DEFAULT "1" COMMENT 'int column', + `k5` TEXT NULL +) ENGINE=OLAP +DUPLICATE KEY(`k1`, `k2`, `k3`) +COMMENT 'manager_test_table' +DISTRIBUTED BY HASH(`k1`) BUCKETS 1""")) + + sql """ drop table test_manager_tb_1 """ + result = sql """ show tables """ + assertTrue(result.size() == 0) + result = sql """ show tables like 'test_manager_tb%' """ + assertTrue(result.size() == 0) + + sql """ drop database test_manager_tb_case """ + } + test_show_tables() + + +//alter table $table_name set ("$key" = "$value") + def test_tables_PROPERTIES = { + sql """ drop database if exists test_manager_tb_properties_case FORCE""" + sql """create database test_manager_tb_properties_case""" + sql """ use test_manager_tb_properties_case """ + + + sql """ create table test_manager_tb_2 + ( + k1 TINYINT, + k2 DECIMAL(10, 2) DEFAULT "10.05", + k3 CHAR(10) COMMENT "string column", + k4 INT NOT NULL DEFAULT "1" COMMENT "int column", + k5 STRING + ) COMMENT "manager_test_table" + DISTRIBUTED BY HASH(k1) BUCKETS 1 + PROPERTIES ('replication_num' = '1', + "bloom_filter_columns" = "k3" + );""" + + List> result = sql """ show create table test_manager_tb_2 """ + assertTrue(result.size() == 1) + assertTrue(result[0][0] == "test_manager_tb_2") + def ddl_str = result[0][1] + def idx = ddl_str.indexOf("replication_allocation") + assertTrue( ddl_str.substring(idx,ddl_str.length()).startsWith("""replication_allocation" = "tag.location.default: 1""")) + + idx = ddl_str.indexOf("min_load_replica_num") + assertTrue( ddl_str.substring(idx,ddl_str.length()).startsWith("""min_load_replica_num" = "-1""")) + + sql """alter table test_manager_tb_2 set ("min_load_replica_num" = "1")""" + result = sql """ show create table test_manager_tb_2 """ + assertTrue(result[0][0] == "test_manager_tb_2") + ddl_str = result[0][1] + idx = ddl_str.indexOf("min_load_replica_num") + assertTrue( ddl_str.substring(idx,ddl_str.length()).startsWith("""min_load_replica_num" = "1""")) + + + + sql """ DROP table test_manager_tb_2 FORCE""" + sql """ drop database test_manager_tb_properties_case FORCE""" + + } + test_tables_PROPERTIES() + + +// show table status from $db_name like '$table_name' + def test_tables_status = { + + sql """ drop database if exists test_manager_tb_case_3 """ + sql """create database test_manager_tb_case_3 """ + sql """ use test_manager_tb_case_3 """ + + def formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + def now = LocalDateTime.now() + def formattedNow = now.format(formatter) + logger.info( " NOW TIME = ${formattedNow} " ) + + sql """ create table test_manager_tb + ( + k1 TINYINT, + k2 CHAR(10) COMMENT "string column", + k3 INT NOT NULL DEFAULT "1" COMMENT "int column", + ) COMMENT "manager_test_table" + DISTRIBUTED BY HASH(k1) BUCKETS 1 + PROPERTIES ('replication_num' = '1');""" + + + List> result = sql """ show table status from test_manager_tb_case_3 like 'test_manager_tb%' """ + println result[0][4] + assertTrue(result[0][4] == 0 )// Rows + + def create_time = result[0][11] //Create_time + def duration = Duration.between(now, create_time) + assertTrue(Math.abs(duration.toHours()) < 2) + logger.info( "table test_manager_tb Create TIME = ${create_time} " ) + + def update_time1 = result[0][12]//Update_time + duration = Duration.between(now, update_time1) + assertTrue(Math.abs(duration.toHours()) < 2) + logger.info( "table test_manager_tb Update TIME = ${update_time1} " ) + + assertTrue( "manager_test_table" == result[0][17] ) //Comment + + result = sql """ insert into test_manager_tb values (1,"hell0",10);""" + assertTrue(result[0][0] == 1) + result = sql """insert into test_manager_tb values (2,"hell0",20); """ + assertTrue(result[0][0] == 1) + result = sql """insert into test_manager_tb values (3,"hell0",30);""" + assertTrue(result[0][0] == 1) + result = sql """ insert into test_manager_tb values (4,"hell0",40);""" + assertTrue(result[0][0] == 1) + result = sql """ insert into test_manager_tb values (5,"hell0",50); """ + assertTrue(result[0][0] == 1) + + def j = 0 ; + def retryTime = 100; + for (j =0 ;j < retryTime;j++) { + sql """ select * from test_manager_tb_case_3.test_manager_tb; """ + result = sql """ show table status from test_manager_tb_case_3 like 'test_manager_tb%' """ + if ( result[0][4] == 5) { + assert( create_time == result[0][11])//Create_time + assertTrue( "manager_test_table" == result[0][17] ) //Comment + def update_time2 = result[0][12] //Update_time + duration = Duration.between(now, update_time2) + assertTrue(Math.abs(duration.toHours()) < 5) + logger.info( "table test_manager_tb Update TIME = ${update_time2} " ) + + break; + } + sleep(10000) + } + if (j == retryTime) { + + logger.info(" TEST show table status from $db_name like '$table_name';ROWS UPDATE FAIL."); + assertTrue(false); + } + + + + sql """ drop table test_manager_tb """ + sql """ drop database if exists test_manager_tb_case_3 """ + } + test_tables_status() + + + +//show index from '$table_name' + def test_table_index = { + sql """ drop database if exists test_manager_tb_case_4 """ + sql """create database test_manager_tb_case_4 """ + sql """ use test_manager_tb_case_4 """ + + sql """ + create table test_manager_tb + ( + k1 TINYINT, + k2 CHAR(10) COMMENT "string column", + k3 INT NOT NULL DEFAULT "1" COMMENT "int column", + ) COMMENT "manager_test_table" + DISTRIBUTED BY HASH(k1) BUCKETS 1 + PROPERTIES ('replication_num' = '1', + "bloom_filter_columns" = "k2");""" + + + + List> result = sql """ insert into test_manager_tb values (5,"hell0",50); """ + assertTrue(result[0][0] == 1) + result = sql """ insert into test_manager_tb values (5,"hell0",50); """ + assertTrue(result[0][0] == 1) + result = sql """ insert into test_manager_tb values (5,"hell0",50); """ + assertTrue(result[0][0] == 1) + result = sql """ insert into test_manager_tb values (5,"hell0",50); """ + assertTrue(result[0][0] == 1) + result = sql """ insert into test_manager_tb values (5,"hell0",50); """ + assertTrue(result[0][0] == 1) + + sql """ CREATE INDEX bitmap_index_name ON test_manager_tb (k1) USING BITMAP COMMENT 'bitmap_k1'; """ + + def j = 0 ; + def retryTime = 100; + for (j =0 ;j < retryTime;j++) { + result = sql """ show index from test_manager_tb; """ + + if (result.size() == 1){ + break; + } + sleep(1000); + } + + if (j == retryTime) { + logger.info(" TEST show index from '$table_name' FAIL."); + assertTrue(false); + } + + + + assertTrue(result[0][2] == "bitmap_index_name" )//Key_name + assertTrue(result[0][4] == "k1" )//Column_name + assertTrue(result[0][10] == "BITMAP" ) //BITMAP + assertTrue(result[0][11] == "bitmap_k1" ) //bitmap_siteid + + sql """ drop INDEX bitmap_index_name on test_manager_tb;""" + + + + + sql """ drop table test_manager_tb FORCE """ + sql """ drop database if exists test_manager_tb_case_4 FORCE""" + + } + test_table_index() + + + + + +//show proc '/current_query_stmts' +// show proc '/current_queries' +// show processlist +// kill query $query_id +// SHOW PROC '/cluster_health/tablet_health' + def test_proc = { + List> result = sql """ show proc '/current_query_stmts' """ + + result = sql """ show proc '/current_queries' """ + + + result = sql """ show processlist """ + for( int i =0 ;i < result.size();i++ ){ + assertTrue( result[i][2].toLowerCase() != "null" )//User + assertTrue( result[i][3].toLowerCase() != "null" )//Host + assertTrue( result[i][5].toLowerCase() != "null" )//Catalog + assertTrue( result[i][6].toLowerCase() != "null" )//Db + assertTrue( result[i][10].toLowerCase() != "null" )//QueryId + } + + def tablet_num = 0; + def healthy_num = 0; + def total_tablet_num = 0; + def total_healthy_num = 0; + result = sql """ SHOW PROC '/cluster_health/tablet_health' """ + for( int i =0 ;i < result.size();i++ ){ + assertTrue(result[i][0].toLowerCase() != null ) // DbId + if (result[i][0].toLowerCase() == "total") { + total_tablet_num = result[i][2].toInteger(); + total_healthy_num = result[i][3].toInteger(); + }else { + tablet_num += result[i][2].toInteger(); + healthy_num += result[i][3].toInteger(); + + } + // assertTrue(result[i][2]()) // TabletNum + // assertTrue(result[i][3]()) // HealthyNum + } + assertTrue(total_healthy_num == healthy_num ) + assertTrue(total_healthy_num == healthy_num ) + } + test_proc(); + + + +//select a.*, b.Name as WorkloadGroupName from active_queries() a left join workload_groups b on a.WORKLOAD_GROUP_ID = b.Id; +//select a.*, b.*, c.NAME as WORKLOAD_GROUP_NAME from information_schema.active_queries a left join information_schema.backend_active_tasks b on a.QUERY_ID = b.QUERY_ID left join information_schema.workload_groups c on a.WORKLOAD_GROUP_ID = c.ID + + def test_active_query = { + + List> result = sql """ select a.*,b.Name as WorkloadGroupName from information_schema.active_queries + a left join information_schema.workload_groups b on a.WORKLOAD_GROUP_ID = b.Id;""" + + result = sql """ + select a.*, b.*, c.NAME as WORKLOAD_GROUP_NAME from information_schema.active_queries a left join information_schema.backend_active_tasks b on a.QUERY_ID = b.QUERY_ID left join information_schema.workload_groups c on a.WORKLOAD_GROUP_ID = c.ID + """ + + // - QueryId + // - BeHost + // - BePort + // - StartTime + // - QueryTimeMs + // - WorkloadGroupName + // - ScanRows + // - Sql + // - ShuffleSendBytes + // - ShuffleSendRows + // - CurrentUsedMemoryBytes + // - QueryCpuTimeMs + + // *************************** 1. row *************************** + // QUERY_ID: 53bad1fbf51741df-8712f288eef9c503 + // QUERY_START_TIME: 2024-06-03 19:39:37 + // QUERY_TIME_MS: 17 + // WORKLOAD_GROUP_ID: 1 + // DATABASE: test_manager_tb_case_5 + // FRONTEND_INSTANCE: 172.22.0.1 + // QUEUE_START_TIME: 2024-06-03 19:39:37 + // QUEUE_END_TIME: 2024-06-03 19:39:37 + // QUERY_STATUS: RUNNING + // SQL: select a.*, b.*, c.NAME as WORKLOAD_GROUP_NAME from information_schema.active_queries a left join information_schema.backend_active_tasks b on a.QUERY_ID = b.QUERY_ID left join information_schema.workload_groups c on a.WORKLOAD_GROUP_ID = c.ID + // BE_ID: 10004 + // FE_HOST: 172.22.0.1 + // QUERY_ID: 53bad1fbf51741df-8712f288eef9c503 + // TASK_TIME_MS: 8 + // TASK_CPU_TIME_MS: 0 + // SCAN_ROWS: 0 + // SCAN_BYTES: 0 + // BE_PEAK_MEMORY_BYTES: 20480 + // CURRENT_USED_MEMORY_BYTES: 20480 + // SHUFFLE_SEND_BYTES: 0 + // SHUFFLE_SEND_ROWS: 0 + // QUERY_TYPE: SELECT + // WORKLOAD_GROUP_NAME: normal + + //缺少 + // - BeHost + // - BePort + for( int i =0 ;i < result.size();i++ ){ + assertTrue(result[i][0]) // QueryId + assertTrue(result[i][1]) // QUERY_START_TIME StartTime + assertTrue(result[i][2]) // QUERY_TIME_MS QueryTimeMs + assertTrue(result[i][11]) // SQL Sql + assertTrue(result[i][16]) // TASK_CPU_TIME_MS QueryCpuTimeMs + + + assertTrue(result[i][17]) // SCAN_ROWS ScanRows + assertTrue(result[i][21]) // SHUFFLE_SEND_BYTES ShuffleSendBytes + assertTrue(result[i][22]) // SHUFFLE_SEND_ROWS ShuffleSendRows + assertTrue(result[i][20]) // CURRENT_USED_MEMORY_BYTES CurrentUsedMemoryBytes + assertTrue(result[i][24]) // WORKLOAD_GROUP_NAME WorkloadGroupName + + } + + } + + + + + +//select * from __internal_schema.audit_log + def test_audit_log = { + + sql """ set global enable_audit_plugin = true; """ + List> result =sql """ show create table __internal_schema.audit_log; """ + + assertTrue(result[0][0] == "audit_log") + + assertTrue(result[0][1].contains("CREATE TABLE `audit_log`")) + assertTrue(result[0][1].contains("`query_id` VARCHAR(48) NULL,")) + assertTrue(result[0][1].contains("`time` DATETIME(3) NULL,")) + assertTrue(result[0][1].contains("`client_ip` VARCHAR(128) NULL,")) + assertTrue(result[0][1].contains("`user` VARCHAR(128) NULL,")) + assertTrue(result[0][1].contains("`catalog` VARCHAR(128) NULL")) + assertTrue(result[0][1].contains("`db` VARCHAR(128) NULL,")) + assertTrue(result[0][1].contains("`state` VARCHAR(128) NULL")) + assertTrue(result[0][1].contains("`error_code` INT NULL,")) + assertTrue(result[0][1].contains("`error_message` TEXT NULL,")) + assertTrue(result[0][1].contains("`query_time` BIGINT NULL,")) + assertTrue(result[0][1].contains("`scan_bytes` BIGINT NULL,")) + assertTrue(result[0][1].contains("`scan_rows` BIGINT NULL,")) + assertTrue(result[0][1].contains("`return_rows` BIGINT NULL,")) + assertTrue(result[0][1].contains("`stmt_id` BIGINT NULL,")) + assertTrue(result[0][1].contains("`is_query` TINYINT NULL,")) + assertTrue(result[0][1].contains("`frontend_ip` VARCHAR(128) NULL,")) + assertTrue(result[0][1].contains("`cpu_time_ms` BIGINT NULL,")) + assertTrue(result[0][1].contains("`sql_hash` VARCHAR(128) NULL,")) + assertTrue(result[0][1].contains("`sql_digest` VARCHAR(128) NULL,")) + assertTrue(result[0][1].contains("`peak_memory_bytes` BIGINT NULL,")) + assertTrue(result[0][1].contains("`workload_group` TEXT NULL,")) + assertTrue(result[0][1].contains("`stmt` TEXT NULL")) + + assertTrue(result[0][1].contains("ENGINE=OLAP")) + + assertTrue(result[0][1].contains("DUPLICATE KEY(`query_id`, `time`, `client_ip`)")) + assertTrue(result[0][1].contains("""PARTITION BY RANGE(`time`)""")) + assertTrue(result[0][1].contains("""dynamic_partition.enable" = "true""")) + assertTrue(result[0][1].contains("""dynamic_partition.time_unit" = "DAY""")) + assertTrue(result[0][1].contains("""dynamic_partition.start" = "-30""")) + + + sql """ set global enable_audit_plugin = false; """ + } + test_audit_log() + + +// admin show frontend config +//show frontend config +// admin set frontend config($key = $value) +// set global $key = $value +// show global variables like '%$key' +//show variables like "%version_comment%"; + def test_config = { + + List> result = sql """ + admin show frontend config + """ + def x = 0; + + def val = 0; + + for(int i = 0 ;i> result = sql """ show partitions from test_manager_tb """ + + for( int i =0 ; i > result = sql """ insert into test_manager_tb values (1,"hell0",10);""" + assertTrue(result[0][0] == 1) + result = sql """insert into test_manager_tb values (2,"hell0",20); """ + assertTrue(result[0][0] == 1) + result = sql """insert into test_manager_tb values (3,"hell0",30);""" + assertTrue(result[0][0] == 1) + result = sql """ insert into test_manager_tb values (4,"hell0",40);""" + assertTrue(result[0][0] == 1) + result = sql """ insert into test_manager_tb values (5,"hell0",50); """ + assertTrue(result[0][0] == 1) + + + + sql """ create table test_manager_tb_2 + ( + k1 TINYINT, + k2 CHAR(10) COMMENT "string column" + ) COMMENT "manager_test_load_table_2" + DISTRIBUTED BY HASH(k1) BUCKETS 1 + PROPERTIES ('replication_num' = '1');""" + + result = sql """ insert into test_manager_tb_2 values (1,"hell0");""" + assertTrue(result[0][0] == 1) + result = sql """insert into test_manager_tb_2 values (2,"hell0"); """ + assertTrue(result[0][0] == 1) + + result = sql """ show load from test_manager_load_case where state='FINISHED' """ + for(int i =0 ;i< result.size();i++) { + assertTrue(result[i][0].toLowerCase() != "null" )//JobId + assertTrue(result[i][0].toInteger() != 0 )//JobId + assertTrue(result[i][2] == "FINISHED") //State + assertTrue(result[i][3].contains( result[i][0]))// Progress + } + + + + + sql """ drop database if exists test_manager_load_case """ + } + test_load(); + + +// show backends +//alter system modify backend +// show frontends +// show broker +// ALTER TABLE internal.__internal_schema.column_statistics SET ("replication_num" = "1") + def test_system = { + + + def address = "127.0.0.1" + def notExistPort = 12346 + def notExistPort2 = 234567 + try { + sql """ALTER SYSTEM DROPP BACKEND "${address}:${notExistPort}";""" + }catch (Exception e) { + } + + sql """ALTER SYSTEM ADD BACKEND "${address}:${notExistPort}";""" + + result = sql """SHOW BACKENDS;""" + + def x = 0 + for(int i =0 ;i> result = sql """show all grants """ + def x = 0 + for(int i = 0;i < result.size(); i++ ) { + + // Roles: test_manager_role_grant_role1 + if ( result[i][3] == "${role1}") { + //UserIdentity: + println result[i][0] + if (result[i][0].contains("test_manager_role_grant_user1")){ + //DatabasePrivs + assertTrue(result[i][6] == "internal.information_schema: Select_priv; internal.mysql: Select_priv; internal.test_manager_role_grant_db: Select_priv,Create_priv,Drop_priv") + x ++ + }else if (result[i][0].contains("test_manager_role_grant_user2")) { + assertTrue(result[i][6] == "internal.information_schema: Select_priv; internal.mysql: Select_priv; internal.test_manager_role_grant_db: Select_priv,Load_priv,Drop_priv") + x ++ + + }else { + assertTrue(false." only ${user1} and ${user2}, no ${result[i][0]}") + } + } + else if ( result[i][3] =="admin"){ + if (result[i][0] == """'admin'@'%'"""){ + x++ + } + + } else if (result[i][3] =="operator") { + if (result[i][0] =="""'root'@'%'""" ){ + x++ + } + } + } + assertTrue(x == 4) + + sql """ revoke CREATE_PRIV on ${dbName} from '${user1}' """ + connect(user=user1, password="${pwd}", url=url) { + test { + sql """ create table test_manager_tb_2 ( + k1 TINYINT, + k2 CHAR(10) COMMENT "string column" + ) COMMENT "manager_test_table_2" + DISTRIBUTED BY HASH(k1) BUCKETS 1 + PROPERTIES ('replication_num' = '1'); + """ + exception "Access denied; you need (at least one of) the (CREATE) privilege(s) for this operation" + } + } + + sql """ revoke LOAD_PRIV on ${dbName} from '${user2}' """ + connect(user=user2, password="${pwd}", url=url) { + test{ + sql """ insert into test_manager_tb values(1,"2"); """ + exception """LOAD command denied to user""" + } + } + + result = sql """show all grants """ + x = 0 + for(int i = 0;i < result.size(); i++ ) { + + // Roles: test_manager_role_grant_role1 + if ( result[i][3] == "${role1}") { + //UserIdentity: + println result[i][0] + if (result[i][0].contains("test_manager_role_grant_user1")){ + //DatabasePrivs + assertTrue(result[i][6] == "internal.information_schema: Select_priv; internal.mysql: Select_priv; internal.test_manager_role_grant_db: Select_priv,Drop_priv") + x ++ + }else if (result[i][0].contains("test_manager_role_grant_user2")) { + assertTrue(result[i][6].contains("internal.information_schema: Select_priv; internal.mysql: Select_priv; internal.test_manager_role_grant_db: Select_priv,Drop_priv")) + x ++ + + }else { + assertTrue(false." only ${user1} and ${user2}, no ${result[i][0]}") + } + } + else if ( result[i][3] =="admin"){ + if (result[i][0] == """'admin'@'%'"""){ + x++ + } + + } else if (result[i][3] =="operator") { + if (result[i][0] =="""'root'@'%'""" ){ + x++ + } + } + } + assertTrue(x == 4) + + + result = sql """show grants """ + x = 0 + for(int i = 0;i < result.size(); i++ ) { + if (result[i][3] =="operator") { + if (result[i][0] =="""'root'@'%'""" ){ + if (result[i][6] == "internal.information_schema: Select_priv; internal.mysql: Select_priv"){ + assertTrue(result[i][4]=="Node_priv,Admin_priv") + x++ + + } + } + } + } + assertTrue(x == 1) + + result = sql """show roles """ + x = 0 + for(int i = 0;i < result.size(); i++ ) { + //NAME + assertTrue(result[i][0].toLowerCase() != "null") + + if (result[i][0] =="test_manager_role_grant_role1") { + //Users + assertTrue(result[i][2].contains("test_manager_role_grant_user2'@'%")) + assertTrue(result[i][2].contains("test_manager_role_grant_user1'@'%")) + x ++ + }else if (result[i][0] == "admin"){ + assertTrue(result[i][2].contains("admin'@'%")) + x ++ + }else if (result[i][0] == "operator"){ + assertTrue(result[i][2].contains("root'@'%")) + x++ + } + } + assertTrue(x == 3) + + + + + sql """revoke DROP_PRIV on ${dbName} FROM ROLE '${role1}' """ + sql """create table ${dbName}.test_manager_tb_2 ( + k1 TINYINT, + k2 CHAR(10) COMMENT "string column" + ) COMMENT "manager_test_table_2" + DISTRIBUTED BY HASH(k1) BUCKETS 1 + PROPERTIES ('replication_num' = '1');""" + + + connect(user=user1, password="${pwd}", url=url) { + test { + sql """ Drop table ${dbName}.test_manager_tb_2""" + exception "Access denied; you need (at least one of) the (DROP) privilege(s) for this operation" + } + } + + connect(user=user2, password="${pwd}", url=url) { + test{ + sql """ Drop table ${dbName}.test_manager_tb_2""" + exception "Access denied; you need (at least one of) the (DROP) privilege(s) for this operation" + } + } + + sql """set password for '${user2}' = password('${new_pwd}')""" + try { + connect(user =user2, password = '${pwd}', url = url) {} + assertTrue(false. "should not be able to login") + } catch (Exception e) { + assertTrue(e.getMessage().contains("Access denied for user"), e.getMessage()) + } + + connect(user=user2, password="${new_pwd}", url=url) { + result = sql """ select k1 from ${dbName}.${tbName} order by k1 desc limit 1""" + assertTrue(result[0][0] == 3) + + + result = sql """ select * from ${dbName}.${tbName} order by k1""" + assertTrue(result[0][0] ==1) + assertTrue(result[0][1] =="abc") + + assertTrue(result[1][0] ==2) + assertTrue(result[1][1] =="adc") + + assertTrue(result[2][0] ==3) + assertTrue(result[2][1] =="ttt") + } + + + sql """ revoke "${role1}" from "${user2}" """ + + try { + connect(user =user2, password = '${pwd}', url = url) {} + assertTrue(false. "should not be able to login") + } catch (Exception e) { + assertTrue(e.getMessage().contains("Access denied for user"), e.getMessage()) + } + + sql """ drop database ${dbName} """ + sql """ drop database ${dbName2} """ + + sql """drop user ${user1}""" + sql """drop user ${user2}""" + sql """drop role ${role1}""" + + } + test_role_grant() + + + + +// grant $privileges on resource $resource_name to $user +// grant $privileges on resource $resource_name to role $role_name +// revoke $privileges on resource $resource_name from $user_name + def test_resource = { + def user = 'test_manager_resource_user' + def role = 'test_manager_resource_role' + def resource_name = "test_manager_resource_case" + def pwd = "123456" + def tokens = context.config.jdbcUrl.split('/') + def url=tokens[0] + "//" + tokens[2] + "/" + "?" + + sql """ drop RESOURCE if exists ${resource_name} """ + sql """ CREATE RESOURCE ${resource_name} PROPERTIES( + "user" = "${jdbcUser}", + "type" = "jdbc", + "password" = "${jdbcPassword}", + "jdbc_url" = "${jdbcUrl}", + "driver_url" = "${driver_url}", + "driver_class" = "com.mysql.cj.jdbc.Driver" + )""" + + + + sql """drop user if exists ${user}""" + sql """drop role if exists ${role}""" + + sql """CREATE ROLE ${role}""" + sql """grant USAGE_PRIV on RESOURCE ${resource_name} TO ROLE '${role}' """ + + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}' default role '${role}' """ + + List> result = sql """ show resources """ + + def x = 0 + for(int i = 0;i show resources where name = "test_manager_resource_case"\G ; + *************************** 1. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: test_connection + Value: true + *************************** 2. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: driver_class + Value: com.mysql.cj.jdbc.Driver + *************************** 3. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: connection_pool_max_size + Value: 10 + *************************** 4. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: connection_pool_max_life_time + Value: 1800000 + *************************** 5. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: create_time + Value: 2024-06-04 17:35:19.097481994 + *************************** 6. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: meta_names_mapping + Value: + *************************** 7. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: only_specified_database + Value: false + *************************** 8. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: driver_url + Value: mysql-connector-java-8.0.25.jar + *************************** 9. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: type + Value: jdbc + *************************** 10. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: connection_pool_min_size + Value: 1 + *************************** 11. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: jdbc_url + Value: jdbc:mysql://127.0.0.1:55557/?&yearIsDateType=false&tinyInt1isBit=false&useUnicode=true&rewriteBatchedStatements=true&characterEncoding=utf-8 + *************************** 12. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: lower_case_meta_names + Value: false + *************************** 13. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: connection_pool_max_wait_time + Value: 5000 + *************************** 14. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: password + Value: + *************************** 15. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: use_meta_cache + Value: false + *************************** 16. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: exclude_database_list + Value: + *************************** 17. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: include_database_list + Value: + *************************** 18. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: checksum + Value: fdf55dcef04b09f2eaf42b75e61ccc9a + *************************** 19. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: connection_pool_keep_alive + Value: false + *************************** 20. row *************************** + Name: test_manager_resource_case + ResourceType: jdbc + Item: user + Value: root + 20 rows in set (0.00 sec) + */ + + } + test_resource() + + +// show property like '%$resource_tag%' +// show property for $user like '%$resource_tag%' +// set property for $user 'resource_tags.location' = '$tags' + def test_property = { + def user = 'test_manager_property_user' + def pwd = "123456" + def tokens = context.config.jdbcUrl.split('/') + def url=tokens[0] + "//" + tokens[2] + "/" + "?" + + sql """drop user if exists ${user}""" + + sql """CREATE USER '${user}' IDENTIFIED BY '${pwd}'""" + + connect(user=user, password="${pwd}", url=url) { + List> result = sql """ show property like "max_query_instances" """ + assertTrue(result[0][0]=="max_query_instances") + assertTrue(result[0][1]=="-1") + } + + List> result = sql """ show property for ${user} like "max_query_instances" """ + assertTrue(result[0][0]=="max_query_instances") + assertTrue(result[0][1]=="-1") + + sql """ set property for ${user} 'max_query_instances' ="100000"; """ + result = sql """ show property for ${user} like "max_query_instances" """ + assertTrue(result[0][0]=="max_query_instances") + assertTrue(result[0][1]=="100000") + + sql """ drop user ${user} """ + } + test_property() + + +} From 973e3db1cee1323aef205dfcbb64bf000c82a960 Mon Sep 17 00:00:00 2001 From: daidai <2017501503@qq.com> Date: Wed, 5 Jun 2024 20:58:36 +0800 Subject: [PATCH 2/2] append other case. --- .../data/manager/test_manager_interface_1.out | 8 + .../manager/test_manager_interface_1.groovy | 240 ++++++++++++------ .../manager/test_manager_interface_2.groovy | 24 +- .../manager/test_manager_interface_3.groovy | 5 +- 4 files changed, 177 insertions(+), 100 deletions(-) diff --git a/regression-test/data/manager/test_manager_interface_1.out b/regression-test/data/manager/test_manager_interface_1.out index 182dae7bea530e..0f50524d648565 100644 --- a/regression-test/data/manager/test_manager_interface_1.out +++ b/regression-test/data/manager/test_manager_interface_1.out @@ -1,4 +1,12 @@ -- This file is automatically generated. You should know what you did if you want to edit this +-- !metadata_1 -- +internal test_manager_metadata_name_ids \N + +-- !metadata_2 -- +internal test_manager_metadata_name_ids test_metadata_name_ids + +-- !metadata_2 -- + -- !tables_1 -- k1 TINYINT Yes true \N k2 DECIMAL(10, 2) Yes true 10.05 diff --git a/regression-test/suites/manager/test_manager_interface_1.groovy b/regression-test/suites/manager/test_manager_interface_1.groovy index 44f0e478a4e570..43cdc9383ec9d2 100644 --- a/regression-test/suites/manager/test_manager_interface_1.groovy +++ b/regression-test/suites/manager/test_manager_interface_1.groovy @@ -93,10 +93,35 @@ suite('test_manager_interface_1',"p0") { test_information_tables() //select * from information_schema.metadata_name_ids - def metadata_name_ids = { + def test_metadata_name_ids = { logger.info("TEST select * from information_schema.metadata_name_ids") List> result = sql """select * from information_schema.metadata_name_ids """ + def tableName = "internal.information_schema.metadata_name_ids" + sql """ create database if not exists test_manager_metadata_name_ids; """ + sql """ use test_manager_metadata_name_ids ; """ + + qt_metadata_1 """ select CATALOG_NAME,DATABASE_NAME,TABLE_NAME from ${tableName} + where CATALOG_NAME="internal" and DATABASE_NAME ="test_manager_metadata_name_ids" """ + + sql """ create table if not exists test_metadata_name_ids ( + a int , + b varchar(30) + ) + DUPLICATE KEY(`a`) + DISTRIBUTED BY HASH(`a`) BUCKETS 10 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); """ + + qt_metadata_2 """ select CATALOG_NAME,DATABASE_NAME,TABLE_NAME from ${tableName} + where CATALOG_NAME="internal" and DATABASE_NAME ="test_manager_metadata_name_ids" """ + + sql """ drop table test_metadata_name_ids """ + + qt_metadata_2 """ select CATALOG_NAME,DATABASE_NAME,TABLE_NAME from ${tableName} + where CATALOG_NAME="internal" and DATABASE_NAME ="test_manager_metadata_name_ids" and TABLE_NAME="test_metadata_name_ids";""" } + test_metadata_name_ids() @@ -473,25 +498,93 @@ DISTRIBUTED BY HASH(`k1`) BUCKETS 1""")) -//show proc '/current_query_stmts' +// show proc '/current_query_stmts' // show proc '/current_queries' // show processlist // kill query $query_id // SHOW PROC '/cluster_health/tablet_health' def test_proc = { - List> result = sql """ show proc '/current_query_stmts' """ - result = sql """ show proc '/current_queries' """ + def futures = [] + + futures.add( thread { + + try{ + sql """ select sleep(9809); """ + }catch(Exception e){ + + } + }) + futures.add( thread { + sleep(1000); + List> result = sql """ show proc '/current_query_stmts' """ + def x = 0 + def queryid = "" + logger.info("result = ${result}") + + for( int i = 0;i> result = sql """ select a.*,b.Name as WorkloadGroupName from information_schema.active_queries - a left join information_schema.workload_groups b on a.WORKLOAD_GROUP_ID = b.Id;""" - - result = sql """ - select a.*, b.*, c.NAME as WORKLOAD_GROUP_NAME from information_schema.active_queries a left join information_schema.backend_active_tasks b on a.QUERY_ID = b.QUERY_ID left join information_schema.workload_groups c on a.WORKLOAD_GROUP_ID = c.ID - """ - - // - QueryId - // - BeHost - // - BePort - // - StartTime - // - QueryTimeMs - // - WorkloadGroupName - // - ScanRows - // - Sql - // - ShuffleSendBytes - // - ShuffleSendRows - // - CurrentUsedMemoryBytes - // - QueryCpuTimeMs - - // *************************** 1. row *************************** - // QUERY_ID: 53bad1fbf51741df-8712f288eef9c503 - // QUERY_START_TIME: 2024-06-03 19:39:37 - // QUERY_TIME_MS: 17 - // WORKLOAD_GROUP_ID: 1 - // DATABASE: test_manager_tb_case_5 - // FRONTEND_INSTANCE: 172.22.0.1 - // QUEUE_START_TIME: 2024-06-03 19:39:37 - // QUEUE_END_TIME: 2024-06-03 19:39:37 - // QUERY_STATUS: RUNNING - // SQL: select a.*, b.*, c.NAME as WORKLOAD_GROUP_NAME from information_schema.active_queries a left join information_schema.backend_active_tasks b on a.QUERY_ID = b.QUERY_ID left join information_schema.workload_groups c on a.WORKLOAD_GROUP_ID = c.ID - // BE_ID: 10004 - // FE_HOST: 172.22.0.1 - // QUERY_ID: 53bad1fbf51741df-8712f288eef9c503 - // TASK_TIME_MS: 8 - // TASK_CPU_TIME_MS: 0 - // SCAN_ROWS: 0 - // SCAN_BYTES: 0 - // BE_PEAK_MEMORY_BYTES: 20480 - // CURRENT_USED_MEMORY_BYTES: 20480 - // SHUFFLE_SEND_BYTES: 0 - // SHUFFLE_SEND_ROWS: 0 - // QUERY_TYPE: SELECT - // WORKLOAD_GROUP_NAME: normal - - //缺少 - // - BeHost - // - BePort - for( int i =0 ;i < result.size();i++ ){ - assertTrue(result[i][0]) // QueryId - assertTrue(result[i][1]) // QUERY_START_TIME StartTime - assertTrue(result[i][2]) // QUERY_TIME_MS QueryTimeMs - assertTrue(result[i][11]) // SQL Sql - assertTrue(result[i][16]) // TASK_CPU_TIME_MS QueryCpuTimeMs + List> result = sql """ select 1;""" - assertTrue(result[i][17]) // SCAN_ROWS ScanRows - assertTrue(result[i][21]) // SHUFFLE_SEND_BYTES ShuffleSendBytes - assertTrue(result[i][22]) // SHUFFLE_SEND_ROWS ShuffleSendRows - assertTrue(result[i][20]) // CURRENT_USED_MEMORY_BYTES CurrentUsedMemoryBytes - assertTrue(result[i][24]) // WORKLOAD_GROUP_NAME WorkloadGroupName + def futures = [] + futures.add( thread { + + try{ + sql """ select sleep(87676); """ + }catch(Exception e){ + } + }) - } + futures.add( thread { + sleep(3000) + result = sql """ + select a.*, b.*, c.NAME as WORKLOAD_GROUP_NAME from information_schema.active_queries a left join + information_schema.backend_active_tasks b on a.QUERY_ID = b.QUERY_ID left join information_schema.workload_groups c on a.WORKLOAD_GROUP_ID = c.ID + """ + logger.info("result = ${result}") + + def x = 0 + def queryId = "" + for( int i =0 ;i < result.size();i++ ){ + assertTrue(result[i][0] != null ) // QueryId + + if ( result[i][9].contains("sleep(87676)") ){ + x = 1 + queryId = result[i][0] + logger.info("result = ${queryId}}") + + assertTrue(result[i][2]!=null) // QUERY_TIME_MS + assertTrue(result[i][14]!=null) // TASK_CPU_TIME_MS + assertTrue(result[i][15].toBigInteger() ==0 ) // SCAN_ROWS + assertTrue(result[i][16].toBigInteger() ==0)//SCAN_BYTES + assertTrue(result[i][19].toBigInteger() ==0) // SHUFFLE_SEND_BYTES + assertTrue(result[i][20].toBigInteger() ==0) // SHUFFLE_SEND_ROWS + assertTrue(result[i][18]!=null) // CURRENT_USED_MEMORY_BYTES + assertTrue(result[i][22]!=null) // WORKLOAD_GROUP_NAME + } + } + assertTrue(x == 1) + sql """ kill query "${queryId}" """ + }) + futures.each { it.get() } } - - + test_active_query() @@ -657,7 +731,7 @@ DISTRIBUTED BY HASH(`k1`) BUCKETS 1""")) for(int i = 0 ;i