mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
ExpressionAnalyzer: added more tests for aliases. fix bug [#METR-23545]
This commit is contained in:
parent
cd15651dfd
commit
106bb24fd8
@ -232,7 +232,7 @@ private:
|
||||
|
||||
/// remove Function_if AST if condition is constant
|
||||
void optimizeIfWithConstantCondition();
|
||||
void optimizeIfWithConstantConditionImpl(ASTPtr & current_ast) const;
|
||||
void optimizeIfWithConstantConditionImpl(ASTPtr & current_ast, Aliases & aliases) const;
|
||||
bool tryExtractConstValueFromCondition(const ASTPtr & condition, bool & value) const;
|
||||
|
||||
/// Превратить перечисление значений или подзапрос в ASTSet. node - функция in или notIn.
|
||||
|
@ -200,7 +200,7 @@ void ExpressionAnalyzer::init()
|
||||
|
||||
void ExpressionAnalyzer::optimizeIfWithConstantCondition()
|
||||
{
|
||||
optimizeIfWithConstantConditionImpl(ast);
|
||||
optimizeIfWithConstantConditionImpl(ast, aliases);
|
||||
}
|
||||
|
||||
bool ExpressionAnalyzer::tryExtractConstValueFromCondition(const ASTPtr & condition, bool & value) const
|
||||
@ -237,7 +237,7 @@ bool ExpressionAnalyzer::tryExtractConstValueFromCondition(const ASTPtr & condit
|
||||
return false;
|
||||
}
|
||||
|
||||
void ExpressionAnalyzer::optimizeIfWithConstantConditionImpl(ASTPtr & current_ast) const
|
||||
void ExpressionAnalyzer::optimizeIfWithConstantConditionImpl(ASTPtr & current_ast, ExpressionAnalyzer::Aliases & aliases) const
|
||||
{
|
||||
if (!current_ast)
|
||||
return;
|
||||
@ -247,11 +247,11 @@ void ExpressionAnalyzer::optimizeIfWithConstantConditionImpl(ASTPtr & current_as
|
||||
ASTFunction * function_node = typeid_cast<ASTFunction *>(child.get());
|
||||
if (!function_node || function_node->name != FunctionIf::name)
|
||||
{
|
||||
optimizeIfWithConstantConditionImpl(child);
|
||||
optimizeIfWithConstantConditionImpl(child, aliases);
|
||||
continue;
|
||||
}
|
||||
|
||||
optimizeIfWithConstantConditionImpl(function_node->arguments);
|
||||
optimizeIfWithConstantConditionImpl(function_node->arguments, aliases);
|
||||
ASTExpressionList * args = typeid_cast<ASTExpressionList *>(function_node->arguments.get());
|
||||
|
||||
ASTPtr condition_expr = args->children.at(0);
|
||||
@ -262,10 +262,24 @@ void ExpressionAnalyzer::optimizeIfWithConstantConditionImpl(ASTPtr & current_as
|
||||
bool condition;
|
||||
if (tryExtractConstValueFromCondition(condition_expr, condition))
|
||||
{
|
||||
if (condition)
|
||||
child = then_expr;
|
||||
ASTPtr replace_ast = condition ? then_expr : else_expr;
|
||||
String replace_alias = replace_ast->tryGetAlias();
|
||||
String if_alias = child->tryGetAlias();
|
||||
|
||||
if (replace_alias.empty())
|
||||
{
|
||||
replace_ast->setAlias(if_alias);
|
||||
child = replace_ast;
|
||||
}
|
||||
else
|
||||
child = else_expr;
|
||||
{
|
||||
/// Only copy of one node is required here.
|
||||
/// But IAST has only method for deep copy of subtree.
|
||||
/// This can be a reason of performance degradation in case of deep queries.
|
||||
ASTPtr replace_ast_deep_copy = replace_ast->clone();
|
||||
replace_ast_deep_copy->setAlias(if_alias);
|
||||
child = replace_ast_deep_copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
1
|
||||
1
|
||||
2
|
||||
42
|
||||
1 0
|
||||
0 5
|
||||
1 2 3
|
||||
1
|
||||
d=2 a=1 b=2 c=3 d=2
|
||||
d=3 a=0 b=2 c=3 d=3
|
||||
d=2 a=1 b=2 c=3 d=2
|
||||
not_existing=42
|
||||
|
@ -1,10 +1,15 @@
|
||||
SELECT 1 ? 1 : 0;
|
||||
SELECT 0 ? not_existing_column : 1 FROM system.numbers LIMIT 1;
|
||||
SELECT if(1, if(0, not_existing_column, 2), 0) FROM system.numbers LIMIT 1;
|
||||
SELECT 1 ? (0 ? not_existing_column : 2) : 0 FROM system.numbers LIMIT 1;
|
||||
|
||||
SELECT (SELECT hasColumnInTable('system', 'numbers', 'not_existing')) ? not_existing : 42 FROM system.numbers LIMIT 1;
|
||||
/* scalar subquery optimization */
|
||||
SELECT (SELECT toUInt8(number + 1) FROM system.numbers LIMIT 1) ? 1 : 2 FROM system.numbers LIMIT 1;
|
||||
|
||||
/* alias test */
|
||||
SELECT 1 ? 1 : (0 as n), n FROM system.numbers LIMIT 1;
|
||||
SELECT 0 ? (number + 5 as n) : 0, n FROM system.numbers LIMIT 1;
|
||||
SELECT (2 as n) ? 1 : (number + 3 as nn), n, nn FROM system.numbers LIMIT 1;
|
||||
SELECT (1 as a) ? (2 as b) : (3 as c) as d, a, b, c, d FORMAT TSKV;
|
||||
SELECT (0 as a) ? (2 as b) : (3 as c) as d, a, b, c, d FORMAT TSKV;
|
||||
|
||||
SELECT (1 as a) ? (number + 2 as b) : (number + 3 as c) as d, a, b, c, d FROM system.numbers LIMIT 1 FORMAT TSKV;
|
||||
|
||||
/* intergration test */
|
||||
SELECT (SELECT hasColumnInTable('system', 'numbers', 'not_existing')) ? not_existing : 42 as not_existing FROM system.numbers LIMIT 1 FORMAT TSKV;
|
Loading…
Reference in New Issue
Block a user