Skip to content

Commit

Permalink
Assume text index comparisons are exact (#2619)
Browse files Browse the repository at this point in the history
* assume text index comparisons are exact

* fix tests

* better safety check for filter elim

* protect prefix indexes from filter elimination

* zach comments
  • Loading branch information
max-hoffman authored Aug 8, 2024
1 parent 56771f6 commit acbef8f
Show file tree
Hide file tree
Showing 7 changed files with 1,022 additions and 1,304 deletions.
1 change: 0 additions & 1 deletion enginetest/enginetests.go
Original file line number Diff line number Diff line change
Expand Up @@ -4770,7 +4770,6 @@ func TestTracing(t *testing.T, harness Harness) {
"plan.Distinct",
"plan.Project",
"plan.Sort",
"plan.Filter",
"plan.IndexedTableAccess",
}

Expand Down
1,624 changes: 725 additions & 899 deletions enginetest/queries/integration_plans.go

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions enginetest/queries/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,22 @@ Select * from (
Query: "select count(*) from typestable where s1 in ('', 'bye');",
Expected: []sql.Row{{1}},
},
{
Query: "select count(*) from mytable where s in ('', 'first row');",
Expected: []sql.Row{{1}},
},
{
Query: "select count(*) from mytable where s in (1, 'first row');",
Expected: []sql.Row{{1}},
},
{
Query: "select count(*) from mytable where s in (NULL, 'first row');",
Expected: []sql.Row{{1}},
},
{
Query: "select count(*) from niltable where i2 in (NULL, 1);",
Expected: []sql.Row{{0}},
},
{
Query: "SELECT * FROM mytable;",
Expected: []sql.Row{
Expand Down
480 changes: 189 additions & 291 deletions enginetest/queries/query_plans.go

Large diffs are not rendered by default.

160 changes: 64 additions & 96 deletions enginetest/queries/tpcc_plans.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions sql/analyzer/costed_index_scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func indexSearchableLookup(n sql.Node, rt sql.TableNode, lookup sql.IndexLookup,
return n, transform.SameTree, nil
}

if !iat.PreciseMatch() {
if !preciseIndexAccess(iat, lookup.Index) {
// cannot drop any filters
newFilter = oldFilter
}
Expand Down Expand Up @@ -284,7 +284,7 @@ func getCostedIndexScan(ctx *sql.Context, statsProv sql.StatsProvider, rt sql.Ta
}

var retFilters []sql.Expression
if !iat.PreciseMatch() {
if !preciseIndexAccess(iat, lookup.Index) {
// cannot drop filters
retFilters = filters
} else if len(b.leftover) > 0 {
Expand Down Expand Up @@ -357,7 +357,7 @@ func addIndexScans(m *memo.Memo) error {
}

var keepFilters []sql.Expression
if !iat.PreciseMatch() {
if !preciseIndexAccess(iat, lookup.Index) {
// cannot drop any filters
keepFilters = filter.Filters
} else {
Expand Down Expand Up @@ -402,6 +402,12 @@ func addIndexScans(m *memo.Memo) error {
})
}

// preciseIndexAccess returns whether an indexed access into a table is a
// replacement for relational filters.
func preciseIndexAccess(t sql.IndexAddressableTable, i sql.Index) bool {
return t.PreciseMatch() && !i.IsFullText() && !i.IsSpatial() && len(i.PrefixLengths()) == 0
}

func newIndexCoster(ctx *sql.Context, underlyingName string) *indexCoster {
return &indexCoster{
ctx: ctx,
Expand Down
33 changes: 19 additions & 14 deletions sql/expression/comparison.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,14 @@ func PreciseComparison(e sql.Expression) bool {
return true
}

// string type comparisons are exact
if types.IsText(left) && types.IsText(right) {
return true
}

if tupType, ok := right.(types.TupleType); ok {
if types.IsInteger(left) {
rightIsAllInt := true
for _, typ := range tupType {
if !types.IsInteger(typ) {
rightIsAllInt = false
break
}
}
if rightIsAllInt {
// left integer and right tuple integer types is OK
return true
}
imprecise = true
return false
if tupleTypesMatch(left, tupType, types.IsInteger) || tupleTypesMatch(left, tupType, types.IsText) {
return true
}
for _, right := range tupType {
if !left.Equals(right) {
Expand All @@ -86,6 +79,18 @@ func PreciseComparison(e sql.Expression) bool {
return !imprecise
}

func tupleTypesMatch(left sql.Type, tup types.TupleType, typeCb func(t sql.Type) bool) bool {
if !typeCb(left) {
return false
}
for _, right := range tup {
if !typeCb(right) {
return false
}
}
return true
}

type comparison struct {
BinaryExpressionStub
}
Expand Down

0 comments on commit acbef8f

Please sign in to comment.