Files
tidb/executor/explain_test.go

202 lines
6.9 KiB
Go

// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package executor_test
import (
. "github.com/pingcap/check"
"github.com/pingcap/tidb/util/testkit"
"github.com/pingcap/tidb/util/testleak"
)
func (s *testSuite) TestExplain(c *C) {
tk := testkit.NewTestKit(c, s.store)
defer func() {
s.cleanEnv(c)
testleak.AfterTest(c)()
tk.MustExec("set @@session.tidb_opt_insubquery_unfold = 0")
}()
tk.MustExec("use test")
tk.MustExec("drop table if exists t1, t2, t3")
tk.MustExec("create table t1 (c1 int primary key, c2 int, c3 int, index c2 (c2))")
tk.MustExec("create table t2 (c1 int unique, c2 int)")
tk.MustExec("insert into t2 values(1, 0), (2, 1)")
tk.MustExec("create table t3 (a bigint, b bigint, c bigint, d bigint)")
tests := []struct {
sql string
expect []string
}{
{
"select * from t3 where exists (select s.a from t3 s having sum(s.a) = t3.a )",
[]string{
"TableScan_15 cop table:t3, range:(-inf,+inf), keep order:false",
"TableReader_16 Projection_12 root data:TableScan_15",
"Projection_12 HashSemiJoin_14 root test.t3.a, test.t3.b, test.t3.c, test.t3.d, cast(test.t3.a)",
"TableScan_18 HashAgg_17 cop table:s, range:(-inf,+inf), keep order:false",
"HashAgg_17 cop type:complete, funcs:sum(s.a)",
"TableReader_20 HashAgg_19 root data:HashAgg_17",
"HashAgg_19 HashSemiJoin_14 root type:final, funcs:sum(col_0)",
"HashSemiJoin_14 Projection_11 root right:HashAgg_19, equal:[eq(cast(test.t3.a), sel_agg_1)]",
"Projection_11 root test.t3.a, test.t3.b, test.t3.c, test.t3.d",
},
},
{
"select * from t1",
[]string{
"TableScan_3 cop table:t1, range:(-inf,+inf), keep order:false",
"TableReader_4 root data:TableScan_3",
},
},
{
"select * from t1 order by c2",
[]string{
"IndexScan_13 cop table:t1, index:c2, range:[<nil>,+inf], out of order:false",
"TableScan_14 cop table:t1, keep order:false",
"IndexLookUp_15 root index:IndexScan_13, table:TableScan_14",
},
},
{
"select * from t2 order by c2",
[]string{
"TableScan_4 cop table:t2, range:(-inf,+inf), keep order:false",
"TableReader_5 Sort_3 root data:TableScan_4",
"Sort_3 root t2.c2:asc",
},
},
{
"select * from t1 where t1.c1 > 0",
[]string{
"TableScan_4 cop table:t1, range:[1,+inf), keep order:false",
"TableReader_5 root data:TableScan_4",
},
},
{
"select t1.c1, t1.c2 from t1 where t1.c2 = 1",
[]string{
"IndexScan_7 cop table:t1, index:c2, range:[1,1], out of order:true",
"IndexReader_8 root index:IndexScan_7",
},
},
{
"select * from t1 left join t2 on t1.c2 = t2.c1 where t1.c1 > 1",
[]string{
"TableScan_22 cop table:t1, range:[2,+inf), keep order:false",
"TableReader_23 IndexJoin_7 root data:TableScan_22",
"IndexScan_33 cop table:t2, index:c1, range:[<nil>,+inf], out of order:false",
"TableScan_34 cop table:t2, keep order:false",
"IndexLookUp_35 IndexJoin_7 root index:IndexScan_33, table:TableScan_34",
"IndexJoin_7 root outer:TableReader_23, outer key:test.t1.c2, inner key:test.t2.c1",
},
},
{
"update t1 set t1.c2 = 2 where t1.c1 = 1",
[]string{
"TableScan_4 cop table:t1, range:[1,1], keep order:false",
"TableReader_5 Update_3 root data:TableScan_4",
"Update_3 root ",
},
},
{
"delete from t1 where t1.c2 = 1",
[]string{
"IndexScan_7 cop table:t1, index:c2, range:[1,1], out of order:true",
"TableScan_8 cop table:t1, keep order:false",
"IndexLookUp_9 Delete_3 root index:IndexScan_7, table:TableScan_8",
"Delete_3 root ",
},
},
{
"select count(b.c2) from t1 a, t2 b where a.c1 = b.c2 group by a.c1",
[]string{
"TableScan_17 HashAgg_16 cop table:b, range:(-inf,+inf), keep order:false",
"HashAgg_16 cop type:complete, group by:b.c2, funcs:count(b.c2), firstrow(b.c2)",
"TableReader_21 HashAgg_20 root data:HashAgg_16",
"HashAgg_20 IndexJoin_9 root type:final, group by:, funcs:count(col_0), firstrow(col_1)",
"TableScan_12 cop table:a, range:(-inf,+inf), keep order:true",
"TableReader_31 IndexJoin_9 root data:TableScan_12",
"IndexJoin_9 Projection_8 root outer:TableReader_31, outer key:b.c2, inner key:a.c1",
"Projection_8 root cast(join_agg_0)",
},
},
{
"select * from t2 order by t2.c2 limit 0, 1",
[]string{
"TableScan_7 TopN_5 cop table:t2, range:(-inf,+inf), keep order:false",
"TopN_5 cop ",
"TableReader_10 TopN_5 root data:TopN_5",
"TopN_5 root ",
},
},
{
"select * from t1 where c1 > 1 and c2 = 1 and c3 < 1",
[]string{
"IndexScan_7 Selection_9 cop table:t1, index:c2, range:[1,1], out of order:true",
"Selection_9 cop gt(test.t1.c1, 1)",
"TableScan_8 Selection_10 cop table:t1, keep order:false",
"Selection_10 cop lt(test.t1.c3, 1)",
"IndexLookUp_11 root index:Selection_9, table:Selection_10",
},
},
{
"select * from t1 where c1 =1 and c2 > 1",
[]string{
"TableScan_4 Selection_5 cop table:t1, range:[1,1], keep order:false",
"Selection_5 cop gt(test.t1.c2, 1)",
"TableReader_6 root data:Selection_5",
},
},
{
"select sum(t1.c1 in (select c1 from t2)) from t1",
[]string{
"TableScan_11 HashAgg_10 cop table:t1, range:(-inf,+inf), keep order:false",
"HashAgg_10 cop type:complete, funcs:sum(in(test.t1.c1, 1, 2))",
"TableReader_14 HashAgg_13 root data:HashAgg_10",
"HashAgg_13 root type:final, funcs:sum(col_0)",
},
},
{
"select c1 from t1 where c1 in (select c2 from t2)",
[]string{
"TableScan_11 cop table:t1, range:[0,0], [1,1], keep order:false",
"TableReader_12 root data:TableScan_11",
},
},
{
"select (select count(1) k from t1 s where s.c1 = t1.c1 having k != 0) from t1",
[]string{
"TableScan_13 cop table:t1, range:(-inf,+inf), keep order:false",
"TableReader_14 Apply_12 root data:TableScan_13",
"TableScan_18 cop table:s, range:(-inf,+inf), keep order:false",
"TableReader_19 Selection_4 root data:TableScan_18",
"Selection_4 HashAgg_17 root eq(s.c1, test.t1.c1)",
"HashAgg_17 Selection_10 root type:complete, funcs:count(1)",
"Selection_10 Apply_12 root ne(k, 0)",
"Apply_12 Projection_2 root left outer join, small:Selection_10, right:Selection_10",
"Projection_2 root k",
},
},
{
"select * from information_schema.columns",
[]string{
"MemTableScan_3 root ",
},
},
}
tk.MustExec("set @@session.tidb_opt_insubquery_unfold = 1")
for _, tt := range tests {
result := tk.MustQuery("explain " + tt.sql)
result.Check(testkit.Rows(tt.expect...))
}
}