Skip to content

Commit

Permalink
add pass covert in single value to equal
Browse files Browse the repository at this point in the history
  • Loading branch information
liuneng1994 committed Mar 19, 2024
1 parent eb26bb2 commit a742b23
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 0 deletions.
55 changes: 55 additions & 0 deletions src/Analyzer/Passes/ConvertInToEqualsPass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <Analyzer/ColumnNode.h>
#include <Analyzer/ConstantNode.h>
#include <Analyzer/FunctionNode.h>
#include <Analyzer/InDepthQueryTreeVisitor.h>
#include <Analyzer/Passes/ConvertInToEqualsPass.h>
#include <Functions/FunctionsComparison.h>
#include <Functions/IFunctionAdaptors.h>

namespace DB
{

using FunctionEquals = FunctionComparison<EqualsOp, NameEquals>;

class ConvertInToEqualsPassVisitor : public InDepthQueryTreeVisitorWithContext<ConvertInToEqualsPassVisitor>
{
public:
using Base = InDepthQueryTreeVisitorWithContext<ConvertInToEqualsPassVisitor>;
using Base::Base;

FunctionOverloadResolverPtr createInternalFunctionEqualOverloadResolver()
{
return std::make_unique<FunctionToOverloadResolverAdaptor>(std::make_shared<FunctionEquals>(getContext()->getSettings().decimal_check_overflow));
}

void enterImpl(QueryTreeNodePtr & node)
{
if (!getSettings().optimize_in_to_equal)
return;
auto * func_node = node->as<FunctionNode>();
if (!func_node || func_node->getFunctionName() != "in" || func_node->getArguments().getNodes().size() != 2)
return ;
auto args = func_node->getArguments().getNodes();
auto * column_node = args[0]->as<ColumnNode>();
auto * constant_node = args[1]->as<ConstantNode>();
if (!column_node || !constant_node)
return ;
if (constant_node->getValue().getType() == Field::Types::Which::Tuple)
return;
auto const_value = std::make_shared<ConstantNode>(constant_node->getValue());

auto equal_resolver = createInternalFunctionEqualOverloadResolver();
auto equal = std::make_shared<FunctionNode>("equals");
QueryTreeNodes arguments{column_node->clone(), const_value};
equal->getArguments().getNodes() = std::move(arguments);
equal->resolveAsFunction(equal_resolver);
node = equal;
}
};

void ConvertInToEqualsPass::run(QueryTreeNodePtr & query_tree_node, ContextPtr context)
{
ConvertInToEqualsPassVisitor visitor(std::move(context));
visitor.visit(query_tree_node);
}
}
24 changes: 24 additions & 0 deletions src/Analyzer/Passes/ConvertInToEqualsPass.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <Analyzer/IQueryTreePass.h>

namespace DB {

/** Optimize `in` to `equals` if possible.
*
* Example: SELECT * from test where x IN (1);
* Result: SELECT * from test where x = 1;
*
*/
class ConvertInToEqualsPass final : public IQueryTreePass {
public:
String getName() override { return "ConvertInToEqualsPass"; }

String getDescription() override { return "Convert in to equal"; }

void run(QueryTreeNodePtr & query_tree_node, ContextPtr context) override;
};
}



2 changes: 2 additions & 0 deletions src/Analyzer/QueryTreePassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <Analyzer/Passes/MultiIfToIfPass.h>
#include <Analyzer/Passes/IfConstantConditionPass.h>
#include <Analyzer/Passes/IfChainToMultiIfPass.h>
#include <Analyzer/Passes/ConvertInToEqualsPass.h>
#include <Analyzer/Passes/OrderByTupleEliminationPass.h>
#include <Analyzer/Passes/NormalizeCountVariantsPass.h>
#include <Analyzer/Passes/AggregateFunctionsArithmericOperationsPass.h>
Expand Down Expand Up @@ -263,6 +264,7 @@ void addQueryTreePasses(QueryTreePassManager & manager, bool only_analyze)
manager.addPass(std::make_unique<SumIfToCountIfPass>());
manager.addPass(std::make_unique<RewriteArrayExistsToHasPass>());
manager.addPass(std::make_unique<NormalizeCountVariantsPass>());
manager.addPass(std::make_unique<ConvertInToEqualsPass>());

/// should before AggregateFunctionsArithmericOperationsPass
manager.addPass(std::make_unique<AggregateFunctionOfGroupByKeysPass>());
Expand Down
1 change: 1 addition & 0 deletions src/Core/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ class IColumn;
M(Bool, optimize_functions_to_subcolumns, false, "Transform functions to subcolumns, if possible, to reduce amount of read data. E.g. 'length(arr)' -> 'arr.size0', 'col IS NULL' -> 'col.null' ", 0) \
M(Bool, optimize_using_constraints, false, "Use constraints for query optimization", 0) \
M(Bool, optimize_substitute_columns, false, "Use constraints for column substitution", 0) \
M(Bool, optimize_in_to_equal, true, "Convert the constant in to equal", 0) \
M(Bool, optimize_append_index, false, "Use constraints in order to append index condition (indexHint)", 0) \
M(Bool, optimize_time_filter_with_preimage, true, "Optimize Date and DateTime predicates by converting functions into equivalent comparisons without conversions (e.g. toYear(col) = 2023 -> col >= '2023-01-01' AND col <= '2023-12-31')", 0) \
M(Bool, normalize_function_names, true, "Normalize function names to their canonical names", 0) \
Expand Down

0 comments on commit a742b23

Please sign in to comment.