github.com/dolthub/go-mysql-server@v0.18.0/sql/analyzer/apply_hash_in.go (about) 1 // Copyright 2021 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package analyzer 16 17 import ( 18 "github.com/dolthub/go-mysql-server/sql" 19 "github.com/dolthub/go-mysql-server/sql/expression" 20 "github.com/dolthub/go-mysql-server/sql/plan" 21 "github.com/dolthub/go-mysql-server/sql/transform" 22 ) 23 24 func applyHashIn(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, sel RuleSelector) (sql.Node, transform.TreeIdentity, error) { 25 return transform.Node(n, func(node sql.Node) (sql.Node, transform.TreeIdentity, error) { 26 filter, ok := node.(*plan.Filter) 27 if !ok { 28 return node, transform.SameTree, nil 29 } 30 31 e, same, err := transform.Expr(filter.Expression, func(expr sql.Expression) (sql.Expression, transform.TreeIdentity, error) { 32 if e, ok := expr.(*expression.InTuple); ok && 33 hasSingleOutput(e.Left()) && 34 isStatic(e.Right()) { 35 newe, err := expression.NewHashInTuple(ctx, e.Left(), e.Right()) 36 if err != nil { 37 return nil, transform.SameTree, err 38 } 39 return newe, transform.NewTree, nil 40 } 41 return expr, transform.SameTree, nil 42 }) 43 if err != nil { 44 return nil, transform.SameTree, err 45 } 46 if same { 47 return node, transform.SameTree, nil 48 } 49 ret, err := filter.WithExpressions(e) 50 if err != nil { 51 return node, transform.SameTree, nil 52 } 53 return ret, transform.NewTree, err 54 }) 55 } 56 57 // hasSingleOutput checks if an expression evaluates to a single output 58 func hasSingleOutput(e sql.Expression) bool { 59 return !transform.InspectExpr(e, func(expr sql.Expression) bool { 60 switch expr.(type) { 61 case expression.Tuple, *expression.Literal, *expression.GetField, 62 expression.Comparer, *expression.Convert, sql.FunctionExpression, 63 *expression.IsTrue, *expression.IsNull, expression.ArithmeticOp: 64 return false 65 default: 66 return true 67 } 68 return false 69 }) 70 } 71 72 // isStatic checks if an expression is static 73 func isStatic(e sql.Expression) bool { 74 return !transform.InspectExpr(e, func(expr sql.Expression) bool { 75 switch expr.(type) { 76 case expression.Tuple, *expression.Literal: 77 return false 78 default: 79 return true 80 } 81 }) 82 }