Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use value comparators for LEAST, GREATEST, BETWEEN #28

Merged
merged 1 commit into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 4 additions & 10 deletions internal/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
28 changes: 20 additions & 8 deletions internal/function_math.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
17 changes: 17 additions & 0 deletions query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3645,6 +3645,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",
Expand Down