From daa672e6f0bba749c27b5fc16557c60a8b0425f1 Mon Sep 17 00:00:00 2001 From: rbock Date: Sat, 25 May 2019 14:04:44 +0200 Subject: [PATCH] Fix joins with CTEs --- include/sqlpp11/cte.h | 1 + include/sqlpp11/pre_join.h | 18 ++++++++++-------- tests/With.cpp | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/include/sqlpp11/cte.h b/include/sqlpp11/cte.h index 9b3d40d4..eaa1129e 100644 --- a/include/sqlpp11/cte.h +++ b/include/sqlpp11/cte.h @@ -163,6 +163,7 @@ namespace sqlpp { using _traits = make_traits; // FIXME: is table? really? using _nodes = detail::type_vector<>; + using _provided_tables = detail::type_set; using _required_ctes = detail::make_joined_set_t, detail::type_set>; using _parameters = parameters_of; diff --git a/include/sqlpp11/pre_join.h b/include/sqlpp11/pre_join.h index 15270b09..975b5042 100644 --- a/include/sqlpp11/pre_join.h +++ b/include/sqlpp11/pre_join.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace sqlpp { @@ -154,7 +155,7 @@ namespace sqlpp auto join_impl(Check, Lhs lhs, Rhs rhs) -> inconsistent; template - auto join_impl(consistent_t, Lhs lhs, Rhs rhs) -> pre_join_t; + auto join_impl(consistent_t, Lhs lhs, Rhs rhs) -> pre_join_t, from_table_t>; template auto join_impl(Lhs lhs, Rhs rhs) -> decltype(join_impl(check_pre_join_t{}, lhs, rhs)); @@ -163,19 +164,19 @@ namespace sqlpp template auto join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl(lhs, rhs)) { - return {lhs, rhs}; + return {from_table(lhs), from_table(rhs)}; } template auto inner_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl(lhs, rhs)) { - return {lhs, rhs}; + return {from_table(lhs), from_table(rhs)}; } template auto left_outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl(lhs, rhs)) { - return {lhs, rhs}; + return {from_table(lhs), from_table(rhs)}; } template @@ -183,13 +184,13 @@ namespace sqlpp { check_pre_join_t{}; - return {lhs, rhs}; + return {from_table(lhs), from_table(rhs)}; } template auto outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl(lhs, rhs)) { - return {lhs, rhs}; + return {from_table(lhs), from_table(rhs)}; } namespace detail @@ -202,13 +203,14 @@ namespace sqlpp -> join_t, on_t>; template - auto cross_join_impl(Lhs lhs, Rhs rhs) -> decltype(cross_join_impl(check_pre_join_t{}, lhs, rhs)); + auto cross_join_impl(Lhs lhs, Rhs rhs) + -> decltype(cross_join_impl(check_pre_join_t, from_table_t>{}, lhs, rhs)); } // namespace detail template auto cross_join(Lhs lhs, Rhs rhs) -> decltype(detail::cross_join_impl(lhs, rhs)) { - return {pre_join_t{lhs, rhs}, {}}; + return {pre_join_t, from_table_t>{from_table(lhs), from_table(rhs)}, {}}; } } // namespace sqlpp diff --git a/tests/With.cpp b/tests/With.cpp index dae27867..fbd2995f 100644 --- a/tests/With.cpp +++ b/tests/With.cpp @@ -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)))); 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; }