2018-03-04 16:15:31 +00:00
|
|
|
#pragma once
|
|
|
|
|
2018-10-30 16:31:21 +00:00
|
|
|
#include <Interpreters/DatabaseAndTableWithAlias.h>
|
2018-03-04 16:15:31 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
class ASTIdentifier;
|
|
|
|
class ASTSelectQuery;
|
|
|
|
class ASTSubquery;
|
|
|
|
class Context;
|
2018-03-04 16:15:31 +00:00
|
|
|
|
|
|
|
/** This class provides functions for Push-Down predicate expressions
|
|
|
|
*
|
|
|
|
* The Example:
|
|
|
|
* - Query before optimization :
|
|
|
|
* SELECT id_1, name_1 FROM (SELECT id_1, name_1 FROM table_a UNION ALL SELECT id_2, name_2 FROM table_b)
|
|
|
|
* WHERE id_1 = 1
|
|
|
|
* - Query after optimization :
|
|
|
|
* SELECT id_1, name_1 FROM (SELECT id_1, name_1 FROM table_a WHERE id_1 = 1 UNION ALL SELECT id_2, name_2 FROM table_b WHERE id_2 = 1)
|
|
|
|
* WHERE id_1 = 1
|
|
|
|
* For more details : https://github.com/yandex/ClickHouse/pull/2015#issuecomment-374283452
|
|
|
|
*/
|
|
|
|
class PredicateExpressionsOptimizer
|
|
|
|
{
|
2019-01-25 15:42:24 +00:00
|
|
|
using ProjectionWithAlias = std::pair<ASTPtr, String>;
|
|
|
|
using SubqueriesProjectionColumns = std::map<ASTSelectQuery *, std::vector<ProjectionWithAlias>>;
|
|
|
|
using IdentifierWithQualifier = std::pair<ASTIdentifier *, String>;
|
|
|
|
|
2018-10-18 15:03:14 +00:00
|
|
|
/// Extracts settings, mostly to show which are used and which are not.
|
|
|
|
struct ExtractedSettings
|
|
|
|
{
|
|
|
|
/// QueryNormalizer settings
|
|
|
|
const UInt64 max_ast_depth;
|
|
|
|
const UInt64 max_expanded_ast_elements;
|
|
|
|
const String count_distinct_implementation;
|
|
|
|
|
2018-10-19 15:42:47 +00:00
|
|
|
/// for PredicateExpressionsOptimizer
|
|
|
|
const bool enable_optimize_predicate_expression;
|
|
|
|
|
2018-10-18 15:03:14 +00:00
|
|
|
template<typename T>
|
|
|
|
ExtractedSettings(const T & settings)
|
2018-10-19 15:42:47 +00:00
|
|
|
: max_ast_depth(settings.max_ast_depth),
|
2018-10-18 15:03:14 +00:00
|
|
|
max_expanded_ast_elements(settings.max_expanded_ast_elements),
|
2018-10-19 15:42:47 +00:00
|
|
|
count_distinct_implementation(settings.count_distinct_implementation),
|
|
|
|
enable_optimize_predicate_expression(settings.enable_optimize_predicate_expression)
|
2018-10-18 15:03:14 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
2018-03-04 16:15:31 +00:00
|
|
|
public:
|
2018-10-18 15:03:14 +00:00
|
|
|
PredicateExpressionsOptimizer(ASTSelectQuery * ast_select_, ExtractedSettings && settings_, const Context & context_);
|
2018-03-04 16:15:31 +00:00
|
|
|
|
|
|
|
bool optimize();
|
|
|
|
|
|
|
|
private:
|
|
|
|
ASTSelectQuery * ast_select;
|
2018-10-18 15:03:14 +00:00
|
|
|
const ExtractedSettings settings;
|
2018-08-22 06:42:37 +00:00
|
|
|
const Context & context;
|
2018-03-04 16:15:31 +00:00
|
|
|
|
|
|
|
enum OptimizeKind
|
|
|
|
{
|
|
|
|
NONE,
|
|
|
|
PUSH_TO_PREWHERE,
|
|
|
|
PUSH_TO_WHERE,
|
|
|
|
PUSH_TO_HAVING,
|
|
|
|
};
|
|
|
|
|
2018-09-12 05:41:09 +00:00
|
|
|
bool isArrayJoinFunction(const ASTPtr & node);
|
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
std::vector<ASTPtr> splitConjunctionPredicate(ASTPtr & predicate_expression);
|
2018-03-04 16:15:31 +00:00
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
std::vector<IdentifierWithQualifier> getDependenciesAndQualifiers(ASTPtr & expression,
|
|
|
|
std::vector<DatabaseAndTableWithAlias> & tables_with_aliases);
|
2018-03-04 16:15:31 +00:00
|
|
|
|
|
|
|
bool optimizeExpression(const ASTPtr & outer_expression, ASTPtr & subquery_expression, ASTSelectQuery * subquery);
|
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
bool optimizeImpl(ASTPtr & outer_expression, SubqueriesProjectionColumns & subqueries_projection_columns, OptimizeKind optimize_kind);
|
2018-03-04 16:15:31 +00:00
|
|
|
|
2019-01-30 02:47:26 +00:00
|
|
|
bool allowPushDown(const ASTSelectQuery * subquery);
|
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
bool canPushDownOuterPredicate(const std::vector<ProjectionWithAlias> & subquery_projection_columns,
|
|
|
|
const std::vector<IdentifierWithQualifier> & outer_predicate_dependencies,
|
|
|
|
OptimizeKind & optimize_kind);
|
2018-03-04 16:15:31 +00:00
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
void setNewAliasesForInnerPredicate(const std::vector<ProjectionWithAlias> & projection_columns,
|
|
|
|
const std::vector<IdentifierWithQualifier> & inner_predicate_dependencies);
|
2018-03-04 16:15:31 +00:00
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
SubqueriesProjectionColumns getAllSubqueryProjectionColumns();
|
2018-03-04 16:15:31 +00:00
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
void getSubqueryProjectionColumns(const ASTPtr & subquery, SubqueriesProjectionColumns & all_subquery_projection_columns);
|
2018-03-04 16:15:31 +00:00
|
|
|
|
2018-08-22 06:42:37 +00:00
|
|
|
ASTs getSelectQueryProjectionColumns(ASTPtr & ast);
|
|
|
|
|
|
|
|
ASTs evaluateAsterisk(ASTSelectQuery * select_query, const ASTPtr & asterisk);
|
2018-09-27 05:27:45 +00:00
|
|
|
|
|
|
|
void cleanExpressionAlias(ASTPtr & expression);
|
2018-03-04 16:15:31 +00:00
|
|
|
};
|
|
|
|
|
2018-08-14 21:48:39 +00:00
|
|
|
}
|