ExpressionAnalyzer: added more tests for aliases. fix bug [#METR-23545]

This commit is contained in:
Pavel Kartavyy 2016-11-29 22:19:15 +03:00
parent cd15651dfd
commit 106bb24fd8
4 changed files with 37 additions and 17 deletions

View File

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

View File

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

View File

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

View File

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