From 4645131f7ac144ee98fe2110c1a68643a5640bec Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 19 Jun 2014 23:00:58 +0400 Subject: [PATCH] dbms: added ALL JOINs [#METR-11370]. --- dbms/include/DB/Interpreters/Join.h | 32 +++++++++++++++++++++++++++++ dbms/src/Interpreters/Join.cpp | 4 ++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/dbms/include/DB/Interpreters/Join.h b/dbms/include/DB/Interpreters/Join.h index be6951669e9..fbd2569426c 100644 --- a/dbms/include/DB/Interpreters/Join.h +++ b/dbms/include/DB/Interpreters/Join.h @@ -21,6 +21,38 @@ namespace DB /** Структура данных для реализации JOIN-а. * По сути, хэш-таблица: ключи -> строки присоединяемой таблицы. + * + * JOIN-ы бывают четырёх типов: ANY/ALL x LEFT/INNER. + * + * Если указано ANY - выбрать из "правой" таблицы только одну, первую попавшуюся строку, даже если там более одной соответствующей строки. + * Если указано ALL - обычный вариант JOIN-а, при котором строки могут размножаться по числу соответствующих строк "правой" таблицы. + * Вариант ANY работает более оптимально. + * + * Если указано INNER - оставить только строки, для которых есть хотя бы одна строка "правой" таблицы. + * Если указано LEFT - в случае, если в "правой" таблице нет соответствующей строки, заполнить её значениями "по-умолчанию". + * + * Все соединения делаются по равенству кортежа столбцов "ключей" (эквисоединение). + * Неравенства и прочие условия не поддерживаются. + * + * Реализация такая: + * + * 1. "Правая" таблица засовывается в хэш-таблицу в оперативке. + * Она имеет вид keys -> row в случае ANY или keys -> [rows...] в случае ALL. + * Это делается в функции insertFromBlock. + * + * 2. При обработке "левой" таблицы, присоединяем к ней данные из сформированной хэш-таблицы. + * Это делается в функции joinBlock. + * + * В случае ANY LEFT JOIN - формируем новые столбцы с найденной строкой или значениями по-умолчанию. + * Самый простой вариант. Количество строк при JOIN-е не меняется. + * + * В случае ANY INNER JOIN - формируем новые столбцы с найденной строкой; + * а также заполняем фильтр - для каких строк значения не нашлось. + * После чего, фильтруем столбцы "левой" таблицы. + * + * В случае ALL ... JOIN - формируем новые столбцы со всеми найденными строками; + * а также заполняем массив offsets, описывающий, во сколько раз надо размножить строки "левой" таблицы. + * После чего, размножаем столбцы "левой" таблицы. */ class Join { diff --git a/dbms/src/Interpreters/Join.cpp b/dbms/src/Interpreters/Join.cpp index 7ea747ed3cd..526c8f591ab 100644 --- a/dbms/src/Interpreters/Join.cpp +++ b/dbms/src/Interpreters/Join.cpp @@ -162,8 +162,8 @@ struct Inserter */ Join::RowRefList * elem = reinterpret_cast(pool.alloc(sizeof(Join::RowRefList))); - it->second.next = elem; elem->next = it->second.next; + it->second.next = elem; elem->block = stored_block; elem->row_num = i; } @@ -188,8 +188,8 @@ struct Inserter { Join::RowRefList * elem = reinterpret_cast(pool.alloc(sizeof(Join::RowRefList))); - it->second.next = elem; elem->next = it->second.next; + it->second.next = elem; elem->block = stored_block; elem->row_num = i; }