Skip to content

Commit

Permalink
cherry pick pingcap#36208 to release-5.2
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <[email protected]>
  • Loading branch information
ywqzzy authored and ti-srebot committed Jul 22, 2022
1 parent 5025a35 commit 8495ab7
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 0 deletions.
14 changes: 14 additions & 0 deletions executor/aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,11 +571,24 @@ func getGroupKey(ctx sessionctx.Context, input *chunk.Chunk, groupKey [][]byte,

for _, item := range groupByItems {
tp := item.GetType()

buf, err := expression.GetColumn(tp.EvalType(), numRows)
if err != nil {
return nil, err
}

// In strict sql mode like ‘STRICT_TRANS_TABLES’,can not insert an invalid enum value like 0.
// While in sql mode like '', can insert an invalid enum value like 0,
// then the enum value 0 will have the enum name '', which maybe conflict with user defined enum ''.
// Ref to issue #26885.
// This check is used to handle invalid enum name same with user defined enum name.
// Use enum value as groupKey instead of enum name.
if item.GetType().GetType() == mysql.TypeEnum {
newTp := *tp
newTp.AddFlag(mysql.EnumSetAsIntFlag)
tp = &newTp
}

if err := expression.EvalExpr(ctx, item, tp.EvalType(), input, buf); err != nil {
expression.PutColumn(buf)
return nil, err
Expand All @@ -586,6 +599,7 @@ func getGroupKey(ctx sessionctx.Context, input *chunk.Chunk, groupKey [][]byte,
newTp.Flen = 0
tp = &newTp
}

groupKey, err = codec.HashGroupKey(ctx.GetSessionVars().StmtCtx, input.NumRows(), buf, groupKey, tp)
if err != nil {
expression.PutColumn(buf)
Expand Down
147 changes: 147 additions & 0 deletions executor/aggregate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1529,3 +1529,150 @@ func (s *testSerialSuite) TestAggInDisk(c *C) {
tk.MustQuery("select /*+ HASH_AGG() */ count(c) from t;").Check(testkit.Rows("0"))
tk.MustQuery("select /*+ HASH_AGG() */ count(c) from t group by c1;").Check(testkit.Rows())
}
<<<<<<< HEAD
=======

func TestRandomPanicAggConsume(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@tidb_max_chunk_size=32")
tk.MustExec("set @@tidb_init_chunk_size=1")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int)")
for i := 0; i <= 1000; i++ {
tk.MustExec(fmt.Sprintf("insert into t values(%v),(%v),(%v)", i, i, i))
}

fpName := "github.com/pingcap/tidb/executor/ConsumeRandomPanic"
require.NoError(t, failpoint.Enable(fpName, "5%panic(\"ERROR 1105 (HY000): Out Of Memory Quota![conn_id=1]\")"))
defer func() {
require.NoError(t, failpoint.Disable(fpName))
}()

// Test 10 times panic for each AggExec.
var res sqlexec.RecordSet
for i := 1; i <= 10; i++ {
var err error
for err == nil {
// Test paralleled hash agg.
res, err = tk.Exec("select /*+ HASH_AGG() */ count(a) from t group by a")
if err == nil {
_, err = session.GetRows4Test(context.Background(), tk.Session(), res)
require.NoError(t, res.Close())
}
}
require.EqualError(t, err, "failpoint panic: ERROR 1105 (HY000): Out Of Memory Quota![conn_id=1]")

err = nil
for err == nil {
// Test unparalleled hash agg.
res, err = tk.Exec("select /*+ HASH_AGG() */ count(distinct a) from t")
if err == nil {
_, err = session.GetRows4Test(context.Background(), tk.Session(), res)
require.NoError(t, res.Close())
}
}
require.EqualError(t, err, "failpoint panic: ERROR 1105 (HY000): Out Of Memory Quota![conn_id=1]")

err = nil
for err == nil {
// Test stream agg.
res, err = tk.Exec("select /*+ STREAM_AGG() */ count(a) from t")
if err == nil {
_, err = session.GetRows4Test(context.Background(), tk.Session(), res)
require.NoError(t, res.Close())
}
}
require.EqualError(t, err, "failpoint panic: ERROR 1105 (HY000): Out Of Memory Quota![conn_id=1]")
}
}

func TestIssue35295(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t100")
// This bug only happens on partition prune mode = 'static'
tk.MustExec("set @@tidb_partition_prune_mode = 'static'")
tk.MustExec(`CREATE TABLE t100 (
ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
col1 int(10) NOT NULL DEFAULT '0' COMMENT 'test',
money bigint(20) NOT NULL COMMENT 'test',
logtime datetime NOT NULL COMMENT '记录时间',
PRIMARY KEY (ID,logtime)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 COMMENT='test'
PARTITION BY RANGE COLUMNS(logtime) (
PARTITION p20220608 VALUES LESS THAN ("20220609"),
PARTITION p20220609 VALUES LESS THAN ("20220610"),
PARTITION p20220610 VALUES LESS THAN ("20220611"),
PARTITION p20220611 VALUES LESS THAN ("20220612"),
PARTITION p20220612 VALUES LESS THAN ("20220613"),
PARTITION p20220613 VALUES LESS THAN ("20220614"),
PARTITION p20220614 VALUES LESS THAN ("20220615"),
PARTITION p20220615 VALUES LESS THAN ("20220616"),
PARTITION p20220616 VALUES LESS THAN ("20220617"),
PARTITION p20220617 VALUES LESS THAN ("20220618"),
PARTITION p20220618 VALUES LESS THAN ("20220619"),
PARTITION p20220619 VALUES LESS THAN ("20220620"),
PARTITION p20220620 VALUES LESS THAN ("20220621"),
PARTITION p20220621 VALUES LESS THAN ("20220622"),
PARTITION p20220622 VALUES LESS THAN ("20220623"),
PARTITION p20220623 VALUES LESS THAN ("20220624"),
PARTITION p20220624 VALUES LESS THAN ("20220625")
);`)
tk.MustExec("insert into t100(col1,money,logtime) values (100,10,'2022-06-09 00:00:00');")
tk.MustExec("insert into t100(col1,money,logtime) values (100,10,'2022-06-10 00:00:00');")
tk.MustQuery("SELECT /*+STREAM_AGG()*/ col1,sum(money) FROM t100 WHERE logtime>='2022-06-09 00:00:00' AND col1=100 ;").Check(testkit.Rows("100 20"))
tk.MustQuery("SELECT /*+HASH_AGG()*/ col1,sum(money) FROM t100 WHERE logtime>='2022-06-09 00:00:00' AND col1=100 ;").Check(testkit.Rows("100 20"))
}

// https://github.com/pingcap/tidb/issues/27751
func TestIssue27751(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table test.t(nname char(20));")
tk.MustExec("insert into test.t values ('2'),(null),('11'),('2'),(null),('2'),(null),('11'),('33');")
tk.MustExec("set @@group_concat_max_len=0;")
tk.MustQuery("select group_concat(nname order by 1 separator '#' ) from t;").Check(testkit.Rows("11#1"))
tk.MustQuery("select group_concat(nname order by 1 desc separator '#' ) from t;").Check(testkit.Rows("33#2"))
}

func TestIssue26885(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec(`SET sql_mode = 'NO_ENGINE_SUBSTITUTION';`)
tk.MustExec(`DROP TABLE IF EXISTS t1;`)

tk.MustExec("CREATE TABLE t1 (c1 ENUM('a', '', 'b'));")
tk.MustExec("INSERT INTO t1 (c1) VALUES ('b');")
tk.MustExec("INSERT INTO t1 (c1) VALUES ('');")
tk.MustExec("INSERT INTO t1 (c1) VALUES ('a');")
tk.MustExec("INSERT INTO t1 (c1) VALUES ('');")
tk.MustExec("INSERT INTO t1 (c1) VALUES (0);")
tk.MustQuery("select * from t1").Check(testkit.Rows("b", "", "a", "", ""))
tk.MustQuery("select c1 + 0 from t1").Check(testkit.Rows("3", "2", "1", "2", "0"))
tk.MustQuery("SELECT c1 + 0, COUNT(c1) FROM t1 GROUP BY c1 order by c1;").Check(testkit.Rows("0 1", "1 1", "2 2", "3 1"))

tk.MustExec("alter table t1 add index idx(c1); ")
tk.MustQuery("select c1 + 0 from t1").Check(testkit.Rows("3", "2", "1", "2", "0"))
tk.MustQuery("SELECT c1 + 0, COUNT(c1) FROM t1 GROUP BY c1 order by c1;").Check(testkit.Rows("0 1", "1 1", "2 2", "3 1"))

tk.MustExec(`DROP TABLE IF EXISTS t1;`)
tk.MustExec("CREATE TABLE t1 (c1 ENUM('a', 'b', 'c'));")
tk.MustExec("INSERT INTO t1 (c1) VALUES ('b');")
tk.MustExec("INSERT INTO t1 (c1) VALUES ('a');")
tk.MustExec("INSERT INTO t1 (c1) VALUES ('b');")
tk.MustExec("INSERT INTO t1 (c1) VALUES ('c');")
tk.MustExec("INSERT INTO t1 (c1) VALUES (0);")
tk.MustQuery("select * from t1").Check(testkit.Rows("b", "a", "b", "c", ""))
tk.MustQuery("SELECT c1 + 0, COUNT(c1) FROM t1 GROUP BY c1 order by c1;").Check(testkit.Rows("0 1", "1 1", "2 2", "3 1"))
}
>>>>>>> 065563a8e... executor: fix aggregating enum zero value gets different results from mysql (#36208)

0 comments on commit 8495ab7

Please sign in to comment.