Skip to content

Commit

Permalink
expression: handle max_allowed_packet warnings for space function. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
hhu-cc authored and XuHuaiyu committed Aug 2, 2018
1 parent cc1c3be commit 6287b24
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
19 changes: 15 additions & 4 deletions expression/builtin_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -708,17 +708,24 @@ func (c *spaceFunctionClass) getFunction(ctx sessionctx.Context, args []Expressi
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETInt)
bf.tp.Flen = mysql.MaxBlobWidth
sig := &builtinSpaceSig{bf}
valStr, _ := ctx.GetSessionVars().GetSystemVar(variable.MaxAllowedPacket)
maxAllowedPacket, err := strconv.ParseUint(valStr, 10, 64)
if err != nil {
return nil, errors.Trace(err)
}
sig := &builtinSpaceSig{bf, maxAllowedPacket}
return sig, nil
}

type builtinSpaceSig struct {
baseBuiltinFunc
maxAllowedPacket uint64
}

func (b *builtinSpaceSig) Clone() builtinFunc {
newSig := &builtinSpaceSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
newSig.maxAllowedPacket = b.maxAllowedPacket
return newSig
}

Expand All @@ -731,12 +738,16 @@ func (b *builtinSpaceSig) evalString(row chunk.Row) (d string, isNull bool, err
if isNull || err != nil {
return d, isNull, errors.Trace(err)
}
if x > mysql.MaxBlobWidth {
return d, true, nil
}
if x < 0 {
x = 0
}
if uint64(x) > b.maxAllowedPacket {
b.ctx.GetSessionVars().StmtCtx.AppendWarning(errWarnAllowedPacketOverflowed.GenByArgs("space", b.maxAllowedPacket))
return d, true, nil
}
if x > mysql.MaxBlobWidth {
return d, true, nil
}
return strings.Repeat(" ", int(x)), false, nil
}

Expand Down
27 changes: 27 additions & 0 deletions expression/builtin_string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,33 @@ func (s *testEvaluatorSuite) TestSpace(c *C) {
c.Assert(err, IsNil)
}

func (s *testEvaluatorSuite) TestSpaceSig(c *C) {
colTypes := []*types.FieldType{
{Tp: mysql.TypeLonglong},
}
resultType := &types.FieldType{Tp: mysql.TypeVarchar, Flen: 1000}
args := []Expression{
&Column{Index: 0, RetType: colTypes[0]},
}
base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType}
space := &builtinSpaceSig{base, 1000}
input := chunk.NewChunkWithCapacity(colTypes, 10)
input.AppendInt64(0, 6)
input.AppendInt64(0, 1001)
res, isNull, err := space.evalString(input.GetRow(0))
c.Assert(res, Equals, " ")
c.Assert(isNull, IsFalse)
c.Assert(err, IsNil)
res, isNull, err = space.evalString(input.GetRow(1))
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]
c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue)
}

func (s *testEvaluatorSuite) TestLocate(c *C) {
// 1. Test LOCATE without binary input.
defer testleak.AfterTest(c)()
Expand Down

0 comments on commit 6287b24

Please sign in to comment.