dbms: added ALL JOINs [#METR-11370].

This commit is contained in:
Alexey Milovidov 2014-06-19 23:00:58 +04:00
parent 7c0f53c34f
commit 4645131f7a
2 changed files with 34 additions and 2 deletions

View File

@ -21,6 +21,38 @@ namespace DB
/** Структура данных для реализации JOIN-а. /** Структура данных для реализации 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 class Join
{ {

View File

@ -162,8 +162,8 @@ struct Inserter<ASTJoin::All, Map>
*/ */
Join::RowRefList * elem = reinterpret_cast<Join::RowRefList *>(pool.alloc(sizeof(Join::RowRefList))); Join::RowRefList * elem = reinterpret_cast<Join::RowRefList *>(pool.alloc(sizeof(Join::RowRefList)));
it->second.next = elem;
elem->next = it->second.next; elem->next = it->second.next;
it->second.next = elem;
elem->block = stored_block; elem->block = stored_block;
elem->row_num = i; elem->row_num = i;
} }
@ -188,8 +188,8 @@ struct Inserter<ASTJoin::All, Join::MapsAll::MapString>
{ {
Join::RowRefList * elem = reinterpret_cast<Join::RowRefList *>(pool.alloc(sizeof(Join::RowRefList))); Join::RowRefList * elem = reinterpret_cast<Join::RowRefList *>(pool.alloc(sizeof(Join::RowRefList)));
it->second.next = elem;
elem->next = it->second.next; elem->next = it->second.next;
it->second.next = elem;
elem->block = stored_block; elem->block = stored_block;
elem->row_num = i; elem->row_num = i;
} }