dbms: Server: Cosmetic changes that make easier to read, understand, and maintain the code that handles UNION ALL. [#METR-14099]

This commit is contained in:
Alexey Arno 2015-07-13 18:02:29 +03:00
parent a3cd654331
commit aa30036fd4
4 changed files with 42 additions and 11 deletions

View File

@ -42,8 +42,7 @@ public:
const Context & context_,
QueryProcessingStage::Enum to_stage_ = QueryProcessingStage::Complete,
size_t subquery_depth_ = 0,
BlockInputStreamPtr input = nullptr,
bool is_union_all_head_ = true);
BlockInputStreamPtr input = nullptr);
InterpreterSelectQuery(
ASTPtr query_ptr_,
@ -76,7 +75,26 @@ public:
DataTypes getReturnTypes();
Block getSampleBlock();
static Block getSampleBlock(
ASTPtr query_ptr_,
const Context & context_,
QueryProcessingStage::Enum to_stage_ = QueryProcessingStage::Complete,
size_t subquery_depth_ = 0);
private:
/**
* ignore_union_all_tail
* - Оптимизация, если объект создаётся только, чтобы вызвать getSampleBlock(): учитываем только первый SELECT цепочки UNION ALL, потом что
* первый SELECT достаточен для определения нужных столбцов.
*/
InterpreterSelectQuery(
ASTPtr query_ptr_,
const Context & context_,
bool ignore_union_all_tail,
QueryProcessingStage::Enum to_stage_ = QueryProcessingStage::Complete,
size_t subquery_depth_ = 0,
BlockInputStreamPtr input = nullptr);
void init(BlockInputStreamPtr input, const Names & required_column_names = Names(), const NamesAndTypesList & table_column_names = NamesAndTypesList());
void basicInit(BlockInputStreamPtr input, const NamesAndTypesList & table_column_names);
void initQueryAnalyzer();

View File

@ -1965,7 +1965,7 @@ void ExpressionAnalyzer::collectJoinedColumns(NameSet & joined_columns, NamesAnd
else if (typeid_cast<const ASTSubquery *>(node.table.get()))
{
const auto & subquery = node.table->children.at(0);
nested_result_sample = InterpreterSelectQuery(subquery, context, QueryProcessingStage::Complete, subquery_depth + 1, nullptr, false).getSampleBlock();
nested_result_sample = InterpreterSelectQuery::getSampleBlock(subquery, context, QueryProcessingStage::Complete, subquery_depth + 1);
}
auto & keys = typeid_cast<ASTExpressionList &>(*node.using_expr_list);

View File

@ -63,7 +63,7 @@ void InterpreterSelectQuery::init(BlockInputStreamPtr input, const Names & requi
ASTSelectQuery & head_query = static_cast<ASTSelectQuery &>(*head);
tail = head_query.next_union_all;
interpreter->next_select_in_union_all.reset(new InterpreterSelectQuery(head, context, to_stage, subquery_depth, nullptr, false));
interpreter->next_select_in_union_all.reset(new InterpreterSelectQuery(head, context, to_stage, subquery_depth));
interpreter = interpreter->next_select_in_union_all.get();
}
}
@ -99,11 +99,7 @@ void InterpreterSelectQuery::basicInit(BlockInputStreamPtr input_, const NamesAn
if (query.table && typeid_cast<ASTSelectQuery *>(&*query.table))
{
if (table_column_names.empty())
{
/// Оптимизация: мы считаем, что запрос содержит только один SELECT, даже если это может быть
/// в самом деле цепочкой UNION ALL. Первый запрос достаточен для определения нужных столбцов.
context.setColumns(InterpreterSelectQuery(query.table, context, to_stage, subquery_depth, nullptr, false).getSampleBlock().getColumnsList());
}
context.setColumns(InterpreterSelectQuery::getSampleBlock(query.table, context, to_stage, subquery_depth).getColumnsList());
}
else
{
@ -173,10 +169,17 @@ void InterpreterSelectQuery::initQueryAnalyzer()
}
InterpreterSelectQuery::InterpreterSelectQuery(ASTPtr query_ptr_, const Context & context_, QueryProcessingStage::Enum to_stage_,
size_t subquery_depth_, BlockInputStreamPtr input_, bool is_union_all_head_)
size_t subquery_depth_, BlockInputStreamPtr input_)
: InterpreterSelectQuery(query_ptr_, context_, false, to_stage_, subquery_depth_, input_)
{
}
InterpreterSelectQuery::InterpreterSelectQuery(ASTPtr query_ptr_, const Context & context_, bool ignore_union_all_tail,
QueryProcessingStage::Enum to_stage_,
size_t subquery_depth_, BlockInputStreamPtr input_)
: query_ptr(query_ptr_), query(typeid_cast<ASTSelectQuery &>(*query_ptr)),
context(context_), to_stage(to_stage_), subquery_depth(subquery_depth_),
is_first_select_inside_union_all(is_union_all_head_ && query.isUnionAllHead()),
is_first_select_inside_union_all(!ignore_union_all_tail && query.isUnionAllHead()),
log(&Logger::get("InterpreterSelectQuery"))
{
init(input_);
@ -303,6 +306,15 @@ Block InterpreterSelectQuery::getSampleBlock()
}
Block InterpreterSelectQuery::getSampleBlock(ASTPtr query_ptr_,
const Context & context_,
QueryProcessingStage::Enum to_stage_,
size_t subquery_depth_)
{
return InterpreterSelectQuery(query_ptr_, context_, true, to_stage_, subquery_depth_).getSampleBlock();
}
BlockIO InterpreterSelectQuery::execute()
{
(void) executeWithoutUnion();

View File

@ -138,6 +138,7 @@ ASTPtr ASTSelectQuery::clone() const
/// Установить указатели на предыдущие запросы SELECT.
ASTPtr current = ptr;
static_cast<ASTSelectQuery *>(&*current)->prev_union_all = nullptr;
ASTPtr next = static_cast<ASTSelectQuery *>(&*current)->next_union_all;
while (!next.isNull())
{