This commit is contained in:
Alexey Arno 2015-04-17 16:56:29 +03:00
parent a2f2cc369d
commit 8a317f076d
3 changed files with 15 additions and 6 deletions

View File

@ -63,8 +63,12 @@ public:
*/
BlockInputStreamPtr execute();
/// Выполнить запрос без объединения потоков.
const BlockInputStreams & executeWithoutUnion();
/** Выполнить запрос без объединения потоков.
* Если force_no_union = false, выполнить объединения, которые не могут быть отложены до оформления окончательного результата.
* Если же force_no_union = true, не выполнять никаких объединений. Это позволяет оптимизировать запросы, в которых таблица
* является представлением.
*/
const BlockInputStreams & executeWithoutUnion(bool force_no_union);
/** Выполнить запрос, записать результат в нужном формате в buf.
* BlockInputStreamPtr возвращается, чтобы можно было потом получить информацию о плане выполнения запроса.
@ -142,6 +146,9 @@ private:
StoragePtr storage;
IStorage::TableStructureReadLockPtr table_lock;
/// См. описание функции executeWithoutUnion().
bool force_no_union = false;
Logger * log;
};

View File

@ -293,7 +293,7 @@ Block InterpreterSelectQuery::getSampleBlock()
BlockInputStreamPtr InterpreterSelectQuery::execute()
{
(void) executeWithoutUnion();
(void) executeWithoutUnion(false);
if (streams.empty())
return new NullBlockInputStream;
@ -323,8 +323,10 @@ BlockInputStreamPtr InterpreterSelectQuery::execute()
return streams[0];
}
const BlockInputStreams & InterpreterSelectQuery::executeWithoutUnion()
const BlockInputStreams & InterpreterSelectQuery::executeWithoutUnion(bool force_no_union_)
{
force_no_union = force_no_union_;
if (is_first_select_inside_union_all)
{
executeSingleQuery();
@ -559,7 +561,7 @@ void InterpreterSelectQuery::executeSingleQuery()
if (need_second_distinct_pass)
do_execute_union = true;
if (do_execute_union)
if (do_execute_union && !force_no_union)
executeUnion(streams);
/// Если было более одного источника - то нужно выполнить DISTINCT ещё раз после их слияния.

View File

@ -92,7 +92,7 @@ BlockInputStreams StorageView::read(
if (outer_select.final && !inner_select.final)
inner_select.final = outer_select.final;
return InterpreterSelectQuery(inner_query_clone, context, column_names).executeWithoutUnion();
return InterpreterSelectQuery(inner_query_clone, context, column_names).executeWithoutUnion(true);
}