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

executor: add a test for dynamic partition prune mode with equal expression #24520

Merged
merged 11 commits into from
May 11, 2021
59 changes: 59 additions & 0 deletions executor/partition_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,65 @@ func (s *partitionTableSuite) TestGlobalStatsAndSQLBinding(c *C) {
tk.MustIndexLookup("select * from tlist where a<1")
}

func createTable4DynamicPruneModeTestWithExpression(tk *testkit.TestKit) {
tk.MustExec("create table trange(a int) partition by range(a) (partition p0 values less than(3), partition p1 values less than (5), partition p2 values less than(11));")
tk.MustExec("create table thash(a int) partition by hash(a) partitions 4;")
tk.MustExec("create table t(a int)")
tk.MustExec("insert into trange values(1), (1), (1), (2), (3), (4), (5), (6), (7), (7), (10), (NULL), (NULL);")
tk.MustExec("insert into thash values(1), (1), (1), (2), (3), (4), (5), (6), (7), (7), (10), (NULL), (NULL);")
tk.MustExec("insert into t values(1), (1), (1), (2), (3), (4), (5), (6), (7), (7), (10), (NULL), (NULL);")
tk.MustExec("set session tidb_partition_prune_mode='dynamic'")
tk.MustExec("analyze table trange")
tk.MustExec("analyze table thash")
tk.MustExec("analyze table t")
}

type testData4Expression struct {
sql string
partitions []string
}

func (s *partitionTableSuite) TestDynamicPruneModeWithEqualExpression(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
tk.MustExec("drop database if exists db_equal_expression")
tk.MustExec("create database db_equal_expression")
tk.MustExec("use db_equal_expression")
createTable4DynamicPruneModeTestWithExpression(tk)

tables := []string{"trange", "thash"}
tests := []testData4Expression{
{
sql: "select * from %s where a = 2",
partitions: []string{
"p0",
"p2",
},
},
{
sql: "select * from %s where a = 4 or a = 1",
partitions: []string{
"p0,p1",
"p0,p1",
},
},
{
sql: "select * from %s where a = -1",
qw4990 marked this conversation as resolved.
Show resolved Hide resolved
partitions: []string{
"p0",
"p1",
},
},
}

for _, t := range tests {
for i := range t.partitions {
sql := fmt.Sprintf(t.sql, tables[i])
c.Assert(tk.MustPartition(sql, t.partitions[i]), IsTrue)
tk.MustQuery(sql).Sort().Check(tk.MustQuery(fmt.Sprintf(t.sql, "t")).Sort().Rows())
}
}
}

func (s *globalIndexSuite) TestGlobalIndexScan(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
tk.MustExec("drop table if exists p")
Expand Down
11 changes: 11 additions & 0 deletions util/testkit/testkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,17 @@ func (tk *TestKit) MustNoGlobalStats(table string) bool {
return true
}

// MustPartition checks if the result execution plan must read specific partitions.
func (tk *TestKit) MustPartition(sql string, partitions string, args ...interface{}) bool {
rs := tk.MustQuery("explain "+sql, args...)
for i := range rs.rows {
if strings.Compare(rs.rows[i][3], "partition:"+partitions) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we extend this to return which partitions (as an int set/array) will be used? So we can check that a query is only using a specific set of partitions (not more and not less). Or should we have that as a separate helper function later?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this function can check that a query is only using a specific set of partitions (not more and not less). Although it can only handle the case of only one partition-read plan. The extension I understand maybe can support multiple partition-read plans. If necessary, I can implement this extension, but I think it shouldn’t be needed at the moment.

return true
}
}
return false
}

// MustUseIndex checks if the result execution plan contains specific index(es).
func (tk *TestKit) MustUseIndex(sql string, index string, args ...interface{}) bool {
rs := tk.MustQuery("explain "+sql, args...)
Expand Down