mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 12:51:13 +08:00
More cte tests
This commit is contained in:
parent
25879d1dc0
commit
6128b78f28
@ -161,6 +161,13 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename NameTagProvider, typename NewNameTagProvider, typename... ColumnSpecs>
|
||||||
|
struct required_ctes_of<cte_as_t<NameTagProvider, NewNameTagProvider, ColumnSpecs...>>
|
||||||
|
{
|
||||||
|
// An aliased CTE requires the original CTE from the WITH clause.
|
||||||
|
using type = sqlpp::detail::type_vector<cte_ref_t<NameTagProvider>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Context, typename NameTagProvider, typename NewNameTagProvider, typename... ColumnSpecs>
|
template <typename Context, typename NameTagProvider, typename NewNameTagProvider, typename... ColumnSpecs>
|
||||||
auto to_sql_string(Context& context, const cte_as_t<NameTagProvider, NewNameTagProvider, ColumnSpecs...>&) -> std::string
|
auto to_sql_string(Context& context, const cte_as_t<NameTagProvider, NewNameTagProvider, ColumnSpecs...>&) -> std::string
|
||||||
{
|
{
|
||||||
|
@ -50,16 +50,23 @@ void test_cte()
|
|||||||
static_assert(sqlpp::is_table<X>::value, "");
|
static_assert(sqlpp::is_table<X>::value, "");
|
||||||
static_assert(sqlpp::required_ctes_of_t<X>::empty(), "");
|
static_assert(sqlpp::required_ctes_of_t<X>::empty(), "");
|
||||||
static_assert(std::is_same<sqlpp::provided_ctes_of_t<X>, sqlpp::detail::type_vector<RX>>::value, "");
|
static_assert(std::is_same<sqlpp::provided_ctes_of_t<X>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
static_assert(sqlpp::parameters_of_t<X>::empty(), "");
|
||||||
|
|
||||||
// CTE reference is what is stored in from_t or join_t.
|
// CTE reference is what is stored in from_t or join_t.
|
||||||
// While it refers to a CTE, it cannot be used as a CTE or table, i.e. with(rx) or from(ra) would not compile.
|
// While it refers to a CTE, it cannot be used as a CTE or table, i.e. with(rx) or from(ra) would not compile.
|
||||||
static_assert(not sqlpp::is_cte<RX>::value, "");
|
static_assert(not sqlpp::is_cte<RX>::value, "");
|
||||||
static_assert(not sqlpp::is_table<RX>::value, "");
|
static_assert(not sqlpp::is_table<RX>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::provided_ctes_of_t<RX>, sqlpp::detail::type_vector<>>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::required_ctes_of_t<RX>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
static_assert(sqlpp::parameters_of_t<RX>::empty(), "");
|
||||||
|
|
||||||
// CTEs can be aliased (e.g. x AS a). This alias can be used as a table in FROM, but not as a CTE in WITH.
|
// CTEs can be aliased (e.g. x AS a). This alias can be used as a table in FROM, but not as a CTE in WITH.
|
||||||
static_assert(not sqlpp::is_cte<A>::value, "");
|
static_assert(not sqlpp::is_cte<A>::value, "");
|
||||||
static_assert(sqlpp::is_table<A>::value, "");
|
static_assert(sqlpp::is_table<A>::value, "");
|
||||||
static_assert(std::is_same<A, RA>::value, "");
|
static_assert(std::is_same<A, RA>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::provided_ctes_of_t<RA>, sqlpp::detail::type_vector<>>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::required_ctes_of_t<RA>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
static_assert(sqlpp::parameters_of_t<RA>::empty(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple CTE with parameter
|
// Simple CTE with parameter
|
||||||
@ -70,7 +77,6 @@ void test_cte()
|
|||||||
|
|
||||||
using X = decltype(x);
|
using X = decltype(x);
|
||||||
using RX = decltype(make_table_ref(x));
|
using RX = decltype(make_table_ref(x));
|
||||||
using A = decltype(a);
|
|
||||||
using RA = decltype(make_table_ref(a));
|
using RA = decltype(make_table_ref(a));
|
||||||
using P = decltype(p);
|
using P = decltype(p);
|
||||||
|
|
||||||
@ -82,16 +88,8 @@ void test_cte()
|
|||||||
static_assert(std::is_same<sqlpp::provided_ctes_of_t<X>, sqlpp::detail::type_vector<RX>>::value, "");
|
static_assert(std::is_same<sqlpp::provided_ctes_of_t<X>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
static_assert(std::is_same<sqlpp::parameters_of_t<X>, sqlpp::detail::type_vector<P>>::value, "");
|
static_assert(std::is_same<sqlpp::parameters_of_t<X>, sqlpp::detail::type_vector<P>>::value, "");
|
||||||
|
|
||||||
// CTE reference is what is stored in from_t or join_t.
|
// Neither CTE reference nor alias carry the parameter.
|
||||||
// While it refers to a CTE, it cannot be used as a CTE or table, i.e. with(rx) or from(rx) would not compile.
|
|
||||||
static_assert(not sqlpp::is_cte<RX>::value, "");
|
|
||||||
static_assert(not sqlpp::is_table<RX>::value, "");
|
|
||||||
static_assert(sqlpp::parameters_of_t<RX>::empty(), "");
|
static_assert(sqlpp::parameters_of_t<RX>::empty(), "");
|
||||||
|
|
||||||
// CTEs can be aliased (e.g. x AS a). This alias can be used as a table in FROM, but not as a CTE in WITH.
|
|
||||||
static_assert(not sqlpp::is_cte<A>::value, "");
|
|
||||||
static_assert(sqlpp::is_table<A>::value, "");
|
|
||||||
static_assert(std::is_same<A, RA>::value, "");
|
|
||||||
static_assert(sqlpp::parameters_of_t<RA>::empty(), "");
|
static_assert(sqlpp::parameters_of_t<RA>::empty(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,21 +98,91 @@ void test_cte()
|
|||||||
auto x =
|
auto x =
|
||||||
cte(sqlpp::alias::x)
|
cte(sqlpp::alias::x)
|
||||||
.as(select(foo.id).from(foo).unconditionally().union_all(select(bar.id).from(bar).unconditionally()));
|
.as(select(foo.id).from(foo).unconditionally().union_all(select(bar.id).from(bar).unconditionally()));
|
||||||
auto a = x.as(sqlpp::alias::a);
|
|
||||||
|
using X = decltype(x);
|
||||||
|
using RX = decltype(make_table_ref(x));
|
||||||
|
|
||||||
|
// CTE is used in WITH and in FROM
|
||||||
|
static_assert(sqlpp::is_cte<X>::value, "");
|
||||||
|
static_assert(not sqlpp::is_recursive_cte<X>::value, "");
|
||||||
|
static_assert(sqlpp::is_table<X>::value, "");
|
||||||
|
static_assert(sqlpp::required_ctes_of_t<X>::empty(), "");
|
||||||
|
static_assert(std::is_same<sqlpp::provided_ctes_of_t<X>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
static_assert(sqlpp::parameters_of_t<X>::empty(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursive union CTE: X AS SELECT ... UNION ALL SELECT ... FROM X ...
|
// Recursive union CTE: X AS SELECT ... UNION ALL SELECT ... FROM X ...
|
||||||
{
|
{
|
||||||
|
auto p = sqlpp::parameter(foo.id);
|
||||||
auto x_base = cte(sqlpp::alias::x).as(select(sqlpp::value(0).as(sqlpp::alias::a)));
|
auto x_base = cte(sqlpp::alias::x).as(select(sqlpp::value(0).as(sqlpp::alias::a)));
|
||||||
auto x = x_base.union_all(select((x_base.a + 1).as(sqlpp::alias::a)).from(x_base).where(x_base.a < 10));
|
auto x = x_base.union_all(select((x_base.a + 1).as(sqlpp::alias::a)).from(x_base).where(x_base.a < p));
|
||||||
auto y = x.as(sqlpp::alias::y);
|
|
||||||
|
using X = decltype(x);
|
||||||
|
using RX = decltype(make_table_ref(x));
|
||||||
|
using P = decltype(p);
|
||||||
|
|
||||||
|
// CTE is used in WITH and in FROM
|
||||||
|
static_assert(sqlpp::is_cte<X>::value, "");
|
||||||
|
static_assert(sqlpp::is_recursive_cte<X>::value, "");
|
||||||
|
static_assert(sqlpp::is_table<X>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::required_ctes_of_t<X>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::provided_ctes_of_t<X>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::parameters_of_t<X>, sqlpp::detail::type_vector<P>>::value, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// A CTE depending on another CTE
|
// A CTE depending on another CTE
|
||||||
{
|
{
|
||||||
auto x = cte(sqlpp::alias::x).as(select(foo.id).from(foo).unconditionally());
|
auto pb = sqlpp::parameter(foo.intN);
|
||||||
auto y = cte(sqlpp::alias::y).as(select(x.id, sqlpp::value(7).as(sqlpp::alias::a)).from(x).unconditionally());
|
auto p = sqlpp::parameter(foo.id);
|
||||||
auto z = y.as(sqlpp::alias::z);
|
auto b = cte(sqlpp::alias::b).as(select(foo.id).from(foo).where(foo.id != pb));
|
||||||
|
auto x = cte(sqlpp::alias::y).as(select(b.id, sqlpp::value(7).as(sqlpp::alias::a)).from(b).where(b.id > p));
|
||||||
|
auto a = x.as(sqlpp::alias::a);
|
||||||
|
|
||||||
|
using RB = decltype(make_table_ref(b));
|
||||||
|
using X = decltype(x);
|
||||||
|
using RX = decltype(make_table_ref(x));
|
||||||
|
using RA = decltype(make_table_ref(a));
|
||||||
|
using P = decltype(p);
|
||||||
|
|
||||||
|
// CTE is used in WITH and in FROM
|
||||||
|
static_assert(sqlpp::is_cte<X>::value, "");
|
||||||
|
static_assert(not sqlpp::is_recursive_cte<X>::value, "");
|
||||||
|
static_assert(sqlpp::is_table<X>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::required_ctes_of_t<X>, sqlpp::detail::type_vector<RB>>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::provided_ctes_of_t<X>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::parameters_of_t<X>, sqlpp::detail::type_vector<P>>::value, "");
|
||||||
|
|
||||||
|
// Neither CTE reference nor alias carry the dependency.
|
||||||
|
static_assert(std::is_same<sqlpp::required_ctes_of_t<RA>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::required_ctes_of_t<RX>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// A recursive CTE depending on another CTE
|
||||||
|
{
|
||||||
|
auto pb = sqlpp::parameter(foo.intN);
|
||||||
|
auto p = sqlpp::parameter(foo.id);
|
||||||
|
auto b = cte(sqlpp::alias::b).as(select(foo.id.as(sqlpp::alias::a)).from(foo).where(foo.id != pb));
|
||||||
|
auto x_base = cte(sqlpp::alias::x).as(select(b.a).from(b).unconditionally());
|
||||||
|
auto x = x_base.union_all(select((x_base.a + 1).as(sqlpp::alias::a)).from(x_base).where(x_base.a < p));
|
||||||
|
auto a = x.as(sqlpp::alias::a);
|
||||||
|
|
||||||
|
using RB = decltype(make_table_ref(b));
|
||||||
|
using X = decltype(x);
|
||||||
|
using RX = decltype(make_table_ref(x));
|
||||||
|
using RA = decltype(make_table_ref(a));
|
||||||
|
using P = decltype(p);
|
||||||
|
|
||||||
|
// CTE is used in WITH and in FROM
|
||||||
|
static_assert(sqlpp::is_cte<X>::value, "");
|
||||||
|
static_assert(sqlpp::is_recursive_cte<X>::value, "");
|
||||||
|
static_assert(sqlpp::is_table<X>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::required_ctes_of_t<X>, sqlpp::detail::type_vector<RB, RX>>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::provided_ctes_of_t<X>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::parameters_of_t<X>, sqlpp::detail::type_vector<P>>::value, "");
|
||||||
|
|
||||||
|
// Neither CTE reference nor alias carry the dependency.
|
||||||
|
static_assert(std::is_same<sqlpp::required_ctes_of_t<RA>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::required_ctes_of_t<RX>, sqlpp::detail::type_vector<RX>>::value, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user