mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Fixed outer-tables for joins, added tests
This commit is contained in:
parent
0a325e4471
commit
aceede57eb
@ -65,6 +65,7 @@ target_compile_features(sqlpp11 INTERFACE
|
||||
endif ()
|
||||
|
||||
add_subdirectory(tests)
|
||||
add_subdirectory(test_types)
|
||||
add_subdirectory(test_serializer)
|
||||
add_subdirectory(test_static_asserts)
|
||||
add_subdirectory(test_constraints)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* Copyright (c) 2013-2016, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -111,7 +111,7 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
|
||||
"avg() cannot be used on an aggregate function");
|
||||
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "avg() requires a value expression as argument");
|
||||
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "avg() requires a numeric value expression as argument");
|
||||
return {t};
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
|
||||
"avg() cannot be used on an aggregate function");
|
||||
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "avg() requires a value expression as argument");
|
||||
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "avg() requires a numeric value expression as argument");
|
||||
return {t};
|
||||
}
|
||||
}
|
||||
|
@ -49,14 +49,14 @@ namespace sqlpp
|
||||
struct left_outer_join_t
|
||||
{
|
||||
template <typename Lhs, typename Rhs>
|
||||
using _provided_outer_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
|
||||
using _provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Lhs>, provided_tables_of<Rhs>>;
|
||||
|
||||
static constexpr const char* _name = " LEFT OUTER";
|
||||
};
|
||||
struct right_outer_join_t
|
||||
{
|
||||
template <typename Lhs, typename Rhs>
|
||||
using _provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Lhs>, provided_tables_of<Rhs>>;
|
||||
using _provided_outer_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
|
||||
|
||||
static constexpr const char* _name = " RIGHT OUTER";
|
||||
};
|
||||
|
@ -91,6 +91,7 @@ namespace sqlpp
|
||||
using _traits = make_traits<no_value_t, tag::is_pre_join>;
|
||||
using _nodes = detail::type_vector<Lhs, Rhs>;
|
||||
using _can_be_null = std::false_type;
|
||||
using _provided_outer_tables = typename JoinType::template _provided_outer_tables<Lhs, Rhs>;
|
||||
|
||||
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");
|
||||
@ -185,7 +186,7 @@ namespace sqlpp
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
auto outer_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
|
||||
pre_join_t<right_outer_join_t, Lhs, Rhs>,
|
||||
pre_join_t<outer_join_t, Lhs, Rhs>,
|
||||
bad_statement>::type
|
||||
{
|
||||
check_pre_join_t<Lhs, Rhs>::_();
|
||||
|
@ -48,6 +48,14 @@ int From(int, char* [])
|
||||
compare(__LINE__, from(foo.cross_join(bar)), " FROM tab_foo CROSS JOIN tab_bar");
|
||||
compare(__LINE__, from(foo.join(bar).on(foo.omega > bar.alpha)),
|
||||
" FROM tab_foo INNER JOIN tab_bar ON (tab_foo.omega>tab_bar.alpha)");
|
||||
compare(__LINE__, from(foo.inner_join(bar).on(foo.omega > bar.alpha)),
|
||||
" FROM tab_foo INNER JOIN tab_bar ON (tab_foo.omega>tab_bar.alpha)");
|
||||
compare(__LINE__, from(foo.outer_join(bar).on(foo.omega > bar.alpha)),
|
||||
" FROM tab_foo OUTER JOIN tab_bar ON (tab_foo.omega>tab_bar.alpha)");
|
||||
compare(__LINE__, from(foo.left_outer_join(bar).on(foo.omega > bar.alpha)),
|
||||
" FROM tab_foo LEFT OUTER JOIN tab_bar ON (tab_foo.omega>tab_bar.alpha)");
|
||||
compare(__LINE__, from(foo.right_outer_join(bar).on(foo.omega > bar.alpha)),
|
||||
" FROM tab_foo RIGHT OUTER JOIN tab_bar ON (tab_foo.omega>tab_bar.alpha)");
|
||||
compare(__LINE__, from(aFoo.join(bFoo).on(aFoo.omega > bFoo.omega)),
|
||||
" FROM tab_foo AS a INNER JOIN tab_foo AS b ON (a.omega>b.omega)");
|
||||
compare(
|
||||
@ -62,11 +70,31 @@ int From(int, char* [])
|
||||
dfa.from.add(dynamic_cross_join(bar));
|
||||
compare(__LINE__, dfa, " FROM tab_foo CROSS JOIN tab_bar");
|
||||
}
|
||||
{
|
||||
auto dfa = df;
|
||||
dfa.from.add(dynamic_join(bar).on(bar.alpha > foo.omega));
|
||||
compare(__LINE__, dfa, " FROM tab_foo INNER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega)");
|
||||
}
|
||||
{
|
||||
auto dfa = df;
|
||||
dfa.from.add(dynamic_inner_join(bar).on(bar.alpha > foo.omega));
|
||||
compare(__LINE__, dfa, " FROM tab_foo INNER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega)");
|
||||
}
|
||||
{
|
||||
auto dfa = df;
|
||||
dfa.from.add(dynamic_outer_join(bar).on(bar.alpha > foo.omega));
|
||||
compare(__LINE__, dfa, " FROM tab_foo OUTER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega)");
|
||||
}
|
||||
{
|
||||
auto dfa = df;
|
||||
dfa.from.add(dynamic_left_outer_join(bar).on(bar.alpha > foo.omega));
|
||||
compare(__LINE__, dfa, " FROM tab_foo LEFT OUTER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega)");
|
||||
}
|
||||
{
|
||||
auto dfa = df;
|
||||
dfa.from.add(dynamic_right_outer_join(bar).on(bar.alpha > foo.omega));
|
||||
compare(__LINE__, dfa, " FROM tab_foo RIGHT OUTER JOIN tab_bar ON (tab_bar.alpha>tab_foo.omega)");
|
||||
}
|
||||
{
|
||||
auto dfa = df;
|
||||
dfa.from.add(dynamic_inner_join(bar).on(bar.alpha > foo.omega));
|
||||
|
32
test_types/CMakeLists.txt
Normal file
32
test_types/CMakeLists.txt
Normal file
@ -0,0 +1,32 @@
|
||||
# Copyright (c) 2016-2016, Roland Bock
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above copyright notice, this
|
||||
# list of conditions and the following disclaimer in the documentation and/or
|
||||
# other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
function(test_compile name)
|
||||
set(target sqlpp11_${name})
|
||||
add_executable(${target} ${name}.cpp)
|
||||
target_link_libraries(${target} PRIVATE sqlpp11 sqlpp11_testing)
|
||||
endfunction()
|
||||
|
||||
test_compile(result_row)
|
||||
|
50
test_types/compare.h
Normal file
50
test_types/compare.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_TEST_SERIALIZER_H
|
||||
#define SQLPP_TEST_SERIALIZER_H
|
||||
|
||||
#include "MockDb.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename Expression>
|
||||
void compare(int lineNo, const Expression& expr, const std::string& expected)
|
||||
{
|
||||
MockDb::_serializer_context_t printer = {};
|
||||
|
||||
const auto result = serialize(expr, printer).str();
|
||||
|
||||
if (result != expected)
|
||||
{
|
||||
std::cerr << __FILE__ << " " << lineNo << '\n' << "Expected: -->|" << expected << "|<--\n"
|
||||
<< "Received: -->|" << result << "|<--\n";
|
||||
throw std::runtime_error("unexpected serialization result");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
212
test_types/result_row.cpp
Normal file
212
test_types/result_row.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "MockDb.h"
|
||||
#include "Sample.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr auto bar = test::TabBar{};
|
||||
constexpr auto foo = test::TabFoo{};
|
||||
|
||||
static_assert(sqlpp::can_be_null_t<decltype(bar.alpha)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(foo.omega)>::value, "");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(foo.delta)>::value, "");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(bar.gamma)>::value, "");
|
||||
const auto seven = sqlpp::value(7).as(sqlpp::alias::s);
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(seven)>::value, "");
|
||||
|
||||
auto db = MockDb{};
|
||||
|
||||
void single_table()
|
||||
{
|
||||
{
|
||||
// result fields are as nullable as the expressions they represent
|
||||
const auto& x = db(select(bar.alpha, bar.gamma, seven).from(bar).unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.gamma)>::value, "");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "");
|
||||
}
|
||||
}
|
||||
|
||||
void join()
|
||||
{
|
||||
// Join
|
||||
{
|
||||
const auto& x = db(select(bar.alpha, foo.delta, bar.gamma, seven)
|
||||
.from(foo.join(bar).on(foo.omega > bar.alpha))
|
||||
.unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.delta)>::value, "left side of (inner) join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.gamma)>::value, "right side of (inner) join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
{
|
||||
const auto& x = db(select(bar.alpha, foo.delta, bar.gamma, seven)
|
||||
.from(bar.join(foo).on(foo.omega > bar.alpha))
|
||||
.unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.gamma)>::value, "left side of (inner) join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.delta)>::value, "right side of (inner) join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
|
||||
// Inner join
|
||||
{
|
||||
const auto& x = db(select(bar.alpha, foo.delta, bar.gamma, seven)
|
||||
.from(foo.inner_join(bar).on(foo.omega > bar.alpha))
|
||||
.unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.delta)>::value, "left side of inner join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.gamma)>::value, "right side of inner join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
{
|
||||
const auto& x = db(select(bar.alpha, foo.delta, bar.gamma, seven)
|
||||
.from(bar.inner_join(foo).on(foo.omega > bar.alpha))
|
||||
.unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.gamma)>::value, "left side of inner join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.delta)>::value, "right side of inner join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
|
||||
// Left outer join
|
||||
{
|
||||
const auto& x = db(select(bar.alpha, foo.delta, bar.gamma, seven)
|
||||
.from(foo.left_outer_join(bar).on(foo.omega > bar.alpha))
|
||||
.unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.delta)>::value, "left side of left outer join cannot be null");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.gamma)>::value, "right side of left outer join can be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
{
|
||||
const auto& x = db(select(bar.alpha, foo.delta, bar.gamma, seven)
|
||||
.from(bar.left_outer_join(foo).on(foo.omega > bar.alpha))
|
||||
.unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.gamma)>::value, "left side of left outer join cannot be null");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.delta)>::value, "right side of left outer join can be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
|
||||
// Right outer join
|
||||
{
|
||||
const auto& x = db(select(bar.alpha, foo.delta, bar.gamma, seven)
|
||||
.from(foo.right_outer_join(bar).on(foo.omega > bar.alpha))
|
||||
.unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.delta)>::value, "left side of right outer join can be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.gamma)>::value,
|
||||
"right side of right outer join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
{
|
||||
const auto& x = db(select(bar.alpha, foo.delta, bar.gamma, seven)
|
||||
.from(bar.right_outer_join(foo).on(foo.omega > bar.alpha))
|
||||
.unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.gamma)>::value, "left side of right outer join can be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.delta)>::value,
|
||||
"right side of right outer join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
|
||||
// Outer join
|
||||
{
|
||||
const auto& x = db(select(bar.alpha, foo.delta, bar.gamma, seven)
|
||||
.from(foo.outer_join(bar).on(foo.omega > bar.alpha))
|
||||
.unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.delta)>::value, "left side of outer join can be null");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.gamma)>::value, "right side of outer join can be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
{
|
||||
const auto& x = db(select(bar.alpha, foo.delta, bar.gamma, seven)
|
||||
.from(bar.outer_join(foo).on(foo.omega > bar.alpha))
|
||||
.unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.gamma)>::value, "left side of outer join can be null");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.delta)>::value, "right side of outer join can be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
|
||||
// Cross join
|
||||
{
|
||||
const auto& x =
|
||||
db(select(bar.alpha, foo.delta, bar.gamma, seven).from(foo.cross_join(bar)).unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.delta)>::value, "left side of cross join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.gamma)>::value, "right side of cross join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
{
|
||||
const auto& x =
|
||||
db(select(bar.alpha, foo.delta, bar.gamma, seven).from(bar.cross_join(foo)).unconditionally()).front();
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.alpha)>::value, "nullable value can always be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.gamma)>::value, "left side of cross join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.delta)>::value, "right side of cross join cannot be null");
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.s)>::value, "constant non-null value can not be null");
|
||||
}
|
||||
}
|
||||
|
||||
void aggregates()
|
||||
{
|
||||
{
|
||||
// aggregates of nullable values
|
||||
const auto a = bar.alpha;
|
||||
static_assert(sqlpp::can_be_null_t<decltype(bar.alpha)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(a)>::value, "");
|
||||
const auto& x = db(select(count(a), avg(a), max(a), min(a), sum(a)).from(bar).unconditionally()).front();
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.count)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.avg)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.sum)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.max)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.min)>::value, "");
|
||||
}
|
||||
{
|
||||
// aggregates of nullable values
|
||||
const auto o = foo.omega;
|
||||
static_assert(sqlpp::can_be_null_t<decltype(foo.omega)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(o)>::value, "");
|
||||
const auto& x = db(select(count(o), avg(o), max(o), min(o), sum(o)).from(foo).unconditionally()).front();
|
||||
static_assert(not sqlpp::can_be_null_t<decltype(x.count)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.avg)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.sum)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.max)>::value, "");
|
||||
static_assert(sqlpp::can_be_null_t<decltype(x.min)>::value, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, char* [])
|
||||
{
|
||||
single_table();
|
||||
join();
|
||||
aggregates();
|
||||
}
|
@ -29,7 +29,7 @@ namespace test
|
||||
}
|
||||
};
|
||||
};
|
||||
using _traits = sqlpp::make_traits<sqlpp::varchar, sqlpp::tag::can_be_null>;
|
||||
using _traits = sqlpp::make_traits<sqlpp::varchar>;
|
||||
};
|
||||
struct Epsilon
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user