diff --git a/include/sqlgen/transpilation/make_field.hpp b/include/sqlgen/transpilation/make_field.hpp index 5ebeb93..c1bef43 100644 --- a/include/sqlgen/transpilation/make_field.hpp +++ b/include/sqlgen/transpilation/make_field.hpp @@ -19,6 +19,7 @@ #include "all_columns_exist.hpp" #include "dynamic_aggregation_t.hpp" #include "dynamic_operator_t.hpp" +#include "remove_as_t.hpp" #include "remove_nullable_t.hpp" #include "to_value.hpp" #include "underlying_t.hpp" @@ -108,8 +109,39 @@ struct MakeField> { remove_nullable_t>>, "Values inside the aggregation must be numerical."); + // Recursively checks if a type contains any aggregations. + template + struct HasAggregations; + + // Case: No operation. + template + requires(!MakeField>::is_operation) + struct HasAggregations { + static constexpr bool value = + MakeField>::is_aggregation; + }; + + // Case: Is operations: Check all operands. + template + requires(MakeField>::is_operation) + struct HasAggregations { + static constexpr bool value = HasAggregations< + typename MakeField>::Operands>::value; + }; + + // Case: Is a set of operands from an operation.. + template + struct HasAggregations> { + static constexpr bool value = + (false || ... || HasAggregations::value); + }; + + static_assert(!HasAggregations>::value, + "Nested aggregations are not allowed. Please restructure your " + "query to avoid nested aggregations."); + static constexpr bool is_aggregation = true; - static constexpr bool is_column = true; + static constexpr bool is_column = false; static constexpr bool is_operation = false; using Name = Nothing;