Skip to content

Commit

Permalink
Function INSERT should be NULL if any argument is NULL. (pingcap#11174)
Browse files Browse the repository at this point in the history
  • Loading branch information
kanchairen committed Jul 14, 2019
1 parent bdec341 commit 5484145
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 9 deletions.
18 changes: 9 additions & 9 deletions expression/builtin_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -3325,15 +3325,11 @@ func (b *builtinInsertBinarySig) evalString(row chunk.Row) (string, bool, error)
if isNull || err != nil {
return "", true, err
}
strLength := int64(len(str))

pos, isNull, err := b.args[1].EvalInt(b.ctx, row)
if isNull || err != nil {
return "", true, err
}
if pos < 1 || pos > strLength {
return str, false, nil
}

length, isNull, err := b.args[2].EvalInt(b.ctx, row)
if isNull || err != nil {
Expand All @@ -3345,6 +3341,10 @@ func (b *builtinInsertBinarySig) evalString(row chunk.Row) (string, bool, error)
return "", true, err
}

strLength := int64(len(str))
if pos < 1 || pos > strLength {
return str, false, nil
}
if length > strLength-pos+1 || length < 0 {
length = strLength - pos + 1
}
Expand Down Expand Up @@ -3376,16 +3376,11 @@ func (b *builtinInsertSig) evalString(row chunk.Row) (string, bool, error) {
if isNull || err != nil {
return "", true, err
}
runes := []rune(str)
runeLength := int64(len(runes))

pos, isNull, err := b.args[1].EvalInt(b.ctx, row)
if isNull || err != nil {
return "", true, err
}
if pos < 1 || pos > runeLength {
return str, false, nil
}

length, isNull, err := b.args[2].EvalInt(b.ctx, row)
if isNull || err != nil {
Expand All @@ -3397,6 +3392,11 @@ func (b *builtinInsertSig) evalString(row chunk.Row) (string, bool, error) {
return "", true, err
}

runes := []rune(str)
runeLength := int64(len(runes))
if pos < 1 || pos > runeLength {
return str, false, nil
}
if length > runeLength-pos+1 || length < 0 {
length = runeLength - pos + 1
}
Expand Down
49 changes: 49 additions & 0 deletions expression/builtin_string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1474,12 +1474,32 @@ func (s *testEvaluatorSuite) TestInsertBinarySig(c *C) {
input := chunk.NewChunkWithCapacity(colTypes, 2)
input.AppendString(0, "abc")
input.AppendString(0, "abc")
input.AppendString(0, "abc")
input.AppendNull(0)
input.AppendString(0, "abc")
input.AppendString(0, "abc")
input.AppendString(0, "abc")
input.AppendInt64(1, 3)
input.AppendInt64(1, 3)
input.AppendInt64(1, 0)
input.AppendInt64(1, 3)
input.AppendNull(1)
input.AppendInt64(1, 3)
input.AppendInt64(1, 3)
input.AppendInt64(2, -1)
input.AppendInt64(2, -1)
input.AppendInt64(2, -1)
input.AppendInt64(2, -1)
input.AppendInt64(2, -1)
input.AppendNull(2)
input.AppendInt64(2, -1)
input.AppendString(3, "d")
input.AppendString(3, "de")
input.AppendString(3, "d")
input.AppendString(3, "d")
input.AppendString(3, "d")
input.AppendString(3, "d")
input.AppendNull(3)

res, isNull, err := insert.evalString(input.GetRow(0))
c.Assert(res, Equals, "abd")
Expand All @@ -1491,6 +1511,31 @@ func (s *testEvaluatorSuite) TestInsertBinarySig(c *C) {
c.Assert(isNull, IsTrue)
c.Assert(err, IsNil)

res, isNull, err = insert.evalString(input.GetRow(2))
c.Assert(res, Equals, "abc")
c.Assert(isNull, IsFalse)
c.Assert(err, IsNil)

res, isNull, err = insert.evalString(input.GetRow(3))
c.Assert(res, Equals, "")
c.Assert(isNull, IsTrue)
c.Assert(err, IsNil)

res, isNull, err = insert.evalString(input.GetRow(4))
c.Assert(res, Equals, "")
c.Assert(isNull, IsTrue)
c.Assert(err, IsNil)

res, isNull, err = insert.evalString(input.GetRow(5))
c.Assert(res, Equals, "")
c.Assert(isNull, IsTrue)
c.Assert(err, IsNil)

res, isNull, err = insert.evalString(input.GetRow(6))
c.Assert(res, Equals, "")
c.Assert(isNull, IsTrue)
c.Assert(err, IsNil)

warnings := s.ctx.GetSessionVars().StmtCtx.GetWarnings()
c.Assert(len(warnings), Equals, 1)
lastWarn := warnings[len(warnings)-1]
Expand Down Expand Up @@ -1855,6 +1900,8 @@ func (s *testEvaluatorSuite) TestInsert(c *C) {
{[]interface{}{"Quadratic", 3, 4, nil}, nil},
{[]interface{}{"Quadratic", 3, -1, "What"}, "QuWhat"},
{[]interface{}{"Quadratic", 3, 1, "What"}, "QuWhatdratic"},
{[]interface{}{"Quadratic", -1, nil, "What"}, nil},
{[]interface{}{"Quadratic", -1, 4, nil}, nil},

{[]interface{}{"我叫小雨呀", 3, 2, "王雨叶"}, "我叫王雨叶呀"},
{[]interface{}{"我叫小雨呀", -1, 2, "王雨叶"}, "我叫小雨呀"},
Expand All @@ -1865,6 +1912,8 @@ func (s *testEvaluatorSuite) TestInsert(c *C) {
{[]interface{}{"我叫小雨呀", 3, 4, nil}, nil},
{[]interface{}{"我叫小雨呀", 3, -1, "王雨叶"}, "我叫王雨叶"},
{[]interface{}{"我叫小雨呀", 3, 1, "王雨叶"}, "我叫王雨叶雨呀"},
{[]interface{}{"我叫小雨呀", -1, nil, "王雨叶"}, nil},
{[]interface{}{"我叫小雨呀", -1, 2, nil}, nil},
}
fc := funcs[ast.InsertFunc]
for _, test := range tests {
Expand Down
4 changes: 4 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,10 @@ func (s *testIntegrationSuite) TestStringBuiltin(c *C) {
result.Check(testkit.Rows("aaa文 ba aaa ba"))
result = tk.MustQuery(`select insert("bb", NULL, 1, "aa"), insert("bb", 1, NULL, "aa"), insert(NULL, 1, 1, "aaa"), insert("bb", 1, 1, NULL);`)
result.Check(testkit.Rows("<nil> <nil> <nil> <nil>"))
result = tk.MustQuery(`SELECT INSERT("bb", 0, 1, NULL), INSERT("bb", 0, NULL, "aaa");`)
result.Check(testkit.Rows("<nil> <nil>"))
result = tk.MustQuery(`SELECT INSERT("中文", 0, 1, NULL), INSERT("中文", 0, NULL, "aaa");`)
result.Check(testkit.Rows("<nil> <nil>"))

// for export_set
result = tk.MustQuery(`select export_set(7, "1", "0", ",", 65);`)
Expand Down

0 comments on commit 5484145

Please sign in to comment.