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
This commit is contained in:
Azat Khuzhin 2020-12-23 22:36:10 +03:00
parent ea7528b853
commit 82e7e7d9cb
4 changed files with 25 additions and 1 deletions

View File

@ -168,6 +168,16 @@ void ExecuteScalarSubqueriesMatcher::visit(const ASTSubquery & subquery, ASTPtr
lit->alias = subquery.alias; lit->alias = subquery.alias;
lit->prefer_alias_to_column_name = subquery.prefer_alias_to_column_name; lit->prefer_alias_to_column_name = subquery.prefer_alias_to_column_name;
ast = addTypeConversionToAST(std::move(lit), scalar.safeGetByPosition(0).type->getName()); 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<ASTFunction>()->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 else
{ {

View File

@ -114,8 +114,9 @@ FROM
( (
SELECT SELECT
1 AS id, 1 AS id,
cast(1, \'UInt8\') AS subquery identity(cast(1, \'UInt8\')) AS subquery
) )
WHERE subquery = 1
1 1 1 1
SELECT SELECT
a, a,

View File

@ -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)

View File

@ -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);