mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 16:42:05 +00:00
dbms: added ALL JOINs [#METR-11370].
This commit is contained in:
parent
7c0f53c34f
commit
4645131f7a
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user