@@ -3,6 +3,7 @@ package analyzer
33import (
44 "github.com/dolthub/go-mysql-server/sql"
55 "github.com/dolthub/go-mysql-server/sql/expression"
6+ "github.com/dolthub/go-mysql-server/sql/expression/function/vector"
67 "github.com/dolthub/go-mysql-server/sql/plan"
78 "github.com/dolthub/go-mysql-server/sql/transform"
89)
@@ -12,9 +13,9 @@ func replaceIdxOrderByDistance(ctx *sql.Context, a *Analyzer, n sql.Node, scope
1213 return replaceIdxOrderByDistanceHelper (ctx , scope , n , nil )
1314}
1415
15- func replaceIdxOrderByDistanceHelper (ctx * sql.Context , scope * plan.Scope , node sql.Node , sortNode plan.Sortable ) (sql.Node , transform.TreeIdentity , error ) {
16+ func replaceIdxOrderByDistanceHelper (ctx * sql.Context , scope * plan.Scope , node sql.Node , sortNode * plan.TopN ) (sql.Node , transform.TreeIdentity , error ) {
1617 switch n := node .(type ) {
17- case plan.Sortable :
18+ case * plan.TopN :
1819 sortNode = n // lowest parent sort node
1920 case * plan.ResolvedTable :
2021 if sortNode == nil {
@@ -40,6 +41,11 @@ func replaceIdxOrderByDistanceHelper(ctx *sql.Context, scope *plan.Scope, node s
4041 if err != nil {
4142 return nil , transform .SameTree , err
4243 }
44+
45+ // Column references have not been assigned their final indexes yet, so do that for the ORDER BY expression now.
46+ // We can safely do this because an expression that references other tables won't pass `isSortFieldsValidPrefix` below.
47+ sortNode = offsetAssignIndexes (sortNode ).(* plan.TopN )
48+
4349 sfExprs := normalizeExpressions (tableAliases , sortNode .GetSortFields ().ToExpressions ()... )
4450 sfAliases := aliasedExpressionsInNode (sortNode )
4551
@@ -49,18 +55,21 @@ func replaceIdxOrderByDistanceHelper(ctx *sql.Context, scope *plan.Scope, node s
4955 if len (sfExprs ) != 1 {
5056 return n , transform .SameTree , nil
5157 }
52- distance , isDistance := sfExprs [0 ].(* expression .Distance )
58+ distance , isDistance := sfExprs [0 ].(* vector .Distance )
5359 if ! isDistance {
5460 return n , transform .SameTree , nil
5561 }
5662 var column sql.Expression
63+ var literal sql.Expression
5764 _ , leftIsLiteral := distance .LeftChild .(* expression.Literal )
5865 if leftIsLiteral {
5966 column = distance .RightChild
67+ literal = distance .LeftChild
6068 } else {
6169 _ , rightIsLiteral := distance .RightChild .(* expression.Literal )
6270 if rightIsLiteral {
6371 column = distance .LeftChild
72+ literal = distance .RightChild
6473 } else {
6574 return n , transform .SameTree , nil
6675 }
@@ -82,17 +91,15 @@ func replaceIdxOrderByDistanceHelper(ctx *sql.Context, scope *plan.Scope, node s
8291 return n , transform .SameTree , nil
8392 }
8493
85- var limit sql.Expression
86- if topn , ok := sortNode .(* plan.TopN ); ok {
87- limit = topn .Limit
88- }
94+ limit := sortNode .Limit
8995
9096 lookup := sql.IndexLookup {
9197 Index : idx ,
9298 Ranges : sql.MySQLRangeCollection {},
9399 VectorOrderAndLimit : sql.OrderAndLimit {
94100 OrderBy : distance ,
95101 Limit : limit ,
102+ Literal : literal ,
96103 },
97104 }
98105 nn , err := plan .NewStaticIndexedAccessForTableNode (n , lookup )
@@ -108,7 +115,7 @@ func replaceIdxOrderByDistanceHelper(ctx *sql.Context, scope *plan.Scope, node s
108115 var err error
109116 same := transform .SameTree
110117 switch c := child .(type ) {
111- case * plan.Project , * plan.TableAlias , * plan.ResolvedTable , * plan.Filter , * plan.Limit , * plan.Offset , * plan.Sort , * plan.IndexedTableAccess :
118+ case * plan.Project , * plan.TableAlias , * plan.ResolvedTable , * plan.Filter , * plan.Limit , * plan.TopN , * plan. Offset , * plan.Sort , * plan.IndexedTableAccess :
112119 newChildren [i ], same , err = replaceIdxOrderByDistanceHelper (ctx , scope , child , sortNode )
113120 default :
114121 newChildren [i ] = c
0 commit comments