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