github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/utils.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 "bytes" 19 "container/list" 20 "context" 21 "encoding/csv" 22 "fmt" 23 "math" 24 "path" 25 "strings" 26 27 "github.com/matrixorigin/matrixone/pkg/common/moerr" 28 "github.com/matrixorigin/matrixone/pkg/common/mpool" 29 "github.com/matrixorigin/matrixone/pkg/container/batch" 30 "github.com/matrixorigin/matrixone/pkg/container/types" 31 "github.com/matrixorigin/matrixone/pkg/container/vector" 32 "github.com/matrixorigin/matrixone/pkg/fileservice" 33 "github.com/matrixorigin/matrixone/pkg/pb/plan" 34 "github.com/matrixorigin/matrixone/pkg/sql/colexec" 35 "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" 36 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 37 "github.com/matrixorigin/matrixone/pkg/sql/plan/function" 38 "github.com/matrixorigin/matrixone/pkg/sql/plan/rule" 39 "github.com/matrixorigin/matrixone/pkg/sql/util" 40 "github.com/matrixorigin/matrixone/pkg/vm/process" 41 ) 42 43 func GetBindings(expr *plan.Expr) []int32 { 44 bindingSet := doGetBindings(expr) 45 bindings := make([]int32, 0, len(bindingSet)) 46 for id := range bindingSet { 47 bindings = append(bindings, id) 48 } 49 return bindings 50 } 51 52 func doGetBindings(expr *plan.Expr) map[int32]bool { 53 res := make(map[int32]bool) 54 55 switch expr := expr.Expr.(type) { 56 case *plan.Expr_Col: 57 res[expr.Col.RelPos] = true 58 59 case *plan.Expr_F: 60 for _, child := range expr.F.Args { 61 for id := range doGetBindings(child) { 62 res[id] = true 63 } 64 } 65 } 66 67 return res 68 } 69 70 func hasParam(expr *plan.Expr) bool { 71 switch exprImpl := expr.Expr.(type) { 72 case *plan.Expr_P: 73 return true 74 75 case *plan.Expr_F: 76 for _, arg := range exprImpl.F.Args { 77 if hasParam(arg) { 78 return true 79 } 80 } 81 return false 82 83 case *plan.Expr_List: 84 for _, arg := range exprImpl.List.List { 85 if hasParam(arg) { 86 return true 87 } 88 } 89 return false 90 91 default: 92 return false 93 } 94 } 95 96 func hasCorrCol(expr *plan.Expr) bool { 97 switch exprImpl := expr.Expr.(type) { 98 case *plan.Expr_Corr: 99 return true 100 101 case *plan.Expr_F: 102 for _, arg := range exprImpl.F.Args { 103 if hasCorrCol(arg) { 104 return true 105 } 106 } 107 return false 108 109 case *plan.Expr_List: 110 for _, arg := range exprImpl.List.List { 111 if hasCorrCol(arg) { 112 return true 113 } 114 } 115 return false 116 117 default: 118 return false 119 } 120 } 121 122 func hasSubquery(expr *plan.Expr) bool { 123 switch exprImpl := expr.Expr.(type) { 124 case *plan.Expr_Sub: 125 return true 126 127 case *plan.Expr_F: 128 for _, arg := range exprImpl.F.Args { 129 if hasSubquery(arg) { 130 return true 131 } 132 } 133 return false 134 135 case *plan.Expr_List: 136 for _, arg := range exprImpl.List.List { 137 if hasSubquery(arg) { 138 return true 139 } 140 } 141 return false 142 143 default: 144 return false 145 } 146 } 147 148 func HasTag(expr *plan.Expr, tag int32) bool { 149 switch exprImpl := expr.Expr.(type) { 150 case *plan.Expr_Col: 151 return exprImpl.Col.RelPos == tag 152 153 case *plan.Expr_F: 154 for _, arg := range exprImpl.F.Args { 155 if HasTag(arg, tag) { 156 return true 157 } 158 } 159 return false 160 161 case *plan.Expr_List: 162 for _, arg := range exprImpl.List.List { 163 if HasTag(arg, tag) { 164 return true 165 } 166 } 167 return false 168 169 default: 170 return false 171 } 172 } 173 174 func decreaseDepthAndDispatch(preds []*plan.Expr) ([]*plan.Expr, []*plan.Expr) { 175 filterPreds := make([]*plan.Expr, 0, len(preds)) 176 joinPreds := make([]*plan.Expr, 0, len(preds)) 177 178 for _, pred := range preds { 179 newPred, correlated := decreaseDepth(pred) 180 if !correlated { 181 joinPreds = append(joinPreds, newPred) 182 continue 183 } 184 filterPreds = append(filterPreds, newPred) 185 } 186 187 return filterPreds, joinPreds 188 } 189 190 func decreaseDepth(expr *plan.Expr) (*plan.Expr, bool) { 191 var correlated bool 192 193 switch exprImpl := expr.Expr.(type) { 194 case *plan.Expr_Corr: 195 if exprImpl.Corr.Depth > 1 { 196 exprImpl.Corr.Depth-- 197 correlated = true 198 } else { 199 expr.Expr = &plan.Expr_Col{ 200 Col: &plan.ColRef{ 201 RelPos: exprImpl.Corr.RelPos, 202 ColPos: exprImpl.Corr.ColPos, 203 }, 204 } 205 } 206 207 case *plan.Expr_F: 208 var tmp bool 209 for i, arg := range exprImpl.F.Args { 210 exprImpl.F.Args[i], tmp = decreaseDepth(arg) 211 correlated = correlated || tmp 212 } 213 } 214 215 return expr, correlated 216 } 217 218 func getJoinSide(expr *plan.Expr, leftTags, rightTags map[int32]bool, markTag int32) (side int8) { 219 switch exprImpl := expr.Expr.(type) { 220 case *plan.Expr_F: 221 for _, arg := range exprImpl.F.Args { 222 side |= getJoinSide(arg, leftTags, rightTags, markTag) 223 } 224 225 case *plan.Expr_Col: 226 if leftTags[exprImpl.Col.RelPos] { 227 side = JoinSideLeft 228 } else if rightTags[exprImpl.Col.RelPos] { 229 side = JoinSideRight 230 } else if exprImpl.Col.RelPos == markTag { 231 side = JoinSideMark 232 } 233 234 case *plan.Expr_Corr: 235 side = JoinSideCorrelated 236 } 237 238 return 239 } 240 241 func containsTag(expr *plan.Expr, tag int32) bool { 242 var ret bool 243 244 switch exprImpl := expr.Expr.(type) { 245 case *plan.Expr_F: 246 for _, arg := range exprImpl.F.Args { 247 ret = ret || containsTag(arg, tag) 248 } 249 250 case *plan.Expr_Col: 251 return exprImpl.Col.RelPos == tag 252 } 253 254 return ret 255 } 256 257 func replaceColRefs(expr *plan.Expr, tag int32, projects []*plan.Expr) *plan.Expr { 258 switch exprImpl := expr.Expr.(type) { 259 case *plan.Expr_F: 260 for i, arg := range exprImpl.F.Args { 261 exprImpl.F.Args[i] = replaceColRefs(arg, tag, projects) 262 } 263 264 case *plan.Expr_Col: 265 colRef := exprImpl.Col 266 if colRef.RelPos == tag { 267 expr = DeepCopyExpr(projects[colRef.ColPos]) 268 } 269 case *plan.Expr_W: 270 replaceColRefs(exprImpl.W.WindowFunc, tag, projects) 271 for _, arg := range exprImpl.W.PartitionBy { 272 replaceColRefs(arg, tag, projects) 273 } 274 for _, order := range exprImpl.W.OrderBy { 275 replaceColRefs(order.Expr, tag, projects) 276 } 277 } 278 279 return expr 280 } 281 282 func replaceColRefsForSet(expr *plan.Expr, projects []*plan.Expr) *plan.Expr { 283 switch exprImpl := expr.Expr.(type) { 284 case *plan.Expr_F: 285 for i, arg := range exprImpl.F.Args { 286 exprImpl.F.Args[i] = replaceColRefsForSet(arg, projects) 287 } 288 289 case *plan.Expr_Col: 290 expr = DeepCopyExpr(projects[exprImpl.Col.ColPos]) 291 } 292 293 return expr 294 } 295 296 func splitAndBindCondition(astExpr tree.Expr, expandAlias ExpandAliasMode, ctx *BindContext) ([]*plan.Expr, error) { 297 conds := splitAstConjunction(astExpr) 298 exprs := make([]*plan.Expr, len(conds)) 299 300 for i, cond := range conds { 301 cond, err := ctx.qualifyColumnNames(cond, expandAlias) 302 if err != nil { 303 return nil, err 304 } 305 306 expr, err := ctx.binder.BindExpr(cond, 0, true) 307 if err != nil { 308 return nil, err 309 } 310 // expr must be bool type, if not, try to do type convert 311 // but just ignore the subQuery. It will be solved at optimizer. 312 if expr.GetSub() == nil { 313 expr, err = makePlan2CastExpr(ctx.binder.GetContext(), expr, plan.Type{Id: int32(types.T_bool)}) 314 if err != nil { 315 return nil, err 316 } 317 } 318 exprs[i] = expr 319 } 320 321 return exprs, nil 322 } 323 324 // splitAstConjunction split a expression to a list of AND conditions. 325 func splitAstConjunction(astExpr tree.Expr) []tree.Expr { 326 var astExprs []tree.Expr 327 switch typ := astExpr.(type) { 328 case nil: 329 case *tree.AndExpr: 330 astExprs = append(astExprs, splitAstConjunction(typ.Left)...) 331 astExprs = append(astExprs, splitAstConjunction(typ.Right)...) 332 case *tree.ParenExpr: 333 astExprs = append(astExprs, splitAstConjunction(typ.Expr)...) 334 default: 335 astExprs = append(astExprs, astExpr) 336 } 337 return astExprs 338 } 339 340 // applyDistributivity (X AND B) OR (X AND C) OR (X AND D) => X AND (B OR C OR D) 341 // TODO: move it into optimizer 342 func applyDistributivity(ctx context.Context, expr *plan.Expr) *plan.Expr { 343 switch exprImpl := expr.Expr.(type) { 344 case *plan.Expr_F: 345 for i, arg := range exprImpl.F.Args { 346 exprImpl.F.Args[i] = applyDistributivity(ctx, arg) 347 } 348 349 if exprImpl.F.Func.ObjName != "or" { 350 break 351 } 352 353 leftConds := splitPlanConjunction(exprImpl.F.Args[0]) 354 rightConds := splitPlanConjunction(exprImpl.F.Args[1]) 355 356 condMap := make(map[string]int) 357 358 for _, cond := range rightConds { 359 condMap[cond.String()] = JoinSideRight 360 } 361 362 var commonConds, leftOnlyConds, rightOnlyConds []*plan.Expr 363 364 for _, cond := range leftConds { 365 exprStr := cond.String() 366 367 if condMap[exprStr] == JoinSideRight { 368 commonConds = append(commonConds, cond) 369 condMap[exprStr] = JoinSideBoth 370 } else { 371 leftOnlyConds = append(leftOnlyConds, cond) 372 condMap[exprStr] = JoinSideLeft 373 } 374 } 375 376 for _, cond := range rightConds { 377 if condMap[cond.String()] == JoinSideRight { 378 rightOnlyConds = append(rightOnlyConds, cond) 379 } 380 } 381 382 if len(commonConds) == 0 { 383 return expr 384 } 385 386 expr, _ = combinePlanConjunction(ctx, commonConds) 387 388 if len(leftOnlyConds) == 0 || len(rightOnlyConds) == 0 { 389 return expr 390 } 391 392 leftExpr, _ := combinePlanConjunction(ctx, leftOnlyConds) 393 rightExpr, _ := combinePlanConjunction(ctx, rightOnlyConds) 394 395 leftExpr, _ = BindFuncExprImplByPlanExpr(ctx, "or", []*plan.Expr{leftExpr, rightExpr}) 396 397 expr, _ = BindFuncExprImplByPlanExpr(ctx, "and", []*plan.Expr{expr, leftExpr}) 398 } 399 400 return expr 401 } 402 403 func unionSlice(left, right []string) []string { 404 if len(left) < 1 { 405 return right 406 } 407 if len(right) < 1 { 408 return left 409 } 410 m := make(map[string]bool, len(left)+len(right)) 411 for _, s := range left { 412 m[s] = true 413 } 414 for _, s := range right { 415 m[s] = true 416 } 417 ret := make([]string, 0) 418 for s := range m { 419 ret = append(ret, s) 420 } 421 return ret 422 } 423 424 func intersectSlice(left, right []string) []string { 425 if len(left) < 1 || len(right) < 1 { 426 return left 427 } 428 m := make(map[string]bool, len(left)+len(right)) 429 for _, s := range left { 430 m[s] = true 431 } 432 ret := make([]string, 0) 433 for _, s := range right { 434 if _, ok := m[s]; ok { 435 ret = append(ret, s) 436 } 437 } 438 return ret 439 } 440 441 /* 442 DNF means disjunctive normal form, for example (a and b) or (c and d) or (e and f) 443 if we have a DNF filter, for example (c1=1 and c2=1) or (c1=2 and c2=2) 444 we can have extra filter: (c1=1 or c1=2) and (c2=1 or c2=2), which can be pushed down to optimize join 445 446 checkDNF scan the expr and return all groups of cond 447 for example (c1=1 and c2=1) or (c1=2 and c3=2), c1 is a group because it appears in all disjunctives 448 and c2,c3 is not a group 449 450 walkThroughDNF accept a keyword string, walk through the expr, 451 and extract all the conds which contains the keyword 452 */ 453 func checkDNF(expr *plan.Expr) []string { 454 var ret []string 455 switch exprImpl := expr.Expr.(type) { 456 case *plan.Expr_F: 457 if exprImpl.F.Func.ObjName == "or" { 458 left := checkDNF(exprImpl.F.Args[0]) 459 right := checkDNF(exprImpl.F.Args[1]) 460 return intersectSlice(left, right) 461 } 462 for _, arg := range exprImpl.F.Args { 463 ret = unionSlice(ret, checkDNF(arg)) 464 } 465 return ret 466 467 case *plan.Expr_Corr: 468 ret = append(ret, exprImpl.Corr.String()) 469 case *plan.Expr_Col: 470 ret = append(ret, exprImpl.Col.String()) 471 } 472 return ret 473 } 474 475 func walkThroughDNF(ctx context.Context, expr *plan.Expr, keywords string) *plan.Expr { 476 var retExpr *plan.Expr 477 switch exprImpl := expr.Expr.(type) { 478 case *plan.Expr_F: 479 if exprImpl.F.Func.ObjName == "or" { 480 left := walkThroughDNF(ctx, exprImpl.F.Args[0], keywords) 481 right := walkThroughDNF(ctx, exprImpl.F.Args[1], keywords) 482 if left != nil && right != nil { 483 retExpr, _ = BindFuncExprImplByPlanExpr(ctx, "or", []*plan.Expr{left, right}) 484 return retExpr 485 } 486 } else if exprImpl.F.Func.ObjName == "and" { 487 left := walkThroughDNF(ctx, exprImpl.F.Args[0], keywords) 488 right := walkThroughDNF(ctx, exprImpl.F.Args[1], keywords) 489 if left == nil { 490 return right 491 } else if right == nil { 492 return left 493 } else { 494 retExpr, _ = BindFuncExprImplByPlanExpr(ctx, "and", []*plan.Expr{left, right}) 495 return retExpr 496 } 497 } else { 498 for _, arg := range exprImpl.F.Args { 499 if walkThroughDNF(ctx, arg, keywords) == nil { 500 return nil 501 } 502 } 503 return expr 504 } 505 506 case *plan.Expr_Corr: 507 if exprImpl.Corr.String() == keywords { 508 return expr 509 } else { 510 return nil 511 } 512 case *plan.Expr_Col: 513 if exprImpl.Col.String() == keywords { 514 return expr 515 } else { 516 return nil 517 } 518 } 519 return expr 520 } 521 522 // deduction of new predicates for join on list. for example join on a=b and b=c, then a=c can be deduced 523 func deduceNewOnList(onList []*plan.Expr) []*plan.Expr { 524 var newPreds []*plan.Expr 525 lenOnlist := len(onList) 526 for i := range onList { 527 ok1, col1, col2 := checkStrictJoinPred(onList[i]) 528 if !ok1 { 529 continue 530 } 531 for j := i + 1; j < lenOnlist; j++ { 532 ok2, col3, col4 := checkStrictJoinPred(onList[j]) 533 if ok2 { 534 ok, newPred := deduceTranstivity(onList[i], col1, col2, col3, col4) 535 if ok { 536 newPreds = append(newPreds, newPred) 537 } 538 } 539 } 540 } 541 return newPreds 542 } 543 544 // deduction of new predicates. for example join on a=b where b=1, then a=1 can be deduced 545 func deduceNewFilterList(filters, onList []*plan.Expr) []*plan.Expr { 546 var newFilters []*plan.Expr 547 for _, onPred := range onList { 548 ret, col1, col2 := checkStrictJoinPred(onPred) 549 if !ret { 550 continue 551 } 552 for _, filter := range filters { 553 col := extractColRefInFilter(filter) 554 if col != nil { 555 newExpr := DeepCopyExpr(filter) 556 if substituteMatchColumn(newExpr, col1, col2) { 557 newFilters = append(newFilters, newExpr) 558 } 559 } 560 } 561 } 562 return newFilters 563 } 564 565 func canMergeToBetweenAnd(expr1, expr2 *plan.Expr) bool { 566 col1, _, _, _ := extractColRefAndLiteralsInFilter(expr1) 567 col2, _, _, _ := extractColRefAndLiteralsInFilter(expr2) 568 if col1 == nil || col2 == nil { 569 return false 570 } 571 if col1.ColPos != col2.ColPos || col1.RelPos != col2.RelPos { 572 return false 573 } 574 575 fnName1 := expr1.GetF().Func.ObjName 576 fnName2 := expr2.GetF().Func.ObjName 577 if fnName1 == ">" || fnName1 == ">=" { 578 return fnName2 == "<" || fnName2 == "<=" 579 } 580 if fnName1 == "<" || fnName1 == "<=" { 581 return fnName2 == ">" || fnName2 == ">=" 582 } 583 return false 584 } 585 586 func extractColRefAndLiteralsInFilter(expr *plan.Expr) (col *ColRef, litType types.T, literals []*Const, colFnName string) { 587 fn := expr.GetF() 588 if fn == nil || len(fn.Args) == 0 { 589 return 590 } 591 592 col = fn.Args[0].GetCol() 593 if col == nil { 594 if fn0 := fn.Args[0].GetF(); fn0 != nil { 595 switch fn0.Func.ObjName { 596 case "year": 597 colFnName = "year" 598 col = fn0.Args[0].GetCol() 599 } 600 } 601 } 602 if col == nil { 603 return 604 } 605 606 switch fn.Func.ObjName { 607 case "=", ">", "<", ">=", "<=": 608 lit := fn.Args[1].GetLit() 609 if lit == nil { 610 return 611 } 612 litType = types.T(fn.Args[0].Typ.Id) 613 literals = []*Const{lit} 614 615 case "between": 616 litType = types.T(fn.Args[0].Typ.Id) 617 literals = []*Const{fn.Args[1].GetLit(), fn.Args[2].GetLit()} 618 } 619 620 return 621 } 622 623 // for predicate deduction, filter must be like func(col)>1 , or (col=1) or (col=2) 624 // and only 1 colRef is allowd in the filter 625 func extractColRefInFilter(expr *plan.Expr) *ColRef { 626 switch exprImpl := expr.Expr.(type) { 627 case *plan.Expr_F: 628 switch exprImpl.F.Func.ObjName { 629 case "=", ">", "<", ">=", "<=", "prefix_eq", "between", "in", "prefix_in": 630 switch e := exprImpl.F.Args[1].Expr.(type) { 631 case *plan.Expr_Lit, *plan.Expr_P, *plan.Expr_V, *plan.Expr_Vec: 632 return extractColRefInFilter(exprImpl.F.Args[0]) 633 case *plan.Expr_F: 634 switch e.F.Func.ObjName { 635 case "cast", "serial": 636 return extractColRefInFilter(exprImpl.F.Args[0]) 637 } 638 return nil 639 default: 640 return nil 641 } 642 default: 643 var col *ColRef 644 for _, arg := range exprImpl.F.Args { 645 c := extractColRefInFilter(arg) 646 if c == nil { 647 return nil 648 } 649 if col != nil { 650 if col.RelPos != c.RelPos || col.ColPos != c.ColPos { 651 return nil 652 } 653 } else { 654 col = c 655 } 656 } 657 return col 658 } 659 case *plan.Expr_Col: 660 return exprImpl.Col 661 } 662 return nil 663 } 664 665 // for col1=col2 and col3 = col4, trying to deduce new pred 666 // for example , if col1 and col3 are the same, then we can deduce that col2=col4 667 func deduceTranstivity(expr *plan.Expr, col1, col2, col3, col4 *ColRef) (bool, *plan.Expr) { 668 if col1.String() == col3.String() || col1.String() == col4.String() || col2.String() == col3.String() || col2.String() == col4.String() { 669 retExpr := DeepCopyExpr(expr) 670 substituteMatchColumn(retExpr, col3, col4) 671 return true, retExpr 672 } 673 return false, nil 674 } 675 676 // if match col1 in expr, substitute it to col2. and othterwise 677 func substituteMatchColumn(expr *plan.Expr, onPredCol1, onPredCol2 *ColRef) bool { 678 var ret bool 679 switch exprImpl := expr.Expr.(type) { 680 case *plan.Expr_Col: 681 colName := exprImpl.Col.String() 682 if colName == onPredCol1.String() { 683 exprImpl.Col.RelPos = onPredCol2.RelPos 684 exprImpl.Col.ColPos = onPredCol2.ColPos 685 exprImpl.Col.Name = onPredCol2.Name 686 return true 687 } else if colName == onPredCol2.String() { 688 exprImpl.Col.RelPos = onPredCol1.RelPos 689 exprImpl.Col.ColPos = onPredCol1.ColPos 690 exprImpl.Col.Name = onPredCol1.Name 691 return true 692 } 693 case *plan.Expr_F: 694 for _, arg := range exprImpl.F.Args { 695 if substituteMatchColumn(arg, onPredCol1, onPredCol2) { 696 ret = true 697 } 698 } 699 } 700 return ret 701 } 702 703 func checkStrictJoinPred(onPred *plan.Expr) (bool, *ColRef, *ColRef) { 704 //onPred must be equality, children must be column name 705 switch onPredImpl := onPred.Expr.(type) { 706 case *plan.Expr_F: 707 if onPredImpl.F.Func.ObjName != "=" { 708 return false, nil, nil 709 } 710 args := onPredImpl.F.Args 711 var col1, col2 *ColRef 712 switch child1 := args[0].Expr.(type) { 713 case *plan.Expr_Col: 714 col1 = child1.Col 715 } 716 switch child2 := args[1].Expr.(type) { 717 case *plan.Expr_Col: 718 col2 = child2.Col 719 } 720 if col1 != nil && col2 != nil { 721 return true, col1, col2 722 } 723 } 724 return false, nil, nil 725 } 726 727 func splitPlanConjunctions(exprList []*plan.Expr) []*plan.Expr { 728 var exprs []*plan.Expr 729 for _, expr := range exprList { 730 exprs = append(exprs, splitPlanConjunction(expr)...) 731 } 732 return exprs 733 } 734 735 func splitPlanConjunction(expr *plan.Expr) []*plan.Expr { 736 var exprs []*plan.Expr 737 switch exprImpl := expr.Expr.(type) { 738 case *plan.Expr_F: 739 if exprImpl.F.Func.ObjName == "and" { 740 exprs = append(exprs, splitPlanConjunction(exprImpl.F.Args[0])...) 741 exprs = append(exprs, splitPlanConjunction(exprImpl.F.Args[1])...) 742 } else { 743 exprs = append(exprs, expr) 744 } 745 746 default: 747 exprs = append(exprs, expr) 748 } 749 750 return exprs 751 } 752 753 func combinePlanConjunction(ctx context.Context, exprs []*plan.Expr) (expr *plan.Expr, err error) { 754 expr = exprs[0] 755 756 for i := 1; i < len(exprs); i++ { 757 expr, err = BindFuncExprImplByPlanExpr(ctx, "and", []*plan.Expr{expr, exprs[i]}) 758 759 if err != nil { 760 break 761 } 762 } 763 764 return 765 } 766 767 func rejectsNull(filter *plan.Expr, proc *process.Process) bool { 768 filter = replaceColRefWithNull(DeepCopyExpr(filter)) 769 770 filter, err := ConstantFold(batch.EmptyForConstFoldBatch, filter, proc, false) 771 if err != nil { 772 return false 773 } 774 775 if f, ok := filter.Expr.(*plan.Expr_Lit); ok { 776 if f.Lit.Isnull { 777 return true 778 } 779 780 if fbool, ok := f.Lit.Value.(*plan.Literal_Bval); ok { 781 return !fbool.Bval 782 } 783 } 784 785 return false 786 } 787 788 func replaceColRefWithNull(expr *plan.Expr) *plan.Expr { 789 switch exprImpl := expr.Expr.(type) { 790 case *plan.Expr_Col: 791 expr = &plan.Expr{ 792 Typ: expr.Typ, 793 Expr: &plan.Expr_Lit{ 794 Lit: &plan.Literal{ 795 Isnull: true, 796 }, 797 }, 798 } 799 800 case *plan.Expr_F: 801 for i, arg := range exprImpl.F.Args { 802 exprImpl.F.Args[i] = replaceColRefWithNull(arg) 803 } 804 } 805 806 return expr 807 } 808 809 func increaseRefCnt(expr *plan.Expr, inc int, colRefCnt map[[2]int32]int) { 810 switch exprImpl := expr.Expr.(type) { 811 case *plan.Expr_Col: 812 colRefCnt[[2]int32{exprImpl.Col.RelPos, exprImpl.Col.ColPos}] += inc 813 814 case *plan.Expr_F: 815 for _, arg := range exprImpl.F.Args { 816 increaseRefCnt(arg, inc, colRefCnt) 817 } 818 case *plan.Expr_W: 819 increaseRefCnt(exprImpl.W.WindowFunc, inc, colRefCnt) 820 //for _, arg := range exprImpl.W.PartitionBy { 821 // increaseRefCnt(arg, inc, colRefCnt) 822 //} 823 for _, order := range exprImpl.W.OrderBy { 824 increaseRefCnt(order.Expr, inc, colRefCnt) 825 } 826 } 827 } 828 829 func getHyperEdgeFromExpr(expr *plan.Expr, leafByTag map[int32]int32, hyperEdge map[int32]bool) { 830 switch exprImpl := expr.Expr.(type) { 831 case *plan.Expr_Col: 832 hyperEdge[leafByTag[exprImpl.Col.RelPos]] = true 833 834 case *plan.Expr_F: 835 for _, arg := range exprImpl.F.Args { 836 getHyperEdgeFromExpr(arg, leafByTag, hyperEdge) 837 } 838 } 839 } 840 841 func getNumOfCharacters(str string) int { 842 strRune := []rune(str) 843 return len(strRune) 844 } 845 846 func getUnionSelects(ctx context.Context, stmt *tree.UnionClause, selects *[]tree.Statement, unionTypes *[]plan.Node_NodeType) error { 847 switch leftStmt := stmt.Left.(type) { 848 case *tree.UnionClause: 849 err := getUnionSelects(ctx, leftStmt, selects, unionTypes) 850 if err != nil { 851 return err 852 } 853 case *tree.SelectClause: 854 *selects = append(*selects, leftStmt) 855 case *tree.ParenSelect: 856 *selects = append(*selects, leftStmt.Select) 857 default: 858 return moerr.NewParseError(ctx, "unexpected statement in union: '%v'", tree.String(leftStmt, dialect.MYSQL)) 859 } 860 861 // right is not UNION always 862 switch rightStmt := stmt.Right.(type) { 863 case *tree.SelectClause: 864 if stmt.Type == tree.UNION && !stmt.All { 865 rightStr := tree.String(rightStmt, dialect.MYSQL) 866 if len(*selects) == 1 && tree.String((*selects)[0], dialect.MYSQL) == rightStr { 867 return nil 868 } 869 } 870 871 *selects = append(*selects, rightStmt) 872 case *tree.ParenSelect: 873 if stmt.Type == tree.UNION && !stmt.All { 874 rightStr := tree.String(rightStmt.Select, dialect.MYSQL) 875 if len(*selects) == 1 && tree.String((*selects)[0], dialect.MYSQL) == rightStr { 876 return nil 877 } 878 } 879 880 *selects = append(*selects, rightStmt.Select) 881 default: 882 return moerr.NewParseError(ctx, "unexpected statement in union2: '%v'", tree.String(rightStmt, dialect.MYSQL)) 883 } 884 885 switch stmt.Type { 886 case tree.UNION: 887 if stmt.All { 888 *unionTypes = append(*unionTypes, plan.Node_UNION_ALL) 889 } else { 890 *unionTypes = append(*unionTypes, plan.Node_UNION) 891 } 892 case tree.INTERSECT: 893 if stmt.All { 894 *unionTypes = append(*unionTypes, plan.Node_INTERSECT_ALL) 895 } else { 896 *unionTypes = append(*unionTypes, plan.Node_INTERSECT) 897 } 898 case tree.EXCEPT, tree.UT_MINUS: 899 if stmt.All { 900 return moerr.NewNYI(ctx, "EXCEPT/MINUS ALL clause") 901 } else { 902 *unionTypes = append(*unionTypes, plan.Node_MINUS) 903 } 904 } 905 return nil 906 } 907 908 func GetColumnMapByExpr(expr *plan.Expr, tableDef *plan.TableDef, columnMap map[int]int) { 909 if expr == nil { 910 return 911 } 912 switch exprImpl := expr.Expr.(type) { 913 case *plan.Expr_F: 914 for _, arg := range exprImpl.F.Args { 915 GetColumnMapByExpr(arg, tableDef, columnMap) 916 } 917 918 case *plan.Expr_Col: 919 idx := exprImpl.Col.ColPos 920 colName := exprImpl.Col.Name 921 dotIdx := strings.Index(colName, ".") 922 colName = colName[dotIdx+1:] 923 colIdx := tableDef.Name2ColIndex[colName] 924 seqnum := int(colIdx) // for extenal scan case, tableDef has only Name2ColIndex, no Cols, leave seqnum as colIdx 925 if len(tableDef.Cols) > 0 { 926 seqnum = int(tableDef.Cols[colIdx].Seqnum) 927 } 928 columnMap[int(idx)] = seqnum 929 } 930 } 931 932 func GetColumnMapByExprs(exprs []*plan.Expr, tableDef *plan.TableDef, columnMap map[int]int) { 933 for _, expr := range exprs { 934 GetColumnMapByExpr(expr, tableDef, columnMap) 935 } 936 } 937 938 func GetColumnsByExpr( 939 expr *plan.Expr, 940 tableDef *plan.TableDef, 941 ) (columnMap map[int]int, defColumns, exprColumns []int, maxCol int) { 942 columnMap = make(map[int]int) 943 // key = expr's ColPos, value = tableDef's ColPos 944 GetColumnMapByExpr(expr, tableDef, columnMap) 945 946 if len(columnMap) == 0 { 947 return 948 } 949 950 defColumns = make([]int, len(columnMap)) 951 exprColumns = make([]int, len(columnMap)) 952 953 // k: col pos in expr 954 // v: col pos in def 955 i := 0 956 for k, v := range columnMap { 957 if v > maxCol { 958 maxCol = v 959 } 960 exprColumns[i] = k 961 defColumns[i] = v 962 i = i + 1 963 } 964 return 965 } 966 967 func EvalFilterExpr(ctx context.Context, expr *plan.Expr, bat *batch.Batch, proc *process.Process) (bool, error) { 968 if len(bat.Vecs) == 0 { //that's constant expr 969 e, err := ConstantFold(bat, expr, proc, false) 970 if err != nil { 971 return false, err 972 } 973 974 if cExpr, ok := e.Expr.(*plan.Expr_Lit); ok { 975 if bVal, bOk := cExpr.Lit.Value.(*plan.Literal_Bval); bOk { 976 return bVal.Bval, nil 977 } 978 } 979 return false, moerr.NewInternalError(ctx, "cannot eval filter expr") 980 } else { 981 executor, err := colexec.NewExpressionExecutor(proc, expr) 982 if err != nil { 983 return false, err 984 } 985 defer executor.Free() 986 987 vec, err := executor.Eval(proc, []*batch.Batch{bat}) 988 if err != nil { 989 return false, err 990 } 991 if vec.GetType().Oid != types.T_bool { 992 return false, moerr.NewInternalError(ctx, "cannot eval filter expr") 993 } 994 cols := vector.MustFixedCol[bool](vec) 995 for _, isNeed := range cols { 996 if isNeed { 997 return true, nil 998 } 999 } 1000 return false, nil 1001 } 1002 } 1003 1004 func exchangeVectors(datas [][2]any, depth int, tmpResult []any, result *[]*vector.Vector, mp *mpool.MPool) { 1005 for i := 0; i < len(datas[depth]); i++ { 1006 tmpResult[depth] = datas[depth][i] 1007 if depth != len(datas)-1 { 1008 exchangeVectors(datas, depth+1, tmpResult, result, mp) 1009 } else { 1010 for j, val := range tmpResult { 1011 vector.AppendAny((*result)[j], val, false, mp) 1012 } 1013 } 1014 } 1015 } 1016 1017 func BuildVectorsByData(datas [][2]any, dataTypes []uint8, mp *mpool.MPool) []*vector.Vector { 1018 vectors := make([]*vector.Vector, len(dataTypes)) 1019 for i, typ := range dataTypes { 1020 vectors[i] = vector.NewVec(types.T(typ).ToType()) 1021 } 1022 1023 tmpResult := make([]any, len(datas)) 1024 exchangeVectors(datas, 0, tmpResult, &vectors, mp) 1025 1026 return vectors 1027 } 1028 1029 func ExprIsZonemappable(ctx context.Context, expr *plan.Expr) bool { 1030 if expr == nil { 1031 return false 1032 } 1033 switch exprImpl := expr.Expr.(type) { 1034 case *plan.Expr_F: 1035 isConst := true 1036 for _, arg := range exprImpl.F.Args { 1037 switch arg.Expr.(type) { 1038 case *plan.Expr_Lit, *plan.Expr_P, *plan.Expr_V, *plan.Expr_T: 1039 continue 1040 } 1041 isConst = false 1042 isZonemappable := ExprIsZonemappable(ctx, arg) 1043 if !isZonemappable { 1044 return false 1045 } 1046 } 1047 if isConst { 1048 return true 1049 } 1050 1051 isZonemappable, _ := function.GetFunctionIsZonemappableById(ctx, exprImpl.F.Func.GetObj()) 1052 if !isZonemappable { 1053 return false 1054 } 1055 1056 return true 1057 default: 1058 return true 1059 } 1060 } 1061 1062 // todo: remove this in the future 1063 func GetSortOrderByName(tableDef *plan.TableDef, colName string) int { 1064 if tableDef.Pkey != nil { 1065 pkNames := tableDef.Pkey.Names 1066 for i := range pkNames { 1067 if pkNames[i] == colName { 1068 return i 1069 } 1070 } 1071 } 1072 if tableDef.ClusterBy != nil { 1073 return util.GetClusterByColumnOrder(tableDef.ClusterBy.Name, colName) 1074 } 1075 return -1 1076 } 1077 1078 func GetSortOrder(tableDef *plan.TableDef, colPos int32) int { 1079 colName := tableDef.Cols[colPos].Name 1080 return GetSortOrderByName(tableDef, colName) 1081 } 1082 1083 func ConstandFoldList(exprs []*plan.Expr, proc *process.Process, varAndParamIsConst bool) ([]*plan.Expr, error) { 1084 newExprs := DeepCopyExprList(exprs) 1085 for i := range newExprs { 1086 foldedExpr, err := ConstantFold(batch.EmptyForConstFoldBatch, newExprs[i], proc, varAndParamIsConst) 1087 if err != nil { 1088 return nil, err 1089 } 1090 if foldedExpr != nil { 1091 newExprs[i] = foldedExpr 1092 } 1093 } 1094 return newExprs, nil 1095 } 1096 1097 func ConstantFold(bat *batch.Batch, expr *plan.Expr, proc *process.Process, varAndParamIsConst bool) (*plan.Expr, error) { 1098 if expr.Typ.Id == int32(types.T_interval) { 1099 panic(moerr.NewInternalError(proc.Ctx, "not supported type INTERVAL")) 1100 } 1101 1102 // If it is Expr_List, perform constant folding on its elements 1103 if elist := expr.GetList(); elist != nil { 1104 exprList := elist.List 1105 for i := range exprList { 1106 foldExpr, err := ConstantFold(bat, exprList[i], proc, varAndParamIsConst) 1107 if err != nil { 1108 return nil, err 1109 } 1110 exprList[i] = foldExpr 1111 } 1112 1113 vec, err := colexec.GenerateConstListExpressionExecutor(proc, exprList) 1114 if err != nil { 1115 return nil, err 1116 } 1117 defer vec.Free(proc.Mp()) 1118 1119 vec.InplaceSortAndCompact() 1120 data, err := vec.MarshalBinary() 1121 if err != nil { 1122 return nil, err 1123 } 1124 1125 return &plan.Expr{ 1126 Typ: expr.Typ, 1127 Expr: &plan.Expr_Vec{ 1128 Vec: &plan.LiteralVec{ 1129 Len: int32(vec.Length()), 1130 Data: data, 1131 }, 1132 }, 1133 }, nil 1134 } 1135 1136 fn := expr.GetF() 1137 if fn == nil || proc == nil { 1138 return expr, nil 1139 } 1140 1141 overloadID := fn.Func.GetObj() 1142 f, err := function.GetFunctionById(proc.Ctx, overloadID) 1143 if err != nil { 1144 return nil, err 1145 } 1146 if f.CannotFold() || f.IsRealTimeRelated() { 1147 return expr, nil 1148 } 1149 isVec := false 1150 for i := range fn.Args { 1151 foldExpr, errFold := ConstantFold(bat, fn.Args[i], proc, varAndParamIsConst) 1152 if errFold != nil { 1153 return nil, errFold 1154 } 1155 fn.Args[i] = foldExpr 1156 isVec = isVec || foldExpr.GetVec() != nil 1157 } 1158 if !rule.IsConstant(expr, varAndParamIsConst) { 1159 return expr, nil 1160 } 1161 1162 vec, err := colexec.EvalExpressionOnce(proc, expr, []*batch.Batch{bat}) 1163 if err != nil { 1164 return nil, err 1165 } 1166 defer vec.Free(proc.Mp()) 1167 1168 if isVec { 1169 data, err := vec.MarshalBinary() 1170 if err != nil { 1171 return expr, nil 1172 } 1173 1174 return &plan.Expr{ 1175 Typ: expr.Typ, 1176 Expr: &plan.Expr_Vec{ 1177 Vec: &plan.LiteralVec{ 1178 Len: int32(vec.Length()), 1179 Data: data, 1180 }, 1181 }, 1182 }, nil 1183 } 1184 1185 c := rule.GetConstantValue(vec, false, 0) 1186 if c == nil { 1187 return expr, nil 1188 } 1189 ec := &plan.Expr_Lit{ 1190 Lit: c, 1191 } 1192 expr.Expr = ec 1193 return expr, nil 1194 } 1195 1196 func unwindTupleComparison(ctx context.Context, nonEqOp, op string, leftExprs, rightExprs []*plan.Expr, idx int) (*plan.Expr, error) { 1197 if idx == len(leftExprs)-1 { 1198 return BindFuncExprImplByPlanExpr(ctx, op, []*plan.Expr{ 1199 leftExprs[idx], 1200 rightExprs[idx], 1201 }) 1202 } 1203 1204 expr, err := BindFuncExprImplByPlanExpr(ctx, nonEqOp, []*plan.Expr{ 1205 DeepCopyExpr(leftExprs[idx]), 1206 DeepCopyExpr(rightExprs[idx]), 1207 }) 1208 if err != nil { 1209 return nil, err 1210 } 1211 1212 eqExpr, err := BindFuncExprImplByPlanExpr(ctx, "=", []*plan.Expr{ 1213 leftExprs[idx], 1214 rightExprs[idx], 1215 }) 1216 if err != nil { 1217 return nil, err 1218 } 1219 1220 tailExpr, err := unwindTupleComparison(ctx, nonEqOp, op, leftExprs, rightExprs, idx+1) 1221 if err != nil { 1222 return nil, err 1223 } 1224 1225 tailExpr, err = BindFuncExprImplByPlanExpr(ctx, "and", []*plan.Expr{eqExpr, tailExpr}) 1226 if err != nil { 1227 return nil, err 1228 } 1229 1230 return BindFuncExprImplByPlanExpr(ctx, "or", []*plan.Expr{expr, tailExpr}) 1231 } 1232 1233 // checkNoNeedCast 1234 // if constant's type higher than column's type 1235 // and constant's value in range of column's type, then no cast was needed 1236 func checkNoNeedCast(constT, columnT types.Type, constExpr *plan.Literal) bool { 1237 if constExpr == nil { 1238 return false 1239 } 1240 1241 //TODO: Check if T_array is required here? 1242 if constT.Eq(columnT) { 1243 return true 1244 } 1245 switch constT.Oid { 1246 case types.T_char, types.T_varchar, types.T_text: 1247 switch columnT.Oid { 1248 case types.T_char, types.T_varchar: 1249 return constT.Width <= columnT.Width 1250 case types.T_text: 1251 return true 1252 default: 1253 return false 1254 } 1255 1256 case types.T_binary, types.T_varbinary, types.T_blob: 1257 switch columnT.Oid { 1258 case types.T_binary, types.T_varbinary: 1259 if constT.Width <= columnT.Width { 1260 return true 1261 } else { 1262 return false 1263 } 1264 case types.T_blob: 1265 return true 1266 default: 1267 return false 1268 } 1269 1270 case types.T_int8, types.T_int16, types.T_int32, types.T_int64: 1271 val, valOk := constExpr.Value.(*plan.Literal_I64Val) 1272 if !valOk { 1273 return false 1274 } 1275 constVal := val.I64Val 1276 switch columnT.Oid { 1277 case types.T_bit: 1278 return constVal >= 0 && uint64(constVal) <= uint64(1<<columnT.Width-1) 1279 case types.T_int8: 1280 return constVal <= int64(math.MaxInt8) && constVal >= int64(math.MinInt8) 1281 case types.T_int16: 1282 return constVal <= int64(math.MaxInt16) && constVal >= int64(math.MinInt16) 1283 case types.T_int32: 1284 return constVal <= int64(math.MaxInt32) && constVal >= int64(math.MinInt32) 1285 case types.T_int64: 1286 return true 1287 case types.T_uint8: 1288 return constVal <= math.MaxUint8 && constVal >= 0 1289 case types.T_uint16: 1290 return constVal <= math.MaxUint16 && constVal >= 0 1291 case types.T_uint32: 1292 return constVal <= math.MaxUint32 && constVal >= 0 1293 case types.T_uint64: 1294 return constVal >= 0 1295 case types.T_float32: 1296 //float32 has 6 significant digits. 1297 return constVal <= 100000 && constVal >= -100000 1298 case types.T_float64: 1299 //float64 has 15 significant digits. 1300 return constVal <= int64(math.MaxInt32) && constVal >= int64(math.MinInt32) 1301 case types.T_decimal64: 1302 return constVal <= int64(math.MaxInt32) && constVal >= int64(math.MinInt32) 1303 default: 1304 return false 1305 } 1306 1307 case types.T_uint8, types.T_uint16, types.T_uint32, types.T_uint64: 1308 val_u, valOk := constExpr.Value.(*plan.Literal_U64Val) 1309 if !valOk { 1310 return false 1311 } 1312 constVal := val_u.U64Val 1313 switch columnT.Oid { 1314 case types.T_bit: 1315 return constVal <= uint64(1<<columnT.Width-1) 1316 case types.T_int8: 1317 return constVal <= math.MaxInt8 1318 case types.T_int16: 1319 return constVal <= math.MaxInt16 1320 case types.T_int32: 1321 return constVal <= math.MaxInt32 1322 case types.T_int64: 1323 return constVal <= math.MaxInt64 1324 case types.T_uint8: 1325 return constVal <= math.MaxUint8 1326 case types.T_uint16: 1327 return constVal <= math.MaxUint16 1328 case types.T_uint32: 1329 return constVal <= math.MaxUint32 1330 case types.T_uint64: 1331 return true 1332 case types.T_float32: 1333 //float32 has 6 significant digits. 1334 return constVal <= 100000 1335 case types.T_float64: 1336 //float64 has 15 significant digits. 1337 return constVal <= math.MaxUint32 1338 case types.T_decimal64: 1339 return constVal <= math.MaxInt32 1340 default: 1341 return false 1342 } 1343 1344 case types.T_decimal64, types.T_decimal128: 1345 return columnT.Oid == types.T_decimal64 || columnT.Oid == types.T_decimal128 1346 1347 default: 1348 return false 1349 } 1350 1351 } 1352 1353 func InitInfileParam(param *tree.ExternParam) error { 1354 for i := 0; i < len(param.Option); i += 2 { 1355 switch strings.ToLower(param.Option[i]) { 1356 case "filepath": 1357 param.Filepath = param.Option[i+1] 1358 case "compression": 1359 param.CompressType = param.Option[i+1] 1360 case "format": 1361 format := strings.ToLower(param.Option[i+1]) 1362 if format != tree.CSV && format != tree.JSONLINE && format != tree.PARQUET { 1363 return moerr.NewBadConfig(param.Ctx, "the format '%s' is not supported", format) 1364 } 1365 param.Format = format 1366 case "jsondata": 1367 jsondata := strings.ToLower(param.Option[i+1]) 1368 if jsondata != tree.OBJECT && jsondata != tree.ARRAY { 1369 return moerr.NewBadConfig(param.Ctx, "the jsondata '%s' is not supported", jsondata) 1370 } 1371 param.JsonData = jsondata 1372 param.Format = tree.JSONLINE 1373 default: 1374 return moerr.NewBadConfig(param.Ctx, "the keyword '%s' is not support", strings.ToLower(param.Option[i])) 1375 } 1376 } 1377 if len(param.Filepath) == 0 { 1378 return moerr.NewBadConfig(param.Ctx, "the filepath must be specified") 1379 } 1380 if param.Format == tree.JSONLINE && len(param.JsonData) == 0 { 1381 return moerr.NewBadConfig(param.Ctx, "the jsondata must be specified") 1382 } 1383 if len(param.Format) == 0 { 1384 param.Format = tree.CSV 1385 } 1386 return nil 1387 } 1388 1389 func InitS3Param(param *tree.ExternParam) error { 1390 param.S3Param = &tree.S3Parameter{} 1391 for i := 0; i < len(param.Option); i += 2 { 1392 switch strings.ToLower(param.Option[i]) { 1393 case "endpoint": 1394 param.S3Param.Endpoint = param.Option[i+1] 1395 case "region": 1396 param.S3Param.Region = param.Option[i+1] 1397 case "access_key_id": 1398 param.S3Param.APIKey = param.Option[i+1] 1399 case "secret_access_key": 1400 param.S3Param.APISecret = param.Option[i+1] 1401 case "bucket": 1402 param.S3Param.Bucket = param.Option[i+1] 1403 case "filepath": 1404 param.Filepath = param.Option[i+1] 1405 case "compression": 1406 param.CompressType = param.Option[i+1] 1407 case "provider": 1408 param.S3Param.Provider = param.Option[i+1] 1409 case "role_arn": 1410 param.S3Param.RoleArn = param.Option[i+1] 1411 case "external_id": 1412 param.S3Param.ExternalId = param.Option[i+1] 1413 case "format": 1414 format := strings.ToLower(param.Option[i+1]) 1415 if format != tree.CSV && format != tree.JSONLINE { 1416 return moerr.NewBadConfig(param.Ctx, "the format '%s' is not supported", format) 1417 } 1418 param.Format = format 1419 case "jsondata": 1420 jsondata := strings.ToLower(param.Option[i+1]) 1421 if jsondata != tree.OBJECT && jsondata != tree.ARRAY { 1422 return moerr.NewBadConfig(param.Ctx, "the jsondata '%s' is not supported", jsondata) 1423 } 1424 param.JsonData = jsondata 1425 param.Format = tree.JSONLINE 1426 1427 default: 1428 return moerr.NewBadConfig(param.Ctx, "the keyword '%s' is not support", strings.ToLower(param.Option[i])) 1429 } 1430 } 1431 if param.Format == tree.JSONLINE && len(param.JsonData) == 0 { 1432 return moerr.NewBadConfig(param.Ctx, "the jsondata must be specified") 1433 } 1434 if len(param.Format) == 0 { 1435 param.Format = tree.CSV 1436 } 1437 return nil 1438 } 1439 1440 func GetForETLWithType(param *tree.ExternParam, prefix string) (res fileservice.ETLFileService, readPath string, err error) { 1441 if param.ScanType == tree.S3 { 1442 buf := new(strings.Builder) 1443 w := csv.NewWriter(buf) 1444 opts := []string{"s3-opts", "endpoint=" + param.S3Param.Endpoint, "region=" + param.S3Param.Region, "key=" + param.S3Param.APIKey, "secret=" + param.S3Param.APISecret, 1445 "bucket=" + param.S3Param.Bucket, "role-arn=" + param.S3Param.RoleArn, "external-id=" + param.S3Param.ExternalId} 1446 if strings.ToLower(param.S3Param.Provider) != "" && strings.ToLower(param.S3Param.Provider) != "minio" { 1447 return nil, "", moerr.NewBadConfig(param.Ctx, "the provider only support 'minio' now") 1448 } 1449 if strings.ToLower(param.S3Param.Provider) == "minio" { 1450 opts = append(opts, "is-minio=true") 1451 } 1452 if err = w.Write(opts); err != nil { 1453 return nil, "", err 1454 } 1455 w.Flush() 1456 return fileservice.GetForETL(context.TODO(), nil, fileservice.JoinPath(buf.String(), prefix)) 1457 } 1458 return fileservice.GetForETL(context.TODO(), param.FileService, prefix) 1459 } 1460 1461 func StatFile(param *tree.ExternParam) error { 1462 filePath := strings.TrimSpace(param.Filepath) 1463 if strings.HasPrefix(filePath, "etl:") { 1464 filePath = path.Clean(filePath) 1465 } else { 1466 filePath = path.Clean("/" + filePath) 1467 } 1468 param.Filepath = filePath 1469 fs, readPath, err := GetForETLWithType(param, filePath) 1470 if err != nil { 1471 return err 1472 } 1473 st, err := fs.StatFile(param.Ctx, readPath) 1474 if err != nil { 1475 return err 1476 } 1477 param.Ctx = nil 1478 param.FileSize = st.Size 1479 return nil 1480 } 1481 1482 // ReadDir support "etl:" and "/..." absolute path, NOT support relative path. 1483 func ReadDir(param *tree.ExternParam) (fileList []string, fileSize []int64, err error) { 1484 filePath := strings.TrimSpace(param.Filepath) 1485 if strings.HasPrefix(filePath, "etl:") { 1486 filePath = path.Clean(filePath) 1487 } else { 1488 filePath = path.Clean("/" + filePath) 1489 } 1490 1491 sep := "/" 1492 pathDir := strings.Split(filePath, sep) 1493 l := list.New() 1494 l2 := list.New() 1495 if pathDir[0] == "" { 1496 l.PushBack(sep) 1497 } else { 1498 l.PushBack(pathDir[0]) 1499 } 1500 1501 for i := 1; i < len(pathDir); i++ { 1502 length := l.Len() 1503 for j := 0; j < length; j++ { 1504 prefix := l.Front().Value.(string) 1505 fs, readPath, err := GetForETLWithType(param, prefix) 1506 if err != nil { 1507 return nil, nil, err 1508 } 1509 entries, err := fs.List(param.Ctx, readPath) 1510 if err != nil { 1511 return nil, nil, err 1512 } 1513 for _, entry := range entries { 1514 if !entry.IsDir && i+1 != len(pathDir) { 1515 continue 1516 } 1517 if entry.IsDir && i+1 == len(pathDir) { 1518 continue 1519 } 1520 matched, err := path.Match(pathDir[i], entry.Name) 1521 if err != nil { 1522 return nil, nil, err 1523 } 1524 if !matched { 1525 continue 1526 } 1527 l.PushBack(path.Join(l.Front().Value.(string), entry.Name)) 1528 if !entry.IsDir { 1529 l2.PushBack(entry.Size) 1530 } 1531 } 1532 l.Remove(l.Front()) 1533 } 1534 } 1535 length := l.Len() 1536 for j := 0; j < length; j++ { 1537 fileList = append(fileList, l.Front().Value.(string)) 1538 l.Remove(l.Front()) 1539 fileSize = append(fileSize, l2.Front().Value.(int64)) 1540 l2.Remove(l2.Front()) 1541 } 1542 return fileList, fileSize, err 1543 } 1544 1545 // GetUniqueColAndIdxFromTableDef 1546 // if get table: t1(a int primary key, b int, c int, d int, unique key(b,c)); 1547 // return : []map[string]int { {'a'=1}, {'b'=2,'c'=3} } 1548 func GetUniqueColAndIdxFromTableDef(tableDef *TableDef) []map[string]int { 1549 uniqueCols := make([]map[string]int, 0, len(tableDef.Cols)) 1550 if tableDef.Pkey != nil && !onlyHasHiddenPrimaryKey(tableDef) { 1551 pkMap := make(map[string]int) 1552 for _, colName := range tableDef.Pkey.Names { 1553 pkMap[colName] = int(tableDef.Name2ColIndex[colName]) 1554 } 1555 uniqueCols = append(uniqueCols, pkMap) 1556 } 1557 1558 for _, index := range tableDef.Indexes { 1559 if index.Unique { 1560 pkMap := make(map[string]int) 1561 for _, part := range index.Parts { 1562 pkMap[part] = int(tableDef.Name2ColIndex[part]) 1563 } 1564 uniqueCols = append(uniqueCols, pkMap) 1565 } 1566 } 1567 return uniqueCols 1568 } 1569 1570 // GenUniqueColJoinExpr 1571 // if get table: t1(a int primary key, b int, c int, d int, unique key(b,c)); 1572 // uniqueCols is: []map[string]int { {'a'=1}, {'b'=2,'c'=3} } 1573 // we will get expr like: 'leftTag.a = rightTag.a or (leftTag.b = rightTag.b and leftTag.c = rightTag. c) 1574 func GenUniqueColJoinExpr(ctx context.Context, tableDef *TableDef, uniqueCols []map[string]int, leftTag int32, rightTag int32) (*Expr, error) { 1575 var checkExpr *Expr 1576 var err error 1577 1578 for i, uniqueColMap := range uniqueCols { 1579 var condExpr *Expr 1580 condIdx := int(0) 1581 for _, colIdx := range uniqueColMap { 1582 col := tableDef.Cols[colIdx] 1583 leftExpr := &Expr{ 1584 Typ: col.Typ, 1585 Expr: &plan.Expr_Col{ 1586 Col: &plan.ColRef{ 1587 RelPos: leftTag, 1588 ColPos: int32(colIdx), 1589 }, 1590 }, 1591 } 1592 rightExpr := &plan.Expr{ 1593 Typ: col.Typ, 1594 Expr: &plan.Expr_Col{ 1595 Col: &plan.ColRef{ 1596 RelPos: rightTag, 1597 ColPos: int32(colIdx), 1598 }, 1599 }, 1600 } 1601 eqExpr, err := BindFuncExprImplByPlanExpr(ctx, "=", []*Expr{leftExpr, rightExpr}) 1602 if err != nil { 1603 return nil, err 1604 } 1605 if condIdx == 0 { 1606 condExpr = eqExpr 1607 } else { 1608 condExpr, err = BindFuncExprImplByPlanExpr(ctx, "and", []*Expr{condExpr, eqExpr}) 1609 if err != nil { 1610 return nil, err 1611 } 1612 } 1613 condIdx++ 1614 } 1615 1616 if i == 0 { 1617 checkExpr = condExpr 1618 } else { 1619 checkExpr, err = BindFuncExprImplByPlanExpr(ctx, "or", []*Expr{checkExpr, condExpr}) 1620 if err != nil { 1621 return nil, err 1622 } 1623 } 1624 } 1625 1626 return checkExpr, nil 1627 } 1628 1629 // GenUniqueColCheckExpr like GenUniqueColJoinExpr. but use for on duplicate key clause to check conflict 1630 // if get table: t1(a int primary key, b int, c int, d int, unique key(b,c)); 1631 // we get batch like [1,2,3,4, origin_a, origin_b, origin_c, origin_d, row_id ....]。 1632 // we get expr like: []*Expr{ 1=origin_a , (2 = origin_b and 3 = origin_c) } 1633 func GenUniqueColCheckExpr(ctx context.Context, tableDef *TableDef, uniqueCols []map[string]int, colCount int) ([]*Expr, error) { 1634 checkExpr := make([]*Expr, len(uniqueCols)) 1635 1636 for i, uniqueColMap := range uniqueCols { 1637 var condExpr *Expr 1638 condIdx := int(0) 1639 for _, colIdx := range uniqueColMap { 1640 col := tableDef.Cols[colIdx] 1641 // insert values 1642 leftExpr := &Expr{ 1643 Typ: col.Typ, 1644 Expr: &plan.Expr_Col{ 1645 Col: &plan.ColRef{ 1646 RelPos: 0, 1647 ColPos: int32(colIdx), 1648 }, 1649 }, 1650 } 1651 rightExpr := &plan.Expr{ 1652 Typ: col.Typ, 1653 Expr: &plan.Expr_Col{ 1654 Col: &plan.ColRef{ 1655 RelPos: 1, 1656 ColPos: int32(colIdx + colCount), 1657 }, 1658 }, 1659 } 1660 eqExpr, err := BindFuncExprImplByPlanExpr(ctx, "=", []*Expr{leftExpr, rightExpr}) 1661 if err != nil { 1662 return nil, err 1663 } 1664 if condIdx == 0 { 1665 condExpr = eqExpr 1666 } else { 1667 condExpr, err = BindFuncExprImplByPlanExpr(ctx, "and", []*Expr{condExpr, eqExpr}) 1668 if err != nil { 1669 return nil, err 1670 } 1671 } 1672 condIdx++ 1673 } 1674 checkExpr[i] = condExpr 1675 } 1676 1677 return checkExpr, nil 1678 } 1679 func onlyContainsTag(filter *Expr, tag int32) bool { 1680 switch ex := filter.Expr.(type) { 1681 case *plan.Expr_Col: 1682 return ex.Col.RelPos == tag 1683 case *plan.Expr_F: 1684 for _, arg := range ex.F.Args { 1685 if !onlyContainsTag(arg, tag) { 1686 return false 1687 } 1688 } 1689 return true 1690 default: 1691 return true 1692 } 1693 } 1694 1695 func AssignAuxIdForExpr(expr *plan.Expr, start int32) int32 { 1696 expr.AuxId = start 1697 vertexCnt := int32(1) 1698 1699 if f, ok := expr.Expr.(*plan.Expr_F); ok { 1700 for _, child := range f.F.Args { 1701 vertexCnt += AssignAuxIdForExpr(child, start+vertexCnt) 1702 } 1703 } 1704 1705 return vertexCnt 1706 } 1707 1708 func ResetAuxIdForExpr(expr *plan.Expr) { 1709 expr.AuxId = 0 1710 1711 if f, ok := expr.Expr.(*plan.Expr_F); ok { 1712 for _, child := range f.F.Args { 1713 ResetAuxIdForExpr(child) 1714 } 1715 } 1716 } 1717 1718 // func SubstitueParam(expr *plan.Expr, proc *process.Process) *plan.Expr { 1719 // switch t := expr.Expr.(type) { 1720 // case *plan.Expr_F: 1721 // for _, arg := range t.F.Args { 1722 // SubstitueParam(arg, proc) 1723 // } 1724 // case *plan.Expr_P: 1725 // vec, _ := proc.GetPrepareParamsAt(int(t.P.Pos)) 1726 // c := rule.GetConstantValue(vec, false) 1727 // ec := &plan.Expr_C{ 1728 // C: c, 1729 // } 1730 // expr.Typ = &plan.Type{Id: int32(vec.GetType().Oid), Scale: vec.GetType().Scale, Width: vec.GetType().Width} 1731 // expr.Expr = ec 1732 // case *plan.Expr_V: 1733 // val, _ := proc.GetResolveVariableFunc()(t.V.Name, t.V.System, t.V.Global) 1734 // typ := types.New(types.T(expr.Typ.Id), expr.Typ.Width, expr.Typ.Scale) 1735 // vec, _ := util.GenVectorByVarValue(proc, typ, val) 1736 // c := rule.GetConstantValue(vec, false) 1737 // ec := &plan.Expr_C{ 1738 // C: c, 1739 // } 1740 // expr.Typ = &plan.Type{Id: int32(vec.GetType().Oid), Scale: vec.GetType().Scale, Width: vec.GetType().Width} 1741 // expr.Expr = ec 1742 // } 1743 // return expr 1744 // } 1745 1746 func FormatExprs(exprs []*plan.Expr) string { 1747 var w bytes.Buffer 1748 for _, expr := range exprs { 1749 w.WriteString(FormatExpr(expr)) 1750 w.WriteByte('\n') 1751 } 1752 return w.String() 1753 } 1754 1755 func FormatExpr(expr *plan.Expr) string { 1756 var w bytes.Buffer 1757 doFormatExpr(expr, &w, 0) 1758 return w.String() 1759 } 1760 1761 func doFormatExpr(expr *plan.Expr, out *bytes.Buffer, depth int) { 1762 out.WriteByte('\n') 1763 prefix := strings.Repeat("\t", depth) 1764 switch t := expr.Expr.(type) { 1765 case *plan.Expr_Col: 1766 out.WriteString(fmt.Sprintf("%sExpr_Col(%s)", prefix, t.Col.Name)) 1767 case *plan.Expr_Lit: 1768 out.WriteString(fmt.Sprintf("%sExpr_C(%s)", prefix, t.Lit.String())) 1769 case *plan.Expr_F: 1770 out.WriteString(fmt.Sprintf("%sExpr_F(\n%s\tFunc[\"%s\"](nargs=%d)", prefix, prefix, t.F.Func.ObjName, len(t.F.Args))) 1771 for _, arg := range t.F.Args { 1772 doFormatExpr(arg, out, depth+1) 1773 } 1774 out.WriteString(fmt.Sprintf("\n%s)", prefix)) 1775 case *plan.Expr_P: 1776 out.WriteString(fmt.Sprintf("%sExpr_P(%d)", prefix, t.P.Pos)) 1777 case *plan.Expr_T: 1778 out.WriteString(fmt.Sprintf("%sExpr_T(%s)", prefix, t.T.String())) 1779 default: 1780 out.WriteString(fmt.Sprintf("%sExpr_Unknown(%s)", prefix, expr.String())) 1781 } 1782 } 1783 1784 // databaseIsValid checks whether the database exists or not. 1785 func databaseIsValid(dbName string, ctx CompilerContext, snapshot Snapshot) (string, error) { 1786 connectDBFirst := false 1787 if len(dbName) == 0 { 1788 connectDBFirst = true 1789 } 1790 if dbName == "" { 1791 dbName = ctx.DefaultDatabase() 1792 } 1793 1794 if len(dbName) == 0 || !ctx.DatabaseExists(dbName, snapshot) { 1795 if connectDBFirst { 1796 return "", moerr.NewNoDB(ctx.GetContext()) 1797 } else { 1798 return "", moerr.NewBadDB(ctx.GetContext(), dbName) 1799 } 1800 } 1801 return dbName, nil 1802 } 1803 1804 /* 1805 * 1806 getSuitableDBName get the database name which need to be used in next steps. 1807 1808 For Cases: 1809 1810 SHOW XXX FROM [DB_NAME1].TABLE_NAME [FROM [DB_NAME2]]; 1811 1812 In mysql, 1813 if the second FROM clause exists, the DB_NAME1 in first FROM clause if it exists will be ignored. 1814 if the second FROM clause does not exist, the DB_NAME1 in first FROM clause if it exists will be used. 1815 if the DB_NAME1 and DB_NAME2 neither does not exist, the current connected database (by USE statement) will be used. 1816 if neither case above succeeds, an error is reported. 1817 */ 1818 func getSuitableDBName(dbName1 string, dbName2 string) string { 1819 if len(dbName2) != 0 { 1820 return dbName2 1821 } 1822 return dbName1 1823 } 1824 1825 func detectedExprWhetherTimeRelated(expr *plan.Expr) bool { 1826 if ef, ok := expr.Expr.(*plan.Expr_F); !ok { 1827 return false 1828 } else { 1829 overloadID := ef.F.Func.GetObj() 1830 f, exists := function.GetFunctionByIdWithoutError(overloadID) 1831 // current_timestamp() 1832 if !exists { 1833 return false 1834 } 1835 if f.IsRealTimeRelated() { 1836 return true 1837 } 1838 1839 // current_timestamp() + 1 1840 for _, arg := range ef.F.Args { 1841 if detectedExprWhetherTimeRelated(arg) { 1842 return true 1843 } 1844 } 1845 } 1846 return false 1847 } 1848 1849 func ResetPreparePlan(ctx CompilerContext, preparePlan *Plan) ([]*plan.ObjectRef, []int32, error) { 1850 // dcl tcl is not support 1851 var schemas []*plan.ObjectRef 1852 var paramTypes []int32 1853 1854 switch pp := preparePlan.Plan.(type) { 1855 case *plan.Plan_Tcl: 1856 return nil, nil, moerr.NewInvalidInput(ctx.GetContext(), "cannot prepare TCL and DCL statement") 1857 case *plan.Plan_Dcl: 1858 switch pp.Dcl.GetDclType() { 1859 case plan.DataControl_CREATE_ACCOUNT, 1860 plan.DataControl_ALTER_ACCOUNT, 1861 plan.DataControl_DROP_ACCOUNT: 1862 return nil, pp.Dcl.GetOther().GetParamTypes(), nil 1863 default: 1864 return nil, nil, moerr.NewInvalidInput(ctx.GetContext(), "cannot prepare TCL and DCL statement") 1865 } 1866 case *plan.Plan_Ddl: 1867 if pp.Ddl.Query != nil { 1868 getParamRule := NewGetParamRule() 1869 VisitQuery := NewVisitPlan(preparePlan, []VisitPlanRule{getParamRule}) 1870 err := VisitQuery.Visit(ctx.GetContext()) 1871 if err != nil { 1872 return nil, nil, err 1873 } 1874 // TODO : need confirm 1875 if len(getParamRule.params) > 0 { 1876 return nil, nil, moerr.NewInvalidInput(ctx.GetContext(), "cannot plan DDL statement") 1877 } 1878 } 1879 1880 case *plan.Plan_Query: 1881 // collect args 1882 getParamRule := NewGetParamRule() 1883 VisitQuery := NewVisitPlan(preparePlan, []VisitPlanRule{getParamRule}) 1884 err := VisitQuery.Visit(ctx.GetContext()) 1885 if err != nil { 1886 return nil, nil, err 1887 } 1888 1889 // sort arg 1890 getParamRule.SetParamOrder() 1891 args := getParamRule.params 1892 schemas = getParamRule.schemas 1893 paramTypes = getParamRule.paramTypes 1894 1895 // reset arg order 1896 resetParamRule := NewResetParamOrderRule(args) 1897 VisitQuery = NewVisitPlan(preparePlan, []VisitPlanRule{resetParamRule}) 1898 err = VisitQuery.Visit(ctx.GetContext()) 1899 if err != nil { 1900 return nil, nil, err 1901 } 1902 } 1903 return schemas, paramTypes, nil 1904 } 1905 1906 func getParamTypes(params []tree.Expr, ctx CompilerContext, isPrepareStmt bool) ([]int32, error) { 1907 paramTypes := make([]int32, 0, len(params)) 1908 for _, p := range params { 1909 switch ast := p.(type) { 1910 case *tree.NumVal: 1911 if ast.ValType != tree.P_char { 1912 return nil, moerr.NewInvalidInput(ctx.GetContext(), "unsupport value '%s'", ast.String()) 1913 } 1914 case *tree.ParamExpr: 1915 if !isPrepareStmt { 1916 return nil, moerr.NewInvalidInput(ctx.GetContext(), "only prepare statement can use ? expr") 1917 } 1918 paramTypes = append(paramTypes, int32(types.T_varchar)) 1919 if ast.Offset != len(paramTypes) { 1920 return nil, moerr.NewInternalError(ctx.GetContext(), "offset not match") 1921 } 1922 default: 1923 return nil, moerr.NewInvalidInput(ctx.GetContext(), "unsupport value '%s'", ast.String()) 1924 } 1925 } 1926 return paramTypes, nil 1927 } 1928 1929 // HasMoCtrl checks whether the expression has mo_ctrl(..,..,..) 1930 func HasMoCtrl(expr *plan.Expr) bool { 1931 switch exprImpl := expr.Expr.(type) { 1932 case *plan.Expr_F: 1933 if exprImpl.F.Func.ObjName == "mo_ctl" { 1934 return true 1935 } 1936 for _, arg := range exprImpl.F.Args { 1937 if HasMoCtrl(arg) { 1938 return true 1939 } 1940 } 1941 return false 1942 1943 case *plan.Expr_List: 1944 for _, arg := range exprImpl.List.List { 1945 if HasMoCtrl(arg) { 1946 return true 1947 } 1948 } 1949 return false 1950 1951 default: 1952 return false 1953 } 1954 } 1955 1956 // IsFkSelfRefer checks the foreign key referencing itself 1957 func IsFkSelfRefer(fkDbName, fkTableName, curDbName, curTableName string) bool { 1958 return fkDbName == curDbName && fkTableName == curTableName 1959 } 1960 1961 // HasFkSelfReferOnly checks the foreign key referencing itself only. 1962 // If there is no children tables, it also returns true 1963 // the tbleId 0 is special. it always denotes the table itself. 1964 func HasFkSelfReferOnly(tableDef *TableDef) bool { 1965 for _, tbl := range tableDef.RefChildTbls { 1966 if tbl != 0 { 1967 return false 1968 } 1969 } 1970 return true 1971 } 1972 1973 func IsFalseExpr(e *Expr) bool { 1974 if e == nil || e.GetTyp().Id != int32(types.T_bool) || e.GetLit() == nil { 1975 return false 1976 } 1977 if x, ok := e.GetLit().GetValue().(*plan.Literal_Bval); ok { 1978 return !x.Bval 1979 } 1980 return false 1981 } 1982 func MakeFalseExpr() *Expr { 1983 return &plan.Expr{ 1984 Typ: plan.Type{ 1985 Id: int32(types.T_bool), 1986 }, 1987 Expr: &plan.Expr_Lit{ 1988 Lit: &plan.Literal{ 1989 Isnull: false, 1990 Value: &plan.Literal_Bval{Bval: false}, 1991 }, 1992 }, 1993 } 1994 } 1995 1996 func MakeRuntimeFilter(tag int32, matchPrefix bool, upperlimit int32, expr *Expr) *plan.RuntimeFilterSpec { 1997 return &plan.RuntimeFilterSpec{ 1998 Tag: tag, 1999 UpperLimit: upperlimit, 2000 Expr: expr, 2001 MatchPrefix: matchPrefix, 2002 } 2003 } 2004 2005 func MakeIntervalExpr(num int64, str string) *Expr { 2006 arg0 := makePlan2Int64ConstExprWithType(num) 2007 arg1 := makePlan2StringConstExprWithType(str, false) 2008 return &plan.Expr{ 2009 Typ: plan.Type{ 2010 Id: int32(types.T_interval), 2011 }, 2012 Expr: &plan.Expr_List{ 2013 List: &plan.ExprList{ 2014 List: []*Expr{arg0, arg1}, 2015 }, 2016 }, 2017 } 2018 } 2019 2020 func MakeInExpr(ctx context.Context, left *Expr, length int32, data []byte, matchPrefix bool) *Expr { 2021 rightType := plan.Type{Id: int32(types.T_tuple)} 2022 if matchPrefix { 2023 rightType = left.Typ 2024 } 2025 rightArg := &plan.Expr{ 2026 Typ: rightType, 2027 Expr: &plan.Expr_Vec{ 2028 Vec: &plan.LiteralVec{ 2029 Len: length, 2030 Data: data, 2031 }, 2032 }, 2033 } 2034 2035 funcID := function.InFunctionEncodedID 2036 funcName := function.InFunctionName 2037 if matchPrefix { 2038 funcID = function.PrefixInFunctionEncodedID 2039 funcName = function.PrefixInFunctionName 2040 } 2041 args := []types.Type{makeTypeByPlan2Expr(left), makeTypeByPlan2Expr(rightArg)} 2042 fGet, err := function.GetFunctionByName(ctx, funcName, args) 2043 if err == nil { 2044 funcID = fGet.GetEncodedOverloadID() 2045 } 2046 inExpr := &plan.Expr{ 2047 Typ: plan.Type{ 2048 Id: int32(types.T_bool), 2049 NotNullable: left.Typ.NotNullable, 2050 }, 2051 Expr: &plan.Expr_F{ 2052 F: &plan.Function{ 2053 Func: &plan.ObjectRef{ 2054 Obj: funcID, 2055 ObjName: funcName, 2056 }, 2057 Args: []*plan.Expr{ 2058 left, 2059 rightArg, 2060 }, 2061 }, 2062 }, 2063 } 2064 return inExpr 2065 } 2066 2067 // FillValuesOfParamsInPlan replaces the params by their values 2068 func FillValuesOfParamsInPlan(ctx context.Context, preparePlan *Plan, paramVals []any) (*Plan, error) { 2069 copied := preparePlan 2070 2071 switch pp := copied.Plan.(type) { 2072 case *plan.Plan_Tcl, *plan.Plan_Dcl: 2073 return nil, moerr.NewInvalidInput(ctx, "cannot prepare TCL and DCL statement") 2074 2075 case *plan.Plan_Ddl: 2076 if pp.Ddl.Query != nil { 2077 err := replaceParamVals(ctx, preparePlan, paramVals) 2078 if err != nil { 2079 return nil, err 2080 } 2081 } 2082 2083 case *plan.Plan_Query: 2084 err := replaceParamVals(ctx, preparePlan, paramVals) 2085 if err != nil { 2086 return nil, err 2087 } 2088 } 2089 return copied, nil 2090 } 2091 2092 func replaceParamVals(ctx context.Context, plan0 *Plan, paramVals []any) error { 2093 params := make([]*Expr, len(paramVals)) 2094 for i, val := range paramVals { 2095 pc := &plan.Literal{} 2096 pc.Value = &plan.Literal_Sval{Sval: fmt.Sprintf("%v", val)} 2097 params[i] = &plan.Expr{ 2098 Expr: &plan.Expr_Lit{ 2099 Lit: pc, 2100 }, 2101 } 2102 } 2103 paramRule := NewResetParamRefRule(ctx, params) 2104 VisitQuery := NewVisitPlan(plan0, []VisitPlanRule{paramRule}) 2105 err := VisitQuery.Visit(ctx) 2106 if err != nil { 2107 return err 2108 } 2109 return nil 2110 } 2111 2112 // XXX: Any code relying on Name in ColRef, except for "explain", is bad design and practically buggy. 2113 func (builder *QueryBuilder) addNameByColRef(tag int32, tableDef *plan.TableDef) { 2114 for i, col := range tableDef.Cols { 2115 builder.nameByColRef[[2]int32{tag, int32(i)}] = tableDef.Name + "." + col.Name 2116 } 2117 } 2118 2119 func GetRowSizeFromTableDef(tableDef *TableDef, ignoreHiddenKey bool) float64 { 2120 size := int32(0) 2121 for _, col := range tableDef.Cols { 2122 if col.Hidden && ignoreHiddenKey { 2123 continue 2124 } 2125 if col.Typ.Width > 0 { 2126 size += col.Typ.Width 2127 continue 2128 } 2129 typ := types.T(col.Typ.Id).ToType() 2130 if typ.Width > 0 { 2131 size += typ.Width 2132 } else { 2133 size += typ.Size 2134 } 2135 } 2136 return float64(size) 2137 }