Skip to content

Commit

Permalink
cherry pick pingcap#29778 to release-4.0
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
time-and-fate authored and ti-srebot committed Nov 15, 2021
1 parent fc92ef9 commit 0fd9d4f
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 0 deletions.
104 changes: 104 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2125,3 +2125,107 @@ func (s *testIntegrationSuite) TestIssue27797(c *C) {
result = tk.MustQuery("select col2 from IDT_HP24172 where col1 = 8388607 and col1 in (select col1 from IDT_HP24172);")
result.Check(testkit.Rows("<nil>"))
}
<<<<<<< HEAD
=======

func (s *testIntegrationSuite) TestIssue28154(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
defer func() {
tk.Exec("drop table if exists t")
}()
tk.MustExec("create table t(a TEXT)")
tk.MustExec("insert into t values('abc')")
result := tk.MustQuery("select * from t where from_base64('')")
result.Check(testkit.Rows())
_, err := tk.Exec("update t set a = 'def' where from_base64('')")
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals, "[types:1292]Truncated incorrect DOUBLE value: ''")
result = tk.MustQuery("select * from t where from_base64('invalidbase64')")
result.Check(testkit.Rows())
tk.MustExec("update t set a = 'hig' where from_base64('invalidbase64')")
result = tk.MustQuery("select * from t where from_base64('test')")
result.Check(testkit.Rows())
_, err = tk.Exec("update t set a = 'xyz' where from_base64('test')")
c.Assert(err, NotNil)
c.Assert(err, ErrorMatches, "\\[types:1292\\]Truncated incorrect DOUBLE value.*")
result = tk.MustQuery("select * from t")
result.Check(testkit.Rows("abc"))
}

func (s *testIntegrationSerialSuite) TestRejectSortForMPP(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (id int, value decimal(6,3), name char(128))")
tk.MustExec("analyze table t")

// Create virtual tiflash replica info.
dom := domain.GetDomain(tk.Se)
is := dom.InfoSchema()
db, exists := is.SchemaByName(model.NewCIStr("test"))
c.Assert(exists, IsTrue)
for _, tblInfo := range db.Tables {
if tblInfo.Name.L == "t" {
tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{
Count: 1,
Available: true,
}
}
}

tk.MustExec("set @@tidb_allow_mpp=1; set @@tidb_opt_broadcast_join=0; set @@tidb_enforce_mpp=1;")

var input []string
var output []struct {
SQL string
Plan []string
}
s.testData.GetTestCases(c, &input, &output)
for i, tt := range input {
s.testData.OnRecord(func() {
output[i].SQL = tt
output[i].Plan = s.testData.ConvertRowsToStrings(tk.MustQuery(tt).Rows())
})
res := tk.MustQuery(tt)
res.Check(testkit.Rows(output[i].Plan...))
}
}

func (s *testIntegrationSuite) TestIssues29711(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")

tk.MustExec("drop table if exists tbl_29711")
tk.MustExec("CREATE TABLE `tbl_29711` (" +
"`col_250` text COLLATE utf8_unicode_ci NOT NULL," +
"`col_251` enum('Alice','Bob','Charlie','David') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Charlie'," +
"PRIMARY KEY (`col_251`,`col_250`(1)) NONCLUSTERED);")
tk.MustQuery("explain format=brief " +
"select col_250,col_251 from tbl_29711 where col_251 between 'Bob' and 'David' order by col_250,col_251 limit 6;").
Check(testkit.Rows(
"TopN 6.00 root test.tbl_29711.col_250, test.tbl_29711.col_251, offset:0, count:6",
"└─IndexLookUp 6.00 root ",
" ├─IndexRangeScan(Build) 30.00 cop[tikv] table:tbl_29711, index:PRIMARY(col_251, col_250) range:[\"Bob\",\"Bob\"], [\"Charlie\",\"Charlie\"], [\"David\",\"David\"], keep order:false, stats:pseudo",
" └─TopN(Probe) 6.00 cop[tikv] test.tbl_29711.col_250, test.tbl_29711.col_251, offset:0, count:6",
" └─TableRowIDScan 30.00 cop[tikv] table:tbl_29711 keep order:false, stats:pseudo",
))

tk.MustExec("drop table if exists t29711")
tk.MustExec("CREATE TABLE `t29711` (" +
"`a` varchar(10) DEFAULT NULL," +
"`b` int(11) DEFAULT NULL," +
"`c` int(11) DEFAULT NULL," +
"KEY `ia` (`a`(2)))")
tk.MustQuery("explain format=brief select * from t29711 use index (ia) order by a limit 10;").
Check(testkit.Rows(
"TopN 10.00 root test.t29711.a, offset:0, count:10",
"└─IndexLookUp 10.00 root ",
" ├─IndexFullScan(Build) 10000.00 cop[tikv] table:t29711, index:ia(a) keep order:false, stats:pseudo",
" └─TopN(Probe) 10.00 cop[tikv] test.t29711.a, offset:0, count:10",
" └─TableRowIDScan 10000.00 cop[tikv] table:t29711 keep order:false, stats:pseudo",
))

}
>>>>>>> a0d3f4fe5... planner: fix topn wrongly pushed to index scan side when it's a prefix index (#29778)
21 changes: 21 additions & 0 deletions planner/core/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -955,14 +955,35 @@ func (p *PhysicalTopN) getPushedDownTopN(childPlan PhysicalPlan) *PhysicalTopN {
return topN
}

// canPushToIndexPlan checks if this TopN can be pushed to the index side of copTask.
// It can be pushed to the index side when all columns used by ByItems are available from the index side and
// there's no prefix index column.
func (p *PhysicalTopN) canPushToIndexPlan(indexPlan PhysicalPlan, byItemCols []*expression.Column) bool {
schema := indexPlan.Schema()
for _, col := range byItemCols {
pos := schema.ColumnIndex(col)
if pos == -1 {
return false
}
if schema.Columns[pos].IsPrefix {
return false
}
}
return true
}

func (p *PhysicalTopN) attach2Task(tasks ...task) task {
t := tasks[0].copy()
inputCount := t.count()
if copTask, ok := t.(*copTask); ok && p.canPushDown(copTask) && len(copTask.rootTaskConds) == 0 {
// If all columns in topN are from index plan, we push it to index plan, otherwise we finish the index plan and
// push it to table plan.
var pushedDownTopN *PhysicalTopN
<<<<<<< HEAD
if !copTask.indexPlanFinished && p.allColsFromSchema(copTask.indexPlan.Schema()) {
=======
if !copTask.indexPlanFinished && p.canPushToIndexPlan(copTask.indexPlan, cols) {
>>>>>>> a0d3f4fe5... planner: fix topn wrongly pushed to index scan side when it's a prefix index (#29778)
pushedDownTopN = p.getPushedDownTopN(copTask.indexPlan)
copTask.indexPlan = pushedDownTopN
} else {
Expand Down

0 comments on commit 0fd9d4f

Please sign in to comment.