Skip to content

Commit

Permalink
*: fix panic when mergeGlobalStats for newly-added index or column (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
chrysan authored May 31, 2022
1 parent 2c3f717 commit b24ef9a
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 4 deletions.
80 changes: 80 additions & 0 deletions executor/analyze_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3282,3 +3282,83 @@ PARTITION BY RANGE ( a ) (
require.Greater(t, tbl.Version, lastVersion)
require.Equal(t, 2, len(tbl.Indices[tableInfo.Indices[0].ID].Buckets))
}

func TestIssue35056(t *testing.T) {
store, dom, clean := testkit.CreateMockStoreAndDomain(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_analyze_version = 1")
createTable := `CREATE TABLE t (id int, a int, b varchar(10))
PARTITION BY RANGE ( id ) (
PARTITION p0 VALUES LESS THAN (10),
PARTITION p1 VALUES LESS THAN (20)
)`
tk.MustExec(createTable)
tk.MustExec("set @@session.tidb_partition_prune_mode = 'static'")
tk.MustExec("insert into t values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(7,7,7),(9,9,9)")
tk.MustExec("insert into t values (11,11,11),(12,12,12),(14,14,14)")
h := dom.StatsHandle()
oriLease := h.Lease()
h.SetLease(1)
defer func() {
h.SetLease(oriLease)
}()
is := dom.InfoSchema()
h.HandleAutoAnalyze(is)
tk.MustExec("create index idxa on t (a)")
tk.MustExec("create index idxb on t (b)")
table, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
require.NoError(t, err)
tableInfo := table.Meta()
pi := tableInfo.GetPartitionInfo()
require.NotNil(t, pi)
tk.MustExec("analyze table t partition p0 index idxa")
tk.MustExec("analyze table t partition p1 index idxb")
tk.MustExec("set @@session.tidb_partition_prune_mode = 'dynamic'")
tk.MustExec("analyze table t partition p0")
tk.MustQuery("show warnings").Sort().Check(testkit.Rows(
"Warning 8244 Build table: `t` column: `id` global-level stats failed due to missing partition-level column stats, please run analyze table to refresh columns of all partitions",
"Warning 8244 Build table: `t` index: `idxa` global-level stats failed due to missing partition-level column stats, please run analyze table to refresh columns of all partitions",
))
}

func TestIssue35056Related(t *testing.T) {
store, dom, clean := testkit.CreateMockStoreAndDomain(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_analyze_version = 2")
createTable := `CREATE TABLE t (id int)
PARTITION BY RANGE ( id ) (
PARTITION p0 VALUES LESS THAN (10),
PARTITION p1 VALUES LESS THAN (20)
)`
tk.MustExec(createTable)
tk.MustExec("set @@session.tidb_partition_prune_mode = 'static'")
tk.MustExec("insert into t values (1),(2),(3),(4),(7),(9)")
tk.MustExec("insert into t values (11),(12),(14)")
h := dom.StatsHandle()
oriLease := h.Lease()
h.SetLease(1)
defer func() {
h.SetLease(oriLease)
}()
is := dom.InfoSchema()
h.HandleAutoAnalyze(is)
tk.MustExec("alter table t add column a int")
tk.MustExec("alter table t add column b int")
table, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
require.NoError(t, err)
tableInfo := table.Meta()
pi := tableInfo.GetPartitionInfo()
require.NotNil(t, pi)
tk.MustExec("analyze table t partition p0 columns id,a")
tk.MustExec("analyze table t partition p1 columns id,b")
tk.MustExec("set @@session.tidb_partition_prune_mode = 'dynamic'")
tk.MustExec("analyze table t partition p0")
tk.MustQuery("show warnings").Sort().Check(testkit.Rows(
"Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t's partition p0",
"Warning 8244 Build table: `t` column: `a` global-level stats failed due to missing partition-level column stats, please run analyze table to refresh columns of all partitions",
))
}
14 changes: 10 additions & 4 deletions statistics/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,17 @@ func (t *Table) ColumnByName(colName string) *Column {
// GetStatsInfo returns their statistics according to the ID of the column or index, including histogram, CMSketch, TopN and FMSketch.
func (t *Table) GetStatsInfo(ID int64, isIndex bool) (int64, *Histogram, *CMSketch, *TopN, *FMSketch) {
if isIndex {
idxStatsInfo := t.Indices[ID]
return int64(idxStatsInfo.TotalRowCount()), idxStatsInfo.Histogram.Copy(), idxStatsInfo.CMSketch.Copy(), idxStatsInfo.TopN.Copy(), idxStatsInfo.FMSketch.Copy()
if idxStatsInfo, ok := t.Indices[ID]; ok {
return int64(idxStatsInfo.TotalRowCount()), idxStatsInfo.Histogram.Copy(), idxStatsInfo.CMSketch.Copy(), idxStatsInfo.TopN.Copy(), idxStatsInfo.FMSketch.Copy()
}
// newly added index which is not analyzed yet
return 0, nil, nil, nil, nil
}
if colStatsInfo, ok := t.Columns[ID]; ok {
return int64(colStatsInfo.TotalRowCount()), colStatsInfo.Histogram.Copy(), colStatsInfo.CMSketch.Copy(), colStatsInfo.TopN.Copy(), colStatsInfo.FMSketch.Copy()
}
colStatsInfo := t.Columns[ID]
return int64(colStatsInfo.TotalRowCount()), colStatsInfo.Histogram.Copy(), colStatsInfo.CMSketch.Copy(), colStatsInfo.TopN.Copy(), colStatsInfo.FMSketch.Copy()
// newly added column which is not analyzed yet
return 0, nil, nil, nil, nil
}

// GetColRowCount tries to get the row count of the a column if possible.
Expand Down

0 comments on commit b24ef9a

Please sign in to comment.