diff --git a/enginetest/queries/query_plans.go b/enginetest/queries/query_plans.go index 1800f90478..795b71189b 100644 --- a/enginetest/queries/query_plans.go +++ b/enginetest/queries/query_plans.go @@ -22663,11 +22663,14 @@ WHERE keyless.c0 IN ( " ├─ Eq\n" + " │ ├─ xy.y:1\n" + " │ └─ uv.u:2!null\n" + - " └─ Table\n" + - " ├─ name: uv\n" + - " ├─ columns: [u v]\n" + + " └─ IndexedTableAccess(uv)\n" + + " ├─ index: [uv.u]\n" + + " ├─ keys: [xy.y:1]\n" + " ├─ colSet: (3,4)\n" + - " └─ tableId: 2\n" + + " ├─ tableId: 2\n" + + " └─ Table\n" + + " ├─ name: uv\n" + + " └─ columns: [u v]\n" + "", ExpectedEstimates: "Project\n" + " ├─ columns: [xy.x, uv.u]\n" + @@ -22683,9 +22686,10 @@ WHERE keyless.c0 IN ( " ├─ tableId: 3\n" + " └─ Filter\n" + " ├─ (xy.y = uv.u)\n" + - " └─ Table\n" + - " ├─ name: uv\n" + - " └─ columns: [u v]\n" + + " └─ IndexedTableAccess(uv)\n" + + " ├─ index: [uv.u]\n" + + " ├─ columns: [u v]\n" + + " └─ keys: xy.y\n" + "", ExpectedAnalysis: "Project\n" + " ├─ columns: [xy.x, uv.u]\n" + @@ -22701,9 +22705,10 @@ WHERE keyless.c0 IN ( " ├─ tableId: 3\n" + " └─ Filter\n" + " ├─ (xy.y = uv.u)\n" + - " └─ Table\n" + - " ├─ name: uv\n" + - " └─ columns: [u v]\n" + + " └─ IndexedTableAccess(uv)\n" + + " ├─ index: [uv.u]\n" + + " ├─ columns: [u v]\n" + + " └─ keys: xy.y\n" + "", }, { diff --git a/sql/analyzer/apply_indexes_from_outer_scope.go b/sql/analyzer/apply_indexes_from_outer_scope.go index 31551a86ba..f10c83ede9 100644 --- a/sql/analyzer/apply_indexes_from_outer_scope.go +++ b/sql/analyzer/apply_indexes_from_outer_scope.go @@ -29,10 +29,6 @@ import ( // apply, effectively, an indexed join between two tables, one of which is defined in the outer scope. This is similar // to the process in the join analyzer. func applyIndexesFromOuterScope(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, sel RuleSelector, qFlags *sql.QueryFlags) (sql.Node, transform.TreeIdentity, error) { - if scope.IsEmpty() { - return n, transform.SameTree, nil - } - // this isn't good enough: we need to consider aliases defined in the outer scope as well for this analysis tableAliases, err := getTableAliases(n, scope) if err != nil { @@ -281,6 +277,11 @@ func tablesInScope(scope *plan.Scope) []string { tables[col.Source] = true } } + for _, table := range scope.JoinSiblings() { + for name, _ := range getTablesByName(table) { + tables[name] = true + } + } var tableSlice []string for table := range tables { tableSlice = append(tableSlice, table) diff --git a/sql/plan/scope.go b/sql/plan/scope.go index d2cb208243..889e7f71df 100644 --- a/sql/plan/scope.go +++ b/sql/plan/scope.go @@ -340,9 +340,15 @@ func (s *Scope) InInsertSource() bool { } func (s *Scope) JoinSiblings() []sql.Node { + if s == nil { + return nil + } return s.joinSiblings } func (s *Scope) Correlated() sql.ColSet { + if s == nil { + return sql.ColSet{} + } return s.corr }