diff --git a/include/sqlpp11/core/clause/select_column_list.h b/include/sqlpp11/core/clause/select_column_list.h index 1bd61feb..32b8f5ec 100644 --- a/include/sqlpp11/core/clause/select_column_list.h +++ b/include/sqlpp11/core/clause/select_column_list.h @@ -215,6 +215,7 @@ namespace sqlpp } }; }; + template struct value_type_of> : public select_column_value_type_of { diff --git a/include/sqlpp11/core/detail/type_vector.h b/include/sqlpp11/core/detail/type_vector.h index ff7ae4eb..90bf40a0 100644 --- a/include/sqlpp11/core/detail/type_vector.h +++ b/include/sqlpp11/core/detail/type_vector.h @@ -27,6 +27,7 @@ */ #include +#include namespace sqlpp { @@ -35,6 +36,8 @@ namespace sqlpp template struct type_vector { + template + using contains = std::integral_constant::value...>::value>; }; template diff --git a/include/sqlpp11/core/function/lower.h b/include/sqlpp11/core/function/lower.h index 7adfbf72..58197b6d 100644 --- a/include/sqlpp11/core/function/lower.h +++ b/include/sqlpp11/core/function/lower.h @@ -51,6 +51,15 @@ namespace sqlpp Expr _expr; }; + template + struct value_type_of> : public value_type_of {}; + + template + struct nodes_of> + { + using type = detail::type_vector; + }; + template auto to_sql_string(Context& context, const lower_t& t) -> std::string { diff --git a/include/sqlpp11/core/function/upper.h b/include/sqlpp11/core/function/upper.h index 2818d899..4f640a11 100644 --- a/include/sqlpp11/core/function/upper.h +++ b/include/sqlpp11/core/function/upper.h @@ -51,6 +51,15 @@ namespace sqlpp Expr _expr; }; + template + struct value_type_of> : public value_type_of {}; + + template + struct nodes_of> + { + using type = detail::type_vector; + }; + template auto to_sql_string(Context& context, const upper_t& t) -> std::string { diff --git a/include/sqlpp11/core/type_traits/aggregates.h b/include/sqlpp11/core/type_traits/aggregates.h index c20c1007..218ce85a 100644 --- a/include/sqlpp11/core/type_traits/aggregates.h +++ b/include/sqlpp11/core/type_traits/aggregates.h @@ -44,20 +44,22 @@ namespace sqlpp { }; - // Finds group_by expressions. + // Finds group_by expression. // @GroupByExpressions: type_vector - template - struct contains_aggregate_expressions - : public std::integral_constant, GroupByExpressions>::value> + template + struct contains_aggregate_expression + : public std::integral_constant::value or + contains_aggregate_expression>::value> { }; - template - struct contains_aggregate_expressions, GroupByExpressions> + template + struct contains_aggregate_expression> : public std::integral_constant< bool, logic::any_t<(GroupByExpressions::template contains::value or - contains_aggregate_expressions::value)...>::value> + contains_aggregate_expression::value)...>::value> { }; diff --git a/tests/core/types/type_traits/aggregates.cpp b/tests/core/types/type_traits/aggregates.cpp index 66877d66..97ad0f28 100644 --- a/tests/core/types/type_traits/aggregates.cpp +++ b/tests/core/types/type_traits/aggregates.cpp @@ -26,37 +26,187 @@ #include "Sample.h" #include +SQLPP_ALIAS_PROVIDER(cheese); + void test_contains_aggregate_function() { - auto v_not_null = sqlpp::value(17); + auto v = sqlpp::value(17); + auto t = sqlpp::value(""); + auto col_int = test::TabFoo{}.id; + auto col_txt = test::TabFoo{}.textNnD; -#warning: Need to test contains_aggregate_function + // Values are aggregate neutral and therefore considered neither aggregate and non-aggregate context. + static_assert(not sqlpp::contains_aggregate_function::value, ""); + static_assert(not sqlpp::contains_aggregate_function::value, ""); + // Columns are non-aggregates. + static_assert(not sqlpp::contains_aggregate_function::value, ""); + static_assert(not sqlpp::contains_aggregate_function::value, ""); + + // Normal functions of values or non-aggregates do not contain aggregate functions. + static_assert(not sqlpp::contains_aggregate_function::value, ""); + static_assert(not sqlpp::contains_aggregate_function::value, ""); + + // Aggregate functions of non-aggregates and values contain aggregate functions. + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + + // Expressions of aggregate functions and non-aggregates contain aggregate functions. + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + + static_assert(sqlpp::contains_aggregate_function::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); + + // Clauses expose non-aggregates (probably irrelevant) + static_assert(not sqlpp::contains_aggregate_function v))>::value, ""); + static_assert(sqlpp::contains_aggregate_function::value, ""); } void test_contains_aggregate_expression() { auto v_not_null = sqlpp::value(17); -#warning: Need to test contains_aggregate_expression + auto v = sqlpp::value(17); + auto t = sqlpp::value(""); + auto col_int = test::TabFoo{}.id; + auto col_txt = test::TabFoo{}.textNnD; + + using known_aggregates = sqlpp::detail::type_vector; + using unknown = sqlpp::detail::type_vector<>; + + // ... + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + + // ... + static_assert(not sqlpp::contains_aggregate_expression::value, ""); + static_assert(not sqlpp::contains_aggregate_expression::value, ""); + +#warning: activate +#if 0 + // Columns are non-aggregates. + static_assert(not sqlpp::contains_aggregate_expression::value, ""); + static_assert(not sqlpp::contains_aggregate_expression::value, ""); + + // Normal expressions of values or non-aggregates do not contain aggregate functions. + static_assert(not sqlpp::contains_aggregate_expression::value, ""); + static_assert(not sqlpp::contains_aggregate_expression::value, ""); + + // Aggregate expressions of non-aggregates contain aggregate functions. + static_assert(not sqlpp::contains_aggregate_expressions::value, ""); + static_assert(not sqlpp::contains_aggregate_expressions::value, ""); + static_assert(not sqlpp::contains_aggregate_expressions::value, ""); + static_assert(not sqlpp::contains_aggregate_expressions::value, ""); + static_assert(not sqlpp::contains_aggregate_expressions::value, ""); + + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + + // Expressions of aggregate expressions and non-aggregates contain aggregate functions. + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + + static_assert(sqlpp::contains_aggregate_expression::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); + + // Clauses expose non-aggregates (probably irrelevant) + static_assert(not sqlpp::contains_aggregate_expression v))>::value, ""); + static_assert(sqlpp::contains_aggregate_expression::value, ""); +#endif } void test_contains_non_aggregate() { auto v = sqlpp::value(17); - auto col = test::TabFoo{}.id; + auto t = sqlpp::value(""); + auto col_int = test::TabFoo{}.id; + auto col_txt = test::TabFoo{}.textNnD; - static_assert(sqlpp::contains_non_aggregate::value, ""); - static_assert(sqlpp::contains_non_aggregate::value, ""); - static_assert(not sqlpp::contains_non_aggregate::value, ""); - static_assert(not sqlpp::contains_non_aggregate::value, ""); - static_assert(not sqlpp::contains_non_aggregate::value, ""); - static_assert(not sqlpp::contains_non_aggregate::value, ""); - static_assert(not sqlpp::contains_non_aggregate::value, ""); -#warning: lets test some functions, too -#warning: lets test some clauses, too + // Values are aggregate neutral and therefore considered neither aggregate and non-aggregate context. + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + // Columns are non-aggregates. + static_assert(sqlpp::contains_non_aggregate::value, ""); + static_assert(sqlpp::contains_non_aggregate::value, ""); + + // Functions can contain non-aggregates. + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(sqlpp::contains_non_aggregate::value, ""); + + // Aggregate functions of non-aggregates and values are aggregate functions. + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + + // Expressions of aggregate functions and non-aggregates contain non-aggregates. + static_assert(sqlpp::contains_non_aggregate::value, ""); + static_assert(sqlpp::contains_non_aggregate::value, ""); + static_assert(sqlpp::contains_non_aggregate::value, ""); + static_assert(sqlpp::contains_non_aggregate::value, ""); + static_assert(sqlpp::contains_non_aggregate::value, ""); + + static_assert(sqlpp::contains_non_aggregate::value, ""); + static_assert(sqlpp::contains_non_aggregate::value, ""); + + // Clauses expose non-aggregates (probably irrelevant) + static_assert(sqlpp::contains_non_aggregate v))>::value, ""); + static_assert(sqlpp::contains_non_aggregate::value, ""); } int main()