evaluator: partially fix issue #1098 (#1100)

Fix the incorrect behavior of `substring` function, multi-byte charset still hasn't been supported.
This commit is contained in:
zyguan
2016-04-17 00:43:30 +08:00
committed by Shen Li
parent bfa3ed7a2d
commit cd3d424252
2 changed files with 30 additions and 11 deletions

View File

@ -275,12 +275,12 @@ func builtinSubstring(args []types.Datum, _ context.Context) (d types.Datum, err
}
pos := args[1].GetInt64()
length := int64(-1)
length, hasLen := int64(-1), false
if len(args) == 3 {
if args[2].Kind() != types.KindInt64 {
return d, errors.Errorf("Substring invalid pos args, need int but get %T", args[2].GetValue())
}
length = args[2].GetInt64()
length, hasLen = args[2].GetInt64(), true
}
// The forms without a len argument return a substring from string str starting at position pos.
// The forms with a len argument return a substring len characters long from string str, starting at position pos.
@ -292,17 +292,20 @@ func builtinSubstring(args []types.Datum, _ context.Context) (d types.Datum, err
} else {
pos--
}
if pos > int64(len(str)) || pos <= int64(0) {
if pos > int64(len(str)) || pos < int64(0) {
pos = int64(len(str))
}
end := int64(len(str))
if length != int64(-1) {
end = pos + length
if hasLen {
if end := pos + length; end < pos {
d.SetString("")
} else if end > int64(len(str)) {
d.SetString(str[pos:])
} else {
d.SetString(str[pos:end])
}
} else {
d.SetString(str[pos:])
}
if end > int64(len(str)) {
end = int64(len(str))
}
d.SetString(str[pos:end])
return d, nil
}

View File

@ -263,6 +263,11 @@ func (s *testEvaluatorSuite) TestReplace(c *C) {
func (s *testEvaluatorSuite) TestSubstring(c *C) {
defer testleak.AfterTest(c)()
d, err := builtinSubstring(types.MakeDatums([]interface{}{"hello", 2, -1}...), nil)
c.Assert(err, IsNil)
c.Assert(d.GetString(), Equals, "")
tbl := []struct {
str string
pos int64
@ -271,10 +276,21 @@ func (s *testEvaluatorSuite) TestSubstring(c *C) {
}{
{"Quadratically", 5, -1, "ratically"},
{"foobarbar", 4, -1, "barbar"},
{"Quadratically", 5, 6, "ratica"},
{"Sakila", 1, -1, "Sakila"},
{"Sakila", 2, -1, "akila"},
{"Sakila", -3, -1, "ila"},
{"Sakila", -5, 3, "aki"},
{"Sakila", -4, 2, "ki"},
{"Quadratically", 5, 6, "ratica"},
{"Sakila", 1, 4, "Saki"},
{"Sakila", -6, 4, "Saki"},
{"Sakila", 2, 1000, "akila"},
{"Sakila", -5, 1000, "akila"},
{"Sakila", 2, -2, ""},
{"Sakila", -5, -2, ""},
{"Sakila", 2, 0, ""},
{"Sakila", -5, -3, ""},
{"Sakila", -1000, 3, ""},
{"Sakila", 1000, 2, ""},
{"", 2, 3, ""},
}