mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
some mote ExpressionAnalyzer refactoring
This commit is contained in:
parent
1f95bf18e4
commit
9a8db441c3
@ -9,6 +9,7 @@
|
||||
#include <Parsers/ASTSelectQuery.h>
|
||||
|
||||
#include <Storages/IStorage.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
@ -51,24 +52,13 @@ ExpressionActionsPtr AnalyzedJoin::createJoinedBlockActions(
|
||||
return analyzer.getActions(false);
|
||||
}
|
||||
|
||||
NameSet AnalyzedJoin::getRequiredColumnsFromJoinedTable(const JoinedColumnsList & columns_added_by_join,
|
||||
const ExpressionActionsPtr & joined_block_actions) const
|
||||
Names AnalyzedJoin::getOriginalColumnNames(const NameSet & required_columns_from_joined_table) const
|
||||
{
|
||||
NameSet required_columns_from_joined_table;
|
||||
|
||||
auto required_action_columns = joined_block_actions->getRequiredColumns();
|
||||
required_columns_from_joined_table.insert(required_action_columns.begin(), required_action_columns.end());
|
||||
auto sample = joined_block_actions->getSampleBlock();
|
||||
|
||||
for (auto & column : key_names_right)
|
||||
if (!sample.has(column))
|
||||
required_columns_from_joined_table.insert(column);
|
||||
|
||||
for (auto & column : columns_added_by_join)
|
||||
if (!sample.has(column.name_and_type.name))
|
||||
required_columns_from_joined_table.insert(column.name_and_type.name);
|
||||
|
||||
return required_columns_from_joined_table;
|
||||
Names original_columns;
|
||||
for (const auto & column : columns_from_joined_table)
|
||||
if (required_columns_from_joined_table.count(column.name_and_type.name))
|
||||
original_columns.emplace_back(column.original_name);
|
||||
return original_columns;
|
||||
}
|
||||
|
||||
const JoinedColumnsList & AnalyzedJoin::getColumnsFromJoinedTable(
|
||||
@ -104,6 +94,30 @@ const JoinedColumnsList & AnalyzedJoin::getColumnsFromJoinedTable(
|
||||
return columns_from_joined_table;
|
||||
}
|
||||
|
||||
void AnalyzedJoin::calculateAvailableJoinedColumns(
|
||||
const NameSet & source_columns, const Context & context, const ASTSelectQuery * select_query_with_join, bool make_nullable)
|
||||
{
|
||||
const auto & columns = getColumnsFromJoinedTable(source_columns, context, select_query_with_join);
|
||||
|
||||
NameSet joined_columns;
|
||||
|
||||
for (auto & column : columns)
|
||||
{
|
||||
auto & column_name = column.name_and_type.name;
|
||||
auto & column_type = column.name_and_type.type;
|
||||
auto & original_name = column.original_name;
|
||||
{
|
||||
if (joined_columns.count(column_name)) /// Duplicate columns in the subquery for JOIN do not make sense.
|
||||
continue;
|
||||
|
||||
joined_columns.insert(column_name);
|
||||
|
||||
auto type = make_nullable ? makeNullable(column_type) : column_type;
|
||||
available_joined_columns.emplace_back(NameAndTypePair(column_name, std::move(type)), original_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NamesAndTypesList getNamesAndTypeListFromTableExpression(const ASTTableExpression & table_expression, const Context & context)
|
||||
{
|
||||
|
@ -66,13 +66,15 @@ struct AnalyzedJoin
|
||||
const ASTSelectQuery * select_query_with_join,
|
||||
const Context & context) const;
|
||||
|
||||
/// Columns which will be used in query from joined table.
|
||||
NameSet getRequiredColumnsFromJoinedTable(const JoinedColumnsList & columns_added_by_join,
|
||||
const ExpressionActionsPtr & joined_block_actions) const;
|
||||
Names getOriginalColumnNames(const NameSet & required_columns) const;
|
||||
|
||||
const JoinedColumnsList & getColumnsFromJoinedTable(const NameSet & source_columns,
|
||||
const Context & context,
|
||||
const ASTSelectQuery * select_query_with_join);
|
||||
void calculateAvailableJoinedColumns(const NameSet & source_columns,
|
||||
const Context & context,
|
||||
const ASTSelectQuery * select_query_with_join,
|
||||
bool make_nullable);
|
||||
};
|
||||
|
||||
struct ASTTableExpression;
|
||||
|
@ -510,6 +510,17 @@ void ExpressionAnalyzer::addJoinAction(ExpressionActionsPtr & actions, bool only
|
||||
columns_added_by_join_list));
|
||||
}
|
||||
|
||||
static void appendRequiredColumns(NameSet & required_columns, const Block & sample, const AnalyzedJoin & analyzed_join)
|
||||
{
|
||||
for (auto & column : analyzed_join.key_names_right)
|
||||
if (!sample.has(column))
|
||||
required_columns.insert(column);
|
||||
|
||||
for (auto & column : analyzed_join.columns_from_joined_table)
|
||||
if (!sample.has(column.name_and_type.name))
|
||||
required_columns.insert(column.name_and_type.name);
|
||||
}
|
||||
|
||||
bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_types)
|
||||
{
|
||||
assertSelect();
|
||||
@ -566,6 +577,11 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty
|
||||
|
||||
if (!subquery_for_set.join)
|
||||
{
|
||||
auto & analyzed_join = analyzedJoin();
|
||||
/// Actions which need to be calculated on joined block.
|
||||
ExpressionActionsPtr joined_block_actions =
|
||||
analyzed_join.createJoinedBlockActions(columns_added_by_join, select_query, context);
|
||||
|
||||
/** For GLOBAL JOINs (in the case, for example, of the push method for executing GLOBAL subqueries), the following occurs
|
||||
* - in the addExternalStorage function, the JOIN (SELECT ...) subquery is replaced with JOIN _data1,
|
||||
* in the subquery_for_set object this subquery is exposed as source and the temporary table _data1 as the `table`.
|
||||
@ -582,15 +598,15 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty
|
||||
else if (table_to_join.database_and_table_name)
|
||||
table = table_to_join.database_and_table_name;
|
||||
|
||||
const JoinedColumnsList & columns_from_joined_table = analyzedJoin().columns_from_joined_table;
|
||||
Names action_columns = joined_block_actions->getRequiredColumns();
|
||||
NameSet required_columns(action_columns.begin(), action_columns.end());
|
||||
|
||||
Names original_columns;
|
||||
for (const auto & column : columns_from_joined_table)
|
||||
if (required_columns_from_joined_table.count(column.name_and_type.name))
|
||||
original_columns.emplace_back(column.original_name);
|
||||
appendRequiredColumns(required_columns, joined_block_actions->getSampleBlock(), analyzed_join);
|
||||
|
||||
Names original_columns = analyzed_join.getOriginalColumnNames(required_columns);
|
||||
|
||||
auto interpreter = interpretSubquery(table, context, subquery_depth, original_columns);
|
||||
subquery_for_set.makeSource(interpreter, columns_from_joined_table, required_columns_from_joined_table);
|
||||
subquery_for_set.makeSource(interpreter, analyzed_join.columns_from_joined_table, required_columns);
|
||||
}
|
||||
|
||||
Block sample_block = subquery_for_set.renamedSampleBlock();
|
||||
@ -1038,9 +1054,6 @@ void ExpressionAnalyzer::collectUsedColumns()
|
||||
|
||||
required.swap(fixed_required);
|
||||
}
|
||||
|
||||
joined_block_actions = analyzed_join.createJoinedBlockActions(columns_added_by_join, select_query, context);
|
||||
required_columns_from_joined_table = analyzed_join.getRequiredColumnsFromJoinedTable(columns_added_by_join, joined_block_actions);
|
||||
}
|
||||
|
||||
if (columns_context.has_array_join)
|
||||
|
@ -67,12 +67,6 @@ struct ExpressionAnalyzerData
|
||||
/// Columns will be added to block by join.
|
||||
JoinedColumnsList columns_added_by_join; /// Subset of analyzed_join.available_joined_columns
|
||||
|
||||
/// Actions which need to be calculated on joined block.
|
||||
ExpressionActionsPtr joined_block_actions;
|
||||
|
||||
/// Columns which will be used in query from joined table. Duplicate names are qualified.
|
||||
NameSet required_columns_from_joined_table;
|
||||
|
||||
protected:
|
||||
ExpressionAnalyzerData(const NamesAndTypesList & source_columns_,
|
||||
const NameSet & required_result_columns_,
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <Parsers/queryToString.h>
|
||||
|
||||
#include <DataTypes/NestedUtils.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <Core/NamesAndTypes.h>
|
||||
@ -641,29 +640,11 @@ void collectJoinedColumns(AnalyzedJoin & analyzed_join, const ASTSelectQuery * s
|
||||
else if (table_join.on_expression)
|
||||
collectJoinedColumnsFromJoinOnExpr(analyzed_join, select_query, source_columns, context);
|
||||
|
||||
auto & columns_from_joined_table = analyzed_join.getColumnsFromJoinedTable(source_columns, context, select_query);
|
||||
|
||||
NameSet joined_columns;
|
||||
|
||||
auto & settings = context.getSettingsRef();
|
||||
bool make_nullable = settings.join_use_nulls && (table_join.kind == ASTTableJoin::Kind::Left ||
|
||||
table_join.kind == ASTTableJoin::Kind::Full);
|
||||
|
||||
for (auto & column : columns_from_joined_table)
|
||||
{
|
||||
auto & column_name = column.name_and_type.name;
|
||||
auto & column_type = column.name_and_type.type;
|
||||
auto & original_name = column.original_name;
|
||||
{
|
||||
if (joined_columns.count(column_name)) /// Duplicate columns in the subquery for JOIN do not make sense.
|
||||
continue;
|
||||
|
||||
joined_columns.insert(column_name);
|
||||
|
||||
bool make_nullable = settings.join_use_nulls && (table_join.kind == ASTTableJoin::Kind::Left ||
|
||||
table_join.kind == ASTTableJoin::Kind::Full);
|
||||
auto type = make_nullable ? makeNullable(column_type) : column_type;
|
||||
analyzed_join.available_joined_columns.emplace_back(NameAndTypePair(column_name, std::move(type)), original_name);
|
||||
}
|
||||
}
|
||||
analyzed_join.calculateAvailableJoinedColumns(source_columns, context, select_query, make_nullable);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user