From 82e7e7d9cbbb6541016ef64852c9858cc3c7e4c4 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 23 Dec 2020 22:36:10 +0300 Subject: [PATCH] Fix constant folding for expressions depends from subqueries result Do not use subquery result, when value is unknown, for constant folding. v2: fix simple subqueries, fixes 00597_push_down_predicate. v3: - use identity over introducing yet another cast analog (as suggested by @akuzm) - simpler suitable_for_const_folding check v4: use identity(cast()) since only cast() can provide corrent type (for data types that does not have it's own type, i.e. DateTime) v5: do not optimize consts if only_analyze isset, regardless the block content --- src/Interpreters/ExecuteScalarSubqueriesVisitor.cpp | 10 ++++++++++ .../0_stateless/00597_push_down_predicate.reference | 3 ++- .../01611_constant_folding_subqueries.reference | 9 +++++++++ .../0_stateless/01611_constant_folding_subqueries.sql | 4 ++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/queries/0_stateless/01611_constant_folding_subqueries.reference create mode 100644 tests/queries/0_stateless/01611_constant_folding_subqueries.sql diff --git a/src/Interpreters/ExecuteScalarSubqueriesVisitor.cpp b/src/Interpreters/ExecuteScalarSubqueriesVisitor.cpp index b3e8af90f28..affd9d0678f 100644 --- a/src/Interpreters/ExecuteScalarSubqueriesVisitor.cpp +++ b/src/Interpreters/ExecuteScalarSubqueriesVisitor.cpp @@ -168,6 +168,16 @@ void ExecuteScalarSubqueriesMatcher::visit(const ASTSubquery & subquery, ASTPtr lit->alias = subquery.alias; lit->prefer_alias_to_column_name = subquery.prefer_alias_to_column_name; ast = addTypeConversionToAST(std::move(lit), scalar.safeGetByPosition(0).type->getName()); + + /// If only analyze was requested the expression is not suitable for constant folding, disable it. + if (data.only_analyze) + { + ast->as()->alias.clear(); + auto func = makeASTFunction("identity", std::move(ast)); + func->alias = subquery.alias; + func->prefer_alias_to_column_name = subquery.prefer_alias_to_column_name; + ast = std::move(func); + } } else { diff --git a/tests/queries/0_stateless/00597_push_down_predicate.reference b/tests/queries/0_stateless/00597_push_down_predicate.reference index e239b1c27fd..cea533d6ccb 100644 --- a/tests/queries/0_stateless/00597_push_down_predicate.reference +++ b/tests/queries/0_stateless/00597_push_down_predicate.reference @@ -114,8 +114,9 @@ FROM ( SELECT 1 AS id, - cast(1, \'UInt8\') AS subquery + identity(cast(1, \'UInt8\')) AS subquery ) +WHERE subquery = 1 1 1 SELECT a, diff --git a/tests/queries/0_stateless/01611_constant_folding_subqueries.reference b/tests/queries/0_stateless/01611_constant_folding_subqueries.reference new file mode 100644 index 00000000000..ac91b53b754 --- /dev/null +++ b/tests/queries/0_stateless/01611_constant_folding_subqueries.reference @@ -0,0 +1,9 @@ +-- { echo } +SELECT * FROM (SELECT (SELECT * FROM system.numbers LIMIT 1 OFFSET 1) AS n, toUInt64(10 / n)) FORMAT CSV; +1,10 +SELECT (SELECT * FROM system.numbers LIMIT 1 OFFSET 1) AS n, toUInt64(10 / n) FORMAT CSV; +1,10 +EXPLAIN SYNTAX SELECT (SELECT * FROM system.numbers LIMIT 1 OFFSET 1) AS n, toUInt64(10 / n); +SELECT + identity(cast(0, \'UInt64\')) AS n, + toUInt64(10 / n) diff --git a/tests/queries/0_stateless/01611_constant_folding_subqueries.sql b/tests/queries/0_stateless/01611_constant_folding_subqueries.sql new file mode 100644 index 00000000000..abf67a8ed6a --- /dev/null +++ b/tests/queries/0_stateless/01611_constant_folding_subqueries.sql @@ -0,0 +1,4 @@ +-- { echo } +SELECT * FROM (SELECT (SELECT * FROM system.numbers LIMIT 1 OFFSET 1) AS n, toUInt64(10 / n)) FORMAT CSV; +SELECT (SELECT * FROM system.numbers LIMIT 1 OFFSET 1) AS n, toUInt64(10 / n) FORMAT CSV; +EXPLAIN SYNTAX SELECT (SELECT * FROM system.numbers LIMIT 1 OFFSET 1) AS n, toUInt64(10 / n);