Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
0d4c134
move around some tests
Sep 18, 2025
7ad4127
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Sep 18, 2025
cd84b29
char refactor
Sep 19, 2025
3e324e5
hex comparisons
Sep 19, 2025
5d69037
simplify in comparison
Sep 19, 2025
35da24b
todos
Sep 19, 2025
71bf218
truncate in Convert function
Sep 22, 2025
e82860b
address insert tests
Sep 22, 2025
cf538c1
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Sep 22, 2025
c355799
fix sql tests
Sep 22, 2025
7034314
convert to bool rounds
Sep 22, 2025
76b48cb
clean up
Sep 22, 2025
34252ae
fix uint64 conversion
Sep 22, 2025
9ea9e08
implement rounding behavior
Sep 23, 2025
50a6dce
fix some functions
Sep 23, 2025
476dd0e
fix tests
Sep 23, 2025
12e35d3
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Sep 23, 2025
d1a95f7
add decimal truncation
Sep 23, 2025
65edac9
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Sep 23, 2025
0515642
fix tests and cleanup
Sep 23, 2025
73ed063
fix uint64
Sep 23, 2025
e9c4242
fix test
Sep 23, 2025
9c126dc
skip warning tests on server engine
Sep 23, 2025
1b47bfb
fix error message
Sep 24, 2025
220e05a
add unit tests for ConvertRound
Sep 24, 2025
094d898
alter table fix
Sep 24, 2025
85e54fc
fix error for in
Sep 24, 2025
dfaf6c0
fixing up and todo
Sep 24, 2025
892124e
fix round and add test
Sep 24, 2025
74a74ed
fix various math functions
Sep 24, 2025
7744df5
include other warnings
Sep 24, 2025
673a418
fixing tests
Sep 24, 2025
593b5fa
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Sep 24, 2025
8d66cba
add more tests and don't drop error for functions
Sep 25, 2025
26f9764
move code to types package
Sep 25, 2025
2594b2e
add unit tests for truncate functions
Sep 25, 2025
eed303d
migrate functions
Sep 26, 2025
0b3c16b
number tests
Sep 26, 2025
f3bcdf0
fix ceil and floor typing
Sep 26, 2025
fb06f2d
fix queries
Sep 26, 2025
035f4c1
fix more queries
Sep 26, 2025
498a67b
more tests
Sep 26, 2025
c4ffba6
move function and add method doc
Sep 29, 2025
938c654
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Sep 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion enginetest/enginetests.go
Original file line number Diff line number Diff line change
Expand Up @@ -3961,9 +3961,9 @@ func TestWindowRangeFrames(t *testing.T, harness Harness) {
TestQueryWithContext(t, ctx, e, harness, `SELECT sum(y) over (partition by z order by date range between unbounded preceding and interval '1' DAY following) FROM c order by x`, []sql.Row{{float64(1)}, {float64(1)}, {float64(1)}, {float64(1)}, {float64(5)}, {float64(5)}, {float64(10)}, {float64(10)}, {float64(10)}, {float64(10)}}, nil, nil, nil)
TestQueryWithContext(t, ctx, e, harness, `SELECT count(y) over (partition by z order by date range between interval '1' DAY following and interval '2' DAY following) FROM c order by x`, []sql.Row{{1}, {1}, {1}, {1}, {1}, {0}, {2}, {2}, {0}, {0}}, nil, nil, nil)
TestQueryWithContext(t, ctx, e, harness, `SELECT count(y) over (partition by z order by date range between interval '1' DAY preceding and interval '2' DAY following) FROM c order by x`, []sql.Row{{4}, {4}, {4}, {5}, {2}, {2}, {4}, {4}, {4}, {4}}, nil, nil, nil)
TestQueryWithContext(t, ctx, e, harness, "SELECT sum(y) over (partition by z order by date range interval 'e' DAY preceding) FROM c order by x", []sql.Row{{float64(0)}, {float64(0)}, {float64(0)}, {float64(1)}, {float64(1)}, {float64(3)}, {float64(1)}, {float64(1)}, {float64(4)}, {float64(4)}}, nil, nil, nil)

AssertErr(t, e, harness, "SELECT sum(y) over (partition by z range between unbounded preceding and interval '1' DAY following) FROM c order by x", nil, aggregation.ErrRangeInvalidOrderBy)
AssertErr(t, e, harness, "SELECT sum(y) over (partition by z order by date range interval 'e' DAY preceding) FROM c order by x", nil, sql.ErrInvalidValue)
}

