Skip to content

Commit

Permalink
end
Browse files Browse the repository at this point in the history
  • Loading branch information
ghazalfamilyusa committed Jun 11, 2024
1 parent 3a98da6 commit aa03831
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 41 deletions.
9 changes: 4 additions & 5 deletions pkg/bindinfo/global_handle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -550,11 +550,10 @@ func TestSetVarFixControlWithBinding(t *testing.T) {
tk.MustExec(`create table t(id int, a varchar(100), b int, c int, index idx_ab(a, b))`)
tk.MustQuery(`explain select * from t where c = 10 and (a = 'xx' or (a = 'kk' and b = 1))`).Check(
testkit.Rows(
`IndexLookUp_12 0.01 root `,
`├─Selection_10(Build) 0.02 cop[tikv] or(eq(test.t.a, "xx"), and(eq(test.t.a, "kk"), eq(test.t.b, 1)))`,
`│ └─IndexRangeScan_8 20.00 cop[tikv] table:t, index:idx_ab(a, b) range:["kk","kk"], ["xx","xx"], keep order:false, stats:pseudo`,
`└─Selection_11(Probe) 0.01 cop[tikv] eq(test.t.c, 10)`,
` └─TableRowIDScan_9 0.02 cop[tikv] table:t keep order:false, stats:pseudo`))
`IndexLookUp_11 0.01 root `,
`├─IndexRangeScan_8(Build) 10.10 cop[tikv] table:t, index:idx_ab(a, b) range:["kk" 1,"kk" 1], ["xx","xx"], keep order:false, stats:pseudo`,
`└─Selection_10(Probe) 0.01 cop[tikv] eq(test.t.c, 10)`,
` └─TableRowIDScan_9 10.10 cop[tikv] table:t keep order:false, stats:pseudo`))

