diff --git a/enginetest/queries/script_queries.go b/enginetest/queries/script_queries.go index e1391ce9b4..406c5c050e 100644 --- a/enginetest/queries/script_queries.go +++ b/enginetest/queries/script_queries.go @@ -120,6 +120,99 @@ type ScriptTestAssertion struct { // Unlike other engine tests, ScriptTests must be self-contained. No other tables are created outside the definition of // the tests. var ScriptTests = []ScriptTest{ + { + // https://github.com/dolthub/dolt/issues/9836 + Skip: true, + Name: "Ordering by pk does not change the order of results", + SetUpScript: []string{ + "CREATE TABLE test(pk VARCHAR(50) PRIMARY KEY)", + "INSERT INTO test VALUES (' 3 12 4'), ('3. 12 4'), ('3.2 12 4'), ('-3.1234'), ('-3.1a'), ('-5+8'), ('+3.1234')", + }, + Assertions: []ScriptTestAssertion{ + { + Query: "SELECT pk FROM test ORDER BY pk", + Expected: []sql.Row{{" 3 12 4"}, {"-3.1234"}, {"-3.1a"}, {"-5+8"}, {"+3.1234"}, {"3. 12 4"}, {"3.2 12 4"}}, + }, + }, + }, + { + // https://github.com/dolthub/dolt/issues/9812 + Name: "String-to-number comparison operators should behave consistently", + Assertions: []ScriptTestAssertion{ + { + Dialect: "mysql", + Query: "SELECT ('A') = (0)", + Expected: []sql.Row{{true}}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, + //ExpectedWarningMessageSubstring: "Truncated incorrect double value: A", + }, + { + Dialect: "mysql", + Query: "SELECT ('A') IN (0)", + Expected: []sql.Row{{true}}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, + //ExpectedWarningMessageSubstring: "Truncated incorrect double value: A", + }, + { + Dialect: "mysql", + Query: "SELECT ('A') != (0)", + Expected: []sql.Row{{false}}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, + //ExpectedWarningMessageSubstring: "Truncated incorrect double value: A", + }, + { + Dialect: "mysql", + Query: "SELECT ('A') <> (0)", + Expected: []sql.Row{{false}}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, + //ExpectedWarningMessageSubstring: "Truncated incorrect double value: A", + }, + { + Dialect: "mysql", + Query: "SELECT ('A') < (0)", + Expected: []sql.Row{{false}}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, + //ExpectedWarningMessageSubstring: "Truncated incorrect double value: A", + }, + { + Dialect: "mysql", + Query: "SELECT ('A') <= (0)", + Expected: []sql.Row{{true}}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, + //ExpectedWarningMessageSubstring: "Truncated incorrect double value: A", + }, + { + Dialect: "mysql", + Query: "SELECT ('A') > (0)", + Expected: []sql.Row{{false}}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, + //ExpectedWarningMessageSubstring: "Truncated incorrect double value: A", + }, + { + Dialect: "mysql", + Query: "SELECT ('A') >= (0)", + Expected: []sql.Row{{true}}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, + //ExpectedWarningMessageSubstring: "Truncated incorrect double value: A", + }, + { + Dialect: "mysql", + Query: "SELECT ('A') NOT IN (0)", + Expected: []sql.Row{{false}}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, + //ExpectedWarningMessageSubstring: "Truncated incorrect double value: A", + }, + }, + }, { // https://github.com/dolthub/dolt/issues/9794 Name: "UPDATE with TRIM function on TEXT column", @@ -11662,6 +11755,8 @@ select * from t1 except ( {"5.932887e7abc", float32(5.932887e+07)}, {"a1a1", float32(0)}, }, + //ExpectedWarningsCount: 12, + //ExpectedWarning: mysql.ERTruncatedWrongValue, }, { Dialect: "mysql", @@ -11686,6 +11781,8 @@ select * from t1 except ( {"5.932887e7abc", 5.932887e+07}, {"a1a1", 0.0}, }, + //ExpectedWarningsCount: 12, + //ExpectedWarning: mysql.ERTruncatedWrongValue, }, { Dialect: "mysql", @@ -11710,6 +11807,8 @@ select * from t1 except ( {"5.932887e7abc", 5}, {"a1a1", 0}, }, + //ExpectedWarningsCount: 12, + //ExpectedWarning: mysql.ERTruncatedWrongValue, }, { Dialect: "mysql", @@ -11734,6 +11833,8 @@ select * from t1 except ( {"5.932887e7abc", uint64(5)}, {"a1a1", uint64(0)}, }, + //ExpectedWarningsCount: 19, + //ExpectedWarning: mysql.ERTruncatedWrongValue, }, { Dialect: "mysql", @@ -11758,10 +11859,13 @@ select * from t1 except ( {"5.932887e7abc", "59328870.000"}, {"a1a1", "0.000"}, }, + //ExpectedWarningsCount: 13, + //ExpectedWarning: mysql.ERTruncatedWrongValue, }, { Query: "select * from test01 where pk in ('11')", Expected: []sql.Row{{"11"}}, + //ExpectedWarningsCount: 0, }, { // https://github.com/dolthub/dolt/issues/9739 @@ -11774,6 +11878,8 @@ select * from t1 except ( {"11d"}, {"11wha?"}, }, + //ExpectedWarningsCount: 12, + //ExpectedWarning: mysql.ERTruncatedWrongValue, }, { // https://github.com/dolthub/dolt/issues/9739 @@ -11785,6 +11891,8 @@ select * from t1 except ( {" 3. 12 4"}, {"3. 12 4"}, }, + //ExpectedWarningsCount: 12, + //ExpectedWarning: mysql.ERTruncatedWrongValue, }, { // https://github.com/dolthub/dolt/issues/9739 @@ -11798,6 +11906,8 @@ select * from t1 except ( {"+3.1234"}, {"3. 12 4"}, }, + //ExpectedWarningsCount: 20, + //ExpectedWarning: mysql.ERTruncatedWrongValue, }, { // https://github.com/dolthub/dolt/issues/9739 @@ -11805,6 +11915,8 @@ select * from t1 except ( Dialect: "mysql", Query: "select * from test02 where pk in ('11asdf')", Expected: []sql.Row{{"11"}}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, }, { // https://github.com/dolthub/dolt/issues/9739 @@ -11812,6 +11924,8 @@ select * from t1 except ( Dialect: "mysql", Query: "select * from test02 where pk='11.12asdf'", Expected: []sql.Row{}, + //ExpectedWarningsCount: 1, + //ExpectedWarning: mysql.ERTruncatedWrongValue, }, }, }, diff --git a/sql/expression/comparison.go b/sql/expression/comparison.go index 97e5f4ba6e..7ea42c475d 100644 --- a/sql/expression/comparison.go +++ b/sql/expression/comparison.go @@ -141,7 +141,7 @@ func (c *comparison) Compare(ctx *sql.Context, row sql.Row) (int, error) { return c.Left().Type().Compare(ctx, left, right) } - l, r, compareType, err := c.castLeftAndRight(ctx, left, right) + l, r, compareType, err := c.CastLeftAndRight(ctx, left, right) if err != nil { return 0, err } @@ -171,7 +171,7 @@ func (c *comparison) evalLeftAndRight(ctx *sql.Context, row sql.Row) (interface{ return left, right, nil } -func (c *comparison) castLeftAndRight(ctx *sql.Context, left, right interface{}) (interface{}, interface{}, sql.Type, error) { +func (c *comparison) CastLeftAndRight(ctx *sql.Context, left, right interface{}) (interface{}, interface{}, sql.Type, error) { leftType := c.Left().Type() rightType := c.Right().Type() @@ -452,7 +452,7 @@ func (e *NullSafeEquals) Compare(ctx *sql.Context, row sql.Row) (int, error) { } var compareType sql.Type - left, right, compareType, err = e.castLeftAndRight(ctx, left, right) + left, right, compareType, err = e.CastLeftAndRight(ctx, left, right) if err != nil { return 0, err } diff --git a/sql/expression/in.go b/sql/expression/in.go index fada137f48..622ee5779f 100644 --- a/sql/expression/in.go +++ b/sql/expression/in.go @@ -61,8 +61,7 @@ func NewInTuple(left sql.Expression, right sql.Expression) *InTuple { // Eval implements the Expression interface. func (in *InTuple) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { - typ := in.Left().Type().Promote() - leftElems := types.NumColumns(typ) + leftElems := types.NumColumns(in.Left().Type()) originalLeft, err := in.Left().Eval(ctx, row) if err != nil { return nil, err @@ -78,11 +77,6 @@ func (in *InTuple) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { // also if no match is found in the list and one of the expressions in the list is NULL. rightNull := false - left, _, err := typ.Convert(ctx, originalLeft) - if err != nil { - return nil, err - } - switch right := in.Right().(type) { case Tuple: for _, el := range right { @@ -102,31 +96,14 @@ func (in *InTuple) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { continue } - var cmp int - elType := el.Type() - if types.IsDecimal(elType) || types.IsFloat(elType) { - rtyp := el.Type().Promote() - left, err := types.ConvertOrTruncate(ctx, left, rtyp) - if err != nil { - return nil, err - } - right, err := types.ConvertOrTruncate(ctx, originalRight, rtyp) - if err != nil { - return nil, err - } - cmp, err = rtyp.Compare(ctx, left, right) - if err != nil { - return nil, err - } - } else { - right, err := types.ConvertOrTruncate(ctx, originalRight, typ) - if err != nil { - return nil, err - } - cmp, err = typ.Compare(ctx, left, right) - if err != nil { - return nil, err - } + comp := newComparison(NewLiteral(originalLeft, in.Left().Type()), NewLiteral(originalRight, el.Type())) + l, r, compareType, err := comp.CastLeftAndRight(ctx, originalLeft, originalRight) + if err != nil { + return nil, err + } + cmp, err := compareType.Compare(ctx, l, r) + if err != nil { + return nil, err } if cmp == 0 {