func TestNamedWindows(t *testing.T, harness Harness) {
Expand Down
15 changes: 12 additions & 3 deletions enginetest/evaluation.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,18 @@ func TestScriptWithEngine(t *testing.T, e QueryEngine, harness Harness, script q
} else if assertion.ExpectedErrStr != "" {
AssertErrWithCtx(t, e, harness, ctx, assertion.Query, assertion.Bindings, nil, assertion.ExpectedErrStr)
} else if assertion.ExpectedWarning != 0 {
AssertWarningAndTestQuery(t, e, nil, harness, assertion.Query,
assertion.Expected, nil, assertion.ExpectedWarning, assertion.ExpectedWarningsCount,
assertion.ExpectedWarningMessageSubstring, assertion.SkipResultsCheck)
if IsServerEngine(e) && assertion.SkipResultCheckOnServerEngine {
t.Skip()
}
AssertWarningAndTestQuery(t, e, nil, harness,
assertion.Query,
assertion.Expected,
nil,
assertion.ExpectedWarning,
assertion.ExpectedWarningsCount,
assertion.ExpectedWarningMessageSubstring,
assertion.SkipResultsCheck,
)
} else if assertion.SkipResultsCheck {
RunQueryWithContext(t, e, harness, nil, assertion.Query)
} else if assertion.CheckIndexedAccess {
Expand Down
2 changes: 1 addition & 1 deletion enginetest/queries/function_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ var FunctionQueryTests = []QueryTest{
{
Query: `SELECT FLOOR(15728640/1024/1030)`,
Expected: []sql.Row{
{"14"},
{14},
},
},
{
Expand Down
4 changes: 2 additions & 2 deletions enginetest/queries/json_table_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ var JSONTableScriptTests = []ScriptTest{
},
{
Query: "SELECT * FROM JSON_TABLE('{\"c1\":\"abc\"}', '$' COLUMNS(c1 INT PATH '$.c1' DEFAULT 'def' ON ERROR)) as jt;",
ExpectedErrStr: "error: 'def' is not a valid value for 'int'",
ExpectedErrStr: "Invalid JSON text in argument 1 to function JSON_TABLE: \"Invalid value.\"",
},
},
},
Expand Down Expand Up @@ -612,7 +612,7 @@ var JSONTableScriptTests = []ScriptTest{
},
{
Query: "SELECT * FROM JSON_TABLE('{\"c1\":\"abc\"}', '$' COLUMNS(c1 INT PATH '$.c1' ERROR ON ERROR)) as jt;",
ExpectedErrStr: "error: 'abc' is not a valid value for 'int'",
ExpectedErrStr: "Invalid JSON text in argument 1 to function JSON_TABLE: \"Invalid value.\"",
},
},
},
Expand Down
4 changes: 2 additions & 2 deletions enginetest/queries/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -5509,11 +5509,11 @@ SELECT * FROM cte WHERE d = 2;`,
},
{
Query: "select ceil(i + 0.5) from mytable order by 1",
Expected: []sql.Row{{"2"}, {"3"}, {"4"}},
Expected: []sql.Row{{2}, {3}, {4}},
},
{
Query: "select floor(i + 0.5) from mytable order by 1",
Expected: []sql.Row{{"1"}, {"2"}, {"3"}},
Expected: []sql.Row{{1}, {2}, {3}},
},
{
Query: "select round(i + 0.55, 1) from mytable order by 1",
Expand Down
39 changes: 15 additions & 24 deletions enginetest/queries/script_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -501,12 +501,12 @@ FROM task_instance INNER JOIN job ON job.id = task_instance.queued_by_job_id INN
},
{
// TODO: 123.456 is converted to a DECIMAL by Builder.ConvertVal, when it should be a DOUBLE
Skip: true,
SkipResultCheckOnServerEngine: true, // TODO: warnings do not make it to server engine
Query: "SELECT '123.456ABC' = 123.456;",
Expected: []sql.Row{{true}},
ExpectedWarningsCount: 1,
ExpectedWarning: mysql.ERTruncatedWrongValue,
ExpectedWarningMessageSubstring: "Truncated incorrect double value: 123A",
ExpectedWarningMessageSubstring: "Truncated incorrect decimal(65,30) value: 123.456ABC",
},
{
Query: "SELECT '123.456e2' = 12345.6;",
Expand All @@ -528,20 +528,18 @@ FROM task_instance INNER JOIN job ON job.id = task_instance.queued_by_job_id INN
},
{
// Valid float strings used as arguments to functions are truncated not rounded
Skip: true,
Query: "SELECT LENGTH(SPACE('1.9'));",
Expected: []sql.Row{{1}},
ExpectedWarningsCount: 2, // MySQL throws two warnings for some reason
ExpectedWarningsCount: 1, // TODO: MySQL throws two warnings for some reason
ExpectedWarning: mysql.ERTruncatedWrongValue,
},
{
// TODO: 123.456 is converted to a DECIMAL by Builder.ConvertVal, when it should be a DOUBLE
Skip: true,
Query: "SELECT -'+123.456ABC' = -123.456",
Expected: []sql.Row{{true}},
ExpectedWarningsCount: 1,
ExpectedWarning: mysql.ERTruncatedWrongValue,
ExpectedWarningMessageSubstring: "Truncated incorrect double value: +123.456ABC",
ExpectedWarningMessageSubstring: "Truncated incorrect decimal(65,30) value: +123.456ABC",
},
{
Query: "SELECT '0xBEEF' = 0;",
Expand Down Expand Up @@ -608,12 +606,12 @@ FROM task_instance INNER JOIN job ON job.id = task_instance.queued_by_job_id INN
},
{
// TODO: 123.456 is converted to a DECIMAL by Builder.ConvertVal, when it should be a DOUBLE
Skip: true,
SkipResultCheckOnServerEngine: true, // TODO: warnings do not make it to server engine
Query: "SELECT '123.456ABC' in (123.456);",
Expected: []sql.Row{{true}},
ExpectedWarningsCount: 1,
ExpectedWarning: mysql.ERTruncatedWrongValue,
ExpectedWarningMessageSubstring: "Truncated incorrect double value: 123A",
ExpectedWarningMessageSubstring: "Truncated incorrect decimal(65,30) value: 123.456ABC",
},
{
Query: "SELECT '123.456e2' in (12345.6);",
Expand Down Expand Up @@ -975,13 +973,13 @@ FROM task_instance INNER JOIN job ON job.id = task_instance.queued_by_job_id INN
Dialect: "mysql",
Name: "strings cast to numbers",
SetUpScript: []string{
"create table test01(pk varchar(20) primary key)",
"create table test01(pk varchar(20) primary key);",
`insert into test01 values (' 3 12 4'),
(' 3.2 12 4'),('-3.1234'),('-3.1a'),('-5+8'),('+3.1234'),
('11d'),('11wha?'),('11'),('12'),('1a1'),('a1a1'),('11-5'),
('3. 12 4'),('5.932887e+07'),('5.932887e+07abc'),('5.932887e7'),('5.932887e7abc')`,
"create table test02(pk int primary key)",
"insert into test02 values(11),(12),(13),(14),(15)",
('3. 12 4'),('5.932887e+07'),('5.932887e+07abc'),('5.932887e7'),('5.932887e7abc');`,
"create table test02(pk int primary key);",
"insert into test02 values(11),(12),(13),(14),(15);",
},
Assertions: []ScriptTestAssertion{
{
Expand Down Expand Up @@ -1082,10 +1080,8 @@ FROM task_instance INNER JOIN job ON job.id = task_instance.queued_by_job_id INN
{"5.932887e7abc", uint64(5)},
{"a1a1", uint64(0)},
},
// TODO: Should be 19. Missing warnings for "Cast to unsigned converted negative integer to its positive
// complement" (1105) https://github.com/dolthub/dolt/issues/9840
ExpectedWarningsCount: 16,
ExpectedWarning: mysql.ERTruncatedWrongValue,
ExpectedWarningsCount: 19,
// Can't check multiple different warnings
},
{
Query: "select pk, cast(pk as decimal(12,3)) from test01",
Expand Down Expand Up @@ -1119,7 +1115,6 @@ FROM task_instance INNER JOIN job ON job.id = task_instance.queued_by_job_id INN
ExpectedWarningsCount: 0,
},

