diff --git a/.github/workflows/server-test.yml b/.github/workflows/server-test.yml index 14aea3aef7..4cc899d628 100644 --- a/.github/workflows/server-test.yml +++ b/.github/workflows/server-test.yml @@ -20,6 +20,12 @@ jobs: env: CI_TEST: "true" SERVER_ENGINE_TEST: "true" + - name: Test using Server Engine (32 bit) + run: go test ./... + env: + GOARCH: "386" + CI_TEST: "true" + SERVER_ENGINE_TEST: "true" - name: Test using Server Engine run: go test -race ./... env: diff --git a/sql/expression/function/export_set_test.go b/sql/expression/function/export_set_test.go index c6425211f3..b834b49fdd 100644 --- a/sql/expression/function/export_set_test.go +++ b/sql/expression/function/export_set_test.go @@ -61,7 +61,7 @@ func TestExportSet(t *testing.T) { {"negative number of bits", []interface{}{5, "1", "0", ",", -5}, "1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", false}, // Large numbers - {"large number", []interface{}{4294967295, "1", "0", ",", 32}, "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1", false}, + {"large number", []interface{}{int64(4294967295), "1", "0", ",", 32}, "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1", false}, {"powers of 2", []interface{}{1024, "1", "0", ",", 12}, "0,0,0,0,0,0,0,0,0,0,1,0", false}, // NULL handling diff --git a/sql/expression/function/extract.go b/sql/expression/function/extract.go index 3d2fbcf689..213be3f86b 100644 --- a/sql/expression/function/extract.go +++ b/sql/expression/function/extract.go @@ -169,11 +169,11 @@ func (td *Extract) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { ss := dateTime.Second() return dd + hh + mm + ss, nil case "DAY_MICROSECOND": - dd := dateTime.Day() * 1_00_00_00_000000 - hh := dateTime.Hour() * 1_00_00_000000 - mm := dateTime.Minute() * 1_00_000000 - ss := dateTime.Second() * 1_000000 - mmmmmm := dateTime.Nanosecond() / 1000 + dd := int64(dateTime.Day()) * 1_00_00_00_000000 + hh := int64(dateTime.Hour()) * 1_00_00_000000 + mm := int64(dateTime.Minute()) * 1_00_000000 + ss := int64(dateTime.Second()) * 1_000000 + mmmmmm := int64(dateTime.Nanosecond()) / 1000 return dd + hh + mm + ss + mmmmmm, nil case "HOUR_MINUTE": hh := dateTime.Hour() * 1_00 @@ -185,19 +185,19 @@ func (td *Extract) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { ss := dateTime.Second() return hh + mm + ss, nil case "HOUR_MICROSECOND": - hh := dateTime.Hour() * 1_00_00_000000 - mm := dateTime.Minute() * 1_00_000000 - ss := dateTime.Second() * 1_000000 - mmmmmm := dateTime.Nanosecond() / 1000 + hh := int64(dateTime.Hour()) * 1_00_00_000000 + mm := int64(dateTime.Minute()) * 1_00_000000 + ss := int64(dateTime.Second()) * 1_000000 + mmmmmm := int64(dateTime.Nanosecond()) / 1000 return hh + mm + ss + mmmmmm, nil case "MINUTE_SECOND": mm := dateTime.Minute() * 1_00 ss := dateTime.Second() return mm + ss, nil case "MINUTE_MICROSECOND": - mm := dateTime.Minute() * 1_00_000000 - ss := dateTime.Second() * 1_000000 - mmmmmm := dateTime.Nanosecond() / 1000 + mm := int64(dateTime.Minute()) * 1_00_000000 + ss := int64(dateTime.Second()) * 1_000000 + mmmmmm := int64(dateTime.Nanosecond()) / 1000 return mm + ss + mmmmmm, nil case "SECOND_MICROSECOND": ss := dateTime.Second() * 1_000000 diff --git a/sql/expression/function/extract_test.go b/sql/expression/function/extract_test.go index d0a6b5c6d4..7a3fa356ba 100644 --- a/sql/expression/function/extract_test.go +++ b/sql/expression/function/extract_test.go @@ -132,7 +132,7 @@ func TestExtract(t *testing.T) { name: "get day_microsecond", unit: "DAY_MICROSECOND", dateTime: "2023-11-12 11:22:33.445566", - expected: 12112233445566, + expected: int64(12112233445566), }, { name: "get hour_minute", @@ -150,7 +150,7 @@ func TestExtract(t *testing.T) { name: "get hour_microsecond", unit: "HOUR_MICROSECOND", dateTime: "2023-11-12 11:22:33.445566", - expected: 112233445566, + expected: int64(112233445566), }, { name: "get minute_second", @@ -162,7 +162,7 @@ func TestExtract(t *testing.T) { name: "get minute_microsecond", unit: "MINUTE_MICROSECOND", dateTime: "2023-11-12 11:22:33.445566", - expected: 2233445566, + expected: int64(2233445566), }, { name: "get second_microsecond", diff --git a/sql/expression/function/make_set_test.go b/sql/expression/function/make_set_test.go index de8b742cf9..82a600b6d5 100644 --- a/sql/expression/function/make_set_test.go +++ b/sql/expression/function/make_set_test.go @@ -76,7 +76,7 @@ func TestMakeSet(t *testing.T) { // Large numbers {"max uint64 bits", []interface{}{^uint64(0), "a", "b", "c"}, "a,b,c", false}, - {"large positive number", []interface{}{4294967295, "a", "b", "c"}, "a,b,c", false}, + {"large positive number", []interface{}{int64(4294967295), "a", "b", "c"}, "a,b,c", false}, // Empty strings {"empty string values", []interface{}{3, "", "test", ""}, ",test", false}, diff --git a/sql/expression/function/oct_test.go b/sql/expression/function/oct_test.go index 7cd978405e..e8c6b7f38c 100644 --- a/sql/expression/function/oct_test.go +++ b/sql/expression/function/oct_test.go @@ -57,8 +57,8 @@ func TestOct(t *testing.T) { // Edge cases {"max int32", types.Int32, sql.NewRow(math.MaxInt32), "17777777777"}, {"min int32", types.Int32, sql.NewRow(math.MinInt32), "1777777777760000000000"}, - {"max int64", types.Int64, sql.NewRow(math.MaxInt64), "777777777777777777777"}, - {"min int64", types.Int64, sql.NewRow(math.MinInt64), "1000000000000000000000"}, + {"max int64", types.Int64, sql.NewRow(int64(math.MaxInt64)), "777777777777777777777"}, + {"min int64", types.Int64, sql.NewRow(int64(math.MinInt64)), "1000000000000000000000"}, // Decimal numbers {"decimal", types.Float64, sql.NewRow(15.5), "17"}, diff --git a/sql/rowexec/ddl.go b/sql/rowexec/ddl.go index 86d3abe036..f628e32577 100644 --- a/sql/rowexec/ddl.go +++ b/sql/rowexec/ddl.go @@ -18,6 +18,7 @@ import ( "bufio" "fmt" "io" + "math" "os" "strings" "time" @@ -94,7 +95,7 @@ func (b *BaseBuilder) buildLoadData(ctx *sql.Context, n *plan.LoadData, row sql. } scanner := bufio.NewScanner(reader) - scanner.Buffer(nil, int(types.LongTextBlobMax)) + scanner.Buffer(nil, int(min(types.LongTextBlobMax, math.MaxInt))) scanner.Split(n.SplitLines) sch := n.Schema() diff --git a/sql/rowexec/proc.go b/sql/rowexec/proc.go index 35af6c65e8..26e0ed7ef3 100644 --- a/sql/rowexec/proc.go +++ b/sql/rowexec/proc.go @@ -306,7 +306,7 @@ func (b *BaseBuilder) buildLoop(ctx *sql.Context, n *plan.Loop, row sql.Row) (sq // It's technically valid to make an infinite loop, but we don't want to actually allow that const maxIterationCount = 10_000_000_000 - for loopIteration := 0; loopIteration <= maxIterationCount; loopIteration++ { + for loopIteration := int64(0); loopIteration <= maxIterationCount; loopIteration++ { if loopIteration >= maxIterationCount { return nil, fmt.Errorf("infinite LOOP detected") } diff --git a/sql/types/geometry.go b/sql/types/geometry.go index 8a429ce480..477314d26c 100644 --- a/sql/types/geometry.go +++ b/sql/types/geometry.go @@ -546,7 +546,7 @@ func (t GeometryType) MatchSRID(v interface{}) error { } func ValidateSRID(srid int, funcName string) error { - if srid < 0 || srid > math.MaxUint32 { + if srid < 0 || srid > min(math.MaxUint32, math.MaxInt) { return sql.ErrInvalidSRID.New(funcName) } if _, ok := SupportedSRIDs[uint32(srid)]; !ok { diff --git a/sql/types/number.go b/sql/types/number.go index b6152a800d..090248fae1 100644 --- a/sql/types/number.go +++ b/sql/types/number.go @@ -1114,27 +1114,27 @@ func convertToUint64(t NumberTypeImpl_, v interface{}) (uint64, sql.ConvertInRan return uint64(v.UTC().Unix()), sql.InRange, nil case int: if v < 0 { - return uint64(math.MaxUint64 - uint(-v-1)), sql.OutOfRange, nil + return math.MaxUint64 - uint64(-v-1), sql.OutOfRange, nil } return uint64(v), sql.InRange, nil case int8: if v < 0 { - return uint64(math.MaxUint64 - uint(-v-1)), sql.OutOfRange, nil + return math.MaxUint64 - uint64(-v-1), sql.OutOfRange, nil } return uint64(v), sql.InRange, nil case int16: if v < 0 { - return uint64(math.MaxUint64 - uint(-v-1)), sql.OutOfRange, nil + return math.MaxUint64 - uint64(-v-1), sql.OutOfRange, nil } return uint64(v), sql.InRange, nil case int32: if v < 0 { - return uint64(math.MaxUint64 - uint(-v-1)), sql.OutOfRange, nil + return math.MaxUint64 - uint64(-v-1), sql.OutOfRange, nil } return uint64(v), sql.InRange, nil case int64: if v < 0 { - return uint64(math.MaxUint64 - uint(-v-1)), sql.OutOfRange, nil + return math.MaxUint64 - uint64(-v-1), sql.OutOfRange, nil } return uint64(v), sql.InRange, nil case uint: @@ -1205,28 +1205,28 @@ func convertToUint32(t NumberTypeImpl_, v interface{}) (uint32, sql.ConvertInRan case int: if v < 0 { return uint32(math.MaxUint32 - uint(-v-1)), sql.OutOfRange, nil - } else if v > math.MaxUint32 { + } else if v > min(math.MaxUint32, math.MaxInt) { return uint32(math.MaxUint32), sql.OutOfRange, nil } return uint32(v), sql.InRange, nil case int8: if v < 0 { return uint32(math.MaxUint32 - uint(-v-1)), sql.OutOfRange, nil - } else if int(v) > math.MaxUint32 { + } else if int(v) > min(math.MaxUint32, math.MaxInt) { return uint32(math.MaxUint32), sql.OutOfRange, nil } return uint32(v), sql.InRange, nil case int16: if v < 0 { return uint32(math.MaxUint32 - uint(-v-1)), sql.OutOfRange, nil - } else if int(v) > math.MaxUint32 { + } else if int(v) > min(math.MaxUint32, math.MaxInt) { return uint32(math.MaxUint32), sql.OutOfRange, nil } return uint32(v), sql.InRange, nil case int32: if v < 0 { return uint32(math.MaxUint32 - uint(-v-1)), sql.OutOfRange, nil - } else if int(v) > math.MaxUint32 { + } else if int(v) > min(math.MaxUint32, math.MaxInt) { return uint32(math.MaxUint32), sql.OutOfRange, nil } return uint32(v), sql.InRange, nil diff --git a/sql/types/number_test.go b/sql/types/number_test.go index 580b50bda2..cda564ed02 100644 --- a/sql/types/number_test.go +++ b/sql/types/number_test.go @@ -204,8 +204,8 @@ func TestNumberConvert(t *testing.T) { {typ: Int16, inp: math.MinInt16 - 1, exp: int16(math.MinInt16), err: false, inRange: sql.OutOfRange}, {typ: Int24, inp: 1 << 24, exp: int32(1<<23 - 1), err: false, inRange: sql.OutOfRange}, {typ: Int24, inp: -1 << 24, exp: int32(-1 << 23), err: false, inRange: sql.OutOfRange}, - {typ: Int32, inp: math.MaxInt32 + 1, exp: int32(math.MaxInt32), err: false, inRange: sql.OutOfRange}, - {typ: Int32, inp: math.MinInt32 - 1, exp: int32(math.MinInt32), err: false, inRange: sql.OutOfRange}, + {typ: Int32, inp: int64(math.MaxInt32 + 1), exp: int32(math.MaxInt32), err: false, inRange: sql.OutOfRange}, + {typ: Int32, inp: int64(math.MinInt32 - 1), exp: int32(math.MinInt32), err: false, inRange: sql.OutOfRange}, {typ: Int64, inp: uint64(math.MaxInt64 + 1), exp: int64(math.MaxInt64), err: false, inRange: sql.OutOfRange}, {typ: Uint8, inp: math.MaxUint8 + 1, exp: uint8(math.MaxUint8), err: false, inRange: sql.OutOfRange}, {typ: Uint8, inp: -1, exp: uint8(math.MaxUint8), err: false, inRange: sql.OutOfRange}, @@ -213,7 +213,7 @@ func TestNumberConvert(t *testing.T) { {typ: Uint16, inp: -1, exp: uint16(math.MaxUint16), err: false, inRange: sql.OutOfRange}, {typ: Uint24, inp: 1 << 24, exp: uint32(1<<24 - 1), err: false, inRange: sql.OutOfRange}, {typ: Uint24, inp: -1, exp: uint32(1<<24 - 1), err: false, inRange: sql.OutOfRange}, - {typ: Uint32, inp: math.MaxUint32 + 1, exp: uint32(math.MaxUint32), err: false, inRange: sql.OutOfRange}, + {typ: Uint32, inp: int64(math.MaxUint32 + 1), exp: uint32(math.MaxUint32), err: false, inRange: sql.OutOfRange}, {typ: Uint32, inp: -1, exp: uint32(math.MaxUint32), err: false, inRange: sql.OutOfRange}, {typ: Uint64, inp: -1, exp: uint64(math.MaxUint64), err: false, inRange: sql.OutOfRange}, {typ: Float32, inp: math.MaxFloat32 * 2, exp: float32(math.MaxFloat32), err: false, inRange: sql.OutOfRange},