From 8488dae0a7d4340eeb6bd730305ff50f7dc0093f Mon Sep 17 00:00:00 2001 From: rbock Date: Sun, 11 Jan 2015 17:10:36 +0100 Subject: [PATCH] Added a few compile-time checks for unions --- include/sqlpp11/union.h | 54 ++++++++++++++++++++++++++++++++++------- tests/UnionTest.cpp | 8 +++--- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/include/sqlpp11/union.h b/include/sqlpp11/union.h index 4e65f95e..615321dc 100644 --- a/include/sqlpp11/union.h +++ b/include/sqlpp11/union.h @@ -37,6 +37,43 @@ namespace sqlpp { + template + struct has_result_row_impl + { + using type = std::false_type; + }; + + template + struct has_result_row_impl::template _result_row_t>::value, + void>::type> + { + using type = std::true_type; + }; + + template + using has_result_row_t = typename has_result_row_impl::type; + + template + struct get_result_row_impl + { + using type = void; + }; + + template + struct get_result_row_impl::template _result_row_t>::value, + void>::type> + { + using type = typename Statement::template _result_methods_t::template _result_row_t; + }; + + template + using get_result_row_t = typename get_result_row_impl::type; + + struct no_union_t; using blank_union_t = statement_t _new_statement_t<_check, union_t, Rhs>> { static_assert(is_statement_t::value, "argument of union call has to be a statement"); - // Being a select might be determined by the return type? - //FIXME static_assert(is_select this and Rhs, "at least one argument is not an expression in union_()"); - //FIXME static_assert(same return type, "at least one argument is not an expression in union_()"); - //FIXME static_assert(consistent/runnable this and Rhs, "at least one expression argument required in union_()"); - //FIXME static_assert(no order_y in this and Rhs, "at least one expression argument required in union_()"); + static_assert(has_result_row_t::value, "argument of a union has to be a (complete) select statement"); + static_assert(has_result_row_t>::value, "left hand side argument of a union has to be a (complete) select statement"); + static_assert(std::is_same>, get_result_row_t>::value, "both select statements in a union have to have the same result columns (type and name)"); return _union_impl(_check, Rhs>{}, rhs); } @@ -185,10 +220,11 @@ namespace sqlpp auto union_all(Rhs rhs) const -> _new_statement_t<_check, union_t, Rhs>> { - //FIXME static_assert(is_select this and Rhs, "at least one argument is not an expression in union_()"); - //FIXME static_assert(same return type, "at least one argument is not an expression in union_()"); - //FIXME static_assert(consistent/runnable this and Rhs, "at least one expression argument required in union_()"); - //FIXME static_assert(no order_y in this and Rhs, "at least one expression argument required in union_()"); + static_assert(is_statement_t::value, "argument of union call has to be a statement"); + static_assert(has_result_row_t::value, "argument of a union has to be a (complete) select statement"); + static_assert(has_result_row_t>::value, "left hand side argument of a union has to be a (complete) select statement"); + static_assert(std::is_same>, get_result_row_t>::value, "both select statements in a union have to have the same result columns (type and name)"); + return _union_impl(_check, Rhs>{}, rhs); } diff --git a/tests/UnionTest.cpp b/tests/UnionTest.cpp index 61436b7d..b4462ded 100644 --- a/tests/UnionTest.cpp +++ b/tests/UnionTest.cpp @@ -37,12 +37,12 @@ int main() test::TabBar t; test::TabFoo f; - db(select(t.alpha).from(t).union_distinct(select(f.epsilon).from(f))); - db(select(t.alpha).from(t).union_all(select(f.epsilon).from(f))); + db(select(t.alpha).from(t).union_distinct(select(f.epsilon.as(t.alpha)).from(f))); + db(select(t.alpha).from(t).union_all(select(f.epsilon.as(t.alpha)).from(f))); - auto u = select(t.alpha).from(t).union_all(select(f.epsilon).from(f)).as(sqlpp::alias::u); + auto u = select(t.alpha).from(t).union_all(select(f.epsilon.as(t.alpha)).from(f)).as(sqlpp::alias::u); - db(select(all_of(u)).from(u).union_all(select(t.delta).from(t))); + db(select(all_of(u)).from(u).union_all(select(t.delta.as(t.alpha)).from(t))); return 0; }