Skip to content

Commit

Permalink
Prevent selection of incompatible index
Browse files Browse the repository at this point in the history
  • Loading branch information
asdine committed Mar 7, 2021
1 parent 7039687 commit 1a9caf0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
10 changes: 10 additions & 0 deletions planner/optimizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,11 @@ func getCandidateFromfilterNode(f *stream.FilterOperator, tableName string, info

// we'll start with checking if the path is the primary key of the table
if pk := info.GetPrimaryKey(); pk != nil && pk.Path.IsEqual(path) {
// if both types are different, don't select this scanner
if pk.Type != v.Type {
return nil, nil
}

cd.isPk = true
cd.priority = 3

Expand All @@ -541,6 +546,11 @@ func getCandidateFromfilterNode(f *stream.FilterOperator, tableName string, info

// if not, check if an index exists for that path
if idx := indexes.GetIndexByPath(document.Path(path)); idx != nil {
// if both types are different, don't select this scanner
if !idx.Info.Type.IsZero() && idx.Info.Type != v.Type {
return nil, nil
}

cd.isIndex = true
if idx.Info.Unique {
cd.priority = 2
Expand Down
31 changes: 30 additions & 1 deletion planner/optimizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,27 @@ func TestUseIndexBasedOnSelectionNodeRule(t *testing.T) {
Pipe(stream.Filter(parser.MustParseExpr("b = 2"))).
Pipe(stream.Project(parser.MustParseExpr("a"))),
},
{
"SELECT a FROM foo WHERE c = 'hello' AND b = 2",
stream.New(stream.SeqScan("foo")).
Pipe(stream.Filter(parser.MustParseExpr("c = 'hello'"))).
Pipe(stream.Filter(parser.MustParseExpr("b = 2"))).
Pipe(stream.Project(parser.MustParseExpr("a"))),
stream.New(stream.IndexScan("idx_foo_b", st.Range{Min: document.NewIntegerValue(2), Exact: true})).
Pipe(stream.Filter(parser.MustParseExpr("c = 'hello'"))).
Pipe(stream.Project(parser.MustParseExpr("a"))),
},
{
"SELECT a FROM foo WHERE c = 'hello' AND d = 2",
stream.New(stream.SeqScan("foo")).
Pipe(stream.Filter(parser.MustParseExpr("c = 'hello'"))).
Pipe(stream.Filter(parser.MustParseExpr("d = 2"))).
Pipe(stream.Project(parser.MustParseExpr("a"))),
stream.New(stream.SeqScan("foo")).
Pipe(stream.Filter(parser.MustParseExpr("c = 'hello'"))).
Pipe(stream.Filter(parser.MustParseExpr("d = 2"))).
Pipe(stream.Project(parser.MustParseExpr("a"))),
},
{
"FROM foo WHERE a IN [1, 2]",
stream.New(stream.SeqScan("foo")).Pipe(stream.Filter(
Expand Down Expand Up @@ -404,6 +425,14 @@ func TestUseIndexBasedOnSelectionNodeRule(t *testing.T) {
stream.New(stream.IndexScan("idx_foo_a", st.Range{Min: document.NewIntegerValue(1), Exact: true})).
Pipe(stream.Filter(parser.MustParseExpr("k < 2"))),
},
{
"FROM foo WHERE a = 1 AND k = 'hello'",
stream.New(stream.SeqScan("foo")).
Pipe(stream.Filter(parser.MustParseExpr("a = 1"))).
Pipe(stream.Filter(parser.MustParseExpr("k = 'hello'"))),
stream.New(stream.IndexScan("idx_foo_a", st.Range{Min: document.NewIntegerValue(1), Exact: true})).
Pipe(stream.Filter(parser.MustParseExpr("k = 'hello'"))),
},
}

for _, test := range tests {
Expand All @@ -417,7 +446,7 @@ func TestUseIndexBasedOnSelectionNodeRule(t *testing.T) {
defer tx.Rollback()

err = tx.Exec(`
CREATE TABLE foo (k INT PRIMARY KEY);
CREATE TABLE foo (k INT PRIMARY KEY, c INT);
CREATE INDEX idx_foo_a ON foo(a);
CREATE INDEX idx_foo_b ON foo(b);
CREATE UNIQUE INDEX idx_foo_c ON foo(c);
Expand Down

0 comments on commit 1a9caf0

Please sign in to comment.