From 1fd15526d7f476734cb29ae81bc3832f3bd60840 Mon Sep 17 00:00:00 2001 From: Reminiscent Date: Thu, 26 Mar 2020 20:26:16 +0800 Subject: [PATCH 1/6] executor: check for null values when comparing different groups during streamAgg --- executor/aggregate.go | 96 +++++++++++++++++++++++++++++++------- executor/aggregate_test.go | 10 ++++ 2 files changed, 88 insertions(+), 18 deletions(-) diff --git a/executor/aggregate.go b/executor/aggregate.go index d46cb7da67ddd..a05a16136c2c3 100644 --- a/executor/aggregate.go +++ b/executor/aggregate.go @@ -1128,8 +1128,16 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - firstRowDatum.SetInt64(vals[0]) - lastRowDatum.SetInt64(vals[numRows-1]) + if col.IsNull(0) { + firstRowDatum.SetNull() + } else { + firstRowDatum.SetInt64(vals[0]) + } + if col.IsNull(numRows - 1) { + lastRowDatum.SetNull() + } else { + lastRowDatum.SetInt64(vals[numRows-1]) + } case types.ETReal: vals := col.Float64s() for i := 1; i < numRows; i++ { @@ -1144,8 +1152,16 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - firstRowDatum.SetFloat64(vals[0]) - lastRowDatum.SetFloat64(vals[numRows-1]) + if col.IsNull(0) { + firstRowDatum.SetNull() + } else { + firstRowDatum.SetFloat64(vals[0]) + } + if col.IsNull(numRows - 1) { + lastRowDatum.SetNull() + } else { + lastRowDatum.SetFloat64(vals[numRows-1]) + } case types.ETDecimal: vals := col.Decimals() for i := 1; i < numRows; i++ { @@ -1160,10 +1176,20 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - // make a copy to avoid DATA RACE - firstDatum, lastDatum := vals[0], vals[numRows-1] - firstRowDatum.SetMysqlDecimal(&firstDatum) - lastRowDatum.SetMysqlDecimal(&lastDatum) + if col.IsNull(0) { + firstRowDatum.SetNull() + } else { + // make a copy to avoid DATA RACE + firstDatum := vals[0] + firstRowDatum.SetMysqlDecimal(&firstDatum) + } + if col.IsNull(numRows - 1) { + lastRowDatum.SetNull() + } else { + // make a copy to avoid DATA RACE + lastDatum := vals[numRows-1] + lastRowDatum.SetMysqlDecimal(&lastDatum) + } case types.ETDatetime, types.ETTimestamp: vals := col.Times() for i := 1; i < numRows; i++ { @@ -1178,8 +1204,16 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - firstRowDatum.SetMysqlTime(vals[0]) - lastRowDatum.SetMysqlTime(vals[numRows-1]) + if col.IsNull(0) { + firstRowDatum.SetNull() + } else { + firstRowDatum.SetMysqlTime(vals[0]) + } + if col.IsNull(numRows - 1) { + lastRowDatum.SetNull() + } else { + lastRowDatum.SetMysqlTime(vals[numRows-1]) + } case types.ETDuration: vals := col.GoDurations() for i := 1; i < numRows; i++ { @@ -1194,8 +1228,16 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - firstRowDatum.SetMysqlDuration(types.Duration{Duration: vals[0], Fsp: int8(item.GetType().Decimal)}) - lastRowDatum.SetMysqlDuration(types.Duration{Duration: vals[numRows-1], Fsp: int8(item.GetType().Decimal)}) + if col.IsNull(0) { + firstRowDatum.SetNull() + } else { + firstRowDatum.SetMysqlDuration(types.Duration{Duration: vals[0], Fsp: int8(item.GetType().Decimal)}) + } + if col.IsNull(numRows - 1) { + lastRowDatum.SetNull() + } else { + lastRowDatum.SetMysqlDuration(types.Duration{Duration: vals[numRows-1], Fsp: int8(item.GetType().Decimal)}) + } case types.ETJson: previousKey := col.GetJSON(0) for i := 1; i < numRows; i++ { @@ -1209,9 +1251,18 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express previousKey = key previousIsNull = isNull } - // make a copy to avoid DATA RACE - firstRowDatum.SetMysqlJSON(col.GetJSON(0).Copy()) - lastRowDatum.SetMysqlJSON(col.GetJSON(numRows - 1).Copy()) + if col.IsNull(0) { + firstRowDatum.SetNull() + } else { + // make a copy to avoid DATA RACE + firstRowDatum.SetMysqlJSON(col.GetJSON(0).Copy()) + } + if col.IsNull(numRows - 1) { + lastRowDatum.SetNull() + } else { + // make a copy to avoid DATA RACE + lastRowDatum.SetMysqlJSON(col.GetJSON(numRows - 1).Copy()) + } case types.ETString: previousKey := codec.ConvertByCollationStr(col.GetString(0), tp) for i := 1; i < numRows; i++ { @@ -1225,9 +1276,18 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express previousKey = key previousIsNull = isNull } - // don't use col.GetString since it will cause DATA RACE - firstRowDatum.SetString(string(col.GetBytes(0)), tp.Collate) - lastRowDatum.SetString(string(col.GetBytes(numRows-1)), tp.Collate) + if col.IsNull(0) { + firstRowDatum.SetNull() + } else { + // don't use col.GetString since it will cause DATA RACE + firstRowDatum.SetString(string(col.GetBytes(0)), tp.Collate) + } + if col.IsNull(numRows - 1) { + lastRowDatum.SetNull() + } else { + // don't use col.GetString since it will cause DATA RACE + lastRowDatum.SetString(string(col.GetBytes(numRows-1)), tp.Collate) + } default: err = errors.New(fmt.Sprintf("invalid eval type %v", eType)) } diff --git a/executor/aggregate_test.go b/executor/aggregate_test.go index 12fbc9700cc3a..0d9204302a1ef 100644 --- a/executor/aggregate_test.go +++ b/executor/aggregate_test.go @@ -844,3 +844,13 @@ func (s *testSuiteAgg) TestPR15242ShallowCopy(c *C) { tk.MustQuery(`select max(JSON_EXTRACT(a, '$.score')) as max_score,JSON_EXTRACT(a,'$.id') as id from t group by id order by id;`).Check(testkit.Rows("233 1", "233 2", "233 3")) } + +func (s *testSuiteAgg) TestIssue15690(c *C) { + tk := testkit.NewTestKitWithInit(c, s.store) + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a int);`) + tk.MustExec(`insert into t values(null),(null);`) + tk.MustExec(`insert into t values(0),(2),(2),(4),(8);`) + tk.Se.GetSessionVars().MaxChunkSize = 2 + tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "0", "2", "4", "8")) +} From 5371cee7e0b9be49551a765919646ef98f363797 Mon Sep 17 00:00:00 2001 From: Reminiscent Date: Fri, 27 Mar 2020 14:42:05 +0800 Subject: [PATCH 2/6] add more tests --- executor/aggregate.go | 19 ++++++++++--- executor/aggregate_test.go | 37 ++++++++++++++++++++++++- executor/executor_required_rows_test.go | 36 +++++++++++++++++++++--- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/executor/aggregate.go b/executor/aggregate.go index a05a16136c2c3..df13cbada6c77 100644 --- a/executor/aggregate.go +++ b/executor/aggregate.go @@ -1239,16 +1239,27 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express lastRowDatum.SetMysqlDuration(types.Duration{Duration: vals[numRows-1], Fsp: int8(item.GetType().Decimal)}) } case types.ETJson: - previousKey := col.GetJSON(0) + var previousKey, key json.BinaryJSON + if !previousIsNull { + previousKey = col.GetJSON(0) + } for i := 1; i < numRows; i++ { - key := col.GetJSON(i) isNull := col.IsNull(i) + if !isNull { + key = col.GetJSON(i) + } if e.sameGroup[i] { - if isNull != previousIsNull || json.CompareBinary(previousKey, key) != 0 { + if isNull == previousIsNull { + if !isNull && json.CompareBinary(previousKey, key) != 0 { + e.sameGroup[i] = false + } + } else { e.sameGroup[i] = false } } - previousKey = key + if !isNull { + previousKey = key + } previousIsNull = isNull } if col.IsNull(0) { diff --git a/executor/aggregate_test.go b/executor/aggregate_test.go index 0d9204302a1ef..21ae2b373ace7 100644 --- a/executor/aggregate_test.go +++ b/executor/aggregate_test.go @@ -847,10 +847,45 @@ func (s *testSuiteAgg) TestPR15242ShallowCopy(c *C) { func (s *testSuiteAgg) TestIssue15690(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) + tk.Se.GetSessionVars().MaxChunkSize = 2 + // check for INT type tk.MustExec(`drop table if exists t;`) tk.MustExec(`create table t(a int);`) tk.MustExec(`insert into t values(null),(null);`) tk.MustExec(`insert into t values(0),(2),(2),(4),(8);`) - tk.Se.GetSessionVars().MaxChunkSize = 2 tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "0", "2", "4", "8")) + + // check for FLOAT type + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a float);`) + tk.MustExec(`insert into t values(null),(null),(null),(null);`) + tk.MustExec(`insert into t values(1.1),(1.1);`) + tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "1.1")) + + // check for DECIMAL type + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a decimal(5,1));`) + tk.MustExec(`insert into t values(null),(null),(null);`) + tk.MustExec(`insert into t values(1.1),(2.2),(2.2);`) + tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "1.1", "2.2")) + + // check for DATETIME type + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a datetime);`) + tk.MustExec(`insert into t values(null);`) + tk.MustExec(`insert into t values("2019-03-20 21:50:00"),("2019-03-20 21:50:01"), ("2019-03-20 21:50:00");`) + tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "2019-03-20 21:50:00", "2019-03-20 21:50:01")) + + // check for JSON type + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a json);`) + tk.MustExec(`insert into t values(null),(null),(null),(null);`) + tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("")) + + // check for char type + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`create table t(a char);`) + tk.MustExec(`insert into t values(null),(null),(null),(null);`) + tk.MustExec(`insert into t values('a'),('b');`) + tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "a", "b")) } diff --git a/executor/executor_required_rows_test.go b/executor/executor_required_rows_test.go index 367f4d9426a47..2b6177c97dd7d 100644 --- a/executor/executor_required_rows_test.go +++ b/executor/executor_required_rows_test.go @@ -711,7 +711,7 @@ func (s *testExecSuite) TestMergeJoinRequiredRows(c *C) { } } -func genTestChunk4VecGroupChecker(chkRows []int, sameNum int) (expr []expression.Expression, inputs []*chunk.Chunk) { +func genTestChunk4VecGroupChecker(chkRows []int, sameNum int, haveNull bool) (expr []expression.Expression, inputs []*chunk.Chunk) { chkNum := len(chkRows) inputs = make([]*chunk.Chunk, chkNum) fts := make([]*types.FieldType, 1) @@ -721,7 +721,12 @@ func genTestChunk4VecGroupChecker(chkRows []int, sameNum int) (expr []expression } cnt := 0 - val := 0 + var val int64 + if haveNull { + val = -1 + } else { + val = 0 + } for i := 0; i < chkNum; i++ { col := inputs[i].Column(0) col.ResizeInt64(chkRows[i], false) @@ -731,7 +736,11 @@ func genTestChunk4VecGroupChecker(chkRows []int, sameNum int) (expr []expression val++ cnt = 0 } - i64s[j] = int64(val) + if val == -1 { + col.SetNull(j, true) + } else { + i64s[j] = val + } cnt++ } } @@ -750,36 +759,55 @@ func (s *testExecSuite) TestVecGroupChecker(c *C) { expectedGroups int expectedFlag []bool sameNum int + haveNull bool }{ { chunkRows: []int{1024, 1}, expectedGroups: 1025, expectedFlag: []bool{false, false}, sameNum: 1, + haveNull: false, }, { chunkRows: []int{1024, 1}, expectedGroups: 1, expectedFlag: []bool{false, true}, sameNum: 1025, + haveNull: false, }, { chunkRows: []int{1, 1}, expectedGroups: 1, expectedFlag: []bool{false, true}, sameNum: 2, + haveNull: false, }, { chunkRows: []int{1, 1}, expectedGroups: 2, expectedFlag: []bool{false, false}, sameNum: 1, + haveNull: false, + }, + { + chunkRows: []int{2, 2}, + expectedGroups: 2, + expectedFlag: []bool{false, false}, + sameNum: 2, + haveNull: true, + }, + { + chunkRows: []int{2, 2}, + expectedGroups: 1, + expectedFlag: []bool{false, true}, + sameNum: 4, + haveNull: true, }, } ctx := mock.NewContext() for _, testCase := range testCases { - expr, inputChks := genTestChunk4VecGroupChecker(testCase.chunkRows, testCase.sameNum) + expr, inputChks := genTestChunk4VecGroupChecker(testCase.chunkRows, testCase.sameNum, testCase.haveNull) groupChecker := newVecGroupChecker(ctx, expr) groupNum := 0 for i, inputChk := range inputChks { From a11b2efd7ed4d28b8f83468ff498f7c01e7f84d0 Mon Sep 17 00:00:00 2001 From: Reminiscent Date: Fri, 27 Mar 2020 15:15:39 +0800 Subject: [PATCH 3/6] clean the code --- executor/aggregate.go | 65 +++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/executor/aggregate.go b/executor/aggregate.go index df13cbada6c77..35df9e0a52aa9 100644 --- a/executor/aggregate.go +++ b/executor/aggregate.go @@ -1111,8 +1111,15 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express return err } - previousIsNull := col.IsNull(0) var firstRowDatum, lastRowDatum types.Datum + firstRowIsNull, lastRowIsNull := col.IsNull(0), col.IsNull(numRows-1) + if firstRowIsNull { + firstRowDatum.SetNull() + } + if lastRowIsNull { + lastRowDatum.SetNull() + } + previousIsNull := firstRowIsNull switch eType { case types.ETInt: vals := col.Int64s() @@ -1128,14 +1135,10 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - if col.IsNull(0) { - firstRowDatum.SetNull() - } else { + if !firstRowIsNull { firstRowDatum.SetInt64(vals[0]) } - if col.IsNull(numRows - 1) { - lastRowDatum.SetNull() - } else { + if !lastRowIsNull { lastRowDatum.SetInt64(vals[numRows-1]) } case types.ETReal: @@ -1152,14 +1155,10 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - if col.IsNull(0) { - firstRowDatum.SetNull() - } else { + if !firstRowIsNull { firstRowDatum.SetFloat64(vals[0]) } - if col.IsNull(numRows - 1) { - lastRowDatum.SetNull() - } else { + if !lastRowIsNull { lastRowDatum.SetFloat64(vals[numRows-1]) } case types.ETDecimal: @@ -1176,16 +1175,12 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - if col.IsNull(0) { - firstRowDatum.SetNull() - } else { + if !firstRowIsNull { // make a copy to avoid DATA RACE firstDatum := vals[0] firstRowDatum.SetMysqlDecimal(&firstDatum) } - if col.IsNull(numRows - 1) { - lastRowDatum.SetNull() - } else { + if !lastRowIsNull { // make a copy to avoid DATA RACE lastDatum := vals[numRows-1] lastRowDatum.SetMysqlDecimal(&lastDatum) @@ -1204,14 +1199,10 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - if col.IsNull(0) { - firstRowDatum.SetNull() - } else { + if !firstRowIsNull { firstRowDatum.SetMysqlTime(vals[0]) } - if col.IsNull(numRows - 1) { - lastRowDatum.SetNull() - } else { + if !lastRowIsNull { lastRowDatum.SetMysqlTime(vals[numRows-1]) } case types.ETDuration: @@ -1228,14 +1219,10 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - if col.IsNull(0) { - firstRowDatum.SetNull() - } else { + if !firstRowIsNull { firstRowDatum.SetMysqlDuration(types.Duration{Duration: vals[0], Fsp: int8(item.GetType().Decimal)}) } - if col.IsNull(numRows - 1) { - lastRowDatum.SetNull() - } else { + if !lastRowIsNull { lastRowDatum.SetMysqlDuration(types.Duration{Duration: vals[numRows-1], Fsp: int8(item.GetType().Decimal)}) } case types.ETJson: @@ -1262,15 +1249,11 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } previousIsNull = isNull } - if col.IsNull(0) { - firstRowDatum.SetNull() - } else { + if !firstRowIsNull { // make a copy to avoid DATA RACE firstRowDatum.SetMysqlJSON(col.GetJSON(0).Copy()) } - if col.IsNull(numRows - 1) { - lastRowDatum.SetNull() - } else { + if !lastRowIsNull { // make a copy to avoid DATA RACE lastRowDatum.SetMysqlJSON(col.GetJSON(numRows - 1).Copy()) } @@ -1287,15 +1270,11 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express previousKey = key previousIsNull = isNull } - if col.IsNull(0) { - firstRowDatum.SetNull() - } else { + if !firstRowIsNull { // don't use col.GetString since it will cause DATA RACE firstRowDatum.SetString(string(col.GetBytes(0)), tp.Collate) } - if col.IsNull(numRows - 1) { - lastRowDatum.SetNull() - } else { + if !lastRowIsNull { // don't use col.GetString since it will cause DATA RACE lastRowDatum.SetString(string(col.GetBytes(numRows-1)), tp.Collate) } From e23ea12344132dbd3fb8824871096b6954df5f9f Mon Sep 17 00:00:00 2001 From: Reminiscent Date: Fri, 27 Mar 2020 15:27:48 +0800 Subject: [PATCH 4/6] clean the test code --- executor/executor_required_rows_test.go | 33 ++++++++++++------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/executor/executor_required_rows_test.go b/executor/executor_required_rows_test.go index 2b6177c97dd7d..56527396346a9 100644 --- a/executor/executor_required_rows_test.go +++ b/executor/executor_required_rows_test.go @@ -711,32 +711,38 @@ func (s *testExecSuite) TestMergeJoinRequiredRows(c *C) { } } -func genTestChunk4VecGroupChecker(chkRows []int, sameNum int, haveNull bool) (expr []expression.Expression, inputs []*chunk.Chunk) { +func genTestChunk4VecGroupChecker(chkRows []int, sameNum int) (expr []expression.Expression, inputs []*chunk.Chunk) { chkNum := len(chkRows) + numRows := 0 inputs = make([]*chunk.Chunk, chkNum) fts := make([]*types.FieldType, 1) fts[0] = types.NewFieldType(mysql.TypeLonglong) for i := 0; i < chkNum; i++ { inputs[i] = chunk.New(fts, chkRows[i], chkRows[i]) + numRows += chkRows[i] } - - cnt := 0 - var val int64 - if haveNull { - val = -1 + var numGroups int + if numRows%sameNum == 0 { + numGroups = numRows / sameNum } else { - val = 0 + numGroups = numRows/sameNum + 1 } + + rand.Seed(time.Now().Unix()) + nullPos := rand.Intn(numGroups) + cnt := 0 + val := rand.Int63() for i := 0; i < chkNum; i++ { col := inputs[i].Column(0) col.ResizeInt64(chkRows[i], false) i64s := col.Int64s() for j := 0; j < chkRows[i]; j++ { if cnt == sameNum { - val++ + val = rand.Int63() cnt = 0 + nullPos-- } - if val == -1 { + if nullPos == 0 { col.SetNull(j, true) } else { i64s[j] = val @@ -759,55 +765,48 @@ func (s *testExecSuite) TestVecGroupChecker(c *C) { expectedGroups int expectedFlag []bool sameNum int - haveNull bool }{ { chunkRows: []int{1024, 1}, expectedGroups: 1025, expectedFlag: []bool{false, false}, sameNum: 1, - haveNull: false, }, { chunkRows: []int{1024, 1}, expectedGroups: 1, expectedFlag: []bool{false, true}, sameNum: 1025, - haveNull: false, }, { chunkRows: []int{1, 1}, expectedGroups: 1, expectedFlag: []bool{false, true}, sameNum: 2, - haveNull: false, }, { chunkRows: []int{1, 1}, expectedGroups: 2, expectedFlag: []bool{false, false}, sameNum: 1, - haveNull: false, }, { chunkRows: []int{2, 2}, expectedGroups: 2, expectedFlag: []bool{false, false}, sameNum: 2, - haveNull: true, }, { chunkRows: []int{2, 2}, expectedGroups: 1, expectedFlag: []bool{false, true}, sameNum: 4, - haveNull: true, }, } ctx := mock.NewContext() for _, testCase := range testCases { - expr, inputChks := genTestChunk4VecGroupChecker(testCase.chunkRows, testCase.sameNum, testCase.haveNull) + expr, inputChks := genTestChunk4VecGroupChecker(testCase.chunkRows, testCase.sameNum) groupChecker := newVecGroupChecker(ctx, expr) groupNum := 0 for i, inputChk := range inputChks { From bf95bf72f05c83c5568cc14262380b33e3d7cb97 Mon Sep 17 00:00:00 2001 From: Reminiscent Date: Fri, 27 Mar 2020 16:25:48 +0800 Subject: [PATCH 5/6] address comment --- executor/aggregate_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/executor/aggregate_test.go b/executor/aggregate_test.go index 21ae2b373ace7..3a9b58ee7790d 100644 --- a/executor/aggregate_test.go +++ b/executor/aggregate_test.go @@ -854,6 +854,8 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`insert into t values(null),(null);`) tk.MustExec(`insert into t values(0),(2),(2),(4),(8);`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "0", "2", "4", "8")) + tk.MustQuery("show warnings;") + c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) // check for FLOAT type tk.MustExec(`drop table if exists t;`) @@ -861,6 +863,8 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`insert into t values(null),(null),(null),(null);`) tk.MustExec(`insert into t values(1.1),(1.1);`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "1.1")) + tk.MustQuery("show warnings;") + c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) // check for DECIMAL type tk.MustExec(`drop table if exists t;`) @@ -868,6 +872,8 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`insert into t values(null),(null),(null);`) tk.MustExec(`insert into t values(1.1),(2.2),(2.2);`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "1.1", "2.2")) + tk.MustQuery("show warnings;") + c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) // check for DATETIME type tk.MustExec(`drop table if exists t;`) @@ -875,12 +881,16 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`insert into t values(null);`) tk.MustExec(`insert into t values("2019-03-20 21:50:00"),("2019-03-20 21:50:01"), ("2019-03-20 21:50:00");`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "2019-03-20 21:50:00", "2019-03-20 21:50:01")) + tk.MustQuery("show warnings;") + c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) // check for JSON type tk.MustExec(`drop table if exists t;`) tk.MustExec(`create table t(a json);`) tk.MustExec(`insert into t values(null),(null),(null),(null);`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("")) + tk.MustQuery("show warnings;") + c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) // check for char type tk.MustExec(`drop table if exists t;`) @@ -888,4 +898,6 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`insert into t values(null),(null),(null),(null);`) tk.MustExec(`insert into t values('a'),('b');`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "a", "b")) + tk.MustQuery("show warnings;") + c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) } From 0dca4bc1d362508c70d6077dff99501d4ca787fc Mon Sep 17 00:00:00 2001 From: Reminiscent Date: Fri, 27 Mar 2020 16:33:43 +0800 Subject: [PATCH 6/6] address comment --- executor/aggregate_test.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/executor/aggregate_test.go b/executor/aggregate_test.go index 3a9b58ee7790d..0219cdd0f5182 100644 --- a/executor/aggregate_test.go +++ b/executor/aggregate_test.go @@ -854,7 +854,6 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`insert into t values(null),(null);`) tk.MustExec(`insert into t values(0),(2),(2),(4),(8);`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "0", "2", "4", "8")) - tk.MustQuery("show warnings;") c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) // check for FLOAT type @@ -863,7 +862,6 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`insert into t values(null),(null),(null),(null);`) tk.MustExec(`insert into t values(1.1),(1.1);`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "1.1")) - tk.MustQuery("show warnings;") c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) // check for DECIMAL type @@ -872,7 +870,6 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`insert into t values(null),(null),(null);`) tk.MustExec(`insert into t values(1.1),(2.2),(2.2);`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "1.1", "2.2")) - tk.MustQuery("show warnings;") c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) // check for DATETIME type @@ -881,7 +878,6 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`insert into t values(null);`) tk.MustExec(`insert into t values("2019-03-20 21:50:00"),("2019-03-20 21:50:01"), ("2019-03-20 21:50:00");`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "2019-03-20 21:50:00", "2019-03-20 21:50:01")) - tk.MustQuery("show warnings;") c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) // check for JSON type @@ -889,7 +885,6 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`create table t(a json);`) tk.MustExec(`insert into t values(null),(null),(null),(null);`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("")) - tk.MustQuery("show warnings;") c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) // check for char type @@ -898,6 +893,5 @@ func (s *testSuiteAgg) TestIssue15690(c *C) { tk.MustExec(`insert into t values(null),(null),(null),(null);`) tk.MustExec(`insert into t values('a'),('b');`) tk.MustQuery(`select /*+ stream_agg() */ distinct * from t;`).Check(testkit.Rows("", "a", "b")) - tk.MustQuery("show warnings;") c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Equals, uint16(0)) }