diff --git a/dbms/src/Parsers/ASTExplainQuery.h b/dbms/src/Parsers/ASTExplainQuery.h index 3bfa9a1065a..5ebd02b85f8 100644 --- a/dbms/src/Parsers/ASTExplainQuery.h +++ b/dbms/src/Parsers/ASTExplainQuery.h @@ -41,6 +41,8 @@ private: case ParsedAST: return "ParsedAST"; case AnalyzedSyntax: return "AnalyzedSyntax"; } + + __builtin_unreachable(); } }; diff --git a/dbms/tests/clickhouse-test b/dbms/tests/clickhouse-test index c66eb51317c..09f44ea436e 100755 --- a/dbms/tests/clickhouse-test +++ b/dbms/tests/clickhouse-test @@ -277,11 +277,12 @@ def main(args): report_testcase.append(skipped) print("{0} - no reference file".format(MSG_UNKNOWN)) else: - result_is_different = subprocess.call(['cmp', '-s', reference_file, stdout_file], stdout = PIPE) + result_is_different = subprocess.call(['diff', '-q', '-bEZ', reference_file, stdout_file], stdout = PIPE) if result_is_different: - (diff, _) = Popen(['diff', '--unified', reference_file, stdout_file], stdout = PIPE).communicate() + diff = Popen(['diff', '--unified', '-bEZ', reference_file, stdout_file], stdout = PIPE).communicate()[0] diff = unicode(diff, errors='replace', encoding='utf-8') + cat = Popen(['cat', '-A'], stdin=PIPE, stdout=PIPE).communicate(input=diff)[0] failure = et.Element("failure", attrib = {"message": "result differs with reference"}) report_testcase.append(failure) @@ -294,7 +295,7 @@ def main(args): report_testcase.append(stdout_element) failures += 1 - print("{0} - result differs with reference:\n{1}".format(MSG_FAIL, diff.encode('utf-8'))) + print("{0} - result differs with reference:\n{1}".format(MSG_FAIL, cat.encode('utf-8'))) else: passed_total += 1 failures_chain = 0 diff --git a/dbms/tests/queries/0_stateless/00597_push_down_predicate.reference b/dbms/tests/queries/0_stateless/00597_push_down_predicate.reference index bc28d4efb7e..e289e90637c 100644 --- a/dbms/tests/queries/0_stateless/00597_push_down_predicate.reference +++ b/dbms/tests/queries/0_stateless/00597_push_down_predicate.reference @@ -1,36 +1,51 @@ --------Not need optimize predicate, but it works.------- +-------No need for predicate optimization, but still works------- 1 1 1 +2000-01-01 1 test string 1 1 -------Need push down------- +SELECT dummy\nFROM system.one \nANY LEFT JOIN \n(\n SELECT 0 AS dummy\n WHERE 1\n) USING (dummy)\nWHERE 1 0 +SELECT toString(value) AS value\nFROM \n(\n SELECT 1 AS value\n WHERE toString(value) = \'1\'\n) \nWHERE value = \'1\' 1 +SELECT id\nFROM \n(\n SELECT 1 AS id\n WHERE id = 1\n UNION ALL\n SELECT 2 AS `2`\n WHERE `2` = 1\n) \nWHERE id = 1 1 +SELECT id\nFROM \n(\n SELECT arrayJoin([1, 2, 3]) AS id\n WHERE id = 1\n) \nWHERE id = 1 1 +SELECT id\nFROM \n(\n SELECT arrayJoin([1, 2, 3]) AS id\n WHERE id = 1\n) \nWHERE id = 1 1 -1 1 -3 3 -3 3 -2000-01-01 1 test string 1 1 -3 3 --------Force push down------- -2000-01-01 1 test string 1 1 -2000-01-01 1 test string 1 1 -2000-01-01 1 test string 1 1 -2000-01-01 1 test string 1 1 -2000-01-01 1 test string 1 1 -2000-01-01 1 test string 1 1 -2000-01-01 1 test string 1 1 -1 2000-01-01 1 -2000-01-01 1 test string 1 1 -2000-01-01 1 test string 1 1 -2000-01-01 1 test string 1 1 2000-01-01 test string 1 1 -2000-01-01 1 test string 1 1 -1 2000-01-01 1 test string 1 1 -2000-01-01 1 test string 1 1 -2000-01-01 2 test string 2 2 -1 -1 --------Push to having expression, need check.------- --------Compatibility test------- -1 2000-01-01 test string 1 1 +SELECT \n id, \n subquery\nFROM \n(\n SELECT \n 1 AS id, \n CAST(1, \'UInt8\') AS subquery\n WHERE subquery = 1\n) \nWHERE subquery = 1 +1 1 +SELECT \n a, \n b\nFROM \n(\n SELECT \n toUInt64(sum(id) AS b) AS a, \n b\n FROM test.test \n HAVING a = 3\n) \nWHERE a = 3 +3 3 +SELECT \n date, \n id, \n name, \n value\nFROM \n(\n SELECT \n date, \n name, \n value, \n min(id) AS id\n FROM test.test \n GROUP BY \n date, \n name, \n value\n HAVING id = 1\n) \nWHERE id = 1 +2000-01-01 1 test string 1 1 +SELECT \n a, \n b\nFROM \n(\n SELECT \n toUInt64(sum(id) AS b) AS a, \n b\n FROM test.test AS table_alias \n HAVING b = 3\n) AS outer_table_alias \nWHERE outer_table_alias.b = 3 +3 3 +SELECT \n date, \n id, \n name, \n value\nFROM \n(\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n WHERE id = 1\n) \nWHERE id = 1 +2000-01-01 1 test string 1 1 +SELECT \n date, \n id, \n name, \n value\nFROM \n(\n SELECT \n date, \n id, \n name, \n value\n FROM \n (\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n ) \n WHERE id = 1\n) \nWHERE id = 1 +2000-01-01 1 test string 1 1 +SELECT \n date, \n id, \n name, \n value\nFROM \n(\n SELECT \n date, \n id, \n name, \n value\n FROM \n (\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n ) AS b \n WHERE id = 1\n) \nWHERE id = 1 +2000-01-01 1 test string 1 1 +SELECT \n date, \n id, \n name, \n value\nFROM \n(\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n WHERE id = 1\n) \nWHERE id = 1 +2000-01-01 1 test string 1 1 +SELECT \n date, \n id, \n name, \n value\nFROM \n(\n SELECT \n date, \n id, \n name, \n value\n FROM \n (\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n ) \n WHERE id = 1\n) \nWHERE id = 1 +2000-01-01 1 test string 1 1 +SELECT \n date, \n id, \n name, \n value\nFROM \n(\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n WHERE id = 1\n) AS b \nWHERE b.id = 1 +2000-01-01 1 test string 1 1 +SELECT \n date, \n id, \n name, \n value\nFROM \n(\n SELECT \n date, \n id, \n name, \n value\n FROM \n (\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n ) AS a \n WHERE id = 1\n) AS b \nWHERE b.id = 1 +2000-01-01 1 test string 1 1 +SELECT \n id, \n date, \n value\nFROM \n(\n SELECT \n id, \n date, \n min(value) AS value\n FROM test.test \n WHERE id = 1\n GROUP BY \n id, \n date\n) \nWHERE id = 1 +1 2000-01-01 1 +SELECT \n date, \n id, \n name, \n value\nFROM \n(\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n WHERE id = 1\n UNION ALL\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n WHERE id = 1\n) \nWHERE id = 1 +2000-01-01 1 test string 1 1 +2000-01-01 1 test string 1 1 +SELECT \n date, \n id, \n name, \n value, \n date, \n name, \n value\nFROM \n(\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n WHERE id = 1\n) \nANY LEFT JOIN \n(\n SELECT *\n FROM test.test \n WHERE id = 1\n) USING (id)\nWHERE id = 1 +2000-01-01 1 test string 1 1 2000-01-01 test string 1 1 +SELECT \n date, \n id, \n name, \n value\nFROM \n(\n SELECT \n date, \n id, \n name, \n value, \n date, \n name, \n value\n FROM \n (\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n ) \n ANY LEFT JOIN \n (\n SELECT *\n FROM test.test \n ) USING (id)\n WHERE id = 1\n) \nWHERE id = 1 +2000-01-01 1 test string 1 1 +SELECT \n date, \n id, \n name, \n value, \n `b.date`, \n `b.name`, \n `b.value`\nFROM \n(\n SELECT \n date, \n id, \n name, \n value\n FROM test.test \n) \nANY LEFT JOIN \n(\n SELECT *\n FROM test.test \n WHERE id = 1\n) AS b USING (id)\nWHERE b.id = 1 +2000-01-01 1 test string 1 1 2000-01-01 test string 1 1 +SELECT \n id, \n date, \n name, \n value\nFROM \n(\n SELECT \n toInt8(1) AS id, \n toDate(\'2000-01-01\') AS date\n FROM system.numbers \n LIMIT 1\n) \nANY LEFT JOIN \n(\n SELECT *\n FROM test.test \n WHERE date = toDate(\'2000-01-01\')\n) AS b USING (date, id)\nWHERE b.date = toDate(\'2000-01-01\') +1 2000-01-01 test string 1 1 diff --git a/dbms/tests/queries/0_stateless/00597_push_down_predicate.sql b/dbms/tests/queries/0_stateless/00597_push_down_predicate.sql index 495c367e3bd..9c309db455a 100644 --- a/dbms/tests/queries/0_stateless/00597_push_down_predicate.sql +++ b/dbms/tests/queries/0_stateless/00597_push_down_predicate.sql @@ -1,10 +1,8 @@ SET send_logs_level = 'none'; -DROP TABLE IF EXISTS test.perf; DROP TABLE IF EXISTS test.test; DROP TABLE IF EXISTS test.test_view; -CREATE TABLE test.perf(site String, user_id UInt64, z Float64)ENGINE = Log; CREATE TABLE test.test(date Date, id Int8, name String, value Int64) ENGINE = MergeTree(date, (id, date), 8192); CREATE VIEW test.test_view AS SELECT * FROM test.test; @@ -12,71 +10,101 @@ INSERT INTO test.test VALUES('2000-01-01', 1, 'test string 1', 1); INSERT INTO test.test VALUES('2000-01-01', 2, 'test string 2', 2); SET enable_optimize_predicate_expression = 1; +SET enable_debug_queries = 1; -SELECT '-------Not need optimize predicate, but it works.-------'; +SELECT '-------No need for predicate optimization, but still works-------'; SELECT 1; SELECT 1 AS id WHERE id = 1; SELECT arrayJoin([1,2,3]) AS id WHERE id = 1; -SELECT * FROM (SELECT perf_1.z AS z_1 FROM test.perf AS perf_1); +SELECT * FROM test.test WHERE id = 1; SELECT '-------Need push down-------'; -SELECT * FROM system.one ANY LEFT JOIN (SELECT 0 AS dummy) USING dummy WHERE 1; -SELECT toString(value) AS value FROM (SELECT 1 AS value) WHERE value = '1'; -SELECT * FROM (SELECT 1 AS id UNION ALL SELECT 2) WHERE id = 1; -SELECT * FROM (SELECT arrayJoin([1, 2, 3]) AS id) WHERE id = 1; -SELECT id FROM (SELECT arrayJoin([1, 2, 3]) AS id) WHERE id = 1; -SELECT * FROM (SELECT perf_1.z AS z_1 FROM test.perf AS perf_1) WHERE z_1 = 1; +-- Optimize predicate expressions without tables +ANALYZE SELECT * FROM system.one ANY LEFT JOIN (SELECT 0 AS dummy) USING dummy WHERE 1; +SELECT * FROM system.one ANY LEFT JOIN (SELECT 0 AS dummy) USING dummy WHERE 1; + +ANALYZE SELECT toString(value) AS value FROM (SELECT 1 AS value) WHERE value = '1'; +SELECT toString(value) AS value FROM (SELECT 1 AS value) WHERE value = '1'; + +ANALYZE SELECT * FROM (SELECT 1 AS id UNION ALL SELECT 2) WHERE id = 1; +SELECT * FROM (SELECT 1 AS id UNION ALL SELECT 2) WHERE id = 1; + +ANALYZE SELECT * FROM (SELECT arrayJoin([1, 2, 3]) AS id) WHERE id = 1; +SELECT * FROM (SELECT arrayJoin([1, 2, 3]) AS id) WHERE id = 1; + +ANALYZE SELECT id FROM (SELECT arrayJoin([1, 2, 3]) AS id) WHERE id = 1; +SELECT id FROM (SELECT arrayJoin([1, 2, 3]) AS id) WHERE id = 1; + +ANALYZE SELECT * FROM (SELECT 1 AS id, (SELECT 1) as subquery) WHERE subquery = 1; SELECT * FROM (SELECT 1 AS id, (SELECT 1) as subquery) WHERE subquery = 1; + +-- Optimize predicate expressions using tables +ANALYZE SELECT * FROM (SELECT toUInt64(b) AS a, sum(id) AS b FROM test.test) WHERE a = 3; SELECT * FROM (SELECT toUInt64(b) AS a, sum(id) AS b FROM test.test) WHERE a = 3; -SELECT * FROM (SELECT toUInt64(b), sum(id) AS b FROM test.test) WHERE `toUInt64(sum(id))` = 3; + +ANALYZE SELECT date, id, name, value FROM (SELECT date, name, value, min(id) AS id FROM test.test GROUP BY date, name, value) WHERE id = 1; SELECT date, id, name, value FROM (SELECT date, name, value, min(id) AS id FROM test.test GROUP BY date, name, value) WHERE id = 1; + +ANALYZE SELECT * FROM (SELECT toUInt64(b) AS a, sum(id) AS b FROM test.test AS table_alias) AS outer_table_alias WHERE outer_table_alias.b = 3; SELECT * FROM (SELECT toUInt64(b) AS a, sum(id) AS b FROM test.test AS table_alias) AS outer_table_alias WHERE outer_table_alias.b = 3; -SELECT '-------Force push down-------'; -SET force_primary_key = 1; - -- Optimize predicate expression with asterisk +ANALYZE SELECT * FROM (SELECT * FROM test.test) WHERE id = 1; SELECT * FROM (SELECT * FROM test.test) WHERE id = 1; + -- Optimize predicate expression with asterisk and nested subquery +-- FIXME: should be pushed down to the innermost subquery +ANALYZE SELECT * FROM (SELECT * FROM (SELECT * FROM test.test)) WHERE id = 1; SELECT * FROM (SELECT * FROM (SELECT * FROM test.test)) WHERE id = 1; + -- Optimize predicate expression with qualified asterisk +-- FIXME: should be pushed down to the innermost subquery +ANALYZE SELECT * FROM (SELECT b.* FROM (SELECT * FROM test.test) AS b) WHERE id = 1; SELECT * FROM (SELECT b.* FROM (SELECT * FROM test.test) AS b) WHERE id = 1; + -- Optimize predicate expression without asterisk +ANALYZE SELECT * FROM (SELECT date, id, name, value FROM test.test) WHERE id = 1; SELECT * FROM (SELECT date, id, name, value FROM test.test) WHERE id = 1; + -- Optimize predicate expression without asterisk and contains nested subquery +-- FIXME: should be pushed down to the innermost subquery +ANALYZE SELECT * FROM (SELECT date, id, name, value FROM (SELECT date, id, name, value FROM test.test)) WHERE id = 1; SELECT * FROM (SELECT date, id, name, value FROM (SELECT date, id, name, value FROM test.test)) WHERE id = 1; + -- Optimize predicate expression with qualified +ANALYZE SELECT * FROM (SELECT * FROM test.test) AS b WHERE b.id = 1; SELECT * FROM (SELECT * FROM test.test) AS b WHERE b.id = 1; + -- Optimize predicate expression with qualified and nested subquery +-- FIXME: should be pushed down to the innermost subquery +ANALYZE SELECT * FROM (SELECT * FROM (SELECT * FROM test.test) AS a) AS b WHERE b.id = 1; SELECT * FROM (SELECT * FROM (SELECT * FROM test.test) AS a) AS b WHERE b.id = 1; + -- Optimize predicate expression with aggregate function +ANALYZE SELECT * FROM (SELECT id, date, min(value) AS value FROM test.test GROUP BY id, date) WHERE id = 1; SELECT * FROM (SELECT id, date, min(value) AS value FROM test.test GROUP BY id, date) WHERE id = 1; -- Optimize predicate expression with union all query +ANALYZE SELECT * FROM (SELECT * FROM test.test UNION ALL SELECT * FROM test.test) WHERE id = 1; SELECT * FROM (SELECT * FROM test.test UNION ALL SELECT * FROM test.test) WHERE id = 1; + -- Optimize predicate expression with join query +ANALYZE SELECT * FROM (SELECT * FROM test.test) ANY LEFT JOIN (SELECT * FROM test.test) USING id WHERE id = 1; SELECT * FROM (SELECT * FROM test.test) ANY LEFT JOIN (SELECT * FROM test.test) USING id WHERE id = 1; + -- Optimize predicate expression with join and nested subquery +-- FIXME: should be pushed down to the innermost subqueries in both parts +ANALYZE SELECT * FROM (SELECT * FROM (SELECT * FROM test.test) ANY LEFT JOIN (SELECT * FROM test.test) USING id) WHERE id = 1; SELECT * FROM (SELECT * FROM (SELECT * FROM test.test) ANY LEFT JOIN (SELECT * FROM test.test) USING id) WHERE id = 1; + -- Optimize predicate expression with join query and qualified -SELECT * FROM (SELECT 1 AS id, toDate('2000-01-01') AS date FROM system.numbers LIMIT 1) ANY LEFT JOIN (SELECT * FROM test.test) AS b USING date WHERE b.id = 1; +ANALYZE SELECT * FROM (SELECT * FROM test.test) ANY LEFT JOIN (SELECT * FROM test.test) AS b USING id WHERE b.id = 1; +SELECT * FROM (SELECT * FROM test.test) ANY LEFT JOIN (SELECT * FROM test.test) AS b USING id WHERE b.id = 1; --- Optimize predicate expression with view -SELECT * FROM test.test_view WHERE id = 1; -SELECT * FROM test.test_view WHERE id = 2; -SELECT id FROM test.test_view WHERE id = 1; -SELECT s.id FROM test.test_view AS s WHERE s.id = 1; - -SELECT '-------Push to having expression, need check.-------'; -SELECT id FROM (SELECT min(id) AS id FROM test.test) WHERE id = 1; -- { serverError 277 } -SELECT * FROM (SELECT toUInt64(b) AS a, sum(id) AS b FROM test.test) WHERE a = 3; -- { serverError 277 } -SELECT * FROM (SELECT toUInt64(b), sum(id) AS b FROM test.test) WHERE `toUInt64(sum(id))` = 3; -- { serverError 277 } -SELECT * FROM (SELECT toUInt64(b) AS a, sum(id) AS b FROM test.test AS table_alias) AS outer_table_alias WHERE outer_table_alias.b = 3; -- { serverError 277 } - -SELECT '-------Compatibility test-------'; +-- Compatibility test +ANALYZE SELECT * FROM (SELECT toInt8(1) AS id, toDate('2000-01-01') AS date FROM system.numbers LIMIT 1) ANY LEFT JOIN (SELECT * FROM test.test) AS b USING date, id WHERE b.date = toDate('2000-01-01'); SELECT * FROM (SELECT toInt8(1) AS id, toDate('2000-01-01') AS date FROM system.numbers LIMIT 1) ANY LEFT JOIN (SELECT * FROM test.test) AS b USING date, id WHERE b.date = toDate('2000-01-01'); -DROP TABLE IF EXISTS test.perf; DROP TABLE IF EXISTS test.test; DROP TABLE IF EXISTS test.test_view; diff --git a/dbms/tests/queries/bugs/00597_push_down_predicate.sql b/dbms/tests/queries/bugs/00597_push_down_predicate.sql new file mode 100644 index 00000000000..0de9522ab50 --- /dev/null +++ b/dbms/tests/queries/bugs/00597_push_down_predicate.sql @@ -0,0 +1,18 @@ +DROP TABLE IF EXISTS test.test; +DROP TABLE IF EXISTS test.test_view; + +CREATE TABLE test.test(date Date, id Int8, name String, value Int64) ENGINE = MergeTree(date, (id, date), 8192); +CREATE VIEW test.test_view AS SELECT * FROM test.test; + +SET enable_optimize_predicate_expression = 1; +SET enable_debug_queries = 1; + +-- Optimize predicate expression with view +-- TODO: simple view is not replaced with subquery inside syntax analyzer +ANALYZE SELECT * FROM test.test_view WHERE id = 1; +ANALYZE SELECT * FROM test.test_view WHERE id = 2; +ANALYZE SELECT id FROM test.test_view WHERE id = 1; +ANALYZE SELECT s.id FROM test.test_view AS s WHERE s.id = 1; + +-- TODO: this query shouldn't work, because the name `toUInt64(sum(id))` is undefined for user +SELECT * FROM (SELECT toUInt64(b), sum(id) AS b FROM test.test) WHERE `toUInt64(sum(id))` = 3;