diff --git a/enginetest/queries/function_queries.go b/enginetest/queries/function_queries.go index 954a3c3b3b..1d1fddbf02 100644 --- a/enginetest/queries/function_queries.go +++ b/enginetest/queries/function_queries.go @@ -1603,12 +1603,63 @@ var FunctionQueryTests = []QueryTest{ }, // https://github.com/dolthub/dolt/issues/9735 { - Query: "select log('10asdf', '100f')", - Expected: []sql.Row{{float64(2)}}, + Query: "select log('10asdf', '100f')", + Expected: []sql.Row{{float64(2)}}, + ExpectedWarningsCount: 2, }, { - Query: "select log('a10asdf', 'b100f')", - Expected: []sql.Row{{nil}}, + Query: "select log('a10asdf', 'b100f')", + Expected: []sql.Row{{nil}}, + ExpectedWarningsCount: 2, + }, + // https://github.com/dolthub/dolt/issues/10171 + { + Query: "select abs('hi')", + Expected: []sql.Row{{float64(0)}}, + ExpectedWarningsCount: 1, + }, + { + Query: "select abs('12.3hi')", + Expected: []sql.Row{{12.3}}, + ExpectedWarningsCount: 1, + }, + { + Query: "select abs('-342.12hi')", + Expected: []sql.Row{{342.12}}, + ExpectedWarningsCount: 1, + }, + // https://github.com/dolthub/dolt/issues/10270 + { + Query: "select abs(1 and true)", + Expected: []sql.Row{{1}}, + }, + { + Query: "select abs(true)", + Expected: []sql.Row{{1}}, + }, + { + Query: "select abs(2 and true)", + Expected: []sql.Row{{1}}, + }, + { + Query: "select abs(false)", + Expected: []sql.Row{{0}}, + }, + { + Query: "select abs(false or 2)", + Expected: []sql.Row{{1}}, + }, + { + Query: "select abs(date('2020-12-15'))", + Expected: []sql.Row{{float64(20201215)}}, + // https://github.com/dolthub/dolt/issues/10278 + Skip: true, + }, + { + Query: "select abs(time('12:23:43'))", + Expected: []sql.Row{{float64(122343)}}, + // https://github.com/dolthub/dolt/issues/10278 + Skip: true, }, // Date Manipulation Function Tests { diff --git a/sql/expression/function/absval.go b/sql/expression/function/absval.go index 2da07f306b..3414c6882a 100644 --- a/sql/expression/function/absval.go +++ b/sql/expression/function/absval.go @@ -16,11 +16,14 @@ package function import ( "fmt" + "math" + "github.com/dolthub/vitess/go/mysql" "github.com/shopspring/decimal" "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/expression" + "github.com/dolthub/go-mysql-server/sql/types" ) // AbsVal is a function that takes the absolute value of a number @@ -93,11 +96,7 @@ func (t *AbsVal) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { return x, nil } case float64: - if x < 0 { - return -x, nil - } else { - return x, nil - } + return math.Abs(x), nil case float32: if x < 0 { return -x, nil @@ -106,13 +105,21 @@ func (t *AbsVal) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { } case decimal.Decimal: return x.Abs(), nil + case bool: + if x { + return 1, nil + } + return 0, nil + default: + v, _, err := types.Float64.Convert(ctx, val) + if err != nil { + if !sql.ErrTruncatedIncorrect.Is(err) { + return nil, err + } + ctx.Warn(mysql.ERTruncatedWrongValue, "%s", err.Error()) + } + return math.Abs(v.(float64)), nil } - - // TODO: Strings should truncate to float prefix. We should also check what other types return. But abs should not - // return null for non-null values - // https://github.com/dolthub/dolt/issues/10171 - // https://dev.mysql.com/doc/refman/8.4/en/mathematical-functions.html#function_abs - return nil, nil } // String implements the fmt.Stringer interface. @@ -139,7 +146,11 @@ func (t *AbsVal) WithChildren(children ...sql.Expression) (sql.Expression, error // Type implements the Expression interface. func (t *AbsVal) Type() sql.Type { - return t.Child.Type() + typ := t.Child.Type() + if types.IsNumber(typ) { + return typ + } + return types.Float64 } // CollationCoercibility implements the interface sql.CollationCoercible.