3#include "../schema/column.hpp"
22template <SqlExpr Left, SqlExpr Right>
26 : func_name_(
std::move(func_name)), unit_(
std::move(unit)), left_(
std::move(left)),
27 right_(
std::move(right)) {}
29 std::string
to_sql()
const override {
31 if (func_name_ ==
"DATE_DIFF") {
32 if (unit_ ==
"year") {
33 return "EXTRACT(YEAR FROM AGE(" + right_.to_sql() +
", " + left_.to_sql() +
"))";
34 }
else if (unit_ ==
"day") {
38 return "(" + right_.to_sql() +
"::date - " + left_.to_sql() +
"::date)";
39 }
else if (unit_ ==
"second") {
40 return "EXTRACT(EPOCH FROM (" + right_.to_sql() +
" - " + left_.to_sql() +
"))";
41 }
else if (unit_ ==
"month") {
42 return "EXTRACT(MONTH FROM AGE(" + right_.to_sql() +
", " + left_.to_sql() +
"))";
43 }
else if (unit_ ==
"hour") {
44 return "EXTRACT(EPOCH FROM (" + right_.to_sql() +
" - " + left_.to_sql() +
"))/3600";
45 }
else if (unit_ ==
"minute") {
46 return "EXTRACT(EPOCH FROM (" + right_.to_sql() +
" - " + left_.to_sql() +
"))/60";
50 return func_name_ +
"('" + unit_ +
"', " + left_.to_sql() +
", " + right_.to_sql() +
")";
54 auto left_params = left_.bind_params();
55 auto right_params = right_.bind_params();
56 left_params.insert(left_params.end(), right_params.begin(), right_params.end());
60 std::string
column_name()
const override {
return func_name_ +
"_" + unit_; }
63 if constexpr (std::is_base_of_v<ColumnExpression, Left>) {
64 auto table = left_.table_name();
69 if constexpr (std::is_base_of_v<ColumnExpression, Right>) {
70 return right_.table_name();
76 template <
typename LiteralT>
77 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
78 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
80 auto val_expr =
val(std::forward<LiteralT>(literal));
84 template <
typename LiteralT>
85 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
86 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
88 auto val_expr =
val(std::forward<LiteralT>(literal));
92 template <
typename LiteralT>
93 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
94 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
96 auto val_expr =
val(std::forward<LiteralT>(literal));
100 template <
typename LiteralT>
101 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
102 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
104 auto val_expr =
val(std::forward<LiteralT>(literal));
108 template <
typename LiteralT>
109 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
110 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
112 auto val_expr =
val(std::forward<LiteralT>(literal));
116 template <
typename LiteralT>
117 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
118 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
120 auto val_expr =
val(std::forward<LiteralT>(literal));
125 template <
typename NumericT>
126 requires std::is_arithmetic_v<std::remove_cvref_t<NumericT>>
128 auto val_expr =
val(std::forward<NumericT>(literal));
132 template <
typename NumericT>
133 requires std::is_arithmetic_v<std::remove_cvref_t<NumericT>>
135 auto val_expr =
val(std::forward<NumericT>(literal));
139 template <
typename NumericT>
140 requires std::is_arithmetic_v<std::remove_cvref_t<NumericT>>
142 auto val_expr =
val(std::forward<NumericT>(literal));
146 template <
typename NumericT>
147 requires std::is_arithmetic_v<std::remove_cvref_t<NumericT>>
149 auto val_expr =
val(std::forward<NumericT>(literal));
154 std::string func_name_;
161template <SqlExpr Expr>
165 : func_name_(
std::move(func_name)), unit_(
std::move(unit)), expr_(
std::move(expr)) {}
168 if (func_name_ ==
"EXTRACT") {
169 return "EXTRACT(" + unit_ +
" FROM " + expr_.to_sql() +
")";
171 if (func_name_ ==
"ABS") {
172 return "ABS(" + expr_.to_sql() +
")";
174 return func_name_ +
"('" + unit_ +
"', " + expr_.to_sql() +
")";
177 std::vector<std::string>
bind_params()
const override {
return expr_.bind_params(); }
179 std::string
column_name()
const override {
return func_name_ +
"_" + unit_; }
182 if constexpr (std::is_base_of_v<ColumnExpression, Expr>) {
183 return expr_.table_name();
189 template <
typename LiteralT>
190 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
191 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
193 auto val_expr =
val(std::forward<LiteralT>(literal));
197 template <
typename LiteralT>
198 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
199 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
201 auto val_expr =
val(std::forward<LiteralT>(literal));
205 template <
typename LiteralT>
206 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
207 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
209 auto val_expr =
val(std::forward<LiteralT>(literal));
213 template <
typename LiteralT>
214 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
215 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
217 auto val_expr =
val(std::forward<LiteralT>(literal));
221 template <
typename LiteralT>
222 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
223 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
225 auto val_expr =
val(std::forward<LiteralT>(literal));
229 template <
typename LiteralT>
230 requires std::is_arithmetic_v<std::remove_cvref_t<LiteralT>> ||
231 std::is_convertible_v<std::remove_cvref_t<LiteralT>, std::string>
233 auto val_expr =
val(std::forward<LiteralT>(literal));
238 template <
typename NumericT>
239 requires std::is_arithmetic_v<std::remove_cvref_t<NumericT>>
241 auto val_expr =
val(std::forward<NumericT>(literal));
245 template <
typename NumericT>
246 requires std::is_arithmetic_v<std::remove_cvref_t<NumericT>>
248 auto val_expr =
val(std::forward<NumericT>(literal));
252 template <
typename NumericT>
253 requires std::is_arithmetic_v<std::remove_cvref_t<NumericT>>
255 auto val_expr =
val(std::forward<NumericT>(literal));
259 template <
typename NumericT>
260 requires std::is_arithmetic_v<std::remove_cvref_t<NumericT>>
262 auto val_expr =
val(std::forward<NumericT>(literal));
267 std::string func_name_;
277 std::string
to_sql()
const override {
return "INTERVAL '" + interval_ +
"'"; }
279 std::vector<std::string>
bind_params()
const override {
return {}; }
286 std::string interval_;
290template <SqlExpr DateExpr, SqlExpr IntervalExpr>
294 : date_expr_(
std::move(date_expr)), op_(
std::move(op)),
295 interval_expr_(
std::move(interval_expr)) {}
298 return "(" + date_expr_.to_sql() +
" " + op_ +
" " + interval_expr_.
to_sql() +
")";
302 auto date_params = date_expr_.bind_params();
303 auto interval_params = interval_expr_.
bind_params();
304 date_params.insert(date_params.end(), interval_params.begin(), interval_params.end());
309 std::string date_name =
"expr";
310 if constexpr (std::is_base_of_v<ColumnExpression, DateExpr>) {
311 date_name = date_expr_.column_name();
313 return "(" + date_name +
"_" + op_ +
"_INTERVAL)";
317 if constexpr (std::is_base_of_v<ColumnExpression, DateExpr>) {
318 return date_expr_.table_name();
334 std::string
to_sql()
const override {
return func_name_; }
336 std::vector<std::string>
bind_params()
const override {
return {}; }
343 template <
typename T>
350 template <
typename T>
357 template <
typename T>
364 template <
typename T>
371 template <
typename T>
378 template <
typename T>
386 template <SqlExpr Expr>
391 template <SqlExpr Expr>
396 template <SqlExpr Expr>
401 template <SqlExpr Expr>
406 template <SqlExpr Expr>
411 template <SqlExpr Expr>
417 std::string func_name_;
427template <SqlExpr Expr1, SqlExpr Expr2>
428auto date_diff(std::string_view unit, Expr1 date1, Expr2 date2) {
434template <
typename T1,
typename T2>
435 requires date_checking::DateTimeColumn<T1> && date_checking::DateTimeColumn<T2>
436auto date_diff(std::string_view unit,
const T1& col1,
const T2& col2) {
441template <
typename T, SqlExpr Expr>
442 requires date_checking::DateTimeColumn<T>
448template <SqlExpr Expr,
typename T>
449 requires date_checking::DateTimeColumn<T>
459template <SqlExpr DateExpr>
462 std::move(interval_expr));
467 requires date_checking::DateTimeColumn<T>
477template <SqlExpr DateExpr>
480 std::move(interval_expr));
485 requires date_checking::DateTimeColumn<T>
496template <SqlExpr Expr>
497auto extract(std::string_view unit, Expr expr) {
503 requires date_checking::DateTimeColumn<T>
513template <SqlExpr Expr>
520 requires date_checking::DateTimeColumn<T>
528inline auto interval(std::string_view interval_str) {
563 requires date_checking::DateTimeColumn<T>
569template <SqlExpr Expr>
579 requires date_checking::DateTimeColumn<T>
585template <SqlExpr Expr>
595 requires date_checking::DateTimeColumn<T>
601template <SqlExpr Expr>
611 requires date_checking::DateTimeColumn<T>
617template <SqlExpr Expr>
627 requires date_checking::DateTimeColumn<T>
633template <SqlExpr Expr>
643 requires date_checking::DateTimeColumn<T>
649template <SqlExpr Expr>
659 requires date_checking::DateTimeColumn<T>
660auto year(
const T& date_column) {
661 return extract(
"year", date_column);
665template <SqlExpr Expr>
667 return extract(
"year", std::move(expr));
675 requires date_checking::DateTimeColumn<T>
677 return extract(
"month", date_column);
681template <SqlExpr Expr>
683 return extract(
"month", std::move(expr));
691 requires date_checking::DateTimeColumn<T>
692auto day(
const T& date_column) {
693 return extract(
"day", date_column);
697template <SqlExpr Expr>
699 return extract(
"day", std::move(expr));
707 requires date_checking::DateTimeColumn<T>
709 return extract(
"dow", date_column);
713template <SqlExpr Expr>
715 return extract(
"dow", std::move(expr));
723 requires date_checking::DateTimeColumn<T>
725 return extract(
"doy", date_column);
729template <SqlExpr Expr>
731 return extract(
"doy", std::move(expr));
739 requires date_checking::DateTimeColumn<T>
740auto hour(
const T& date_column) {
741 return extract(
"hour", date_column);
745template <SqlExpr Expr>
747 return extract(
"hour", std::move(expr));
755 requires date_checking::DateTimeColumn<T>
757 return extract(
"minute", date_column);
761template <SqlExpr Expr>
763 return extract(
"minute", std::move(expr));
771 requires date_checking::DateTimeColumn<T>
773 return extract(
"second", date_column);
777template <SqlExpr Expr>
779 return extract(
"second", std::move(expr));
786 requires date_checking::DateTimeColumn<T>
793template <SqlExpr DateExpr>
800 requires date_checking::DateTimeColumn<T>
807template <SqlExpr DateExpr>
813template <SqlExpr DateExpr, SqlExpr IntervalExpr1>
817 date_expr,
"+", interval_expr);
821template <SqlExpr DateExpr, SqlExpr IntervalExpr1>
825 date_expr,
"-", interval_expr);
832template <SqlExpr Expr>
840template <SqlExpr Expr1, SqlExpr Expr2>
848template <SqlExpr Expr1, SqlExpr Expr2>
Binary arithmetic expression.
Generic binary condition expression.
Binary date function expression (e.g., DATE_DIFF)
auto operator>=(LiteralT &&literal) const
std::string to_sql() const override
auto operator>(LiteralT &&literal) const
std::vector< std::string > bind_params() const override
BinaryDateFunctionExpr(std::string func_name, std::string unit, Left left, Right right)
auto operator==(LiteralT &&literal) const
auto operator*(NumericT &&literal) const
auto operator+(NumericT &&literal) const
auto operator<(LiteralT &&literal) const
auto operator<=(LiteralT &&literal) const
std::string table_name() const override
std::string column_name() const override
auto operator/(NumericT &&literal) const
auto operator!=(LiteralT &&literal) const
auto operator-(NumericT &&literal) const
Base class for column expressions.
Current date/time functions (no arguments)
auto operator!=(Expr expr) const
auto operator==(Expr expr) const
auto operator==(const T &column) const
std::string table_name() const override
auto operator>(const T &column) const
auto operator<(const T &column) const
auto operator<=(Expr expr) const
auto operator>(Expr expr) const
auto operator>=(const T &column) const
auto operator<(Expr expr) const
CurrentDateTimeExpr(std::string func_name)
auto operator!=(const T &column) const
std::string to_sql() const override
std::vector< std::string > bind_params() const override
auto operator<=(const T &column) const
auto operator>=(Expr expr) const
std::string column_name() const override
Date addition/subtraction expression.
std::string column_name() const override
std::string to_sql() const override
std::string table_name() const override
DateArithmeticExpr(DateExpr date_expr, std::string op, IntervalExpr interval_expr)
std::vector< std::string > bind_params() const override
Date interval expression for date arithmetic.
IntervalExpr(std::string interval)
std::string table_name() const override
std::string column_name() const override
std::vector< std::string > bind_params() const override
std::string to_sql() const override
Unary date function expression with unit (e.g., EXTRACT)
auto operator/(NumericT &&literal) const
auto operator==(LiteralT &&literal) const
auto operator>=(LiteralT &&literal) const
auto operator!=(LiteralT &&literal) const
UnaryDateFunctionExpr(std::string func_name, std::string unit, Expr expr)
auto operator*(NumericT &&literal) const
std::string column_name() const override
std::string to_sql() const override
auto operator<(LiteralT &&literal) const
std::string table_name() const override
auto operator>(LiteralT &&literal) const
auto operator<=(LiteralT &&literal) const
auto operator-(NumericT &&literal) const
std::vector< std::string > bind_params() const override
auto operator+(NumericT &&literal) const
Represents a column in a database table.
Check if type is a date/time type (unwrapping optional)
auto current_timestamp()
CURRENT_TIMESTAMP function - returns the current timestamp.
auto start_of_day(const T &date_column)
Get the start of the day for a date.
auto current_time()
CURRENT_TIME function - returns the current time.
auto second(const T &date_column)
Get the second from a timestamp.
auto age_in_years(const T &birth_date_column)
Calculate age in years between birth date and current date.
auto hour(const T &date_column)
Get the hour from a timestamp.
auto interval(std::string_view interval_str)
Create an interval expression.
auto start_of_month(const T &date_column)
Get the start of the month for a date.
auto start_of_year(const T &date_column)
Get the start of the year for a date.
auto year(const T &date_column)
Get the year from a date.
auto month(const T &date_column)
Get the month from a date.
auto day_of_year(const T &date_column)
Get the day of year from a date (1-366)
auto extract(std::string_view unit, Expr expr)
EXTRACT function - extracts a date part from a date.
auto day(const T &date_column)
Get the day from a date.
auto date_add(DateExpr date_expr, IntervalExpr interval_expr)
DATE_ADD function - adds an interval to a date.
auto operator-(const schema::column< TableT1, Name1, T1, Modifiers1... > &left, const schema::column< TableT2, Name2, T2, Modifiers2... > &right)
Subtraction operator for columns.
auto minute(const T &date_column)
Get the minute from a timestamp.
auto current_date()
CURRENT_DATE function - returns the current date.
auto to_expr(const C &col, std::string_view table_name="")
Helper to wrap a schema column in a SQL expression.
auto days_until(const T &date_column)
Calculate days until a date.
auto date_trunc(std::string_view unit, Expr expr)
DATE_TRUNC function - truncates a date to specified precision.
auto days_since(const T &date_column)
Calculate days since a date.
auto date_diff(std::string_view unit, Expr1 date1, Expr2 date2)
DATE_DIFF function - calculates difference between two dates.
auto abs(Expr expr)
ABS function for SQL expressions.
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 day_of_week(const T &date_column)
Get the day of week from a date (0=Sunday, 1=Monday, etc.)
auto val(const char *str)
Helper to create a value expression from a string literal.
auto now()
NOW function - alias for CURRENT_TIMESTAMP.
auto date_sub(DateExpr date_expr, IntervalExpr interval_expr)
DATE_SUB function - subtracts an interval from a date.