#pragma once #include #include #include /** Used in implementation of Join to process different data structures. */ namespace DB { template struct MapGetterImpl; template <> struct MapGetterImpl { using Map = Join::MapsAny; }; template <> struct MapGetterImpl { using Map = Join::MapsAnyFull; }; template <> struct MapGetterImpl { using Map = Join::MapsAll; }; template <> struct MapGetterImpl { using Map = Join::MapsAllFull; }; template struct MapGetterImpl { using Map = Join::MapsAsof; }; template struct KindTrait { // Affects the Adder trait so that when the right part is empty, adding a default value on the left static constexpr bool fill_left = static_in_v; // Affects the Map trait so that a `used` flag is attached to map slots in order to // generate default values on the right when the left part is empty static constexpr bool fill_right = static_in_v; }; template using Map = typename MapGetterImpl::fill_right, strictness>::Map; static constexpr std::array STRICTNESSES = { ASTTableJoin::Strictness::Any, ASTTableJoin::Strictness::All, ASTTableJoin::Strictness::Asof }; static constexpr std::array KINDS = { ASTTableJoin::Kind::Left, ASTTableJoin::Kind::Inner, ASTTableJoin::Kind::Full, ASTTableJoin::Kind::Right }; /// Init specified join map inline bool joinDispatchInit(ASTTableJoin::Kind kind, ASTTableJoin::Strictness strictness, Join::MapsVariant & maps) { 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]) { maps = Map(); return true; } return false; }); } /// Call function on specified join map template 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(), std::integral_constant(), std::get>(maps)); return true; } return false; }); } }