Skip to content

Commit

Permalink
expression: deep copy the string when setting user variable from Chunk (
Browse files Browse the repository at this point in the history
  • Loading branch information
zz-jason committed Jul 3, 2019
1 parent 2e406b0 commit fde32ba
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
3 changes: 2 additions & 1 deletion expression/builtin_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/types/json"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/stringutil"
"github.com/pingcap/tipb/go-tipb"
)

Expand Down Expand Up @@ -420,7 +421,7 @@ func (b *builtinSetVarSig) evalString(row chunk.Row) (res string, isNull bool, e
}
varName = strings.ToLower(varName)
sessionVars.UsersLock.Lock()
sessionVars.Users[varName] = res
sessionVars.Users[varName] = stringutil.Copy(res)
sessionVars.UsersLock.Unlock()
return res, false, nil
}
Expand Down
43 changes: 43 additions & 0 deletions expression/builtin_other_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,46 @@ func (s *testEvaluatorSuite) TestValues(c *C) {
c.Assert(err, IsNil)
c.Assert(cmp, Equals, 0)
}

func (s *testEvaluatorSuite) TestSetVarFromColumn(c *C) {
defer testleak.AfterTest(c)()

// Construct arguments.
argVarName := &Constant{
Value: types.NewStringDatum("a"),
RetType: &types.FieldType{Tp: mysql.TypeVarString, Flen: 20},
}
argCol := &Column{
RetType: &types.FieldType{Tp: mysql.TypeVarString, Flen: 20},
Index: 0,
}

// Construct SetVar function.
funcSetVar, err := NewFunction(
s.ctx,
ast.SetVar,
&types.FieldType{Tp: mysql.TypeVarString, Flen: 20},
[]Expression{argVarName, argCol}...,
)
c.Assert(err, IsNil)

// Construct input and output Chunks.
inputChunk := chunk.NewChunkWithCapacity([]*types.FieldType{argCol.RetType}, 1)
inputChunk.AppendString(0, "a")
outputChunk := chunk.NewChunkWithCapacity([]*types.FieldType{argCol.RetType}, 1)

// Evaluate the SetVar function.
err = evalOneCell(s.ctx, funcSetVar, inputChunk.GetRow(0), outputChunk, 0)
c.Assert(err, IsNil)
c.Assert(outputChunk.GetRow(0).GetString(0), Equals, "a")

// Change the content of the underlying Chunk.
inputChunk.Reset()
inputChunk.AppendString(0, "b")

// Check whether the user variable changed.
sessionVars := s.ctx.GetSessionVars()
sessionVars.UsersLock.RLock()
defer sessionVars.UsersLock.RUnlock()
c.Assert(sessionVars.Users["a"], Equals, "a")
}

0 comments on commit fde32ba

Please sign in to comment.