From 2e1606d2c0670612de2123fc7a36be6fedb699f2 Mon Sep 17 00:00:00 2001 From: Haibin Xie Date: Mon, 11 Nov 2019 17:34:59 +0800 Subject: [PATCH] stats: fix panic when fast analyze on empty table (#13284) (#13343) --- 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 4cbee01c0df48..e202fcbed6825 100644 --- a/executor/analyze.go +++ b/executor/analyze.go @@ -1081,7 +1081,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 b53d5545a560b..8f874ef4f31ee 100644 --- a/executor/analyze_test.go +++ b/executor/analyze_test.go @@ -238,6 +238,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.