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  }