From f5be4095ae68ad0c3962a33501693a70af75cc3d Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Sun, 22 May 2022 13:50:53 +0200 Subject: [PATCH] Allow parameter in having clause, see #443 Disallow mixing aggregate and non-aggregate columns in select, too. --- include/sqlpp11/data_types/blob/operand.h | 2 +- include/sqlpp11/data_types/boolean/operand.h | 2 +- .../sqlpp11/data_types/day_point/operand.h | 2 +- .../data_types/floating_point/operand.h | 2 +- include/sqlpp11/data_types/integral/operand.h | 2 +- include/sqlpp11/data_types/text/operand.h | 2 +- .../sqlpp11/data_types/time_of_day/operand.h | 2 +- .../sqlpp11/data_types/time_point/operand.h | 2 +- .../data_types/unsigned_integral/operand.h | 2 +- include/sqlpp11/having.h | 6 +-- include/sqlpp11/parameter.h | 1 + include/sqlpp11/select_column_list.h | 19 +++++-- include/sqlpp11/statement.h | 6 ++- include/sqlpp11/trim.h | 1 - include/sqlpp11/type_traits.h | 54 ++++++++++++++++++- tests/core/static_asserts/aggregates.cpp | 8 ++- tests/core/static_asserts/having.cpp | 11 ++-- tests/core/usage/Select.cpp | 4 +- tests/postgresql/usage/Exceptions.cpp | 2 - 19 files changed, 99 insertions(+), 31 deletions(-) diff --git a/include/sqlpp11/data_types/blob/operand.h b/include/sqlpp11/data_types/blob/operand.h index 67772fa2..5f95e001 100644 --- a/include/sqlpp11/data_types/blob/operand.h +++ b/include/sqlpp11/data_types/blob/operand.h @@ -39,7 +39,7 @@ namespace sqlpp { using _traits = make_traits; using _nodes = detail::type_vector<>; - using _is_aggregate_expression = std::true_type; + using _is_literal_expression = std::true_type; using _value_t = std::vector; diff --git a/include/sqlpp11/data_types/boolean/operand.h b/include/sqlpp11/data_types/boolean/operand.h index d82f5e8f..0aa852a9 100644 --- a/include/sqlpp11/data_types/boolean/operand.h +++ b/include/sqlpp11/data_types/boolean/operand.h @@ -40,7 +40,7 @@ namespace sqlpp { using _traits = make_traits; using _nodes = detail::type_vector<>; - using _is_aggregate_expression = std::true_type; + using _is_literal_expression = std::true_type; using _value_t = bool; diff --git a/include/sqlpp11/data_types/day_point/operand.h b/include/sqlpp11/data_types/day_point/operand.h index 66eedfe5..f47438fe 100644 --- a/include/sqlpp11/data_types/day_point/operand.h +++ b/include/sqlpp11/data_types/day_point/operand.h @@ -40,7 +40,7 @@ namespace sqlpp { using _traits = make_traits; using _nodes = detail::type_vector<>; - using _is_aggregate_expression = std::true_type; + using _is_literal_expression = std::true_type; using _value_t = ::sqlpp::chrono::day_point; diff --git a/include/sqlpp11/data_types/floating_point/operand.h b/include/sqlpp11/data_types/floating_point/operand.h index 8e754900..44ee44ba 100644 --- a/include/sqlpp11/data_types/floating_point/operand.h +++ b/include/sqlpp11/data_types/floating_point/operand.h @@ -36,7 +36,7 @@ namespace sqlpp { using _traits = make_traits; using _nodes = detail::type_vector<>; - using _is_aggregate_expression = std::true_type; + using _is_literal_expression = std::true_type; using _value_t = double; diff --git a/include/sqlpp11/data_types/integral/operand.h b/include/sqlpp11/data_types/integral/operand.h index 6338f2b7..997342a8 100644 --- a/include/sqlpp11/data_types/integral/operand.h +++ b/include/sqlpp11/data_types/integral/operand.h @@ -38,7 +38,7 @@ namespace sqlpp { using _traits = make_traits; using _nodes = detail::type_vector<>; - using _is_aggregate_expression = std::true_type; + using _is_literal_expression = std::true_type; using _value_t = int64_t; diff --git a/include/sqlpp11/data_types/text/operand.h b/include/sqlpp11/data_types/text/operand.h index 8a0b9ca2..5a2d02e7 100644 --- a/include/sqlpp11/data_types/text/operand.h +++ b/include/sqlpp11/data_types/text/operand.h @@ -43,7 +43,7 @@ namespace sqlpp { using _traits = make_traits; using _nodes = detail::type_vector<>; - using _is_aggregate_expression = std::true_type; + using _is_literal_expression = std::true_type; using _value_t = std::string; diff --git a/include/sqlpp11/data_types/time_of_day/operand.h b/include/sqlpp11/data_types/time_of_day/operand.h index a7b20064..9458aa66 100644 --- a/include/sqlpp11/data_types/time_of_day/operand.h +++ b/include/sqlpp11/data_types/time_of_day/operand.h @@ -40,7 +40,7 @@ namespace sqlpp { using _traits = make_traits; using _nodes = detail::type_vector<>; - using _is_aggregate_expression = std::true_type; + using _is_literal_expression = std::true_type; using _value_t = std::chrono::microseconds; diff --git a/include/sqlpp11/data_types/time_point/operand.h b/include/sqlpp11/data_types/time_point/operand.h index 7bd5893f..dff77368 100644 --- a/include/sqlpp11/data_types/time_point/operand.h +++ b/include/sqlpp11/data_types/time_point/operand.h @@ -40,7 +40,7 @@ namespace sqlpp { using _traits = make_traits; using _nodes = detail::type_vector<>; - using _is_aggregate_expression = std::true_type; + using _is_literal_expression = std::true_type; using _value_t = std::chrono::time_point; diff --git a/include/sqlpp11/data_types/unsigned_integral/operand.h b/include/sqlpp11/data_types/unsigned_integral/operand.h index 0e146b8e..e73bb7f4 100644 --- a/include/sqlpp11/data_types/unsigned_integral/operand.h +++ b/include/sqlpp11/data_types/unsigned_integral/operand.h @@ -38,7 +38,7 @@ namespace sqlpp { using _traits = make_traits; using _nodes = detail::type_vector<>; - using _is_aggregate_expression = std::true_type; + using _is_literal_expression = std::true_type; using _value_t = uint64_t; diff --git a/include/sqlpp11/having.h b/include/sqlpp11/having.h index 3f6dc8bf..c023b26c 100644 --- a/include/sqlpp11/having.h +++ b/include/sqlpp11/having.h @@ -59,7 +59,7 @@ namespace sqlpp assert_having_no_unknown_tables_t, "at least one having-expression requires a table which is otherwise not known in the statement"); - SQLPP_PORTABLE_STATIC_ASSERT(assert_having_no_non_aggregates_t, + SQLPP_PORTABLE_STATIC_ASSERT(assert_having_all_aggregates_t, "having expression not built out of aggregate expressions"); // HAVING @@ -142,9 +142,9 @@ namespace sqlpp consistent_t, assert_having_no_unknown_tables_t>::type; - using _aggregate_check = typename std::conditional::value, + using _aggregate_check = typename std::conditional::value, consistent_t, - assert_having_no_non_aggregates_t>::type; + assert_having_all_aggregates_t>::type; using _consistency_check = detail::get_first_if; }; diff --git a/include/sqlpp11/parameter.h b/include/sqlpp11/parameter.h index 8e4cee27..7b61d33b 100644 --- a/include/sqlpp11/parameter.h +++ b/include/sqlpp11/parameter.h @@ -44,6 +44,7 @@ namespace sqlpp using _nodes = detail::type_vector<>; using _parameters = detail::type_vector; using _can_be_null = std::true_type; + using _is_literal_expression = std::true_type; using _instance_t = member_t>; diff --git a/include/sqlpp11/select_column_list.h b/include/sqlpp11/select_column_list.h index e102058e..88d66b3d 100644 --- a/include/sqlpp11/select_column_list.h +++ b/include/sqlpp11/select_column_list.h @@ -92,6 +92,9 @@ namespace sqlpp SQLPP_PORTABLE_STATIC_ASSERT( assert_no_unknown_tables_in_selected_columns_t, "at least one selected column requires a table which is otherwise not known in the statement"); + SQLPP_PORTABLE_STATIC_ASSERT(assert_no_aggregate_mix_t, + "selected columns contain a mix of aggregates and non-aggregates"); + SQLPP_PORTABLE_STATIC_ASSERT(assert_no_unknown_aggregates_t, "not all selected columns are made of aggregates, despite group_by or similar"); @@ -196,11 +199,19 @@ namespace sqlpp consistent_t, assert_no_unknown_tables_in_selected_columns_t>::type; - using _aggregate_check = typename std::conditional::value, - consistent_t, - assert_no_unknown_aggregates_t>::type; + using _unknown_aggregate_check = + typename std::conditional::value, + consistent_t, + assert_no_unknown_aggregates_t>::type; - using _consistency_check = detail::get_first_if; + using _no_aggregate_mix_check = + typename std::conditional::value || + Policies::template _no_aggregates::value, + consistent_t, + assert_no_aggregate_mix_t>::type; + + using _consistency_check = detail:: + get_first_if; }; // Result methods diff --git a/include/sqlpp11/statement.h b/include/sqlpp11/statement.h index 3210111d..fe9f26be 100644 --- a/include/sqlpp11/statement.h +++ b/include/sqlpp11/statement.h @@ -99,9 +99,13 @@ namespace sqlpp Expressions>::type::value...>::value>; template - using _no_non_aggregates = logic::any_t::type::value...>::value>; + template + using _no_aggregates = logic::any_t::type::value...>::value>; + template