github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sem/tree/normalize.go (about) 1 // Copyright 2015 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package tree 12 13 import ( 14 "github.com/cockroachdb/cockroach/pkg/sql/types" 15 "github.com/cockroachdb/cockroach/pkg/util/json" 16 "github.com/cockroachdb/errors" 17 ) 18 19 type normalizableExpr interface { 20 Expr 21 normalize(*NormalizeVisitor) TypedExpr 22 } 23 24 func (expr *CastExpr) normalize(v *NormalizeVisitor) TypedExpr { 25 return expr 26 } 27 28 func (expr *CoalesceExpr) normalize(v *NormalizeVisitor) TypedExpr { 29 // This normalization checks whether COALESCE can be simplified 30 // based on constant expressions at the start of the COALESCE 31 // argument list. All known-null constant arguments are simply 32 // removed, and any known-nonnull constant argument before 33 // non-constant argument cause the entire COALESCE expression to 34 // collapse to that argument. 35 last := len(expr.Exprs) - 1 36 for i := range expr.Exprs { 37 subExpr := expr.TypedExprAt(i) 38 39 if i == last { 40 return subExpr 41 } 42 43 if !v.isConst(subExpr) { 44 exprCopy := *expr 45 exprCopy.Exprs = expr.Exprs[i:] 46 return &exprCopy 47 } 48 49 val, err := subExpr.Eval(v.ctx) 50 if err != nil { 51 v.err = err 52 return expr 53 } 54 55 if val != DNull { 56 return subExpr 57 } 58 } 59 return expr 60 } 61 62 func (expr *IfExpr) normalize(v *NormalizeVisitor) TypedExpr { 63 if v.isConst(expr.Cond) { 64 cond, err := expr.TypedCondExpr().Eval(v.ctx) 65 if err != nil { 66 v.err = err 67 return expr 68 } 69 if d, err := GetBool(cond); err == nil { 70 if d { 71 return expr.TypedTrueExpr() 72 } 73 return expr.TypedElseExpr() 74 } 75 return DNull 76 } 77 return expr 78 } 79 80 func (expr *UnaryExpr) normalize(v *NormalizeVisitor) TypedExpr { 81 val := expr.TypedInnerExpr() 82 83 if val == DNull { 84 return val 85 } 86 87 switch expr.Operator { 88 case UnaryMinus: 89 // -0 -> 0 (except for float which has negative zero) 90 if val.ResolvedType().Family() != types.FloatFamily && v.isNumericZero(val) { 91 return val 92 } 93 switch b := val.(type) { 94 // -(a - b) -> (b - a) 95 case *BinaryExpr: 96 if b.Operator == Minus { 97 newBinExpr := newBinExprIfValidOverload(Minus, 98 b.TypedRight(), b.TypedLeft()) 99 if newBinExpr != nil { 100 newBinExpr.memoizeFn() 101 b = newBinExpr 102 } 103 return b 104 } 105 // - (- a) -> a 106 case *UnaryExpr: 107 if b.Operator == UnaryMinus { 108 return b.TypedInnerExpr() 109 } 110 } 111 } 112 113 return expr 114 } 115 116 func (expr *BinaryExpr) normalize(v *NormalizeVisitor) TypedExpr { 117 left := expr.TypedLeft() 118 right := expr.TypedRight() 119 expectedType := expr.ResolvedType() 120 121 if !expr.Fn.NullableArgs && (left == DNull || right == DNull) { 122 return DNull 123 } 124 125 var final TypedExpr 126 127 switch expr.Operator { 128 case Plus: 129 if v.isNumericZero(right) { 130 final = ReType(left, expectedType) 131 break 132 } 133 if v.isNumericZero(left) { 134 final = ReType(right, expectedType) 135 break 136 } 137 case Minus: 138 if types.IsAdditiveType(left.ResolvedType()) && v.isNumericZero(right) { 139 final = ReType(left, expectedType) 140 break 141 } 142 case Mult: 143 if v.isNumericOne(right) { 144 final = ReType(left, expectedType) 145 break 146 } 147 if v.isNumericOne(left) { 148 final = ReType(right, expectedType) 149 break 150 } 151 // We can't simplify multiplication by zero to zero, 152 // because if the other operand is NULL during evaluation 153 // the result must be NULL. 154 case Div, FloorDiv: 155 if v.isNumericOne(right) { 156 final = ReType(left, expectedType) 157 break 158 } 159 } 160 161 if final == nil { 162 return expr 163 } 164 return final 165 } 166 167 func (expr *AndExpr) normalize(v *NormalizeVisitor) TypedExpr { 168 left := expr.TypedLeft() 169 right := expr.TypedRight() 170 var dleft, dright Datum 171 172 if left == DNull && right == DNull { 173 return DNull 174 } 175 176 // Use short-circuit evaluation to simplify AND expressions. 177 if v.isConst(left) { 178 dleft, v.err = left.Eval(v.ctx) 179 if v.err != nil { 180 return expr 181 } 182 if dleft != DNull { 183 if d, err := GetBool(dleft); err == nil { 184 if !d { 185 return dleft 186 } 187 return right 188 } 189 return DNull 190 } 191 return NewTypedAndExpr( 192 dleft, 193 right, 194 ) 195 } 196 if v.isConst(right) { 197 dright, v.err = right.Eval(v.ctx) 198 if v.err != nil { 199 return expr 200 } 201 if dright != DNull { 202 if d, err := GetBool(dright); err == nil { 203 if !d { 204 return right 205 } 206 return left 207 } 208 return DNull 209 } 210 return NewTypedAndExpr( 211 left, 212 dright, 213 ) 214 } 215 return expr 216 } 217 218 func (expr *ComparisonExpr) normalize(v *NormalizeVisitor) TypedExpr { 219 switch expr.Operator { 220 case EQ, GE, GT, LE, LT: 221 // We want var nodes (VariableExpr, VarName, etc) to be immediate 222 // children of the comparison expression and not second or third 223 // children. That is, we want trees that look like: 224 // 225 // cmp cmp 226 // / \ / \ 227 // a op op a 228 // / \ / \ 229 // 1 2 1 2 230 // 231 // Not trees that look like: 232 // 233 // cmp cmp cmp cmp 234 // / \ / \ / \ / \ 235 // op 2 op 2 1 op 1 op 236 // / \ / \ / \ / \ 237 // a 1 1 a a 2 2 a 238 // 239 // We loop attempting to simplify the comparison expression. As a 240 // pre-condition, we know there is at least one variable in the expression 241 // tree or we would not have entered this code path. 242 exprCopied := false 243 for { 244 if expr.TypedLeft() == DNull || expr.TypedRight() == DNull { 245 return DNull 246 } 247 248 if v.isConst(expr.Left) { 249 switch expr.Right.(type) { 250 case *BinaryExpr, VariableExpr: 251 break 252 default: 253 return expr 254 } 255 256 invertedOp, err := invertComparisonOp(expr.Operator) 257 if err != nil { 258 v.err = err 259 return expr 260 } 261 262 // The left side is const and the right side is a binary expression or a 263 // variable. Flip the comparison op so that the right side is const and 264 // the left side is a binary expression or variable. 265 // Create a new ComparisonExpr so the function cache isn't reused. 266 if !exprCopied { 267 exprCopy := *expr 268 expr = &exprCopy 269 exprCopied = true 270 } 271 272 expr = NewTypedComparisonExpr(invertedOp, expr.TypedRight(), expr.TypedLeft()) 273 } else if !v.isConst(expr.Right) { 274 return expr 275 } 276 277 left, ok := expr.Left.(*BinaryExpr) 278 if !ok { 279 return expr 280 } 281 // The right is const and the left side is a binary expression. Rotate the 282 // comparison combining portions that are const. 283 284 switch { 285 case v.isConst(left.Right) && 286 (left.Operator == Plus || left.Operator == Minus || left.Operator == Div): 287 288 // cmp cmp 289 // / \ / \ 290 // [+-/] 2 -> a [-+*] 291 // / \ / \ 292 // a 1 2 1 293 var op BinaryOperator 294 switch left.Operator { 295 case Plus: 296 op = Minus 297 case Minus: 298 op = Plus 299 case Div: 300 op = Mult 301 if expr.Operator != EQ { 302 // In this case, we must remember to *flip* the inequality if the 303 // divisor is negative, since we are in effect multiplying both sides 304 // of the inequality by a negative number. 305 divisor, err := left.TypedRight().Eval(v.ctx) 306 if err != nil { 307 v.err = err 308 return expr 309 } 310 if divisor.Compare(v.ctx, DZero) < 0 { 311 if !exprCopied { 312 exprCopy := *expr 313 expr = &exprCopy 314 exprCopied = true 315 } 316 317 invertedOp, err := invertComparisonOp(expr.Operator) 318 if err != nil { 319 v.err = err 320 return expr 321 } 322 expr = NewTypedComparisonExpr(invertedOp, expr.TypedLeft(), expr.TypedRight()) 323 } 324 } 325 } 326 327 newBinExpr := newBinExprIfValidOverload(op, 328 expr.TypedRight(), left.TypedRight()) 329 if newBinExpr == nil { 330 // Substitution is not possible type-wise. Nothing else to do. 331 break 332 } 333 334 newRightExpr, err := newBinExpr.Eval(v.ctx) 335 if err != nil { 336 // In the case of an error during Eval, give up on normalizing this 337 // expression. There are some expected errors here if, for example, 338 // normalization produces a result that overflows an int64. 339 break 340 } 341 342 if !exprCopied { 343 exprCopy := *expr 344 expr = &exprCopy 345 exprCopied = true 346 } 347 348 expr.Left = left.Left 349 expr.Right = newRightExpr 350 expr.memoizeFn() 351 if !isVar(v.ctx, expr.Left, true /*allowConstPlaceholders*/) { 352 // Continue as long as the left side of the comparison is not a 353 // variable. 354 continue 355 } 356 357 case v.isConst(left.Left) && (left.Operator == Plus || left.Operator == Minus): 358 // cmp cmp 359 // / \ / \ 360 // [+-] 2 -> [+-] a 361 // / \ / \ 362 // 1 a 1 2 363 364 op := expr.Operator 365 var newBinExpr *BinaryExpr 366 367 switch left.Operator { 368 case Plus: 369 // 370 // (A + X) cmp B => X cmp (B - C) 371 // 372 newBinExpr = newBinExprIfValidOverload(Minus, 373 expr.TypedRight(), left.TypedLeft()) 374 case Minus: 375 // 376 // (A - X) cmp B => X cmp' (A - B) 377 // 378 newBinExpr = newBinExprIfValidOverload(Minus, 379 left.TypedLeft(), expr.TypedRight()) 380 op, v.err = invertComparisonOp(op) 381 if v.err != nil { 382 return expr 383 } 384 } 385 386 if newBinExpr == nil { 387 break 388 } 389 390 newRightExpr, err := newBinExpr.Eval(v.ctx) 391 if err != nil { 392 break 393 } 394 395 if !exprCopied { 396 exprCopy := *expr 397 expr = &exprCopy 398 exprCopied = true 399 } 400 401 expr.Operator = op 402 expr.Left = left.Right 403 expr.Right = newRightExpr 404 expr.memoizeFn() 405 if !isVar(v.ctx, expr.Left, true /*allowConstPlaceholders*/) { 406 // Continue as long as the left side of the comparison is not a 407 // variable. 408 continue 409 } 410 411 case expr.Operator == EQ && left.Operator == JSONFetchVal && v.isConst(left.Right) && 412 v.isConst(expr.Right): 413 // This is a JSONB inverted index normalization, changing things of the form 414 // x->y=z to x @> {y:z} which can be used to build spans for inverted index 415 // lookups. 416 417 if left.TypedRight().ResolvedType().Family() != types.StringFamily { 418 break 419 } 420 421 str, err := left.TypedRight().Eval(v.ctx) 422 if err != nil { 423 break 424 } 425 // Check that we still have a string after evaluation. 426 if _, ok := str.(*DString); !ok { 427 break 428 } 429 430 rhs, err := expr.TypedRight().Eval(v.ctx) 431 if err != nil { 432 break 433 } 434 435 rjson := rhs.(*DJSON).JSON 436 t := rjson.Type() 437 if t == json.ObjectJSONType || t == json.ArrayJSONType { 438 // We can't make this transformation in cases like 439 // 440 // a->'b' = '["c"]', 441 // 442 // because containment is not equivalent to equality for non-scalar types. 443 break 444 } 445 446 j := json.NewObjectBuilder(1) 447 j.Add(string(*str.(*DString)), rjson) 448 449 dj, err := MakeDJSON(j.Build()) 450 if err != nil { 451 break 452 } 453 454 typedJ, err := dj.TypeCheck(v.ctx.Context, nil, types.Jsonb) 455 if err != nil { 456 break 457 } 458 459 return NewTypedComparisonExpr(Contains, left.TypedLeft(), typedJ) 460 } 461 462 // We've run out of work to do. 463 break 464 } 465 case In, NotIn: 466 // If the right tuple in an In or NotIn comparison expression is constant, it can 467 // be normalized. 468 tuple, ok := expr.Right.(*DTuple) 469 if ok { 470 tupleCopy := *tuple 471 tupleCopy.Normalize(v.ctx) 472 473 // If the tuple only contains NULL values, Normalize will have reduced 474 // it to a single NULL value. 475 if len(tupleCopy.D) == 1 && tupleCopy.D[0] == DNull { 476 return DNull 477 } 478 if len(tupleCopy.D) == 0 { 479 // NULL IN <empty-tuple> is false. 480 if expr.Operator == In { 481 return DBoolFalse 482 } 483 return DBoolTrue 484 } 485 if expr.TypedLeft() == DNull { 486 // NULL IN <non-empty-tuple> is NULL. 487 return DNull 488 } 489 490 exprCopy := *expr 491 expr = &exprCopy 492 expr.Right = &tupleCopy 493 } 494 case IsDistinctFrom, IsNotDistinctFrom: 495 left := expr.TypedLeft() 496 right := expr.TypedRight() 497 498 if v.isConst(left) && !v.isConst(right) { 499 // Switch operand order so that constant expression is on the right. 500 // This helps support index selection rules. 501 return NewTypedComparisonExpr(expr.Operator, right, left) 502 } 503 case NE, 504 Like, NotLike, 505 ILike, NotILike, 506 SimilarTo, NotSimilarTo, 507 RegMatch, NotRegMatch, 508 RegIMatch, NotRegIMatch, 509 Any, Some, All: 510 if expr.TypedLeft() == DNull || expr.TypedRight() == DNull { 511 return DNull 512 } 513 } 514 515 return expr 516 } 517 518 func (expr *OrExpr) normalize(v *NormalizeVisitor) TypedExpr { 519 left := expr.TypedLeft() 520 right := expr.TypedRight() 521 var dleft, dright Datum 522 523 if left == DNull && right == DNull { 524 return DNull 525 } 526 527 // Use short-circuit evaluation to simplify OR expressions. 528 if v.isConst(left) { 529 dleft, v.err = left.Eval(v.ctx) 530 if v.err != nil { 531 return expr 532 } 533 if dleft != DNull { 534 if d, err := GetBool(dleft); err == nil { 535 if d { 536 return dleft 537 } 538 return right 539 } 540 return DNull 541 } 542 return NewTypedOrExpr( 543 dleft, 544 right, 545 ) 546 } 547 if v.isConst(right) { 548 dright, v.err = right.Eval(v.ctx) 549 if v.err != nil { 550 return expr 551 } 552 if dright != DNull { 553 if d, err := GetBool(dright); err == nil { 554 if d { 555 return right 556 } 557 return left 558 } 559 return DNull 560 } 561 return NewTypedOrExpr( 562 left, 563 dright, 564 ) 565 } 566 return expr 567 } 568 569 func (expr *NotExpr) normalize(v *NormalizeVisitor) TypedExpr { 570 inner := expr.TypedInnerExpr() 571 switch t := inner.(type) { 572 case *NotExpr: 573 return t.TypedInnerExpr() 574 } 575 return expr 576 } 577 578 func (expr *ParenExpr) normalize(v *NormalizeVisitor) TypedExpr { 579 return expr.TypedInnerExpr() 580 } 581 582 func (expr *AnnotateTypeExpr) normalize(v *NormalizeVisitor) TypedExpr { 583 // Type annotations have no runtime effect, so they can be removed after 584 // semantic analysis. 585 return expr.TypedInnerExpr() 586 } 587 588 func (expr *RangeCond) normalize(v *NormalizeVisitor) TypedExpr { 589 leftFrom, from := expr.TypedLeftFrom(), expr.TypedFrom() 590 leftTo, to := expr.TypedLeftTo(), expr.TypedTo() 591 // The visitor hasn't walked down into leftTo; do it now. 592 if leftTo, v.err = v.ctx.NormalizeExpr(leftTo); v.err != nil { 593 return expr 594 } 595 596 if (leftFrom == DNull || from == DNull) && (leftTo == DNull || to == DNull) { 597 return DNull 598 } 599 600 leftCmp := GE 601 rightCmp := LE 602 if expr.Not { 603 leftCmp = LT 604 rightCmp = GT 605 } 606 607 // "a BETWEEN b AND c" -> "a >= b AND a <= c" 608 // "a NOT BETWEEN b AND c" -> "a < b OR a > c" 609 transform := func(from, to TypedExpr) TypedExpr { 610 var newLeft, newRight TypedExpr 611 if from == DNull { 612 newLeft = DNull 613 } else { 614 newLeft = NewTypedComparisonExpr(leftCmp, leftFrom, from).normalize(v) 615 if v.err != nil { 616 return expr 617 } 618 } 619 if to == DNull { 620 newRight = DNull 621 } else { 622 newRight = NewTypedComparisonExpr(rightCmp, leftTo, to).normalize(v) 623 if v.err != nil { 624 return expr 625 } 626 } 627 if expr.Not { 628 return NewTypedOrExpr(newLeft, newRight).normalize(v) 629 } 630 return NewTypedAndExpr(newLeft, newRight).normalize(v) 631 } 632 633 out := transform(from, to) 634 if expr.Symmetric { 635 if expr.Not { 636 // "a NOT BETWEEN SYMMETRIC b AND c" -> "(a < b OR a > c) AND (a < c OR a > b)" 637 out = NewTypedAndExpr(out, transform(to, from)).normalize(v) 638 } else { 639 // "a BETWEEN SYMMETRIC b AND c" -> "(a >= b AND a <= c) OR (a >= c OR a <= b)" 640 out = NewTypedOrExpr(out, transform(to, from)).normalize(v) 641 } 642 } 643 return out 644 } 645 646 func (expr *Tuple) normalize(v *NormalizeVisitor) TypedExpr { 647 // A Tuple should be directly evaluated into a DTuple if it's either fully 648 // constant or contains only constants and top-level Placeholders. 649 isConst := true 650 for _, subExpr := range expr.Exprs { 651 if !v.isConst(subExpr) { 652 isConst = false 653 break 654 } 655 } 656 if !isConst { 657 return expr 658 } 659 e, err := expr.Eval(v.ctx) 660 if err != nil { 661 v.err = err 662 } 663 return e 664 } 665 666 // NormalizeExpr normalizes a typed expression, simplifying where possible, 667 // but guaranteeing that the result of evaluating the expression is 668 // unchanged and that resulting expression tree is still well-typed. 669 // Example normalizations: 670 // 671 // (a) -> a 672 // a = 1 + 1 -> a = 2 673 // a + 1 = 2 -> a = 1 674 // a BETWEEN b AND c -> (a >= b) AND (a <= c) 675 // a NOT BETWEEN b AND c -> (a < b) OR (a > c) 676 func (ctx *EvalContext) NormalizeExpr(typedExpr TypedExpr) (TypedExpr, error) { 677 v := MakeNormalizeVisitor(ctx) 678 expr, _ := WalkExpr(&v, typedExpr) 679 if v.err != nil { 680 return nil, v.err 681 } 682 return expr.(TypedExpr), nil 683 } 684 685 // NormalizeVisitor supports the execution of NormalizeExpr. 686 type NormalizeVisitor struct { 687 ctx *EvalContext 688 err error 689 690 fastIsConstVisitor fastIsConstVisitor 691 } 692 693 var _ Visitor = &NormalizeVisitor{} 694 695 // MakeNormalizeVisitor creates a NormalizeVisitor instance. 696 func MakeNormalizeVisitor(ctx *EvalContext) NormalizeVisitor { 697 return NormalizeVisitor{ctx: ctx, fastIsConstVisitor: fastIsConstVisitor{ctx: ctx}} 698 } 699 700 // Err retrieves the error field in the NormalizeVisitor. 701 func (v *NormalizeVisitor) Err() error { return v.err } 702 703 // VisitPre implements the Visitor interface. 704 func (v *NormalizeVisitor) VisitPre(expr Expr) (recurse bool, newExpr Expr) { 705 if v.err != nil { 706 return false, expr 707 } 708 709 switch expr.(type) { 710 case *Subquery: 711 // Subqueries are pre-normalized during semantic analysis. There 712 // is nothing to do here. 713 return false, expr 714 } 715 716 return true, expr 717 } 718 719 // VisitPost implements the Visitor interface. 720 func (v *NormalizeVisitor) VisitPost(expr Expr) Expr { 721 if v.err != nil { 722 return expr 723 } 724 // We don't propagate errors during this step because errors might involve a 725 // branch of code that isn't traversed by normal execution (for example, 726 // IF(2 = 2, 1, 1 / 0)). 727 728 // Normalize expressions that know how to normalize themselves. 729 if normalizable, ok := expr.(normalizableExpr); ok { 730 expr = normalizable.normalize(v) 731 if v.err != nil { 732 return expr 733 } 734 } 735 736 // Evaluate all constant expressions. 737 if v.isConst(expr) { 738 value, err := expr.(TypedExpr).Eval(v.ctx) 739 if err != nil { 740 // Ignore any errors here (e.g. division by zero), so they can happen 741 // during execution where they are correctly handled. Note that in some 742 // cases we might not even get an error (if this particular expression 743 // does not get evaluated when the query runs, e.g. it's inside a CASE). 744 return expr 745 } 746 if value == DNull { 747 // We don't want to return an expression that has a different type; cast 748 // the NULL if necessary. 749 return ReType(DNull, expr.(TypedExpr).ResolvedType()) 750 } 751 return value 752 } 753 754 return expr 755 } 756 757 func (v *NormalizeVisitor) isConst(expr Expr) bool { 758 return v.fastIsConstVisitor.run(expr) 759 } 760 761 // isNumericZero returns true if the datum is a number and equal to 762 // zero. 763 func (v *NormalizeVisitor) isNumericZero(expr TypedExpr) bool { 764 if d, ok := expr.(Datum); ok { 765 switch t := UnwrapDatum(v.ctx, d).(type) { 766 case *DDecimal: 767 return t.Decimal.Sign() == 0 768 case *DFloat: 769 return *t == 0 770 case *DInt: 771 return *t == 0 772 } 773 } 774 return false 775 } 776 777 // isNumericOne returns true if the datum is a number and equal to 778 // one. 779 func (v *NormalizeVisitor) isNumericOne(expr TypedExpr) bool { 780 if d, ok := expr.(Datum); ok { 781 switch t := UnwrapDatum(v.ctx, d).(type) { 782 case *DDecimal: 783 return t.Decimal.Cmp(&DecimalOne.Decimal) == 0 784 case *DFloat: 785 return *t == 1.0 786 case *DInt: 787 return *t == 1 788 } 789 } 790 return false 791 } 792 793 func invertComparisonOp(op ComparisonOperator) (ComparisonOperator, error) { 794 switch op { 795 case EQ: 796 return EQ, nil 797 case GE: 798 return LE, nil 799 case GT: 800 return LT, nil 801 case LE: 802 return GE, nil 803 case LT: 804 return GT, nil 805 default: 806 return op, errors.AssertionFailedf("unable to invert: %s", op) 807 } 808 } 809 810 type isConstVisitor struct { 811 ctx *EvalContext 812 isConst bool 813 } 814 815 var _ Visitor = &isConstVisitor{} 816 817 func (v *isConstVisitor) VisitPre(expr Expr) (recurse bool, newExpr Expr) { 818 if v.isConst { 819 if isVar(v.ctx, expr, true /*allowConstPlaceholders*/) { 820 v.isConst = false 821 return false, expr 822 } 823 824 switch t := expr.(type) { 825 case *FuncExpr: 826 if t.IsImpure() { 827 v.isConst = false 828 return false, expr 829 } 830 } 831 } 832 return true, expr 833 } 834 835 func (*isConstVisitor) VisitPost(expr Expr) Expr { return expr } 836 837 func (v *isConstVisitor) run(expr Expr) bool { 838 v.isConst = true 839 WalkExprConst(v, expr) 840 return v.isConst 841 } 842 843 // IsConst returns whether the expression is constant. A constant expression 844 // does not contain variables, as defined by ContainsVars, nor impure functions. 845 func IsConst(evalCtx *EvalContext, expr Expr) bool { 846 v := isConstVisitor{ctx: evalCtx} 847 return v.run(expr) 848 } 849 850 // fastIsConstVisitor is similar to isConstVisitor, but it only visits 851 // at most two levels of the tree (with one exception, see below). 852 // In essence, it determines whether an expression is constant by checking 853 // whether its children are const Datums. 854 // 855 // This can be used during normalization since constants are evaluated 856 // bottom-up. If a child is *not* a const Datum, that means it was already 857 // determined to be non-constant, and therefore was not evaluated. 858 type fastIsConstVisitor struct { 859 ctx *EvalContext 860 isConst bool 861 862 // visited indicates whether we have already visited one level of the tree. 863 // fastIsConstVisitor only visits at most two levels of the tree, with one 864 // exception: If the second level has a Cast expression, fastIsConstVisitor 865 // may visit three levels. 866 visited bool 867 } 868 869 var _ Visitor = &fastIsConstVisitor{} 870 871 func (v *fastIsConstVisitor) VisitPre(expr Expr) (recurse bool, newExpr Expr) { 872 if v.visited { 873 if _, ok := expr.(*CastExpr); ok { 874 // We recurse one more time for cast expressions, since the 875 // NormalizeVisitor may have wrapped a NULL. 876 return true, expr 877 } 878 if _, ok := expr.(Datum); !ok || isVar(v.ctx, expr, true /*allowConstPlaceholders*/) { 879 // If the child expression is not a const Datum, the parent expression is 880 // not constant. Note that all constant literals have already been 881 // normalized to Datum in TypeCheck. 882 v.isConst = false 883 } 884 return false, expr 885 } 886 v.visited = true 887 888 // If the parent expression is a variable or impure function, we know that it 889 // is not constant. 890 891 if isVar(v.ctx, expr, true /*allowConstPlaceholders*/) { 892 v.isConst = false 893 return false, expr 894 } 895 896 switch t := expr.(type) { 897 case *FuncExpr: 898 if t.IsImpure() { 899 v.isConst = false 900 return false, expr 901 } 902 } 903 904 return true, expr 905 } 906 907 func (*fastIsConstVisitor) VisitPost(expr Expr) Expr { return expr } 908 909 func (v *fastIsConstVisitor) run(expr Expr) bool { 910 v.isConst = true 911 v.visited = false 912 WalkExprConst(v, expr) 913 return v.isConst 914 } 915 916 // isVar returns true if the expression's value can vary during plan 917 // execution. The parameter allowConstPlaceholders should be true 918 // in the common case of scalar expressions that will be evaluated 919 // in the context of the execution of a prepared query, where the 920 // placeholder will have the same value for every row processed. 921 // It is set to false for scalar expressions that are not 922 // evaluated as part of query execution, eg. DEFAULT expressions. 923 func isVar(evalCtx *EvalContext, expr Expr, allowConstPlaceholders bool) bool { 924 switch expr.(type) { 925 case VariableExpr: 926 return true 927 case *Placeholder: 928 if allowConstPlaceholders { 929 if evalCtx == nil || !evalCtx.HasPlaceholders() { 930 // The placeholder cannot be resolved -- it is variable. 931 return true 932 } 933 return evalCtx.Placeholders.IsUnresolvedPlaceholder(expr) 934 } 935 // Placeholders considered always variable. 936 return true 937 } 938 return false 939 } 940 941 type containsVarsVisitor struct { 942 containsVars bool 943 } 944 945 var _ Visitor = &containsVarsVisitor{} 946 947 func (v *containsVarsVisitor) VisitPre(expr Expr) (recurse bool, newExpr Expr) { 948 if !v.containsVars && isVar(nil, expr, false /*allowConstPlaceholders*/) { 949 v.containsVars = true 950 } 951 if v.containsVars { 952 return false, expr 953 } 954 return true, expr 955 } 956 957 func (*containsVarsVisitor) VisitPost(expr Expr) Expr { return expr } 958 959 // ContainsVars returns true if the expression contains any variables. 960 // (variables = sub-expressions, placeholders, indexed vars, etc.) 961 func ContainsVars(expr Expr) bool { 962 v := containsVarsVisitor{containsVars: false} 963 WalkExprConst(&v, expr) 964 return v.containsVars 965 } 966 967 // DecimalOne represents the constant 1 as DECIMAL. 968 var DecimalOne DDecimal 969 970 func init() { 971 DecimalOne.SetFinite(1, 0) 972 } 973 974 // ReType ensures that the given numeric expression evaluates 975 // to the requested type, inserting a cast if necessary. 976 func ReType(expr TypedExpr, wantedType *types.T) TypedExpr { 977 if expr.ResolvedType().Equivalent(wantedType) { 978 return expr 979 } 980 res := &CastExpr{Expr: expr, Type: wantedType} 981 res.typ = wantedType 982 return res 983 }