From 61870e5fa1afd15852e65dbd8faa73e8d6100a90 Mon Sep 17 00:00:00 2001 From: Haibin Xie Date: Mon, 11 Nov 2019 14:54:44 +0800 Subject: [PATCH] stats: fix panic when fast analyze on empty table (#13284) (#13344) --- executor/analyze.go | 4 +++- executor/analyze_test.go | 2 ++ statistics/cmsketch.go | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/executor/analyze.go b/executor/analyze.go index eb6f5c17a5818..8a4c8227125b7 100644 --- a/executor/analyze.go +++ b/executor/analyze.go @@ -1089,7 +1089,9 @@ func (e *AnalyzeFastExec) runTasks() ([]*statistics.Histogram, []*statistics.CMS sort.Slice(collector.Samples, func(i, j int) bool { return collector.Samples[i].RowID < collector.Samples[j].RowID }) collector.CalcTotalSize() // Scale the total column size. - collector.TotalSize *= rowCount / int64(len(collector.Samples)) + if len(collector.Samples) > 0 { + collector.TotalSize *= rowCount / int64(len(collector.Samples)) + } if i < hasPKInfo { hists[i], cms[i], err = e.buildColumnStats(e.pkInfo.ID, e.collectors[i], &e.pkInfo.FieldType, rowCount) } else if i < hasPKInfo+len(e.colsInfo) { diff --git a/executor/analyze_test.go b/executor/analyze_test.go index 5eb773cb3880b..a2af202958445 100644 --- a/executor/analyze_test.go +++ b/executor/analyze_test.go @@ -247,6 +247,8 @@ func (s *testSuite1) TestFastAnalyze(c *C) { tk.MustExec("create table t(a int primary key, b int, c char(10), index index_b(b))") tk.MustExec("set @@session.tidb_enable_fast_analyze=1") tk.MustExec("set @@session.tidb_build_stats_concurrency=1") + // Should not panic. + tk.MustExec("analyze table t") tblInfo, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) c.Assert(err, IsNil) tid := tblInfo.Meta().ID diff --git a/statistics/cmsketch.go b/statistics/cmsketch.go index 9473ae616d427..728db838e8382 100644 --- a/statistics/cmsketch.go +++ b/statistics/cmsketch.go @@ -111,6 +111,9 @@ func newTopNHelper(sample [][]byte, numTop uint32) *topNHelper { // NewCMSketchWithTopN returns a new CM sketch with TopN elements, the estimate NDV and the scale ratio. func NewCMSketchWithTopN(d, w int32, sample [][]byte, numTop uint32, rowCount uint64) (*CMSketch, uint64, uint64) { + if rowCount == 0 || len(sample) == 0 { + return nil, 0, 0 + } helper := newTopNHelper(sample, numTop) // rowCount is not a accurate value when fast analyzing // In some cases, if user triggers fast analyze when rowCount is close to sampleSize, unexpected bahavior might happen.