github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/visit_plan_rule.go (about) 1 // Copyright 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 "context" 19 "sort" 20 "strconv" 21 22 "github.com/matrixorigin/matrixone/pkg/container/batch" 23 "github.com/matrixorigin/matrixone/pkg/sql/colexec" 24 "github.com/matrixorigin/matrixone/pkg/vm/process" 25 26 "github.com/matrixorigin/matrixone/pkg/common/moerr" 27 "github.com/matrixorigin/matrixone/pkg/container/types" 28 "github.com/matrixorigin/matrixone/pkg/pb/plan" 29 "github.com/matrixorigin/matrixone/pkg/sql/plan/rule" 30 ) 31 32 var ( 33 _ VisitPlanRule = &GetParamRule{} 34 _ VisitPlanRule = &ResetParamOrderRule{} 35 _ VisitPlanRule = &ResetParamRefRule{} 36 _ VisitPlanRule = &ResetVarRefRule{} 37 _ VisitPlanRule = &ConstantFoldRule{} 38 ) 39 40 var ( 41 constantFoldRule = rule.NewConstantFold(false) 42 ) 43 44 type GetParamRule struct { 45 params map[int]int 46 mapTypes map[int]int32 47 paramTypes []int32 48 schemas []*plan.ObjectRef 49 } 50 51 func NewGetParamRule() *GetParamRule { 52 return &GetParamRule{ 53 params: make(map[int]int), 54 mapTypes: make(map[int]int32), 55 } 56 } 57 58 func (rule *GetParamRule) MatchNode(node *Node) bool { 59 if node.NodeType == plan.Node_TABLE_SCAN { 60 rule.schemas = append(rule.schemas, &plan.ObjectRef{ 61 Server: node.ObjRef.Server, 62 Db: node.ObjRef.Db, 63 Schema: node.ObjRef.Schema, 64 Obj: node.ObjRef.Obj, 65 ServerName: node.ObjRef.ServerName, 66 DbName: node.ObjRef.DbName, 67 SchemaName: node.ObjRef.SchemaName, 68 ObjName: node.ObjRef.ObjName, 69 }) 70 } 71 return false 72 } 73 74 func (rule *GetParamRule) IsApplyExpr() bool { 75 return true 76 } 77 78 func (rule *GetParamRule) ApplyNode(node *Node) error { 79 return nil 80 } 81 82 func (rule *GetParamRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) { 83 switch exprImpl := e.Expr.(type) { 84 case *plan.Expr_F: 85 for i := range exprImpl.F.Args { 86 exprImpl.F.Args[i], _ = rule.ApplyExpr(exprImpl.F.Args[i]) 87 } 88 return e, nil 89 case *plan.Expr_P: 90 pos := int(exprImpl.P.Pos) 91 rule.params[pos] = 0 92 if e.Typ.Id == int32(types.T_any) && e.Typ.NotNullable { 93 // is not null, use string 94 rule.mapTypes[pos] = int32(types.T_varchar) 95 } else { 96 rule.mapTypes[pos] = e.Typ.Id 97 } 98 return e, nil 99 default: 100 return e, nil 101 } 102 } 103 104 func (rule *GetParamRule) SetParamOrder() { 105 argPos := []int{} 106 for pos := range rule.params { 107 argPos = append(argPos, pos) 108 } 109 sort.Ints(argPos) 110 rule.paramTypes = make([]int32, len(argPos)) 111 112 for idx, pos := range argPos { 113 rule.params[pos] = idx 114 rule.paramTypes[idx] = rule.mapTypes[pos] 115 } 116 } 117 118 // --------------------------- 119 120 type ResetParamOrderRule struct { 121 params map[int]int 122 } 123 124 func NewResetParamOrderRule(params map[int]int) *ResetParamOrderRule { 125 return &ResetParamOrderRule{ 126 params: params, 127 } 128 } 129 130 func (rule *ResetParamOrderRule) MatchNode(_ *Node) bool { 131 return false 132 } 133 134 func (rule *ResetParamOrderRule) IsApplyExpr() bool { 135 return true 136 } 137 138 func (rule *ResetParamOrderRule) ApplyNode(node *Node) error { 139 return nil 140 } 141 142 func (rule *ResetParamOrderRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) { 143 switch exprImpl := e.Expr.(type) { 144 case *plan.Expr_F: 145 for i := range exprImpl.F.Args { 146 exprImpl.F.Args[i], _ = rule.ApplyExpr(exprImpl.F.Args[i]) 147 } 148 return e, nil 149 case *plan.Expr_P: 150 exprImpl.P.Pos = int32(rule.params[int(exprImpl.P.Pos)]) 151 return e, nil 152 default: 153 return e, nil 154 } 155 } 156 157 // --------------------------- 158 159 type ResetParamRefRule struct { 160 ctx context.Context 161 params []*Expr 162 } 163 164 func NewResetParamRefRule(ctx context.Context, params []*Expr) *ResetParamRefRule { 165 return &ResetParamRefRule{ 166 ctx: ctx, 167 params: params, 168 } 169 } 170 171 func (rule *ResetParamRefRule) MatchNode(_ *Node) bool { 172 return false 173 } 174 175 func (rule *ResetParamRefRule) IsApplyExpr() bool { 176 return true 177 } 178 179 func (rule *ResetParamRefRule) ApplyNode(node *Node) error { 180 return nil 181 } 182 183 func (rule *ResetParamRefRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) { 184 var err error 185 switch exprImpl := e.Expr.(type) { 186 case *plan.Expr_F: 187 needResetFunction := false 188 for i, arg := range exprImpl.F.Args { 189 if _, ok := arg.Expr.(*plan.Expr_P); ok { 190 needResetFunction = true 191 } 192 exprImpl.F.Args[i], err = rule.ApplyExpr(arg) 193 if err != nil { 194 return nil, err 195 } 196 } 197 198 // reset function 199 if needResetFunction { 200 return bindFuncExprImplByPlanExpr(rule.ctx, exprImpl.F.Func.GetObjName(), exprImpl.F.Args) 201 } 202 return e, nil 203 case *plan.Expr_P: 204 return &plan.Expr{ 205 Typ: e.Typ, 206 Expr: rule.params[int(exprImpl.P.Pos)].Expr, 207 }, nil 208 default: 209 return e, nil 210 } 211 } 212 213 // --------------------------- 214 215 type ResetVarRefRule struct { 216 compCtx CompilerContext 217 proc *process.Process 218 bat *batch.Batch 219 } 220 221 func NewResetVarRefRule(compCtx CompilerContext, proc *process.Process) *ResetVarRefRule { 222 bat := batch.NewWithSize(0) 223 bat.Zs = []int64{1} 224 return &ResetVarRefRule{ 225 compCtx: compCtx, 226 proc: proc, 227 bat: bat, 228 } 229 } 230 231 func (rule *ResetVarRefRule) MatchNode(_ *Node) bool { 232 return false 233 } 234 235 func (rule *ResetVarRefRule) IsApplyExpr() bool { 236 return true 237 } 238 239 func (rule *ResetVarRefRule) ApplyNode(node *Node) error { 240 return nil 241 } 242 243 func (rule *ResetVarRefRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) { 244 var err error 245 switch exprImpl := e.Expr.(type) { 246 case *plan.Expr_F: 247 needResetFunction := false 248 for i, arg := range exprImpl.F.Args { 249 if _, ok := arg.Expr.(*plan.Expr_V); ok { 250 needResetFunction = true 251 } 252 exprImpl.F.Args[i], err = rule.ApplyExpr(arg) 253 if err != nil { 254 return nil, err 255 } 256 } 257 258 // reset function 259 if needResetFunction { 260 return bindFuncExprImplByPlanExpr(rule.getContext(), exprImpl.F.Func.GetObjName(), exprImpl.F.Args) 261 } 262 return e, nil 263 case *plan.Expr_V: 264 return getVarValue(e, rule) 265 case *plan.Expr_C: 266 if exprImpl.C.Src != nil { 267 if _, ok := exprImpl.C.Src.Expr.(*plan.Expr_V); ok { 268 return getVarValue(exprImpl.C.Src, rule) 269 } 270 } 271 return e, nil 272 default: 273 return e, nil 274 } 275 } 276 277 func (rule *ResetVarRefRule) getContext() context.Context { return rule.compCtx.GetContext() } 278 279 func getVarValue(e *plan.Expr, r *ResetVarRefRule) (*plan.Expr, error) { 280 exprImpl := e.Expr.(*plan.Expr_V) 281 var expr *plan.Expr 282 getVal, err := r.compCtx.ResolveVariable(exprImpl.V.Name, exprImpl.V.System, exprImpl.V.Global) 283 if err != nil { 284 return nil, err 285 } 286 287 switch val := getVal.(type) { 288 case string: 289 expr = makePlan2StringConstExprWithType(val) 290 case int: 291 expr = makePlan2Int64ConstExprWithType(int64(val)) 292 case uint8: 293 expr = makePlan2Int64ConstExprWithType(int64(val)) 294 case uint16: 295 expr = makePlan2Int64ConstExprWithType(int64(val)) 296 case uint32: 297 expr = makePlan2Int64ConstExprWithType(int64(val)) 298 case int8: 299 expr = makePlan2Int64ConstExprWithType(int64(val)) 300 case int16: 301 expr = makePlan2Int64ConstExprWithType(int64(val)) 302 case int32: 303 expr = makePlan2Int64ConstExprWithType(int64(val)) 304 case int64: 305 expr = makePlan2Int64ConstExprWithType(val) 306 case uint64: 307 expr = makePlan2Uint64ConstExprWithType(val) 308 case float32: 309 // when we build plan with constant in float, we cast them to decimal. 310 // so we cast @float_var to decimal too. 311 strVal := strconv.FormatFloat(float64(val), 'f', -1, 64) 312 expr, err = makePlan2DecimalExprWithType(r.getContext(), strVal) 313 case float64: 314 // when we build plan with constant in float, we cast them to decimal. 315 // so we cast @float_var to decimal too. 316 strVal := strconv.FormatFloat(val, 'f', -1, 64) 317 expr, err = makePlan2DecimalExprWithType(r.getContext(), strVal) 318 case bool: 319 expr = makePlan2BoolConstExprWithType(val) 320 case nil: 321 if e.Typ.Id == int32(types.T_any) { 322 expr = makePlan2NullConstExprWithType() 323 } else { 324 expr = &plan.Expr{ 325 Expr: &plan.Expr_C{ 326 C: &Const{ 327 Isnull: true, 328 }, 329 }, 330 Typ: e.Typ, 331 } 332 } 333 case types.Decimal64, types.Decimal128: 334 err = moerr.NewNYI(r.getContext(), "decimal var") 335 default: 336 err = moerr.NewParseError(r.getContext(), "type of var %q is not supported now", exprImpl.V.Name) 337 } 338 if err != nil { 339 return nil, err 340 } 341 if e.Typ.Id != int32(types.T_any) && expr.Typ.Id != e.Typ.Id { 342 expr, err = appendCastBeforeExpr(r.getContext(), expr, e.Typ) 343 } 344 if err != nil { 345 return nil, err 346 } 347 if c, ok := expr.Expr.(*plan.Expr_C); ok { 348 c.C.Src = e 349 } else if _, ok = expr.Expr.(*plan.Expr_F); ok { 350 vec, err := colexec.EvalExpr(r.bat, r.proc, expr) 351 if err != nil { 352 return nil, err 353 } 354 constValue := rule.GetConstantValue(vec, true) 355 constValue.Src = e 356 expr.Typ = &plan.Type{Id: int32(vec.Typ.Oid), Precision: vec.Typ.Precision, Scale: vec.Typ.Scale, Width: vec.Typ.Width, Size: vec.Typ.Size} 357 expr.Expr = &plan.Expr_C{ 358 C: constValue, 359 } 360 } 361 return expr, err 362 } 363 364 type ConstantFoldRule struct { 365 compCtx CompilerContext 366 rule *rule.ConstantFold 367 } 368 369 func NewConstantFoldRule(compCtx CompilerContext) *ConstantFoldRule { 370 return &ConstantFoldRule{ 371 compCtx: compCtx, 372 rule: constantFoldRule, 373 } 374 } 375 376 func (r *ConstantFoldRule) MatchNode(node *Node) bool { 377 return r.rule.Match(node) 378 } 379 380 func (r *ConstantFoldRule) IsApplyExpr() bool { 381 return false 382 } 383 384 func (r *ConstantFoldRule) ApplyNode(node *Node) error { 385 r.rule.Apply(node, nil, r.compCtx.GetProcess()) 386 return nil 387 } 388 389 func (r *ConstantFoldRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) { 390 return e, nil 391 } 392 393 type RecomputeRealTimeRelatedFuncRule struct { 394 bat *batch.Batch 395 proc *process.Process 396 } 397 398 func NewRecomputeRealTimeRelatedFuncRule(proc *process.Process) *RecomputeRealTimeRelatedFuncRule { 399 bat := batch.NewWithSize(0) 400 bat.Zs = []int64{1} 401 return &RecomputeRealTimeRelatedFuncRule{bat, proc} 402 } 403 404 func (r *RecomputeRealTimeRelatedFuncRule) MatchNode(_ *Node) bool { 405 return false 406 } 407 408 func (r *RecomputeRealTimeRelatedFuncRule) IsApplyExpr() bool { 409 return true 410 } 411 412 func (r *RecomputeRealTimeRelatedFuncRule) ApplyNode(_ *Node) error { 413 return nil 414 } 415 416 func (r *RecomputeRealTimeRelatedFuncRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) { 417 var err error 418 switch exprImpl := e.Expr.(type) { 419 case *plan.Expr_F: 420 for i, arg := range exprImpl.F.Args { 421 exprImpl.F.Args[i], err = r.ApplyExpr(arg) 422 if err != nil { 423 return nil, err 424 } 425 } 426 return e, nil 427 case *plan.Expr_C: 428 if exprImpl.C.Src != nil { 429 if _, ok := exprImpl.C.Src.Expr.(*plan.Expr_F); ok { 430 vec, err := colexec.EvalExpr(r.bat, r.proc, exprImpl.C.Src) 431 if err != nil { 432 return nil, err 433 } 434 constValue := rule.GetConstantValue(vec, false) 435 constValue.Src = exprImpl.C.Src 436 exprImpl.C = constValue 437 } 438 } 439 return e, nil 440 default: 441 return e, nil 442 } 443 }