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, expression: fix TableFullScan caused by extraHandleId not correctly found #45139

Merged
merged 3 commits into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
12 changes: 12 additions & 0 deletions expression/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"strings"
"unsafe"

"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/util/size"
)

Expand Down Expand Up @@ -237,6 +238,17 @@ func (s *Schema) MemoryUsage() (sum int64) {
return
}

// GetExtraHandleColumn gets the extra handle column.
func (s *Schema) GetExtraHandleColumn() *Column {
columnLen := len(s.Columns)
if columnLen > 0 && s.Columns[columnLen-1].ID == model.ExtraHandleID {
return s.Columns[columnLen-1]
} else if columnLen > 1 && s.Columns[columnLen-2].ID == model.ExtraHandleID {
return s.Columns[columnLen-2]
}
time-and-fate marked this conversation as resolved.
Show resolved Hide resolved
return nil
}

// MergeSchema will merge two schema into one schema. We shouldn't need to consider unique keys.
// That will be processed in build_key_info.go.
func MergeSchema(lSchema, rSchema *Schema) *Schema {
Expand Down
27 changes: 27 additions & 0 deletions planner/core/issuetest/planner_issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,30 @@ func TestIssue42732(t *testing.T) {
tk.MustExec("INSERT INTO t2 VALUES (1, 1)")
tk.MustQuery("SELECT one.a, one.b as b2 FROM t1 one ORDER BY (SELECT two.b FROM t2 two WHERE two.a = one.b)").Check(testkit.Rows("1 1"))
}

// https://github.com/pingcap/tidb/issues/45036
func TestIssue45036(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("CREATE TABLE ads_txn (\n" +
" `cusno` varchar(10) NOT NULL,\n" +
" `txn_dt` varchar(8) NOT NULL,\n" +
" `unn_trno` decimal(22,0) NOT NULL,\n" +
" `aml_cntpr_accno` varchar(64) DEFAULT NULL,\n" +
" `acpayr_accno` varchar(35) DEFAULT NULL,\n" +
" PRIMARY KEY (`cusno`,`txn_dt`,`unn_trno`) NONCLUSTERED\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n" +
"PARTITION BY LIST COLUMNS(`txn_dt`)\n" +
"(PARTITION `p20000101` VALUES IN ('20000101'),\n" +
"PARTITION `p20220101` VALUES IN ('20220101'),\n" +
"PARTITION `p20230516` VALUES IN ('20230516'))")
tk.MustExec("analyze table ads_txn")
time-and-fate marked this conversation as resolved.
Show resolved Hide resolved
tk.MustExec("set autocommit=OFF;")
tk.MustQuery("explain update ads_txn s set aml_cntpr_accno = trim(acpayr_accno) where s._tidb_rowid between 1 and 100000;").Check(testkit.Rows(
"Update_5 N/A root N/A",
"└─Projection_6 8000.00 root test.ads_txn.cusno, test.ads_txn.txn_dt, test.ads_txn.unn_trno, test.ads_txn.aml_cntpr_accno, test.ads_txn.acpayr_accno, test.ads_txn._tidb_rowid",
" └─SelectLock_7 8000.00 root for update 0",
" └─TableReader_9 10000.00 root partition:all data:TableRangeScan_8",
" └─TableRangeScan_8 10000.00 cop[tikv] table:s range:[1,100000], keep order:false, stats:pseudo"))
}
5 changes: 2 additions & 3 deletions planner/core/logical_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -1714,15 +1714,14 @@ func (ds *DataSource) deriveTablePathStats(path *util.AccessPath, conds []expres
path.CountAfterAccess = float64(ds.statisticTable.RealtimeCount)
path.TableFilters = conds
var pkCol *expression.Column
columnLen := len(ds.schema.Columns)
isUnsigned := false
if ds.tableInfo.PKIsHandle {
if pkColInfo := ds.tableInfo.GetPkColInfo(); pkColInfo != nil {
isUnsigned = mysql.HasUnsignedFlag(pkColInfo.GetFlag())
pkCol = expression.ColInfo2Col(ds.schema.Columns, pkColInfo)
}
} else if columnLen > 0 && ds.schema.Columns[columnLen-1].ID == model.ExtraHandleID {
pkCol = ds.schema.Columns[columnLen-1]
} else {
pkCol = ds.schema.GetExtraHandleColumn()
}
if pkCol == nil {
path.Ranges = ranger.FullIntRange(isUnsigned)
Expand Down