github.com/dolthub/go-mysql-server@v0.18.0/sql/planbuilder/transactions.go (about) 1 // Copyright 2023 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 planbuilder 16 17 import ( 18 "strings" 19 20 ast "github.com/dolthub/vitess/go/vt/sqlparser" 21 22 "github.com/dolthub/go-mysql-server/sql" 23 "github.com/dolthub/go-mysql-server/sql/expression" 24 "github.com/dolthub/go-mysql-server/sql/plan" 25 "github.com/dolthub/go-mysql-server/sql/types" 26 ) 27 28 func (b *Builder) buildUse(inScope *scope, n *ast.Use) (outScope *scope) { 29 name := n.DBName.String() 30 ret := plan.NewUse(b.resolveDb(name)) 31 ret.Catalog = b.cat 32 outScope = inScope.push() 33 outScope.node = ret 34 return 35 } 36 37 func (b *Builder) buildPrepare(inScope *scope, n *ast.Prepare) (outScope *scope) { 38 outScope = inScope.push() 39 expr := n.Expr 40 if strings.HasPrefix(n.Expr, "@") { 41 // TODO resolve user variable 42 varName := strings.ToLower(strings.Trim(n.Expr, "@")) 43 _, val, err := b.ctx.GetUserVariable(b.ctx, varName) 44 if err != nil { 45 b.handleErr(err) 46 } 47 strVal, _, err := types.LongText.Convert(val) 48 if err != nil { 49 b.handleErr(err) 50 } 51 if strVal == nil { 52 expr = "NULL" 53 } else { 54 expr = strVal.(string) 55 } 56 } 57 58 sqlMode := sql.LoadSqlMode(b.ctx) 59 60 childStmt, err := ast.ParseWithOptions(expr, sqlMode.ParserOptions()) 61 if err != nil { 62 b.handleErr(err) 63 } 64 65 oldCtx := b.BindCtx() 66 defer func() { 67 b.bindCtx = oldCtx 68 }() 69 // test for query structure; bind variables will be discarded 70 b.bindCtx = &BindvarContext{resolveOnly: true} 71 childScope := b.build(inScope, childStmt, expr) 72 outScope.node = plan.NewPrepareQuery(n.Name, childScope.node) 73 return outScope 74 } 75 76 func (b *Builder) buildExecute(inScope *scope, n *ast.Execute) (outScope *scope) { 77 outScope = inScope.push() 78 exprs := make([]sql.Expression, len(n.VarList)) 79 for i, e := range n.VarList { 80 if strings.HasPrefix(e, "@") { 81 exprs[i] = expression.NewUserVar(strings.TrimPrefix(e, "@")) 82 } else { 83 exprs[i] = expression.NewUnresolvedProcedureParam(e) 84 } 85 } 86 outScope.node = plan.NewExecuteQuery(n.Name, exprs...) 87 return outScope 88 } 89 90 func (b *Builder) buildDeallocate(inScope *scope, n *ast.Deallocate) (outScope *scope) { 91 outScope = inScope.push() 92 outScope.node = plan.NewDeallocateQuery(n.Name) 93 return outScope 94 } 95 96 func (b *Builder) buildLockTables(inScope *scope, s *ast.LockTables) (outScope *scope) { 97 outScope = inScope.push() 98 tables := make([]*plan.TableLock, len(s.Tables)) 99 100 for i, tbl := range s.Tables { 101 tableScope := b.buildDataSource(inScope, tbl.Table) 102 write := tbl.Lock == ast.LockWrite || tbl.Lock == ast.LockLowPriorityWrite 103 104 // TODO: Allow for other types of locks (LOW PRIORITY WRITE & LOCAL READ) 105 tables[i] = &plan.TableLock{Table: tableScope.node, Write: write} 106 } 107 108 lockTables := plan.NewLockTables(tables) 109 lockTables.Catalog = b.cat 110 outScope.node = lockTables 111 return outScope 112 } 113 114 func (b *Builder) buildUnlockTables(inScope *scope, s *ast.UnlockTables) (outScope *scope) { 115 outScope = inScope.push() 116 unlockTables := plan.NewUnlockTables() 117 unlockTables.Catalog = b.cat 118 outScope.node = unlockTables 119 return outScope 120 }