From 6287b24f431afc219caa916cd878fce21ba5f962 Mon Sep 17 00:00:00 2001 From: H Date: Thu, 2 Aug 2018 12:57:06 +0800 Subject: [PATCH] expression: handle max_allowed_packet warnings for space function. (#7210) --- expression/builtin_string.go | 19 +++++++++++++++---- expression/builtin_string_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/expression/builtin_string.go b/expression/builtin_string.go index c21ecae092aeb..22a6bbd28448d 100644 --- a/expression/builtin_string.go +++ b/expression/builtin_string.go @@ -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 } @@ -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 } diff --git a/expression/builtin_string_test.go b/expression/builtin_string_test.go index 46dde9237fa0d..5425996080143 100644 --- a/expression/builtin_string_test.go +++ b/expression/builtin_string_test.go @@ -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)()