mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-28 18:42:26 +00:00
0a4eccb73e
Omitted new checks which produce too many matches or which are controversial (e.g. readability-identifier-length). New checks: - misc-misleading-bidirectional + misc-misleading-identifier Detects potential attack as described in the Trojan Source attack - modernize-macro-to-enum Replaces groups of adjacent macros with an unscoped anonymous enum - modernize-shrink-to-fit Replace copy and swap tricks on shrinkable containers with the shrink_to_fit() method call - modernize-use-transparent-functors Prefer transparent functors to non-transparent ones - modernize-use-uncaught-exceptions This check will warn on calls to std::uncaught_exception and replace them with calls to std::uncaught_exceptions (uncaught_exception was deprecated with C++17) - performance-no-int-to-ptr Diagnoses every integer to pointer cast - readability-duplicate-include Looks for duplicate includes and removes them - readability-redundant-preprocessor Finds potentially redundant preprocessor directives - bugprone-lambda-function-name Checks for attempts to get the name of a function from within a lambda expression - bugprone-redundant-branch-condition Finds condition variables in nested if statements that were also checked in the outer if statement and were not changed - bugprone-shared-ptr-array-mismatch Finds initializations of C++ shared pointers to non-array type that are initialized with an array - bugprone-stringview-nullptr Checks for various ways that the const CharT* constructor of std::basic_string_view can be passed a null argument and replaces them with the default constructor in most cases - bugprone-suspicious-memory-comparison Finds potentially incorrect calls to memcmp() based on properties of the arguments
76 lines
3.3 KiB
C++
76 lines
3.3 KiB
C++
#include <AggregateFunctions/AggregateFunctionFactory.h>
|
|
#include <Interpreters/RewriteCountDistinctVisitor.h>
|
|
#include <Parsers/ASTFunction.h>
|
|
#include <Parsers/ASTLiteral.h>
|
|
#include <Common/typeid_cast.h>
|
|
#include "Coordination/KeeperStorage.h"
|
|
#include "Parsers/ASTExpressionList.h"
|
|
#include "Parsers/ASTIdentifier.h"
|
|
#include "Parsers/ASTSelectQuery.h"
|
|
#include "Parsers/ASTSubquery.h"
|
|
#include "Parsers/ASTTablesInSelectQuery.h"
|
|
#include <Parsers/Lexer.h>
|
|
#include <Parsers/parseQuery.h>
|
|
#include <Parsers/ParserQuery.h>
|
|
#include <Parsers/ASTSelectWithUnionQuery.h>
|
|
|
|
namespace DB
|
|
{
|
|
|
|
void RewriteCountDistinctFunctionMatcher::visit(ASTPtr & ast, Data & /*data*/)
|
|
{
|
|
auto * selectq = ast->as<ASTSelectQuery>();
|
|
if (!selectq || !selectq->tables() || selectq->tables()->children.size() != 1)
|
|
return;
|
|
auto expr_list = selectq->select();
|
|
if (!expr_list || expr_list->children.size() != 1)
|
|
return;
|
|
auto * func = expr_list->children[0]->as<ASTFunction>();
|
|
if (!func || (Poco::toLower(func->name) != "countdistinct" && Poco::toLower(func->name) != "uniqexact"))
|
|
return;
|
|
auto arg = func->arguments->children;
|
|
if (arg.size() != 1)
|
|
return;
|
|
if (!arg[0]->as<ASTIdentifier>())
|
|
return;
|
|
if (selectq->tables()->as<ASTTablesInSelectQuery>()->children[0]->as<ASTTablesInSelectQueryElement>()->children.size() != 1)
|
|
return;
|
|
auto * table_expr = selectq->tables()->as<ASTTablesInSelectQuery>()->children[0]->as<ASTTablesInSelectQueryElement>()->children[0]->as<ASTTableExpression>();
|
|
if (!table_expr || table_expr->size() != 1 || !table_expr->database_and_table_name)
|
|
return;
|
|
// Check done, we now rewrite the AST
|
|
auto cloned_select_query = selectq->clone();
|
|
expr_list->children[0] = makeASTFunction("count");
|
|
|
|
auto table_name = table_expr->database_and_table_name->as<ASTTableIdentifier>()->name();
|
|
table_expr->children.clear();
|
|
table_expr->children.emplace_back(std::make_shared<ASTSubquery>());
|
|
table_expr->database_and_table_name = nullptr;
|
|
table_expr->table_function = nullptr;
|
|
table_expr->subquery = table_expr->children[0];
|
|
|
|
auto column_name = arg[0]->as<ASTIdentifier>()->name();
|
|
// Form AST for subquery
|
|
{
|
|
auto * select_ptr = cloned_select_query->as<ASTSelectQuery>();
|
|
select_ptr->refSelect()->children.clear();
|
|
select_ptr->refSelect()->children.emplace_back(std::make_shared<ASTIdentifier>(column_name));
|
|
auto exprlist = std::make_shared<ASTExpressionList>();
|
|
exprlist->children.emplace_back(std::make_shared<ASTIdentifier>(column_name));
|
|
cloned_select_query->as<ASTSelectQuery>()->setExpression(ASTSelectQuery::Expression::GROUP_BY, exprlist);
|
|
|
|
auto expr = std::make_shared<ASTExpressionList>();
|
|
expr->children.emplace_back(cloned_select_query);
|
|
auto select_with_union = std::make_shared<ASTSelectWithUnionQuery>();
|
|
select_with_union->union_mode = SelectUnionMode::Unspecified;
|
|
select_with_union->is_normalized = false;
|
|
select_with_union->list_of_modes.clear();
|
|
select_with_union->set_of_modes.clear();
|
|
select_with_union->children.emplace_back(expr);
|
|
select_with_union->list_of_selects = expr;
|
|
table_expr->children[0]->as<ASTSubquery>()->children.emplace_back(select_with_union);
|
|
}
|
|
}
|
|
|
|
}
|