Skip to content

Commit

Permalink
Optimizer: add test cases for predicate simplifications (#41117)
Browse files Browse the repository at this point in the history
ref #40221
  • Loading branch information
ghazalfamilyusa authored Feb 7, 2023
1 parent 833e0b9 commit 79a5d3b
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 0 deletions.
1 change: 1 addition & 0 deletions planner/core/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ go_test(
"plan_to_pb_test.go",
"planbuilder_test.go",
"point_get_plan_test.go",
"predicate_simplification_test.go",
"prepare_test.go",
"preprocess_test.go",
"rule_inject_extra_projection_test.go",
Expand Down
63 changes: 63 additions & 0 deletions planner/core/predicate_simplification_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2023 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package core_test

import (
"context"
"fmt"
"testing"

"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/parser"
"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/planner"
"github.com/pingcap/tidb/planner/core"
"github.com/pingcap/tidb/sessiontxn"
"github.com/pingcap/tidb/testkit"
"github.com/pingcap/tidb/testkit/testdata"
"github.com/stretchr/testify/require"
)

// Test redundant conditions in single table and join predicates.
func TestRemoveRedundantPredicates(t *testing.T) {
store := testkit.CreateMockStore(t)

tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("set tidb_opt_limit_push_down_threshold=0")
var input []string
var output []struct {
SQL string
Best string
}
planSuiteData := core.GetPlanSuiteData()
planSuiteData.LoadTestCases(t, &input, &output)
p := parser.New()
is := infoschema.MockInfoSchema([]*model.TableInfo{core.MockSignedTable(), core.MockUnsignedTable()})
for i, tt := range input {
comment := fmt.Sprintf("case: %v, sql: %s", i, tt)
stmt, err := p.ParseOneStmt(tt, "", "")
require.NoError(t, err, comment)
require.NoError(t, sessiontxn.NewTxn(context.Background(), tk.Session()))
p, _, err := planner.Optimize(context.TODO(), tk.Session(), stmt, is)
require.NoError(t, err)
testdata.OnRecord(func() {
output[i].SQL = tt
output[i].Best = core.ToString(p)
})
require.Equal(t, output[i].Best, core.ToString(p), comment)
}
}
16 changes: 16 additions & 0 deletions planner/core/testdata/plan_suite_in.json
Original file line number Diff line number Diff line change
Expand Up @@ -1194,5 +1194,21 @@
"select /*+ agg_to_cop() hash_agg() */ count(1) from tbl_15 ;",
"select /*+ agg_to_cop() stream_agg() */ avg( tbl_16.col_100 ) as r0 from tbl_16 where tbl_16.col_100 in ( 10672141 ) or tbl_16.col_104 in ( 'yfEG1t!*b' ,'C1*bqx_qyO' ,'vQ^yUpKHr&j#~' ) group by tbl_16.col_100 order by r0 limit 20 ;"
]
},
{
"name": "TestRemoveRedundantPredicates",
"cases":[
"select f from t use index() where f = 1 and f = 1 -- simple redundancy of exact condition",
"select f from t use index() where f = 1 and f = 2 -- unsatisfiable condition",
"select f from t use index() where f = 1 and f in (1,2,3) -- intersection of in and =",
"select f from t use index() where f = 1 and f <> 1 -- intersection of = and <>",
"select f from t use index() where f not in (1,2,3) and f = 3 -- intersection of not in list and =",
"select f from t use index() where f <> 3 and f <> 3 -- intersection of two not in values.",
"select t1.f /* merge_join(t1, t2) */ from t t1, t t2 where t1.a=t2.a and t1.a=t2.a -- exact redundancy in joins",
"select f from t use index() where f in (1,2,3) and f <> 2 -- intersection of in and <>. Not done yet see issue 39676",
"select f from t use index() where f in (1,2,3) and f in (3,4,5) -- intersection of two in. Not done yet",
"select f from t use index() where f not in (1,2,3) and f not in (3,4,5) -- intersection of two not in. Not done yet",
"select f from t use index() where f not in (1,2,3) and f in (1,2,3) -- intersection of in and not in. Not done yet"
]
}
]
49 changes: 49 additions & 0 deletions planner/core/testdata/plan_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -7600,5 +7600,54 @@
"Warning": null
}
]
},
{
"Name": "TestRemoveRedundantPredicates",
"Cases": [
{
"SQL": "select f from t use index() where f = 1 and f = 1 -- simple redundancy of exact condition",
"Best": "TableReader(Table(t)->Sel([eq(test.t.f, 1)]))"
},
{
"SQL": "select f from t use index() where f = 1 and f = 2 -- unsatisfiable condition",
"Best": "Dual"
},
{
"SQL": "select f from t use index() where f = 1 and f in (1,2,3) -- intersection of in and =",
"Best": "TableReader(Table(t)->Sel([eq(test.t.f, 1)]))"
},
{
"SQL": "select f from t use index() where f = 1 and f <> 1 -- intersection of = and <>",
"Best": "Dual"
},
{
"SQL": "select f from t use index() where f not in (1,2,3) and f = 3 -- intersection of not in list and =",
"Best": "Dual"
},
{
"SQL": "select f from t use index() where f <> 3 and f <> 3 -- intersection of two not in values.",
"Best": "TableReader(Table(t)->Sel([ne(test.t.f, 3)]))"
},
{
"SQL": "select t1.f /* merge_join(t1, t2) */ from t t1, t t2 where t1.a=t2.a and t1.a=t2.a -- exact redundancy in joins",
"Best": "MergeInnerJoin{TableReader(Table(t))->TableReader(Table(t))}(test.t.a,test.t.a)"
},
{
"SQL": "select f from t use index() where f in (1,2,3) and f <> 2 -- intersection of in and <>. Not done yet see issue 39676",
"Best": "TableReader(Table(t)->Sel([in(test.t.f, 1, 2, 3) ne(test.t.f, 2)]))"
},
{
"SQL": "select f from t use index() where f in (1,2,3) and f in (3,4,5) -- intersection of two in. Not done yet",
"Best": "TableReader(Table(t)->Sel([in(test.t.f, 1, 2, 3) in(test.t.f, 3, 4, 5)]))"
},
{
"SQL": "select f from t use index() where f not in (1,2,3) and f not in (3,4,5) -- intersection of two not in. Not done yet",
"Best": "TableReader(Table(t)->Sel([not(in(test.t.f, 1, 2, 3)) not(in(test.t.f, 3, 4, 5))]))"
},
{
"SQL": "select f from t use index() where f not in (1,2,3) and f in (1,2,3) -- intersection of in and not in. Not done yet",
"Best": "TableReader(Table(t)->Sel([not(in(test.t.f, 1, 2, 3)) in(test.t.f, 1, 2, 3)]))"
}
]
}
]

0 comments on commit 79a5d3b

Please sign in to comment.