github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/build_dcl.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 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 "math" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 "github.com/matrixorigin/matrixone/pkg/pb/plan" 22 "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect/mysql" 23 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 24 ) 25 26 func getPreparePlan(ctx CompilerContext, stmt tree.Statement) (*Plan, error) { 27 if s, ok := stmt.(*tree.Insert); ok { 28 if _, ok := s.Rows.Select.(*tree.ValuesClause); ok { 29 return BuildPlan(ctx, stmt, true) 30 } 31 } else if s, ok := stmt.(*tree.Replace); ok { 32 if _, ok := s.Rows.Select.(*tree.ValuesClause); ok { 33 return BuildPlan(ctx, stmt, true) 34 } 35 } 36 37 switch stmt := stmt.(type) { 38 case *tree.Select, *tree.ParenSelect, 39 *tree.Update, *tree.Delete, *tree.Insert, 40 *tree.ShowDatabases, *tree.ShowTables, *tree.ShowSequences, *tree.ShowColumns, 41 *tree.ShowCreateDatabase, *tree.ShowCreateTable: 42 opt := NewPrepareOptimizer(ctx) 43 optimized, err := opt.Optimize(stmt, true) 44 if err != nil { 45 return nil, err 46 } 47 return &Plan{ 48 Plan: &Plan_Query{ 49 Query: optimized, 50 }, 51 }, nil 52 default: 53 return BuildPlan(ctx, stmt, true) 54 } 55 } 56 57 func buildPrepare(stmt tree.Prepare, ctx CompilerContext) (*Plan, error) { 58 var preparePlan *Plan 59 var err error 60 var stmtName string 61 62 switch pstmt := stmt.(type) { 63 case *tree.PrepareStmt: 64 stmtName = string(pstmt.Name) 65 preparePlan, err = getPreparePlan(ctx, pstmt.Stmt) 66 if err != nil { 67 return nil, err 68 } 69 preparePlan.IsPrepare = true 70 71 case *tree.PrepareString: 72 var v interface{} 73 v, err = ctx.ResolveVariable("lower_case_table_names", true, true) 74 if err != nil { 75 v = int64(1) 76 } 77 stmts, err := mysql.Parse(ctx.GetContext(), pstmt.Sql, v.(int64), 0) 78 defer func() { 79 for _, s := range stmts { 80 s.Free() 81 } 82 }() 83 if err != nil { 84 return nil, err 85 } 86 if len(stmts) > 1 { 87 return nil, moerr.NewInvalidInput(ctx.GetContext(), "cannot prepare multi statements") 88 } 89 stmtName = string(pstmt.Name) 90 preparePlan, err = getPreparePlan(ctx, stmts[0]) 91 if err != nil { 92 return nil, err 93 } 94 preparePlan.IsPrepare = true 95 } 96 97 schemas, paramTypes, err := ResetPreparePlan(ctx, preparePlan) 98 if err != nil { 99 return nil, err 100 } 101 if len(paramTypes) > math.MaxUint16 { 102 return nil, moerr.NewErrTooManyParameter(ctx.GetContext()) 103 } 104 105 prepare := &plan.Prepare{ 106 Name: stmtName, 107 Schemas: schemas, 108 Plan: preparePlan, 109 ParamTypes: paramTypes, 110 } 111 112 return &Plan{ 113 Plan: &plan.Plan_Dcl{ 114 Dcl: &plan.DataControl{ 115 DclType: plan.DataControl_PREPARE, 116 Control: &plan.DataControl_Prepare{ 117 Prepare: prepare, 118 }, 119 }, 120 }, 121 }, nil 122 } 123 124 func buildExecute(stmt *tree.Execute, ctx CompilerContext) (*Plan, error) { 125 builder := NewQueryBuilder(plan.Query_SELECT, ctx, false) 126 binder := NewWhereBinder(builder, &BindContext{}) 127 128 args := make([]*Expr, len(stmt.Variables)) 129 for idx, variable := range stmt.Variables { 130 arg, err := binder.baseBindExpr(variable, 0, true) 131 if err != nil { 132 return nil, err 133 } 134 args[idx] = arg 135 } 136 137 execute := &plan.Execute{ 138 Name: string(stmt.Name), 139 Args: args, 140 } 141 142 return &Plan{ 143 Plan: &plan.Plan_Dcl{ 144 Dcl: &plan.DataControl{ 145 DclType: plan.DataControl_EXECUTE, 146 Control: &plan.DataControl_Execute{ 147 Execute: execute, 148 }, 149 }, 150 }, 151 }, nil 152 } 153 154 func buildDeallocate(stmt *tree.Deallocate, _ CompilerContext) (*Plan, error) { 155 deallocate := &plan.Deallocate{ 156 Name: string(stmt.Name), 157 } 158 159 return &Plan{ 160 Plan: &plan.Plan_Dcl{ 161 Dcl: &plan.DataControl{ 162 DclType: plan.DataControl_DEALLOCATE, 163 Control: &plan.DataControl_Deallocate{ 164 Deallocate: deallocate, 165 }, 166 }, 167 }, 168 }, nil 169 } 170 171 func buildSetVariables(stmt *tree.SetVar, ctx CompilerContext) (*Plan, error) { 172 var err error 173 items := make([]*plan.SetVariablesItem, len(stmt.Assignments)) 174 175 builder := NewQueryBuilder(plan.Query_SELECT, ctx, false) 176 binder := NewWhereBinder(builder, &BindContext{}) 177 178 for idx, assignment := range stmt.Assignments { 179 item := &plan.SetVariablesItem{ 180 System: assignment.System, 181 Global: assignment.Global, 182 Name: assignment.Name, 183 } 184 if assignment.Value == nil { 185 return nil, moerr.NewInvalidInput(ctx.GetContext(), "Set statement has no value") 186 } 187 item.Value, err = binder.baseBindExpr(assignment.Value, 0, true) 188 if err != nil { 189 return nil, err 190 } 191 if assignment.Reserved != nil { 192 item.Reserved, err = binder.baseBindExpr(assignment.Reserved, 0, true) 193 if err != nil { 194 return nil, err 195 } 196 } 197 items[idx] = item 198 } 199 200 setVariables := &plan.SetVariables{ 201 Items: items, 202 } 203 204 return &Plan{ 205 Plan: &plan.Plan_Dcl{ 206 Dcl: &plan.DataControl{ 207 DclType: plan.DataControl_SET_VARIABLES, 208 Control: &plan.DataControl_SetVariables{ 209 SetVariables: setVariables, 210 }, 211 }, 212 }, 213 }, nil 214 } 215 216 func buildCreateAccount(stmt *tree.CreateAccount, ctx CompilerContext, isPrepareStmt bool) (*Plan, error) { 217 params := []tree.Expr{ 218 stmt.Name, 219 stmt.AuthOption.AdminName, 220 stmt.AuthOption.IdentifiedType.Str, 221 } 222 paramTypes, err := getParamTypes(params, ctx, isPrepareStmt) 223 if err != nil { 224 return nil, err 225 } 226 227 return &Plan{ 228 Plan: &plan.Plan_Dcl{ 229 Dcl: &plan.DataControl{ 230 DclType: plan.DataControl_CREATE_ACCOUNT, 231 Control: &plan.DataControl_Other{ 232 Other: &plan.OtherDCL{ 233 ParamTypes: paramTypes, 234 }, 235 }, 236 }, 237 }, 238 }, nil 239 } 240 241 func buildAlterAccount(stmt *tree.AlterAccount, ctx CompilerContext, isPrepareStmt bool) (*Plan, error) { 242 params := []tree.Expr{ 243 stmt.Name, 244 stmt.AuthOption.AdminName, 245 stmt.AuthOption.IdentifiedType.Str, 246 } 247 paramTypes, err := getParamTypes(params, ctx, isPrepareStmt) 248 if err != nil { 249 return nil, err 250 } 251 252 return &Plan{ 253 Plan: &plan.Plan_Dcl{ 254 Dcl: &plan.DataControl{ 255 DclType: plan.DataControl_ALTER_ACCOUNT, 256 Control: &plan.DataControl_Other{ 257 Other: &plan.OtherDCL{ 258 ParamTypes: paramTypes, 259 }, 260 }, 261 }, 262 }, 263 }, nil 264 } 265 266 func buildDropAccount(stmt *tree.DropAccount, ctx CompilerContext, isPrepareStmt bool) (*Plan, error) { 267 params := []tree.Expr{ 268 stmt.Name, 269 } 270 paramTypes, err := getParamTypes(params, ctx, isPrepareStmt) 271 if err != nil { 272 return nil, err 273 } 274 275 return &Plan{ 276 Plan: &plan.Plan_Dcl{ 277 Dcl: &plan.DataControl{ 278 DclType: plan.DataControl_DROP_ACCOUNT, 279 Control: &plan.DataControl_Other{ 280 Other: &plan.OtherDCL{ 281 ParamTypes: paramTypes, 282 }, 283 }, 284 }, 285 }, 286 }, nil 287 }