Fix the incorrect behavior of `substring` function, multi-byte charset still hasn't been supported.
This commit is contained in:
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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, ""},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user