Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner: fix unique key get wrong row count when to query the NULL value | tidb-test=pr/2476 #56277

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions statistics/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,10 @@ func (idx *Index) GetRowCount(sctx sessionctx.Context, coll *HistColl, indexRang
if fullLen {
// At most 1 in this case.
if idx.Info.Unique {
totalCount++
continue
if !indexRange.IsOnlyNull() {
totalCount++
continue
}
}
count = idx.equalRowCount(lb, realtimeRowCount)
// If the current table row count has changed, we should scale the row count accordingly.
Expand Down
15 changes: 15 additions & 0 deletions statistics/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -808,3 +808,18 @@ func TestIssue49986(t *testing.T) {
" └─Selection 10.00 cop[tikv] eq(\"astp2019121731703151\", test.acc.m)",
" └─TableFullScan 10000.00 cop[tikv] table:b keep order:false, stats:pseudo"))
}

func TestIssue56116(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")

tk.MustExec("create table t2(id bigint(20) DEFAULT NULL, UNIQUE KEY index_on_id (id))")
tk.MustExec("insert into t2 values (), (), ()")
tk.MustExec("analyze table t2")
tk.MustQuery("explain select count(*) from t2 where id is null;").Check(testkit.Rows(
"StreamAgg_17 1.00 root funcs:count(Column#5)->Column#3",
"└─IndexReader_18 1.00 root index:StreamAgg_9",
" └─StreamAgg_9 1.00 cop[tikv] funcs:count(1)->Column#5",
" └─IndexRangeScan_16 3.00 cop[tikv] table:t2, index:index_on_id(id) range:[NULL,NULL], keep order:false"))
}
12 changes: 12 additions & 0 deletions util/ranger/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,18 @@ func (ran *Range) isPoint(stmtCtx *stmtctx.StatementContext, regardNullAsPoint b
return !ran.LowExclude && !ran.HighExclude
}

// IsOnlyNull checks if the range has [NULL, NULL] or [NULL NULL, NULL NULL] range.
func (ran *Range) IsOnlyNull() bool {
for i := range ran.LowVal {
a := ran.LowVal[i]
b := ran.HighVal[i]
if !(a.IsNull() && b.IsNull()) {
return false
}
}
return true
}

// IsPointNonNullable returns if the range is a point without NULL.
func (ran *Range) IsPointNonNullable(sctx sessionctx.Context) bool {
return ran.isPoint(sctx.GetSessionVars().StmtCtx, false)
Expand Down