Calculate the tables required by a sub-select

This commit is contained in:
rbock
2014-04-11 21:12:39 +02:00
parent 207310effe
commit cffc85879a
5 changed files with 36 additions and 13 deletions

View File

@@ -197,6 +197,23 @@ namespace sqlpp
template<typename... Sets>
using make_joined_set_t = typename make_joined_set<Sets...>::type;
template<typename Minuend, typename Subtrahend>
struct make_difference_set
{
static_assert(::sqlpp::vendor::wrong_t<Minuend, Subtrahend>::value, "invalid argument for difference set");
};
template<typename... Minuends, typename... Subtrahends>
struct make_difference_set<type_set<Minuends...>, type_set<Subtrahends...>>
{
template<typename E>
using is_subtrahend = is_element_of<E, type_set<Subtrahends...>>;
using type = typename make_type_set_if_not<is_subtrahend, Minuends...>::type;
};
template<typename Minuend, typename Subtrahend>
using make_difference_set_t = typename make_difference_set<Minuend, Subtrahend>::type;
}
}

View File

@@ -140,7 +140,18 @@ namespace sqlpp
using _parameter_tuple_t = std::tuple<Policies...>;
using _parameter_list_t = typename make_parameter_list_t<select_t>::type;
using _table_set = ::sqlpp::detail::type_set<>;
using _table_set = detail::make_difference_set_t<
typename _from_t::_table_set,
detail::make_joined_set_t<
typename _flag_list_t::_table_set,
typename _column_list_t::_table_set,
typename _where_t::_table_set,
typename _group_by_t::_table_set,
typename _having_t::_table_set,
typename _order_by_t::_table_set,
typename _limit_t::_table_set,
typename _offset_t::_table_set
>>;
template<typename Database>
using _result_row_t = typename _column_list_t::template _result_row_t<Database>;
@@ -210,18 +221,6 @@ namespace sqlpp
return _column_list_t::static_size() + get_dynamic_names().size();
}
/*
static_assert(column_list::_table_set::template is_subset_t<_from_t::_table_set>::value
static_assert(detail::is_subset_of<column_list::_table_set, _from_t::_table_set>::value
subset_of_t sollte ein eigenes template sein, das macht so etwas wie obiges sicher einfacher lesbar
also: use any and all instead of and_t and or_t
*/
//static_assert(is_where_t<Where>::value, "cannot select select without having a where condition, use .where(true) to remove all rows");
//static_assert(not vendor::is_noop<ColumnList>::value, "cannot run select without having selected anything");
//static_assert(is_from_t<From>::value, "cannot run select without a from()");
//static_assert(is_where_t<Where>::value, "cannot run select without having a where condition, use .where(true) to select all rows");
// FIXME: Check for missing aliases (if references are used)
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
template<typename A>
struct is_table_subset_of_from
{
@@ -244,6 +243,7 @@ namespace sqlpp
static_assert(is_table_subset_of_from<_limit_t>::value, "limit() expression requires additional tables in from()");
static_assert(is_table_subset_of_from<_offset_t>::value, "offset() expression requires additional tables in from()");
static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
return {db.select(*this), get_dynamic_names()};
}

View File

@@ -41,6 +41,7 @@ namespace sqlpp
{
using _is_select_flag = std::true_type;
};
using _table_set = detail::type_set<>;
};
static constexpr all_t all = {};
@@ -63,6 +64,7 @@ namespace sqlpp
{
using _is_select_flag = std::true_type;
};
using _table_set = detail::type_set<>;
};
static constexpr distinct_t distinct = {};
@@ -85,6 +87,7 @@ namespace sqlpp
{
using _is_select_flag = std::true_type;
};
using _table_set = detail::type_set<>;
};
static constexpr straight_join_t straight_join = {};

View File

@@ -216,6 +216,7 @@ namespace sqlpp
struct no_select_column_list_t
{
using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>;
template<typename Db>
using _result_row_t = ::sqlpp::result_row_t<Db>;
using _dynamic_names_t = typename dynamic_select_column_list<void>::_names_t;

View File

@@ -46,6 +46,7 @@ namespace sqlpp
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Flags...>;
using size = std::tuple_size<_parameter_tuple_t>;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Flags::_table_set...>::type;
static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list");
@@ -94,6 +95,7 @@ namespace sqlpp
struct no_select_flag_list_t
{
using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>;
template<typename Policies>
struct _methods_t