mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 09:32:06 +00:00
Merge pull request #26579 from vdimir/test-jinja-templates
Support jinja templates for sql files in clickhouse-test
This commit is contained in:
commit
772b18db8a
@ -65,7 +65,7 @@ RUN apt-get update \
|
||||
unixodbc \
|
||||
--yes --no-install-recommends
|
||||
|
||||
RUN pip3 install numpy scipy pandas
|
||||
RUN pip3 install numpy scipy pandas Jinja2
|
||||
|
||||
# This symlink required by gcc to find lld compiler
|
||||
RUN ln -s /usr/bin/lld-${LLVM_VERSION} /usr/bin/ld.lld
|
||||
|
@ -32,7 +32,7 @@ RUN apt-get update -y \
|
||||
postgresql-client \
|
||||
sqlite3
|
||||
|
||||
RUN pip3 install numpy scipy pandas
|
||||
RUN pip3 install numpy scipy pandas Jinja2
|
||||
|
||||
RUN mkdir -p /tmp/clickhouse-odbc-tmp \
|
||||
&& wget -nv -O - ${odbc_driver_url} | tar --strip-components=1 -xz -C /tmp/clickhouse-odbc-tmp \
|
||||
|
3
tests/.gitignore
vendored
3
tests/.gitignore
vendored
@ -3,3 +3,6 @@
|
||||
*.error
|
||||
*.dump
|
||||
test_data
|
||||
|
||||
/queries/0_stateless/*.gen.sql
|
||||
/queries/0_stateless/*.gen.reference
|
||||
|
@ -29,6 +29,13 @@ import string
|
||||
import multiprocessing
|
||||
from contextlib import closing
|
||||
|
||||
USE_JINJA = True
|
||||
try:
|
||||
import jinja2
|
||||
except ImportError:
|
||||
USE_JINJA = False
|
||||
print('WARNING: jinja2 not installed! Template tests will be skipped.')
|
||||
|
||||
DISTRIBUTED_DDL_TIMEOUT_MSG = "is executing longer than distributed_ddl_task_timeout"
|
||||
|
||||
MESSAGES_TO_RETRY = [
|
||||
@ -47,6 +54,8 @@ MESSAGES_TO_RETRY = [
|
||||
|
||||
MAX_RETRIES = 3
|
||||
|
||||
TEST_FILE_EXTENSIONS = ['.sql', '.sql.j2', '.sh', '.py', '.expect']
|
||||
|
||||
class Terminated(KeyboardInterrupt):
|
||||
pass
|
||||
|
||||
@ -407,13 +416,13 @@ def run_tests_array(all_tests_with_params):
|
||||
status = ''
|
||||
if not is_concurrent:
|
||||
sys.stdout.flush()
|
||||
sys.stdout.write("{0:72}".format(name + ": "))
|
||||
sys.stdout.write("{0:72}".format(removesuffix(name, ".gen", ".sql") + ": "))
|
||||
# This flush is needed so you can see the test name of the long
|
||||
# running test before it will finish. But don't do it in parallel
|
||||
# mode, so that the lines don't mix.
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
status = "{0:72}".format(name + ": ")
|
||||
status = "{0:72}".format(removesuffix(name, ".gen", ".sql") + ": ")
|
||||
|
||||
if args.skip and any(s in name for s in args.skip):
|
||||
status += MSG_SKIPPED + " - skip\n"
|
||||
@ -434,6 +443,9 @@ def run_tests_array(all_tests_with_params):
|
||||
or 'race' in name):
|
||||
status += MSG_SKIPPED + " - no long\n"
|
||||
skipped_total += 1
|
||||
elif not USE_JINJA and ext.endswith("j2"):
|
||||
status += MSG_SKIPPED + " - no jinja\n"
|
||||
skipped_total += 1
|
||||
else:
|
||||
disabled_file = os.path.join(suite_dir, name) + '.disabled'
|
||||
|
||||
@ -458,11 +470,10 @@ def run_tests_array(all_tests_with_params):
|
||||
break
|
||||
|
||||
file_suffix = ('.' + str(os.getpid())) if is_concurrent and args.test_runs > 1 else ''
|
||||
reference_file = os.path.join(suite_dir, name) + '.reference'
|
||||
reference_file = get_reference_file(suite_dir, name)
|
||||
stdout_file = os.path.join(suite_tmp_dir, name) + file_suffix + '.stdout'
|
||||
stderr_file = os.path.join(suite_tmp_dir, name) + file_suffix + '.stderr'
|
||||
|
||||
|
||||
testcase_args = configure_testcase_args(args, case_file, suite_tmp_dir, stderr_file)
|
||||
proc, stdout, stderr, total_time = run_single_test(testcase_args, ext, server_logs_level, client_options, case_file, stdout_file, stderr_file)
|
||||
|
||||
@ -535,7 +546,7 @@ def run_tests_array(all_tests_with_params):
|
||||
status += " - having exception:\n{}\n".format(
|
||||
'\n'.join(stdout.split('\n')[:100]))
|
||||
status += 'Database: ' + testcase_args.testcase_database
|
||||
elif not os.path.isfile(reference_file):
|
||||
elif reference_file is None:
|
||||
status += MSG_UNKNOWN
|
||||
status += print_test_time(total_time)
|
||||
status += " - no reference file\n"
|
||||
@ -760,6 +771,97 @@ def do_run_tests(jobs, suite, suite_dir, suite_tmp_dir, all_tests, parallel_test
|
||||
return num_tests
|
||||
|
||||
|
||||
def is_test_from_dir(suite_dir, case):
|
||||
case_file = os.path.join(suite_dir, case)
|
||||
# We could also test for executable files (os.access(case_file, os.X_OK),
|
||||
# but it interferes with 01610_client_spawn_editor.editor, which is invoked
|
||||
# as a query editor in the test, and must be marked as executable.
|
||||
return os.path.isfile(case_file) and any(case_file.endswith(suppotred_ext) for suppotred_ext in TEST_FILE_EXTENSIONS)
|
||||
|
||||
|
||||
def removesuffix(text, *suffixes):
|
||||
"""
|
||||
Added in python 3.9
|
||||
https://www.python.org/dev/peps/pep-0616/
|
||||
|
||||
This version can work with severtal possible suffixes
|
||||
"""
|
||||
for suffix in suffixes:
|
||||
if suffix and text.endswith(suffix):
|
||||
return text[:-len(suffix)]
|
||||
return text
|
||||
|
||||
|
||||
def render_test_template(j2env, suite_dir, test_name):
|
||||
"""
|
||||
Render template for test and reference file if needed
|
||||
"""
|
||||
|
||||
if j2env is None:
|
||||
return test_name
|
||||
|
||||
test_base_name = removesuffix(test_name, ".sql.j2", ".sql")
|
||||
|
||||
reference_file_name = test_base_name + ".reference.j2"
|
||||
reference_file_path = os.path.join(suite_dir, reference_file_name)
|
||||
if os.path.isfile(reference_file_path):
|
||||
tpl = j2env.get_template(reference_file_name)
|
||||
tpl.stream().dump(os.path.join(suite_dir, test_base_name) + ".gen.reference")
|
||||
|
||||
if test_name.endswith(".sql.j2"):
|
||||
tpl = j2env.get_template(test_name)
|
||||
generated_test_name = test_base_name + ".gen.sql"
|
||||
tpl.stream().dump(os.path.join(suite_dir, generated_test_name))
|
||||
return generated_test_name
|
||||
|
||||
return test_name
|
||||
|
||||
|
||||
def get_selected_tests(suite_dir, patterns):
|
||||
"""
|
||||
Find all files with tests, filter, render templates
|
||||
"""
|
||||
|
||||
j2env = jinja2.Environment(
|
||||
loader=jinja2.FileSystemLoader(suite_dir),
|
||||
keep_trailing_newline=True,
|
||||
) if USE_JINJA else None
|
||||
|
||||
for test_name in os.listdir(suite_dir):
|
||||
if not is_test_from_dir(suite_dir, test_name):
|
||||
continue
|
||||
if patterns and not any(re.search(pattern, test_name) for pattern in patterns):
|
||||
continue
|
||||
if USE_JINJA and test_name.endswith(".gen.sql"):
|
||||
continue
|
||||
test_name = render_test_template(j2env, suite_dir, test_name)
|
||||
yield test_name
|
||||
|
||||
|
||||
def get_tests_list(suite_dir, patterns, test_runs, sort_key):
|
||||
"""
|
||||
Return list of tests file names to run
|
||||
"""
|
||||
|
||||
all_tests = list(get_selected_tests(suite_dir, patterns))
|
||||
all_tests = all_tests * test_runs
|
||||
all_tests.sort(key=sort_key)
|
||||
return all_tests
|
||||
|
||||
|
||||
def get_reference_file(suite_dir, name):
|
||||
"""
|
||||
Returns reference file name for specified test
|
||||
"""
|
||||
|
||||
name = removesuffix(name, ".gen")
|
||||
for ext in ['.reference', '.gen.reference']:
|
||||
reference_file = os.path.join(suite_dir, name) + ext
|
||||
if os.path.isfile(reference_file):
|
||||
return reference_file
|
||||
return None
|
||||
|
||||
|
||||
def main(args):
|
||||
global server_died
|
||||
global stop_time
|
||||
@ -844,14 +946,6 @@ def main(args):
|
||||
create_common_database(args, args.database)
|
||||
create_common_database(args, "test")
|
||||
|
||||
def is_test_from_dir(suite_dir, case):
|
||||
case_file = os.path.join(suite_dir, case)
|
||||
(_, ext) = os.path.splitext(case)
|
||||
# We could also test for executable files (os.access(case_file, os.X_OK),
|
||||
# but it interferes with 01610_client_spawn_editor.editor, which is invoked
|
||||
# as a query editor in the test, and must be marked as executable.
|
||||
return os.path.isfile(case_file) and (ext in ['.sql', '.sh', '.py', '.expect'])
|
||||
|
||||
def sute_key_func(item):
|
||||
if args.order == 'random':
|
||||
return random.random()
|
||||
@ -911,12 +1005,7 @@ def main(args):
|
||||
except ValueError:
|
||||
return 99997
|
||||
|
||||
all_tests = os.listdir(suite_dir)
|
||||
all_tests = [case for case in all_tests if is_test_from_dir(suite_dir, case)]
|
||||
if args.test:
|
||||
all_tests = [t for t in all_tests if any(re.search(r, t) for r in args.test)]
|
||||
all_tests = all_tests * args.test_runs
|
||||
all_tests.sort(key=key_func)
|
||||
all_tests = get_tests_list(suite_dir, args.test, args.test_runs, key_func)
|
||||
|
||||
jobs = args.jobs
|
||||
parallel_tests = []
|
||||
|
@ -1,102 +0,0 @@
|
||||
=== hash ===
|
||||
= full =
|
||||
1 1
|
||||
2 2
|
||||
-1 1
|
||||
1 \N
|
||||
1 257
|
||||
1 -1
|
||||
= left =
|
||||
1 1
|
||||
2 2
|
||||
= right =
|
||||
1 1
|
||||
-1 1
|
||||
1 \N
|
||||
1 257
|
||||
1 -1
|
||||
= inner =
|
||||
1 1
|
||||
= full =
|
||||
1 1 1 1
|
||||
2 2 0 \N
|
||||
0 0 -1 1
|
||||
0 0 1 \N
|
||||
0 0 1 257
|
||||
0 0 1 -1
|
||||
= left =
|
||||
1 1 1 1
|
||||
2 2 0 \N
|
||||
= right =
|
||||
1 1 1 1
|
||||
0 0 -1 1
|
||||
0 0 1 \N
|
||||
0 0 1 257
|
||||
0 0 1 -1
|
||||
= inner =
|
||||
1 1 1 1
|
||||
= agg =
|
||||
5 260
|
||||
3 3
|
||||
3 258
|
||||
1 1
|
||||
5 260
|
||||
3 3
|
||||
3 258
|
||||
1 1
|
||||
= types =
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
=== partial_merge ===
|
||||
= full =
|
||||
1 1
|
||||
2 2
|
||||
-1 1
|
||||
1 \N
|
||||
1 257
|
||||
1 -1
|
||||
= left =
|
||||
1 1
|
||||
2 2
|
||||
= right =
|
||||
1 1
|
||||
-1 1
|
||||
1 \N
|
||||
1 257
|
||||
1 -1
|
||||
= inner =
|
||||
1 1
|
||||
= full =
|
||||
1 1 1 1
|
||||
2 2 0 \N
|
||||
0 0 -1 1
|
||||
0 0 1 \N
|
||||
0 0 1 257
|
||||
0 0 1 -1
|
||||
= left =
|
||||
1 1 1 1
|
||||
2 2 0 \N
|
||||
= right =
|
||||
1 1 1 1
|
||||
0 0 -1 1
|
||||
0 0 1 \N
|
||||
0 0 1 257
|
||||
0 0 1 -1
|
||||
= inner =
|
||||
1 1 1 1
|
||||
= agg =
|
||||
5 260
|
||||
3 3
|
||||
3 258
|
||||
1 1
|
||||
5 260
|
||||
3 3
|
||||
3 258
|
||||
1 1
|
||||
= types =
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
@ -0,0 +1,53 @@
|
||||
{% for join_type in ['hash', 'partial_merge'] -%}
|
||||
=== {{ join_type }} ===
|
||||
= full =
|
||||
1 1
|
||||
2 2
|
||||
-1 1
|
||||
1 \N
|
||||
1 257
|
||||
1 -1
|
||||
= left =
|
||||
1 1
|
||||
2 2
|
||||
= right =
|
||||
1 1
|
||||
-1 1
|
||||
1 \N
|
||||
1 257
|
||||
1 -1
|
||||
= inner =
|
||||
1 1
|
||||
= full =
|
||||
1 1 1 1
|
||||
2 2 0 \N
|
||||
0 0 -1 1
|
||||
0 0 1 \N
|
||||
0 0 1 257
|
||||
0 0 1 -1
|
||||
= left =
|
||||
1 1 1 1
|
||||
2 2 0 \N
|
||||
= right =
|
||||
1 1 1 1
|
||||
0 0 -1 1
|
||||
0 0 1 \N
|
||||
0 0 1 257
|
||||
0 0 1 -1
|
||||
= inner =
|
||||
1 1 1 1
|
||||
= agg =
|
||||
5 260
|
||||
3 3
|
||||
3 258
|
||||
1 1
|
||||
5 260
|
||||
3 3
|
||||
3 258
|
||||
1 1
|
||||
= types =
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
{% endfor -%}
|
@ -6,9 +6,11 @@ CREATE TABLE t_ab2 (id Nullable(Int32), a Int16, b Nullable(Int64)) ENGINE = Tin
|
||||
INSERT INTO t_ab1 VALUES (0, 1, 1), (1, 2, 2);
|
||||
INSERT INTO t_ab2 VALUES (2, -1, 1), (3, 1, NULL), (4, 1, 257), (5, 1, -1), (6, 1, 1);
|
||||
|
||||
SELECT '=== hash ===';
|
||||
{% for join_type in ['hash', 'partial_merge'] -%}
|
||||
|
||||
SET join_algorithm = 'hash';
|
||||
SELECT '=== {{ join_type }} ===';
|
||||
|
||||
SET join_algorithm = '{{ join_type }}';
|
||||
|
||||
SELECT '= full =';
|
||||
SELECT a, b FROM t_ab1 FULL JOIN t_ab2 USING (a, b) ORDER BY ifNull(t_ab1.id, t_ab2.id);
|
||||
@ -49,48 +51,7 @@ SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(b)) == 'Nullable(Int64)'
|
||||
SELECT * FROM ( SELECT a, b as "CAST(a, Int32)" FROM t_ab1 ) t_ab1 FULL JOIN t_ab2 ON (t_ab1.a == t_ab2.a); -- { serverError 44 }
|
||||
SELECT * FROM ( SELECT a, b as "CAST(a, Int32)" FROM t_ab1 ) t_ab1 FULL JOIN t_ab2 USING (a) FORMAT Null;
|
||||
|
||||
SELECT '=== partial_merge ===';
|
||||
|
||||
SET join_algorithm = 'partial_merge';
|
||||
|
||||
SELECT '= full =';
|
||||
SELECT a, b FROM t_ab1 FULL JOIN t_ab2 USING (a, b) ORDER BY ifNull(t_ab1.id, t_ab2.id);
|
||||
SELECT '= left =';
|
||||
SELECT a, b FROM t_ab1 LEFT JOIN t_ab2 USING (a, b) ORDER BY ifNull(t_ab1.id, t_ab2.id);
|
||||
SELECT '= right =';
|
||||
SELECT a, b FROM t_ab1 RIGHT JOIN t_ab2 USING (a, b) ORDER BY ifNull(t_ab1.id, t_ab2.id);
|
||||
SELECT '= inner =';
|
||||
SELECT a, b FROM t_ab1 INNER JOIN t_ab2 USING (a, b) ORDER BY ifNull(t_ab1.id, t_ab2.id);
|
||||
|
||||
SELECT '= full =';
|
||||
SELECT a, b, t_ab2.a, t_ab2.b FROM t_ab1 FULL JOIN t_ab2 ON (t_ab1.a == t_ab2.a AND t_ab1.b == t_ab2.b) ORDER BY ifNull(t_ab1.id, t_ab2.id);
|
||||
SELECT '= left =';
|
||||
SELECT a, b, t_ab2.a, t_ab2.b FROM t_ab1 LEFT JOIN t_ab2 ON (t_ab1.a == t_ab2.a AND t_ab1.b == t_ab2.b) ORDER BY ifNull(t_ab1.id, t_ab2.id);
|
||||
SELECT '= right =';
|
||||
SELECT a, b, t_ab2.a, t_ab2.b FROM t_ab1 RIGHT JOIN t_ab2 ON (t_ab1.a == t_ab2.a AND t_ab1.b == t_ab2.b) ORDER BY ifNull(t_ab1.id, t_ab2.id);
|
||||
SELECT '= inner =';
|
||||
SELECT a, b, t_ab2.a, t_ab2.b FROM t_ab1 INNER JOIN t_ab2 ON (t_ab1.a == t_ab2.a AND t_ab1.b == t_ab2.b) ORDER BY ifNull(t_ab1.id, t_ab2.id);
|
||||
|
||||
SELECT '= agg =';
|
||||
SELECT sum(a), sum(b) FROM t_ab1 FULL JOIN t_ab2 USING (a, b);
|
||||
SELECT sum(a), sum(b) FROM t_ab1 LEFT JOIN t_ab2 USING (a, b);
|
||||
SELECT sum(a), sum(b) FROM t_ab1 RIGHT JOIN t_ab2 USING (a, b);
|
||||
SELECT sum(a), sum(b) FROM t_ab1 INNER JOIN t_ab2 USING (a, b);
|
||||
|
||||
SELECT sum(a) + sum(t_ab2.a) - 1, sum(b) + sum(t_ab2.b) - 1 FROM t_ab1 FULL JOIN t_ab2 ON (t_ab1.a == t_ab2.a AND t_ab1.b == t_ab2.b);
|
||||
SELECT sum(a) + sum(t_ab2.a) - 1, sum(b) + sum(t_ab2.b) - 1 FROM t_ab1 LEFT JOIN t_ab2 ON (t_ab1.a == t_ab2.a AND t_ab1.b == t_ab2.b);
|
||||
SELECT sum(a) + sum(t_ab2.a) - 1, sum(b) + sum(t_ab2.b) - 1 FROM t_ab1 RIGHT JOIN t_ab2 ON (t_ab1.a == t_ab2.a AND t_ab1.b == t_ab2.b);
|
||||
SELECT sum(a) + sum(t_ab2.a) - 1, sum(b) + sum(t_ab2.b) - 1 FROM t_ab1 INNER JOIN t_ab2 ON (t_ab1.a == t_ab2.a AND t_ab1.b == t_ab2.b);
|
||||
|
||||
SELECT '= types =';
|
||||
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(b)) == 'Nullable(Int64)' FROM t_ab1 FULL JOIN t_ab2 USING (a, b);
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(b)) == 'Nullable(Int64)' FROM t_ab1 LEFT JOIN t_ab2 USING (a, b);
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(b)) == 'Nullable(Int64)' FROM t_ab1 RIGHT JOIN t_ab2 USING (a, b);
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(b)) == 'Nullable(Int64)' FROM t_ab1 INNER JOIN t_ab2 USING (a, b);
|
||||
|
||||
SELECT * FROM ( SELECT a, b as "CAST(a, Int32)" FROM t_ab1 ) t_ab1 FULL JOIN t_ab2 ON (t_ab1.a == t_ab2.a); -- { serverError 44 }
|
||||
SELECT * FROM ( SELECT a, b as "CAST(a, Int32)" FROM t_ab1 ) t_ab1 FULL JOIN t_ab2 USING (a) FORMAT Null;
|
||||
{% endfor %}
|
||||
|
||||
DROP TABLE IF EXISTS t_ab1;
|
||||
DROP TABLE IF EXISTS t_ab2;
|
@ -400,7 +400,7 @@
|
||||
1
|
||||
1
|
||||
1
|
||||
=== switch ===
|
||||
=== auto ===
|
||||
= full =
|
||||
-4 0 196
|
||||
-3 0 197
|
||||
|
@ -7,159 +7,14 @@ CREATE TABLE t2 (a Int16, b Nullable(Int64)) ENGINE = TinyLog;
|
||||
INSERT INTO t1 SELECT number as a, 100 + number as b FROM system.numbers LIMIT 1, 10;
|
||||
INSERT INTO t2 SELECT number - 5 as a, 200 + number - 5 as b FROM system.numbers LIMIT 1, 10;
|
||||
|
||||
SELECT '=== hash ===';
|
||||
SET join_algorithm = 'hash';
|
||||
{% for join_type in ['hash', 'partial_merge', 'auto'] -%}
|
||||
|
||||
SELECT '= full =';
|
||||
SELECT a, b, t2.b FROM t1 FULL JOIN t2 USING (a) ORDER BY (a);
|
||||
SELECT '= left =';
|
||||
SELECT a, b, t2.b FROM t1 LEFT JOIN t2 USING (a) ORDER BY (a);
|
||||
SELECT '= right =';
|
||||
SELECT a, b, t2.b FROM t1 RIGHT JOIN t2 USING (a) ORDER BY (a);
|
||||
SELECT '= inner =';
|
||||
SELECT a, b, t2.b FROM t1 INNER JOIN t2 USING (a) ORDER BY (a);
|
||||
SELECT '=== {{ join_type }} ===';
|
||||
SET join_algorithm = '{{ join_type }}';
|
||||
|
||||
SELECT '= full =';
|
||||
SELECT a, t1.a, t2.a FROM t1 FULL JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= left =';
|
||||
SELECT a, t1.a, t2.a FROM t1 LEFT JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= right =';
|
||||
SELECT a, t1.a, t2.a FROM t1 RIGHT JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= inner =';
|
||||
SELECT a, t1.a, t2.a FROM t1 INNER JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
|
||||
|
||||
SELECT '= join on =';
|
||||
SELECT '= full =';
|
||||
SELECT a, b, t2.a, t2.b FROM t1 FULL JOIN t2 ON (t1.a == t2.a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= left =';
|
||||
SELECT a, b, t2.a, t2.b FROM t1 LEFT JOIN t2 ON (t1.a == t2.a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= right =';
|
||||
SELECT a, b, t2.a, t2.b FROM t1 RIGHT JOIN t2 ON (t1.a == t2.a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= inner =';
|
||||
SELECT a, b, t2.a, t2.b FROM t1 INNER JOIN t2 ON (t1.a == t2.a) ORDER BY (t1.a, t2.a);
|
||||
|
||||
SELECT '= full =';
|
||||
SELECT * FROM t1 FULL JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= left =';
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= right =';
|
||||
SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= inner =';
|
||||
SELECT * FROM t1 INNER JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) ORDER BY (t1.a, t2.a);
|
||||
|
||||
-- Int64 and UInt64 has no supertype
|
||||
SELECT * FROM t1 FULL JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
|
||||
SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
|
||||
SELECT * FROM t1 INNER JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
|
||||
|
||||
SELECT '= agg =';
|
||||
SELECT sum(a) == 7 FROM t1 FULL JOIN t2 USING (a) WHERE b > 102 AND t2.b <= 204;
|
||||
SELECT sum(a) == 7 FROM t1 INNER JOIN t2 USING (a) WHERE b > 102 AND t2.b <= 204;
|
||||
|
||||
SELECT sum(b) = 103 FROM t1 LEFT JOIN t2 USING (a) WHERE b > 102 AND t2.b < 204;
|
||||
SELECT sum(t2.b) = 203 FROM t1 RIGHT JOIN t2 USING (a) WHERE b > 102 AND t2.b < 204;
|
||||
|
||||
SELECT sum(a) == 2 + 3 + 4 FROM t1 FULL JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) WHERE t1.b < 105 AND t2.b > 201;
|
||||
SELECT sum(a) == 55 FROM t1 FULL JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) WHERE 1;
|
||||
|
||||
SELECT a > 0, sum(a), sum(b) FROM t1 FULL JOIN t2 USING (a) GROUP BY (a > 0) ORDER BY a > 0;
|
||||
SELECT a > 0, sum(a), sum(t2.a), sum(b), sum(t2.b) FROM t1 FULL JOIN t2 ON (t1.a == t2.a) GROUP BY (a > 0) ORDER BY a > 0;
|
||||
|
||||
SELECT '= types =';
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 FULL JOIN t2 USING (a);
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 LEFT JOIN t2 USING (a);
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 RIGHT JOIN t2 USING (a);
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 INNER JOIN t2 USING (a);
|
||||
|
||||
SELECT toTypeName(any(a)) == 'Int32' AND toTypeName(any(t2.a)) == 'Int32' FROM t1 FULL JOIN t2 USING (a);
|
||||
SELECT min(toTypeName(a) == 'Int32' AND toTypeName(t2.a) == 'Int32') FROM t1 FULL JOIN t2 USING (a);
|
||||
|
||||
SELECT any(toTypeName(a)) == 'UInt16' AND any(toTypeName(t2.a)) == 'Int16' FROM t1 FULL JOIN t2 ON (t1.a == t2.a);
|
||||
SELECT any(toTypeName(a)) == 'UInt16' AND any(toTypeName(t2.a)) == 'Int16' FROM t1 LEFT JOIN t2 ON (t1.a == t2.a);
|
||||
SELECT any(toTypeName(a)) == 'UInt16' AND any(toTypeName(t2.a)) == 'Int16' FROM t1 RIGHT JOIN t2 ON (t1.a == t2.a);
|
||||
SELECT any(toTypeName(a)) == 'UInt16' AND any(toTypeName(t2.a)) == 'Int16' FROM t1 INNER JOIN t2 ON (t1.a == t2.a);
|
||||
SELECT toTypeName(any(a)) == 'UInt16' AND toTypeName(any(t2.a)) == 'Int16' FROM t1 FULL JOIN t2 ON (t1.a == t2.a);
|
||||
|
||||
SELECT '=== partial_merge ===';
|
||||
|
||||
SET join_algorithm = 'partial_merge';
|
||||
|
||||
SELECT '= full =';
|
||||
SELECT a, b, t2.b FROM t1 FULL JOIN t2 USING (a) ORDER BY (a);
|
||||
SELECT '= left =';
|
||||
SELECT a, b, t2.b FROM t1 LEFT JOIN t2 USING (a) ORDER BY (a);
|
||||
SELECT '= right =';
|
||||
SELECT a, b, t2.b FROM t1 RIGHT JOIN t2 USING (a) ORDER BY (a);
|
||||
SELECT '= inner =';
|
||||
SELECT a, b, t2.b FROM t1 INNER JOIN t2 USING (a) ORDER BY (a);
|
||||
|
||||
SELECT '= full =';
|
||||
SELECT a, t1.a, t2.a FROM t1 FULL JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= left =';
|
||||
SELECT a, t1.a, t2.a FROM t1 LEFT JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= right =';
|
||||
SELECT a, t1.a, t2.a FROM t1 RIGHT JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= inner =';
|
||||
SELECT a, t1.a, t2.a FROM t1 INNER JOIN t2 USING (a) ORDER BY (t1.a, t2.a);
|
||||
|
||||
SELECT '= join on =';
|
||||
SELECT '= full =';
|
||||
SELECT a, b, t2.a, t2.b FROM t1 FULL JOIN t2 ON (t1.a == t2.a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= left =';
|
||||
SELECT a, b, t2.a, t2.b FROM t1 LEFT JOIN t2 ON (t1.a == t2.a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= right =';
|
||||
SELECT a, b, t2.a, t2.b FROM t1 RIGHT JOIN t2 ON (t1.a == t2.a) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= inner =';
|
||||
SELECT a, b, t2.a, t2.b FROM t1 INNER JOIN t2 ON (t1.a == t2.a) ORDER BY (t1.a, t2.a);
|
||||
|
||||
SELECT '= full =';
|
||||
SELECT * FROM t1 FULL JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= left =';
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= right =';
|
||||
SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) ORDER BY (t1.a, t2.a);
|
||||
SELECT '= inner =';
|
||||
SELECT * FROM t1 INNER JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) ORDER BY (t1.a, t2.a);
|
||||
|
||||
-- Int64 and UInt64 has no supertype
|
||||
SELECT * FROM t1 FULL JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
|
||||
SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
|
||||
SELECT * FROM t1 INNER JOIN t2 ON (t1.a + t1.b + 100 = t2.a + t2.b) ORDER BY (t1.a, t2.a); -- { serverError 53 }
|
||||
|
||||
SELECT '= agg =';
|
||||
SELECT sum(a) == 7 FROM t1 FULL JOIN t2 USING (a) WHERE b > 102 AND t2.b <= 204;
|
||||
SELECT sum(a) == 7 FROM t1 INNER JOIN t2 USING (a) WHERE b > 102 AND t2.b <= 204;
|
||||
|
||||
SELECT sum(b) = 103 FROM t1 LEFT JOIN t2 USING (a) WHERE b > 102 AND t2.b < 204;
|
||||
SELECT sum(t2.b) = 203 FROM t1 RIGHT JOIN t2 USING (a) WHERE b > 102 AND t2.b < 204;
|
||||
|
||||
SELECT sum(a) == 2 + 3 + 4 FROM t1 FULL JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) WHERE t1.b < 105 AND t2.b > 201;
|
||||
SELECT sum(a) == 55 FROM t1 FULL JOIN t2 ON (t1.a + t1.b = t2.a + t2.b - 100) WHERE 1;
|
||||
|
||||
SELECT a > 0, sum(a), sum(b) FROM t1 FULL JOIN t2 USING (a) GROUP BY (a > 0) ORDER BY a > 0;
|
||||
SELECT a > 0, sum(a), sum(t2.a), sum(b), sum(t2.b) FROM t1 FULL JOIN t2 ON (t1.a == t2.a) GROUP BY (a > 0) ORDER BY a > 0;
|
||||
|
||||
SELECT '= types =';
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 FULL JOIN t2 USING (a);
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 LEFT JOIN t2 USING (a);
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 RIGHT JOIN t2 USING (a);
|
||||
SELECT any(toTypeName(a)) == 'Int32' AND any(toTypeName(t2.a)) == 'Int32' FROM t1 INNER JOIN t2 USING (a);
|
||||
|
||||
SELECT toTypeName(any(a)) == 'Int32' AND toTypeName(any(t2.a)) == 'Int32' FROM t1 FULL JOIN t2 USING (a);
|
||||
SELECT min(toTypeName(a) == 'Int32' AND toTypeName(t2.a) == 'Int32') FROM t1 FULL JOIN t2 USING (a);
|
||||
|
||||
SELECT any(toTypeName(a)) == 'UInt16' AND any(toTypeName(t2.a)) == 'Int16' FROM t1 FULL JOIN t2 ON (t1.a == t2.a);
|
||||
SELECT any(toTypeName(a)) == 'UInt16' AND any(toTypeName(t2.a)) == 'Int16' FROM t1 LEFT JOIN t2 ON (t1.a == t2.a);
|
||||
SELECT any(toTypeName(a)) == 'UInt16' AND any(toTypeName(t2.a)) == 'Int16' FROM t1 RIGHT JOIN t2 ON (t1.a == t2.a);
|
||||
SELECT any(toTypeName(a)) == 'UInt16' AND any(toTypeName(t2.a)) == 'Int16' FROM t1 INNER JOIN t2 ON (t1.a == t2.a);
|
||||
SELECT toTypeName(any(a)) == 'UInt16' AND toTypeName(any(t2.a)) == 'Int16' FROM t1 FULL JOIN t2 ON (t1.a == t2.a);
|
||||
|
||||
SELECT '=== switch ===';
|
||||
|
||||
SET join_algorithm = 'auto';
|
||||
{% if join_type == 'auto' -%}
|
||||
SET max_bytes_in_join = 100;
|
||||
{% endif -%}
|
||||
|
||||
SELECT '= full =';
|
||||
SELECT a, b, t2.b FROM t1 FULL JOIN t2 USING (a) ORDER BY (a);
|
||||
@ -232,7 +87,11 @@ SELECT any(toTypeName(a)) == 'UInt16' AND any(toTypeName(t2.a)) == 'Int16' FROM
|
||||
SELECT any(toTypeName(a)) == 'UInt16' AND any(toTypeName(t2.a)) == 'Int16' FROM t1 INNER JOIN t2 ON (t1.a == t2.a);
|
||||
SELECT toTypeName(any(a)) == 'UInt16' AND toTypeName(any(t2.a)) == 'Int16' FROM t1 FULL JOIN t2 ON (t1.a == t2.a);
|
||||
|
||||
{% if join_type == 'auto' -%}
|
||||
SET max_bytes_in_join = 0;
|
||||
{% endif -%}
|
||||
|
||||
{% endfor -%}
|
||||
|
||||
SELECT '=== join use nulls ===';
|
||||
|
@ -1,16 +0,0 @@
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
@ -0,0 +1,3 @@
|
||||
{% for i in range(24) -%}
|
||||
1
|
||||
{% endfor -%}
|
@ -1,19 +0,0 @@
|
||||
SET max_block_size = 6, join_algorithm = 'partial_merge';
|
||||
|
||||
SELECT count() == 4 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 5 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 6 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 7 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 8 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 9 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3, 3]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 10 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3, 3, 3]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 11 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 12 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 13 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 14 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 15 FROM (SELECT 1 AS s) AS js1 ALL RIGHT JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3]) AS s) AS js2 USING (s);
|
||||
|
||||
SELECT count() == 8 FROM (SELECT 1 AS s) AS js1 FULL JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 9 FROM (SELECT 1 AS s) AS js1 FULL JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 10 FROM (SELECT 1 AS s) AS js1 FULL JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3, 3]) AS s) AS js2 USING (s);
|
||||
SELECT count() == 11 FROM (SELECT 1 AS s) AS js1 FULL JOIN (SELECT arrayJoin([2, 2, 2, 2, 2, 2, 2, 3, 3, 3]) AS s) AS js2 USING (s);
|
@ -0,0 +1,9 @@
|
||||
SET max_block_size = 6, join_algorithm = 'partial_merge';
|
||||
|
||||
{% for i in range(4, 16) -%}
|
||||
SELECT count() == {{ i }} FROM (SELECT 100 AS s) AS js1 ALL RIGHT JOIN ( SELECT number AS s FROM numbers({{ i }}) ) AS js2 USING (s);
|
||||
{% endfor -%}
|
||||
|
||||
{% for i in range(4, 16) -%}
|
||||
SELECT count() == {{ i + 1 }} FROM (SELECT 100 AS s) AS js1 ALL FULL JOIN ( SELECT number AS s FROM numbers({{ i }}) ) AS js2 USING (s);
|
||||
{% endfor -%}
|
Loading…
Reference in New Issue
Block a user