diff --git a/executor/index_merge_reader_test.go b/executor/index_merge_reader_test.go index 9aa01c434d3c3..73322d3581755 100644 --- a/executor/index_merge_reader_test.go +++ b/executor/index_merge_reader_test.go @@ -67,6 +67,22 @@ func (s *testSuite1) TestIndexMergeReaderAndGeneratedColumn(c *C) { tk.MustQuery("SELECT t0.c0 FROM t0 WHERE t0.c1 OR t0.c0").Check(testkit.Rows("1")) } +// issue 25045 +func (s *testSuite1) TestIndexMergeReaderIssue25045(c *C) { + tk := testkit.NewTestKitWithInit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1(a int primary key, b int, c int, key(b), key(c));") + tk.MustExec("INSERT INTO t1 VALUES (10, 10, 10), (11, 11, 11)") + tk.MustQuery("explain format='brief' select /*+ use_index_merge(t1) */ * from t1 where c=10 or (b=10 and a=10);").Check(testkit.Rows( + "IndexMerge 0.01 root ", + "├─IndexRangeScan(Build) 10.00 cop[tikv] table:t1, index:c(c) range:[10,10], keep order:false, stats:pseudo", + "├─TableRangeScan(Build) 1.00 cop[tikv] table:t1 range:[10,10], keep order:false, stats:pseudo", + "└─Selection(Probe) 0.01 cop[tikv] or(eq(test.t1.c, 10), and(eq(test.t1.b, 10), eq(test.t1.a, 10)))", + " └─TableRowIDScan 11.00 cop[tikv] table:t1 keep order:false, stats:pseudo")) + tk.MustQuery("select /*+ use_index_merge(t1) */ * from t1 where c=10 or (b=10 and a=10);").Check(testkit.Rows("10 10 10")) +} + func (s *testSuite1) TestIssue16910(c *C) { tk := testkit.NewTestKitWithInit(c, s.store) tk.MustExec("use test;") diff --git a/planner/core/find_best_task.go b/planner/core/find_best_task.go index 6a80a9e93bfb1..f9b233ff1d7c3 100644 --- a/planner/core/find_best_task.go +++ b/planner/core/find_best_task.go @@ -897,10 +897,28 @@ func (ds *DataSource) convertToPartialIndexScan(prop *property.PhysicalProperty, return indexPlan, partialCost } +func checkColinSchema(cols []*expression.Column, schema *expression.Schema) bool { + for _, col := range cols { + if schema.ColumnIndex(col) == -1 { + return false + } + } + return true +} + func (ds *DataSource) convertToPartialTableScan(prop *property.PhysicalProperty, path *util.AccessPath) ( tablePlan PhysicalPlan, partialCost float64) { ts, partialCost, rowCount := ds.getOriginalPhysicalTableScan(prop, path, false) overwritePartialTableScanSchema(ds, ts) + // remove ineffetive filter condition after overwriting physicalscan schema + newFilterConds := make([]expression.Expression, 0, len(path.TableFilters)) + for _, cond := range ts.filterCondition { + cols := expression.ExtractColumns(cond) + if checkColinSchema(cols, ts.schema) { + newFilterConds = append(newFilterConds, cond) + } + } + ts.filterCondition = newFilterConds rowSize := ds.TblColHists.GetAvgRowSize(ds.ctx, ts.schema.Columns, false, false) sessVars := ds.ctx.GetSessionVars() if len(ts.filterCondition) > 0 {