Skip to content
This repository has been archived by the owner on Jan 28, 2021. It is now read-only.

Commit

Permalink
Support unsigned ints too, add tes for overflow error
Browse files Browse the repository at this point in the history
Signed-off-by: Juanjo Alvarez <juanjo@sourced.tech>
  • Loading branch information
Juanjo Alvarez committed May 20, 2019
1 parent b1801c1 commit 62ffb2d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
28 changes: 27 additions & 1 deletion sql/expression/function/greatest_least.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import (
"gopkg.in/src-d/go-mysql-server.v0/sql"
)

var ErrUintOverflow = errors.NewKind(
"Unsigned integer too big to fit on signed integer")

// compEval is used to implement Greatest/Least Eval() using a comparison function
func compEval(
returnType sql.Type,
Expand All @@ -32,12 +35,35 @@ func compEval(
}

switch t := val.(type) {
case int, int32, int64:
case int, int8, int16, int32, int64, uint,
uint8, uint16, uint32, uint64:
switch x := t.(type) {
case int:
t = int64(x)
case int8:
t = int64(x)
case int16:
t = int64(x)
case int32:
t = int64(x)
case uint:
i := int64(x)
if i < 0 {
return nil, ErrUintOverflow.New()
}
t = i
case uint64:
i := int64(x)
if i < 0 {
return nil, ErrUintOverflow.New()
}
t = i
case uint8:
t = int64(x)
case uint16:
t = int64(x)
case uint32:
t = int64(x)
}
ival := t.(int64)
if i == 0 || cmp(ival, int64(selectedNum)) {
Expand Down
30 changes: 30 additions & 0 deletions sql/expression/function/greatest_least_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"gopkg.in/src-d/go-mysql-server.v0/sql"
"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
"testing"
"unsafe"
)

func TestGreatest(t *testing.T) {
Expand Down Expand Up @@ -95,6 +96,35 @@ func TestGreatest(t *testing.T) {
}
}

func TestGreatestUnsignedOverflow(t *testing.T) {
require := require.New(t)

var x int
var gr sql.Expression
var err error

switch unsafe.Sizeof(x) {
case 4:
gr, err = NewGreatest(
expression.NewLiteral(int32(1), sql.Int32),
expression.NewLiteral(uint32(4294967295), sql.Uint32),
)
require.NoError(err)
case 8:
gr, err = NewGreatest(
expression.NewLiteral(int64(1), sql.Int64),
expression.NewLiteral(uint64(18446744073709551615), sql.Uint64),
)
require.NoError(err)
default:
// non 32/64 bits??
return
}

_, err = gr.Eval(sql.NewEmptyContext(), nil)
require.EqualError(err, "Unsigned integer too big to fit on signed integer")
}

func TestLeast(t *testing.T) {
testCases := []struct {
name string
Expand Down

0 comments on commit 62ffb2d

Please sign in to comment.