From 1d9b417b232396cc44d4acb9717778639369501a Mon Sep 17 00:00:00 2001 From: Dan Hansen Date: Sat, 9 Mar 2024 02:23:50 -0800 Subject: [PATCH] Use value comparators for `LEAST`, `GREATEST`, `BETWEEN` (#182) --- internal/function.go | 14 ++++---------- internal/function_math.go | 28 ++++++++++++++++++++-------- query_test.go | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/internal/function.go b/internal/function.go index 067a81f..cd77da6 100644 --- a/internal/function.go +++ b/internal/function.go @@ -224,22 +224,16 @@ func LIKE(a, b Value) (Value, error) { } func BETWEEN(target, start, end Value) (Value, error) { - t, err := target.ToInt64() + greaterThanStart, err := target.GTE(start) if err != nil { return nil, err } - s, err := start.ToInt64() + lessThanEnd, err := target.LTE(end) if err != nil { return nil, err } - e, err := end.ToInt64() - if err != nil { - return nil, err - } - if s <= t && t <= e { - return BoolValue(true), nil - } - return BoolValue(false), nil + + return BoolValue(greaterThanStart && lessThanEnd), nil } func IN(a Value, values ...Value) (Value, error) { diff --git a/internal/function_math.go b/internal/function_math.go index c72a990..80b7059 100644 --- a/internal/function_math.go +++ b/internal/function_math.go @@ -144,33 +144,45 @@ func LOG10(x Value) (Value, error) { } func GREATEST(args ...Value) (Value, error) { - var max float64 = math.Inf(-1) + var max Value for _, arg := range args { if arg == nil { return nil, nil } - f, err := arg.ToFloat64() + if max == nil { + max = arg + continue + } + gt, err := arg.GT(max) if err != nil { return nil, err } - max = math.Max(max, f) + if gt { + max = arg + } } - return FloatValue(max), nil + return max, nil } func LEAST(args ...Value) (Value, error) { - var min float64 = math.Inf(1) + var min Value for _, arg := range args { if arg == nil { return nil, nil } - f, err := arg.ToFloat64() + if min == nil { + min = arg + continue + } + less, err := arg.LT(min) if err != nil { return nil, err } - min = math.Min(min, f) + if less { + min = arg + } } - return FloatValue(min), nil + return min, nil } func DIV(x, y Value) (Value, error) { diff --git a/query_test.go b/query_test.go index ada20e5..78db900 100644 --- a/query_test.go +++ b/query_test.go @@ -3657,6 +3657,23 @@ WITH example AS ( expectedRows: [][]interface{}{{"FOO", "BAR", "BAZ"}}, }, + // Regression tests for goccy/go-zetasqlite#177 + { + name: "least greatest between string", + query: `SELECT LEAST("a", "b"), GREATEST("a", "b"), "b" BETWEEN "a" AND "c";`, + expectedRows: [][]interface{}{{"a", "b", true}}, + }, + { + name: "least greatest between integer", + query: `SELECT LEAST(1, 2), GREATEST(1, 2), 2 BETWEEN 1 AND 3;`, + expectedRows: [][]interface{}{{int64(1), int64(2), true}}, + }, + { + name: "least greatest date", + query: `SELECT LEAST(DATE '2024-02-27', DATE '2024-02-28'), GREATEST(DATE '2024-02-27', DATE '2024-02-28');`, + expectedRows: [][]interface{}{{"2024-02-27", "2024-02-28"}}, + }, + // date functions { name: "current_date",