tk.MustExec(`create global binding using select /*+ set_var(tidb_opt_fix_control='44389:ON') */ * from t where c = 10 and (a = 'xx' or (a = 'kk' and b = 1))`)
tk.MustQuery(`show warnings`).Check(testkit.Rows()) // no warning
Expand Down
9 changes: 5 additions & 4 deletions pkg/expression/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package expression
import (
"bytes"
"context"
"fmt"
"math"
"strconv"
"strings"
Expand Down Expand Up @@ -994,9 +993,11 @@ func containOuterNot(expr Expression, not bool) bool {
func Contains(exprs []Expression, e Expression) bool {
for _, expr := range exprs {
// Check string equivalence if one of the expressions is a clone.
str1 := fmt.Sprintf("", e)
str2 := fmt.Sprintf("", expr)
if e == expr || (str1 == str2) {
sameString := false
if e != nil && expr != nil {
sameString = (e.String() == expr.String())
}
if e == expr || sameString {
return true
}
}
Expand Down
1 change: 1 addition & 0 deletions pkg/planner/core/casetest/index/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ go_test(
],
data = glob(["testdata/**"]),
flaky = True,
shard_count = 3,
deps = [
"//pkg/testkit",
"//pkg/testkit/testdata",
Expand Down
5 changes: 2 additions & 3 deletions pkg/planner/core/casetest/index/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ func TestInvisibleIndex(t *testing.T) {
tk.MustExec("use test")
tk.MustExec("CREATE TABLE t1 ( a INT, KEY( a ) INVISIBLE );")
tk.MustExec("INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);")
tk.MustQuery(`select a FROM t1;`).Check(
tk.MustQuery(`EXPLAIN SELECT a FROM t1;`).Check(
testkit.Rows(
`TableReader_5 10000.00 root data:TableFullScan_4`,
`└─TableFullScan_4 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo`))
tk.MustExec("set session tidb_opt_use_invisible_indexes=on;")
tk.MustQuery(`select a FROM t1;`).Check(
tk.MustQuery(`EXPLAIN SELECT a FROM t1;`).Check(
testkit.Rows(
`IndexReader_7 10000.00 root index:IndexFullScan_6`,
`└─IndexFullScan_6 10000.00 cop[tikv] table:t1, index:a(a) keep order:false, stats:pseudo`))
Expand Down Expand Up @@ -122,5 +122,4 @@ func TestRangeDerivation(t *testing.T) {
})
plan.Check(testkit.Rows(output[i].Plan...))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -480,8 +480,8 @@
"IndexPlan": [
"HashJoin 0.03 root CARTESIAN inner join",
"├─IndexReader(Build) 0.01 root partition:p0 index:Selection",
"│ └─Selection 0.01 cop[tikv] eq(test_partition_1.t1.id, 7), or(eq(test_partition_1.t1.a, 1), and(eq(test_partition_1.t1.a, 3), in(test_partition_1.t1.b, 3, 5)))",
"│ └─IndexRangeScan 20.00 cop[tikv] table:t1, index:a(a, b, id) range:[1,1], [3,3], keep order:false, stats:pseudo",
"│ └─Selection 0.01 cop[tikv] eq(test_partition_1.t1.id, 7)",
"│ └─IndexRangeScan 10.20 cop[tikv] table:t1, index:a(a, b, id) range:[1,1], [3 3,3 3], [3 5,3 5], keep order:false, stats:pseudo",
"└─IndexReader(Probe) 3.00 root partition:p1 index:IndexRangeScan",
" └─IndexRangeScan 3.00 cop[tikv] table:t2, index:a(a, b, id) range:[6 7 7,6 7 7], [7 7 7,7 7 7], [8 7 7,8 7 7], keep order:false, stats:pseudo"
]
Expand Down
4 changes: 2 additions & 2 deletions pkg/util/ranger/detacher.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,11 +463,11 @@ func (d *rangeDetacher) detachCNFCondAndBuildRangeForIndex(conditions []expressi
// TODO: we will optimize it later.
res.RemainedConds = AppendConditionsIfNotExist(res.RemainedConds, remainedConds)
res.Ranges = ranges
if bestCNFItemRes != nil {
if bestCNFItemRes != nil && res != nil && len(res.Ranges) != 0 {
bestCNFIsSubset := bestCNFItemRes.rangeResult.Ranges.Subset(d.sctx.TypeCtx, res.Ranges)
pointRangeIsSubset := res.Ranges.Subset(d.sctx.TypeCtx, bestCNFItemRes.rangeResult.Ranges)
// Pick bestCNFIsSubset if it is more selective than point ranges(res).
// Only optimization if it is a proper subset bestCNFIsSubset and !pointRangeIsSubset.
// Apply optimization if bestCNFItemRes is a proper subset of point ranges.
if bestCNFIsSubset && !pointRangeIsSubset {
// Update final result and just update: Ranges, AccessConds and RemainedConds
res.RemainedConds = removeConditions(res.RemainedConds, bestCNFItemRes.rangeResult.AccessConds)
Expand Down
43 changes: 18 additions & 25 deletions pkg/util/ranger/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,26 +294,20 @@ func prefix(tc types.Context, superValue []types.Datum, supValue []types.Datum,
return true
}

// Check if a list of ranges(subRanges) is a subset of another list of ranges(superRanges).
// Subset checks if a list of ranges(rs) is a subset of another list of ranges(superRanges).
// This is true if every range in the first list is a subset of any
// range in the second list. Also, we check if all elements of superRanges are covered.
func (subRanges Ranges) Subset(tc types.Context, superRanges Ranges) bool {
func (rs Ranges) Subset(tc types.Context, superRanges Ranges) bool {
var subset bool
superRangesCovered := make([]bool, len(superRanges))
if len(subRanges) == 0 {
// Both lists are unrestricted
if len(superRanges) == 0 {
return true
} else {
// unrestricted subRanges and restricted superRanges
return false
}
if len(rs) == 0 {
return len(superRanges) == 0
} else if len(superRanges) == 0 {
// unrestricted superRanges and restricted subRanges
// unrestricted superRanges and restricted rs
return true
}

for _, subRange := range subRanges {
for _, subRange := range rs {
subset = false
for i, superRange := range superRanges {
if subRange.Subset(tc, superRange) {
Expand All @@ -335,35 +329,34 @@ func (subRanges Ranges) Subset(tc types.Context, superRanges Ranges) bool {
return true
}

// check if range(subRange) is a subset of another range(superRange).
// Subset for Range type, check if range(ran) is a subset of another range(superRange).
// This is done by:
// - Both subRange and superRange have the same collators. This is not needed for the current code path.
// - Both ran and superRange have the same collators. This is not needed for the current code path.
// But, it is used here for future use of the function.
// - Checking if the lower/upper bound of superRange covers the corresponding lower/upper bound of subRange.
// - Checking if the lower/upper bound of superRange covers the corresponding lower/upper bound of ran.
// Thus include checking open/closed inetrvals.
func (subRange *Range) Subset(tc types.Context, superRange *Range) bool {

if len(subRange.LowVal) < len(superRange.LowVal) {
func (ran *Range) Subset(tc types.Context, superRange *Range) bool {
if len(ran.LowVal) < len(superRange.LowVal) {
return false
}

// Make sure both subRange and superRange have the same collations.
// Make sure both ran and superRange have the same collations.
// The current code path for this function always will have same collation
// for subRange and superRange. It is added here for future
// for ran and superRange. It is added here for future
// use of the function.
for i := 0; i < len(superRange.LowVal); i++ {
if subRange.Collators[i] != superRange.Collators[i] {
if ran.Collators[i] != superRange.Collators[i] {
return false
}
}

// Either superRange is closed or both ranges have the same open/close setting.
lowExcludeOK := !superRange.LowExclude || subRange.LowExclude == superRange.LowExclude
highExcludeOK := !superRange.HighExclude || subRange.HighExclude == superRange.HighExclude
lowExcludeOK := !superRange.LowExclude || ran.LowExclude == superRange.LowExclude
highExcludeOK := !superRange.HighExclude || ran.HighExclude == superRange.HighExclude
if !lowExcludeOK || !highExcludeOK {
return false
}

return prefix(tc, superRange.LowVal, subRange.LowVal, len(superRange.LowVal), subRange.Collators) &&
prefix(tc, superRange.HighVal, subRange.HighVal, len(superRange.LowVal), subRange.Collators)
return prefix(tc, superRange.LowVal, ran.LowVal, len(superRange.LowVal), ran.Collators) &&
prefix(tc, superRange.HighVal, ran.HighVal, len(superRange.LowVal), ran.Collators)
}

0 comments on commit aa03831

Please sign in to comment.