github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/base_binder.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 "encoding/hex" 20 "fmt" 21 "go/constant" 22 "strings" 23 24 "github.com/matrixorigin/matrixone/pkg/sql/plan/function/builtin/binary" 25 "github.com/matrixorigin/matrixone/pkg/util/errutil" 26 27 "github.com/matrixorigin/matrixone/pkg/common/moerr" 28 "github.com/matrixorigin/matrixone/pkg/container/types" 29 "github.com/matrixorigin/matrixone/pkg/pb/plan" 30 "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" 31 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 32 "github.com/matrixorigin/matrixone/pkg/sql/plan/function" 33 ) 34 35 func (b *baseBinder) baseBindExpr(astExpr tree.Expr, depth int32, isRoot bool) (expr *Expr, err error) { 36 switch exprImpl := astExpr.(type) { 37 case *tree.NumVal: 38 if d, ok := b.impl.(*DefaultBinder); ok { 39 expr, err = b.bindNumVal(exprImpl, d.typ) 40 } else { 41 expr, err = b.bindNumVal(exprImpl, nil) 42 } 43 case *tree.ParenExpr: 44 expr, err = b.impl.BindExpr(exprImpl.Expr, depth, isRoot) 45 46 case *tree.OrExpr: 47 expr, err = b.bindFuncExprImplByAstExpr("or", []tree.Expr{exprImpl.Left, exprImpl.Right}, depth) 48 49 case *tree.NotExpr: 50 if subqueryAst, ok := exprImpl.Expr.(*tree.Subquery); ok { 51 expr, err = b.impl.BindSubquery(subqueryAst, isRoot) 52 if err != nil { 53 return 54 } 55 56 subquery := expr.Expr.(*plan.Expr_Sub) 57 if subquery.Sub.Typ == plan.SubqueryRef_EXISTS { 58 subquery.Sub.Typ = plan.SubqueryRef_NOT_EXISTS 59 } 60 } else { 61 expr, err = b.impl.BindExpr(exprImpl.Expr, depth, false) 62 if err != nil { 63 return 64 } 65 66 expr, err = bindFuncExprImplByPlanExpr(b.GetContext(), "not", []*plan.Expr{expr}) 67 } 68 69 case *tree.AndExpr: 70 expr, err = b.bindFuncExprImplByAstExpr("and", []tree.Expr{exprImpl.Left, exprImpl.Right}, depth) 71 72 case *tree.UnaryExpr: 73 expr, err = b.bindUnaryExpr(exprImpl, depth, isRoot) 74 75 case *tree.BinaryExpr: 76 expr, err = b.bindBinaryExpr(exprImpl, depth, isRoot) 77 78 case *tree.ComparisonExpr: 79 expr, err = b.bindComparisonExpr(exprImpl, depth, isRoot) 80 81 case *tree.FuncExpr: 82 expr, err = b.bindFuncExpr(exprImpl, depth, isRoot) 83 84 case *tree.RangeCond: 85 expr, err = b.bindRangeCond(exprImpl, depth, isRoot) 86 87 case *tree.UnresolvedName: 88 expr, err = b.impl.BindColRef(exprImpl, depth, isRoot) 89 90 case *tree.CastExpr: 91 expr, err = b.impl.BindExpr(exprImpl.Expr, depth, false) 92 if err != nil { 93 return 94 } 95 var typ *Type 96 typ, err = getTypeFromAst(b.GetContext(), exprImpl.Type) 97 if err != nil { 98 return 99 } 100 expr, err = appendCastBeforeExpr(b.GetContext(), expr, typ) 101 102 case *tree.IsNullExpr: 103 expr, err = b.bindFuncExprImplByAstExpr("isnull", []tree.Expr{exprImpl.Expr}, depth) 104 105 case *tree.IsNotNullExpr: 106 expr, err = b.bindFuncExprImplByAstExpr("isnotnull", []tree.Expr{exprImpl.Expr}, depth) 107 108 case *tree.IsUnknownExpr: 109 expr, err = b.bindFuncExprImplByAstExpr("isnull", []tree.Expr{exprImpl.Expr}, depth) 110 111 case *tree.IsNotUnknownExpr: 112 expr, err = b.bindFuncExprImplByAstExpr("isnotnull", []tree.Expr{exprImpl.Expr}, depth) 113 114 case *tree.IsTrueExpr: 115 expr, err = b.bindFuncExprImplByAstExpr("istrue", []tree.Expr{exprImpl.Expr}, depth) 116 117 case *tree.IsNotTrueExpr: 118 expr, err = b.bindFuncExprImplByAstExpr("isnottrue", []tree.Expr{exprImpl.Expr}, depth) 119 120 case *tree.IsFalseExpr: 121 expr, err = b.bindFuncExprImplByAstExpr("isfalse", []tree.Expr{exprImpl.Expr}, depth) 122 123 case *tree.IsNotFalseExpr: 124 expr, err = b.bindFuncExprImplByAstExpr("isnotfalse", []tree.Expr{exprImpl.Expr}, depth) 125 126 case *tree.Tuple: 127 exprs := make([]*Expr, 0, len(exprImpl.Exprs)) 128 var planItem *Expr 129 for _, astItem := range exprImpl.Exprs { 130 planItem, err = b.impl.BindExpr(astItem, depth, false) 131 if err != nil { 132 return 133 } 134 exprs = append(exprs, planItem) 135 } 136 expr = &Expr{ 137 Expr: &plan.Expr_List{ 138 List: &plan.ExprList{ 139 List: exprs, 140 }, 141 }, 142 Typ: &plan.Type{ 143 Id: int32(types.T_tuple), 144 }, 145 } 146 147 case *tree.CaseExpr: 148 expr, err = b.bindCaseExpr(exprImpl, depth, isRoot) 149 150 case *tree.IntervalExpr: 151 err = moerr.NewNYI(b.GetContext(), "expr interval'%v'", exprImpl) 152 153 case *tree.XorExpr: 154 expr, err = b.bindFuncExprImplByAstExpr("xor", []tree.Expr{exprImpl.Left, exprImpl.Right}, depth) 155 156 case *tree.Subquery: 157 expr, err = b.impl.BindSubquery(exprImpl, isRoot) 158 159 case *tree.DefaultVal: 160 return &Expr{ 161 Expr: &plan.Expr_C{ 162 C: &Const{ 163 Isnull: false, 164 Value: &plan.Const_Defaultval{ 165 Defaultval: true, 166 }, 167 }, 168 }, 169 }, nil 170 case *tree.UpdateVal: 171 return &Expr{ 172 Expr: &plan.Expr_C{ 173 C: &Const{ 174 Isnull: false, 175 Value: &plan.Const_UpdateVal{ 176 UpdateVal: true, 177 }, 178 }, 179 }, 180 }, nil 181 case *tree.MaxValue: 182 return &Expr{ 183 Expr: &plan.Expr_Max{ 184 Max: &MaxValue{ 185 Value: "maxvalue", 186 }, 187 }, 188 }, nil 189 case *tree.VarExpr: 190 expr, err = b.baseBindVar(exprImpl, depth, isRoot) 191 192 case *tree.ParamExpr: 193 expr, err = b.baseBindParam(exprImpl, depth, isRoot) 194 195 case *tree.StrVal: 196 err = moerr.NewNYI(b.GetContext(), "expr str'%v'", exprImpl) 197 198 case *tree.ExprList: 199 err = moerr.NewNYI(b.GetContext(), "expr plan.ExprList'%v'", exprImpl) 200 201 case tree.UnqualifiedStar: 202 // select * from table 203 // * should only appear in SELECT clause 204 err = moerr.NewInvalidInput(b.GetContext(), "SELECT clause contains unqualified star") 205 206 default: 207 err = moerr.NewNYI(b.GetContext(), "expr '%+v'", exprImpl) 208 } 209 210 return 211 } 212 213 func (b *baseBinder) baseBindParam(astExpr *tree.ParamExpr, depth int32, isRoot bool) (expr *plan.Expr, err error) { 214 return &Expr{ 215 Typ: &plan.Type{ 216 Id: int32(types.T_any), 217 }, 218 Expr: &plan.Expr_P{ 219 P: &plan.ParamRef{ 220 Pos: int32(astExpr.Offset), 221 }, 222 }, 223 }, nil 224 } 225 226 func (b *baseBinder) baseBindVar(astExpr *tree.VarExpr, depth int32, isRoot bool) (expr *plan.Expr, err error) { 227 return &Expr{ 228 Typ: &plan.Type{ 229 Id: int32(types.T_any), 230 }, 231 Expr: &plan.Expr_V{ 232 V: &plan.VarRef{ 233 Name: astExpr.Name, 234 System: astExpr.System, 235 Global: astExpr.Global, 236 }, 237 }, 238 }, nil 239 } 240 241 func (b *baseBinder) baseBindColRef(astExpr *tree.UnresolvedName, depth int32, isRoot bool) (expr *plan.Expr, err error) { 242 if b.ctx == nil { 243 return nil, moerr.NewInvalidInput(b.GetContext(), "ambigous column reference '%v'", astExpr.Parts[0]) 244 } 245 246 col := astExpr.Parts[0] 247 table := astExpr.Parts[1] 248 name := tree.String(astExpr, dialect.MYSQL) 249 250 relPos := NotFound 251 colPos := NotFound 252 var typ *plan.Type 253 localErrCtx := errutil.ContextWithNoReport(b.GetContext(), true) 254 255 if len(table) == 0 { 256 if binding, ok := b.ctx.bindingByCol[col]; ok { 257 if binding != nil { 258 relPos = binding.tag 259 colPos = binding.colIdByName[col] 260 typ = binding.types[colPos] 261 table = binding.table 262 } else { 263 return nil, moerr.NewInvalidInput(b.GetContext(), "ambiguous column reference '%v'", name) 264 } 265 } else { 266 err = moerr.NewInvalidInput(localErrCtx, "column %s does not exist", name) 267 } 268 } else { 269 if binding, ok := b.ctx.bindingByTable[table]; ok { 270 colPos = binding.FindColumn(col) 271 if colPos == AmbiguousName { 272 return nil, moerr.NewInvalidInput(b.GetContext(), "ambiguous column reference '%v'", name) 273 } 274 if colPos != NotFound { 275 typ = binding.types[colPos] 276 relPos = binding.tag 277 } else { 278 err = moerr.NewInvalidInput(localErrCtx, "column '%s' does not exist", name) 279 } 280 } else { 281 err = moerr.NewInvalidInput(localErrCtx, "missing FROM-clause entry for table '%v'", table) 282 } 283 } 284 285 if colPos != NotFound { 286 b.boundCols = append(b.boundCols, table+"."+col) 287 288 expr = &plan.Expr{ 289 Typ: typ, 290 } 291 292 if depth == 0 { 293 expr.Expr = &plan.Expr_Col{ 294 Col: &plan.ColRef{ 295 RelPos: relPos, 296 ColPos: colPos, 297 }, 298 } 299 } else { 300 expr.Expr = &plan.Expr_Corr{ 301 Corr: &plan.CorrColRef{ 302 RelPos: relPos, 303 ColPos: colPos, 304 Depth: depth, 305 }, 306 } 307 } 308 if err != nil { 309 errutil.ReportError(b.GetContext(), err) 310 } 311 return 312 } 313 314 parent := b.ctx.parent 315 for parent != nil && parent.binder == nil { 316 parent = parent.parent 317 } 318 319 if parent == nil { 320 if err != nil { 321 errutil.ReportError(b.GetContext(), err) 322 } 323 return 324 } 325 326 expr, err = parent.binder.BindColRef(astExpr, depth+1, isRoot) 327 328 if err == nil { 329 b.ctx.isCorrelated = true 330 } 331 332 return 333 } 334 335 func (b *baseBinder) baseBindSubquery(astExpr *tree.Subquery, isRoot bool) (*Expr, error) { 336 if b.ctx == nil { 337 return nil, moerr.NewInvalidInput(b.GetContext(), "field reference doesn't support SUBQUERY") 338 } 339 subCtx := NewBindContext(b.builder, b.ctx) 340 341 var nodeID int32 342 var err error 343 switch subquery := astExpr.Select.(type) { 344 case *tree.ParenSelect: 345 nodeID, err = b.builder.buildSelect(subquery.Select, subCtx, false) 346 if err != nil { 347 return nil, err 348 } 349 350 default: 351 return nil, moerr.NewNYI(b.GetContext(), "unsupported select statement: %s", tree.String(astExpr, dialect.MYSQL)) 352 } 353 354 rowSize := int32(len(subCtx.results)) 355 356 returnExpr := &plan.Expr{ 357 Typ: &plan.Type{ 358 Id: int32(types.T_tuple), 359 }, 360 Expr: &plan.Expr_Sub{ 361 Sub: &plan.SubqueryRef{ 362 NodeId: nodeID, 363 RowSize: rowSize, 364 }, 365 }, 366 } 367 368 if astExpr.Exists { 369 returnExpr.Typ = &plan.Type{ 370 Id: int32(types.T_bool), 371 NotNullable: true, 372 Size: 1, 373 } 374 returnExpr.Expr.(*plan.Expr_Sub).Sub.Typ = plan.SubqueryRef_EXISTS 375 } else if rowSize == 1 { 376 returnExpr.Typ = subCtx.results[0].Typ 377 } 378 379 return returnExpr, nil 380 } 381 382 func (b *baseBinder) bindCaseExpr(astExpr *tree.CaseExpr, depth int32, isRoot bool) (*Expr, error) { 383 args := make([]tree.Expr, 0, len(astExpr.Whens)+1) 384 caseExist := astExpr.Expr != nil 385 386 for _, whenExpr := range astExpr.Whens { 387 if caseExist { 388 newCandExpr := tree.NewComparisonExpr(tree.EQUAL, astExpr.Expr, whenExpr.Cond) 389 args = append(args, newCandExpr) 390 } else { 391 args = append(args, whenExpr.Cond) 392 } 393 args = append(args, whenExpr.Val) 394 } 395 396 if astExpr.Else != nil { 397 args = append(args, astExpr.Else) 398 } else { 399 args = append(args, tree.NewNumValWithType(constant.MakeUnknown(), "", false, tree.P_null)) 400 } 401 402 return b.bindFuncExprImplByAstExpr("case", args, depth) 403 } 404 405 func (b *baseBinder) bindRangeCond(astExpr *tree.RangeCond, depth int32, isRoot bool) (*Expr, error) { 406 if astExpr.Not { 407 // rewrite 'col not between 1, 20' to 'col < 1 or col > 20' 408 newLefExpr := tree.NewComparisonExpr(tree.LESS_THAN, astExpr.Left, astExpr.From) 409 newRightExpr := tree.NewComparisonExpr(tree.GREAT_THAN, astExpr.Left, astExpr.To) 410 return b.bindFuncExprImplByAstExpr("or", []tree.Expr{newLefExpr, newRightExpr}, depth) 411 } else { 412 // rewrite 'col between 1, 20 ' to ' col >= 1 and col <= 2' 413 newLefExpr := tree.NewComparisonExpr(tree.GREAT_THAN_EQUAL, astExpr.Left, astExpr.From) 414 newRightExpr := tree.NewComparisonExpr(tree.LESS_THAN_EQUAL, astExpr.Left, astExpr.To) 415 return b.bindFuncExprImplByAstExpr("and", []tree.Expr{newLefExpr, newRightExpr}, depth) 416 } 417 } 418 419 func (b *baseBinder) bindUnaryExpr(astExpr *tree.UnaryExpr, depth int32, isRoot bool) (*Expr, error) { 420 switch astExpr.Op { 421 case tree.UNARY_MINUS: 422 return b.bindFuncExprImplByAstExpr("unary_minus", []tree.Expr{astExpr.Expr}, depth) 423 case tree.UNARY_PLUS: 424 return b.bindFuncExprImplByAstExpr("unary_plus", []tree.Expr{astExpr.Expr}, depth) 425 case tree.UNARY_TILDE: 426 return b.bindFuncExprImplByAstExpr("unary_tilde", []tree.Expr{astExpr.Expr}, depth) 427 case tree.UNARY_MARK: 428 return nil, moerr.NewNYI(b.GetContext(), "'%v'", astExpr) 429 } 430 return nil, moerr.NewNYI(b.GetContext(), "'%v'", astExpr) 431 } 432 433 func (b *baseBinder) bindBinaryExpr(astExpr *tree.BinaryExpr, depth int32, isRoot bool) (*Expr, error) { 434 switch astExpr.Op { 435 case tree.PLUS: 436 return b.bindFuncExprImplByAstExpr("+", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 437 case tree.MINUS: 438 return b.bindFuncExprImplByAstExpr("-", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 439 case tree.MULTI: 440 return b.bindFuncExprImplByAstExpr("*", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 441 case tree.MOD: 442 return b.bindFuncExprImplByAstExpr("%", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 443 case tree.DIV: 444 return b.bindFuncExprImplByAstExpr("/", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 445 case tree.INTEGER_DIV: 446 return b.bindFuncExprImplByAstExpr("div", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 447 case tree.BIT_XOR: 448 return b.bindFuncExprImplByAstExpr("^", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 449 case tree.BIT_OR: 450 return b.bindFuncExprImplByAstExpr("|", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 451 case tree.BIT_AND: 452 return b.bindFuncExprImplByAstExpr("&", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 453 case tree.LEFT_SHIFT: 454 return b.bindFuncExprImplByAstExpr("<<", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 455 case tree.RIGHT_SHIFT: 456 return b.bindFuncExprImplByAstExpr(">>", []tree.Expr{astExpr.Left, astExpr.Right}, depth) 457 } 458 return nil, moerr.NewNYI(b.GetContext(), "'%v' operator", astExpr.Op.ToString()) 459 } 460 461 func (b *baseBinder) bindComparisonExpr(astExpr *tree.ComparisonExpr, depth int32, isRoot bool) (*Expr, error) { 462 var op string 463 464 switch astExpr.Op { 465 case tree.EQUAL: 466 op = "=" 467 468 case tree.LESS_THAN: 469 op = "<" 470 471 case tree.LESS_THAN_EQUAL: 472 op = "<=" 473 474 case tree.GREAT_THAN: 475 op = ">" 476 477 case tree.GREAT_THAN_EQUAL: 478 op = ">=" 479 480 case tree.NOT_EQUAL: 481 op = "<>" 482 483 case tree.LIKE: 484 op = "like" 485 486 case tree.NOT_LIKE: 487 newExpr := tree.NewComparisonExpr(tree.LIKE, astExpr.Left, astExpr.Right) 488 return b.bindFuncExprImplByAstExpr("not", []tree.Expr{newExpr}, depth) 489 490 case tree.ILIKE: 491 op = "ilike" 492 493 case tree.NOT_ILIKE: 494 newExpr := tree.NewComparisonExpr(tree.ILIKE, astExpr.Left, astExpr.Right) 495 return b.bindFuncExprImplByAstExpr("not", []tree.Expr{newExpr}, depth) 496 497 case tree.IN: 498 switch astExpr.Right.(type) { 499 case *tree.Tuple: 500 op = "in" 501 502 default: 503 leftArg, err := b.impl.BindExpr(astExpr.Left, depth, false) 504 if err != nil { 505 return nil, err 506 } 507 508 rightArg, err := b.impl.BindExpr(astExpr.Right, depth, false) 509 if err != nil { 510 return nil, err 511 } 512 513 if subquery, ok := rightArg.Expr.(*plan.Expr_Sub); ok { 514 if list, ok := leftArg.Expr.(*plan.Expr_List); ok { 515 if len(list.List.List) != int(subquery.Sub.RowSize) { 516 return nil, moerr.NewNYI(b.GetContext(), "subquery should return %d columns", len(list.List.List)) 517 } 518 } else { 519 if subquery.Sub.RowSize > 1 { 520 return nil, moerr.NewInvalidInput(b.GetContext(), "subquery returns more than 1 column") 521 } 522 } 523 524 subquery.Sub.Typ = plan.SubqueryRef_IN 525 subquery.Sub.Child = leftArg 526 527 rightArg.Typ = &plan.Type{ 528 Id: int32(types.T_bool), 529 NotNullable: leftArg.Typ.NotNullable && rightArg.Typ.NotNullable, 530 Size: 1, 531 } 532 533 return rightArg, nil 534 } else { 535 return bindFuncExprImplByPlanExpr(b.GetContext(), "in", []*plan.Expr{leftArg, rightArg}) 536 } 537 } 538 539 case tree.NOT_IN: 540 switch astExpr.Right.(type) { 541 case *tree.Tuple: 542 op = "not_in" 543 544 default: 545 leftArg, err := b.impl.BindExpr(astExpr.Left, depth, false) 546 if err != nil { 547 return nil, err 548 } 549 550 rightArg, err := b.impl.BindExpr(astExpr.Right, depth, false) 551 if err != nil { 552 return nil, err 553 } 554 555 if subquery, ok := rightArg.Expr.(*plan.Expr_Sub); ok { 556 if list, ok := leftArg.Expr.(*plan.Expr_List); ok { 557 if len(list.List.List) != int(subquery.Sub.RowSize) { 558 return nil, moerr.NewInvalidInput(b.GetContext(), "subquery should return %d columns", len(list.List.List)) 559 } 560 } else { 561 if subquery.Sub.RowSize > 1 { 562 return nil, moerr.NewInvalidInput(b.GetContext(), "subquery should return 1 column") 563 } 564 } 565 566 subquery.Sub.Typ = plan.SubqueryRef_NOT_IN 567 subquery.Sub.Child = leftArg 568 569 rightArg.Typ = &plan.Type{ 570 Id: int32(types.T_bool), 571 NotNullable: leftArg.Typ.NotNullable && rightArg.Typ.NotNullable, 572 Size: 1, 573 } 574 575 return rightArg, nil 576 } else { 577 expr, err := bindFuncExprImplByPlanExpr(b.GetContext(), "in", []*plan.Expr{leftArg, rightArg}) 578 if err != nil { 579 return nil, err 580 } 581 582 return bindFuncExprImplByPlanExpr(b.GetContext(), "not", []*plan.Expr{expr}) 583 } 584 } 585 case tree.REG_MATCH: 586 op = "reg_match" 587 case tree.NOT_REG_MATCH: 588 op = "not_reg_match" 589 default: 590 return nil, moerr.NewNYI(b.GetContext(), "'%v'", astExpr) 591 } 592 593 if astExpr.SubOp >= tree.ANY { 594 expr, err := b.impl.BindExpr(astExpr.Right, depth, false) 595 if err != nil { 596 return nil, err 597 } 598 599 child, err := b.impl.BindExpr(astExpr.Left, depth, false) 600 if err != nil { 601 return nil, err 602 } 603 604 if subquery, ok := expr.Expr.(*plan.Expr_Sub); ok { 605 if list, ok := child.Expr.(*plan.Expr_List); ok { 606 if len(list.List.List) != int(subquery.Sub.RowSize) { 607 return nil, moerr.NewInvalidInput(b.GetContext(), "subquery should return %d columns", len(list.List.List)) 608 } 609 } else { 610 if subquery.Sub.RowSize > 1 { 611 return nil, moerr.NewInvalidInput(b.GetContext(), "subquery should return 1 column") 612 } 613 } 614 615 subquery.Sub.Op = op 616 subquery.Sub.Child = child 617 618 switch astExpr.SubOp { 619 case tree.ANY, tree.SOME: 620 subquery.Sub.Typ = plan.SubqueryRef_ANY 621 case tree.ALL: 622 subquery.Sub.Typ = plan.SubqueryRef_ALL 623 } 624 625 expr.Typ = &plan.Type{ 626 Id: int32(types.T_bool), 627 NotNullable: expr.Typ.NotNullable && child.Typ.NotNullable, 628 Size: 1, 629 } 630 631 return expr, nil 632 } else { 633 return nil, moerr.NewInvalidInput(b.GetContext(), "subquery '%s' is not a quantifying subquery", astExpr.SubOp.ToString()) 634 } 635 } 636 637 return b.bindFuncExprImplByAstExpr(op, []tree.Expr{astExpr.Left, astExpr.Right}, depth) 638 } 639 640 func (b *baseBinder) bindFuncExpr(astExpr *tree.FuncExpr, depth int32, isRoot bool) (*Expr, error) { 641 funcRef, ok := astExpr.Func.FunctionReference.(*tree.UnresolvedName) 642 if !ok { 643 return nil, moerr.NewNYI(b.GetContext(), "function expr '%v'", astExpr) 644 } 645 funcName := funcRef.Parts[0] 646 647 if function.GetFunctionIsAggregateByName(funcName) { 648 return b.impl.BindAggFunc(funcName, astExpr, depth, isRoot) 649 } else if function.GetFunctionIsWinfunByName(funcName) { 650 return b.impl.BindWinFunc(funcName, astExpr, depth, isRoot) 651 } 652 653 return b.bindFuncExprImplByAstExpr(funcName, astExpr.Exprs, depth) 654 } 655 656 func (b *baseBinder) bindFuncExprImplByAstExpr(name string, astArgs []tree.Expr, depth int32) (*plan.Expr, error) { 657 // rewrite some ast Exprs before binding 658 switch name { 659 case "nullif": 660 // rewrite 'nullif(expr1, expr2)' to 'case when expr1=expr2 then null else expr1' 661 if len(astArgs) != 2 { 662 return nil, moerr.NewInvalidArg(b.GetContext(), "nullif need two args", len(astArgs)) 663 } 664 elseExpr := astArgs[0] 665 thenExpr := tree.NewNumValWithType(constant.MakeUnknown(), "", false, tree.P_char) 666 whenExpr := tree.NewComparisonExpr(tree.EQUAL, astArgs[0], astArgs[1]) 667 astArgs = []tree.Expr{whenExpr, thenExpr, elseExpr} 668 name = "case" 669 case "ifnull": 670 // rewrite 'ifnull(expr1, expr2)' to 'case when isnull(expr1) then expr2 else null' 671 if len(astArgs) != 2 { 672 return nil, moerr.NewInvalidArg(b.GetContext(), "ifnull function need two args", len(astArgs)) 673 } 674 elseExpr := tree.NewNumValWithType(constant.MakeUnknown(), "", false, tree.P_null) 675 thenExpr := astArgs[1] 676 whenExpr := tree.NewIsNullExpr(astArgs[0]) 677 astArgs = []tree.Expr{whenExpr, thenExpr, elseExpr} 678 name = "case" 679 //case "extract": 680 // // "extract(year from col_name)" parser return year as UnresolvedName. 681 // // we must rewrite it to string。 because binder bind UnresolvedName as column name 682 // unit := astArgs[0].(*tree.UnresolvedName).Parts[0] 683 // astArgs[0] = tree.NewNumVal(constant.MakeString(unit), unit, false) 684 case "count": 685 if b.ctx == nil { 686 return nil, moerr.NewInvalidInput(b.GetContext(), "invalid field reference to COUNT") 687 } 688 // we will rewrite "count(*)" to "starcount(col)" 689 // count(*) : astExprs[0].(type) is *tree.NumVal 690 // count(col_name) : astExprs[0].(type) is *tree.UnresolvedName 691 switch nval := astArgs[0].(type) { 692 case *tree.NumVal: 693 if nval.String() == "*" { 694 if len(b.ctx.bindings) == 0 || len(b.ctx.bindings[0].cols) == 0 { 695 // sql: 'select count(*)' without from clause. we do nothing 696 } else { 697 // sql: 'select count(*) from t1', 698 // rewrite count(*) to starcount(col_name) 699 name = "starcount" 700 701 astArgs[0] = tree.NewNumValWithType(constant.MakeInt64(1), "1", false, tree.P_int64) 702 } 703 } 704 } 705 case "trim": 706 astArgs = astArgs[1:] 707 } 708 // bind ast function's args 709 args := make([]*Expr, len(astArgs)) 710 for idx, arg := range astArgs { 711 expr, err := b.impl.BindExpr(arg, depth, false) 712 if err != nil { 713 return nil, err 714 } 715 args[idx] = expr 716 } 717 718 return bindFuncExprImplByPlanExpr(b.GetContext(), name, args) 719 } 720 721 func bindFuncExprImplByPlanExpr(ctx context.Context, name string, args []*Expr) (*plan.Expr, error) { 722 var err error 723 724 // deal with some special function 725 switch name { 726 case "date": 727 // rewrite date function to cast function, and retrun directly 728 if len(args) == 0 { 729 return nil, moerr.NewInvalidArg(ctx, name+" function have invalid input args length", len(args)) 730 } 731 if args[0].Typ.Id != int32(types.T_varchar) && args[0].Typ.Id != int32(types.T_char) { 732 return appendCastBeforeExpr(ctx, args[0], &Type{ 733 Id: int32(types.T_date), 734 }) 735 } 736 case "interval": 737 // rewrite interval function to ListExpr, and retrun directly 738 return &plan.Expr{ 739 Typ: &plan.Type{ 740 Id: int32(types.T_interval), 741 }, 742 Expr: &plan.Expr_List{ 743 List: &plan.ExprList{ 744 List: args, 745 }, 746 }, 747 }, nil 748 case "and", "or", "not", "xor": 749 // why not append cast function? 750 // for i := 0; i < len(args); i++ { 751 // if args[i].Typ.Id != types.T_bool { 752 // arg, err := appendCastBeforeExpr(args[i], &plan.Type{ 753 // Id: types.T_bool, 754 // }) 755 // if err != nil { 756 // return nil, err 757 // } 758 // args[i] = arg 759 // } 760 // } 761 if err := convertValueIntoBool(name, args, true); err != nil { 762 return nil, err 763 } 764 case "=", "<", "<=", ">", ">=", "<>": 765 // why not append cast function? 766 if err := convertValueIntoBool(name, args, false); err != nil { 767 return nil, err 768 } 769 case "date_add", "date_sub": 770 // rewrite date_add/date_sub function 771 // date_add(col_name, "1 day"), will rewrite to date_add(col_name, number, unit) 772 if len(args) != 2 { 773 return nil, moerr.NewInvalidArg(ctx, "date_add/date_sub function need two args", len(args)) 774 } 775 args, err = resetDateFunction(ctx, args[0], args[1]) 776 if err != nil { 777 return nil, err 778 } 779 case "adddate", "subdate": 780 if len(args) != 2 { 781 return nil, moerr.NewInvalidArg(ctx, "adddate/subdate function need two args", len(args)) 782 } 783 args, err = resetDateFunction(ctx, args[0], args[1]) 784 if err != nil { 785 return nil, err 786 } 787 if name == "adddate" { 788 name = "date_add" 789 } else { 790 name = "date_sub" 791 } 792 case "+": 793 if len(args) != 2 { 794 return nil, moerr.NewInvalidArg(ctx, "operator + need two args", len(args)) 795 } 796 if isNullExpr(args[0]) { 797 return args[0], nil 798 } 799 if isNullExpr(args[1]) { 800 return args[1], nil 801 } 802 if args[0].Typ.Id == int32(types.T_date) && args[1].Typ.Id == int32(types.T_interval) { 803 name = "date_add" 804 args, err = resetDateFunctionArgs(ctx, args[0], args[1]) 805 } else if args[0].Typ.Id == int32(types.T_interval) && args[1].Typ.Id == int32(types.T_date) { 806 name = "date_add" 807 args, err = resetDateFunctionArgs(ctx, args[1], args[0]) 808 } else if args[0].Typ.Id == int32(types.T_datetime) && args[1].Typ.Id == int32(types.T_interval) { 809 name = "date_add" 810 args, err = resetDateFunctionArgs(ctx, args[0], args[1]) 811 } else if args[0].Typ.Id == int32(types.T_interval) && args[1].Typ.Id == int32(types.T_datetime) { 812 name = "date_add" 813 args, err = resetDateFunctionArgs(ctx, args[1], args[0]) 814 } else if args[0].Typ.Id == int32(types.T_varchar) && args[1].Typ.Id == int32(types.T_interval) { 815 name = "date_add" 816 args, err = resetDateFunctionArgs(ctx, args[0], args[1]) 817 } else if args[0].Typ.Id == int32(types.T_interval) && args[1].Typ.Id == int32(types.T_varchar) { 818 name = "date_add" 819 args, err = resetDateFunctionArgs(ctx, args[1], args[0]) 820 } else if args[0].Typ.Id == int32(types.T_varchar) && args[1].Typ.Id == int32(types.T_varchar) { 821 name = "concat" 822 } 823 if err != nil { 824 return nil, err 825 } 826 case "-": 827 if len(args) != 2 { 828 return nil, moerr.NewInvalidArg(ctx, "operator - need two args", len(args)) 829 } 830 if isNullExpr(args[0]) { 831 return args[0], nil 832 } 833 if isNullExpr(args[1]) { 834 return args[1], nil 835 } 836 // rewrite "date '2001' - interval '1 day'" to date_sub(date '2001', 1, day(unit)) 837 if args[0].Typ.Id == int32(types.T_date) && args[1].Typ.Id == int32(types.T_interval) { 838 name = "date_sub" 839 args, err = resetDateFunctionArgs(ctx, args[0], args[1]) 840 } else if args[0].Typ.Id == int32(types.T_datetime) && args[1].Typ.Id == int32(types.T_interval) { 841 name = "date_sub" 842 args, err = resetDateFunctionArgs(ctx, args[0], args[1]) 843 } else if args[0].Typ.Id == int32(types.T_varchar) && args[1].Typ.Id == int32(types.T_interval) { 844 name = "date_sub" 845 args, err = resetDateFunctionArgs(ctx, args[0], args[1]) 846 } 847 if err != nil { 848 return nil, err 849 } 850 case "*", "/", "%": 851 if len(args) != 2 { 852 return nil, moerr.NewInvalidArg(ctx, fmt.Sprintf("operator %s need two args", name), len(args)) 853 } 854 if isNullExpr(args[0]) { 855 return args[0], nil 856 } 857 if isNullExpr(args[1]) { 858 return args[1], nil 859 } 860 case "unary_minus": 861 if len(args) == 0 { 862 return nil, moerr.NewInvalidArg(ctx, name+" function have invalid input args length", len(args)) 863 } 864 if args[0].Typ.Id == int32(types.T_uint64) { 865 args[0], err = appendCastBeforeExpr(ctx, args[0], &plan.Type{ 866 Id: int32(types.T_decimal128), 867 NotNullable: args[0].Typ.NotNullable, 868 }) 869 if err != nil { 870 return nil, err 871 } 872 } 873 case "oct", "bit_and", "bit_or", "bit_xor": 874 if len(args) == 0 { 875 return nil, moerr.NewInvalidArg(ctx, name+" function have invalid input args length", len(args)) 876 } 877 if args[0].Typ.Id == int32(types.T_decimal128) || args[0].Typ.Id == int32(types.T_decimal64) { 878 args[0], err = appendCastBeforeExpr(ctx, args[0], &plan.Type{ 879 Id: int32(types.T_float64), 880 NotNullable: args[0].Typ.NotNullable, 881 }) 882 if err != nil { 883 return nil, err 884 } 885 } 886 case "like": 887 // sql 'select * from t where col like ?' the ? Expr's type will be T_any 888 if len(args) != 2 { 889 return nil, moerr.NewInvalidArg(ctx, name+" function have invalid input args length", len(args)) 890 } 891 if args[0].Typ.Id == int32(types.T_any) { 892 args[0].Typ.Id = int32(types.T_varchar) 893 } 894 if args[1].Typ.Id == int32(types.T_any) { 895 args[1].Typ.Id = int32(types.T_varchar) 896 } 897 if args[0].Typ.Id == int32(types.T_json) { 898 targetTp := types.T_varchar.ToType() 899 args[0], err = appendCastBeforeExpr(ctx, args[0], makePlan2Type(&targetTp), false) 900 if err != nil { 901 return nil, err 902 } 903 } 904 if args[1].Typ.Id == int32(types.T_json) { 905 targetTp := types.T_varchar.ToType() 906 args[1], err = appendCastBeforeExpr(ctx, args[1], makePlan2Type(&targetTp), false) 907 if err != nil { 908 return nil, err 909 } 910 } 911 case "timediff": 912 if len(args) != 2 { 913 return nil, moerr.NewInvalidArg(ctx, name+" function have invalid input args length", len(args)) 914 } 915 916 case "str_to_date", "to_date": 917 if len(args) != 2 { 918 return nil, moerr.NewInvalidArg(ctx, name+" function have invalid input args length", len(args)) 919 } 920 921 if args[1].Typ.Id == int32(types.T_varchar) || args[1].Typ.Id == int32(types.T_char) { 922 if exprC, ok := args[1].Expr.(*plan.Expr_C); ok { 923 sval := exprC.C.Value.(*plan.Const_Sval) 924 tp, _ := binary.JudgmentToDateReturnType(sval.Sval) 925 args = append(args, makePlan2DateConstNullExpr(tp)) 926 } else { 927 return nil, moerr.NewInvalidArg(ctx, "to_date format", "not constant") 928 } 929 } else if args[1].Typ.Id == int32(types.T_any) { 930 args = append(args, makePlan2DateConstNullExpr(types.T_datetime)) 931 } else { 932 return nil, moerr.NewInvalidArg(ctx, name+" function have invalid input args length", len(args)) 933 } 934 case "unix_timestamp": 935 if len(args) == 1 { 936 if types.IsString(types.T(args[0].Typ.Id)) { 937 if exprC, ok := args[0].Expr.(*plan.Expr_C); ok { 938 sval := exprC.C.Value.(*plan.Const_Sval) 939 tp := judgeUnixTimestampReturnType(sval.Sval) 940 if tp == types.T_int64 { 941 args = append(args, makePlan2Int64ConstExprWithType(0)) 942 } else { 943 args = append(args, makePlan2Decimal128ConstNullExpr()) 944 } 945 } else { 946 args = append(args, makePlan2Decimal128ConstNullExpr()) 947 } 948 } 949 } else if len(args) > 1 { 950 return nil, moerr.NewInvalidArg(ctx, name+" function have invalid input args size", len(args)) 951 } 952 case "ascii": 953 if len(args) != 1 { 954 return nil, moerr.NewInvalidArg(ctx, name+" function have invalid input args length", len(args)) 955 } 956 tp := types.T(args[0].Typ.Id) 957 switch { 958 case types.IsString(tp), types.IsInteger(tp): 959 default: 960 targetTp := types.T_varchar.ToType() 961 args[0], err = appendCastBeforeExpr(ctx, args[0], makePlan2Type(&targetTp), false) 962 if err != nil { 963 return nil, err 964 } 965 } 966 } 967 968 // get args(exprs) & types 969 argsLength := len(args) 970 argsType := make([]types.Type, argsLength) 971 for idx, expr := range args { 972 argsType[idx] = makeTypeByPlan2Expr(expr) 973 } 974 975 var funcID int64 976 var returnType types.Type 977 var argsCastType []types.Type 978 979 // get function definition 980 funcID, returnType, argsCastType, err = function.GetFunctionByName(ctx, name, argsType) 981 if err != nil { 982 return nil, err 983 } 984 if function.GetFunctionIsAggregateByName(name) { 985 if constExpr, ok := args[0].Expr.(*plan.Expr_C); ok && constExpr.C.Isnull { 986 args[0].Typ = makePlan2Type(&returnType) 987 } 988 } 989 990 // rewrite some cast rule: expr: int32Col > 10, 991 // old rule: cast(int32Col as int64) >10 , new rule: int32Col > (cast 10 as int32) 992 switch name { 993 case "=", "<", "<=", ">", ">=", "<>", "like": 994 // if constant's type higher than column's type 995 // and constant's value in range of column's type, then no cast was needed 996 switch leftExpr := args[0].Expr.(type) { 997 case *plan.Expr_C: 998 if _, ok := args[1].Expr.(*plan.Expr_Col); ok { 999 if checkNoNeedCast(argsType[0], argsType[1], leftExpr) { 1000 tmpType := argsType[1] // cast const_expr as column_expr's type 1001 argsCastType = []types.Type{tmpType, tmpType} 1002 // need to update function id 1003 funcID, _, _, err = function.GetFunctionByName(ctx, name, argsCastType) 1004 if err != nil { 1005 return nil, err 1006 } 1007 } 1008 } 1009 case *plan.Expr_Col: 1010 if rightExpr, ok := args[1].Expr.(*plan.Expr_C); ok { 1011 if checkNoNeedCast(argsType[1], argsType[0], rightExpr) { 1012 tmpType := argsType[0] // cast const_expr as column_expr's type 1013 argsCastType = []types.Type{tmpType, tmpType} 1014 funcID, _, _, err = function.GetFunctionByName(ctx, name, argsCastType) 1015 if err != nil { 1016 return nil, err 1017 } 1018 } 1019 } 1020 } 1021 1022 case "in", "not_in": 1023 //if all the expr in the in list can safely cast to left type, we call it safe 1024 var safe bool 1025 if rightList, ok := args[1].Expr.(*plan.Expr_List); ok { 1026 typLeft := makeTypeByPlan2Expr(args[0]) 1027 lenList := len(rightList.List.List) 1028 1029 for i := 0; i < lenList; i++ { 1030 if constExpr, ok := rightList.List.List[i].Expr.(*plan.Expr_C); ok { 1031 safe = checkNoNeedCast(makeTypeByPlan2Expr(rightList.List.List[i]), typLeft, constExpr) 1032 if !safe { 1033 break 1034 } 1035 } else { 1036 safe = false 1037 break 1038 } 1039 } 1040 1041 if safe { 1042 //if safe, try to cast the in list to left type 1043 for i := 0; i < lenList; i++ { 1044 rightList.List.List[i], err = appendCastBeforeExpr(ctx, rightList.List.List[i], args[0].Typ) 1045 if err != nil { 1046 return nil, err 1047 } 1048 } 1049 } else { 1050 //expand the in list to col=a or col=b or ...... 1051 if name == "in" { 1052 newExpr, _ := bindFuncExprImplByPlanExpr(ctx, "=", []*Expr{DeepCopyExpr(args[0]), DeepCopyExpr(rightList.List.List[0])}) 1053 for i := 1; i < lenList; i++ { 1054 tmpExpr, _ := bindFuncExprImplByPlanExpr(ctx, "=", []*Expr{DeepCopyExpr(args[0]), DeepCopyExpr(rightList.List.List[i])}) 1055 newExpr, _ = bindFuncExprImplByPlanExpr(ctx, "or", []*Expr{newExpr, tmpExpr}) 1056 } 1057 return newExpr, nil 1058 } else { 1059 //expand the not in list to col!=a and col!=b and ...... 1060 newExpr, _ := bindFuncExprImplByPlanExpr(ctx, "!=", []*Expr{DeepCopyExpr(args[0]), DeepCopyExpr(rightList.List.List[0])}) 1061 for i := 1; i < lenList; i++ { 1062 tmpExpr, _ := bindFuncExprImplByPlanExpr(ctx, "!=", []*Expr{DeepCopyExpr(args[0]), DeepCopyExpr(rightList.List.List[i])}) 1063 newExpr, _ = bindFuncExprImplByPlanExpr(ctx, "and", []*Expr{newExpr, tmpExpr}) 1064 } 1065 return newExpr, nil 1066 } 1067 } 1068 } 1069 1070 case "timediff": 1071 if len(argsType) == len(argsCastType) { 1072 for i := range argsType { 1073 if int(argsType[i].Oid) == int(types.T_time) && int(argsCastType[i].Oid) == int(types.T_datetime) { 1074 return nil, moerr.NewInvalidInput(ctx, name+" function have invalid input args type") 1075 } 1076 } 1077 } 1078 } 1079 1080 if len(argsCastType) != 0 { 1081 if len(argsCastType) != argsLength { 1082 return nil, moerr.NewInvalidArg(ctx, "cast types length not match args length", "") 1083 } 1084 for idx, castType := range argsCastType { 1085 if !argsType[idx].Eq(castType) && castType.Oid != types.T_any { 1086 typ := makePlan2Type(&castType) 1087 args[idx], err = appendCastBeforeExpr(ctx, args[idx], typ) 1088 if err != nil { 1089 return nil, err 1090 } 1091 } 1092 } 1093 } 1094 1095 if function.GetFunctionAppendHideArgByID(funcID) { 1096 // Append a hidden parameter to the function. The default value is constant null 1097 args = append(args, makePlan2NullConstExprWithType()) 1098 } 1099 1100 // return new expr 1101 Typ := makePlan2Type(&returnType) 1102 Typ.NotNullable = function.DeduceNotNullable(funcID, args) 1103 return &Expr{ 1104 Expr: &plan.Expr_F{ 1105 F: &plan.Function{ 1106 Func: getFunctionObjRef(funcID, name), 1107 Args: args, 1108 }, 1109 }, 1110 Typ: Typ, 1111 }, nil 1112 } 1113 1114 func (b *baseBinder) bindNumVal(astExpr *tree.NumVal, typ *Type) (*Expr, error) { 1115 // over_int64_err := moerr.NewInternalError(b.GetContext(), "", "Constants over int64 will support in future version.") 1116 // rewrite the hexnum process logic 1117 // for float64, if the number is over 1<<53-1,it will lost, so if typ is float64, 1118 // don't cast 0xXXXX as float64, use the uint64 1119 returnDecimalExpr := func(val string) (*Expr, error) { 1120 if typ != nil { 1121 return appendCastBeforeExpr(b.GetContext(), makePlan2StringConstExprWithType(val), typ) 1122 } 1123 return makePlan2DecimalExprWithType(b.GetContext(), val) 1124 } 1125 1126 returnHexNumExpr := func(val string, isBin ...bool) (*Expr, error) { 1127 if typ != nil { 1128 isFloat := typ.Id == int32(types.T_float32) || typ.Id == int32(types.T_float64) 1129 return appendCastBeforeExpr(b.GetContext(), makePlan2StringConstExprWithType(val, isBin[0]), typ, isBin[0], isFloat) 1130 } 1131 return makePlan2StringConstExprWithType(val, isBin...), nil 1132 } 1133 1134 switch astExpr.ValType { 1135 case tree.P_null: 1136 return makePlan2NullConstExprWithType(), nil 1137 case tree.P_bool: 1138 val := constant.BoolVal(astExpr.Value) 1139 return makePlan2BoolConstExprWithType(val), nil 1140 case tree.P_int64: 1141 val, ok := constant.Int64Val(astExpr.Value) 1142 if !ok { 1143 return nil, moerr.NewInvalidInput(b.GetContext(), "invalid int value '%s'", astExpr.Value.String()) 1144 } 1145 expr := makePlan2Int64ConstExprWithType(val) 1146 if typ != nil && typ.Id == int32(types.T_varchar) { 1147 return appendCastBeforeExpr(b.GetContext(), expr, typ) 1148 } 1149 return expr, nil 1150 case tree.P_uint64: 1151 val, ok := constant.Uint64Val(astExpr.Value) 1152 if !ok { 1153 return nil, moerr.NewInvalidInput(b.GetContext(), "invalid int value '%s'", astExpr.Value.String()) 1154 } 1155 return makePlan2Uint64ConstExprWithType(val), nil 1156 case tree.P_decimal: 1157 if typ != nil { 1158 if typ.Id == int32(types.T_decimal64) { 1159 d64, err := types.Decimal64_FromStringWithScale(astExpr.String(), typ.Width, typ.Scale) 1160 if err != nil { 1161 return nil, err 1162 } 1163 return &Expr{ 1164 Expr: &plan.Expr_C{ 1165 C: &Const{ 1166 Isnull: false, 1167 Value: &plan.Const_Decimal64Val{ 1168 Decimal64Val: &plan.Decimal64{A: types.Decimal64ToInt64Raw(d64)}, 1169 }, 1170 }, 1171 }, 1172 Typ: typ, 1173 }, nil 1174 } 1175 if typ.Id == int32(types.T_decimal128) { 1176 d128, err := types.Decimal128_FromStringWithScale(astExpr.String(), typ.Width, typ.Scale) 1177 if err != nil { 1178 return nil, err 1179 } 1180 a, b := types.Decimal128ToInt64Raw(d128) 1181 return &Expr{ 1182 Expr: &plan.Expr_C{ 1183 C: &Const{ 1184 Isnull: false, 1185 Value: &plan.Const_Decimal128Val{ 1186 Decimal128Val: &plan.Decimal128{A: a, B: b}, 1187 }, 1188 }, 1189 }, 1190 Typ: typ, 1191 }, nil 1192 } 1193 return appendCastBeforeExpr(b.GetContext(), makePlan2StringConstExprWithType(astExpr.String()), typ) 1194 } 1195 d128, scale, err := types.ParseStringToDecimal128WithoutTable(astExpr.String()) 1196 if err != nil { 1197 return nil, err 1198 } 1199 a, b := types.Decimal128ToInt64Raw(d128) 1200 return &Expr{ 1201 Expr: &plan.Expr_C{ 1202 C: &Const{ 1203 Isnull: false, 1204 Value: &plan.Const_Decimal128Val{ 1205 Decimal128Val: &plan.Decimal128{A: a, B: b}, 1206 }, 1207 }, 1208 }, 1209 Typ: &plan.Type{ 1210 Id: int32(types.T_decimal128), 1211 Width: 34, 1212 Scale: scale, 1213 Precision: 34, 1214 NotNullable: true, 1215 }, 1216 }, nil 1217 case tree.P_float64: 1218 originString := astExpr.String() 1219 if typ != nil && (typ.Id == int32(types.T_decimal64) || typ.Id == int32(types.T_decimal128)) { 1220 return returnDecimalExpr(originString) 1221 } 1222 if !strings.Contains(originString, "e") { 1223 expr, err := returnDecimalExpr(originString) 1224 if err == nil { 1225 return expr, nil 1226 } 1227 } 1228 floatValue, ok := constant.Float64Val(astExpr.Value) 1229 if !ok { 1230 return returnDecimalExpr(originString) 1231 } 1232 return makePlan2Float64ConstExprWithType(floatValue), nil 1233 case tree.P_hexnum: 1234 s := astExpr.String()[2:] 1235 if len(s)%2 != 0 { 1236 s = string('0') + s 1237 } 1238 bytes, _ := hex.DecodeString(s) 1239 return returnHexNumExpr(string(bytes), true) 1240 case tree.P_ScoreBinary: 1241 return returnHexNumExpr(astExpr.String(), true) 1242 case tree.P_bit: 1243 return returnDecimalExpr(astExpr.String()) 1244 case tree.P_char: 1245 expr := makePlan2StringConstExprWithType(astExpr.String()) 1246 return expr, nil 1247 case tree.P_nulltext: 1248 expr := MakePlan2NullTextConstExprWithType(astExpr.String()) 1249 return expr, nil 1250 default: 1251 return nil, moerr.NewInvalidInput(b.GetContext(), "unsupport value '%s'", astExpr.String()) 1252 } 1253 } 1254 1255 func (b *baseBinder) GetContext() context.Context { return b.sysCtx } 1256 1257 // --- util functions ---- 1258 1259 func appendCastBeforeExpr(ctx context.Context, expr *Expr, toType *Type, isBin ...bool) (*Expr, error) { 1260 if expr.Typ.Id == int32(types.T_any) { 1261 return expr, nil 1262 } 1263 toType.NotNullable = expr.Typ.NotNullable 1264 argsType := []types.Type{ 1265 makeTypeByPlan2Expr(expr), 1266 makeTypeByPlan2Type(toType), 1267 } 1268 funcID, _, _, err := function.GetFunctionByName(ctx, "cast", argsType) 1269 if err != nil { 1270 return nil, err 1271 } 1272 // for 0xXXXX, if the value is over 1<<53-1, when covert it into float64,it will lost, so just change it into uint64 1273 typ := *toType 1274 if len(isBin) == 2 && isBin[0] && isBin[1] { 1275 typ.Id = int32(types.T_uint64) 1276 } 1277 return &Expr{ 1278 Expr: &plan.Expr_F{ 1279 F: &plan.Function{ 1280 Func: getFunctionObjRef(funcID, "cast"), 1281 Args: []*Expr{expr, 1282 { 1283 Typ: &typ, 1284 Expr: &plan.Expr_T{ 1285 T: &plan.TargetType{ 1286 Typ: &typ, 1287 }, 1288 }, 1289 }}, 1290 }, 1291 }, 1292 Typ: &typ, 1293 }, nil 1294 } 1295 1296 func resetDateFunctionArgs(ctx context.Context, dateExpr *Expr, intervalExpr *Expr) ([]*Expr, error) { 1297 firstExpr := intervalExpr.Expr.(*plan.Expr_List).List.List[0] 1298 secondExpr := intervalExpr.Expr.(*plan.Expr_List).List.List[1] 1299 1300 intervalTypeStr := secondExpr.Expr.(*plan.Expr_C).C.Value.(*plan.Const_Sval).Sval 1301 intervalType, err := types.IntervalTypeOf(intervalTypeStr) 1302 if err != nil { 1303 return nil, err 1304 } 1305 1306 intervalTypeInFunction := &plan.Type{ 1307 Id: int32(types.T_int64), 1308 Size: 8, 1309 } 1310 1311 if firstExpr.Typ.Id == int32(types.T_varchar) || firstExpr.Typ.Id == int32(types.T_char) { 1312 s := firstExpr.Expr.(*plan.Expr_C).C.Value.(*plan.Const_Sval).Sval 1313 returnNum, returnType, err := types.NormalizeInterval(s, intervalType) 1314 1315 if err != nil { 1316 return nil, err 1317 } 1318 // "date '2020-10-10' - interval 1 Hour" will return datetime 1319 // so we rewrite "date '2020-10-10' - interval 1 Hour" to "date_add(datetime, 1, hour)" 1320 if dateExpr.Typ.Id == int32(types.T_date) { 1321 switch returnType { 1322 case types.Day, types.Week, types.Month, types.Quarter, types.Year: 1323 default: 1324 dateExpr, err = appendCastBeforeExpr(ctx, dateExpr, &plan.Type{ 1325 Id: int32(types.T_datetime), 1326 Size: 8, 1327 }) 1328 1329 if err != nil { 1330 return nil, err 1331 } 1332 } 1333 } 1334 return []*Expr{ 1335 dateExpr, 1336 makePlan2Int64ConstExprWithType(returnNum), 1337 makePlan2Int64ConstExprWithType(int64(returnType)), 1338 }, nil 1339 } 1340 1341 // "date '2020-10-10' - interval 1 Hour" will return datetime 1342 // so we rewrite "date '2020-10-10' - interval 1 Hour" to "date_add(datetime, 1, hour)" 1343 if dateExpr.Typ.Id == int32(types.T_date) { 1344 switch intervalType { 1345 case types.Day, types.Week, types.Month, types.Quarter, types.Year: 1346 default: 1347 dateExpr, err = appendCastBeforeExpr(ctx, dateExpr, &plan.Type{ 1348 Id: int32(types.T_datetime), 1349 Size: 8, 1350 }) 1351 1352 if err != nil { 1353 return nil, err 1354 } 1355 } 1356 } 1357 1358 numberExpr, err := appendCastBeforeExpr(ctx, firstExpr, intervalTypeInFunction) 1359 if err != nil { 1360 return nil, err 1361 } 1362 1363 return []*Expr{ 1364 dateExpr, 1365 numberExpr, 1366 makePlan2Int64ConstExprWithType(int64(intervalType)), 1367 }, nil 1368 } 1369 1370 func resetDateFunction(ctx context.Context, dateExpr *Expr, intervalExpr *Expr) ([]*Expr, error) { 1371 switch intervalExpr.Expr.(type) { 1372 case *plan.Expr_List: 1373 return resetDateFunctionArgs(ctx, dateExpr, intervalExpr) 1374 } 1375 list := &plan.ExprList{ 1376 List: make([]*Expr, 2), 1377 } 1378 list.List[0] = intervalExpr 1379 strType := &plan.Type{ 1380 Id: int32(types.T_char), 1381 Size: 4, 1382 } 1383 strExpr := &Expr{ 1384 Expr: &plan.Expr_C{ 1385 C: &Const{ 1386 Value: &plan.Const_Sval{ 1387 Sval: "day", 1388 }, 1389 }, 1390 }, 1391 Typ: strType, 1392 } 1393 list.List[1] = strExpr 1394 expr := &plan.Expr_List{ 1395 List: list, 1396 } 1397 listExpr := &Expr{ 1398 Expr: expr, 1399 } 1400 return resetDateFunctionArgs(ctx, dateExpr, listExpr) 1401 }