github.com/XiaoMi/Gaea@v1.2.5/proxy/plan/plan_delete.go (about) 1 // Copyright 2019 The Gaea Authors. All Rights Reserved. 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 plan 16 17 import ( 18 "fmt" 19 20 "github.com/XiaoMi/Gaea/mysql" 21 "github.com/XiaoMi/Gaea/parser/ast" 22 "github.com/XiaoMi/Gaea/proxy/router" 23 "github.com/XiaoMi/Gaea/util" 24 ) 25 26 // DeletePlan is the plan for delete statement 27 type DeletePlan struct { 28 basePlan 29 *TableAliasStmtInfo 30 31 stmt *ast.DeleteStmt 32 sqls map[string]map[string][]string 33 } 34 35 // NewDeletePlan constructor of DeletePlan 36 func NewDeletePlan(stmt *ast.DeleteStmt, db, sql string, r *router.Router) *DeletePlan { 37 return &DeletePlan{ 38 TableAliasStmtInfo: NewTableAliasStmtInfo(db, sql, r), 39 stmt: stmt, 40 } 41 } 42 43 // ExecuteIn implement Plan 44 func (p *DeletePlan) ExecuteIn(reqCtx *util.RequestContext, sess Executor) (*mysql.Result, error) { 45 sqls := p.sqls 46 if sqls == nil { 47 return nil, fmt.Errorf("SQL has not generated") 48 } 49 50 if len(sqls) == 0 { 51 return nil, nil 52 } 53 54 rs, err := sess.ExecuteSQLs(reqCtx, sqls) 55 if err != nil { 56 return nil, fmt.Errorf("execute in UpdatePlan error: %v", err) 57 } 58 59 r, err := MergeExecResult(rs) 60 61 if err != nil { 62 return nil, fmt.Errorf("merge update result error: %v", err) 63 } 64 65 return r, nil 66 } 67 68 // HandleDeletePlan build a DeletePlan 69 func HandleDeletePlan(p *DeletePlan) error { 70 if err := handleDeleteTableRefs(p); err != nil { 71 return fmt.Errorf("handle From error: %v", err) 72 } 73 74 if err := handleDeleteWhere(p); err != nil { 75 return fmt.Errorf("handle Where error: %v", err) 76 } 77 78 if err := handleDeleteOrderBy(p); err != nil { 79 return fmt.Errorf("handle OrderBy error: %v", err) 80 } 81 82 // Limit clause does not need to handle 83 84 // handle global table 85 if err := postHandleGlobalTableRouteResultInModify(p.StmtInfo); err != nil { 86 return fmt.Errorf("post handle global table error: %v", err) 87 } 88 89 sqls, err := generateShardingSQLs(p.stmt, p.GetRouteResult(), p.router) 90 if err != nil { 91 return fmt.Errorf("generate sqls error: %v", err) 92 } 93 94 p.sqls = sqls 95 return nil 96 } 97 98 func handleDeleteTableRefs(p *DeletePlan) error { 99 tableRefs := p.stmt.TableRefs 100 if tableRefs == nil { 101 return nil 102 } 103 104 join := tableRefs.TableRefs 105 if join == nil { 106 return nil 107 } 108 109 if join.Right != nil { 110 return fmt.Errorf("does not support update multiple tables in sharding") 111 } 112 113 return handleJoin(p.TableAliasStmtInfo, join) 114 } 115 116 func handleDeleteWhere(p *DeletePlan) error { 117 stmt := p.stmt 118 if stmt.Where == nil { 119 return nil 120 } 121 122 has, result, decorator, err := handleComparisonExpr(p.TableAliasStmtInfo, stmt.Where) 123 if err != nil { 124 return fmt.Errorf("rewrite Where error: %v", err) 125 } 126 if has { 127 p.GetRouteResult().Inter(result) 128 } 129 stmt.Where = decorator 130 return nil 131 132 } 133 134 func handleDeleteOrderBy(p *DeletePlan) error { 135 order := p.stmt.Order 136 if order == nil { 137 return nil 138 } 139 140 for _, item := range order.Items { 141 columnExpr, ok := item.Expr.(*ast.ColumnNameExpr) 142 if !ok { 143 return fmt.Errorf("ByItem.Expr is not a ColumnNameExpr") 144 } 145 146 rule, need, isAlias, err := NeedCreateColumnNameExprDecoratorInField(p.TableAliasStmtInfo, columnExpr) 147 if err != nil { 148 return err 149 } 150 151 if need { 152 decorator := CreateColumnNameExprDecorator(columnExpr, rule, isAlias, p.GetRouteResult()) 153 item.Expr = decorator 154 } 155 } 156 157 return nil 158 }