From 26a88654eb4032d32bf3a0609ba4d99981e0ab30 Mon Sep 17 00:00:00 2001 From: crazycs Date: Thu, 5 Jul 2018 14:00:28 +0800 Subject: [PATCH 1/3] aggregation: fix bit_or handle decimal bugs --- expression/aggregation/bit_or.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/expression/aggregation/bit_or.go b/expression/aggregation/bit_or.go index 7d7cfef5e652e..174907e96a722 100644 --- a/expression/aggregation/bit_or.go +++ b/expression/aggregation/bit_or.go @@ -41,7 +41,15 @@ func (bf *bitOrFunction) Update(evalCtx *AggEvaluateContext, sc *stmtctx.Stateme return errors.Trace(err) } if !value.IsNull() { - evalCtx.Value.SetUint64(evalCtx.Value.GetUint64() | value.GetUint64()) + if value.Kind() == types.KindUint64 { + evalCtx.Value.SetUint64(evalCtx.Value.GetUint64() | value.GetUint64()) + } else { + int64Value, err := value.ToInt64(sc) + if err != nil { + return errors.Trace(err) + } + evalCtx.Value.SetUint64(evalCtx.Value.GetUint64() | uint64(int64Value)) + } } return nil } From bddd85ebde8ce46daf9df10320ce8cbf5b5e8a80 Mon Sep 17 00:00:00 2001 From: crazycs Date: Thu, 5 Jul 2018 15:57:16 +0800 Subject: [PATCH 2/3] aggregation: add bit or test --- expression/aggregation/aggregation_test.go | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/expression/aggregation/aggregation_test.go b/expression/aggregation/aggregation_test.go index 274f3c082f8f8..a2c1c39e8324b 100644 --- a/expression/aggregation/aggregation_test.go +++ b/expression/aggregation/aggregation_test.go @@ -234,6 +234,51 @@ func (s *testAggFuncSuit) TestBitOr(c *C) { c.Assert(result.GetUint64(), Equals, uint64(3)) partialResult := bitOrFunc.GetPartialResult(evalCtx) c.Assert(partialResult[0].GetUint64(), Equals, uint64(3)) + + // test bit_or( decimal ) + col.RetType = types.NewFieldType(mysql.TypeNewDecimal) + bitOrFunc.ResetContext(s.ctx.GetSessionVars().StmtCtx, evalCtx) + + result = bitOrFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(0)) + + var dec types.MyDecimal + err = dec.FromString([]byte("12.234")) + c.Assert(err, IsNil) + + row = types.MakeDatums(&dec) + err = bitOrFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) + c.Assert(err, IsNil) + result = bitOrFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(12)) + + err = dec.FromString([]byte("1.012")) + c.Assert(err, IsNil) + + row = types.MakeDatums(&dec) + err = bitOrFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) + c.Assert(err, IsNil) + result = bitOrFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(13)) + + err = dec.FromString([]byte("15.12345678")) + c.Assert(err, IsNil) + + row = types.MakeDatums(&dec) + err = bitOrFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) + c.Assert(err, IsNil) + result = bitOrFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(15)) + + err = dec.FromString([]byte("16.00")) + c.Assert(err, IsNil) + + row = types.MakeDatums(&dec) + err = bitOrFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) + c.Assert(err, IsNil) + result = bitOrFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(31)) + } func (s *testAggFuncSuit) TestBitXor(c *C) { From b4e22c1e82d0463168a45cea2a1f856e92836a12 Mon Sep 17 00:00:00 2001 From: crazycs Date: Thu, 5 Jul 2018 16:28:13 +0800 Subject: [PATCH 3/3] aggregation: fix bit_and, bit_xor handle decimal the same bug too --- expression/aggregation/aggregation_test.go | 69 ++++++++++++++++++++-- expression/aggregation/bit_and.go | 10 +++- expression/aggregation/bit_xor.go | 10 +++- 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/expression/aggregation/aggregation_test.go b/expression/aggregation/aggregation_test.go index a2c1c39e8324b..50334aedadc20 100644 --- a/expression/aggregation/aggregation_test.go +++ b/expression/aggregation/aggregation_test.go @@ -191,6 +191,38 @@ func (s *testAggFuncSuit) TestBitAnd(c *C) { c.Assert(result.GetUint64(), Equals, uint64(0)) partialResult := bitAndFunc.GetPartialResult(evalCtx) c.Assert(partialResult[0].GetUint64(), Equals, uint64(0)) + + // test bit_and( decimal ) + col.RetType = types.NewFieldType(mysql.TypeNewDecimal) + bitAndFunc.ResetContext(s.ctx.GetSessionVars().StmtCtx, evalCtx) + + result = bitAndFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(math.MaxUint64)) + + var dec types.MyDecimal + err = dec.FromString([]byte("1.234")) + c.Assert(err, IsNil) + row = types.MakeDatums(&dec) + err = bitAndFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) + c.Assert(err, IsNil) + result = bitAndFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(1)) + + err = dec.FromString([]byte("3.012")) + c.Assert(err, IsNil) + row = types.MakeDatums(&dec) + err = bitAndFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) + c.Assert(err, IsNil) + result = bitAndFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(1)) + + err = dec.FromString([]byte("2.12345678")) + c.Assert(err, IsNil) + row = types.MakeDatums(&dec) + err = bitAndFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) + c.Assert(err, IsNil) + result = bitAndFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(0)) } func (s *testAggFuncSuit) TestBitOr(c *C) { @@ -245,7 +277,6 @@ func (s *testAggFuncSuit) TestBitOr(c *C) { var dec types.MyDecimal err = dec.FromString([]byte("12.234")) c.Assert(err, IsNil) - row = types.MakeDatums(&dec) err = bitOrFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) c.Assert(err, IsNil) @@ -254,13 +285,11 @@ func (s *testAggFuncSuit) TestBitOr(c *C) { err = dec.FromString([]byte("1.012")) c.Assert(err, IsNil) - row = types.MakeDatums(&dec) err = bitOrFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) c.Assert(err, IsNil) result = bitOrFunc.GetResult(evalCtx) c.Assert(result.GetUint64(), Equals, uint64(13)) - err = dec.FromString([]byte("15.12345678")) c.Assert(err, IsNil) @@ -272,13 +301,11 @@ func (s *testAggFuncSuit) TestBitOr(c *C) { err = dec.FromString([]byte("16.00")) c.Assert(err, IsNil) - row = types.MakeDatums(&dec) err = bitOrFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) c.Assert(err, IsNil) result = bitOrFunc.GetResult(evalCtx) c.Assert(result.GetUint64(), Equals, uint64(31)) - } func (s *testAggFuncSuit) TestBitXor(c *C) { @@ -322,6 +349,38 @@ func (s *testAggFuncSuit) TestBitXor(c *C) { c.Assert(result.GetUint64(), Equals, uint64(1)) partialResult := bitXorFunc.GetPartialResult(evalCtx) c.Assert(partialResult[0].GetUint64(), Equals, uint64(1)) + + // test bit_xor( decimal ) + col.RetType = types.NewFieldType(mysql.TypeNewDecimal) + bitXorFunc.ResetContext(s.ctx.GetSessionVars().StmtCtx, evalCtx) + + result = bitXorFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(0)) + + var dec types.MyDecimal + err = dec.FromString([]byte("1.234")) + c.Assert(err, IsNil) + row = types.MakeDatums(&dec) + err = bitXorFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) + c.Assert(err, IsNil) + result = bitXorFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(1)) + + err = dec.FromString([]byte("1.012")) + c.Assert(err, IsNil) + row = types.MakeDatums(&dec) + err = bitXorFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) + c.Assert(err, IsNil) + result = bitXorFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(0)) + + err = dec.FromString([]byte("2.12345678")) + c.Assert(err, IsNil) + row = types.MakeDatums(&dec) + err = bitXorFunc.Update(evalCtx, s.ctx.GetSessionVars().StmtCtx, types.DatumRow(row)) + c.Assert(err, IsNil) + result = bitXorFunc.GetResult(evalCtx) + c.Assert(result.GetUint64(), Equals, uint64(2)) } func (s *testAggFuncSuit) TestCount(c *C) { diff --git a/expression/aggregation/bit_and.go b/expression/aggregation/bit_and.go index f64e5ae777a3f..b848df2cccd09 100644 --- a/expression/aggregation/bit_and.go +++ b/expression/aggregation/bit_and.go @@ -43,7 +43,15 @@ func (bf *bitAndFunction) Update(evalCtx *AggEvaluateContext, sc *stmtctx.Statem return errors.Trace(err) } if !value.IsNull() { - evalCtx.Value.SetUint64(evalCtx.Value.GetUint64() & value.GetUint64()) + if value.Kind() == types.KindUint64 { + evalCtx.Value.SetUint64(evalCtx.Value.GetUint64() & value.GetUint64()) + } else { + int64Value, err := value.ToInt64(sc) + if err != nil { + return errors.Trace(err) + } + evalCtx.Value.SetUint64(evalCtx.Value.GetUint64() & uint64(int64Value)) + } } return nil } diff --git a/expression/aggregation/bit_xor.go b/expression/aggregation/bit_xor.go index 9edec18581cc9..c8afc7b42f8d1 100644 --- a/expression/aggregation/bit_xor.go +++ b/expression/aggregation/bit_xor.go @@ -41,7 +41,15 @@ func (bf *bitXorFunction) Update(evalCtx *AggEvaluateContext, sc *stmtctx.Statem return errors.Trace(err) } if !value.IsNull() { - evalCtx.Value.SetUint64(evalCtx.Value.GetUint64() ^ value.GetUint64()) + if value.Kind() == types.KindUint64 { + evalCtx.Value.SetUint64(evalCtx.Value.GetUint64() ^ value.GetUint64()) + } else { + int64Value, err := value.ToInt64(sc) + if err != nil { + return errors.Trace(err) + } + evalCtx.Value.SetUint64(evalCtx.Value.GetUint64() ^ uint64(int64Value)) + } } return nil }