2024-09-27 10:19:39 +00:00
import threading
import time
2018-05-14 11:10:07 +00:00
from contextlib import contextmanager
## sudo -H pip install PyMySQL
import pymysql . cursors
2020-09-16 04:26:10 +00:00
import pytest
2024-09-27 10:19:39 +00:00
2021-09-02 19:32:32 +00:00
from helpers . client import QueryRuntimeException
2024-09-27 10:19:39 +00:00
from helpers . cluster import ClickHouseCluster
2018-05-14 11:10:07 +00:00
cluster = ClickHouseCluster ( __file__ )
2022-03-22 16:39:58 +00:00
node1 = cluster . add_instance (
" node1 " ,
main_configs = [ " configs/remote_servers.xml " , " configs/named_collections.xml " ] ,
2023-06-08 18:30:34 +00:00
user_configs = [ " configs/users.xml " ] ,
2024-02-13 12:15:46 +00:00
with_mysql8 = True ,
2022-03-22 16:39:58 +00:00
)
node2 = cluster . add_instance (
" node2 " , main_configs = [ " configs/remote_servers.xml " ] , with_mysql_cluster = True
)
node3 = cluster . add_instance (
" node3 " ,
main_configs = [ " configs/remote_servers.xml " ] ,
user_configs = [ " configs/users.xml " ] ,
2024-02-13 12:15:46 +00:00
with_mysql8 = True ,
2022-03-22 16:39:58 +00:00
)
2021-03-31 17:04:57 +00:00
2019-12-12 12:17:27 +00:00
create_table_sql_template = """
2018-05-14 11:10:07 +00:00
CREATE TABLE ` clickhouse ` . ` { } ` (
` id ` int ( 11 ) NOT NULL ,
` name ` varchar ( 50 ) NOT NULL ,
` age ` int NOT NULL default 0 ,
` money ` int NOT NULL default 0 ,
2020-06-27 01:22:01 +00:00
` source ` enum ( ' IP ' , ' URL ' ) DEFAULT ' IP ' ,
2018-05-14 11:10:07 +00:00
PRIMARY KEY ( ` id ` ) ) ENGINE = InnoDB ;
"""
2021-06-21 15:42:40 +00:00
drop_table_sql_template = """
DROP TABLE IF EXISTS ` clickhouse ` . ` { } ` ;
"""
2021-03-24 18:15:31 +00:00
2022-03-22 16:39:58 +00:00
2021-06-21 15:42:40 +00:00
def get_mysql_conn ( started_cluster , host ) :
2022-03-22 16:39:58 +00:00
conn = pymysql . connect (
2024-02-13 12:15:46 +00:00
user = " root " , password = " clickhouse " , host = host , port = started_cluster . mysql8_port
2022-03-22 16:39:58 +00:00
)
2021-06-21 15:42:40 +00:00
return conn
2021-03-24 18:15:31 +00:00
2022-03-22 16:39:58 +00:00
2021-03-24 18:15:31 +00:00
def create_mysql_table ( conn , tableName ) :
with conn . cursor ( ) as cursor :
cursor . execute ( create_table_sql_template . format ( tableName ) )
2022-03-22 16:39:58 +00:00
2021-06-21 15:42:40 +00:00
def drop_mysql_table ( conn , tableName ) :
with conn . cursor ( ) as cursor :
cursor . execute ( drop_table_sql_template . format ( tableName ) )
2022-03-22 16:39:58 +00:00
2021-06-21 15:42:40 +00:00
def create_mysql_db ( conn , name ) :
with conn . cursor ( ) as cursor :
cursor . execute ( " DROP DATABASE IF EXISTS {} " . format ( name ) )
cursor . execute ( " CREATE DATABASE {} DEFAULT CHARACTER SET ' utf8 ' " . format ( name ) )
2019-12-12 12:17:27 +00:00
2018-05-14 11:10:07 +00:00
@pytest.fixture ( scope = " module " )
def started_cluster ( ) :
try :
cluster . start ( )
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( cluster , cluster . mysql8_ip )
2022-03-22 16:39:58 +00:00
create_mysql_db ( conn , " clickhouse " )
2021-04-08 09:30:24 +00:00
2018-05-14 11:10:07 +00:00
## create mysql db and table
2021-04-08 09:30:24 +00:00
conn1 = get_mysql_conn ( cluster , cluster . mysql2_ip )
2022-03-22 16:39:58 +00:00
create_mysql_db ( conn1 , " clickhouse " )
2018-05-14 11:10:07 +00:00
yield cluster
finally :
cluster . shutdown ( )
2020-09-25 11:12:48 +00:00
def test_many_connections ( started_cluster ) :
2022-03-22 16:39:58 +00:00
table_name = " test_many_connections "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2021-06-21 15:42:40 +00:00
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2021-06-21 15:42:40 +00:00
drop_mysql_table ( conn , table_name )
2020-09-25 11:12:48 +00:00
create_mysql_table ( conn , table_name )
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2024-02-13 12:15:46 +00:00
CREATE TABLE { } ( id UInt32 , name String , age UInt32 , money UInt32 ) ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' ) ;
2022-03-22 16:39:58 +00:00
""" .format(
table_name , table_name
)
)
2020-09-25 11:12:48 +00:00
2022-03-22 16:39:58 +00:00
node1 . query (
" INSERT INTO {} (id, name) SELECT number, concat( ' name_ ' , toString(number)) from numbers(10) " . format (
table_name
)
)
2020-09-25 11:12:48 +00:00
query = " SELECT count() FROM ( "
2022-03-22 16:39:58 +00:00
for i in range ( 24 ) :
2020-09-25 11:12:48 +00:00
query + = " SELECT id FROM {t} UNION ALL "
query + = " SELECT id FROM {t} ) "
2022-03-22 16:39:58 +00:00
assert node1 . query ( query . format ( t = table_name ) ) == " 250 \n "
2021-06-21 15:42:40 +00:00
drop_mysql_table ( conn , table_name )
2020-09-25 11:12:48 +00:00
conn . close ( )
2021-03-24 18:15:31 +00:00
2018-05-14 11:10:07 +00:00
def test_insert_select ( started_cluster ) :
2022-03-22 16:39:58 +00:00
table_name = " test_insert_select "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2021-06-21 15:42:40 +00:00
drop_mysql_table ( conn , table_name )
2018-05-14 11:10:07 +00:00
create_mysql_table ( conn , table_name )
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2024-02-13 12:15:46 +00:00
CREATE TABLE { } ( id UInt32 , name String , age UInt32 , money UInt32 ) ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' ) ;
2022-03-22 16:39:58 +00:00
""" .format(
table_name , table_name
)
)
2020-09-16 04:26:10 +00:00
node1 . query (
" INSERT INTO {} (id, name, money) select number, concat( ' name_ ' , toString(number)), 3 from numbers(10000) " . format (
2022-03-22 16:39:58 +00:00
table_name
)
)
assert node1 . query ( " SELECT count() FROM {} " . format ( table_name ) ) . rstrip ( ) == " 10000 "
assert (
node1 . query ( " SELECT sum(money) FROM {} " . format ( table_name ) ) . rstrip ( ) == " 30000 "
)
2018-05-14 11:10:07 +00:00
conn . close ( )
def test_replace_select ( started_cluster ) :
2022-03-22 16:39:58 +00:00
table_name = " test_replace_select "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2021-06-21 15:42:40 +00:00
drop_mysql_table ( conn , table_name )
2018-05-14 11:10:07 +00:00
create_mysql_table ( conn , table_name )
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2024-02-13 12:15:46 +00:00
CREATE TABLE { } ( id UInt32 , name String , age UInt32 , money UInt32 ) ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' , 1 ) ;
2022-03-22 16:39:58 +00:00
""" .format(
table_name , table_name
)
)
2020-09-16 04:26:10 +00:00
node1 . query (
" INSERT INTO {} (id, name, money) select number, concat( ' name_ ' , toString(number)), 3 from numbers(10000) " . format (
2022-03-22 16:39:58 +00:00
table_name
)
)
2020-09-16 04:26:10 +00:00
node1 . query (
" INSERT INTO {} (id, name, money) select number, concat( ' name_ ' , toString(number)), 3 from numbers(10000) " . format (
2022-03-22 16:39:58 +00:00
table_name
)
)
assert node1 . query ( " SELECT count() FROM {} " . format ( table_name ) ) . rstrip ( ) == " 10000 "
assert (
node1 . query ( " SELECT sum(money) FROM {} " . format ( table_name ) ) . rstrip ( ) == " 30000 "
)
2018-05-14 11:10:07 +00:00
conn . close ( )
def test_insert_on_duplicate_select ( started_cluster ) :
2022-03-22 16:39:58 +00:00
table_name = " test_insert_on_duplicate_select "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2021-06-21 15:42:40 +00:00
drop_mysql_table ( conn , table_name )
2018-05-14 11:10:07 +00:00
create_mysql_table ( conn , table_name )
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2024-02-13 12:15:46 +00:00
CREATE TABLE { } ( id UInt32 , name String , age UInt32 , money UInt32 ) ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' , 0 , ' update money = money + values(money) ' ) ;
2022-03-22 16:39:58 +00:00
""" .format(
table_name , table_name
)
)
2020-09-16 04:26:10 +00:00
node1 . query (
" INSERT INTO {} (id, name, money) select number, concat( ' name_ ' , toString(number)), 3 from numbers(10000) " . format (
2022-03-22 16:39:58 +00:00
table_name
)
)
2020-09-16 04:26:10 +00:00
node1 . query (
" INSERT INTO {} (id, name, money) select number, concat( ' name_ ' , toString(number)), 3 from numbers(10000) " . format (
2022-03-22 16:39:58 +00:00
table_name
)
)
assert node1 . query ( " SELECT count() FROM {} " . format ( table_name ) ) . rstrip ( ) == " 10000 "
assert (
node1 . query ( " SELECT sum(money) FROM {} " . format ( table_name ) ) . rstrip ( ) == " 60000 "
)
2018-05-14 11:10:07 +00:00
conn . close ( )
2019-12-12 12:17:27 +00:00
2018-10-08 15:05:23 +00:00
def test_where ( started_cluster ) :
2022-03-22 16:39:58 +00:00
table_name = " test_where "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2021-06-21 15:42:40 +00:00
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2021-06-21 15:42:40 +00:00
drop_mysql_table ( conn , table_name )
2018-10-08 15:05:23 +00:00
create_mysql_table ( conn , table_name )
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2024-02-13 12:15:46 +00:00
CREATE TABLE { } ( id UInt32 , name String , age UInt32 , money UInt32 ) ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' ) ;
2022-03-22 16:39:58 +00:00
""" .format(
table_name , table_name
)
)
2020-09-16 04:26:10 +00:00
node1 . query (
" INSERT INTO {} (id, name, money) select number, concat( ' name_ ' , toString(number)), 3 from numbers(10000) " . format (
2022-03-22 16:39:58 +00:00
table_name
)
)
assert (
node1 . query (
" SELECT count() FROM {} WHERE name LIKE ' % name_ % ' " . format ( table_name )
) . rstrip ( )
== " 10000 "
)
assert (
node1 . query (
" SELECT count() FROM {} WHERE name NOT LIKE ' % tmp_ % ' " . format ( table_name )
) . rstrip ( )
== " 10000 "
)
assert (
node1 . query (
" SELECT count() FROM {} WHERE money IN (1, 2, 3) " . format ( table_name )
) . rstrip ( )
== " 10000 "
)
assert (
node1 . query (
" SELECT count() FROM {} WHERE money IN (1, 2, 4, 5, 6) " . format ( table_name )
) . rstrip ( )
== " 0 "
)
assert (
node1 . query (
" SELECT count() FROM {} WHERE money NOT IN (1, 2, 4, 5, 6) " . format (
table_name
)
) . rstrip ( )
== " 10000 "
)
assert (
node1 . query (
" SELECT count() FROM {} WHERE name LIKE concat( ' name_ ' , toString(1)) " . format (
table_name
)
) . rstrip ( )
== " 1 "
)
2018-10-08 15:05:23 +00:00
conn . close ( )
2018-05-14 11:10:07 +00:00
2019-12-12 12:17:27 +00:00
def test_table_function ( started_cluster ) :
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2022-03-22 16:39:58 +00:00
drop_mysql_table ( conn , " table_function " )
create_mysql_table ( conn , " table_function " )
table_function = (
2024-02-13 12:15:46 +00:00
" mysql( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' ) " . format (
2022-03-22 16:39:58 +00:00
" table_function "
)
)
assert node1 . query ( " SELECT count() FROM {} " . format ( table_function ) ) . rstrip ( ) == " 0 "
2020-09-16 04:26:10 +00:00
node1 . query (
" INSERT INTO {} (id, name, money) select number, concat( ' name_ ' , toString(number)), 3 from numbers(10000) " . format (
2022-03-22 16:39:58 +00:00
" TABLE FUNCTION " + table_function
)
)
assert (
node1 . query ( " SELECT count() FROM {} " . format ( table_function ) ) . rstrip ( ) == " 10000 "
)
assert (
node1 . query (
" SELECT sum(c) FROM ( "
" SELECT count() as c FROM {} WHERE id % 3 == 0 "
" UNION ALL SELECT count() as c FROM {} WHERE id % 3 == 1 "
" UNION ALL SELECT count() as c FROM {} WHERE id % 3 == 2) " . format (
table_function , table_function , table_function
)
) . rstrip ( )
== " 10000 "
)
assert (
node1 . query ( " SELECT sum(`money`) FROM {} " . format ( table_function ) ) . rstrip ( )
== " 30000 "
)
node1 . query (
" INSERT INTO {} (id, name, age, money) SELECT id + 100000, name, age, money FROM {} " . format (
" TABLE FUNCTION " + table_function , table_function
)
)
assert (
node1 . query ( " SELECT sum(`money`) FROM {} " . format ( table_function ) ) . rstrip ( )
== " 60000 "
)
2019-12-12 12:17:27 +00:00
conn . close ( )
2021-03-24 18:15:31 +00:00
2023-05-19 00:44:27 +00:00
def test_schema_inference ( started_cluster ) :
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2023-05-19 00:44:27 +00:00
drop_mysql_table ( conn , " inference_table " )
with conn . cursor ( ) as cursor :
cursor . execute (
" CREATE TABLE clickhouse.inference_table (id INT PRIMARY KEY, data BINARY(16) NOT NULL) "
)
2024-02-13 12:15:46 +00:00
parameters = " ' mysql80:3306 ' , ' clickhouse ' , ' inference_table ' , ' root ' , ' clickhouse ' "
2023-05-19 00:44:27 +00:00
node1 . query (
f " CREATE TABLE mysql_schema_inference_engine ENGINE=MySQL( { parameters } ) "
)
node1 . query ( f " CREATE TABLE mysql_schema_inference_function AS mysql( { parameters } ) " )
expected = " id \t Int32 \t \t \t \t \t \n data \t FixedString(16) \t \t \t \t \t \n "
assert node1 . query ( " DESCRIBE TABLE mysql_schema_inference_engine " ) == expected
assert node1 . query ( " DESCRIBE TABLE mysql_schema_inference_function " ) == expected
node1 . query ( " DROP TABLE mysql_schema_inference_engine " )
node1 . query ( " DROP TABLE mysql_schema_inference_function " )
drop_mysql_table ( conn , " inference_table " )
2020-12-28 20:21:57 +00:00
def test_binary_type ( started_cluster ) :
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2022-03-22 16:39:58 +00:00
drop_mysql_table ( conn , " binary_type " )
2021-06-21 15:42:40 +00:00
2020-12-28 20:21:57 +00:00
with conn . cursor ( ) as cursor :
2022-03-22 16:39:58 +00:00
cursor . execute (
" CREATE TABLE clickhouse.binary_type (id INT PRIMARY KEY, data BINARY(16) NOT NULL) "
)
table_function = (
2024-02-13 12:15:46 +00:00
" mysql( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' ) " . format (
2022-03-22 16:39:58 +00:00
" binary_type "
)
)
node1 . query (
" INSERT INTO {} VALUES (42, ' clickhouse ' ) " . format (
" TABLE FUNCTION " + table_function
)
)
assert (
node1 . query ( " SELECT * FROM {} " . format ( table_function ) )
== " 42 \t clickhouse \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \n "
)
2023-05-19 00:44:27 +00:00
drop_mysql_table ( conn , " binary_type " )
2019-12-12 12:17:27 +00:00
2021-03-24 18:15:31 +00:00
2020-06-27 01:22:01 +00:00
def test_enum_type ( started_cluster ) :
2022-03-22 16:39:58 +00:00
table_name = " test_enum_type "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2021-06-21 15:42:40 +00:00
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2021-06-21 15:42:40 +00:00
drop_mysql_table ( conn , table_name )
2020-06-27 01:22:01 +00:00
create_mysql_table ( conn , table_name )
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2024-02-13 12:15:46 +00:00
CREATE TABLE { } ( id UInt32 , name String , age UInt32 , money UInt32 , source Enum8 ( ' IP ' = 1 , ' URL ' = 2 ) ) ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' , 1 ) ;
2022-03-22 16:39:58 +00:00
""" .format(
table_name , table_name
)
)
node1 . query (
" INSERT INTO {} (id, name, age, money, source) VALUES (1, ' name ' , 0, 0, ' URL ' ) " . format (
table_name
)
)
assert (
node1 . query ( " SELECT source FROM {} LIMIT 1 " . format ( table_name ) ) . rstrip ( )
== " URL "
)
2020-06-27 01:22:01 +00:00
conn . close ( )
2018-05-14 11:10:07 +00:00
2021-04-14 05:41:15 +00:00
def test_external_settings ( started_cluster ) :
2022-03-22 16:39:58 +00:00
table_name = " test_external_settings "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , started_cluster . mysql8_ip )
2021-06-21 15:42:40 +00:00
drop_mysql_table ( conn , table_name )
2021-04-14 05:41:15 +00:00
create_mysql_table ( conn , table_name )
2022-03-22 16:39:58 +00:00
node3 . query ( f " DROP TABLE IF EXISTS { table_name } " )
node3 . query (
"""
2024-02-13 12:15:46 +00:00
CREATE TABLE { } ( id UInt32 , name String , age UInt32 , money UInt32 ) ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' ) ;
2022-03-22 16:39:58 +00:00
""" .format(
table_name , table_name
)
)
2021-04-14 05:41:15 +00:00
node3 . query (
" INSERT INTO {} (id, name, money) select number, concat( ' name_ ' , toString(number)), 3 from numbers(100) " . format (
2022-03-22 16:39:58 +00:00
table_name
)
)
assert node3 . query ( " SELECT count() FROM {} " . format ( table_name ) ) . rstrip ( ) == " 100 "
assert node3 . query ( " SELECT sum(money) FROM {} " . format ( table_name ) ) . rstrip ( ) == " 300 "
node3 . query (
" select value from system.settings where name = ' max_block_size ' FORMAT TSV "
) == " 2 \n "
node3 . query (
" select value from system.settings where name = ' external_storage_max_read_rows ' FORMAT TSV "
) == " 0 \n "
assert (
node3 . query (
" SELECT COUNT(DISTINCT blockNumber()) FROM {} FORMAT TSV " . format ( table_name )
)
== " 50 \n "
)
2021-04-14 05:41:15 +00:00
conn . close ( )
2021-09-02 19:32:32 +00:00
def test_settings_connection_wait_timeout ( started_cluster ) :
2022-03-22 16:39:58 +00:00
table_name = " test_settings_connection_wait_timeout "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2021-09-02 19:32:32 +00:00
wait_timeout = 2
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2021-09-02 19:32:32 +00:00
drop_mysql_table ( conn , table_name )
create_mysql_table ( conn , table_name )
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2021-09-02 19:32:32 +00:00
CREATE TABLE { }
(
id UInt32 ,
name String ,
age UInt32 ,
money UInt32
)
2024-02-13 12:15:46 +00:00
ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' )
2021-09-02 19:32:32 +00:00
SETTINGS connection_wait_timeout = { } , connection_pool_size = 1
2022-03-22 16:39:58 +00:00
""" .format(
table_name , table_name , wait_timeout
)
2021-09-02 19:32:32 +00:00
)
2022-03-22 16:39:58 +00:00
node1 . query (
" INSERT INTO {} (id, name) SELECT number, concat( ' name_ ' , toString(number)) from numbers(10) " . format (
table_name
)
)
2021-09-02 19:32:32 +00:00
2023-04-13 20:26:23 +00:00
worker_started_event = threading . Event ( )
2023-04-13 20:52:16 +00:00
2021-09-02 19:32:32 +00:00
def worker ( ) :
2023-04-13 20:26:23 +00:00
worker_started_event . set ( )
2023-04-13 20:52:16 +00:00
node1 . query (
2023-04-14 20:38:11 +00:00
" SELECT 1, sleepEachRow(1) FROM {} SETTINGS max_threads=1 " . format (
table_name
)
2023-04-13 20:52:16 +00:00
)
2021-09-02 19:32:32 +00:00
worker_thread = threading . Thread ( target = worker )
worker_thread . start ( )
# ensure that first query started in worker_thread
2023-04-14 20:10:57 +00:00
assert worker_started_event . wait ( 10 )
time . sleep ( 1 )
2021-09-02 19:32:32 +00:00
started = time . time ( )
2022-03-22 16:39:58 +00:00
with pytest . raises (
QueryRuntimeException ,
match = r " Exception: mysqlxx::Pool is full \ (connection_wait_timeout is exceeded \ ) " ,
) :
2023-04-13 20:52:16 +00:00
node1 . query (
2023-04-14 20:38:11 +00:00
" SELECT 2, sleepEachRow(1) FROM {} SETTINGS max_threads=1 " . format (
table_name
)
2023-04-13 20:52:16 +00:00
)
2021-09-02 19:32:32 +00:00
ended = time . time ( )
assert ( ended - started ) > = wait_timeout
worker_thread . join ( )
drop_mysql_table ( conn , table_name )
conn . close ( )
2021-09-08 17:42:52 +00:00
2021-09-02 13:01:26 +00:00
def test_predefined_connection_configuration ( started_cluster ) :
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , started_cluster . mysql8_ip )
2022-03-22 16:39:58 +00:00
table_name = " test_table "
2021-09-02 13:01:26 +00:00
drop_mysql_table ( conn , table_name )
create_mysql_table ( conn , table_name )
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2021-09-02 13:01:26 +00:00
DROP TABLE IF EXISTS test_table ;
CREATE TABLE test_table ( id UInt32 , name String , age UInt32 , money UInt32 )
ENGINE MySQL ( mysql1 ) ;
2022-03-22 16:39:58 +00:00
"""
)
node1 . query (
" INSERT INTO test_table (id, name, money) select number, toString(number), number from numbers(100) "
)
assert node1 . query ( f " SELECT count() FROM test_table " ) . rstrip ( ) == " 100 "
2021-09-02 13:01:26 +00:00
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2021-09-02 13:01:26 +00:00
DROP TABLE IF EXISTS test_table ;
CREATE TABLE test_table ( id UInt32 , name String , age UInt32 , money UInt32 )
ENGINE MySQL ( mysql1 , replace_query = 1 ) ;
2022-03-22 16:39:58 +00:00
"""
)
node1 . query (
" INSERT INTO test_table (id, name, money) select number, toString(number), number from numbers(100) "
)
node1 . query (
" INSERT INTO test_table (id, name, money) select number, toString(number), number from numbers(100) "
)
assert node1 . query ( f " SELECT count() FROM test_table " ) . rstrip ( ) == " 100 "
2021-09-02 13:01:26 +00:00
2022-03-22 16:39:58 +00:00
node1 . query_and_get_error (
"""
2021-09-02 13:01:26 +00:00
DROP TABLE IF EXISTS test_table ;
CREATE TABLE test_table ( id UInt32 , name String , age UInt32 , money UInt32 )
ENGINE MySQL ( mysql1 , query = 1 ) ;
2022-03-22 16:39:58 +00:00
"""
)
node1 . query_and_get_error (
"""
2021-09-02 13:01:26 +00:00
DROP TABLE IF EXISTS test_table ;
CREATE TABLE test_table ( id UInt32 , name String , age UInt32 , money UInt32 )
ENGINE MySQL ( mysql1 , replace_query = 1 , on_duplicate_clause = ' kek ' ) ;
2022-03-22 16:39:58 +00:00
"""
)
node1 . query_and_get_error (
"""
2021-09-02 13:01:26 +00:00
DROP TABLE IF EXISTS test_table ;
CREATE TABLE test_table ( id UInt32 , name String , age UInt32 , money UInt32 )
ENGINE MySQL ( fff ) ;
2022-03-22 16:39:58 +00:00
"""
)
node1 . query_and_get_error (
"""
2021-09-02 13:01:26 +00:00
DROP TABLE IF EXISTS test_table ;
CREATE TABLE test_table ( id UInt32 , name String , age UInt32 , money UInt32 )
ENGINE MySQL ( mysql2 ) ;
2022-03-22 16:39:58 +00:00
"""
)
2021-09-02 13:01:26 +00:00
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2021-09-02 13:01:26 +00:00
DROP TABLE IF EXISTS test_table ;
CREATE TABLE test_table ( id UInt32 , name String , age UInt32 , money UInt32 )
ENGINE MySQL ( mysql3 , port = 3306 ) ;
2022-03-22 16:39:58 +00:00
"""
)
assert node1 . query ( f " SELECT count() FROM test_table " ) . rstrip ( ) == " 100 "
2021-09-02 13:01:26 +00:00
2022-03-22 16:39:58 +00:00
assert " Connection pool cannot have zero size " in node1 . query_and_get_error (
2024-02-26 23:54:20 +00:00
" SELECT count() FROM mysql(mysql1, `table`= ' test_table ' , connection_pool_size=0) "
2022-03-22 16:39:58 +00:00
)
assert " Connection pool cannot have zero size " in node1 . query_and_get_error (
" SELECT count() FROM mysql(mysql4) "
)
assert (
int ( node1 . query ( " SELECT count() FROM mysql(mysql4, connection_pool_size=1) " ) )
== 100
)
2021-12-27 14:41:37 +00:00
2021-09-22 15:10:25 +00:00
# Regression for (k, v) IN ((k, v))
def test_mysql_in ( started_cluster ) :
2022-03-22 16:39:58 +00:00
table_name = " test_mysql_in "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2021-09-22 15:10:25 +00:00
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2021-09-22 15:10:25 +00:00
drop_mysql_table ( conn , table_name )
create_mysql_table ( conn , table_name )
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2021-09-11 10:14:46 +00:00
CREATE TABLE { }
(
id UInt32 ,
name String ,
age UInt32 ,
money UInt32
)
2024-02-13 12:15:46 +00:00
ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' )
2022-03-22 16:39:58 +00:00
""" .format(
table_name , table_name
)
2021-09-11 10:14:46 +00:00
)
2022-03-22 16:39:58 +00:00
node1 . query (
" INSERT INTO {} (id, name) SELECT number, concat( ' name_ ' , toString(number)) from numbers(10) " . format (
table_name
)
)
2021-09-11 10:14:46 +00:00
node1 . query ( " SELECT * FROM {} WHERE (id) IN (1) " . format ( table_name ) )
node1 . query ( " SELECT * FROM {} WHERE (id) IN (1, 2) " . format ( table_name ) )
2022-03-22 16:39:58 +00:00
node1 . query (
" SELECT * FROM {} WHERE (id, name) IN ((1, ' name_1 ' )) " . format ( table_name )
)
node1 . query (
" SELECT * FROM {} WHERE (id, name) IN ((1, ' name_1 ' ),(1, ' name_1 ' )) " . format (
table_name
)
)
2021-09-11 10:14:46 +00:00
drop_mysql_table ( conn , table_name )
conn . close ( )
2021-09-22 15:10:25 +00:00
2022-03-22 16:39:58 +00:00
2021-09-28 07:05:52 +00:00
def test_mysql_null ( started_cluster ) :
2022-03-22 16:39:58 +00:00
table_name = " test_mysql_in "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2021-09-28 07:05:52 +00:00
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2021-09-28 07:05:52 +00:00
drop_mysql_table ( conn , table_name )
with conn . cursor ( ) as cursor :
2022-03-22 16:39:58 +00:00
cursor . execute (
"""
2021-09-28 07:05:52 +00:00
CREATE TABLE ` clickhouse ` . ` { } ` (
` id ` int ( 11 ) NOT NULL ,
` money ` int NULL default NULL ,
PRIMARY KEY ( ` id ` ) ) ENGINE = InnoDB ;
2022-03-22 16:39:58 +00:00
""" .format(
table_name
)
)
2021-09-28 07:05:52 +00:00
2022-03-22 16:39:58 +00:00
node1 . query (
"""
2021-09-28 07:05:52 +00:00
CREATE TABLE { }
(
id UInt32 ,
money Nullable ( UInt32 )
)
2024-02-13 12:15:46 +00:00
ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {} ' , ' root ' , ' clickhouse ' )
2022-03-22 16:39:58 +00:00
""" .format(
table_name , table_name
)
2021-09-28 07:05:52 +00:00
)
2022-03-22 16:39:58 +00:00
node1 . query (
" INSERT INTO {} (id, money) SELECT number, if(number % 2, NULL, 1) from numbers(10) " . format (
table_name
)
)
2021-09-28 07:05:52 +00:00
2022-03-22 16:39:58 +00:00
assert (
int (
node1 . query (
" SELECT count() FROM {} WHERE money IS NULL SETTINGS external_table_strict_query=1 " . format (
table_name
)
)
)
== 5
)
assert (
int (
node1 . query (
" SELECT count() FROM {} WHERE money IS NOT NULL SETTINGS external_table_strict_query=1 " . format (
table_name
)
)
)
== 5
)
2021-09-28 07:05:52 +00:00
drop_mysql_table ( conn , table_name )
conn . close ( )
2021-09-02 13:01:26 +00:00
2022-08-29 13:41:32 +00:00
def test_settings ( started_cluster ) :
table_name = " test_settings "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
wait_timeout = 123
rw_timeout = 10123001
connect_timeout = 10123002
connection_pool_size = 1
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2022-08-29 13:41:32 +00:00
drop_mysql_table ( conn , table_name )
create_mysql_table ( conn , table_name )
node1 . query (
f """
CREATE TABLE { table_name }
(
id UInt32 ,
name String ,
age UInt32 ,
money UInt32
)
2024-02-13 12:15:46 +00:00
ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' {table_name} ' , ' root ' , ' clickhouse ' )
2022-08-29 13:41:32 +00:00
SETTINGS connection_wait_timeout = { wait_timeout } , connect_timeout = { connect_timeout } , read_write_timeout = { rw_timeout } , connection_pool_size = { connection_pool_size }
"""
)
node1 . query ( f " SELECT * FROM { table_name } " )
assert node1 . contains_in_log (
f " with settings: connect_timeout= { connect_timeout } , read_write_timeout= { rw_timeout } "
)
rw_timeout = 20123001
connect_timeout = 20123002
2023-03-02 18:04:33 +00:00
node1 . query ( f " SELECT * FROM mysql(mysql_with_settings, table= ' test_settings ' ) " )
2022-08-29 13:41:32 +00:00
assert node1 . contains_in_log (
f " with settings: connect_timeout= { connect_timeout } , read_write_timeout= { rw_timeout } "
)
rw_timeout = 30123001
connect_timeout = 30123002
node1 . query (
f """
SELECT *
2024-02-13 12:15:46 +00:00
FROM mysql ( ' mysql80:3306 ' , ' clickhouse ' , ' {table_name} ' , ' root ' , ' clickhouse ' ,
2022-08-29 13:41:32 +00:00
SETTINGS
connection_wait_timeout = { wait_timeout } ,
connect_timeout = { connect_timeout } ,
read_write_timeout = { rw_timeout } ,
connection_pool_size = { connection_pool_size } )
"""
)
assert node1 . contains_in_log (
f " with settings: connect_timeout= { connect_timeout } , read_write_timeout= { rw_timeout } "
)
2024-08-12 06:35:44 +00:00
node1 . query ( " DROP DATABASE IF EXISTS m " )
node1 . query ( " DROP DATABASE IF EXISTS mm " )
2022-08-29 13:41:32 +00:00
rw_timeout = 40123001
connect_timeout = 40123002
node1 . query (
f """
CREATE DATABASE m
ENGINE = MySQL ( mysql_with_settings , connection_wait_timeout = { wait_timeout } , connect_timeout = { connect_timeout } , read_write_timeout = { rw_timeout } , connection_pool_size = { connection_pool_size } )
"""
)
assert node1 . contains_in_log (
f " with settings: connect_timeout= { connect_timeout } , read_write_timeout= { rw_timeout } "
)
rw_timeout = 50123001
connect_timeout = 50123002
node1 . query (
f """
2024-02-13 12:15:46 +00:00
CREATE DATABASE mm ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' root ' , ' clickhouse ' )
2022-08-29 13:41:32 +00:00
SETTINGS
connection_wait_timeout = { wait_timeout } ,
connect_timeout = { connect_timeout } ,
read_write_timeout = { rw_timeout } ,
connection_pool_size = { connection_pool_size }
"""
)
assert node1 . contains_in_log (
f " with settings: connect_timeout= { connect_timeout } , read_write_timeout= { rw_timeout } "
)
2024-08-12 06:35:44 +00:00
node1 . query ( " DROP DATABASE m " )
node1 . query ( " DROP DATABASE mm " )
2022-08-29 13:41:32 +00:00
drop_mysql_table ( conn , table_name )
conn . close ( )
2024-01-11 10:47:58 +00:00
def test_mysql_point ( started_cluster ) :
table_name = " test_mysql_point "
node1 . query ( f " DROP TABLE IF EXISTS { table_name } " )
2024-02-13 12:15:46 +00:00
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
2024-01-11 10:47:58 +00:00
drop_mysql_table ( conn , table_name )
with conn . cursor ( ) as cursor :
cursor . execute (
f """
CREATE TABLE ` clickhouse ` . ` { table_name } ` (
` id ` int NOT NULL ,
` point ` Point NOT NULL ,
PRIMARY KEY ( ` id ` ) ) ENGINE = InnoDB ;
"""
)
cursor . execute (
f " INSERT INTO `clickhouse`.` { table_name } ` SELECT 1, Point(15, 20) "
)
assert 1 == cursor . execute ( f " SELECT count(*) FROM `clickhouse`.` { table_name } ` " )
conn . commit ( )
result = node1 . query (
2024-02-13 12:15:46 +00:00
f " DESCRIBE mysql( ' mysql80:3306 ' , ' clickhouse ' , ' { table_name } ' , ' root ' , ' clickhouse ' ) "
2024-01-11 10:47:58 +00:00
)
assert result . strip ( ) == " id \t Int32 \t \t \t \t \t \n point \t Point "
assert 1 == int (
node1 . query (
2024-02-13 12:15:46 +00:00
f " SELECT count() FROM mysql( ' mysql80:3306 ' , ' clickhouse ' , ' { table_name } ' , ' root ' , ' clickhouse ' ) "
2024-01-11 10:47:58 +00:00
)
)
assert (
2024-01-12 08:40:15 +00:00
" (15,20) "
2024-01-11 10:47:58 +00:00
== node1 . query (
2024-02-13 12:15:46 +00:00
f " SELECT point FROM mysql( ' mysql80:3306 ' , ' clickhouse ' , ' { table_name } ' , ' root ' , ' clickhouse ' ) "
2024-01-11 10:47:58 +00:00
) . strip ( )
)
2024-01-12 09:41:04 +00:00
node1 . query ( " DROP TABLE IF EXISTS test " )
node1 . query (
2024-02-13 12:15:46 +00:00
f " CREATE TABLE test (id Int32, point Point) Engine=MySQL( ' mysql80:3306 ' , ' clickhouse ' , ' { table_name } ' , ' root ' , ' clickhouse ' ) "
2024-01-12 09:41:04 +00:00
)
assert " (15,20) " == node1 . query ( f " SELECT point FROM test " ) . strip ( )
2024-01-11 10:47:58 +00:00
drop_mysql_table ( conn , table_name )
conn . close ( )
2024-07-19 09:30:26 +00:00
def test_joins ( started_cluster ) :
conn = get_mysql_conn ( started_cluster , cluster . mysql8_ip )
drop_mysql_table ( conn , " test_joins_mysql_users " )
with conn . cursor ( ) as cursor :
cursor . execute (
" CREATE TABLE clickhouse.test_joins_mysql_users (id INT NOT NULL, name varchar(50) NOT NULL, created TIMESTAMP, PRIMARY KEY (`id`)) ENGINE=InnoDB; "
)
cursor . execute (
f " INSERT INTO clickhouse.test_joins_mysql_users VALUES (469722, ' user@example.com ' , ' 2019-08-30 07:55:01 ' ) "
)
drop_mysql_table ( conn , " test_joins_mysql_tickets " )
with conn . cursor ( ) as cursor :
cursor . execute (
" CREATE TABLE clickhouse.test_joins_mysql_tickets (id INT NOT NULL, subject varchar(50), created TIMESTAMP, creator INT NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB; "
)
cursor . execute (
f " INSERT INTO clickhouse.test_joins_mysql_tickets VALUES (281607, ' Feedback ' , ' 2024-06-25 12:09:41 ' , 469722) "
)
conn . commit ( )
2024-08-12 06:35:44 +00:00
node1 . query ( " DROP TABLE IF EXISTS test_joins_table_users " )
node1 . query ( " DROP TABLE IF EXISTS test_joins_table_tickets " )
2024-07-19 09:30:26 +00:00
node1 . query (
"""
CREATE TABLE test_joins_table_users
(
` id ` Int32 ,
` Name ` String ,
` Created ` Nullable ( DateTime )
)
ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' test_joins_mysql_users ' , ' root ' , ' clickhouse ' ) ;
"""
)
node1 . query (
"""
CREATE TABLE test_joins_table_tickets
(
` id ` Int32 ,
` Subject ` Nullable ( String ) ,
` Created ` Nullable ( DateTime ) ,
` Creator ` Int32
)
ENGINE = MySQL ( ' mysql80:3306 ' , ' clickhouse ' , ' test_joins_mysql_tickets ' , ' root ' , ' clickhouse ' ) ;
"""
)
node1 . query (
"""
SELECT test_joins_table_tickets . id , Subject , test_joins_table_tickets . Created , Name
FROM test_joins_table_tickets
LEFT JOIN test_joins_table_users ON test_joins_table_tickets . Creator = test_joins_table_users . id
WHERE test_joins_table_tickets . Created = ' 2024-06-25 12:09:41 '
"""
) == " 281607 \t Feedback \t 2024-06-25 12:09:41 \t user@example.com \n "
2024-08-12 06:35:44 +00:00
node1 . query ( " DROP TABLE test_joins_table_users " )
node1 . query ( " DROP TABLE test_joins_table_tickets " )
2024-07-19 09:30:26 +00:00
2022-03-22 16:39:58 +00:00
if __name__ == " __main__ " :
2018-05-14 11:10:07 +00:00
with contextmanager ( started_cluster ) ( ) as cluster :
2020-10-02 16:54:07 +00:00
for name , instance in list ( cluster . instances . items ( ) ) :
print ( name , instance . ip_address )
input ( " Cluster created, press any key to destroy... " )