diff --git a/tests/testflows/extended_precision_data_types/common.py b/tests/testflows/extended_precision_data_types/common.py
new file mode 100644
index 00000000000..1c852bbf935
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/common.py
@@ -0,0 +1,118 @@
+import uuid
+
+from contextlib import contextmanager
+
+from testflows.core.name import basename, parentname
+from testflows._core.testtype import TestSubType
+from testflows.asserts import values, error, snapshot
+
+from helpers.common import *
+
+@contextmanager
+def allow_experimental_bigint(node):
+ """Enable experimental big int setting in Clickhouse.
+ """
+ setting = ("allow_experimental_bigint_types", 1)
+ default_query_settings = None
+
+ try:
+ with Given("I add allow_experimental_bigint to the default query settings"):
+ default_query_settings = getsattr(current().context, "default_query_settings", [])
+ default_query_settings.append(setting)
+ yield
+ finally:
+ with Finally("I remove allow_experimental_bigint from the default query settings"):
+ if default_query_settings:
+ try:
+ default_query_settings.pop(default_query_settings.index(setting))
+ except ValueError:
+ pass
+
+@TestStep(Given)
+def allow_experimental_map_type(self):
+ """Set allow_experimental_map_type = 1
+ """
+ setting = ("allow_experimental_map_type", 1)
+ default_query_settings = None
+
+ try:
+ with By("adding allow_experimental_map_type to the default query settings"):
+ default_query_settings = getsattr(current().context, "default_query_settings", [])
+ default_query_settings.append(setting)
+ yield
+ finally:
+ with Finally("I remove allow_experimental_map_type from the default query settings"):
+ if default_query_settings:
+ try:
+ default_query_settings.pop(default_query_settings.index(setting))
+ except ValueError:
+ pass
+
+def execute_query(sql, expected=None, format="TabSeparatedWithNames", compare_func=None):
+ """Execute SQL query and compare the output to the snapshot.
+ """
+ name = basename(current().name)
+
+ with When("I execute query", description=sql):
+ r = current().context.node.query(sql + " FORMAT " + format)
+
+ if expected is not None:
+ with Then("I check output against expected"):
+
+ if compare_func is None:
+ assert r.output.strip() == expected, error()
+
+ else:
+ assert compare_func(r.output.strip(), expected), error()
+
+ else:
+ with Then("I check output against snapshot"):
+ with values() as that:
+ assert that(snapshot("\n" + r.output.strip() + "\n", "tests", name=name, encoder=str)), error()
+
+@TestStep(Given)
+def table(self, data_type, name="table0"):
+ """Create a table.
+ """
+ node = current().context.node
+
+ try:
+ with By("creating table"):
+ node.query(f"CREATE TABLE {name}(a {data_type}) ENGINE = Memory")
+ yield
+
+ finally:
+ with Finally("drop the table"):
+ node.query(f"DROP TABLE IF EXISTS {name}")
+
+def getuid():
+ """Create a unique variable name based on the test it is called from.
+ """
+ if current().subtype == TestSubType.Example:
+ testname = f"{basename(parentname(current().name)).replace(' ', '_').replace(',','')}"
+ else:
+ testname = f"{basename(current().name).replace(' ', '_').replace(',','')}"
+
+ for char in ['(', ')', '[', ']','\'']:
+ testname = testname.replace(f'{char}', '')
+
+ return testname + "_" + str(uuid.uuid1()).replace('-', '_')
+
+def to_data_type(data_type, value):
+ """Return a conversion statement based on the data type provided
+ """
+ if data_type in ['Decimal256(0)']:
+ return f'toDecimal256(\'{value}\',0)'
+
+ else:
+ return f'to{data_type}(\'{value}\')'
+
+
+data_types = [
+ ('Int128', '-170141183460469231731687303715884105728', '170141183460469231731687303715884105727'),
+ ('Int256', '-57896044618658097711785492504343953926634992332820282019728792003956564819968', '57896044618658097711785492504343953926634992332820282019728792003956564819967'),
+ ('UInt128','0','340282366920938463463374607431768211455'),
+ ('UInt256', '0', '115792089237316195423570985008687907853269984665640564039457584007913129639935'),
+]
+
+Decimal256_min_max = -1000000000000000000000000000000000000000000000000000000000000000000000000000,1000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/tests/testflows/extended_precision_data_types/configs/clickhouse/common.xml b/tests/testflows/extended_precision_data_types/configs/clickhouse/common.xml
new file mode 100644
index 00000000000..567c8c05e32
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/configs/clickhouse/common.xml
@@ -0,0 +1,6 @@
+
+ Europe/Moscow
+ ::
+ /var/lib/clickhouse/
+ /var/lib/clickhouse/tmp/
+
diff --git a/tests/testflows/extended_precision_data_types/configs/clickhouse/config.d/logs.xml b/tests/testflows/extended_precision_data_types/configs/clickhouse/config.d/logs.xml
new file mode 100644
index 00000000000..bdf1bbc11c1
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/configs/clickhouse/config.d/logs.xml
@@ -0,0 +1,17 @@
+
+ 3
+
+ trace
+ /var/log/clickhouse-server/log.log
+ /var/log/clickhouse-server/log.err.log
+ 1000M
+ 10
+ /var/log/clickhouse-server/stderr.log
+ /var/log/clickhouse-server/stdout.log
+
+
+ system
+
+ 500
+
+
diff --git a/tests/testflows/extended_precision_data_types/configs/clickhouse/config.d/storage.xml b/tests/testflows/extended_precision_data_types/configs/clickhouse/config.d/storage.xml
new file mode 100644
index 00000000000..618fd6b6d24
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/configs/clickhouse/config.d/storage.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+ 1024
+
+
+
+
+
+
+ default
+
+
+
+
+
+
+
diff --git a/tests/testflows/extended_precision_data_types/configs/clickhouse/config.xml b/tests/testflows/extended_precision_data_types/configs/clickhouse/config.xml
new file mode 100644
index 00000000000..4ec12232539
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/configs/clickhouse/config.xml
@@ -0,0 +1,448 @@
+
+
+
+
+
+ trace
+ /var/log/clickhouse-server/clickhouse-server.log
+ /var/log/clickhouse-server/clickhouse-server.err.log
+ 1000M
+ 10
+
+
+
+ 8123
+ 9000
+
+
+
+
+
+
+
+
+ /etc/clickhouse-server/server.crt
+ /etc/clickhouse-server/server.key
+
+ /etc/clickhouse-server/dhparam.pem
+ none
+ true
+ true
+ sslv2,sslv3
+ true
+
+
+
+ true
+ true
+ sslv2,sslv3
+ true
+
+
+
+ RejectCertificateHandler
+
+
+
+
+
+
+
+
+ 9009
+
+
+
+
+
+
+
+ 0.0.0.0
+
+
+
+
+
+
+
+
+
+
+
+ 4096
+ 3
+
+
+ 100
+
+
+
+
+
+ 8589934592
+
+
+ 5368709120
+
+
+
+ /var/lib/clickhouse/
+
+
+ /var/lib/clickhouse/tmp/
+
+
+ /var/lib/clickhouse/user_files/
+
+
+ /var/lib/clickhouse/access/
+
+
+
+
+
+ users.xml
+
+
+
+ /var/lib/clickhouse/access/
+
+
+
+
+ users.xml
+
+
+ default
+
+
+
+
+
+ default
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+ localhost
+ 9000
+
+
+
+
+
+
+ localhost
+ 9000
+
+
+
+
+ localhost
+ 9000
+
+
+
+
+
+
+ localhost
+ 9440
+ 1
+
+
+
+
+
+
+ localhost
+ 9000
+
+
+
+
+ localhost
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3600
+
+
+
+ 3600
+
+
+ 60
+
+
+
+
+
+
+
+
+
+ system
+
+
+ toYYYYMM(event_date)
+
+ 7500
+
+
+
+
+ system
+
+
+ toYYYYMM(event_date)
+ 7500
+
+
+
+
+ system
+
+ toYYYYMM(event_date)
+ 7500
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ *_dictionary.xml
+
+
+
+
+
+
+
+
+
+ /clickhouse/task_queue/ddl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ click_cost
+ any
+
+ 0
+ 3600
+
+
+ 86400
+ 60
+
+
+
+ max
+
+ 0
+ 60
+
+
+ 3600
+ 300
+
+
+ 86400
+ 3600
+
+
+
+
+
+ /var/lib/clickhouse/format_schemas/
+
+
+
+
diff --git a/tests/testflows/extended_precision_data_types/configs/clickhouse/users.xml b/tests/testflows/extended_precision_data_types/configs/clickhouse/users.xml
new file mode 100644
index 00000000000..86b2cd9e1e3
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/configs/clickhouse/users.xml
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+ 10000000000
+
+
+ 0
+
+
+ random
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+ ::/0
+
+
+
+ default
+
+
+ default
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3600
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
diff --git a/tests/testflows/extended_precision_data_types/errors.py b/tests/testflows/extended_precision_data_types/errors.py
new file mode 100644
index 00000000000..63b82f3368d
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/errors.py
@@ -0,0 +1,11 @@
+def not_implemented_bigints(name):
+ return(48, f"Exception: {name} is not implemented for big integers")
+
+def bigints_not_implements(name):
+ return(48, f'Exception: {name} for big integers is not implemented')
+
+def illegal_type():
+ return(43, 'Exception: Illegal type')
+
+def illegal_column():
+ return(44, 'Exception: Illegal column')
\ No newline at end of file
diff --git a/tests/testflows/extended_precision_data_types/extended-precision-data-type_env/clickhouse-service.yml b/tests/testflows/extended_precision_data_types/extended-precision-data-type_env/clickhouse-service.yml
new file mode 100644
index 00000000000..fdd4a8057a9
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/extended-precision-data-type_env/clickhouse-service.yml
@@ -0,0 +1,27 @@
+version: '2.3'
+
+services:
+ clickhouse:
+ image: yandex/clickhouse-integration-test
+ expose:
+ - "9000"
+ - "9009"
+ - "8123"
+ volumes:
+ - "${CLICKHOUSE_TESTS_DIR}/configs/clickhouse/config.d:/etc/clickhouse-server/config.d"
+ - "${CLICKHOUSE_TESTS_DIR}/configs/clickhouse/users.d:/etc/clickhouse-server/users.d"
+ - "${CLICKHOUSE_TESTS_DIR}/configs/clickhouse/config.xml:/etc/clickhouse-server/config.xml"
+ - "${CLICKHOUSE_TESTS_DIR}/configs/clickhouse/users.xml:/etc/clickhouse-server/users.xml"
+ - "${CLICKHOUSE_TESTS_SERVER_BIN_PATH:-/usr/bin/clickhouse}:/usr/bin/clickhouse"
+ - "${CLICKHOUSE_TESTS_ODBC_BRIDGE_BIN_PATH:-/usr/bin/clickhouse-odbc-bridge}:/usr/bin/clickhouse-odbc-bridge"
+ entrypoint: bash -c "clickhouse server --config-file=/etc/clickhouse-server/config.xml --log-file=/var/log/clickhouse-server/clickhouse-server.log --errorlog-file=/var/log/clickhouse-server/clickhouse-server.err.log"
+ healthcheck:
+ test: clickhouse client --query='select 1'
+ interval: 10s
+ timeout: 10s
+ retries: 3
+ start_period: 300s
+ cap_add:
+ - SYS_PTRACE
+ security_opt:
+ - label:disable
diff --git a/tests/testflows/extended_precision_data_types/extended-precision-data-type_env/docker-compose.yml b/tests/testflows/extended_precision_data_types/extended-precision-data-type_env/docker-compose.yml
new file mode 100644
index 00000000000..74d17d40e66
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/extended-precision-data-type_env/docker-compose.yml
@@ -0,0 +1,30 @@
+version: '2.3'
+
+services:
+
+ mysql1:
+ extends:
+ file: mysql-service.yml
+ service: mysql
+ hostname: mysql1
+ volumes:
+ - "${CLICKHOUSE_TESTS_DIR}/_instances/mysql1/database:/var/lib/mysql"
+
+ clickhouse1:
+ extends:
+ file: clickhouse-service.yml
+ service: clickhouse
+ hostname: clickhouse1
+ volumes:
+ - "${CLICKHOUSE_TESTS_DIR}/_instances/clickhouse1/database/:/var/lib/clickhouse/"
+ - "${CLICKHOUSE_TESTS_DIR}/_instances/clickhouse1/logs/:/var/log/clickhouse-server/"
+
+ # dummy service which does nothing, but allows to postpone
+ # 'docker-compose up -d' till all dependecies will go healthy
+ all_services_ready:
+ image: hello-world
+ depends_on:
+ clickhouse1:
+ condition: service_healthy
+ mysql1:
+ condition: service_healthy
diff --git a/tests/testflows/extended_precision_data_types/extended-precision-data-type_env/mysql-service.yml b/tests/testflows/extended_precision_data_types/extended-precision-data-type_env/mysql-service.yml
new file mode 100644
index 00000000000..6924bccfad5
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/extended-precision-data-type_env/mysql-service.yml
@@ -0,0 +1,19 @@
+version: '2.3'
+
+services:
+ mysql:
+ image: mysql:5.7.30
+ restart: always
+ environment:
+ MYSQL_DATABASE: 'db'
+ MYSQL_USER: 'user'
+ MYSQL_PASSWORD: 'password'
+ MYSQL_ROOT_PASSWORD: 'password'
+ expose:
+ - '3306'
+ healthcheck:
+ test: mysql -D db -u user --password=password -e "select 1;"
+ interval: 3s
+ timeout: 2s
+ retries: 40
+ start_period: 2s
diff --git a/tests/testflows/extended_precision_data_types/regression.py b/tests/testflows/extended_precision_data_types/regression.py
new file mode 100755
index 00000000000..a0c3186c961
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/regression.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+import os
+import sys
+
+from testflows.core import *
+
+append_path(sys.path, "..")
+
+from helpers.cluster import Cluster
+from helpers.argparser import argparser
+from extended_precision_data_types.requirements import *
+
+xfails = {
+}
+
+xflags = {
+}
+
+@TestModule
+@ArgumentParser(argparser)
+@XFails(xfails)
+@XFlags(xflags)
+@Name("extended precision data types")
+@Specifications(
+ QA_SRS020_ClickHouse_Extended_Precision_Data_Types
+)
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision("1.0"),
+)
+def regression(self, local, clickhouse_binary_path, stress=None, parallel=None):
+ """Extended precision data type regression.
+ """
+
+ top().terminating = False
+
+ nodes = {
+ "clickhouse":
+ ("clickhouse1",)
+ }
+ with Cluster(local, clickhouse_binary_path, nodes=nodes,
+ docker_compose_project_dir=os.path.join(current_dir(), "extended-precision-data-type_env")) as cluster:
+
+ self.context.cluster = cluster
+ self.context.stress = stress
+
+ if parallel is not None:
+ self.context.parallel = parallel
+
+ Feature(run=load("extended_precision_data_types.tests.feature", "feature"))
+
+if main():
+ regression()
diff --git a/tests/testflows/extended_precision_data_types/requirements/__init__.py b/tests/testflows/extended_precision_data_types/requirements/__init__.py
new file mode 100644
index 00000000000..75e9d5b4bb8
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/requirements/__init__.py
@@ -0,0 +1 @@
+from .requirements import *
\ No newline at end of file
diff --git a/tests/testflows/extended_precision_data_types/requirements/requirements.md b/tests/testflows/extended_precision_data_types/requirements/requirements.md
new file mode 100644
index 00000000000..9bbd59a14d5
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/requirements/requirements.md
@@ -0,0 +1,565 @@
+# QA-SRS020 ClickHouse Extended Precision Data Types
+# Software Requirements Specification
+
+## Table of Contents
+
+* 1 [Revision History](#revision-history)
+* 2 [Introduction](#introduction)
+* 3 [Terminology](#terminology)
+ * 3.1 [Extended Precision Data Types](#extended-precision-data-types)
+* 4 [Requirements](#requirements)
+ * 4.1 [RQ.SRS-020.ClickHouse.Extended.Precision](#rqsrs-020clickhouseextendedprecision)
+ * 4.2 [Conversion](#conversion)
+ * 4.2.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt128](#rqsrs-020clickhouseextendedprecisionconversiontoint128)
+ * 4.2.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt128](#rqsrs-020clickhouseextendedprecisionconversiontouint128)
+ * 4.2.3 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt256](#rqsrs-020clickhouseextendedprecisionconversiontoint256)
+ * 4.2.4 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt256](#rqsrs-020clickhouseextendedprecisionconversiontouint256)
+ * 4.2.5 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toDecimal256](#rqsrs-020clickhouseextendedprecisionconversiontodecimal256)
+ * 4.2.6 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.FromMySQL](#rqsrs-020clickhouseextendedprecisionconversionfrommysql)
+ * 4.2.7 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.ToMySQL](#rqsrs-020clickhouseextendedprecisionconversiontomysql)
+ * 4.3 [Arithmetic](#arithmetic)
+ * 4.3.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Int.Supported](#rqsrs-020clickhouseextendedprecisionarithmeticintsupported)
+ * 4.3.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.Supported](#rqsrs-020clickhouseextendedprecisionarithmeticdecsupported)
+ * 4.3.3 [RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.NotSupported](#rqsrs-020clickhouseextendedprecisionarithmeticdecnotsupported)
+ * 4.4 [Arrays](#arrays)
+ * 4.4.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.Supported](#rqsrs-020clickhouseextendedprecisionarraysintsupported)
+ * 4.4.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.NotSupported](#rqsrs-020clickhouseextendedprecisionarraysintnotsupported)
+ * 4.4.3 [RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.Supported](#rqsrs-020clickhouseextendedprecisionarraysdecsupported)
+ * 4.4.4 [RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.NotSupported](#rqsrs-020clickhouseextendedprecisionarraysdecnotsupported)
+ * 4.5 [Comparison](#comparison)
+ * 4.5.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Comparison](#rqsrs-020clickhouseextendedprecisioncomparison)
+ * 4.6 [Logical Functions](#logical-functions)
+ * 4.6.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Logical](#rqsrs-020clickhouseextendedprecisionlogical)
+ * 4.7 [Mathematical Functions](#mathematical-functions)
+ * 4.7.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.Supported](#rqsrs-020clickhouseextendedprecisionmathematicalsupported)
+ * 4.7.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.NotSupported](#rqsrs-020clickhouseextendedprecisionmathematicalnotsupported)
+ * 4.8 [Rounding Functions](#rounding-functions)
+ * 4.8.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.Supported](#rqsrs-020clickhouseextendedprecisionroundingintsupported)
+ * 4.8.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.NotSupported](#rqsrs-020clickhouseextendedprecisionroundingintnotsupported)
+ * 4.8.3 [RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.Supported](#rqsrs-020clickhouseextendedprecisionroundingdecsupported)
+ * 4.8.4 [RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.NotSupported](#rqsrs-020clickhouseextendedprecisionroundingdecnotsupported)
+ * 4.9 [Bit Functions](#bit-functions)
+ * 4.9.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.Supported](#rqsrs-020clickhouseextendedprecisionbitintsupported)
+ * 4.9.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.NotSupported](#rqsrs-020clickhouseextendedprecisionbitintnotsupported)
+ * 4.9.3 [RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Dec.NotSupported](#rqsrs-020clickhouseextendedprecisionbitdecnotsupported)
+ * 4.10 [Null Functions](#null-functions)
+ * 4.10.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Null](#rqsrs-020clickhouseextendedprecisionnull)
+ * 4.11 [Tuple Functions](#tuple-functions)
+ * 4.11.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Tuple](#rqsrs-020clickhouseextendedprecisiontuple)
+ * 4.12 [Map Functions](#map-functions)
+ * 4.12.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Map.Supported](#rqsrs-020clickhouseextendedprecisionmapsupported)
+ * 4.12.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Map.NotSupported](#rqsrs-020clickhouseextendedprecisionmapnotsupported)
+ * 4.13 [Create](#create)
+ * 4.13.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Create.Table](#rqsrs-020clickhouseextendedprecisioncreatetable)
+* 5 [References](#references)
+
+## Revision History
+
+This document is stored in an electronic form using [Git] source control management software
+hosted in a [GitHub Repository].
+All the updates are tracked using the [Revision History].
+
+## Introduction
+
+This software requirements specification covers requirements related to [ClickHouse]
+using extended precision data types.
+
+## Terminology
+
+### Extended Precision Data Types
+
+Inclusive bounds:
+* Int128 - [-170141183460469231731687303715884105728 : 170141183460469231731687303715884105727]
+* UInt128 - [0 : 340282366920938463463374607431768211455]
+* Int256 - [-57896044618658097711785492504343953926634992332820282019728792003956564819968 : 57896044618658097711785492504343953926634992332820282019728792003956564819967]
+* UInt256 - [0 : 115792089237316195423570985008687907853269984665640564039457584007913129639935]
+
+Exclusive bounds:
+* Decimal256 - (10^(76 - S): 10^(76 - S)), where S is the scale.
+
+## Requirements
+
+### RQ.SRS-020.ClickHouse.Extended.Precision
+version: 1.0
+
+[ClickHouse] SHALL support using [Extended Precision Data Types].
+
+### Conversion
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt128
+version: 1.0
+
+[ClickHouse] SHALL support converting values to `Int128` using the `toInt128` function.
+
+For example,
+
+```sql
+SELECT toInt128(1)
+```
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt128
+version: 1.0
+
+[ClickHouse] SHALL support converting values to `UInt128` format using `toUInt128` function.
+
+For example,
+
+```sql
+SELECT toUInt128(1)
+```
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt256
+version: 1.0
+
+[ClickHouse] SHALL support converting values to `Int256` using `toInt256` function.
+
+For example,
+
+```sql
+SELECT toInt256(1)
+```
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt256
+version: 1.0
+
+[ClickHouse] SHALL support converting values to `UInt256` format using `toUInt256` function.
+
+For example,
+
+```sql
+SELECT toUInt256(1)
+```
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toDecimal256
+version: 1.0
+
+[ClickHouse] SHALL support converting values to `Decimal256` format using `toDecimal256` function.
+
+For example,
+
+```sql
+SELECT toDecimal256(1,2)
+```
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.FromMySQL
+version: 1.0
+
+[ClickHouse] SHALL support converting to [Extended Precision Data Types] from MySQL.
+
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.ToMySQL
+version: 1.0
+
+[ClickHouse] MAY not support converting from [Extended Precision Data Types] to MySQL.
+
+### Arithmetic
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Int.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using [Arithmetic functions] with Int128, UInt128, Int256, and UInt256.
+
+Arithmetic functions:
+* plus
+* minus
+* multiply
+* divide
+* intDiv
+* intDivOrZero
+* modulo
+* moduloOrZero
+* negate
+* abs
+* gcd
+* lcm
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Arithmetic functions] with Decimal256:
+
+* plus
+* minus
+* multiply
+* divide
+* intDiv
+* intDivOrZero
+* negate
+* abs
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Arithmetic functions] with Decimal256:
+
+* modulo
+* moduloOrZero
+* gcd
+* lcm
+
+### Arrays
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Array functions] with Int128, UInt128, Int256, and UInt256.
+
+* empty
+* notEmpty
+* length
+* arrayCount
+* arrayPopBack
+* arrayPopFront
+* arraySort
+* arrayReverseSort
+* arrayUniq
+* arrayJoin
+* arrayDistinct
+* arrayEnumerate
+* arrayEnumerateDense
+* arrayEnumerateUniq
+* arrayReverse
+* reverse
+* arrayFlatten
+* arrayCompact
+* arrayExists
+* arrayAll
+* arrayMin
+* arrayMax
+* arraySum
+* arrayAvg
+* arrayReduce
+* arrayReduceInRanges
+* arrayZip
+* arrayMap
+* arrayFilter
+* arrayFill
+* arrayReverseFill
+* arraySplit
+* arrayFirst
+* arrayFirstIndex
+* arrayConcat
+* hasAll
+* hasAny
+* hasSubstr
+* arrayElement
+* has
+* indexOf
+* countEqual
+* arrayPushBack
+* arrayPushFront
+* arrayResize
+* arraySlice
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Array functions] with Int128, UInt128, Int256, and UInt256:
+
+* arrayDifference
+* arrayCumSum
+* arrayCumSumNonNegative
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Array functions] with Decimal256:
+
+* empty
+* notEmpty
+* length
+* arrayCount
+* arrayPopBack
+* arrayPopFront
+* arraySort
+* arrayReverseSort
+* arrayUniq
+* arrayJoin
+* arrayDistinct
+* arrayEnumerate
+* arrayEnumerateDense
+* arrayEnumerateUniq
+* arrayReverse
+* reverse
+* arrayFlatten
+* arrayCompact
+* arrayExists
+* arrayAll
+* arrayReduce
+* arrayReduceInRanges
+* arrayZip
+* arrayMap
+* arrayFilter
+* arrayFill
+* arrayReverseFill
+* arraySplit
+* arrayFirst
+* arrayFirstIndex
+* arrayConcat
+* hasAll
+* hasAny
+* hasSubstr
+* arrayElement
+* has
+* indexOf
+* countEqual
+* arrayPushBack
+* arrayPushFront
+* arrayResize
+* arraySlice
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Array functions] with Decimal256:
+
+* arrayMin
+* arrayMax
+* arraaySum
+* arrayAvg
+* arrayDifference
+* arrayCumSum
+* arrayCumSumNonNegative
+
+### Comparison
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Comparison
+version: 1.0
+
+[ClickHouse] SHALL support using [Comparison functions] with [Extended Precision Data Types].
+
+Comparison functions:
+* equals
+* notEquals
+* less
+* greater
+* lessOrEquals
+* greaterOrEquals
+
+### Logical Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Logical
+version: 1.0
+
+[ClickHouse] MAY not support using [Logical functions] with [Extended Precision Data Types].
+
+Logical functions:
+* and
+* or
+* not
+* xor
+
+### Mathematical Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Mathematical functions] with [Extended Precision Data Types]:
+
+* exp
+* log, ln
+* exp2
+* log2
+* exp10
+* log10
+* sqrt
+* cbrt
+* erf
+* erfc
+* lgamma
+* tgamma
+* sin
+* cos
+* tan
+* asin
+* acos
+* atan
+* cosh
+* acosh
+* sinh
+* asinh
+* tanh
+* atanh
+* log1p
+* sign
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Mathematical functions] with [Extended Precision Data Types]:
+
+* pow, power
+* intExp2
+* intExp10
+* atan2
+* hypot
+
+### Rounding Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Rounding functions] with Int128, UInt128, Int256, and UInt256:
+
+* floor
+* ceil
+* trunc
+* round
+* roundBankers
+* roundDuration
+* roundAge
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Rounding functions] with Int128, UInt128, Int256, and UInt256:
+
+* roundDown
+* roundToExp2
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Rounding functions] with Decimal256:
+
+* floor
+* ceil
+* trunc
+* round
+* roundBankers
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Rounding functions] with Decimal256:
+
+* roundDuration
+* roundAge
+* roundDown
+* roundToExp2
+
+### Bit Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Bit functions] with Int128, UInt128, Int256, and UInt256:
+
+* bitAnd
+* bitOr
+* bitXor
+* bitNot
+* bitShiftLeft
+* bitShiftRight
+* bitCount
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Bit functions] with Int128, UInt128, Int256, and UInt256:
+
+* bitRotateLeft
+* bitRotateRight
+* bitTest
+* bitTestAll
+* bitTestAny
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Dec.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using [Bit functions] with Decimal256.
+
+Bit functions:
+* bitAnd
+* bitOr
+* bitXor
+* bitNot
+* bitShiftLeft
+* bitShiftRight
+* bitCount
+* bitRotateLeft
+* bitRotateRight
+* bitTest
+* bitTestAll
+* bitTestAny
+
+### Null Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Null
+version: 1.0
+
+[ClickHouse] SHALL support using [Null functions] with [Extended Precision Data Types].
+
+Null functions:
+* isNull
+* isNotNull
+* coalesce
+* ifNull
+* nullIf
+* assumeNotNull
+* toNullable
+
+### Tuple Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Tuple
+version: 1.0
+
+[ClickHouse] SHALL support using [Tuple functions] with [Extended Precision Data Types].
+
+Tuple functions:
+* tuple
+* tupleElement
+* untuple
+
+### Map Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Map.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Map functions] with [Extended Precision Data Types]:
+
+* map
+* mapContains
+* mapKeys
+* mapValues
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Map.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Map functions] with [Extended Precision Data Types]:
+
+* mapAdd
+* mapSubtract
+* mapPopulateSeries
+
+### Create
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Create.Table
+version: 1.0
+
+[ClickHouse] SHALL support creating table with columns that use [Extended Precision Data Types].
+
+## References
+
+* **ClickHouse:** https://clickhouse.tech
+* **GitHub Repository**: https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/extended_precision_data_types/requirements/requirements.md
+* **Revision History**: https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/extended_precision_data_types/requirements/requirements.md
+* **Git:** https://git-scm.com/
+
+[Extended Precision Data Types]: #extended-precision-data-types
+[Arithmetic functions]: https://clickhouse.tech/docs/en/sql-reference/functions/arithmetic-functions/
+[Array functions]: https://clickhouse.tech/docs/en/sql-reference/functions/array-functions/
+[Comparison functions]: https://clickhouse.tech/docs/en/sql-reference/functions/comparison-functions/
+[Logical Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/logical-functions/
+[Mathematical Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/math-functions/
+[Rounding Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/rounding-functions/
+[Bit Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/bit-functions/
+[Null Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/functions-for-nulls/
+[Tuple Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/tuple-functions/
+[Map Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/tuple-map-functions/
+[SRS]: #srs
+[ClickHouse]: https://clickhouse.tech
+[GitHub Repository]: https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/extended_precision_data_types/requirements/requirements.md
+[Revision History]: https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/extended_precision_data_types/requirements/requirements.md
+[Git]: https://git-scm.com/
+[GitHub]: https://github.com
diff --git a/tests/testflows/extended_precision_data_types/requirements/requirements.py b/tests/testflows/extended_precision_data_types/requirements/requirements.py
new file mode 100644
index 00000000000..3fcf7798651
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/requirements/requirements.py
@@ -0,0 +1,1423 @@
+# These requirements were auto generated
+# from software requirements specification (SRS)
+# document by TestFlows v1.6.210505.1133630.
+# Do not edit by hand but re-generate instead
+# using 'tfs requirements generate' command.
+from testflows.core import Specification
+from testflows.core import Requirement
+
+Heading = Specification.Heading
+
+RQ_SRS_020_ClickHouse_Extended_Precision = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using [Extended Precision Data Types].\n'
+ '\n'
+ ),
+ link=None,
+ level=2,
+ num='4.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toInt128 = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt128',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support converting values to `Int128` using the `toInt128` function.\n'
+ '\n'
+ 'For example,\n'
+ '\n'
+ '```sql\n'
+ 'SELECT toInt128(1)\n'
+ '```\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.2.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toUInt128 = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt128',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support converting values to `UInt128` format using `toUInt128` function.\n'
+ '\n'
+ 'For example,\n'
+ '\n'
+ '```sql\n'
+ 'SELECT toUInt128(1)\n'
+ '```\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.2.2')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toInt256 = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt256',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support converting values to `Int256` using `toInt256` function.\n'
+ '\n'
+ 'For example,\n'
+ '\n'
+ '```sql\n'
+ 'SELECT toInt256(1)\n'
+ '```\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.2.3')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toUInt256 = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt256',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support converting values to `UInt256` format using `toUInt256` function.\n'
+ '\n'
+ 'For example,\n'
+ '\n'
+ '```sql\n'
+ 'SELECT toUInt256(1)\n'
+ '```\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.2.4')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toDecimal256 = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toDecimal256',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support converting values to `Decimal256` format using `toDecimal256` function.\n'
+ '\n'
+ 'For example,\n'
+ '\n'
+ '```sql\n'
+ 'SELECT toDecimal256(1,2)\n'
+ '```\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.2.5')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_FromMySQL = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.FromMySQL',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support converting to [Extended Precision Data Types] from MySQL.\n'
+ '\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.2.6')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_ToMySQL = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.ToMySQL',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support converting from [Extended Precision Data Types] to MySQL.\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.2.7')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Arithmetic_Int_Supported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Int.Supported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using [Arithmetic functions] with Int128, UInt128, Int256, and UInt256.\n'
+ '\n'
+ 'Arithmetic functions:\n'
+ '* plus\n'
+ '* minus\n'
+ '* multiply\n'
+ '* divide\n'
+ '* intDiv\n'
+ '* intDivOrZero\n'
+ '* modulo\n'
+ '* moduloOrZero\n'
+ '* negate\n'
+ '* abs\n'
+ '* gcd\n'
+ '* lcm\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.3.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Arithmetic_Dec_Supported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.Supported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using the following [Arithmetic functions] with Decimal256:\n'
+ '\n'
+ '* plus\n'
+ '* minus\n'
+ '* multiply\n'
+ '* divide\n'
+ '* intDiv\n'
+ '* intDivOrZero\n'
+ '* negate\n'
+ '* abs\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.3.2')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Arithmetic_Dec_NotSupported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.NotSupported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support using the following [Arithmetic functions] with Decimal256:\n'
+ '\n'
+ '* modulo\n'
+ '* moduloOrZero\n'
+ '* gcd\n'
+ '* lcm\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.3.3')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Int_Supported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.Supported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using the following [Array functions] with Int128, UInt128, Int256, and UInt256.\n'
+ '\n'
+ '* empty\n'
+ '* notEmpty\n'
+ '* length\n'
+ '* arrayCount\n'
+ '* arrayPopBack\n'
+ '* arrayPopFront\n'
+ '* arraySort\n'
+ '* arrayReverseSort\n'
+ '* arrayUniq\n'
+ '* arrayJoin\n'
+ '* arrayDistinct\n'
+ '* arrayEnumerate\n'
+ '* arrayEnumerateDense\n'
+ '* arrayEnumerateUniq\n'
+ '* arrayReverse\n'
+ '* reverse\n'
+ '* arrayFlatten\n'
+ '* arrayCompact\n'
+ '* arrayExists\n'
+ '* arrayAll\n'
+ '* arrayMin\n'
+ '* arrayMax\n'
+ '* arraySum\n'
+ '* arrayAvg\n'
+ '* arrayReduce\n'
+ '* arrayReduceInRanges\n'
+ '* arrayZip\n'
+ '* arrayMap\n'
+ '* arrayFilter\n'
+ '* arrayFill\n'
+ '* arrayReverseFill\n'
+ '* arraySplit\n'
+ '* arrayFirst\n'
+ '* arrayFirstIndex\n'
+ '* arrayConcat\n'
+ '* hasAll\n'
+ '* hasAny\n'
+ '* hasSubstr\n'
+ '* arrayElement\n'
+ '* has\n'
+ '* indexOf\n'
+ '* countEqual\n'
+ '* arrayPushBack\n'
+ '* arrayPushFront\n'
+ '* arrayResize\n'
+ '* arraySlice\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.4.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Int_NotSupported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.NotSupported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support using the following [Array functions] with Int128, UInt128, Int256, and UInt256:\n'
+ '\n'
+ '* arrayDifference\n'
+ '* arrayCumSum\n'
+ '* arrayCumSumNonNegative\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.4.2')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Dec_Supported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.Supported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using the following [Array functions] with Decimal256:\n'
+ '\n'
+ '* empty\n'
+ '* notEmpty\n'
+ '* length\n'
+ '* arrayCount\n'
+ '* arrayPopBack\n'
+ '* arrayPopFront\n'
+ '* arraySort\n'
+ '* arrayReverseSort\n'
+ '* arrayUniq\n'
+ '* arrayJoin\n'
+ '* arrayDistinct\n'
+ '* arrayEnumerate\n'
+ '* arrayEnumerateDense\n'
+ '* arrayEnumerateUniq\n'
+ '* arrayReverse\n'
+ '* reverse\n'
+ '* arrayFlatten\n'
+ '* arrayCompact\n'
+ '* arrayExists\n'
+ '* arrayAll\n'
+ '* arrayReduce\n'
+ '* arrayReduceInRanges\n'
+ '* arrayZip\n'
+ '* arrayMap\n'
+ '* arrayFilter\n'
+ '* arrayFill\n'
+ '* arrayReverseFill\n'
+ '* arraySplit\n'
+ '* arrayFirst\n'
+ '* arrayFirstIndex\n'
+ '* arrayConcat\n'
+ '* hasAll\n'
+ '* hasAny\n'
+ '* hasSubstr\n'
+ '* arrayElement\n'
+ '* has\n'
+ '* indexOf\n'
+ '* countEqual\n'
+ '* arrayPushBack\n'
+ '* arrayPushFront\n'
+ '* arrayResize\n'
+ '* arraySlice\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.4.3')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Dec_NotSupported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.NotSupported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support using the following [Array functions] with Decimal256:\n'
+ '\n'
+ '* arrayMin\n'
+ '* arrayMax\n'
+ '* arraaySum\n'
+ '* arrayAvg\n'
+ '* arrayDifference\n'
+ '* arrayCumSum\n'
+ '* arrayCumSumNonNegative\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.4.4')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Comparison = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Comparison',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using [Comparison functions] with [Extended Precision Data Types].\n'
+ '\n'
+ 'Comparison functions:\n'
+ '* equals\n'
+ '* notEquals\n'
+ '* less\n'
+ '* greater\n'
+ '* lessOrEquals\n'
+ '* greaterOrEquals\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.5.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Logical = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Logical',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support using [Logical functions] with [Extended Precision Data Types].\n'
+ '\n'
+ 'Logical functions:\n'
+ '* and\n'
+ '* or\n'
+ '* not\n'
+ '* xor\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.6.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Mathematical_Supported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.Supported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using the following [Mathematical functions] with [Extended Precision Data Types]:\n'
+ '\n'
+ '* exp\n'
+ '* log, ln\n'
+ '* exp2\n'
+ '* log2\n'
+ '* exp10\n'
+ '* log10\n'
+ '* sqrt\n'
+ '* cbrt\n'
+ '* erf\n'
+ '* erfc\n'
+ '* lgamma\n'
+ '* tgamma\n'
+ '* sin\n'
+ '* cos\n'
+ '* tan\n'
+ '* asin\n'
+ '* acos\n'
+ '* atan\n'
+ '* cosh\n'
+ '* acosh\n'
+ '* sinh\n'
+ '* asinh\n'
+ '* tanh\n'
+ '* atanh\n'
+ '* log1p\n'
+ '* sign\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.7.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Mathematical_NotSupported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.NotSupported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support using the following [Mathematical functions] with [Extended Precision Data Types]:\n'
+ '\n'
+ '* pow, power\n'
+ '* intExp2\n'
+ '* intExp10\n'
+ '* atan2\n'
+ '* hypot\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.7.2')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Int_Supported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.Supported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using the following [Rounding functions] with Int128, UInt128, Int256, and UInt256:\n'
+ '\n'
+ '* floor\n'
+ '* ceil\n'
+ '* trunc\n'
+ '* round\n'
+ '* roundBankers\n'
+ '* roundDuration\n'
+ '* roundAge\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.8.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Int_NotSupported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.NotSupported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support using the following [Rounding functions] with Int128, UInt128, Int256, and UInt256:\n'
+ '\n'
+ '* roundDown\n'
+ '* roundToExp2\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.8.2')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Dec_Supported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.Supported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using the following [Rounding functions] with Decimal256:\n'
+ '\n'
+ '* floor\n'
+ '* ceil\n'
+ '* trunc\n'
+ '* round\n'
+ '* roundBankers\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.8.3')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Dec_NotSupported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.NotSupported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support using the following [Rounding functions] with Decimal256:\n'
+ '\n'
+ '* roundDuration\n'
+ '* roundAge\n'
+ '* roundDown\n'
+ '* roundToExp2\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.8.4')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Bit_Int_Supported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.Supported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using the following [Bit functions] with Int128, UInt128, Int256, and UInt256:\n'
+ '\n'
+ '* bitAnd\n'
+ '* bitOr\n'
+ '* bitXor\n'
+ '* bitNot\n'
+ '* bitShiftLeft\n'
+ '* bitShiftRight\n'
+ '* bitCount\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.9.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Bit_Int_NotSupported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.NotSupported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support using the following [Bit functions] with Int128, UInt128, Int256, and UInt256:\n'
+ '\n'
+ '* bitRotateLeft\n'
+ '* bitRotateRight\n'
+ '* bitTest\n'
+ '* bitTestAll\n'
+ '* bitTestAny\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.9.2')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Bit_Dec_NotSupported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Dec.NotSupported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support using [Bit functions] with Decimal256.\n'
+ '\n'
+ 'Bit functions:\n'
+ '* bitAnd\n'
+ '* bitOr\n'
+ '* bitXor\n'
+ '* bitNot\n'
+ '* bitShiftLeft\n'
+ '* bitShiftRight\n'
+ '* bitCount\n'
+ '* bitRotateLeft\n'
+ '* bitRotateRight\n'
+ '* bitTest\n'
+ '* bitTestAll\n'
+ '* bitTestAny\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.9.3')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Null = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Null',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using [Null functions] with [Extended Precision Data Types].\n'
+ '\n'
+ 'Null functions:\n'
+ '* isNull\n'
+ '* isNotNull\n'
+ '* coalesce\n'
+ '* ifNull\n'
+ '* nullIf\n'
+ '* assumeNotNull\n'
+ '* toNullable\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.10.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Tuple = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Tuple',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using [Tuple functions] with [Extended Precision Data Types].\n'
+ '\n'
+ 'Tuple functions:\n'
+ '* tuple\n'
+ '* tupleElement\n'
+ '* untuple\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.11.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Map_Supported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Map.Supported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support using the following [Map functions] with [Extended Precision Data Types]:\n'
+ '\n'
+ '* map\n'
+ '* mapContains\n'
+ '* mapKeys\n'
+ '* mapValues\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.12.1')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Map_NotSupported = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Map.NotSupported',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] MAY not support using the following [Map functions] with [Extended Precision Data Types]:\n'
+ '\n'
+ '* mapAdd\n'
+ '* mapSubtract\n'
+ '* mapPopulateSeries\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.12.2')
+
+RQ_SRS_020_ClickHouse_Extended_Precision_Create_Table = Requirement(
+ name='RQ.SRS-020.ClickHouse.Extended.Precision.Create.Table',
+ version='1.0',
+ priority=None,
+ group=None,
+ type=None,
+ uid=None,
+ description=(
+ '[ClickHouse] SHALL support creating table with columns that use [Extended Precision Data Types].\n'
+ '\n'
+ ),
+ link=None,
+ level=3,
+ num='4.13.1')
+
+QA_SRS020_ClickHouse_Extended_Precision_Data_Types = Specification(
+ name='QA-SRS020 ClickHouse Extended Precision Data Types',
+ description=None,
+ author=None,
+ date=None,
+ status=None,
+ approved_by=None,
+ approved_date=None,
+ approved_version=None,
+ version=None,
+ group=None,
+ type=None,
+ link=None,
+ uid=None,
+ parent=None,
+ children=None,
+ headings=(
+ Heading(name='Revision History', level=1, num='1'),
+ Heading(name='Introduction', level=1, num='2'),
+ Heading(name='Terminology', level=1, num='3'),
+ Heading(name='Extended Precision Data Types', level=2, num='3.1'),
+ Heading(name='Requirements', level=1, num='4'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision', level=2, num='4.1'),
+ Heading(name='Conversion', level=2, num='4.2'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt128', level=3, num='4.2.1'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt128', level=3, num='4.2.2'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt256', level=3, num='4.2.3'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt256', level=3, num='4.2.4'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toDecimal256', level=3, num='4.2.5'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.FromMySQL', level=3, num='4.2.6'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.ToMySQL', level=3, num='4.2.7'),
+ Heading(name='Arithmetic', level=2, num='4.3'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Int.Supported', level=3, num='4.3.1'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.Supported', level=3, num='4.3.2'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.NotSupported', level=3, num='4.3.3'),
+ Heading(name='Arrays', level=2, num='4.4'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.Supported', level=3, num='4.4.1'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.NotSupported', level=3, num='4.4.2'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.Supported', level=3, num='4.4.3'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.NotSupported', level=3, num='4.4.4'),
+ Heading(name='Comparison', level=2, num='4.5'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Comparison', level=3, num='4.5.1'),
+ Heading(name='Logical Functions', level=2, num='4.6'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Logical', level=3, num='4.6.1'),
+ Heading(name='Mathematical Functions', level=2, num='4.7'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.Supported', level=3, num='4.7.1'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.NotSupported', level=3, num='4.7.2'),
+ Heading(name='Rounding Functions', level=2, num='4.8'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.Supported', level=3, num='4.8.1'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.NotSupported', level=3, num='4.8.2'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.Supported', level=3, num='4.8.3'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.NotSupported', level=3, num='4.8.4'),
+ Heading(name='Bit Functions', level=2, num='4.9'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.Supported', level=3, num='4.9.1'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.NotSupported', level=3, num='4.9.2'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Dec.NotSupported', level=3, num='4.9.3'),
+ Heading(name='Null Functions', level=2, num='4.10'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Null', level=3, num='4.10.1'),
+ Heading(name='Tuple Functions', level=2, num='4.11'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Tuple', level=3, num='4.11.1'),
+ Heading(name='Map Functions', level=2, num='4.12'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Map.Supported', level=3, num='4.12.1'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Map.NotSupported', level=3, num='4.12.2'),
+ Heading(name='Create', level=2, num='4.13'),
+ Heading(name='RQ.SRS-020.ClickHouse.Extended.Precision.Create.Table', level=3, num='4.13.1'),
+ Heading(name='References', level=1, num='5'),
+ ),
+ requirements=(
+ RQ_SRS_020_ClickHouse_Extended_Precision,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toInt128,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toUInt128,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toInt256,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toUInt256,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toDecimal256,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_FromMySQL,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_ToMySQL,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arithmetic_Int_Supported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arithmetic_Dec_Supported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arithmetic_Dec_NotSupported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Int_Supported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Int_NotSupported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Dec_Supported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Dec_NotSupported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Comparison,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Logical,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Mathematical_Supported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Mathematical_NotSupported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Int_Supported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Int_NotSupported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Dec_Supported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Dec_NotSupported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Bit_Int_Supported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Bit_Int_NotSupported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Bit_Dec_NotSupported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Null,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Tuple,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Map_Supported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Map_NotSupported,
+ RQ_SRS_020_ClickHouse_Extended_Precision_Create_Table,
+ ),
+ content='''
+# QA-SRS020 ClickHouse Extended Precision Data Types
+# Software Requirements Specification
+
+## Table of Contents
+
+* 1 [Revision History](#revision-history)
+* 2 [Introduction](#introduction)
+* 3 [Terminology](#terminology)
+ * 3.1 [Extended Precision Data Types](#extended-precision-data-types)
+* 4 [Requirements](#requirements)
+ * 4.1 [RQ.SRS-020.ClickHouse.Extended.Precision](#rqsrs-020clickhouseextendedprecision)
+ * 4.2 [Conversion](#conversion)
+ * 4.2.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt128](#rqsrs-020clickhouseextendedprecisionconversiontoint128)
+ * 4.2.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt128](#rqsrs-020clickhouseextendedprecisionconversiontouint128)
+ * 4.2.3 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt256](#rqsrs-020clickhouseextendedprecisionconversiontoint256)
+ * 4.2.4 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt256](#rqsrs-020clickhouseextendedprecisionconversiontouint256)
+ * 4.2.5 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toDecimal256](#rqsrs-020clickhouseextendedprecisionconversiontodecimal256)
+ * 4.2.6 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.FromMySQL](#rqsrs-020clickhouseextendedprecisionconversionfrommysql)
+ * 4.2.7 [RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.ToMySQL](#rqsrs-020clickhouseextendedprecisionconversiontomysql)
+ * 4.3 [Arithmetic](#arithmetic)
+ * 4.3.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Int.Supported](#rqsrs-020clickhouseextendedprecisionarithmeticintsupported)
+ * 4.3.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.Supported](#rqsrs-020clickhouseextendedprecisionarithmeticdecsupported)
+ * 4.3.3 [RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.NotSupported](#rqsrs-020clickhouseextendedprecisionarithmeticdecnotsupported)
+ * 4.4 [Arrays](#arrays)
+ * 4.4.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.Supported](#rqsrs-020clickhouseextendedprecisionarraysintsupported)
+ * 4.4.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.NotSupported](#rqsrs-020clickhouseextendedprecisionarraysintnotsupported)
+ * 4.4.3 [RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.Supported](#rqsrs-020clickhouseextendedprecisionarraysdecsupported)
+ * 4.4.4 [RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.NotSupported](#rqsrs-020clickhouseextendedprecisionarraysdecnotsupported)
+ * 4.5 [Comparison](#comparison)
+ * 4.5.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Comparison](#rqsrs-020clickhouseextendedprecisioncomparison)
+ * 4.6 [Logical Functions](#logical-functions)
+ * 4.6.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Logical](#rqsrs-020clickhouseextendedprecisionlogical)
+ * 4.7 [Mathematical Functions](#mathematical-functions)
+ * 4.7.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.Supported](#rqsrs-020clickhouseextendedprecisionmathematicalsupported)
+ * 4.7.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.NotSupported](#rqsrs-020clickhouseextendedprecisionmathematicalnotsupported)
+ * 4.8 [Rounding Functions](#rounding-functions)
+ * 4.8.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.Supported](#rqsrs-020clickhouseextendedprecisionroundingintsupported)
+ * 4.8.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.NotSupported](#rqsrs-020clickhouseextendedprecisionroundingintnotsupported)
+ * 4.8.3 [RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.Supported](#rqsrs-020clickhouseextendedprecisionroundingdecsupported)
+ * 4.8.4 [RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.NotSupported](#rqsrs-020clickhouseextendedprecisionroundingdecnotsupported)
+ * 4.9 [Bit Functions](#bit-functions)
+ * 4.9.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.Supported](#rqsrs-020clickhouseextendedprecisionbitintsupported)
+ * 4.9.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.NotSupported](#rqsrs-020clickhouseextendedprecisionbitintnotsupported)
+ * 4.9.3 [RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Dec.NotSupported](#rqsrs-020clickhouseextendedprecisionbitdecnotsupported)
+ * 4.10 [Null Functions](#null-functions)
+ * 4.10.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Null](#rqsrs-020clickhouseextendedprecisionnull)
+ * 4.11 [Tuple Functions](#tuple-functions)
+ * 4.11.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Tuple](#rqsrs-020clickhouseextendedprecisiontuple)
+ * 4.12 [Map Functions](#map-functions)
+ * 4.12.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Map.Supported](#rqsrs-020clickhouseextendedprecisionmapsupported)
+ * 4.12.2 [RQ.SRS-020.ClickHouse.Extended.Precision.Map.NotSupported](#rqsrs-020clickhouseextendedprecisionmapnotsupported)
+ * 4.13 [Create](#create)
+ * 4.13.1 [RQ.SRS-020.ClickHouse.Extended.Precision.Create.Table](#rqsrs-020clickhouseextendedprecisioncreatetable)
+* 5 [References](#references)
+
+## Revision History
+
+This document is stored in an electronic form using [Git] source control management software
+hosted in a [GitHub Repository].
+All the updates are tracked using the [Revision History].
+
+## Introduction
+
+This software requirements specification covers requirements related to [ClickHouse]
+using extended precision data types.
+
+## Terminology
+
+### Extended Precision Data Types
+
+Inclusive bounds:
+* Int128 - [-170141183460469231731687303715884105728 : 170141183460469231731687303715884105727]
+* UInt128 - [0 : 340282366920938463463374607431768211455]
+* Int256 - [-57896044618658097711785492504343953926634992332820282019728792003956564819968 : 57896044618658097711785492504343953926634992332820282019728792003956564819967]
+* UInt256 - [0 : 115792089237316195423570985008687907853269984665640564039457584007913129639935]
+
+Exclusive bounds:
+* Decimal256 - (10^(76 - S): 10^(76 - S)), where S is the scale.
+
+## Requirements
+
+### RQ.SRS-020.ClickHouse.Extended.Precision
+version: 1.0
+
+[ClickHouse] SHALL support using [Extended Precision Data Types].
+
+### Conversion
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt128
+version: 1.0
+
+[ClickHouse] SHALL support converting values to `Int128` using the `toInt128` function.
+
+For example,
+
+```sql
+SELECT toInt128(1)
+```
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt128
+version: 1.0
+
+[ClickHouse] SHALL support converting values to `UInt128` format using `toUInt128` function.
+
+For example,
+
+```sql
+SELECT toUInt128(1)
+```
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toInt256
+version: 1.0
+
+[ClickHouse] SHALL support converting values to `Int256` using `toInt256` function.
+
+For example,
+
+```sql
+SELECT toInt256(1)
+```
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toUInt256
+version: 1.0
+
+[ClickHouse] SHALL support converting values to `UInt256` format using `toUInt256` function.
+
+For example,
+
+```sql
+SELECT toUInt256(1)
+```
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.toDecimal256
+version: 1.0
+
+[ClickHouse] SHALL support converting values to `Decimal256` format using `toDecimal256` function.
+
+For example,
+
+```sql
+SELECT toDecimal256(1,2)
+```
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.FromMySQL
+version: 1.0
+
+[ClickHouse] SHALL support converting to [Extended Precision Data Types] from MySQL.
+
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Conversion.ToMySQL
+version: 1.0
+
+[ClickHouse] MAY not support converting from [Extended Precision Data Types] to MySQL.
+
+### Arithmetic
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Int.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using [Arithmetic functions] with Int128, UInt128, Int256, and UInt256.
+
+Arithmetic functions:
+* plus
+* minus
+* multiply
+* divide
+* intDiv
+* intDivOrZero
+* modulo
+* moduloOrZero
+* negate
+* abs
+* gcd
+* lcm
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Arithmetic functions] with Decimal256:
+
+* plus
+* minus
+* multiply
+* divide
+* intDiv
+* intDivOrZero
+* negate
+* abs
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arithmetic.Dec.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Arithmetic functions] with Decimal256:
+
+* modulo
+* moduloOrZero
+* gcd
+* lcm
+
+### Arrays
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Array functions] with Int128, UInt128, Int256, and UInt256.
+
+* empty
+* notEmpty
+* length
+* arrayCount
+* arrayPopBack
+* arrayPopFront
+* arraySort
+* arrayReverseSort
+* arrayUniq
+* arrayJoin
+* arrayDistinct
+* arrayEnumerate
+* arrayEnumerateDense
+* arrayEnumerateUniq
+* arrayReverse
+* reverse
+* arrayFlatten
+* arrayCompact
+* arrayExists
+* arrayAll
+* arrayMin
+* arrayMax
+* arraySum
+* arrayAvg
+* arrayReduce
+* arrayReduceInRanges
+* arrayZip
+* arrayMap
+* arrayFilter
+* arrayFill
+* arrayReverseFill
+* arraySplit
+* arrayFirst
+* arrayFirstIndex
+* arrayConcat
+* hasAll
+* hasAny
+* hasSubstr
+* arrayElement
+* has
+* indexOf
+* countEqual
+* arrayPushBack
+* arrayPushFront
+* arrayResize
+* arraySlice
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Int.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Array functions] with Int128, UInt128, Int256, and UInt256:
+
+* arrayDifference
+* arrayCumSum
+* arrayCumSumNonNegative
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Array functions] with Decimal256:
+
+* empty
+* notEmpty
+* length
+* arrayCount
+* arrayPopBack
+* arrayPopFront
+* arraySort
+* arrayReverseSort
+* arrayUniq
+* arrayJoin
+* arrayDistinct
+* arrayEnumerate
+* arrayEnumerateDense
+* arrayEnumerateUniq
+* arrayReverse
+* reverse
+* arrayFlatten
+* arrayCompact
+* arrayExists
+* arrayAll
+* arrayReduce
+* arrayReduceInRanges
+* arrayZip
+* arrayMap
+* arrayFilter
+* arrayFill
+* arrayReverseFill
+* arraySplit
+* arrayFirst
+* arrayFirstIndex
+* arrayConcat
+* hasAll
+* hasAny
+* hasSubstr
+* arrayElement
+* has
+* indexOf
+* countEqual
+* arrayPushBack
+* arrayPushFront
+* arrayResize
+* arraySlice
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Arrays.Dec.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Array functions] with Decimal256:
+
+* arrayMin
+* arrayMax
+* arraaySum
+* arrayAvg
+* arrayDifference
+* arrayCumSum
+* arrayCumSumNonNegative
+
+### Comparison
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Comparison
+version: 1.0
+
+[ClickHouse] SHALL support using [Comparison functions] with [Extended Precision Data Types].
+
+Comparison functions:
+* equals
+* notEquals
+* less
+* greater
+* lessOrEquals
+* greaterOrEquals
+
+### Logical Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Logical
+version: 1.0
+
+[ClickHouse] MAY not support using [Logical functions] with [Extended Precision Data Types].
+
+Logical functions:
+* and
+* or
+* not
+* xor
+
+### Mathematical Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Mathematical functions] with [Extended Precision Data Types]:
+
+* exp
+* log, ln
+* exp2
+* log2
+* exp10
+* log10
+* sqrt
+* cbrt
+* erf
+* erfc
+* lgamma
+* tgamma
+* sin
+* cos
+* tan
+* asin
+* acos
+* atan
+* cosh
+* acosh
+* sinh
+* asinh
+* tanh
+* atanh
+* log1p
+* sign
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Mathematical.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Mathematical functions] with [Extended Precision Data Types]:
+
+* pow, power
+* intExp2
+* intExp10
+* atan2
+* hypot
+
+### Rounding Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Rounding functions] with Int128, UInt128, Int256, and UInt256:
+
+* floor
+* ceil
+* trunc
+* round
+* roundBankers
+* roundDuration
+* roundAge
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Int.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Rounding functions] with Int128, UInt128, Int256, and UInt256:
+
+* roundDown
+* roundToExp2
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Rounding functions] with Decimal256:
+
+* floor
+* ceil
+* trunc
+* round
+* roundBankers
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Rounding.Dec.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Rounding functions] with Decimal256:
+
+* roundDuration
+* roundAge
+* roundDown
+* roundToExp2
+
+### Bit Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Bit functions] with Int128, UInt128, Int256, and UInt256:
+
+* bitAnd
+* bitOr
+* bitXor
+* bitNot
+* bitShiftLeft
+* bitShiftRight
+* bitCount
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Int.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Bit functions] with Int128, UInt128, Int256, and UInt256:
+
+* bitRotateLeft
+* bitRotateRight
+* bitTest
+* bitTestAll
+* bitTestAny
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Bit.Dec.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using [Bit functions] with Decimal256.
+
+Bit functions:
+* bitAnd
+* bitOr
+* bitXor
+* bitNot
+* bitShiftLeft
+* bitShiftRight
+* bitCount
+* bitRotateLeft
+* bitRotateRight
+* bitTest
+* bitTestAll
+* bitTestAny
+
+### Null Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Null
+version: 1.0
+
+[ClickHouse] SHALL support using [Null functions] with [Extended Precision Data Types].
+
+Null functions:
+* isNull
+* isNotNull
+* coalesce
+* ifNull
+* nullIf
+* assumeNotNull
+* toNullable
+
+### Tuple Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Tuple
+version: 1.0
+
+[ClickHouse] SHALL support using [Tuple functions] with [Extended Precision Data Types].
+
+Tuple functions:
+* tuple
+* tupleElement
+* untuple
+
+### Map Functions
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Map.Supported
+version: 1.0
+
+[ClickHouse] SHALL support using the following [Map functions] with [Extended Precision Data Types]:
+
+* map
+* mapContains
+* mapKeys
+* mapValues
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Map.NotSupported
+version: 1.0
+
+[ClickHouse] MAY not support using the following [Map functions] with [Extended Precision Data Types]:
+
+* mapAdd
+* mapSubtract
+* mapPopulateSeries
+
+### Create
+
+#### RQ.SRS-020.ClickHouse.Extended.Precision.Create.Table
+version: 1.0
+
+[ClickHouse] SHALL support creating table with columns that use [Extended Precision Data Types].
+
+## References
+
+* **ClickHouse:** https://clickhouse.tech
+* **GitHub Repository**: https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/extended_precision_data_types/requirements/requirements.md
+* **Revision History**: https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/extended_precision_data_types/requirements/requirements.md
+* **Git:** https://git-scm.com/
+
+[Extended Precision Data Types]: #extended-precision-data-types
+[Arithmetic functions]: https://clickhouse.tech/docs/en/sql-reference/functions/arithmetic-functions/
+[Array functions]: https://clickhouse.tech/docs/en/sql-reference/functions/array-functions/
+[Comparison functions]: https://clickhouse.tech/docs/en/sql-reference/functions/comparison-functions/
+[Logical Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/logical-functions/
+[Mathematical Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/math-functions/
+[Rounding Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/rounding-functions/
+[Bit Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/bit-functions/
+[Null Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/functions-for-nulls/
+[Tuple Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/tuple-functions/
+[Map Functions]: https://clickhouse.tech/docs/en/sql-reference/functions/tuple-map-functions/
+[SRS]: #srs
+[ClickHouse]: https://clickhouse.tech
+[GitHub Repository]: https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/extended_precision_data_types/requirements/requirements.md
+[Revision History]: https://github.com/ClickHouse/ClickHouse/blob/master/tests/testflows/extended_precision_data_types/requirements/requirements.md
+[Git]: https://git-scm.com/
+[GitHub]: https://github.com
+''')
diff --git a/tests/testflows/extended_precision_data_types/tests/__init__.py b/tests/testflows/extended_precision_data_types/tests/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/tests/testflows/extended_precision_data_types/tests/arithmetic.py b/tests/testflows/extended_precision_data_types/tests/arithmetic.py
new file mode 100644
index 00000000000..d939569d5a7
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/arithmetic.py
@@ -0,0 +1,217 @@
+import os
+import textwrap
+
+from extended_precision_data_types.requirements import *
+from extended_precision_data_types.common import *
+
+funcs = [
+ ('plus', '2'),
+ ('minus', '0'),
+ ('multiply', '1'),
+ ('divide', '1'),
+ ('intDiv', '1'),
+ ('intDivOrZero', '1'),
+ ('modulo', '0'),
+ ('moduloOrZero', '0'),
+ ('negate', '-1'),
+ ('abs', '1'),
+ ('gcd', '1'),
+ ('lcm', '1'),
+]
+
+Examples_list = [tuple(list(func)+list(data_type)+[Name(f'{func[0]} - {data_type[0]}')]) for func in funcs for data_type in data_types]
+Examples_dec_list = [tuple(list(func)+[Name(f'{func[0]} - Decimal256')]) for func in funcs]
+
+@TestOutline
+@Examples('arithmetic_func expected_result int_type min max', Examples_list)
+def inline_check(self, arithmetic_func, expected_result, int_type, min, max, node=None):
+ """Check that arithmetic functions work using inline tests with Int128, UInt128, Int256, and UInt256.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ if arithmetic_func in ['negate','abs']:
+
+ with When(f"I check {arithmetic_func} with {int_type}"):
+ output = node.query(f"SELECT {arithmetic_func}(to{int_type}(1))").output
+ assert output == expected_result, error()
+
+ with When(f"I check {arithmetic_func} with {int_type} max and min value"):
+ execute_query(f"""
+ SELECT {arithmetic_func}(to{int_type}(\'{max}\')), {arithmetic_func}(to{int_type}(\'{min}\'))
+ """)
+
+ else:
+
+ with When(f"I check {arithmetic_func} with {int_type}"):
+ output = node.query(f"SELECT {arithmetic_func}(to{int_type}(1), to{int_type}(1))").output
+ assert output == expected_result, error()
+
+ if arithmetic_func in ['gcd','lcm']:
+
+ if int_type in ['UInt128','UInt256']:
+ exitcode=153
+ else:
+ exitcode=151
+
+ with When(f"I check {arithmetic_func} with {int_type} max and min value"):
+ node.query(f"SELECT {arithmetic_func}(to{int_type}(\'{max}\'), to{int_type}(1)), {arithmetic_func}(to{int_type}(\'{min}\'), to{int_type}(1))",
+ exitcode = exitcode, message = 'Exception:')
+
+ else:
+
+ with When(f"I check {arithmetic_func} with {int_type} max and min value"):
+ execute_query(f"""
+ SELECT {arithmetic_func}(to{int_type}(\'{max}\'), to{int_type}(1)), {arithmetic_func}(to{int_type}(\'{min}\'), to{int_type}(1))
+ """)
+
+@TestOutline
+@Examples('arithmetic_func expected_result int_type min max', Examples_list)
+def table_check(self, arithmetic_func, expected_result, int_type, min, max, node=None):
+ """Check that arithmetic functions work using tables with Int128, UInt128, Int256, and UInt256.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ table_name = f'table_{getuid()}'
+
+ with Given(f"I have a table"):
+ table(name = table_name, data_type = int_type)
+
+ if arithmetic_func in ['negate','abs']:
+
+ for value in [1, min, max]:
+
+ with When(f"I insert {arithmetic_func} with {int_type} {value} into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {arithmetic_func}(to{int_type}(\'{value}\'))")
+
+ with Then(f"I check the table output of {arithmetic_func} with {int_type}"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ else:
+
+ with When(f"I insert {arithmetic_func} with {int_type} into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {arithmetic_func}(to{int_type}(1), to{int_type}(1))")
+
+ with Then("I check that the output matches the expected value"):
+ output = node.query(f"SELECT * FROM {table_name}").output
+ assert output == expected_result, error()
+
+ if arithmetic_func in ['gcd', 'lcm']:
+
+ if int_type in ['UInt128', 'UInt256']:
+
+ with When(f"I insert {arithmetic_func} with {int_type} {min} into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {arithmetic_func}(to{int_type}(\'{min}\'), to{int_type}(1))",
+ exitcode = 153, message = 'Exception:')
+
+ with And(f"I insert {arithmetic_func} with {int_type} {max} into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {arithmetic_func}(to{int_type}(\'{max}\'), to{int_type}(1))")
+
+ else:
+
+ for value in [min, max]:
+
+ with When(f"I insert {arithmetic_func} with {int_type} {value} into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {arithmetic_func}(to{int_type}(\'{value}\'), to{int_type}(1))",
+ exitcode = 151, message = 'Exception:')
+
+ else:
+
+ for value in [min, max]:
+
+ with When(f"I insert {arithmetic_func} with {int_type} {value} into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {arithmetic_func}(to{int_type}(\'{value}\'), to{int_type}(1))")
+
+ with Then(f"I check the table output of {arithmetic_func} with {int_type}"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+@TestOutline
+@Examples('arithmetic_func expected_result', Examples_dec_list)
+def inline_check_dec(self, arithmetic_func, expected_result, node=None):
+ """Check that arithmetic functions work using inline with Decimal256.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ if arithmetic_func is 'negate' or arithmetic_func is 'abs':
+
+ with When(f"I check {arithmetic_func} with toDecimal256"):
+ output = node.query(f"SELECT {arithmetic_func}(toDecimal256(1,0))").output
+ assert output == expected_result, error()
+
+ elif arithmetic_func in ['modulo', 'moduloOrZero', 'gcd', 'lcm']:
+
+ with When(f"I check {arithmetic_func} with toDecimal256"):
+ node.query(f"SELECT {arithmetic_func}(toDecimal256(1,0), toDecimal256(1,0))",
+ exitcode=43, message = 'Exception:')
+
+ else:
+
+ with When(f"I check {arithmetic_func} with toDecimal256"):
+ output = node.query(f"SELECT {arithmetic_func}(toDecimal256(1,0), toDecimal256(1,0))").output
+ assert output == expected_result, error()
+
+@TestOutline
+@Examples('arithmetic_func expected_result', Examples_dec_list)
+def table_check_dec(self, arithmetic_func, expected_result, node=None):
+ """Check that arithmetic functions work using tables with Decimal256.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ table_name = f'table_{getuid()}'
+
+ with Given(f"I have a table"):
+ table(name = table_name, data_type = 'Decimal256(0)')
+
+ if arithmetic_func in ['negate','abs']:
+
+ with When(f"I insert {arithmetic_func} with toDecimal256 into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {arithmetic_func}(toDecimal256(1,0))")
+
+ with Then(f"I check the table for output of {arithmetic_func} with Decimal256"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ elif arithmetic_func in ['modulo', 'moduloOrZero', 'gcd', 'lcm']:
+
+ with When(f"I check {arithmetic_func} with toDecimal256"):
+ node.query(f"INSERT INTO {table_name} SELECT {arithmetic_func}(toDecimal256(1,0), toDecimal256(1,0))",
+ exitcode=43, message = 'Exception:')
+
+ else:
+ with When(f"I insert {arithmetic_func} with toDecimal256 into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {arithmetic_func}(toDecimal256(1,0), toDecimal256(1,0))")
+
+ with Then("I check that the output matches the expected value"):
+ output = node.query(f"SELECT * FROM {table_name}").output
+ assert output == expected_result, error()
+
+@TestFeature
+@Name("arithmetic")
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arithmetic_Int_Supported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arithmetic_Dec_Supported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arithmetic_Dec_NotSupported("1.0"),
+)
+def feature(self, node="clickhouse1", mysql_node="mysql1", stress=None, parallel=None):
+ """Check that arithmetic functions work with extended precision data types.
+ """
+ self.context.node = self.context.cluster.node(node)
+ self.context.mysql_node = self.context.cluster.node(mysql_node)
+
+ with allow_experimental_bigint(self.context.node):
+ Scenario(run = inline_check)
+ Scenario(run = table_check)
+ Scenario(run = inline_check_dec)
+ Scenario(run = table_check_dec)
diff --git a/tests/testflows/extended_precision_data_types/tests/array_tuple_map.py b/tests/testflows/extended_precision_data_types/tests/array_tuple_map.py
new file mode 100644
index 00000000000..6efa122ffdf
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/array_tuple_map.py
@@ -0,0 +1,484 @@
+import uuid
+
+from extended_precision_data_types.requirements import *
+from extended_precision_data_types.common import *
+
+def get_table_name():
+ return "table" + "_" + str(uuid.uuid1()).replace('-', '_')
+
+@TestOutline(Suite)
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Int_Supported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Int_NotSupported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Dec_Supported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Arrays_Dec_NotSupported("1.0"),
+)
+def array_func(self, data_type, node=None):
+ """Check array functions with extended precision data types.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ for func in ['arrayPopBack(',
+ 'arrayPopFront(',
+ 'arraySort(',
+ 'arrayReverseSort(',
+ 'arrayDistinct(',
+ 'arrayEnumerate(',
+ 'arrayEnumerateDense(',
+ 'arrayEnumerateUniq(',
+ 'arrayReverse(',
+ 'reverse(',
+ 'arrayFlatten(',
+ 'arrayCompact(',
+ 'arrayReduceInRanges(\'sum\', [(1, 5)],',
+ 'arrayMap(x -> (x + 2),',
+ 'arrayFill(x -> x=3,',
+ 'arrayReverseFill(x -> x=3,',
+ f'arrayConcat([{to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}],',
+ 'arrayFilter(x -> x == 1, ']:
+
+ with Scenario(f"Inline - {data_type} - {func}"):
+ execute_query(f"""
+ SELECT {func}array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}))
+ """)
+
+ with Scenario(f"Table - {data_type} - {func}"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Array({data_type})')
+
+ with When("I insert the output into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}))")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ for func in ['arraySplit((x, y) -> x=y, [0, 0, 0],']:
+
+ with Scenario(f"Inline - {data_type} - {func}"):
+ execute_query(f"""
+ SELECT {func}array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}))
+ """)
+
+ with Scenario(f"Table - {data_type} - {func}"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Array(Array({data_type}))')
+
+ with When("I insert the output into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}))")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ for func in [f'arrayZip([{to_data_type(data_type,1)}],']:
+
+ with Scenario(f"Inline - {data_type} - {func}"):
+ execute_query(f"""
+ SELECT {func}array({to_data_type(data_type,3)}))
+ """)
+
+ with Scenario(f"Table - {data_type} - {func}"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Array(Tuple({data_type}, {data_type}))')
+
+ with When("I insert the output into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}array({to_data_type(data_type,1)}))")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ for func in ['empty(',
+ 'notEmpty(',
+ 'length(',
+ 'arrayCount(x -> x == 1, ',
+ 'arrayUniq(',
+ 'arrayJoin(',
+ 'arrayExists(x -> x==1,',
+ 'arrayAll(x -> x==1,',
+ 'arrayMin(',
+ 'arrayMax(',
+ 'arraySum(',
+ 'arrayAvg(',
+ 'arrayReduce(\'max\', ',
+ 'arrayFirst(x -> x==3,',
+ 'arrayFirstIndex(x -> x==3,',
+ f'hasAll([{to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}], ',
+ f'hasAny([{to_data_type(data_type,2)}, {to_data_type(data_type,1)}], ',
+ f'hasSubstr([{to_data_type(data_type,2)}, {to_data_type(data_type,1)}], ']:
+
+ if func in ['arrayMin(','arrayMax(','arraySum(', 'arrayAvg('] and data_type in ['Decimal256(0)']:
+
+ with Scenario(f"Inline - {data_type} - {func}"):
+ node.query(f"SELECT {func}array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}))",
+ exitcode = 44, message = 'Exception:')
+
+ with Scenario(f"Table - {data_type} - {func}"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = data_type)
+
+ with When("I insert the output into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}))",
+ exitcode = 44, message = 'Exception:')
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ else:
+
+ with Scenario(f"Inline - {data_type} - {func}"):
+
+ execute_query(f"""
+ SELECT {func}array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}))
+ """)
+
+ with Scenario(f"Table - {data_type} - {func}"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = data_type)
+
+ with When("I insert the output into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}))")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ for func in ['arrayDifference(',
+ 'arrayCumSum(',
+ 'arrayCumSumNonNegative(']:
+
+ if data_type in ['Decimal256(0)']:
+ exitcode = 44
+ else:
+ exitcode = 43
+
+ with Scenario(f"Inline - {data_type} - {func}"):
+ node.query(f"SELECT {func}array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}))",
+ exitcode = exitcode, message = 'Exception:')
+
+ with Scenario(f"Table - {data_type} - {func}"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = data_type)
+
+ with When("I insert the output into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}))",
+ exitcode = exitcode, message = 'Exception:')
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ for func in ['arrayElement']:
+
+ with Scenario(f"Inline - {data_type} - {func}"):
+
+ execute_query(f"""
+ SELECT {func}(array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}), 1)
+ """)
+
+ with Scenario(f"Table - {data_type} - {func}"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = data_type)
+
+ with When("I insert the output into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}), 1)")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ for func in ['arrayPushBack',
+ 'arrayPushFront']:
+
+ with Scenario(f"Inline - {data_type} - {func}"):
+
+ execute_query(f"""
+ SELECT {func}(array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}), {to_data_type(data_type,1)})
+ """)
+
+ with Scenario(f"Table - {data_type} - {func}"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Array({data_type})')
+
+ with When("I insert the output into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}), {to_data_type(data_type,1)})")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ for func in ['arrayResize',
+ 'arraySlice']:
+
+ with Scenario(f"Inline - {data_type} - {func}"):
+
+ execute_query(f"""
+ SELECT {func}(array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}), 1)
+ """)
+
+ with Scenario(f"Table - {data_type} - {func}"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Array({data_type})')
+
+ with When("I insert the output into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}), 1)")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ for func in ['has',
+ 'indexOf',
+ 'countEqual']:
+
+ with Scenario(f"Inline - {data_type} - {func}"):
+ execute_query(f"""
+ SELECT {func}(array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}), NULL)
+ """)
+
+ with Scenario(f"Table - {data_type} - {func}"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = data_type)
+
+ with When("I insert the output into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(array({to_data_type(data_type,3)}, {to_data_type(data_type,2)}, {to_data_type(data_type,1)}), NULL)")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+@TestOutline(Suite)
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Tuple("1.0"),
+)
+def tuple_func(self, data_type, node=None):
+ """Check tuple functions with extended precision data types.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ with Scenario(f"Creating a tuple with {data_type}"):
+ node.query(f"SELECT tuple({to_data_type(data_type,1)}, {to_data_type(data_type,1)}, {to_data_type(data_type,1)})")
+
+ with Scenario(f"Creating a tuple with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Tuple({data_type}, {data_type}, {data_type})')
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT tuple({to_data_type(data_type,1)}, {to_data_type(data_type,1)}, {to_data_type(data_type,1)})")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ with Scenario(f"tupleElement with {data_type}"):
+ node.query(f"SELECT tupleElement(({to_data_type(data_type,1)}, {to_data_type(data_type,1)}), 1)")
+
+ with Scenario(f"tupleElement with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = data_type)
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT tupleElement(({to_data_type(data_type,1)}, {to_data_type(data_type,1)}), 1)")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ with Scenario(f"untuple with {data_type}"):
+ node.query(f"SELECT untuple(({to_data_type(data_type,1)},))")
+
+ with Scenario(f"untuple with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = data_type)
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT untuple(({to_data_type(data_type,1)},))")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ with Scenario(f"tupleHammingDistance with {data_type}"):
+ node.query(f"SELECT tupleHammingDistance(({to_data_type(data_type,1)}, {to_data_type(data_type,1)}), ({to_data_type(data_type,2)}, {to_data_type(data_type,2)}))")
+
+ with Scenario(f"tupleHammingDistance with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = data_type)
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT tupleHammingDistance(({to_data_type(data_type,1)}, {to_data_type(data_type,1)}), ({to_data_type(data_type,2)}, {to_data_type(data_type,2)}))")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+@TestOutline(Suite)
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Map_Supported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Map_NotSupported("1.0"),
+)
+def map_func(self, data_type, node=None):
+ """Check Map functions with extended precision data types.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ with Scenario(f"Creating a map with {data_type}"):
+ node.query(f"SELECT map('key1', {to_data_type(data_type,1)}, 'key2', {to_data_type(data_type,2)})")
+
+ with Scenario(f"Creating a map with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Map(String, {data_type})')
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT map('key1', {to_data_type(data_type,1)}, 'key2', {to_data_type(data_type,2)})")
+
+ execute_query(f"""
+ SELECT * FROM {table_name}
+ """)
+
+ with Scenario(f"mapAdd with {data_type}"):
+ node.query(f"SELECT mapAdd(([{to_data_type(data_type,1)}, {to_data_type(data_type,2)}], [{to_data_type(data_type,1)}, {to_data_type(data_type,2)}]), ([{to_data_type(data_type,1)}, {to_data_type(data_type,2)}], [{to_data_type(data_type,1)}, {to_data_type(data_type,2)}]))",
+ exitcode = 44, message='Exception:')
+
+ with Scenario(f"mapAdd with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Tuple(Array({data_type}), Array({data_type}))')
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT mapAdd(([{to_data_type(data_type,1)}, {to_data_type(data_type,2)}], [{to_data_type(data_type,1)}, {to_data_type(data_type,2)}]), ([{to_data_type(data_type,1)}, {to_data_type(data_type,2)}], [{to_data_type(data_type,1)}, {to_data_type(data_type,2)}]))",
+ exitcode = 44, message='Exception:')
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ with Scenario(f"mapSubtract with {data_type}"):
+ node.query(f"SELECT mapSubtract(([{to_data_type(data_type,1)}, {to_data_type(data_type,2)}], [{to_data_type(data_type,1)}, {to_data_type(data_type,2)}]), ([{to_data_type(data_type,1)}, {to_data_type(data_type,2)}], [{to_data_type(data_type,1)}, {to_data_type(data_type,2)}]))",
+ exitcode = 44, message='Exception:')
+
+ with Scenario(f"mapSubtract with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Tuple(Array({data_type}), Array({data_type}))')
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT mapSubtract(([{to_data_type(data_type,1)}, {to_data_type(data_type,2)}], [{to_data_type(data_type,1)}, {to_data_type(data_type,2)}]), ([{to_data_type(data_type,1)}, {to_data_type(data_type,2)}], [{to_data_type(data_type,1)}, {to_data_type(data_type,2)}]))",
+ exitcode = 44, message='Exception:')
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ with Scenario(f"mapPopulateSeries with {data_type}"):
+ node.query(f"SELECT mapPopulateSeries([1,2,3], [{to_data_type(data_type,1)}, {to_data_type(data_type,2)}, {to_data_type(data_type,3)}], 5)",
+ exitcode = 44, message='Exception:')
+
+ with Scenario(f"mapPopulateSeries with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Tuple(Array({data_type}), Array({data_type}))')
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT mapPopulateSeries([1,2,3], [{to_data_type(data_type,1)}, {to_data_type(data_type,2)}, {to_data_type(data_type,3)}], 5)",
+ exitcode = 44, message='Exception:')
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ with Scenario(f"mapContains with {data_type}"):
+ node.query(f"SELECT mapContains( map('key1', {to_data_type(data_type,1)}, 'key2', {to_data_type(data_type,2)}), 'key1')")
+
+ with Scenario(f"mapContains with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = data_type)
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT mapContains( map('key1', {to_data_type(data_type,1)}, 'key2', {to_data_type(data_type,2)}), 'key1')")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ with Scenario(f"mapKeys with {data_type}"):
+ node.query(f"SELECT mapKeys( map('key1', {to_data_type(data_type,1)}, 'key2', {to_data_type(data_type,2)}))")
+
+ with Scenario(f"mapKeys with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = 'Array(String)')
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT mapKeys( map('key1', {to_data_type(data_type,1)}, 'key2', {to_data_type(data_type,2)}))")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ with Scenario(f"mapValues with {data_type}"):
+ node.query(f"SELECT mapValues( map('key1', {to_data_type(data_type,1)}, 'key2', {to_data_type(data_type,2)}))")
+
+ with Scenario(f"mapValues with {data_type} on a table"):
+ table_name = get_table_name()
+
+ table(name = table_name, data_type = f'Array({data_type})')
+
+ with When("I insert the output into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT mapValues( map('key1', {to_data_type(data_type,1)}, 'key2', {to_data_type(data_type,2)}))")
+
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+@TestFeature
+@Name("array, tuple, map")
+@Examples("data_type",[
+ ('Int128',),
+ ('Int256',),
+ ('UInt128',),
+ ('UInt256',),
+ ('Decimal256(0)',),
+])
+def feature(self, node="clickhouse1", stress=None, parallel=None):
+ """Check that array, tuple, and map functions work with extended precision data types.
+ """
+ self.context.node = self.context.cluster.node(node)
+
+ with allow_experimental_bigint(self.context.node):
+ for example in self.examples:
+ data_type, = example
+
+ with Feature(data_type):
+
+ Suite(test=array_func)(data_type=data_type)
+ Suite(test=tuple_func)(data_type=data_type)
+
+ with Given("I allow experimental map type"):
+ allow_experimental_map_type()
+
+ Suite(test=map_func)(data_type=data_type)
diff --git a/tests/testflows/extended_precision_data_types/tests/bit.py b/tests/testflows/extended_precision_data_types/tests/bit.py
new file mode 100644
index 00000000000..24f63532c74
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/bit.py
@@ -0,0 +1,179 @@
+from extended_precision_data_types.requirements import *
+from extended_precision_data_types.common import *
+from extended_precision_data_types.errors import *
+
+funcs = [
+ ('bitAnd', True, None),
+ ('bitOr', True, None),
+ ('bitXor', True, None),
+ ('bitShiftLeft', True, None),
+ ('bitShiftRight', True, None),
+ ('bitRotateLeft', False, not_implemented_bigints('Bit rotate')),
+ ('bitRotateRight', False, not_implemented_bigints('Bit rotate')),
+ ('bitTest', False, not_implemented_bigints('bitTest')),
+ ('bitTestAll', False, illegal_column()),
+ ('bitTestAny', False, illegal_column()),
+ ('bitNot', True, None),
+ ('bitCount', True, None)
+]
+
+Examples_list = [tuple(list(func)+list(data_type)+[Name(f'{func[0]} - {data_type[0]}')]) for func in funcs for data_type in data_types]
+Examples_dec_list = [tuple(list(func)+[Name(f'{func[0]} - Decimal256')]) for func in funcs]
+
+@TestOutline(Scenario)
+@Examples('func supported error int_type min max', Examples_list)
+def bit_int_inline(self, func, supported, error, int_type, min, max, node=None):
+ """ Check bit functions with Int128, UInt128, Int256, and UInt256 using inline tests.
+ """
+
+ if error is not None:
+ exitcode,message = error
+
+ if node is None:
+ node = self.context.node
+
+ if func in ["bitNot", "bitCount"]:
+
+ with When(f"Check {func} with {int_type}"):
+ execute_query(f"""
+ SELECT {func}(to{int_type}(1)), {func}(to{int_type}(\'{max}\')), {func}(to{int_type}(\'{min}\'))
+ """)
+
+ elif supported:
+
+ with When(f"I check {func} with {int_type}"):
+ execute_query(f"""
+ SELECT {func}(to{int_type}(1), 1), {func}(to{int_type}(\'{max}\'), 1), {func}(to{int_type}(\'{min}\'), 1)
+ """)
+
+ else:
+
+ with When(f"I check {func} with {int_type}"):
+ node.query(f"SELECT {func}(to{int_type}(1), 1), {func}(to{int_type}(\'{max}\'), 1), {func}(to{int_type}(\'{min}\'), 1)",
+ exitcode=exitcode, message = message)
+
+@TestOutline(Scenario)
+@Examples('func supported error int_type min max', Examples_list)
+def bit_int_table(self, func, supported, error, int_type, min, max, node=None):
+ """ Check bit functions with Int128, UInt128, Int256, and UInt256 using table tests.
+ """
+
+ table_name = f"table_{getuid()}"
+
+ if node is None:
+ node = self.context.node
+
+ if error is not None:
+ exitcode,message = error
+
+ with Given(f"I have a table"):
+ table(name = table_name, data_type = int_type)
+
+ if func in ["bitNot", "bitCount"]:
+
+ for value in [1, min, max]:
+
+ with When(f"I insert the output of {func} with {int_type} and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(to{int_type}(\'{value}\'))")
+
+ with Then(f"I check the table with values of {func} and {int_type}"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ elif supported:
+
+ for value in [1, min, max]:
+
+ with When(f"I insert the output of {func} with {int_type} and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(to{int_type}(\'{value}\'), 1)")
+
+ with Then(f"I check the table with values of {func} and {int_type}"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ else:
+
+ for value in [1, min, max]:
+
+ with When(f"I insert the output of {func} with {int_type} and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(to{int_type}(\'{value}\'), 1)",
+ exitcode=exitcode, message=message)
+
+@TestOutline(Scenario)
+@Examples('func supported error', Examples_dec_list)
+def bit_dec_inline(self, func, supported, error, node=None):
+ """ Check bit functions with Decimal256 using inline tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ exitcode, message = illegal_type()
+
+ if node is None:
+ node = self.context.node
+
+ if func in ["bitNot", "bitCount"]:
+
+ with When(f"Check {func} with Decimal256"):
+ node.query(f"SELECT {func}(toDecimal256(1,0)), {func}(toDecimal256(\'{max}\',0)), {func}(toDecimal256(\'{min}\',0))",
+ exitcode=exitcode, message = message)
+
+ else:
+
+ with When(f"I check {func} with Decimal256"):
+ node.query(f"SELECT {func}(toDecimal256(1,0), 1), {func}(toDecimal256(\'{max}\',0), 1), {func}(toDecimal256(\'{min}\',0), 1)",
+ exitcode=exitcode, message = message)
+
+@TestOutline(Scenario)
+@Examples('func supported error', Examples_dec_list)
+def bit_dec_table(self, func, supported, error, node=None):
+ """ Check bit functions with Decimal256 using table tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ table_name = f"table_{getuid()}"
+ exitcode, message = illegal_type()
+
+ if node is None:
+ node = self.context.node
+
+ with Given(f"I have a table"):
+ table(name = table_name, data_type = 'Decimal256(0)')
+
+ if func in ["bitNot", "bitCount"]:
+
+ for value in [1, min, max]:
+
+ with When(f"I insert the output of {func} with Decimal256 and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(toDecimal256(\'{value}\',0))",
+ exitcode=exitcode, message = message)
+
+ else:
+
+ for value in [1, min, max]:
+
+ with When(f"I insert the output of {func} with Decimal256 and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(toDecimal256(\'{value}\',0), 1)",
+ exitcode=exitcode, message=message)
+
+@TestFeature
+@Name("bit")
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Bit_Int_Supported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Bit_Int_NotSupported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Bit_Dec_NotSupported("1.0"),
+)
+def feature(self, node="clickhouse1", mysql_node="mysql1", stress=None, parallel=None):
+ """Check that bit functions work with extended precision data types.
+ """
+ self.context.node = self.context.cluster.node(node)
+ self.context.mysql_node = self.context.cluster.node(mysql_node)
+
+ with allow_experimental_bigint(self.context.node):
+ Scenario(run=bit_int_inline)
+ Scenario(run=bit_int_table)
+ Scenario(run=bit_dec_inline)
+ Scenario(run=bit_dec_table)
diff --git a/tests/testflows/extended_precision_data_types/tests/comparison.py b/tests/testflows/extended_precision_data_types/tests/comparison.py
new file mode 100644
index 00000000000..d3e5dcc0dbd
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/comparison.py
@@ -0,0 +1,110 @@
+from extended_precision_data_types.requirements import *
+from extended_precision_data_types.common import *
+
+funcs = [
+ ('equals',),
+ ('notEquals',),
+ ('less',),
+ ('greater',),
+ ('lessOrEquals',),
+ ('greaterOrEquals',)
+]
+
+Examples_list = [tuple(list(func)+list(data_type)+[Name(f'{func[0]} - {data_type[0]}')]) for func in funcs for data_type in data_types]
+
+@TestOutline(Scenario)
+@Examples('func int_type min max', Examples_list)
+def comp_int_inline(self, func, int_type, min, max, node=None):
+ """Check comparison functions with Int128, UInt128, Int256, and UInt256 using inline tests.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ with When(f"I check {func} with {int_type}"):
+ execute_query(f"""
+ SELECT {func}(to{int_type}(1), to{int_type}(1)), {func}(to{int_type}(\'{max}\'), to{int_type}(\'{min}\'))
+ """)
+
+@TestOutline(Scenario)
+@Examples('func int_type min max', Examples_list)
+def comp_int_table(self, func, int_type, min, max, node=None):
+ """Check comparison functions with Int128, UInt128, Int256, and UInt256 using table tests.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ table_name = f'table_{getuid()}'
+
+ with Given(f"I have a table"):
+ table(name = table_name, data_type = int_type)
+
+ for value in [1, max, min]:
+
+ with When(f"I insert into a table the output {func} with {int_type} and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(to{int_type}(\'{value}\'), to{int_type}(1))")
+
+ with Then(f"I check the table for the output of {func} with {int_type}"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+@TestOutline(Scenario)
+@Examples('func', funcs)
+def comp_dec_inline(self, func, node=None):
+ """Check comparison functions with Decimal256 using inline tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ if node is None:
+ node = self.context.node
+
+ with When(f"I check {func} with Decimal256"):
+ execute_query(f"""
+ SELECT {func}(toDecimal256(1,0), toDecimal256(1,0)), {func}(toDecimal256(\'{max}\',0), toDecimal256(\'{min}\',0))
+ """)
+
+@TestOutline(Scenario)
+@Examples('func', funcs)
+def comp_dec_table(self, func, node=None):
+ """Check comparison functions with Decimal256 using table tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ if node is None:
+ node = self.context.node
+
+ table_name = f'table_{getuid()}'
+
+ with Given(f"I have a table"):
+ table(name = table_name, data_type = 'Decimal256(0)')
+
+ for value in [1, max, min]:
+
+ with When(f"I insert into a table the output {func} with Decimal256 and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(toDecimal256(\'{value}\',0), toDecimal256(1,0))")
+
+ with Then(f"I check the table for the output of {func} with Decimal256"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+@TestFeature
+@Name("comparison")
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Comparison("1.0"),
+)
+def feature(self, node="clickhouse1", mysql_node="mysql1", stress=None, parallel=None):
+ """Check that comparison functions work with extended precision data types.
+ """
+ self.context.node = self.context.cluster.node(node)
+ self.context.mysql_node = self.context.cluster.node(mysql_node)
+
+ with allow_experimental_bigint(self.context.node):
+ Scenario(run=comp_int_inline)
+ Scenario(run=comp_int_table)
+ Scenario(run=comp_dec_inline)
+ Scenario(run=comp_dec_table)
diff --git a/tests/testflows/extended_precision_data_types/tests/conversion.py b/tests/testflows/extended_precision_data_types/tests/conversion.py
new file mode 100644
index 00000000000..e46031ad29f
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/conversion.py
@@ -0,0 +1,275 @@
+import os
+import textwrap
+
+from extended_precision_data_types.requirements import *
+from extended_precision_data_types.common import *
+
+@contextmanager
+def dictionary(name, node, mysql_node):
+ """Create a table in MySQL and use it a source for a dictionary.
+ """
+ try:
+ with Given("table in MySQL"):
+ sql = f"""
+ CREATE TABLE {name}(
+ id INT NOT NULL AUTO_INCREMENT,
+ int128 BIGINT,
+ uint128 BIGINT,
+ int256 BIGINT,
+ uint256 BIGINT,
+ dec256 DECIMAL,
+ PRIMARY KEY ( id )
+ );
+ """
+ with When("I drop the table if exists"):
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user -e \"DROP TABLE IF EXISTS {name};\"", exitcode=0)
+ with And("I create a table"):
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user <<'EOF'{textwrap.dedent(sql)}\nEOF", exitcode=0)
+
+ with And("dictionary that uses MySQL table as the external source"):
+ with When("I drop the dictionary if exists"):
+ node.query(f"DROP DICTIONARY IF EXISTS dict_{name}")
+ with And("I create the dictionary"):
+ sql = f"""
+ CREATE DICTIONARY dict_{name}
+ (
+ id UInt8,
+ int128 Int128,
+ uint128 UInt128,
+ int256 Int256,
+ uint256 UInt256,
+ dec256 Decimal256(0)
+ )
+ PRIMARY KEY id
+ SOURCE(MYSQL(
+ USER 'user'
+ PASSWORD 'password'
+ DB 'db'
+ TABLE '{name}'
+ REPLICA(PRIORITY 1 HOST '{mysql_node.name}' PORT 3306)
+ ))
+ LAYOUT(HASHED())
+ LIFETIME(0)
+ """
+ node.query(textwrap.dedent(sql))
+
+ yield f"dict_{name}"
+
+ finally:
+ with Finally("I drop the dictionary", flags=TE):
+ node.query(f"DROP DICTIONARY IF EXISTS dict_{name}")
+
+ with And("I drop a table in MySQL", flags=TE):
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user -e \"DROP TABLE IF EXISTS {name};\"", exitcode=0)
+
+@contextmanager
+def table(name, node, mysql_node):
+ """Create a table in MySQL and use it a source for a table in ClickHouse.
+ """
+ try:
+ with Given("table in MySQL"):
+ sql = f"""
+ CREATE TABLE {name}(
+ id INT NOT NULL AUTO_INCREMENT,
+ int128 BIGINT,
+ uint128 BIGINT,
+ int256 BIGINT,
+ uint256 BIGINT,
+ dec256 DECIMAL,
+ PRIMARY KEY ( id )
+ );
+ """
+ with When("I drop the table if exists"):
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user -e \"DROP TABLE IF EXISTS {name};\"", exitcode=0)
+
+ with And("I create a table"):
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user <<'EOF'{textwrap.dedent(sql)}\nEOF", exitcode=0)
+
+ with And("table that uses MySQL table as the external source"):
+
+ with When("I drop the table if exists"):
+ node.query(f"DROP TABLE IF EXISTS {name}")
+ with And("I create the table"):
+ sql = f"""
+ CREATE TABLE {name}
+ (
+ id UInt8,
+ int128 Int128,
+ uint128 UInt128,
+ int256 Int256,
+ uint256 UInt256,
+ dec256 Decimal256(0)
+ )
+ ENGINE = MySQL('{mysql_node.name}:3306', 'default', '{name}', 'default', 'password')
+ """
+ node.query(textwrap.dedent(sql))
+
+ yield f"table_{name}"
+
+ finally:
+ with Finally("I drop the table", flags=TE):
+ node.query(f"DROP TABLE IF EXISTS {name}")
+
+ with And("I drop a table in MySQL", flags=TE):
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user -e \"DROP TABLE IF EXISTS {name};\"", exitcode=0)
+
+@contextmanager
+def table_func(name, node, mysql_node):
+ """Create a table in MySQL and use it a source for a table using mysql table function.
+ """
+ try:
+ with Given("table in MySQL"):
+ sql = f"""
+ CREATE TABLE {name}(
+ id INT NOT NULL AUTO_INCREMENT,
+ int128 BIGINT,
+ uint128 BIGINT,
+ int256 BIGINT,
+ uint256 BIGINT,
+ dec256 DECIMAL,
+ PRIMARY KEY ( id )
+ );
+ """
+ with When("I drop the table if exists"):
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user -e \"DROP TABLE IF EXISTS {name};\"", exitcode=0)
+ with And("I create a table"):
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user <<'EOF'{textwrap.dedent(sql)}\nEOF", exitcode=0)
+
+ yield f"mysql('{mysql_node.name}:3306', 'db', '{name}', 'user', 'password')"
+
+ finally:
+
+ with Finally("I drop the table", flags=TE):
+ node.query(f"DROP TABLE IF EXISTS {name}")
+
+ with And("I drop a table in MySQL", flags=TE):
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user -e \"DROP TABLE IF EXISTS {name};\"", exitcode=0)
+
+@TestOutline(Scenario)
+@Examples('int_type min max',[
+ ('Int128', '-170141183460469231731687303715884105728', '170141183460469231731687303715884105727', Requirements(RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toInt128("1.0")), Name('Int128')),
+ ('Int256', '-57896044618658097711785492504343953926634992332820282019728792003956564819968', '57896044618658097711785492504343953926634992332820282019728792003956564819967', Requirements(RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toInt256("1.0")), Name('Int256')),
+ ('UInt128','0','340282366920938463463374607431768211455', Requirements(RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toUInt128("1.0")), Name('UInt128')),
+ ('UInt256', '0', '115792089237316195423570985008687907853269984665640564039457584007913129639935', Requirements(RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toUInt256("1.0")), Name('UInt256')),
+])
+def int_conversion(self, int_type, min, max, node=None):
+ """Check that ClickHouse converts values to Int128.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ with When(f"I convert {min}, {max}, 1 to {int_type}"):
+ output = node.query(f"SELECT to{int_type}(\'{min}\'), to{int_type}(\'{max}\'), to{int_type}(1) format TabSeparatedRaw").output
+ assert output == f'{min}\t{max}\t1', error()
+
+@TestScenario
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_toDecimal256("1.0"),
+)
+def to_decimal256(self, node=None):
+ """Check that ClickHouse converts values to Int128.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ if node is None:
+ node = self.context.node
+
+ for value in [1,min,max]:
+ output = node.query(f"SELECT toDecimal256(\'{value}\',0)").output
+ assert output == str(value), error()
+
+@TestScenario
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_ToMySQL("1.0"),
+)
+def MySQL_table(self, node=None):
+ """Check that ClickHouse converts MySQL values from MySQL table into ClickHouse table.
+ """
+ table_name = f'table_{getuid()}'
+
+ node = self.context.node
+ mysql_node = self.context.mysql_node
+
+ with table(table_name, node, mysql_node):
+
+ with When("I insert parameters values in MySQL"):
+ sql = f"""
+ INSERT INTO {table_name}(int128, uint128, int256, uint256, dec256) VALUES (1,1,1,1,1);
+ """
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user <<'EOF'{textwrap.dedent(sql)}\nEOF", exitcode=0)
+
+ with Then("I select from the table on top of the mysql table"):
+ node.query(f"SELECT * FROM {table_name}",
+ exitcode=50, message='Exception:')
+
+@TestScenario
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_FromMySQL("1.0"),
+)
+def MySQL_func(self, node=None):
+ """Check that ClickHouse converts MySQL values into a ClickHouse table using the MySQL table function.
+ """
+ table_name = f'table_{getuid()}'
+
+ node = self.context.node
+ mysql_node = self.context.mysql_node
+
+ with table_func(table_name, node, mysql_node) as table_function:
+
+ with When("I insert parameters values in MySQL"):
+ sql = f"""
+ INSERT INTO {table_name}(int128, uint128, int256, uint256, dec256) VALUES (1,1,1,1,1);
+ """
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user <<'EOF'{textwrap.dedent(sql)}\nEOF", exitcode=0)
+
+ with And("I make sure the table doesn't exist"):
+ node.query(f"DROP TABLE IF EXISTS {table_name}")
+
+ with And("I create the table"):
+ node.query(f"CREATE TABLE {table_name} (id UInt8, int128 Int128, uint128 UInt128, int256 Int256, uint256 UInt256, dec256 Decimal256(0)) Engine = Memory")
+
+ with And("I insert into the clickhouse table from the mysql table"):
+ node.query(f"INSERT INTO {table_name} SELECT * FROM {table_function}")
+
+ with Then("I select from the clickhouse table"):
+ output = node.query(f"SELECT * FROM {table_name}").output
+ assert output == '1\t1\t1\t1\t1\t1', error()
+
+@TestScenario
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Conversion_ToMySQL("1.0"),
+)
+def MySQL_dict(self, node=None):
+ """Check that ClickHouse converts MySQL values from MySQL table into ClickHouse dictionary.
+ """
+
+ node = self.context.node
+ mysql_node = self.context.mysql_node
+
+ table_name = f'table_{getuid()}'
+
+ with dictionary(table_name, node, mysql_node):
+
+ with When("I insert parameters values in MySQL"):
+ sql = f"""
+ INSERT INTO {table_name}(int128, uint128, int256, uint256, dec256) VALUES (1,1,1,1,1);
+ """
+ mysql_node.command(f"MYSQL_PWD=password mysql -D db -u user <<'EOF'{textwrap.dedent(sql)}\nEOF", exitcode=0)
+
+ with Then("I select from the table on top of the mysql table"):
+ node.query(f"SELECT * FROM dict_{table_name}",
+ exitcode=50, message='Exception:')
+
+@TestFeature
+@Name("conversion")
+def feature(self, node="clickhouse1", mysql_node="mysql1", stress=None, parallel=None):
+ """Check the conversion of extended precision data types.
+ """
+ self.context.node = self.context.cluster.node(node)
+ self.context.mysql_node = self.context.cluster.node(mysql_node)
+
+ for scenario in loads(current_module(), Scenario):
+ with allow_experimental_bigint(self.context.node):
+ Scenario(run=scenario)
diff --git a/tests/testflows/extended_precision_data_types/tests/feature.py b/tests/testflows/extended_precision_data_types/tests/feature.py
new file mode 100644
index 00000000000..83293b61f35
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/feature.py
@@ -0,0 +1,19 @@
+from testflows.core import *
+from testflows.core.name import basename, parentname
+from testflows._core.testtype import TestSubType
+
+@TestFeature
+@Name("tests")
+def feature(self):
+ """Check functions with Int128, Int256, UInt256, and Decimal256.
+ """
+ Feature(run=load("extended_precision_data_types.tests.conversion", "feature"))
+ Feature(run=load("extended_precision_data_types.tests.arithmetic", "feature"))
+ Feature(run=load("extended_precision_data_types.tests.array_tuple_map", "feature"))
+ Feature(run=load("extended_precision_data_types.tests.comparison", "feature"))
+ Feature(run=load("extended_precision_data_types.tests.logical", "feature"))
+ Feature(run=load("extended_precision_data_types.tests.mathematical", "feature"))
+ Feature(run=load("extended_precision_data_types.tests.rounding", "feature"))
+ Feature(run=load("extended_precision_data_types.tests.bit", "feature"))
+ Feature(run=load("extended_precision_data_types.tests.null", "feature"))
+ Feature(run=load("extended_precision_data_types.tests.table", "feature"))
diff --git a/tests/testflows/extended_precision_data_types/tests/logical.py b/tests/testflows/extended_precision_data_types/tests/logical.py
new file mode 100644
index 00000000000..36dbc97da97
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/logical.py
@@ -0,0 +1,99 @@
+from extended_precision_data_types.requirements import *
+from extended_precision_data_types.common import *
+
+funcs = [
+ ('and',),
+ ('or',),
+ ('not',),
+ ('xor',),
+]
+
+Examples_list = [tuple(list(func)+list(data_type)+[Name(f'{func[0]} - {data_type[0]}')]) for func in funcs for data_type in data_types]
+
+@TestOutline(Scenario)
+@Examples('func int_type min max', Examples_list)
+def log_int_inline(self, func, int_type, min, max, node=None):
+ """Check logical functions with Int128, Int256, and UInt256 using inline tests.
+ """
+ table_name = f'table_{getuid()}'
+
+ if node is None:
+ node = self.context.node
+
+ with When(f"Check {func} with {int_type}"):
+ node.query(f"SELECT {func}(to{int_type}(1), to{int_type}(1)), {func}(to{int_type}(\'{max}\'), to{int_type}(1)), {func}(to{int_type}(\'{min}\'), to{int_type}(1))",
+ exitcode=43, message = 'Exception: Illegal type ')
+
+@TestOutline(Scenario)
+@Examples('func int_type min max', Examples_list)
+def log_int_table(self, func, int_type, min, max, node=None):
+ """Check logical functions with Int128, Int256, and UInt256 using table tests.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ table_name = f'table_{getuid()}'
+
+ with Given(f"I have a table"):
+ table(name = table_name, data_type = int_type)
+
+ for value in [1, min, max]:
+
+ with When(f"Check {func} with {int_type} and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(to{int_type}(\'{value}\'), to{int_type}(\'{value}\'))",
+ exitcode=43, message = 'Exception: Illegal type')
+
+@TestOutline(Scenario)
+@Examples('func', funcs)
+def log_dec_inline(self, func, node=None):
+ """Check logical functions with Decimal256 using inline tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ if node is None:
+ node = self.context.node
+
+ with When(f"Check {func} with Decimal256"):
+ node.query(f"SELECT {func}(toDecimal256(1,0), toDecimal256(1,0)), {func}(toDecimal256(\'{max}\',0), toDecimal256(1)), {func}(toDecimal256(\'{min}\',0), toDecimal256(1))",
+ exitcode=43, message = 'Exception: Illegal type ')
+
+@TestOutline(Scenario)
+@Examples('func', funcs)
+def log_dec_table(self, func, node=None):
+ """Check logical functions with Decimal256 using table tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ if node is None:
+ node = self.context.node
+
+ table_name = f'table_{getuid()}'
+
+ with Given(f"I have a table"):
+ table(name = table_name, data_type = 'Decimal256(0)')
+
+ for value in [1, min, max]:
+
+ with When(f"Check {func} with Decimal256 and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(toDecimal256(\'{value}\',0), toDecimal256(\'{value}\',0))",
+ exitcode=43, message = 'Exception: Illegal type ')
+
+@TestFeature
+@Name("logical")
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Logical("1.0"),
+)
+def feature(self, node="clickhouse1", mysql_node="mysql1", stress=None, parallel=None):
+ """Check that comparison functions work with extended precision data types.
+ """
+ self.context.node = self.context.cluster.node(node)
+ self.context.mysql_node = self.context.cluster.node(mysql_node)
+
+ with allow_experimental_bigint(self.context.node):
+ Scenario(run=log_int_inline)
+ Scenario(run=log_int_table)
+ Scenario(run=log_dec_inline)
+ Scenario(run=log_dec_table)
diff --git a/tests/testflows/extended_precision_data_types/tests/mathematical.py b/tests/testflows/extended_precision_data_types/tests/mathematical.py
new file mode 100644
index 00000000000..6062a00a7c9
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/mathematical.py
@@ -0,0 +1,187 @@
+from extended_precision_data_types.requirements import *
+from extended_precision_data_types.common import *
+
+funcs = [
+ ('exp(', 3, 0),
+ ('log(', 0, 0),
+ ('ln(', 0, 0),
+ ('exp2(', 2, 0),
+ ('log2(', 0, 0),
+ ('exp10(', 10, 0),
+ ('log10(', 0, 0),
+ ('sqrt(', 1, 0),
+ ('cbrt(', 1, 0),
+ ('erf(', 1, 0),
+ ('erfc(', 0, 0),
+ ('lgamma(', 0, 0),
+ ('tgamma(', 1, 0),
+ ('sin(', 1, 0),
+ ('cos(', 1, 0),
+ ('tan(', 2, 0),
+ ('asin(', 2, 0),
+ ('acos(', 0, 0),
+ ('atan(', 1, 0),
+ ('intExp2(', 2, 48),
+ ('intExp10(', 10, 48),
+ ('cosh(', 2, 0),
+ ('acosh(', 0, 0),
+ ('sinh(', 1, 0),
+ ('asinh(', 1, 0),
+ ('tanh(', 1, 0),
+ ('atanh(', 'inf', 0),
+ ('log1p(', 1, 0),
+ ('sign(', 1, 0),
+ ('pow(1,', 1, 43),
+ ('power(1,', 1, 43),
+ ('atan2(1,', 1, 43),
+ ('hypot(1,', 1, 43),
+]
+
+Examples_list = [tuple(list(func)+list(data_type)+[Name(f'{func[0]} - {data_type[0]}')]) for func in funcs for data_type in data_types]
+Examples_dec_list = [tuple(list(func)+[Name(f'{func[0]} - Decimal256')]) for func in funcs]
+
+@TestOutline(Scenario)
+@Examples('func expected_result exitcode int_type min max', Examples_list)
+def math_int_inline(self, func, expected_result, exitcode, int_type, min, max, node=None):
+ """Check mathematical functions with Int128, UInt128, Int256, and UInt256 using inline tests.
+ """
+ if node is None:
+ node = self.context.node
+
+ if func in ['intExp2(', 'intExp10(', 'pow(1,', 'power(1,', 'atan2(1,', 'hypot(1,']:
+
+ with When(f"I check {func} with {int_type} using 1, max, and min"):
+ node.query(f"SELECT {func} to{int_type}(1)), {func} to{int_type}(\'{max}\')), {func} to{int_type}(\'{min}\'))",
+ exitcode=exitcode, message = 'Exception:')
+
+ else:
+
+ with When(f"I check {func} with {int_type} using 1"):
+ output = node.query(f"SELECT {func} to{int_type}(1))").output
+ if output == 'inf':
+ pass
+ else:
+ assert round(float(output)) == expected_result, error()
+
+ with And(f"I check {func} with {int_type} using max and min"):
+ execute_query(f"""
+ SELECT {func} to{int_type}(\'{max}\')), {func} to{int_type}(\'{min}\'))
+ """)
+
+@TestOutline(Scenario)
+@Examples('func expected_result exitcode int_type min max', Examples_list)
+def math_int_table(self, func, expected_result, exitcode, int_type, min, max, node=None):
+ """Check mathematical functions with Int128, UInt128, Int256, and UInt256 using table tests.
+ """
+ if node is None:
+ node = self.context.node
+
+ table_name = f'table_{getuid()}'
+
+ with Given(f"I have a table"):
+ table(name = table_name, data_type = f'Nullable({int_type})')
+
+ if func in ['intExp2(', 'intExp10(', 'pow(1,', 'power(1,', 'atan2(1,', 'hypot(1,']:
+
+ for value in [1, max, min]:
+
+ with When(f"I insert the output of {func} with {int_type} using {value} into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func} to{int_type}(\'{value}\'))",
+ exitcode=exitcode, message = 'Exception:')
+
+ else:
+
+ for value in [1, max, min]:
+
+ with And(f"I insert the output of {func} with {int_type} using {value} into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT to{int_type}OrZero( toString({func} to{int_type}(\'{value}\'))))")
+
+ with Then(f"I check the outputs of {func} with {int_type}"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+@TestOutline(Scenario)
+@Examples('func expected_result exitcode', Examples_dec_list)
+def math_dec_inline(self, func, expected_result, exitcode, node=None):
+ """Check mathematical functions with Decimal256 using inline tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ if node is None:
+ node = self.context.node
+
+ if func in ['intExp2(', 'intExp10(', 'pow(1,', 'power(1,', 'atan2(1,', 'hypot(1,']:
+
+ with When(f"I check {func} with Decimal256 using 1, max, and min"):
+ node.query(f"SELECT {func} toDecimal256(1,0)), {func} toDecimal256(\'{max}\',0)), {func} toDecimal256(\'{min}\',0))",
+ exitcode=43, message = 'Exception: Illegal type ')
+
+ else:
+
+ with When(f"I check {func} with Decimal256 using 1"):
+ output = node.query(f"SELECT {func} toDecimal256(1,0))").output
+ if output == 'inf':
+ pass
+ else:
+ assert round(float(output)) == expected_result, error()
+
+ with And(f"I check {func} with Decimal256 using max and min"):
+ execute_query(f"""
+ SELECT {func} toDecimal256(\'{max}\',0)), {func} toDecimal256(\'{min}\',0))
+ """)
+
+@TestOutline(Scenario)
+@Examples('func expected_result exitcode', Examples_dec_list)
+def math_dec_table(self, func, expected_result, exitcode, node=None):
+ """Check mathematical functions with Decimal256 using table tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ if node is None:
+ node = self.context.node
+
+ table_name = f'table_{getuid()}'
+
+ with Given(f"I have a table"):
+ table(name = table_name, data_type = 'Decimal256(0)')
+
+ if func in ['intExp2(', 'intExp10(', 'pow(1,', 'power(1,', 'atan2(1,', 'hypot(1,']:
+
+ for value in [1, max, min]:
+
+ with When(f"I insert the output of {func} with Decimal256 using {value} into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func} toDecimal256(\'{value}\',0))",
+ exitcode=43, message = 'Exception: Illegal type ')
+
+ else:
+
+ for value in [1, max, min]:
+
+ with When(f"I insert the output of {func} with Decimal256 using {value} into a table"):
+ node.query(f"INSERT INTO {table_name} SELECT toDecimal256OrZero( toString({func} toDecimal256(\'{value}\',0))),0)")
+
+ with Then(f"I check the outputs of {func} with Decimal256"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+@TestFeature
+@Name("mathematical")
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Mathematical_Supported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Mathematical_NotSupported("1.0"),
+)
+def feature(self, node="clickhouse1", mysql_node="mysql1", stress=None, parallel=None):
+ """Check that mathematical functions work with extended precision data types.
+ """
+ self.context.node = self.context.cluster.node(node)
+ self.context.mysql_node = self.context.cluster.node(mysql_node)
+
+ with allow_experimental_bigint(self.context.node):
+ Scenario(run=math_int_inline)
+ Scenario(run=math_int_table)
+ Scenario(run=math_dec_inline)
+ Scenario(run=math_dec_table)
diff --git a/tests/testflows/extended_precision_data_types/tests/null.py b/tests/testflows/extended_precision_data_types/tests/null.py
new file mode 100644
index 00000000000..9ddaa94a245
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/null.py
@@ -0,0 +1,119 @@
+from extended_precision_data_types.requirements import *
+from extended_precision_data_types.common import *
+
+funcs = [
+ ('isNull(', 0),
+ ('isNotNull(', 1),
+ ('coalesce(', 1),
+ ('assumeNotNull(', 1),
+ ('toNullable(', 1),
+ ('ifNull(1,', 1),
+ ('nullIf(1,', '\\N'),
+]
+
+Examples_list = [tuple(list(func)+list(data_type)+[Name(f'{func[0]} - {data_type[0]}')]) for func in funcs for data_type in data_types]
+
+@TestOutline(Scenario)
+@Examples('func expected_result int_type min max', Examples_list)
+def null_int_inline(self, func, expected_result, int_type, min, max, node=None):
+ """Check null function with Int128, UInt128, Int256, and UInt256 using inline tests.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ with When(f"I check {func} with {int_type}"):
+ output = node.query(f"SELECT {func} to{int_type}(1))").output
+ assert output == str(expected_result), error()
+
+ with And(f"I check {func} with {int_type} using min and max"):
+ execute_query(f"""
+ SELECT {func} to{int_type}(\'{min}\')), {func} to{int_type}(\'{max}\'))
+ """)
+
+@TestOutline(Scenario)
+@Examples('func expected_result int_type min max', Examples_list)
+def null_int_table(self, func, expected_result, int_type, min, max, node=None):
+ """Check null function with Int128, UInt128, Int256, and UInt256 using table tests.
+ """
+
+ table_name = f"table_{getuid()}"
+
+ if node is None:
+ node = self.context.node
+
+ with Given("I have a table"):
+ table(name = table_name, data_type = f'Nullable({int_type})')
+
+ for value in [1, min, max]:
+
+ with When(f"I insert the output of {func} with {int_type} and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func} to{int_type}(\'{value}\'))")
+
+ with Then(f"I check {func} with {int_type} on the table"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+@TestOutline(Scenario)
+@Examples('func expected_result', funcs)
+def null_dec_inline(self, func, expected_result, node=None):
+ """Check null function with Decimal256 using inline tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ if node is None:
+ node = self.context.node
+
+ with When(f"I check {func} with Decimal256"):
+ output = node.query(f"SELECT {func} toDecimal256(1,0))").output
+ assert output == str(expected_result), error()
+
+ with And(f"I check {func} with Decimal256 using min and max"):
+ execute_query(f"""
+ SELECT {func} toDecimal256(\'{min}\',0)), {func} toDecimal256(\'{max}\',0))
+ """)
+
+@TestOutline(Scenario)
+@Examples('func expected_result', funcs)
+def null_dec_table(self, func, expected_result, node=None):
+ """Check null function with Decimal256 using table tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ table_name = f"table_{getuid()}"
+
+ if node is None:
+ node = self.context.node
+
+ with Given("I have a table"):
+ table(name = table_name, data_type = 'Nullable(Decimal256(0))')
+
+ for value in [1, min, max]:
+
+ with When(f"I insert the output of {func} with Decimal256 and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT {func} toDecimal256(\'{value}\',0))")
+
+ with Then(f"I check {func} with Decimal256 on the table"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+@TestFeature
+@Name("null")
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Null("1.0"),
+)
+def feature(self, node="clickhouse1", mysql_node="mysql1", stress=None, parallel=None):
+ """Check that null functions work with extended precision data types.
+ """
+ self.context.node = self.context.cluster.node(node)
+ self.context.mysql_node = self.context.cluster.node(mysql_node)
+
+ with allow_experimental_bigint(self.context.node):
+ Scenario(run=null_int_inline)
+ Scenario(run=null_int_table)
+ Scenario(run=null_dec_inline)
+ Scenario(run=null_dec_table)
diff --git a/tests/testflows/extended_precision_data_types/tests/rounding.py b/tests/testflows/extended_precision_data_types/tests/rounding.py
new file mode 100644
index 00000000000..f01d6898b32
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/rounding.py
@@ -0,0 +1,191 @@
+from extended_precision_data_types.requirements import *
+from extended_precision_data_types.common import *
+
+funcs = [
+ ('ceil', 1, True),
+ ('floor', 1, True),
+ ('trunc', 1, True),
+ ('round', 1, True),
+ ('roundBankers', 1, True),
+ ('roundToExp2', 1, False),
+ ('roundDuration', 1, True),
+ ('roundAge', 17, True),
+ ('roundDown', 1, False)
+]
+
+Examples_list = [tuple(list(func)+list(data_type)+[Name(f'{func[0]} - {data_type[0]}')]) for func in funcs for data_type in data_types]
+Examples_dec_list = [tuple(list(func)+[Name(f'{func[0]} - Decimal256')]) for func in funcs]
+
+@TestOutline(Scenario)
+@Examples('func expected_result supported int_type min max', Examples_list)
+def round_int_inline(self, func, expected_result, supported, int_type, min, max, node=None):
+ """Check rounding functions with Int128, UInt128, Int256, and UInt256 using inline tests.
+ """
+
+ if node is None:
+ node = self.context.node
+
+ if func is 'roundDown':
+
+ with When(f"I check roundDown with {int_type}"):
+ node.query(f"SELECT roundDown(to{int_type}(1), [0,2]), roundDown(to{int_type}(\'{max}\'), [0,2]), roundDown(to{int_type}(\'{min}\'), [0,2])",
+ exitcode=44, message=f'Exception: Illegal column {int_type} of first argument of function roundDown')
+
+ elif supported:
+
+ with When(f"I check {func} with {int_type}"):
+ output = node.query(f"SELECT {func}(to{int_type}(1))").output
+ assert output == str(expected_result), error()
+
+ with And(f'I check {func} with {int_type} using min and max values'):
+ execute_query(f"""
+ SELECT {func}(to{int_type}(\'{min}\')), {func}(to{int_type}(\'{max}\'))
+ """)
+
+ else:
+
+ with When(f"I check {func} with {int_type}"):
+ node.query(f"SELECT {func}(to{int_type}(1)), {func}(to{int_type}(\'{max}\')), {func}(to{int_type}(\'{min}\'))",
+ exitcode=48, message=f'Exception: {func}() for big integers is not implemented:')
+
+@TestOutline(Scenario)
+@Examples('func expected_result supported int_type min max', Examples_list)
+def round_int_table(self, func, expected_result, supported, int_type, min, max, node=None):
+ """Check rounding functions with Int128, UInt128, Int256, and UInt256 using table tests.
+ """
+
+ table_name = f"table_{getuid()}"
+
+ if node is None:
+ node = self.context.node
+
+ with Given("I have a table"):
+ table(name = table_name, data_type = int_type)
+
+ if func is 'roundDown':
+
+ for value in [1,max,min]:
+
+ with When(f"I check roundDown with {int_type} and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT roundDown(to{int_type}(\'{value}\'), [0,2])",
+ exitcode=44, message=f'Exception: Illegal column {int_type} of first argument of function roundDown')
+
+ elif supported:
+
+ for value in [1,max,min]:
+
+ with When(f"I insert the output of {func} with {int_type} and {value} into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(to{int_type}(\'{value}\'))")
+
+ with Then(f"I select the output of {func} with {int_type} from the table"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ else:
+
+ for value in [1,max,min]:
+
+ with When(f"I insert the output of {func} with {int_type} and {value} into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(to{int_type}(1))",
+ exitcode=48, message=f'Exception: {func}() for big integers is not implemented:')
+
+@TestOutline(Scenario)
+@Examples('func expected_result supported', Examples_dec_list)
+def round_dec_inline(self, func, expected_result, supported, node=None):
+ """Check rounding functions with Decimal256 using inline tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ if node is None:
+ node = self.context.node
+
+ if func is 'roundDown':
+
+ with When(f"I check roundDown with Decimal256"):
+ node.query(f"""SELECT roundDown(toDecimal256(1,0), [toDecimal256(0,0),toDecimal256(2,0)]),
+ roundDown(toDecimal256(\'{max}\',0), [toDecimal256(0,0),toDecimal256(2,0)]),
+ roundDown(toDecimal256(\'{min}\',0), [toDecimal256(0,0),toDecimal256(2,0)])""",
+ exitcode=44, message=f'Exception: Illegal column Decimal256 of first argument of function roundDown')
+
+ elif func not in ['roundDuration', 'roundAge', 'roundToExp2']:
+
+ with When(f"I check {func} with Decimal256"):
+ output = node.query(f"SELECT {func}(toDecimal256(1,0))").output
+ assert output == str(expected_result), error()
+
+ with And(f'I check {func} with Decimal256 using min and max values'):
+ execute_query(f"""
+ SELECT {func}(toDecimal256(\'{min}\',0)), {func}(toDecimal256(\'{max}\',0))
+ """)
+
+ else:
+
+ with When(f"I check {func} with Decimal256"):
+ node.query(f"SELECT {func}(toDecimal256(1,0)), {func}(toDecimal256(\'{max}\',0)), {func}(toDecimal256(\'{min}\',0))",
+ exitcode=43, message=f'Exception: Illegal type Decimal(76, 0)')
+
+@TestOutline(Scenario)
+@Examples('func expected_result supported', Examples_dec_list)
+def round_dec_table(self, func, expected_result, supported, node=None):
+ """Check rounding functions with Decimal256 using table tests.
+ """
+ min = Decimal256_min_max[0]
+ max = Decimal256_min_max[1]
+
+ table_name = f"table_{getuid()}"
+
+ if node is None:
+ node = self.context.node
+
+ with Given("I have a table"):
+ table(name = table_name, data_type = 'Decimal256(0)')
+
+ if func is 'roundDown':
+
+ for value in [1, max, min]:
+
+ with When(f"I check roundDown with Decimal256 and {value}"):
+ node.query(f"INSERT INTO {table_name} SELECT roundDown(toDecimal256(\'{value}\',0), [toDecimal256(0,0),toDecimal256(2,0)])",
+ exitcode=44, message=f'Exception: Illegal column Decimal256 of first argument of function roundDown')
+
+ elif func not in ['roundDuration', 'roundAge', 'roundToExp2']:
+
+ for value in [1, max, min]:
+
+ with When(f"I insert the output of {func} with Decimal256 and {value} into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(toDecimal256(\'{value}\',0))")
+
+ with Then(f"I select the output of {func} with Decimal256 from the table"):
+ execute_query(f"""
+ SELECT * FROM {table_name} ORDER BY a ASC
+ """)
+
+ else:
+
+ for value in [1, max, min]:
+
+ with When(f"I insert the output of {func} with Decimal256 and {value} into the table"):
+ node.query(f"INSERT INTO {table_name} SELECT {func}(toDecimal256(\'{value}\',0))",
+ exitcode=43, message=f'Exception: Illegal type Decimal(76, 0)')
+
+@TestFeature
+@Name("rounding")
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Int_Supported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Int_NotSupported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Dec_Supported("1.0"),
+ RQ_SRS_020_ClickHouse_Extended_Precision_Rounding_Dec_NotSupported("1.0"),
+)
+def feature(self, node="clickhouse1", mysql_node="mysql1", stress=None, parallel=None):
+ """Check that rounding functions work with extended precision data types.
+ """
+ self.context.node = self.context.cluster.node(node)
+ self.context.mysql_node = self.context.cluster.node(mysql_node)
+
+ with allow_experimental_bigint(self.context.node):
+ Scenario(run=round_int_inline)
+ Scenario(run=round_int_table)
+ Scenario(run=round_dec_inline)
+ Scenario(run=round_dec_table)
diff --git a/tests/testflows/extended_precision_data_types/tests/table.py b/tests/testflows/extended_precision_data_types/tests/table.py
new file mode 100644
index 00000000000..1548d6b20c2
--- /dev/null
+++ b/tests/testflows/extended_precision_data_types/tests/table.py
@@ -0,0 +1,35 @@
+from testflows.core import *
+from testflows.asserts import error
+from contextlib import contextmanager
+
+from extended_precision_data_types.requirements import *
+from extended_precision_data_types.common import *
+
+@TestFeature
+@Name("table")
+@Requirements(
+ RQ_SRS_020_ClickHouse_Extended_Precision_Create_Table("1.0"),
+)
+def feature(self, node="clickhouse1", mysql_node="mysql1", stress=None, parallel=None):
+ """Check that clickhouse is able to create a table with extended precision data types.
+ """
+ node = self.context.cluster.node(node)
+
+ table_name = f"table_{getuid()}"
+
+ with allow_experimental_bigint(node):
+
+ try:
+ with When("I create a table with Int128, UInt128, Int256, UInt256, Decimal256"):
+ node.query(f"CREATE TABLE {table_name}(a Int128, b UInt128, c Int256, d UInt256, e Decimal256(0)) ENGINE = Memory")
+
+ with And("I insert values into the table"):
+ node.query(f"INSERT INTO {table_name} VALUES (toInt128(1), toUInt128(1), toInt256(1), toUInt256(1), toDecimal256(1,0))")
+
+ with Then("I select from the table"):
+ output = node.query(f"SELECT * FROM {table_name}").output
+ assert output == '1\t1\t1\t1\t1', error()
+
+ finally:
+ with Finally("I drop the table"):
+ node.query(f"DROP TABLE IF EXISTS {table_name}")
diff --git a/tests/testflows/regression.py b/tests/testflows/regression.py
index 2547463a91d..c7a264a9c27 100755
--- a/tests/testflows/regression.py
+++ b/tests/testflows/regression.py
@@ -30,6 +30,7 @@ def regression(self, local, clickhouse_binary_path, stress=None, parallel=None):
run_scenario(pool, tasks, Feature(test=load("window_functions.regression", "regression")), args)
run_scenario(pool, tasks, Feature(test=load("datetime64_extended_range.regression", "regression")), args)
#run_scenario(pool, tasks, Feature(test=load("kerberos.regression", "regression")), args)
+ run_scenario(pool, tasks, Feature(test=load("extended_precision_data_types.regression", "regression")), args)
finally:
join(tasks)