Skip to content

Commit

Permalink
executor: group_concat aggr panic when session.group_concat_max_len i…
Browse files Browse the repository at this point in the history
…s small (#23131)
  • Loading branch information
guo-shaoge authored Mar 11, 2021
1 parent 32d54d2 commit b298b86
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 11 deletions.
31 changes: 20 additions & 11 deletions executor/aggfuncs/func_group_concat.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,11 @@ type topNRows struct {
currSize uint64
limitSize uint64
sepSize uint64
// If sep is truncated, we need to append part of sep to result.
// In the following example, session.group_concat_max_len is 10 and sep is '---'.
// ('---', 'ccc') should be poped from heap, so '-' should be appended to result.
// eg: 'aaa---bbb---ccc' -> 'aaa---bbb-'
isSepTruncated bool
}

func (h topNRows) Len() int {
Expand Down Expand Up @@ -349,6 +354,7 @@ func (h *topNRows) tryToAdd(row sortRow) (truncated bool, memDelta int64) {
memDelta -= GetDatumMemSize(dt)
}
heap.Pop(h)
h.isSepTruncated = true
}
}
return true, memDelta
Expand All @@ -369,10 +375,11 @@ func (h *topNRows) concat(sep string, truncated bool) string {
}
buffer.Write(row.buffer.Bytes())
}
if truncated && uint64(buffer.Len()) < h.limitSize {
// append the last separator, because the last separator may be truncated in tryToAdd.
if h.isSepTruncated {
buffer.WriteString(sep)
buffer.Truncate(int(h.limitSize))
if uint64(buffer.Len()) > h.limitSize {
buffer.Truncate(int(h.limitSize))
}
}
return buffer.String()
}
Expand Down Expand Up @@ -402,10 +409,11 @@ func (e *groupConcatOrder) AllocPartialResult() (pr PartialResult, memDelta int6
}
p := &partialResult4GroupConcatOrder{
topN: &topNRows{
desc: desc,
currSize: 0,
limitSize: e.maxLen,
sepSize: uint64(len(e.sep)),
desc: desc,
currSize: 0,
limitSize: e.maxLen,
sepSize: uint64(len(e.sep)),
isSepTruncated: false,
},
}
return PartialResult(p), DefPartialResult4GroupConcatOrderSize + DefTopNRowsSize
Expand Down Expand Up @@ -504,10 +512,11 @@ func (e *groupConcatDistinctOrder) AllocPartialResult() (pr PartialResult, memDe
valSet, setSize := set.NewStringSetWithMemoryUsage()
p := &partialResult4GroupConcatOrderDistinct{
topN: &topNRows{
desc: desc,
currSize: 0,
limitSize: e.maxLen,
sepSize: uint64(len(e.sep)),
desc: desc,
currSize: 0,
limitSize: e.maxLen,
sepSize: uint64(len(e.sep)),
isSepTruncated: false,
},
valSet: valSet,
}
Expand Down
17 changes: 17 additions & 0 deletions executor/aggregate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,23 @@ func (s *testSuiteAgg) TestGroupConcatAggr(c *C) {

// issue #9920
tk.MustQuery("select group_concat(123, null)").Check(testkit.Rows("<nil>"))

// issue #23129
tk.MustExec("drop table if exists t1;")
tk.MustExec("create table t1(cid int, sname varchar(100));")
tk.MustExec("insert into t1 values(1, 'Bob'), (1, 'Alice');")
tk.MustExec("insert into t1 values(3, 'Ace');")
tk.MustExec("set @@group_concat_max_len=5;")
rows := tk.MustQuery("select group_concat(sname order by sname) from t1 group by cid;")
rows.Check(testkit.Rows("Alice", "Ace"))

tk.MustExec("drop table if exists t1;")
tk.MustExec("create table t1(c1 varchar(10));")
tk.MustExec("insert into t1 values('0123456789');")
tk.MustExec("insert into t1 values('12345');")
tk.MustExec("set @@group_concat_max_len=8;")
rows = tk.MustQuery("select group_concat(c1 order by c1) from t1 group by c1;")
rows.Check(testkit.Rows("01234567", "12345"))
}

func (s *testSuiteAgg) TestSelectDistinct(c *C) {
Expand Down

0 comments on commit b298b86

Please sign in to comment.