Skip to content

Commit fa0fe88

Browse files
committed
Slightly better comparison of row types for unions.
Needs some work for non-static versions
1 parent b0aa23e commit fa0fe88

File tree

3 files changed

+53
-6
lines changed

3 files changed

+53
-6
lines changed

include/sqlpp11/field_spec.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,39 @@ namespace sqlpp
4141
using _nodes = detail::type_vector<>;
4242

4343
using _alias_t = NameType;
44+
45+
template <typename N, typename V, bool C, bool T>
46+
static constexpr auto is_compatible(field_spec_t<N, V, C, T>) -> bool
47+
{
48+
using rhs = field_spec_t<N, V, C, T>;
49+
return std::is_same<_traits, typename rhs::_traits>::value and
50+
std::is_same<typename _alias_t::_name_t, typename rhs::_alias_t::_name_t>::value;
51+
}
4452
};
4553

4654
template <typename AliasProvider, typename FieldSpecTuple>
4755
struct multi_field_spec_t
4856
{
57+
static_assert(wrong_t<AliasProvider, FieldSpecTuple>::value,
58+
"multi_field_spec_t needs to be specialized with a tuple");
59+
};
60+
61+
template <typename AliasProvider, typename... FieldSpecs>
62+
struct multi_field_spec_t<AliasProvider, std::tuple<FieldSpecs...>>
63+
{
64+
template <typename A, typename... Fs>
65+
static constexpr auto is_compatible(multi_field_spec_t<A, Fs...>) ->
66+
typename std::enable_if<sizeof...(Fs) == sizeof...(FieldSpecs), bool>::type
67+
{
68+
return logic::all_t<FieldSpecs::is_compatible(Fs{})...>::value;
69+
}
70+
71+
template <typename A, typename... Fs>
72+
static constexpr auto is_compatible(multi_field_spec_t<A, Fs...>) ->
73+
typename std::enable_if<sizeof...(Fs) != sizeof...(FieldSpecs), bool>::type
74+
{
75+
return false;
76+
}
4977
};
5078

5179
namespace detail

include/sqlpp11/result_row.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,19 @@ namespace sqlpp
186186
using _impl = detail::result_row_impl<Db, _field_index_sequence, FieldSpecs...>;
187187
bool _is_valid;
188188

189+
template <typename D, typename... Fs>
190+
static constexpr auto is_compatible(detail::type_vector<result_row_t<D, Fs...>>) ->
191+
typename std::enable_if<sizeof...(Fs) == sizeof...(FieldSpecs), bool>::type
192+
{
193+
return logic::all_t<FieldSpecs::is_compatible(Fs{})...>::value;
194+
}
195+
196+
template <typename D, typename... Fs>
197+
static constexpr auto is_compatible(detail::type_vector<result_row_t<D, Fs...>>) ->
198+
typename std::enable_if<sizeof...(Fs) != sizeof...(FieldSpecs), bool>::type
199+
{
200+
return false;
201+
}
189202
result_row_t() : _impl(), _is_valid(false)
190203
{
191204
}

include/sqlpp11/union.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,13 @@ namespace sqlpp
213213
static_assert(has_result_row_t<derived_statement_t<Policies>>::value,
214214
"left hand side argument of a union has to be a complete select statement or union");
215215

216-
using _result_row_t = get_result_row_t<Rhs>;
217-
static_assert(std::is_same<get_result_row_t<derived_statement_t<Policies>>, _result_row_t>::value,
216+
using lhs_result_row_t = get_result_row_t<derived_statement_t<Policies>>;
217+
using rhs_result_row_t = get_result_row_t<Rhs>;
218+
static_assert(lhs_result_row_t::is_compatible(detail::type_vector<rhs_result_row_t>{}),
218219
"both arguments in a union have to have the same result columns (type and name)");
219-
static_assert(is_static_result_row_t<_result_row_t>::value, "unions must not have dynamically added columns");
220+
static_assert(
221+
is_static_result_row_t<lhs_result_row_t>::value && is_static_result_row_t<rhs_result_row_t>::value,
222+
"unions must not have dynamically added columns");
220223

221224
return _union_impl<void, union_distinct_t>(check_union_t<derived_statement_t<Policies>, Rhs>{}, rhs);
222225
}
@@ -231,10 +234,13 @@ namespace sqlpp
231234
static_assert(has_result_row_t<derived_statement_t<Policies>>::value,
232235
"left hand side argument of a union has to be a (complete) select statement");
233236

234-
using _result_row_t = get_result_row_t<Rhs>;
235-
static_assert(std::is_same<get_result_row_t<derived_statement_t<Policies>>, _result_row_t>::value,
237+
using lhs_result_row_t = get_result_row_t<derived_statement_t<Policies>>;
238+
using rhs_result_row_t = get_result_row_t<Rhs>;
239+
static_assert(lhs_result_row_t::is_compatible(detail::type_vector<rhs_result_row_t>{}),
236240
"both arguments in a union have to have the same result columns (type and name)");
237-
static_assert(is_static_result_row_t<_result_row_t>::value, "unions must not have dynamically added columns");
241+
static_assert(
242+
is_static_result_row_t<lhs_result_row_t>::value && is_static_result_row_t<rhs_result_row_t>::value,
243+
"unions must not have dynamically added columns");
238244

239245
return _union_impl<void, union_all_t>(check_union_t<derived_statement_t<Policies>, Rhs>{}, rhs);
240246
}

0 commit comments

Comments
 (0)