0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 04:47:18 +08:00

Follow outer tables through the statement.

This is important to determine which result column of a select can be
NULL.
This commit is contained in:
rbock 2014-07-24 08:57:35 +02:00
parent d1e8a0153e
commit b73133d47a
9 changed files with 37 additions and 21 deletions

View File

@ -55,6 +55,7 @@ namespace sqlpp
{ {
using _parameters = std::tuple<>; using _parameters = std::tuple<>;
using _provided_tables = detail::type_set<>; using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _required_tables = detail::type_set<Table>; using _required_tables = detail::type_set<Table>;
using _extra_tables = detail::type_set<>; using _extra_tables = detail::type_set<>;
using _can_be_null = column_spec_can_be_null_t<ColumnSpec>; using _can_be_null = column_spec_can_be_null_t<ColumnSpec>;

View File

@ -56,6 +56,7 @@ namespace sqlpp
{ {
using _parameters = std::tuple<>; using _parameters = std::tuple<>;
using _required_tables = ::sqlpp::detail::type_set<>; using _required_tables = ::sqlpp::detail::type_set<>;
using _provided_outer_tables = ::sqlpp::detail::type_set<>;
using _provided_tables = ::sqlpp::detail::type_set<>; using _provided_tables = ::sqlpp::detail::type_set<>;
using _extra_tables = ::sqlpp::detail::type_set<Tables...>; using _extra_tables = ::sqlpp::detail::type_set<Tables...>;
using _can_be_null = std::false_type; using _can_be_null = std::false_type;

View File

@ -35,41 +35,29 @@ namespace sqlpp
{ {
struct inner_join_t struct inner_join_t
{ {
template<typename Db> template<typename Lhs, typename Rhs>
struct _is_supported using _provided_outer_tables = detail::make_joined_set<provided_outer_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
{
static constexpr bool value = Db::_supports_inner_join;
};
static constexpr const char* _name = " INNER "; static constexpr const char* _name = " INNER ";
}; };
struct outer_join_t struct outer_join_t
{ {
template<typename Db> template<typename Lhs, typename Rhs>
struct _is_supported using _provided_outer_tables = detail::make_joined_set<provided_tables_of<Lhs>, provided_tables_of<Rhs>>;
{
static constexpr bool value = Db::_supports_outer_join;
};
static constexpr const char* _name = " OUTER "; static constexpr const char* _name = " OUTER ";
}; };
struct left_outer_join_t struct left_outer_join_t
{ {
template<typename Db> template<typename Lhs, typename Rhs>
struct _is_supported using _provided_outer_tables = detail::make_joined_set<provided_outer_tables_of<Lhs>, provided_tables_of<Rhs>>;
{
static constexpr bool value = Db::_supports_left_outer_join;
};
static constexpr const char* _name = " LEFT OUTER "; static constexpr const char* _name = " LEFT OUTER ";
}; };
struct right_outer_join_t struct right_outer_join_t
{ {
template<typename Db> template<typename Lhs, typename Rhs>
struct _is_supported using _provided_outer_tables = detail::make_joined_set<provided_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
{
static constexpr bool value = Db::_supports_right_outer_join;
};
static constexpr const char* _name = " RIGHT OUTER "; static constexpr const char* _name = " RIGHT OUTER ";
}; };
@ -78,7 +66,16 @@ namespace sqlpp
struct join_t struct join_t
{ {
using _traits = make_traits<no_value_t, tag::table, tag::join>; using _traits = make_traits<no_value_t, tag::table, tag::join>;
using _recursive_traits = make_recursive_traits<Lhs, Rhs>; struct _recursive_traits
{
using _required_tables = detail::make_joined_set_t<required_tables_of<Lhs>, required_tables_of<Rhs>>;
using _provided_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_tables_of<Rhs>>;
using _provided_outer_tables = typename JoinType::template _provided_outer_tables<Lhs, Rhs>;
using _extra_tables = detail::make_joined_set_t<extra_tables_of<Lhs>, extra_tables_of<Rhs>>;
using _parameters = detail::make_parameter_tuple_t<parameters_of<Lhs>, parameters_of<Rhs>>;
using _can_be_null = std::false_type;
};
static_assert(is_table_t<Lhs>::value, "lhs argument for join() has to be a table or join"); static_assert(is_table_t<Lhs>::value, "lhs argument for join() has to be a table or join");
static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table"); static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table");

View File

@ -41,6 +41,7 @@ namespace sqlpp
{ {
using _parameters = std::tuple<parameter_t>; using _parameters = std::tuple<parameter_t>;
using _provided_tables = detail::type_set<>; using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _required_tables = detail::type_set<>; using _required_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>; using _extra_tables = detail::type_set<>;
using _can_be_null = std::true_type; using _can_be_null = std::true_type;

View File

@ -35,6 +35,7 @@ namespace sqlpp
template<typename NamedExpr> template<typename NamedExpr>
struct select_column_spec_t struct select_column_spec_t
{ {
#warning use Select here to determine if a column relates to a outer join table
using _name_t = typename NamedExpr::_name_t; using _name_t = typename NamedExpr::_name_t;
using _traits = make_traits<value_type_of<NamedExpr>, using _traits = make_traits<value_type_of<NamedExpr>,

View File

@ -63,6 +63,7 @@ namespace sqlpp
using _all_required_tables = detail::make_joined_set_t<required_tables_of<Policies>...>; using _all_required_tables = detail::make_joined_set_t<required_tables_of<Policies>...>;
using _all_provided_tables = detail::make_joined_set_t<provided_tables_of<Policies>...>; using _all_provided_tables = detail::make_joined_set_t<provided_tables_of<Policies>...>;
using _all_provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Policies>...>;
using _all_extra_tables = detail::make_joined_set_t<extra_tables_of<Policies>...>; using _all_extra_tables = detail::make_joined_set_t<extra_tables_of<Policies>...>;
using _known_tables = detail::make_joined_set_t<_all_provided_tables, _all_extra_tables>; using _known_tables = detail::make_joined_set_t<_all_provided_tables, _all_extra_tables>;
@ -108,6 +109,7 @@ namespace sqlpp
{ {
using _required_tables = statement_policies_t::_required_tables; using _required_tables = statement_policies_t::_required_tables;
using _provided_tables = detail::type_set<>; using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>; using _extra_tables = detail::type_set<>;
using _parameters = detail::make_parameter_tuple_t<parameters_of<Policies>...>; using _parameters = detail::make_parameter_tuple_t<parameters_of<Policies>...>;
using _can_be_null = detail::any_t<can_be_null_t<_value_type>::value>; using _can_be_null = detail::any_t<can_be_null_t<_value_type>::value>;
@ -128,6 +130,7 @@ namespace sqlpp
using _traits = make_traits<value_type_of<_policies_t>, ::sqlpp::tag::select, tag::expression_if<typename _policies_t::_is_expression>, tag::named_expression_if<typename _policies_t::_is_expression>>; using _traits = make_traits<value_type_of<_policies_t>, ::sqlpp::tag::select, tag::expression_if<typename _policies_t::_is_expression>, tag::named_expression_if<typename _policies_t::_is_expression>>;
using _recursive_traits = typename _policies_t::_recursive_traits; using _recursive_traits = typename _policies_t::_recursive_traits;
using _used_outer_tables = typename _policies_t::_all_provided_outer_tables;
using _result_type_provider = typename _policies_t::_result_type_provider; using _result_type_provider = typename _policies_t::_result_type_provider;

View File

@ -49,6 +49,7 @@ namespace sqlpp
using _parameters = std::tuple<>; using _parameters = std::tuple<>;
using _required_tables = detail::type_set<>; using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<Table>; using _provided_tables = detail::type_set<Table>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>; using _extra_tables = detail::type_set<>;
using _can_be_null = std::false_type; using _can_be_null = std::false_type;
}; };

View File

@ -46,6 +46,7 @@ namespace sqlpp
using _parameters = std::tuple<>; using _parameters = std::tuple<>;
using _required_tables = detail::type_set<>; using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<AliasProvider>; using _provided_tables = detail::type_set<AliasProvider>;
using _provided_outer_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>; using _extra_tables = detail::type_set<>;
using _can_be_null = std::false_type; using _can_be_null = std::false_type;
}; };

View File

@ -202,6 +202,12 @@ namespace sqlpp
using type = typename T::_recursive_traits::_provided_tables; using type = typename T::_recursive_traits::_provided_tables;
}; };
template<typename T>
struct provided_outer_table_of_impl
{
using type = typename T::_recursive_traits::_provided_outer_tables;
};
template<typename T> template<typename T>
struct extra_table_of_impl struct extra_table_of_impl
{ {
@ -238,6 +244,9 @@ namespace sqlpp
template<typename T> template<typename T>
using provided_tables_of = typename detail::provided_table_of_impl<T>::type; using provided_tables_of = typename detail::provided_table_of_impl<T>::type;
template<typename T>
using provided_outer_tables_of = typename detail::provided_outer_table_of_impl<T>::type;
template<typename T> template<typename T>
using extra_tables_of = typename detail::extra_table_of_impl<T>::type; using extra_tables_of = typename detail::extra_table_of_impl<T>::type;
@ -258,6 +267,7 @@ namespace sqlpp
{ {
using _required_tables = detail::make_joined_set_t<required_tables_of<Arguments>...>; using _required_tables = detail::make_joined_set_t<required_tables_of<Arguments>...>;
using _provided_tables = detail::make_joined_set_t<provided_tables_of<Arguments>...>; using _provided_tables = detail::make_joined_set_t<provided_tables_of<Arguments>...>;
using _provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Arguments>...>;
using _extra_tables = detail::make_joined_set_t<extra_tables_of<Arguments>...>; using _extra_tables = detail::make_joined_set_t<extra_tables_of<Arguments>...>;
using _parameters = detail::make_parameter_tuple_t<parameters_of<Arguments>...>; using _parameters = detail::make_parameter_tuple_t<parameters_of<Arguments>...>;
using _can_be_null = detail::any_t<can_be_null_t<Arguments>::value...>; using _can_be_null = detail::any_t<can_be_null_t<Arguments>::value...>;