mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +08:00
Fix joins with CTEs
This commit is contained in:
parent
c4db147ca0
commit
daa672e6f0
@ -163,6 +163,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, tag::is_cte, tag::is_table>; // FIXME: is table? really?
|
using _traits = make_traits<no_value_t, tag::is_cte, tag::is_table>; // FIXME: is table? really?
|
||||||
using _nodes = detail::type_vector<>;
|
using _nodes = detail::type_vector<>;
|
||||||
|
using _provided_tables = detail::type_set<cte_t>;
|
||||||
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Statement>, detail::type_set<AliasProvider>>;
|
using _required_ctes = detail::make_joined_set_t<required_ctes_of<Statement>, detail::type_set<AliasProvider>>;
|
||||||
using _parameters = parameters_of<Statement>;
|
using _parameters = parameters_of<Statement>;
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <sqlpp11/join_types.h>
|
#include <sqlpp11/join_types.h>
|
||||||
#include <sqlpp11/noop.h>
|
#include <sqlpp11/noop.h>
|
||||||
#include <sqlpp11/on.h>
|
#include <sqlpp11/on.h>
|
||||||
|
#include <sqlpp11/table_ref.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -154,7 +155,7 @@ namespace sqlpp
|
|||||||
auto join_impl(Check, Lhs lhs, Rhs rhs) -> inconsistent<Check>;
|
auto join_impl(Check, Lhs lhs, Rhs rhs) -> inconsistent<Check>;
|
||||||
|
|
||||||
template <typename JoinType, typename Lhs, typename Rhs>
|
template <typename JoinType, typename Lhs, typename Rhs>
|
||||||
auto join_impl(consistent_t, Lhs lhs, Rhs rhs) -> pre_join_t<JoinType, Lhs, Rhs>;
|
auto join_impl(consistent_t, Lhs lhs, Rhs rhs) -> pre_join_t<JoinType, from_table_t<Lhs>, from_table_t<Rhs>>;
|
||||||
|
|
||||||
template <typename JoinType, typename Lhs, typename Rhs>
|
template <typename JoinType, typename Lhs, typename Rhs>
|
||||||
auto join_impl(Lhs lhs, Rhs rhs) -> decltype(join_impl<JoinType>(check_pre_join_t<Lhs, Rhs>{}, lhs, rhs));
|
auto join_impl(Lhs lhs, Rhs rhs) -> decltype(join_impl<JoinType>(check_pre_join_t<Lhs, Rhs>{}, lhs, rhs));
|
||||||
@ -163,19 +164,19 @@ namespace sqlpp
|
|||||||
template <typename Lhs, typename Rhs>
|
template <typename Lhs, typename Rhs>
|
||||||
auto join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<inner_join_t>(lhs, rhs))
|
auto join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<inner_join_t>(lhs, rhs))
|
||||||
{
|
{
|
||||||
return {lhs, rhs};
|
return {from_table(lhs), from_table(rhs)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Lhs, typename Rhs>
|
template <typename Lhs, typename Rhs>
|
||||||
auto inner_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<inner_join_t>(lhs, rhs))
|
auto inner_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<inner_join_t>(lhs, rhs))
|
||||||
{
|
{
|
||||||
return {lhs, rhs};
|
return {from_table(lhs), from_table(rhs)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Lhs, typename Rhs>
|
template <typename Lhs, typename Rhs>
|
||||||
auto left_outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<left_outer_join_t>(lhs, rhs))
|
auto left_outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<left_outer_join_t>(lhs, rhs))
|
||||||
{
|
{
|
||||||
return {lhs, rhs};
|
return {from_table(lhs), from_table(rhs)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Lhs, typename Rhs>
|
template <typename Lhs, typename Rhs>
|
||||||
@ -183,13 +184,13 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
check_pre_join_t<Lhs, Rhs>{};
|
check_pre_join_t<Lhs, Rhs>{};
|
||||||
|
|
||||||
return {lhs, rhs};
|
return {from_table(lhs), from_table(rhs)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Lhs, typename Rhs>
|
template <typename Lhs, typename Rhs>
|
||||||
auto outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<outer_join_t>(lhs, rhs))
|
auto outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<outer_join_t>(lhs, rhs))
|
||||||
{
|
{
|
||||||
return {lhs, rhs};
|
return {from_table(lhs), from_table(rhs)};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
@ -202,13 +203,14 @@ namespace sqlpp
|
|||||||
-> join_t<pre_join_t<cross_join_t, Lhs, Rhs>, on_t<unconditional_t>>;
|
-> join_t<pre_join_t<cross_join_t, Lhs, Rhs>, on_t<unconditional_t>>;
|
||||||
|
|
||||||
template <typename Lhs, typename Rhs>
|
template <typename Lhs, typename Rhs>
|
||||||
auto cross_join_impl(Lhs lhs, Rhs rhs) -> decltype(cross_join_impl(check_pre_join_t<Lhs, Rhs>{}, lhs, rhs));
|
auto cross_join_impl(Lhs lhs, Rhs rhs)
|
||||||
|
-> decltype(cross_join_impl(check_pre_join_t<from_table_t<Lhs>, from_table_t<Rhs>>{}, lhs, rhs));
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <typename Lhs, typename Rhs>
|
template <typename Lhs, typename Rhs>
|
||||||
auto cross_join(Lhs lhs, Rhs rhs) -> decltype(detail::cross_join_impl(lhs, rhs))
|
auto cross_join(Lhs lhs, Rhs rhs) -> decltype(detail::cross_join_impl(lhs, rhs))
|
||||||
{
|
{
|
||||||
return {pre_join_t<cross_join_t, Lhs, Rhs>{lhs, rhs}, {}};
|
return {pre_join_t<cross_join_t, from_table_t<Lhs>, from_table_t<Rhs>>{from_table(lhs), from_table(rhs)}, {}};
|
||||||
}
|
}
|
||||||
} // namespace sqlpp
|
} // namespace sqlpp
|
||||||
|
|
||||||
|
@ -55,5 +55,24 @@ int With(int, char*[])
|
|||||||
sqlpp::cte(b).as(select(t.alpha.as(a)).from(t).unconditionally().union_all(select(sqlpp::value(123).as(a))));
|
sqlpp::cte(b).as(select(t.alpha.as(a)).from(t).unconditionally().union_all(select(sqlpp::value(123).as(a))));
|
||||||
db(with(c)(select(all_of(c)).from(c).unconditionally()));
|
db(with(c)(select(all_of(c)).from(c).unconditionally()));
|
||||||
|
|
||||||
|
// recursive CTE with join
|
||||||
|
{
|
||||||
|
const auto selectBase = select(t.alpha, t.delta).from(t).where(t.alpha > 17);
|
||||||
|
const auto initialCte = ::sqlpp::cte(sqlpp::alias::a).as(selectBase);
|
||||||
|
const auto recursiveCte = initialCte.union_all(
|
||||||
|
select(t.alpha, t.delta).from(t.join(initialCte).on(t.alpha == initialCte.delta)).unconditionally());
|
||||||
|
const auto query = with(recursiveCte)(select(recursiveCte.alpha).from(recursiveCte).unconditionally());
|
||||||
|
|
||||||
|
::MockDb::_serializer_context_t printer = {};
|
||||||
|
const auto serializedQuery = serialize(query, printer).str();
|
||||||
|
std::cout << serializedQuery << '\n';
|
||||||
|
|
||||||
|
auto db = MockDb{};
|
||||||
|
for (const auto& row : db(query))
|
||||||
|
{
|
||||||
|
std::cout << row.alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user