0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Fix joins with CTEs

This commit is contained in:
rbock 2019-05-25 14:04:44 +02:00
parent c4db147ca0
commit daa672e6f0
3 changed files with 30 additions and 8 deletions

View File

@ -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>;

View File

@ -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

View File

@ -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;
} }