// TODO: these are not directly testing casting
{
// https://github.com/dolthub/dolt/issues/9739
Skip: true,
Expand Down Expand Up @@ -1163,19 +1158,15 @@ FROM task_instance INNER JOIN job ON job.id = task_instance.queued_by_job_id INN
ExpectedWarning: mysql.ERTruncatedWrongValue,
},
{
// https://github.com/dolthub/dolt/issues/9739
Skip: true,
Dialect: "mysql",
Query: "select * from test02 where pk in ('11asdf')",
Expected: []sql.Row{{"11"}},
Query: "select * from test02 where pk in ('11asdf');",
Expected: []sql.Row{{11}},
ExpectedWarningsCount: 1,
ExpectedWarning: mysql.ERTruncatedWrongValue,
},
{
// https://github.com/dolthub/dolt/issues/9739
Skip: true,
Dialect: "mysql",
Query: "select * from test02 where pk='11.12asdf'",
Query: "select * from test02 where pk='11.12asdf';",
Expected: []sql.Row{},
ExpectedWarningsCount: 1,
ExpectedWarning: mysql.ERTruncatedWrongValue,
Expand Down
2 changes: 1 addition & 1 deletion server/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1572,7 +1572,7 @@ func TestStatusVariableMaxUsedConnections(t *testing.T) {
}

checkGlobalStatVar(t, "Max_used_connections", uint64(0))
checkGlobalStatVar(t, "Max_used_connections_time", "")
checkGlobalStatVar(t, "Max_used_connections_time", uint64(0))

conn1 := newConn(1)
handler.NewConnection(conn1)
Expand Down
21 changes: 16 additions & 5 deletions sql/columndefault.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,15 @@ func (e *ColumnDefaultValue) Eval(ctx *Context, r Row) (interface{}, error) {

if e.OutType != nil {
var inRange ConvertInRange
if val, inRange, err = e.OutType.Convert(ctx, val); err != nil {
if roundType, isRoundType := e.OutType.(RoundingNumberType); isRoundType {
val, inRange, err = roundType.ConvertRound(ctx, val)
} else {
val, inRange, err = e.OutType.Convert(ctx, val)
}
if err != nil {
return nil, ErrIncompatibleDefaultType.New()
} else if !inRange {
}
if !inRange {
return nil, ErrValueOutOfRange.New(val, e.OutType)
}
}
Expand Down Expand Up @@ -227,13 +233,18 @@ func (e *ColumnDefaultValue) CheckType(ctx *Context) error {
if val == nil && !e.ReturnNil {
return ErrIncompatibleDefaultType.New()
}
_, inRange, err := e.OutType.Convert(ctx, val)
var inRange ConvertInRange
if roundType, isRoundType := e.OutType.(RoundingNumberType); isRoundType {
val, inRange, err = roundType.ConvertRound(ctx, val)
} else {
val, inRange, err = e.OutType.Convert(ctx, val)
}
if err != nil {
return ErrIncompatibleDefaultType.Wrap(err)
} else if !inRange {
}
if !inRange {
return ErrIncompatibleDefaultType.Wrap(ErrValueOutOfRange.New(val, e.Expr))
}

}
return nil
}
Expand Down
44 changes: 0 additions & 44 deletions sql/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ import (
"strings"
"sync/atomic"
"time"
"unicode"
"unsafe"

"github.com/dolthub/vitess/go/mysql"
"github.com/shopspring/decimal"
"gopkg.in/src-d/go-errors.v1"

Expand Down Expand Up @@ -340,48 +338,6 @@ const (
NumericCutSet = " \t\n\r"
)

// TODO: type processing logic should all be in the types package
func TrimStringToNumberPrefix(ctx *Context, s string, isInt bool) string {
if isInt {
s = strings.TrimLeft(s, IntCutSet)
} else {
s = strings.TrimLeft(s, NumericCutSet)
}

seenDigit := false
seenDot := false
seenExp := false
signIndex := 0

for i := 0; i < len(s); i++ {
char := rune(s[i])
if unicode.IsDigit(char) {
seenDigit = true
} else if char == '.' && !seenDot && !isInt {
seenDot = true
} else if (char == 'e' || char == 'E') && !seenExp && seenDigit && !isInt {
seenExp = true
signIndex = i + 1
} else if !((char == '-' || char == '+') && i == signIndex) {
// TODO: this should not happen here, and it should use sql.ErrIncorrectTruncation
if isInt {
ctx.Warn(mysql.ERTruncatedWrongValue, "Truncated incorrect INTEGER value: '%s'", s)
} else {
ctx.Warn(mysql.ERTruncatedWrongValue, "Truncated incorrect DOUBLE value: '%s'", s)
}
return convertEmptyStringToZero(s[:i])
}
}
return convertEmptyStringToZero(s)
}

func convertEmptyStringToZero(s string) string {
if s == "" {
return "0"
}
return s
}

var ErrVectorInvalidBinaryLength = errors.NewKind("cannot convert BINARY(%d) to vector, byte length must be a multiple of 4 bytes")

// DecodeVector decodes a byte slice that represents a vector. This is needed for distance functions.
Expand Down
9 changes: 6 additions & 3 deletions sql/expression/arithmetic.go
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,12 @@ func (e *UnaryMinus) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
}

if !types.IsNumber(e.Child.Type()) {
child, err = decimal.NewFromString(fmt.Sprintf("%v", child))
child, _, err = types.InternalDecimalType.Convert(ctx, child)
if err != nil {
child = 0.0
if !sql.ErrTruncatedIncorrect.Is(err) {
child = 0.0
}
ctx.Warn(mysql.ERTruncatedWrongValue, "%s", err.Error())
}
}

Expand Down Expand Up @@ -735,7 +738,7 @@ func (e *UnaryMinus) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
case uint64:
return -int64(n), nil
case decimal.Decimal:
return n.Neg(), err
return n.Neg(), nil
case string:
// try getting int out of string value
i, iErr := strconv.ParseInt(n, 10, 64)
Expand Down
6 changes: 3 additions & 3 deletions sql/expression/comparison.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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
}
Expand Down
Loading
Loading