mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-18 21:51:57 +00:00
b75963d370
This PR formats all the `*.py` files found under the `tests/integration` folder. It also reorders the imports and cleans up a bunch of unused imports. The formatting also takes care of other things like wrapping lines and fixing spaces and indents such that the tests look more readable.
521 lines
22 KiB
Python
521 lines
22 KiB
Python
# coding: utf-8
|
|
|
|
import datetime
|
|
import math
|
|
import os
|
|
import subprocess
|
|
import time
|
|
|
|
import docker
|
|
import pymysql.connections
|
|
import pytest
|
|
from docker.models.containers import Container
|
|
from helpers.cluster import ClickHouseCluster, get_docker_compose_path
|
|
|
|
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
|
|
DOCKER_COMPOSE_PATH = get_docker_compose_path()
|
|
|
|
cluster = ClickHouseCluster(__file__)
|
|
node = cluster.add_instance('node', main_configs=["configs/log_conf.xml", "configs/ssl_conf.xml", "configs/mysql.xml",
|
|
"configs/dhparam.pem", "configs/server.crt", "configs/server.key"],
|
|
user_configs=["configs/users.xml"], env_variables={'UBSAN_OPTIONS': 'print_stacktrace=1'})
|
|
|
|
server_port = 9001
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def server_address():
|
|
cluster.start()
|
|
try:
|
|
yield cluster.get_instance_ip('node')
|
|
finally:
|
|
cluster.shutdown()
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def mysql_client():
|
|
docker_compose = os.path.join(DOCKER_COMPOSE_PATH, 'docker_compose_mysql_client.yml')
|
|
subprocess.check_call(
|
|
['docker-compose', '-p', cluster.project_name, '-f', docker_compose, 'up', '--no-recreate', '-d', '--no-build'])
|
|
yield docker.from_env().containers.get(cluster.project_name + '_mysql1_1')
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def mysql_server(mysql_client):
|
|
"""Return MySQL container when it is healthy.
|
|
|
|
:type mysql_client: Container
|
|
:rtype: Container
|
|
"""
|
|
retries = 30
|
|
for i in range(retries):
|
|
info = mysql_client.client.api.inspect_container(mysql_client.name)
|
|
if info['State']['Health']['Status'] == 'healthy':
|
|
break
|
|
time.sleep(1)
|
|
else:
|
|
raise Exception('Mysql server has not started in %d seconds.' % retries)
|
|
|
|
return mysql_client
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def golang_container():
|
|
docker_compose = os.path.join(DOCKER_COMPOSE_PATH, 'docker_compose_mysql_golang_client.yml')
|
|
subprocess.check_call(
|
|
['docker-compose', '-p', cluster.project_name, '-f', docker_compose, 'up', '--no-recreate', '-d', '--no-build'])
|
|
yield docker.from_env().containers.get(cluster.project_name + '_golang1_1')
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def php_container():
|
|
docker_compose = os.path.join(DOCKER_COMPOSE_PATH, 'docker_compose_mysql_php_client.yml')
|
|
subprocess.check_call(
|
|
['docker-compose', '-p', cluster.project_name, '-f', docker_compose, 'up', '--no-recreate', '-d', '--no-build'])
|
|
yield docker.from_env().containers.get(cluster.project_name + '_php1_1')
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def nodejs_container():
|
|
docker_compose = os.path.join(DOCKER_COMPOSE_PATH, 'docker_compose_mysql_js_client.yml')
|
|
subprocess.check_call(
|
|
['docker-compose', '-p', cluster.project_name, '-f', docker_compose, 'up', '--no-recreate', '-d', '--no-build'])
|
|
yield docker.from_env().containers.get(cluster.project_name + '_mysqljs1_1')
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
def java_container():
|
|
docker_compose = os.path.join(DOCKER_COMPOSE_PATH, 'docker_compose_mysql_java_client.yml')
|
|
subprocess.check_call(
|
|
['docker-compose', '-p', cluster.project_name, '-f', docker_compose, 'up', '--no-recreate', '-d', '--no-build'])
|
|
yield docker.from_env().containers.get(cluster.project_name + '_java1_1')
|
|
|
|
|
|
def test_mysql_client(mysql_client, server_address):
|
|
# type: (Container, str) -> None
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u user_with_double_sha1 --password=abacaba
|
|
-e "SELECT 1;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
|
|
assert stdout == '\n'.join(['1', '1', ''])
|
|
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default --password=123
|
|
-e "SELECT 1 as a;"
|
|
-e "SELECT 'тест' as b;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
|
|
assert stdout == '\n'.join(['a', '1', 'b', 'тест', ''])
|
|
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default --password=abc -e "select 1 as a;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
|
|
assert stderr == 'mysql: [Warning] Using a password on the command line interface can be insecure.\n' \
|
|
'ERROR 516 (00000): default: Authentication failed: password is incorrect or there is no user with such name\n'
|
|
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default --password=123
|
|
-e "use system;"
|
|
-e "select count(*) from (select name from tables limit 1);"
|
|
-e "use system2;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
|
|
assert stdout == 'count()\n1\n'
|
|
assert stderr[0:182] == "mysql: [Warning] Using a password on the command line interface can be insecure.\n" \
|
|
"ERROR 81 (00000) at line 1: Code: 81, e.displayText() = DB::Exception: Database system2 doesn't exist"
|
|
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default --password=123
|
|
-e "CREATE DATABASE x;"
|
|
-e "USE x;"
|
|
-e "CREATE TABLE table1 (column UInt32) ENGINE = Memory;"
|
|
-e "INSERT INTO table1 VALUES (0), (1), (5);"
|
|
-e "INSERT INTO table1 VALUES (0), (1), (5);"
|
|
-e "SELECT * FROM table1 ORDER BY column;"
|
|
-e "DROP DATABASE x;"
|
|
-e "CREATE TEMPORARY TABLE tmp (tmp_column UInt32);"
|
|
-e "INSERT INTO tmp VALUES (0), (1);"
|
|
-e "SELECT * FROM tmp ORDER BY tmp_column;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
|
|
assert stdout == '\n'.join(['column', '0', '0', '1', '1', '5', '5', 'tmp_column', '0', '1', ''])
|
|
|
|
|
|
def test_mysql_client_exception(mysql_client, server_address):
|
|
# Poco exception.
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default --password=123
|
|
-e "CREATE TABLE default.t1_remote_mysql AS mysql('127.0.0.1:10086','default','t1_local','default','');"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
|
|
assert stderr[0:266] == "mysql: [Warning] Using a password on the command line interface can be insecure.\n" \
|
|
"ERROR 1000 (00000) at line 1: Poco::Exception. Code: 1000, e.code() = 2002, e.displayText() = mysqlxx::ConnectionFailed: Can't connect to MySQL server on '127.0.0.1' (115) ((nullptr):0)"
|
|
|
|
|
|
def test_mysql_replacement_query(mysql_client, server_address):
|
|
# SHOW TABLE STATUS LIKE.
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default
|
|
--password=123 -e "show table status like 'xx';"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
|
|
# SHOW VARIABLES.
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default
|
|
--password=123 -e "show variables;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
|
|
# KILL QUERY.
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default
|
|
--password=123 -e "kill query 0;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default
|
|
--password=123 -e "kill query where query_id='mysql:0';"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
|
|
# SELECT DATABASE().
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default
|
|
--password=123 -e "select database();"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
assert stdout == 'database()\ndefault\n'
|
|
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default
|
|
--password=123 -e "select DATABASE();"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
assert stdout == 'DATABASE()\ndefault\n'
|
|
|
|
|
|
def test_mysql_explain(mysql_client, server_address):
|
|
# EXPLAIN SELECT 1
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default --password=123
|
|
-e "EXPLAIN SELECT 1;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
|
|
# EXPLAIN AST SELECT 1
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default --password=123
|
|
-e "EXPLAIN AST SELECT 1;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
|
|
# EXPLAIN PLAN SELECT 1
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default --password=123
|
|
-e "EXPLAIN PLAN SELECT 1;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
|
|
# EXPLAIN PIPELINE graph=1 SELECT 1
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default --password=123
|
|
-e "EXPLAIN PIPELINE graph=1 SELECT 1;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
|
|
|
|
def test_mysql_federated(mysql_server, server_address):
|
|
# For some reason it occasionally fails without retries.
|
|
retries = 100
|
|
for try_num in range(retries):
|
|
node.query('''DROP DATABASE IF EXISTS mysql_federated''', settings={"password": "123"})
|
|
node.query('''CREATE DATABASE mysql_federated''', settings={"password": "123"})
|
|
node.query('''CREATE TABLE mysql_federated.test (col UInt32) ENGINE = Log''', settings={"password": "123"})
|
|
node.query('''INSERT INTO mysql_federated.test VALUES (0), (1), (5)''', settings={"password": "123"})
|
|
|
|
def check_retryable_error_in_stderr(stderr):
|
|
return "Can't connect to local MySQL server through socket" in stderr or "MySQL server has gone away" in stderr
|
|
|
|
code, (stdout, stderr) = mysql_server.exec_run('''
|
|
mysql
|
|
-e "DROP SERVER IF EXISTS clickhouse;"
|
|
-e "CREATE SERVER clickhouse FOREIGN DATA WRAPPER mysql
|
|
OPTIONS (USER 'default', PASSWORD '123', HOST '{host}', PORT {port}, DATABASE 'mysql_federated');"
|
|
-e "DROP DATABASE IF EXISTS mysql_federated;"
|
|
-e "CREATE DATABASE mysql_federated;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
|
|
if code != 0:
|
|
print("stdout", stdout)
|
|
print("stderr", stderr)
|
|
if try_num + 1 < retries and check_retryable_error_in_stderr(stderr):
|
|
time.sleep(1)
|
|
continue
|
|
assert code == 0
|
|
|
|
code, (stdout, stderr) = mysql_server.exec_run('''
|
|
mysql
|
|
-e "CREATE TABLE mysql_federated.test(`col` int UNSIGNED) ENGINE=FEDERATED CONNECTION='clickhouse';"
|
|
-e "SELECT * FROM mysql_federated.test ORDER BY col;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
|
|
if code != 0:
|
|
print("stdout", stdout)
|
|
print("stderr", stderr)
|
|
if try_num + 1 < retries and check_retryable_error_in_stderr(stderr):
|
|
time.sleep(1)
|
|
continue
|
|
assert code == 0
|
|
|
|
assert stdout == '\n'.join(['col', '0', '1', '5', ''])
|
|
|
|
code, (stdout, stderr) = mysql_server.exec_run('''
|
|
mysql
|
|
-e "INSERT INTO mysql_federated.test VALUES (0), (1), (5);"
|
|
-e "SELECT * FROM mysql_federated.test ORDER BY col;"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
|
|
if code != 0:
|
|
print("stdout", stdout)
|
|
print("stderr", stderr)
|
|
if try_num + 1 < retries and check_retryable_error_in_stderr(stderr):
|
|
time.sleep(1)
|
|
continue
|
|
assert code == 0
|
|
|
|
assert stdout == '\n'.join(['col', '0', '0', '1', '1', '5', '5', ''])
|
|
|
|
|
|
def test_mysql_set_variables(mysql_client, server_address):
|
|
code, (stdout, stderr) = mysql_client.exec_run('''
|
|
mysql --protocol tcp -h {host} -P {port} default -u default --password=123
|
|
-e
|
|
"
|
|
SET NAMES=default;
|
|
SET character_set_results=default;
|
|
SET FOREIGN_KEY_CHECKS=false;
|
|
SET AUTOCOMMIT=1;
|
|
SET sql_mode='strict';
|
|
SET @@wait_timeout = 2147483;
|
|
SET SESSION TRANSACTION ISOLATION LEVEL READ;
|
|
"
|
|
'''.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
|
|
|
|
def test_python_client(server_address):
|
|
client = pymysql.connections.Connection(host=server_address, user='user_with_double_sha1', password='abacaba',
|
|
database='default', port=server_port)
|
|
|
|
with pytest.raises(pymysql.InternalError) as exc_info:
|
|
client.query('select name from tables')
|
|
|
|
assert exc_info.value.args[1][
|
|
0:77] == "Code: 60, e.displayText() = DB::Exception: Table default.tables doesn't exist"
|
|
|
|
cursor = client.cursor(pymysql.cursors.DictCursor)
|
|
cursor.execute("select 1 as a, 'тест' as b")
|
|
assert cursor.fetchall() == [{'a': 1, 'b': 'тест'}]
|
|
|
|
with pytest.raises(pymysql.InternalError) as exc_info:
|
|
pymysql.connections.Connection(host=server_address, user='default', password='abacab', database='default',
|
|
port=server_port)
|
|
|
|
assert exc_info.value.args == (
|
|
516, 'default: Authentication failed: password is incorrect or there is no user with such name')
|
|
|
|
client = pymysql.connections.Connection(host=server_address, user='default', password='123', database='default',
|
|
port=server_port)
|
|
|
|
with pytest.raises(pymysql.InternalError) as exc_info:
|
|
client.query('select name from tables')
|
|
|
|
assert exc_info.value.args[1][
|
|
0:77] == "Code: 60, e.displayText() = DB::Exception: Table default.tables doesn't exist"
|
|
|
|
cursor = client.cursor(pymysql.cursors.DictCursor)
|
|
cursor.execute("select 1 as a, 'тест' as b")
|
|
assert cursor.fetchall() == [{'a': 1, 'b': 'тест'}]
|
|
|
|
client.select_db('system')
|
|
|
|
with pytest.raises(pymysql.InternalError) as exc_info:
|
|
client.select_db('system2')
|
|
|
|
assert exc_info.value.args[1][0:73] == "Code: 81, e.displayText() = DB::Exception: Database system2 doesn't exist"
|
|
|
|
cursor = client.cursor(pymysql.cursors.DictCursor)
|
|
cursor.execute('CREATE DATABASE x')
|
|
client.select_db('x')
|
|
cursor.execute("CREATE TABLE table1 (a UInt32) ENGINE = Memory")
|
|
cursor.execute("INSERT INTO table1 VALUES (1), (3)")
|
|
cursor.execute("INSERT INTO table1 VALUES (1), (4)")
|
|
cursor.execute("SELECT * FROM table1 ORDER BY a")
|
|
assert cursor.fetchall() == [{'a': 1}, {'a': 1}, {'a': 3}, {'a': 4}]
|
|
|
|
|
|
def test_golang_client(server_address, golang_container):
|
|
# type: (str, Container) -> None
|
|
with open(os.path.join(SCRIPT_DIR, 'golang.reference')) as fp:
|
|
reference = fp.read()
|
|
|
|
code, (stdout, stderr) = golang_container.exec_run(
|
|
'./main --host {host} --port {port} --user default --password 123 --database '
|
|
'abc'.format(host=server_address, port=server_port), demux=True)
|
|
|
|
assert code == 1
|
|
assert stderr == "Error 81: Database abc doesn't exist\n"
|
|
|
|
code, (stdout, stderr) = golang_container.exec_run(
|
|
'./main --host {host} --port {port} --user default --password 123 --database '
|
|
'default'.format(host=server_address, port=server_port), demux=True)
|
|
|
|
assert code == 0
|
|
assert stdout == reference
|
|
|
|
code, (stdout, stderr) = golang_container.exec_run(
|
|
'./main --host {host} --port {port} --user user_with_double_sha1 --password abacaba --database '
|
|
'default'.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
assert stdout == reference
|
|
|
|
|
|
def test_php_client(server_address, php_container):
|
|
# type: (str, Container) -> None
|
|
code, (stdout, stderr) = php_container.exec_run(
|
|
'php -f test.php {host} {port} default 123'.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
assert stdout == 'tables\n'
|
|
|
|
code, (stdout, stderr) = php_container.exec_run(
|
|
'php -f test_ssl.php {host} {port} default 123'.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
assert stdout == 'tables\n'
|
|
|
|
code, (stdout, stderr) = php_container.exec_run(
|
|
'php -f test.php {host} {port} user_with_double_sha1 abacaba'.format(host=server_address, port=server_port),
|
|
demux=True)
|
|
assert code == 0
|
|
assert stdout == 'tables\n'
|
|
|
|
code, (stdout, stderr) = php_container.exec_run(
|
|
'php -f test_ssl.php {host} {port} user_with_double_sha1 abacaba'.format(host=server_address, port=server_port),
|
|
demux=True)
|
|
assert code == 0
|
|
assert stdout == 'tables\n'
|
|
|
|
|
|
def test_mysqljs_client(server_address, nodejs_container):
|
|
code, (_, stderr) = nodejs_container.exec_run(
|
|
'node test.js {host} {port} user_with_sha256 abacaba'.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 1
|
|
assert 'MySQL is requesting the sha256_password authentication method, which is not supported.' in stderr
|
|
|
|
code, (_, stderr) = nodejs_container.exec_run(
|
|
'node test.js {host} {port} user_with_empty_password ""'.format(host=server_address, port=server_port),
|
|
demux=True)
|
|
assert code == 0
|
|
|
|
code, (_, _) = nodejs_container.exec_run(
|
|
'node test.js {host} {port} user_with_double_sha1 abacaba'.format(host=server_address, port=server_port),
|
|
demux=True)
|
|
assert code == 0
|
|
|
|
code, (_, _) = nodejs_container.exec_run(
|
|
'node test.js {host} {port} user_with_empty_password 123'.format(host=server_address, port=server_port),
|
|
demux=True)
|
|
assert code == 1
|
|
|
|
|
|
def test_java_client(server_address, java_container):
|
|
# type: (str, Container) -> None
|
|
with open(os.path.join(SCRIPT_DIR, 'java.reference')) as fp:
|
|
reference = fp.read()
|
|
|
|
# database not exists exception.
|
|
code, (stdout, stderr) = java_container.exec_run(
|
|
'java JavaConnectorTest --host {host} --port {port} --user user_with_empty_password --database '
|
|
'abc'.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 1
|
|
|
|
# empty password passed.
|
|
code, (stdout, stderr) = java_container.exec_run(
|
|
'java JavaConnectorTest --host {host} --port {port} --user user_with_empty_password --database '
|
|
'default'.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
assert stdout == reference
|
|
|
|
# non-empty password passed.
|
|
code, (stdout, stderr) = java_container.exec_run(
|
|
'java JavaConnectorTest --host {host} --port {port} --user default --password 123 --database '
|
|
'default'.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
assert stdout == reference
|
|
|
|
# double-sha1 password passed.
|
|
code, (stdout, stderr) = java_container.exec_run(
|
|
'java JavaConnectorTest --host {host} --port {port} --user user_with_double_sha1 --password abacaba --database '
|
|
'default'.format(host=server_address, port=server_port), demux=True)
|
|
assert code == 0
|
|
assert stdout == reference
|
|
|
|
|
|
def test_types(server_address):
|
|
client = pymysql.connections.Connection(host=server_address, user='default', password='123', database='default',
|
|
port=server_port)
|
|
|
|
cursor = client.cursor(pymysql.cursors.DictCursor)
|
|
cursor.execute(
|
|
"select "
|
|
"toInt8(-pow(2, 7)) as Int8_column, "
|
|
"toUInt8(pow(2, 8) - 1) as UInt8_column, "
|
|
"toInt16(-pow(2, 15)) as Int16_column, "
|
|
"toUInt16(pow(2, 16) - 1) as UInt16_column, "
|
|
"toInt32(-pow(2, 31)) as Int32_column, "
|
|
"toUInt32(pow(2, 32) - 1) as UInt32_column, "
|
|
"toInt64('-9223372036854775808') as Int64_column, " # -2^63
|
|
"toUInt64('18446744073709551615') as UInt64_column, " # 2^64 - 1
|
|
"'тест' as String_column, "
|
|
"toFixedString('тест', 8) as FixedString_column, "
|
|
"toFloat32(1.5) as Float32_column, "
|
|
"toFloat64(1.5) as Float64_column, "
|
|
"toFloat32(NaN) as Float32_NaN_column, "
|
|
"-Inf as Float64_Inf_column, "
|
|
"toDate('2019-12-08') as Date_column, "
|
|
"toDate('1970-01-01') as Date_min_column, "
|
|
"toDate('1970-01-02') as Date_after_min_column, "
|
|
"toDateTime('2019-12-08 08:24:03') as DateTime_column"
|
|
)
|
|
|
|
result = cursor.fetchall()[0]
|
|
expected = [
|
|
('Int8_column', -2 ** 7),
|
|
('UInt8_column', 2 ** 8 - 1),
|
|
('Int16_column', -2 ** 15),
|
|
('UInt16_column', 2 ** 16 - 1),
|
|
('Int32_column', -2 ** 31),
|
|
('UInt32_column', 2 ** 32 - 1),
|
|
('Int64_column', -2 ** 63),
|
|
('UInt64_column', 2 ** 64 - 1),
|
|
('String_column', 'тест'),
|
|
('FixedString_column', 'тест'),
|
|
('Float32_column', 1.5),
|
|
('Float64_column', 1.5),
|
|
('Float32_NaN_column', float('nan')),
|
|
('Float64_Inf_column', float('-inf')),
|
|
('Date_column', datetime.date(2019, 12, 8)),
|
|
('Date_min_column', datetime.date(1970, 1, 1)),
|
|
('Date_after_min_column', datetime.date(1970, 1, 2)),
|
|
('DateTime_column', datetime.datetime(2019, 12, 8, 8, 24, 3)),
|
|
]
|
|
|
|
for key, value in expected:
|
|
if isinstance(value, float) and math.isnan(value):
|
|
assert math.isnan(result[key])
|
|
else:
|
|
assert result[key] == value
|