From e09c78dec3f8e500a8a307360421700612aedd21 Mon Sep 17 00:00:00 2001 From: go-jet Date: Mon, 30 Sep 2019 14:42:04 +0200 Subject: [PATCH] New MIN/MAX functions that accepts any expression type. --- internal/jet/func_expression.go | 10 ++++++++++ internal/jet/func_expression_test.go | 16 ++++++++++++++++ mysql/functions.go | 6 ++++++ postgres/functions.go | 6 ++++++ tests/mysql/select_test.go | 4 ++++ tests/postgres/select_test.go | 4 ++++ 6 files changed, 46 insertions(+) diff --git a/internal/jet/func_expression.go b/internal/jet/func_expression.go index 91f200a..3b334c6 100644 --- a/internal/jet/func_expression.go +++ b/internal/jet/func_expression.go @@ -115,6 +115,11 @@ func EVERY(boolExpression BoolExpression) boolWindowExpression { return newBoolWindowFunc("EVERY", boolExpression) } +// MAX is aggregate function. Returns minimum value of expression across all input values. +func MAX(expression Expression) Expression { + return newWindowFunc("MAX", expression) +} + // MAXf is aggregate function. Returns maximum value of float expression across all input values func MAXf(floatExpression FloatExpression) floatWindowExpression { return NewFloatWindowFunc("MAX", floatExpression) @@ -125,6 +130,11 @@ func MAXi(integerExpression IntegerExpression) integerWindowExpression { return newIntegerWindowFunc("MAX", integerExpression) } +// MIN is aggregate function. Returns minimum value of expression across all input values. +func MIN(expression Expression) Expression { + return newWindowFunc("MIN", expression) +} + // MINf is aggregate function. Returns minimum value of float expression across all input values func MINf(floatExpression FloatExpression) floatWindowExpression { return NewFloatWindowFunc("MIN", floatExpression) diff --git a/internal/jet/func_expression_test.go b/internal/jet/func_expression_test.go index fa4a0a5..c5a1e40 100644 --- a/internal/jet/func_expression_test.go +++ b/internal/jet/func_expression_test.go @@ -30,6 +30,14 @@ func TestFuncEVERY(t *testing.T) { } func TestFuncMIN(t *testing.T) { + t.Run("expression", func(t *testing.T) { + assertClauseSerialize(t, MIN(table1ColDate), "MIN(table1.col_date)") + assertClauseSerialize(t, MIN(Date(2001, 1, 1)), "MIN($1)", "2001-01-01") + assertClauseSerialize(t, MIN(Time(12, 10, 10)), "MIN($1)", "12:10:10") + assertClauseSerialize(t, MIN(Timestamp(2001, 1, 1, 12, 10, 10)), "MIN($1)", "2001-01-01 12:10:10") + assertClauseSerialize(t, MIN(Timestampz(2001, 1, 1, 12, 10, 10, 1, "UTC")), "MIN($1)", "2001-01-01 12:10:10.000000001 UTC") + }) + t.Run("float", func(t *testing.T) { assertClauseSerialize(t, MINf(table1ColFloat), "MIN(table1.col_float)") }) @@ -40,6 +48,14 @@ func TestFuncMIN(t *testing.T) { } func TestFuncMAX(t *testing.T) { + t.Run("expression", func(t *testing.T) { + assertClauseSerialize(t, MAX(table1ColDate), "MAX(table1.col_date)") + assertClauseSerialize(t, MAX(Date(2001, 1, 1)), "MAX($1)", "2001-01-01") + assertClauseSerialize(t, MAX(Time(12, 10, 10)), "MAX($1)", "12:10:10") + assertClauseSerialize(t, MAX(Timestamp(2001, 1, 1, 12, 10, 10)), "MAX($1)", "2001-01-01 12:10:10") + assertClauseSerialize(t, MAX(Timestampz(2001, 1, 1, 12, 10, 10, 1, "UTC")), "MAX($1)", "2001-01-01 12:10:10.000000001 UTC") + }) + t.Run("float", func(t *testing.T) { assertClauseSerialize(t, MAXf(table1ColFloat), "MAX(table1.col_float)") assertClauseSerialize(t, MAXf(Float(11.2222)), "MAX($1)", float64(11.2222)) diff --git a/mysql/functions.go b/mysql/functions.go index 0064d9d..17702b7 100644 --- a/mysql/functions.go +++ b/mysql/functions.go @@ -67,12 +67,18 @@ var BIT_OR = jet.BIT_OR // COUNT is aggregate function. Returns number of input rows for which the value of expression is not null. var COUNT = jet.COUNT +// MAX is aggregate function. Returns maximum value of expression across all input values +var MAX = jet.MAX + // MAXi is aggregate function. Returns maximum value of int expression across all input values var MAXi = jet.MAXi // MAXf is aggregate function. Returns maximum value of float expression across all input values var MAXf = jet.MAXf +// MIN is aggregate function. Returns minimum value of int expression across all input values +var MIN = jet.MIN + // MINi is aggregate function. Returns minimum value of int expression across all input values var MINi = jet.MINi diff --git a/postgres/functions.go b/postgres/functions.go index 4f657ca..6993de4 100644 --- a/postgres/functions.go +++ b/postgres/functions.go @@ -69,12 +69,18 @@ var COUNT = jet.COUNT // EVERY is aggregate function. Returns true if all input values are true, otherwise false var EVERY = jet.EVERY +// MAXf is aggregate function. Returns maximum value of expression across all input values +var MAX = jet.MAX + // MAXf is aggregate function. Returns maximum value of float expression across all input values var MAXf = jet.MAXf // MAXi is aggregate function. Returns maximum value of int expression across all input values var MAXi = jet.MAXi +// MIN is aggregate function. Returns minimum value of expression across all input values. +var MIN = jet.MIN + // MINf is aggregate function. Returns minimum value of float expression across all input values var MINf = jet.MINf diff --git a/tests/mysql/select_test.go b/tests/mysql/select_test.go index 0e20ae2..c34cfd6 100644 --- a/tests/mysql/select_test.go +++ b/tests/mysql/select_test.go @@ -87,7 +87,9 @@ SELECT customer.customer_id AS "customer.customer_id", customer.last_update AS "customer.last_update", SUM(payment.amount) AS "amount.sum", AVG(payment.amount) AS "amount.avg", + MAX(payment.payment_date) AS "amount.max_date", MAX(payment.amount) AS "amount.max", + MIN(payment.payment_date) AS "amount.min_date", MIN(payment.amount) AS "amount.min", COUNT(payment.amount) AS "amount.count" FROM dvds.payment @@ -103,7 +105,9 @@ ORDER BY payment.customer_id, SUM(payment.amount) ASC; SUMf(Payment.Amount).AS("amount.sum"), AVG(Payment.Amount).AS("amount.avg"), + MAX(Payment.PaymentDate).AS("amount.max_date"), MAXf(Payment.Amount).AS("amount.max"), + MIN(Payment.PaymentDate).AS("amount.min_date"), MINf(Payment.Amount).AS("amount.min"), COUNT(Payment.Amount).AS("amount.count"), ). diff --git a/tests/postgres/select_test.go b/tests/postgres/select_test.go index 15ec4fd..401854d 100644 --- a/tests/postgres/select_test.go +++ b/tests/postgres/select_test.go @@ -1009,7 +1009,9 @@ SELECT customer.customer_id AS "customer.customer_id", customer.active AS "customer.active", SUM(payment.amount) AS "amount.sum", AVG(payment.amount) AS "amount.avg", + MAX(payment.payment_date) AS "amount.max_date", MAX(payment.amount) AS "amount.max", + MIN(payment.payment_date) AS "amount.min_date", MIN(payment.amount) AS "amount.min", COUNT(payment.amount) AS "amount.count" FROM dvds.payment @@ -1025,7 +1027,9 @@ ORDER BY customer.customer_id, SUM(payment.amount) ASC; SUMf(Payment.Amount).AS("amount.sum"), AVG(Payment.Amount).AS("amount.avg"), + MAX(Payment.PaymentDate).AS("amount.max_date"), MAXf(Payment.Amount).AS("amount.max"), + MIN(Payment.PaymentDate).AS("amount.min_date"), MINf(Payment.Amount).AS("amount.min"), COUNT(Payment.Amount).AS("amount.count"), ).