2019-07-02 14:38:31 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
#include <common/constexpr_helpers.h>
|
|
|
|
|
2020-04-07 09:48:47 +00:00
|
|
|
#include <Interpreters/HashJoin.h>
|
2019-07-02 14:38:31 +00:00
|
|
|
|
2019-07-02 22:55:36 +00:00
|
|
|
|
|
|
|
/** Used in implementation of Join to process different data structures.
|
|
|
|
*/
|
|
|
|
|
2019-07-02 14:38:31 +00:00
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2019-11-07 21:32:44 +00:00
|
|
|
template <ASTTableJoin::Kind kind, typename ASTTableJoin::Strictness>
|
|
|
|
struct MapGetter;
|
|
|
|
|
2021-02-04 14:46:36 +00:00
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Left, ASTTableJoin::Strictness::RightAny> { using Map = HashJoin::MapsOne; static constexpr bool flagged = false; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Inner, ASTTableJoin::Strictness::RightAny> { using Map = HashJoin::MapsOne; static constexpr bool flagged = false; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Right, ASTTableJoin::Strictness::RightAny> { using Map = HashJoin::MapsOne; static constexpr bool flagged = true; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Full, ASTTableJoin::Strictness::RightAny> { using Map = HashJoin::MapsOne; static constexpr bool flagged = true; };
|
2019-11-07 21:32:44 +00:00
|
|
|
|
2021-02-04 14:46:36 +00:00
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Left, ASTTableJoin::Strictness::Any> { using Map = HashJoin::MapsOne; static constexpr bool flagged = false; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Inner, ASTTableJoin::Strictness::Any> { using Map = HashJoin::MapsOne; static constexpr bool flagged = true; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Right, ASTTableJoin::Strictness::Any> { using Map = HashJoin::MapsAll; static constexpr bool flagged = true; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Full, ASTTableJoin::Strictness::Any> { using Map = HashJoin::MapsAll; static constexpr bool flagged = true; };
|
2019-11-07 21:32:44 +00:00
|
|
|
|
2021-02-04 14:46:36 +00:00
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Left, ASTTableJoin::Strictness::All> { using Map = HashJoin::MapsAll; static constexpr bool flagged = false; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Inner, ASTTableJoin::Strictness::All> { using Map = HashJoin::MapsAll; static constexpr bool flagged = false; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Right, ASTTableJoin::Strictness::All> { using Map = HashJoin::MapsAll; static constexpr bool flagged = true; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Full, ASTTableJoin::Strictness::All> { using Map = HashJoin::MapsAll; static constexpr bool flagged = true; };
|
2019-11-07 21:32:44 +00:00
|
|
|
|
2019-12-05 12:01:34 +00:00
|
|
|
/// Only SEMI LEFT and SEMI RIGHT are valid. INNER and FULL are here for templates instantiation.
|
2021-02-04 14:46:36 +00:00
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Left, ASTTableJoin::Strictness::Semi> { using Map = HashJoin::MapsOne; static constexpr bool flagged = false; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Inner, ASTTableJoin::Strictness::Semi> { using Map = HashJoin::MapsOne; static constexpr bool flagged = false; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Right, ASTTableJoin::Strictness::Semi> { using Map = HashJoin::MapsAll; static constexpr bool flagged = true; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Full, ASTTableJoin::Strictness::Semi> { using Map = HashJoin::MapsOne; static constexpr bool flagged = false; };
|
2019-12-02 18:07:27 +00:00
|
|
|
|
2019-12-05 12:01:34 +00:00
|
|
|
/// Only SEMI LEFT and SEMI RIGHT are valid. INNER and FULL are here for templates instantiation.
|
2021-02-04 14:46:36 +00:00
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Left, ASTTableJoin::Strictness::Anti> { using Map = HashJoin::MapsOne; static constexpr bool flagged = false; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Inner, ASTTableJoin::Strictness::Anti> { using Map = HashJoin::MapsOne; static constexpr bool flagged = false; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Right, ASTTableJoin::Strictness::Anti> { using Map = HashJoin::MapsAll; static constexpr bool flagged = true; };
|
|
|
|
template <> struct MapGetter<ASTTableJoin::Kind::Full, ASTTableJoin::Strictness::Anti> { using Map = HashJoin::MapsOne; static constexpr bool flagged = false; };
|
2019-12-02 18:07:27 +00:00
|
|
|
|
2019-11-07 21:32:44 +00:00
|
|
|
template <ASTTableJoin::Kind kind>
|
2021-02-04 14:46:36 +00:00
|
|
|
struct MapGetter<kind, ASTTableJoin::Strictness::Asof> { using Map = HashJoin::MapsAsof; static constexpr bool flagged = false; };
|
2019-07-02 14:38:31 +00:00
|
|
|
|
|
|
|
|
2019-12-02 18:07:27 +00:00
|
|
|
static constexpr std::array<ASTTableJoin::Strictness, 6> STRICTNESSES = {
|
2019-11-07 21:32:44 +00:00
|
|
|
ASTTableJoin::Strictness::RightAny,
|
2019-07-02 14:38:31 +00:00
|
|
|
ASTTableJoin::Strictness::Any,
|
|
|
|
ASTTableJoin::Strictness::All,
|
2019-12-02 18:07:27 +00:00
|
|
|
ASTTableJoin::Strictness::Asof,
|
|
|
|
ASTTableJoin::Strictness::Semi,
|
|
|
|
ASTTableJoin::Strictness::Anti,
|
2019-07-02 14:38:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static constexpr std::array<ASTTableJoin::Kind, 4> KINDS = {
|
|
|
|
ASTTableJoin::Kind::Left,
|
|
|
|
ASTTableJoin::Kind::Inner,
|
|
|
|
ASTTableJoin::Kind::Full,
|
|
|
|
ASTTableJoin::Kind::Right
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Init specified join map
|
2020-04-07 09:48:47 +00:00
|
|
|
inline bool joinDispatchInit(ASTTableJoin::Kind kind, ASTTableJoin::Strictness strictness, HashJoin::MapsVariant & maps)
|
2019-07-02 14:38:31 +00:00
|
|
|
{
|
|
|
|
return static_for<0, KINDS.size() * STRICTNESSES.size()>([&](auto ij)
|
|
|
|
{
|
|
|
|
constexpr auto i = ij / STRICTNESSES.size();
|
|
|
|
constexpr auto j = ij % STRICTNESSES.size();
|
|
|
|
if (kind == KINDS[i] && strictness == STRICTNESSES[j])
|
|
|
|
{
|
2019-11-07 21:32:44 +00:00
|
|
|
maps = typename MapGetter<KINDS[i], STRICTNESSES[j]>::Map();
|
2019-07-02 14:38:31 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Call function on specified join map
|
|
|
|
template <typename MapsVariant, typename Func>
|
|
|
|
inline bool joinDispatch(ASTTableJoin::Kind kind, ASTTableJoin::Strictness strictness, MapsVariant & maps, Func && func)
|
|
|
|
{
|
|
|
|
return static_for<0, KINDS.size() * STRICTNESSES.size()>([&](auto ij)
|
|
|
|
{
|
|
|
|
// NOTE: Avoid using nested static loop as GCC and CLANG have bugs in different ways
|
|
|
|
// See https://stackoverflow.com/questions/44386415/gcc-and-clang-disagree-about-c17-constexpr-lambda-captures
|
|
|
|
constexpr auto i = ij / STRICTNESSES.size();
|
|
|
|
constexpr auto j = ij % STRICTNESSES.size();
|
|
|
|
if (kind == KINDS[i] && strictness == STRICTNESSES[j])
|
|
|
|
{
|
|
|
|
func(
|
|
|
|
std::integral_constant<ASTTableJoin::Kind, KINDS[i]>(),
|
|
|
|
std::integral_constant<ASTTableJoin::Strictness, STRICTNESSES[j]>(),
|
2019-11-07 21:32:44 +00:00
|
|
|
std::get<typename MapGetter<KINDS[i], STRICTNESSES[j]>::Map>(maps));
|
2019-07-02 14:38:31 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|