14namespace arithmetic_checking {
18concept Arithmetic = std::is_arithmetic_v<std::remove_cvref_t<T>> &&
19 !std::same_as<std::remove_cvref_t<T>,
bool>;
51 "Arithmetic operations (+, -, *, /) can only be performed on numeric columns (int, long, "
52 "float, double, etc.). "
53 "String, boolean, and other non-numeric types cannot be used in arithmetic expressions.";
57template <SqlExpr Left, SqlExpr Right>
61 : left_(
std::move(left)), op_(
std::move(op)), right_(
std::move(right)) {}
63 std::string
to_sql()
const override {
64 return "(" + left_.to_sql() +
" " + op_ +
" " + right_.to_sql() +
")";
68 auto left_params = left_.bind_params();
69 auto right_params = right_.bind_params();
70 left_params.insert(left_params.end(), right_params.begin(), right_params.end());
75 std::string left_name;
76 std::string right_name;
79 if constexpr (std::is_base_of_v<ColumnExpression, Left>) {
80 left_name = left_.column_name();
85 if constexpr (std::is_base_of_v<ColumnExpression, Right>) {
86 right_name = right_.column_name();
91 return "(" + left_name +
"_" + op_ +
"_" + right_name +
")";
96 if constexpr (std::is_base_of_v<ColumnExpression, Left>) {
97 auto table = left_.table_name();
102 if constexpr (std::is_base_of_v<ColumnExpression, Right>) {
103 return right_.table_name();
128 auto left_expr =
to_expr(left);
129 auto right_expr =
to_expr(right);
131 std::move(right_expr));
137 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
144 "Arithmetic operations require numeric values. Cannot add non-numeric values to columns.");
146 auto left_expr =
to_expr(left);
147 auto value_expr =
val(std::forward<ValueT>(
value));
149 std::move(value_expr));
154 typename... Modifiers>
155 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
157 return right + std::forward<ValueT>(
value);
173 auto left_expr =
to_expr(left);
174 auto right_expr =
to_expr(right);
176 std::move(right_expr));
182 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
188 "Arithmetic operations require numeric values. Cannot subtract non-numeric values "
191 auto left_expr =
to_expr(left);
192 auto value_expr =
val(std::forward<ValueT>(
value));
194 std::move(value_expr));
199 typename... Modifiers>
200 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
206 "Arithmetic operations require numeric values.");
208 auto value_expr =
val(std::forward<ValueT>(
value));
209 auto right_expr =
to_expr(right);
211 std::move(right_expr));
227 auto left_expr =
to_expr(left);
228 auto right_expr =
to_expr(right);
230 std::move(right_expr));
236 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
242 "Arithmetic operations require numeric values. Cannot multiply columns by "
243 "non-numeric values.");
245 auto left_expr =
to_expr(left);
246 auto value_expr =
val(std::forward<ValueT>(
value));
248 std::move(value_expr));
253 typename... Modifiers>
254 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
256 return right * std::forward<ValueT>(
value);
272 auto left_expr =
to_expr(left);
273 auto right_expr =
to_expr(right);
275 std::move(right_expr));
281 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
288 "Arithmetic operations require numeric values. Cannot divide columns by non-numeric values.");
290 auto left_expr =
to_expr(left);
291 auto value_expr =
val(std::forward<ValueT>(
value));
293 std::move(value_expr));
298 typename... Modifiers>
299 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
305 "Arithmetic operations require numeric values.");
307 auto value_expr =
val(std::forward<ValueT>(
value));
308 auto right_expr =
to_expr(right);
310 std::move(right_expr));
317 typename... Modifiers>
324 auto right_expr =
to_expr(right);
326 std::move(right_expr));
338 auto left_expr =
to_expr(left);
344template <SqlExpr Left, SqlExpr Right,
typename ValueT>
345 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
348 "Arithmetic operations require numeric values.");
350 auto value_expr =
val(std::forward<ValueT>(
value));
352 std::move(value_expr));
356template <
typename ValueT, SqlExpr Left, SqlExpr Right>
357 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
359 return right_expr + std::forward<ValueT>(
value);
364 typename... Modifiers>
371 auto right_expr =
to_expr(right);
373 std::move(right_expr));
385 auto left_expr =
to_expr(left);
391template <SqlExpr Left, SqlExpr Right,
typename ValueT>
392 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
395 "Arithmetic operations require numeric values.");
397 auto value_expr =
val(std::forward<ValueT>(
value));
399 std::move(value_expr));
403template <
typename ValueT, SqlExpr Left, SqlExpr Right>
404 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
407 "Arithmetic operations require numeric values.");
409 auto value_expr =
val(std::forward<ValueT>(
value));
416 typename... Modifiers>
423 auto right_expr =
to_expr(right);
425 std::move(right_expr));
437 auto left_expr =
to_expr(left);
443template <SqlExpr Left, SqlExpr Right,
typename ValueT>
444 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
447 "Arithmetic operations require numeric values.");
449 auto value_expr =
val(std::forward<ValueT>(
value));
451 std::move(value_expr));
455template <
typename ValueT, SqlExpr Left, SqlExpr Right>
456 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
458 return right_expr * std::forward<ValueT>(
value);
463 typename... Modifiers>
470 auto right_expr =
to_expr(right);
472 std::move(right_expr));
484 auto left_expr =
to_expr(left);
490template <SqlExpr Left, SqlExpr Right,
typename ValueT>
491 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
494 "Arithmetic operations require numeric values.");
496 auto value_expr =
val(std::forward<ValueT>(
value));
498 std::move(value_expr));
502template <
typename ValueT, SqlExpr Left, SqlExpr Right>
503 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
506 "Arithmetic operations require numeric values.");
510 std::move(value_expr),
"/", std::move(right_expr));
519template <
typename TableT1,
fixed_string Name1,
typename T1,
typename... Modifiers1,
520 typename TableT2,
fixed_string Name2,
typename T2,
typename... Modifiers2>
535 std::move(right_expr));
539template <
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers,
typename ValueT>
540 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
547 "Arithmetic operations require numeric values. Cannot add non-numeric values to columns.");
550 auto value_expr =
query::val(std::forward<ValueT>(value));
552 std::move(value_expr));
556template <
typename ValueT,
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers>
557 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
559 return right + std::forward<ValueT>(value);
563template <
typename TableT1,
fixed_string Name1,
typename T1,
typename... Modifiers1,
564 typename TableT2,
fixed_string Name2,
typename T2,
typename... Modifiers2>
578 std::move(right_expr));
582template <
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers,
typename ValueT>
583 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
589 "Arithmetic operations require numeric values. Cannot subtract non-numeric values "
593 auto value_expr =
query::val(std::forward<ValueT>(value));
595 std::move(value_expr));
599template <
typename ValueT,
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers>
600 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
606 "Arithmetic operations require numeric values.");
608 auto value_expr =
query::val(std::forward<ValueT>(value));
611 std::move(value_expr),
"-", std::move(right_expr));
615template <
typename TableT1,
fixed_string Name1,
typename T1,
typename... Modifiers1,
616 typename TableT2,
fixed_string Name2,
typename T2,
typename... Modifiers2>
630 std::move(right_expr));
634template <
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers,
typename ValueT>
635 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
641 "Arithmetic operations require numeric values. Cannot multiply columns by "
642 "non-numeric values.");
645 auto value_expr =
query::val(std::forward<ValueT>(value));
647 std::move(value_expr));
651template <
typename ValueT,
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers>
652 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
654 return right * std::forward<ValueT>(value);
658template <
typename TableT1,
fixed_string Name1,
typename T1,
typename... Modifiers1,
659 typename TableT2,
fixed_string Name2,
typename T2,
typename... Modifiers2>
673 std::move(right_expr));
677template <
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers,
typename ValueT>
678 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
685 "Arithmetic operations require numeric values. Cannot divide columns by non-numeric values.");
688 auto value_expr =
query::val(std::forward<ValueT>(value));
690 std::move(value_expr));
694template <
typename ValueT,
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers>
695 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
701 "Arithmetic operations require numeric values.");
703 auto value_expr =
query::val(std::forward<ValueT>(value));
706 std::move(value_expr),
"/", std::move(right_expr));
713 typename... Modifiers>
722 left_expr,
"+", std::move(right_expr));
726template <
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers,
736 std::move(left_expr),
"+", right_expr);
740template <query::SqlExpr Left, query::SqlExpr Right,
typename ValueT>
741 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
744 "Arithmetic operations require numeric values.");
746 auto value_expr =
query::val(std::forward<ValueT>(value));
748 left_expr,
"+", std::move(value_expr));
752template <
typename ValueT, query::SqlExpr Left, query::SqlExpr Right>
753 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
755 return right_expr + std::forward<ValueT>(value);
760 typename... Modifiers>
769 left_expr,
"-", std::move(right_expr));
773template <
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers,
783 std::move(left_expr),
"-", right_expr);
787template <query::SqlExpr Left, query::SqlExpr Right,
typename ValueT>
788 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
791 "Arithmetic operations require numeric values.");
793 auto value_expr =
query::val(std::forward<ValueT>(value));
795 left_expr,
"-", std::move(value_expr));
799template <
typename ValueT, query::SqlExpr Left, query::SqlExpr Right>
800 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
803 "Arithmetic operations require numeric values.");
805 auto value_expr =
query::val(std::forward<ValueT>(value));
807 std::move(value_expr),
"-", right_expr);
812 typename... Modifiers>
821 left_expr,
"*", std::move(right_expr));
825template <
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers,
835 std::move(left_expr),
"*", right_expr);
839template <query::SqlExpr Left, query::SqlExpr Right,
typename ValueT>
840 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
843 "Arithmetic operations require numeric values.");
845 auto value_expr =
query::val(std::forward<ValueT>(value));
847 left_expr,
"*", std::move(value_expr));
851template <
typename ValueT, query::SqlExpr Left, query::SqlExpr Right>
852 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
854 return right_expr * std::forward<ValueT>(value);
859 typename... Modifiers>
868 left_expr,
"/", std::move(right_expr));
872template <
typename TableT,
fixed_string Name,
typename T,
typename... Modifiers,
882 std::move(left_expr),
"/", right_expr);
886template <query::SqlExpr Left, query::SqlExpr Right,
typename ValueT>
887 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
890 "Arithmetic operations require numeric values.");
892 auto value_expr =
query::val(std::forward<ValueT>(value));
894 left_expr,
"/", std::move(value_expr));
898template <
typename ValueT, query::SqlExpr Left, query::SqlExpr Right>
899 requires std::is_arithmetic_v<std::remove_cvref_t<ValueT>>
902 "Arithmetic operations require numeric values.");
904 auto value_expr =
query::val(std::forward<ValueT>(value));
906 std::move(value_expr),
"/", std::move(right_expr));
auto operator-(const schema::column< TableT1, Name1, T1, Modifiers1... > &left, const schema::column< TableT2, Name2, T2, Modifiers2... > &right)
Subtraction operator for columns.
auto operator/(const schema::column< TableT1, Name1, T1, Modifiers1... > &left, const schema::column< TableT2, Name2, T2, Modifiers2... > &right)
Division operator for columns.
auto operator+(const schema::column< TableT1, Name1, T1, Modifiers1... > &left, const schema::column< TableT2, Name2, T2, Modifiers2... > &right)
Addition operator for columns with type checking.
auto operator*(const schema::column< TableT1, Name1, T1, Modifiers1... > &left, const schema::column< TableT2, Name2, T2, Modifiers2... > &right)
Multiplication operator for columns.