github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sem/tree/eval.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  	"context"
    15  	"fmt"
    16  	"math"
    17  	"math/big"
    18  	"regexp"
    19  	"strings"
    20  	"time"
    21  	"unicode/utf8"
    22  
    23  	"github.com/cockroachdb/apd"
    24  	"github.com/cockroachdb/cockroach/pkg/base"
    25  	"github.com/cockroachdb/cockroach/pkg/keys"
    26  	"github.com/cockroachdb/cockroach/pkg/kv"
    27  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    28  	"github.com/cockroachdb/cockroach/pkg/server/telemetry"
    29  	"github.com/cockroachdb/cockroach/pkg/settings/cluster"
    30  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
    31  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    32  	"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
    33  	"github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry"
    34  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    35  	"github.com/cockroachdb/cockroach/pkg/util/arith"
    36  	"github.com/cockroachdb/cockroach/pkg/util/bitarray"
    37  	"github.com/cockroachdb/cockroach/pkg/util/duration"
    38  	"github.com/cockroachdb/cockroach/pkg/util/hlc"
    39  	"github.com/cockroachdb/cockroach/pkg/util/json"
    40  	"github.com/cockroachdb/cockroach/pkg/util/mon"
    41  	"github.com/cockroachdb/cockroach/pkg/util/timeofday"
    42  	"github.com/cockroachdb/cockroach/pkg/util/timeutil"
    43  	"github.com/cockroachdb/cockroach/pkg/util/uuid"
    44  	"github.com/cockroachdb/errors"
    45  	"github.com/lib/pq/oid"
    46  )
    47  
    48  var (
    49  	// ErrIntOutOfRange is reported when integer arithmetic overflows.
    50  	ErrIntOutOfRange = pgerror.New(pgcode.NumericValueOutOfRange, "integer out of range")
    51  	// ErrFloatOutOfRange is reported when float arithmetic overflows.
    52  	ErrFloatOutOfRange = pgerror.New(pgcode.NumericValueOutOfRange, "float out of range")
    53  	errDecOutOfRange   = pgerror.New(pgcode.NumericValueOutOfRange, "decimal out of range")
    54  
    55  	// ErrDivByZero is reported on a division by zero.
    56  	ErrDivByZero       = pgerror.New(pgcode.DivisionByZero, "division by zero")
    57  	errSqrtOfNegNumber = pgerror.New(pgcode.InvalidArgumentForPowerFunction, "cannot take square root of a negative number")
    58  	// ErrZeroModulus is reported when computing the rest of a division by zero.
    59  	ErrZeroModulus = pgerror.New(pgcode.DivisionByZero, "zero modulus")
    60  
    61  	big10E6  = big.NewInt(1e6)
    62  	big10E10 = big.NewInt(1e10)
    63  )
    64  
    65  // NewCannotMixBitArraySizesError creates an error for the case when a bitwise
    66  // aggregate function is called on bit arrays with different sizes.
    67  func NewCannotMixBitArraySizesError(op string) error {
    68  	return pgerror.Newf(pgcode.StringDataLengthMismatch,
    69  		"cannot %s bit strings of different sizes", op)
    70  }
    71  
    72  // UnaryOp is a unary operator.
    73  type UnaryOp struct {
    74  	Typ        *types.T
    75  	ReturnType *types.T
    76  	Fn         func(*EvalContext, Datum) (Datum, error)
    77  	Volatility Volatility
    78  
    79  	types   TypeList
    80  	retType ReturnTyper
    81  
    82  	// counter, if non-nil, should be incremented every time the
    83  	// operator is type checked.
    84  	counter telemetry.Counter
    85  }
    86  
    87  func (op *UnaryOp) params() TypeList {
    88  	return op.types
    89  }
    90  
    91  func (op *UnaryOp) returnType() ReturnTyper {
    92  	return op.retType
    93  }
    94  
    95  func (*UnaryOp) preferred() bool {
    96  	return false
    97  }
    98  
    99  func unaryOpFixups(ops map[UnaryOperator]unaryOpOverload) map[UnaryOperator]unaryOpOverload {
   100  	for op, overload := range ops {
   101  		for i, impl := range overload {
   102  			casted := impl.(*UnaryOp)
   103  			casted.types = ArgTypes{{"arg", casted.Typ}}
   104  			casted.retType = FixedReturnType(casted.ReturnType)
   105  			ops[op][i] = casted
   106  		}
   107  	}
   108  	return ops
   109  }
   110  
   111  // unaryOpOverload is an overloaded set of unary operator implementations.
   112  type unaryOpOverload []overloadImpl
   113  
   114  // UnaryOps contains the unary operations indexed by operation type.
   115  var UnaryOps = unaryOpFixups(map[UnaryOperator]unaryOpOverload{
   116  	UnaryMinus: {
   117  		&UnaryOp{
   118  			Typ:        types.Int,
   119  			ReturnType: types.Int,
   120  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   121  				i := MustBeDInt(d)
   122  				if i == math.MinInt64 {
   123  					return nil, ErrIntOutOfRange
   124  				}
   125  				return NewDInt(-i), nil
   126  			},
   127  			Volatility: VolatilityImmutable,
   128  		},
   129  		&UnaryOp{
   130  			Typ:        types.Float,
   131  			ReturnType: types.Float,
   132  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   133  				return NewDFloat(-*d.(*DFloat)), nil
   134  			},
   135  			Volatility: VolatilityImmutable,
   136  		},
   137  		&UnaryOp{
   138  			Typ:        types.Decimal,
   139  			ReturnType: types.Decimal,
   140  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   141  				dec := &d.(*DDecimal).Decimal
   142  				dd := &DDecimal{}
   143  				dd.Decimal.Neg(dec)
   144  				return dd, nil
   145  			},
   146  			Volatility: VolatilityImmutable,
   147  		},
   148  		&UnaryOp{
   149  			Typ:        types.Interval,
   150  			ReturnType: types.Interval,
   151  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   152  				i := d.(*DInterval).Duration
   153  				i.SetNanos(-i.Nanos())
   154  				i.Days = -i.Days
   155  				i.Months = -i.Months
   156  				return &DInterval{Duration: i}, nil
   157  			},
   158  			Volatility: VolatilityImmutable,
   159  		},
   160  	},
   161  
   162  	UnaryComplement: {
   163  		&UnaryOp{
   164  			Typ:        types.Int,
   165  			ReturnType: types.Int,
   166  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   167  				return NewDInt(^MustBeDInt(d)), nil
   168  			},
   169  			Volatility: VolatilityImmutable,
   170  		},
   171  		&UnaryOp{
   172  			Typ:        types.VarBit,
   173  			ReturnType: types.VarBit,
   174  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   175  				p := MustBeDBitArray(d)
   176  				return &DBitArray{BitArray: bitarray.Not(p.BitArray)}, nil
   177  			},
   178  			Volatility: VolatilityImmutable,
   179  		},
   180  		&UnaryOp{
   181  			Typ:        types.INet,
   182  			ReturnType: types.INet,
   183  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   184  				ipAddr := MustBeDIPAddr(d).IPAddr
   185  				return NewDIPAddr(DIPAddr{ipAddr.Complement()}), nil
   186  			},
   187  			Volatility: VolatilityImmutable,
   188  		},
   189  	},
   190  
   191  	UnarySqrt: {
   192  		&UnaryOp{
   193  			Typ:        types.Float,
   194  			ReturnType: types.Float,
   195  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   196  				return Sqrt(float64(*d.(*DFloat)))
   197  			},
   198  			Volatility: VolatilityImmutable,
   199  		},
   200  		&UnaryOp{
   201  			Typ:        types.Decimal,
   202  			ReturnType: types.Decimal,
   203  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   204  				dec := &d.(*DDecimal).Decimal
   205  				return DecimalSqrt(dec)
   206  			},
   207  			Volatility: VolatilityImmutable,
   208  		},
   209  	},
   210  
   211  	UnaryCbrt: {
   212  		&UnaryOp{
   213  			Typ:        types.Float,
   214  			ReturnType: types.Float,
   215  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   216  				return Cbrt(float64(*d.(*DFloat)))
   217  			},
   218  			Volatility: VolatilityImmutable,
   219  		},
   220  		&UnaryOp{
   221  			Typ:        types.Decimal,
   222  			ReturnType: types.Decimal,
   223  			Fn: func(_ *EvalContext, d Datum) (Datum, error) {
   224  				dec := &d.(*DDecimal).Decimal
   225  				return DecimalCbrt(dec)
   226  			},
   227  			Volatility: VolatilityImmutable,
   228  		},
   229  	},
   230  })
   231  
   232  // BinOp is a binary operator.
   233  type BinOp struct {
   234  	LeftType     *types.T
   235  	RightType    *types.T
   236  	ReturnType   *types.T
   237  	NullableArgs bool
   238  	Fn           func(*EvalContext, Datum, Datum) (Datum, error)
   239  	Volatility   Volatility
   240  
   241  	types   TypeList
   242  	retType ReturnTyper
   243  
   244  	// counter, if non-nil, should be incremented every time the
   245  	// operator is type checked.
   246  	counter telemetry.Counter
   247  }
   248  
   249  func (op *BinOp) params() TypeList {
   250  	return op.types
   251  }
   252  
   253  func (op *BinOp) matchParams(l, r *types.T) bool {
   254  	return op.params().MatchAt(l, 0) && op.params().MatchAt(r, 1)
   255  }
   256  
   257  func (op *BinOp) returnType() ReturnTyper {
   258  	return op.retType
   259  }
   260  
   261  func (*BinOp) preferred() bool {
   262  	return false
   263  }
   264  
   265  // AppendToMaybeNullArray appends an element to an array. If the first
   266  // argument is NULL, an array of one element is created.
   267  func AppendToMaybeNullArray(typ *types.T, left Datum, right Datum) (Datum, error) {
   268  	result := NewDArray(typ)
   269  	if left != DNull {
   270  		for _, e := range MustBeDArray(left).Array {
   271  			if err := result.Append(e); err != nil {
   272  				return nil, err
   273  			}
   274  		}
   275  	}
   276  	if err := result.Append(right); err != nil {
   277  		return nil, err
   278  	}
   279  	return result, nil
   280  }
   281  
   282  // PrependToMaybeNullArray prepends an element in the front of an arrray.
   283  // If the argument is NULL, an array of one element is created.
   284  func PrependToMaybeNullArray(typ *types.T, left Datum, right Datum) (Datum, error) {
   285  	result := NewDArray(typ)
   286  	if err := result.Append(left); err != nil {
   287  		return nil, err
   288  	}
   289  	if right != DNull {
   290  		for _, e := range MustBeDArray(right).Array {
   291  			if err := result.Append(e); err != nil {
   292  				return nil, err
   293  			}
   294  		}
   295  	}
   296  	return result, nil
   297  }
   298  
   299  // TODO(justin): these might be improved by making arrays into an interface and
   300  // then introducing a ConcatenatedArray implementation which just references two
   301  // existing arrays. This would optimize the common case of appending an element
   302  // (or array) to an array from O(n) to O(1).
   303  func initArrayElementConcatenation() {
   304  	for _, t := range types.Scalar {
   305  		typ := t
   306  		BinOps[Concat] = append(BinOps[Concat], &BinOp{
   307  			LeftType:     types.MakeArray(typ),
   308  			RightType:    typ,
   309  			ReturnType:   types.MakeArray(typ),
   310  			NullableArgs: true,
   311  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   312  				return AppendToMaybeNullArray(typ, left, right)
   313  			},
   314  			Volatility: VolatilityImmutable,
   315  		})
   316  
   317  		BinOps[Concat] = append(BinOps[Concat], &BinOp{
   318  			LeftType:     typ,
   319  			RightType:    types.MakeArray(typ),
   320  			ReturnType:   types.MakeArray(typ),
   321  			NullableArgs: true,
   322  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   323  				return PrependToMaybeNullArray(typ, left, right)
   324  			},
   325  			Volatility: VolatilityImmutable,
   326  		})
   327  	}
   328  }
   329  
   330  // ConcatArrays concatenates two arrays.
   331  func ConcatArrays(typ *types.T, left Datum, right Datum) (Datum, error) {
   332  	if left == DNull && right == DNull {
   333  		return DNull, nil
   334  	}
   335  	result := NewDArray(typ)
   336  	if left != DNull {
   337  		for _, e := range MustBeDArray(left).Array {
   338  			if err := result.Append(e); err != nil {
   339  				return nil, err
   340  			}
   341  		}
   342  	}
   343  	if right != DNull {
   344  		for _, e := range MustBeDArray(right).Array {
   345  			if err := result.Append(e); err != nil {
   346  				return nil, err
   347  			}
   348  		}
   349  	}
   350  	return result, nil
   351  }
   352  
   353  // ArrayContains return true if the haystack contains all needles.
   354  func ArrayContains(ctx *EvalContext, haystack *DArray, needles *DArray) (*DBool, error) {
   355  	if !haystack.ParamTyp.Equivalent(needles.ParamTyp) {
   356  		return DBoolFalse, pgerror.New(pgcode.DatatypeMismatch, "cannot compare arrays with different element types")
   357  	}
   358  	for _, needle := range needles.Array {
   359  		// Nulls don't compare to each other in @> syntax.
   360  		if needle == DNull {
   361  			return DBoolFalse, nil
   362  		}
   363  		var found bool
   364  		for _, hay := range haystack.Array {
   365  			if needle.Compare(ctx, hay) == 0 {
   366  				found = true
   367  				break
   368  			}
   369  		}
   370  		if !found {
   371  			return DBoolFalse, nil
   372  		}
   373  	}
   374  	return DBoolTrue, nil
   375  }
   376  
   377  func initArrayToArrayConcatenation() {
   378  	for _, t := range types.Scalar {
   379  		typ := t
   380  		BinOps[Concat] = append(BinOps[Concat], &BinOp{
   381  			LeftType:     types.MakeArray(typ),
   382  			RightType:    types.MakeArray(typ),
   383  			ReturnType:   types.MakeArray(typ),
   384  			NullableArgs: true,
   385  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   386  				return ConcatArrays(typ, left, right)
   387  			},
   388  			Volatility: VolatilityImmutable,
   389  		})
   390  	}
   391  }
   392  
   393  func init() {
   394  	initArrayElementConcatenation()
   395  	initArrayToArrayConcatenation()
   396  }
   397  
   398  func init() {
   399  	for op, overload := range BinOps {
   400  		for i, impl := range overload {
   401  			casted := impl.(*BinOp)
   402  			casted.types = ArgTypes{{"left", casted.LeftType}, {"right", casted.RightType}}
   403  			casted.retType = FixedReturnType(casted.ReturnType)
   404  			BinOps[op][i] = casted
   405  		}
   406  	}
   407  }
   408  
   409  // binOpOverload is an overloaded set of binary operator implementations.
   410  type binOpOverload []overloadImpl
   411  
   412  func (o binOpOverload) lookupImpl(left, right *types.T) (*BinOp, bool) {
   413  	for _, fn := range o {
   414  		casted := fn.(*BinOp)
   415  		if casted.matchParams(left, right) {
   416  			return casted, true
   417  		}
   418  	}
   419  	return nil, false
   420  }
   421  
   422  // getJSONPath is used for the #> and #>> operators.
   423  func getJSONPath(j DJSON, ary DArray) (Datum, error) {
   424  	// TODO(justin): this is slightly annoying because we have to allocate
   425  	// a new array since the JSON package isn't aware of DArray.
   426  	path := make([]string, len(ary.Array))
   427  	for i, v := range ary.Array {
   428  		if v == DNull {
   429  			return DNull, nil
   430  		}
   431  		path[i] = string(MustBeDString(v))
   432  	}
   433  	result, err := json.FetchPath(j.JSON, path)
   434  	if err != nil {
   435  		return nil, err
   436  	}
   437  	if result == nil {
   438  		return DNull, nil
   439  	}
   440  	return &DJSON{result}, nil
   441  }
   442  
   443  // BinOps contains the binary operations indexed by operation type.
   444  var BinOps = map[BinaryOperator]binOpOverload{
   445  	Bitand: {
   446  		&BinOp{
   447  			LeftType:   types.Int,
   448  			RightType:  types.Int,
   449  			ReturnType: types.Int,
   450  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   451  				return NewDInt(MustBeDInt(left) & MustBeDInt(right)), nil
   452  			},
   453  			Volatility: VolatilityImmutable,
   454  		},
   455  		&BinOp{
   456  			LeftType:   types.VarBit,
   457  			RightType:  types.VarBit,
   458  			ReturnType: types.VarBit,
   459  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   460  				lhs := MustBeDBitArray(left)
   461  				rhs := MustBeDBitArray(right)
   462  				if lhs.BitLen() != rhs.BitLen() {
   463  					return nil, NewCannotMixBitArraySizesError("AND")
   464  				}
   465  				return &DBitArray{
   466  					BitArray: bitarray.And(lhs.BitArray, rhs.BitArray),
   467  				}, nil
   468  			},
   469  			Volatility: VolatilityImmutable,
   470  		},
   471  		&BinOp{
   472  			LeftType:   types.INet,
   473  			RightType:  types.INet,
   474  			ReturnType: types.INet,
   475  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   476  				ipAddr := MustBeDIPAddr(left).IPAddr
   477  				other := MustBeDIPAddr(right).IPAddr
   478  				newIPAddr, err := ipAddr.And(&other)
   479  				return NewDIPAddr(DIPAddr{newIPAddr}), err
   480  			},
   481  			Volatility: VolatilityImmutable,
   482  		},
   483  	},
   484  
   485  	Bitor: {
   486  		&BinOp{
   487  			LeftType:   types.Int,
   488  			RightType:  types.Int,
   489  			ReturnType: types.Int,
   490  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   491  				return NewDInt(MustBeDInt(left) | MustBeDInt(right)), nil
   492  			},
   493  			Volatility: VolatilityImmutable,
   494  		},
   495  		&BinOp{
   496  			LeftType:   types.VarBit,
   497  			RightType:  types.VarBit,
   498  			ReturnType: types.VarBit,
   499  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   500  				lhs := MustBeDBitArray(left)
   501  				rhs := MustBeDBitArray(right)
   502  				if lhs.BitLen() != rhs.BitLen() {
   503  					return nil, NewCannotMixBitArraySizesError("OR")
   504  				}
   505  				return &DBitArray{
   506  					BitArray: bitarray.Or(lhs.BitArray, rhs.BitArray),
   507  				}, nil
   508  			},
   509  			Volatility: VolatilityImmutable,
   510  		},
   511  		&BinOp{
   512  			LeftType:   types.INet,
   513  			RightType:  types.INet,
   514  			ReturnType: types.INet,
   515  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   516  				ipAddr := MustBeDIPAddr(left).IPAddr
   517  				other := MustBeDIPAddr(right).IPAddr
   518  				newIPAddr, err := ipAddr.Or(&other)
   519  				return NewDIPAddr(DIPAddr{newIPAddr}), err
   520  			},
   521  			Volatility: VolatilityImmutable,
   522  		},
   523  	},
   524  
   525  	Bitxor: {
   526  		&BinOp{
   527  			LeftType:   types.Int,
   528  			RightType:  types.Int,
   529  			ReturnType: types.Int,
   530  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   531  				return NewDInt(MustBeDInt(left) ^ MustBeDInt(right)), nil
   532  			},
   533  			Volatility: VolatilityImmutable,
   534  		},
   535  		&BinOp{
   536  			LeftType:   types.VarBit,
   537  			RightType:  types.VarBit,
   538  			ReturnType: types.VarBit,
   539  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   540  				lhs := MustBeDBitArray(left)
   541  				rhs := MustBeDBitArray(right)
   542  				if lhs.BitLen() != rhs.BitLen() {
   543  					return nil, NewCannotMixBitArraySizesError("XOR")
   544  				}
   545  				return &DBitArray{
   546  					BitArray: bitarray.Xor(lhs.BitArray, rhs.BitArray),
   547  				}, nil
   548  			},
   549  			Volatility: VolatilityImmutable,
   550  		},
   551  	},
   552  
   553  	Plus: {
   554  		&BinOp{
   555  			LeftType:   types.Int,
   556  			RightType:  types.Int,
   557  			ReturnType: types.Int,
   558  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   559  				a, b := MustBeDInt(left), MustBeDInt(right)
   560  				r, ok := arith.AddWithOverflow(int64(a), int64(b))
   561  				if !ok {
   562  					return nil, ErrIntOutOfRange
   563  				}
   564  				return NewDInt(DInt(r)), nil
   565  			},
   566  			Volatility: VolatilityImmutable,
   567  		},
   568  		&BinOp{
   569  			LeftType:   types.Float,
   570  			RightType:  types.Float,
   571  			ReturnType: types.Float,
   572  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   573  				return NewDFloat(*left.(*DFloat) + *right.(*DFloat)), nil
   574  			},
   575  			Volatility: VolatilityImmutable,
   576  		},
   577  		&BinOp{
   578  			LeftType:   types.Decimal,
   579  			RightType:  types.Decimal,
   580  			ReturnType: types.Decimal,
   581  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   582  				l := &left.(*DDecimal).Decimal
   583  				r := &right.(*DDecimal).Decimal
   584  				dd := &DDecimal{}
   585  				_, err := ExactCtx.Add(&dd.Decimal, l, r)
   586  				return dd, err
   587  			},
   588  			Volatility: VolatilityImmutable,
   589  		},
   590  		&BinOp{
   591  			LeftType:   types.Decimal,
   592  			RightType:  types.Int,
   593  			ReturnType: types.Decimal,
   594  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   595  				l := &left.(*DDecimal).Decimal
   596  				r := MustBeDInt(right)
   597  				dd := &DDecimal{}
   598  				dd.SetFinite(int64(r), 0)
   599  				_, err := ExactCtx.Add(&dd.Decimal, l, &dd.Decimal)
   600  				return dd, err
   601  			},
   602  			Volatility: VolatilityImmutable,
   603  		},
   604  		&BinOp{
   605  			LeftType:   types.Int,
   606  			RightType:  types.Decimal,
   607  			ReturnType: types.Decimal,
   608  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   609  				l := MustBeDInt(left)
   610  				r := &right.(*DDecimal).Decimal
   611  				dd := &DDecimal{}
   612  				dd.SetFinite(int64(l), 0)
   613  				_, err := ExactCtx.Add(&dd.Decimal, &dd.Decimal, r)
   614  				return dd, err
   615  			},
   616  			Volatility: VolatilityImmutable,
   617  		},
   618  		&BinOp{
   619  			LeftType:   types.Date,
   620  			RightType:  types.Int,
   621  			ReturnType: types.Date,
   622  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   623  				d, err := left.(*DDate).AddDays(int64(MustBeDInt(right)))
   624  				if err != nil {
   625  					return nil, err
   626  				}
   627  				return NewDDate(d), nil
   628  			},
   629  			Volatility: VolatilityImmutable,
   630  		},
   631  		&BinOp{
   632  			LeftType:   types.Int,
   633  			RightType:  types.Date,
   634  			ReturnType: types.Date,
   635  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   636  				d, err := right.(*DDate).AddDays(int64(MustBeDInt(left)))
   637  				if err != nil {
   638  					return nil, err
   639  				}
   640  				return NewDDate(d), nil
   641  
   642  			},
   643  			Volatility: VolatilityImmutable,
   644  		},
   645  		&BinOp{
   646  			LeftType:   types.Date,
   647  			RightType:  types.Time,
   648  			ReturnType: types.Timestamp,
   649  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   650  				leftTime, err := left.(*DDate).ToTime()
   651  				if err != nil {
   652  					return nil, err
   653  				}
   654  				t := time.Duration(*right.(*DTime)) * time.Microsecond
   655  				return MakeDTimestamp(leftTime.Add(t), time.Microsecond)
   656  			},
   657  			Volatility: VolatilityImmutable,
   658  		},
   659  		&BinOp{
   660  			LeftType:   types.Time,
   661  			RightType:  types.Date,
   662  			ReturnType: types.Timestamp,
   663  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   664  				rightTime, err := right.(*DDate).ToTime()
   665  				if err != nil {
   666  					return nil, err
   667  				}
   668  				t := time.Duration(*left.(*DTime)) * time.Microsecond
   669  				return MakeDTimestamp(rightTime.Add(t), time.Microsecond)
   670  			},
   671  			Volatility: VolatilityImmutable,
   672  		},
   673  		&BinOp{
   674  			LeftType:   types.Date,
   675  			RightType:  types.TimeTZ,
   676  			ReturnType: types.TimestampTZ,
   677  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   678  				leftTime, err := left.(*DDate).ToTime()
   679  				if err != nil {
   680  					return nil, err
   681  				}
   682  				t := leftTime.Add(right.(*DTimeTZ).ToDuration())
   683  				return MakeDTimestampTZ(t, time.Microsecond)
   684  			},
   685  			Volatility: VolatilityImmutable,
   686  		},
   687  		&BinOp{
   688  			LeftType:   types.TimeTZ,
   689  			RightType:  types.Date,
   690  			ReturnType: types.TimestampTZ,
   691  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   692  				rightTime, err := right.(*DDate).ToTime()
   693  				if err != nil {
   694  					return nil, err
   695  				}
   696  				t := rightTime.Add(left.(*DTimeTZ).ToDuration())
   697  				return MakeDTimestampTZ(t, time.Microsecond)
   698  			},
   699  			Volatility: VolatilityImmutable,
   700  		},
   701  		&BinOp{
   702  			LeftType:   types.Time,
   703  			RightType:  types.Interval,
   704  			ReturnType: types.Time,
   705  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   706  				t := timeofday.TimeOfDay(*left.(*DTime))
   707  				return MakeDTime(t.Add(right.(*DInterval).Duration)), nil
   708  			},
   709  			Volatility: VolatilityImmutable,
   710  		},
   711  		&BinOp{
   712  			LeftType:   types.Interval,
   713  			RightType:  types.Time,
   714  			ReturnType: types.Time,
   715  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   716  				t := timeofday.TimeOfDay(*right.(*DTime))
   717  				return MakeDTime(t.Add(left.(*DInterval).Duration)), nil
   718  			},
   719  			Volatility: VolatilityImmutable,
   720  		},
   721  		&BinOp{
   722  			LeftType:   types.TimeTZ,
   723  			RightType:  types.Interval,
   724  			ReturnType: types.TimeTZ,
   725  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   726  				t := left.(*DTimeTZ)
   727  				duration := right.(*DInterval).Duration
   728  				return NewDTimeTZFromOffset(t.Add(duration), t.OffsetSecs), nil
   729  			},
   730  			Volatility: VolatilityImmutable,
   731  		},
   732  		&BinOp{
   733  			LeftType:   types.Interval,
   734  			RightType:  types.TimeTZ,
   735  			ReturnType: types.TimeTZ,
   736  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   737  				t := right.(*DTimeTZ)
   738  				duration := left.(*DInterval).Duration
   739  				return NewDTimeTZFromOffset(t.Add(duration), t.OffsetSecs), nil
   740  			},
   741  			Volatility: VolatilityImmutable,
   742  		},
   743  		&BinOp{
   744  			LeftType:   types.Timestamp,
   745  			RightType:  types.Interval,
   746  			ReturnType: types.Timestamp,
   747  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   748  				return MakeDTimestamp(duration.Add(
   749  					left.(*DTimestamp).Time, right.(*DInterval).Duration), time.Microsecond)
   750  			},
   751  			Volatility: VolatilityImmutable,
   752  		},
   753  		&BinOp{
   754  			LeftType:   types.Interval,
   755  			RightType:  types.Timestamp,
   756  			ReturnType: types.Timestamp,
   757  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   758  				return MakeDTimestamp(duration.Add(
   759  					right.(*DTimestamp).Time, left.(*DInterval).Duration), time.Microsecond)
   760  			},
   761  			Volatility: VolatilityImmutable,
   762  		},
   763  		&BinOp{
   764  			LeftType:   types.TimestampTZ,
   765  			RightType:  types.Interval,
   766  			ReturnType: types.TimestampTZ,
   767  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
   768  				// Convert time to be in the given timezone, as math relies on matching timezones..
   769  				t := duration.Add(left.(*DTimestampTZ).Time.In(ctx.GetLocation()), right.(*DInterval).Duration)
   770  				return MakeDTimestampTZ(t, time.Microsecond)
   771  			},
   772  			Volatility: VolatilityStable,
   773  		},
   774  		&BinOp{
   775  			LeftType:   types.Interval,
   776  			RightType:  types.TimestampTZ,
   777  			ReturnType: types.TimestampTZ,
   778  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
   779  				// Convert time to be in the given timezone, as math relies on matching timezones..
   780  				t := duration.Add(right.(*DTimestampTZ).Time.In(ctx.GetLocation()), left.(*DInterval).Duration)
   781  				return MakeDTimestampTZ(t, time.Microsecond)
   782  			},
   783  			Volatility: VolatilityStable,
   784  		},
   785  		&BinOp{
   786  			LeftType:   types.Interval,
   787  			RightType:  types.Interval,
   788  			ReturnType: types.Interval,
   789  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   790  				return &DInterval{Duration: left.(*DInterval).Duration.Add(right.(*DInterval).Duration)}, nil
   791  			},
   792  			Volatility: VolatilityImmutable,
   793  		},
   794  		&BinOp{
   795  			LeftType:   types.Date,
   796  			RightType:  types.Interval,
   797  			ReturnType: types.Timestamp,
   798  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
   799  				leftTime, err := left.(*DDate).ToTime()
   800  				if err != nil {
   801  					return nil, err
   802  				}
   803  				t := duration.Add(leftTime, right.(*DInterval).Duration)
   804  				return MakeDTimestamp(t, time.Microsecond)
   805  			},
   806  			Volatility: VolatilityImmutable,
   807  		},
   808  		&BinOp{
   809  			LeftType:   types.Interval,
   810  			RightType:  types.Date,
   811  			ReturnType: types.Timestamp,
   812  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   813  				rightTime, err := right.(*DDate).ToTime()
   814  				if err != nil {
   815  					return nil, err
   816  				}
   817  				t := duration.Add(rightTime, left.(*DInterval).Duration)
   818  				return MakeDTimestamp(t, time.Microsecond)
   819  			},
   820  			Volatility: VolatilityImmutable,
   821  		},
   822  		&BinOp{
   823  			LeftType:   types.INet,
   824  			RightType:  types.Int,
   825  			ReturnType: types.INet,
   826  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   827  				ipAddr := MustBeDIPAddr(left).IPAddr
   828  				i := MustBeDInt(right)
   829  				newIPAddr, err := ipAddr.Add(int64(i))
   830  				return NewDIPAddr(DIPAddr{newIPAddr}), err
   831  			},
   832  			Volatility: VolatilityImmutable,
   833  		},
   834  		&BinOp{
   835  			LeftType:   types.Int,
   836  			RightType:  types.INet,
   837  			ReturnType: types.INet,
   838  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   839  				i := MustBeDInt(left)
   840  				ipAddr := MustBeDIPAddr(right).IPAddr
   841  				newIPAddr, err := ipAddr.Add(int64(i))
   842  				return NewDIPAddr(DIPAddr{newIPAddr}), err
   843  			},
   844  			Volatility: VolatilityImmutable,
   845  		},
   846  	},
   847  
   848  	Minus: {
   849  		&BinOp{
   850  			LeftType:   types.Int,
   851  			RightType:  types.Int,
   852  			ReturnType: types.Int,
   853  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   854  				a, b := MustBeDInt(left), MustBeDInt(right)
   855  				r, ok := arith.SubWithOverflow(int64(a), int64(b))
   856  				if !ok {
   857  					return nil, ErrIntOutOfRange
   858  				}
   859  				return NewDInt(DInt(r)), nil
   860  			},
   861  			Volatility: VolatilityImmutable,
   862  		},
   863  		&BinOp{
   864  			LeftType:   types.Float,
   865  			RightType:  types.Float,
   866  			ReturnType: types.Float,
   867  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   868  				return NewDFloat(*left.(*DFloat) - *right.(*DFloat)), nil
   869  			},
   870  			Volatility: VolatilityImmutable,
   871  		},
   872  		&BinOp{
   873  			LeftType:   types.Decimal,
   874  			RightType:  types.Decimal,
   875  			ReturnType: types.Decimal,
   876  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   877  				l := &left.(*DDecimal).Decimal
   878  				r := &right.(*DDecimal).Decimal
   879  				dd := &DDecimal{}
   880  				_, err := ExactCtx.Sub(&dd.Decimal, l, r)
   881  				return dd, err
   882  			},
   883  			Volatility: VolatilityImmutable,
   884  		},
   885  		&BinOp{
   886  			LeftType:   types.Decimal,
   887  			RightType:  types.Int,
   888  			ReturnType: types.Decimal,
   889  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   890  				l := &left.(*DDecimal).Decimal
   891  				r := MustBeDInt(right)
   892  				dd := &DDecimal{}
   893  				dd.SetFinite(int64(r), 0)
   894  				_, err := ExactCtx.Sub(&dd.Decimal, l, &dd.Decimal)
   895  				return dd, err
   896  			},
   897  			Volatility: VolatilityImmutable,
   898  		},
   899  		&BinOp{
   900  			LeftType:   types.Int,
   901  			RightType:  types.Decimal,
   902  			ReturnType: types.Decimal,
   903  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   904  				l := MustBeDInt(left)
   905  				r := &right.(*DDecimal).Decimal
   906  				dd := &DDecimal{}
   907  				dd.SetFinite(int64(l), 0)
   908  				_, err := ExactCtx.Sub(&dd.Decimal, &dd.Decimal, r)
   909  				return dd, err
   910  			},
   911  			Volatility: VolatilityImmutable,
   912  		},
   913  		&BinOp{
   914  			LeftType:   types.Date,
   915  			RightType:  types.Int,
   916  			ReturnType: types.Date,
   917  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   918  				d, err := left.(*DDate).SubDays(int64(MustBeDInt(right)))
   919  				if err != nil {
   920  					return nil, err
   921  				}
   922  				return NewDDate(d), nil
   923  			},
   924  			Volatility: VolatilityImmutable,
   925  		},
   926  		&BinOp{
   927  			LeftType:   types.Date,
   928  			RightType:  types.Date,
   929  			ReturnType: types.Int,
   930  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   931  				l, r := left.(*DDate).Date, right.(*DDate).Date
   932  				if !l.IsFinite() || !r.IsFinite() {
   933  					return nil, pgerror.New(pgcode.DatetimeFieldOverflow, "cannot subtract infinite dates")
   934  				}
   935  				a := l.PGEpochDays()
   936  				b := r.PGEpochDays()
   937  				// This can't overflow because they are upconverted from int32 to int64.
   938  				return NewDInt(DInt(int64(a) - int64(b))), nil
   939  			},
   940  			Volatility: VolatilityImmutable,
   941  		},
   942  		&BinOp{
   943  			LeftType:   types.Date,
   944  			RightType:  types.Time,
   945  			ReturnType: types.Timestamp,
   946  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   947  				leftTime, err := left.(*DDate).ToTime()
   948  				if err != nil {
   949  					return nil, err
   950  				}
   951  				t := time.Duration(*right.(*DTime)) * time.Microsecond
   952  				return MakeDTimestamp(leftTime.Add(-1*t), time.Microsecond)
   953  			},
   954  			Volatility: VolatilityImmutable,
   955  		},
   956  		&BinOp{
   957  			LeftType:   types.Time,
   958  			RightType:  types.Time,
   959  			ReturnType: types.Interval,
   960  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   961  				t1 := timeofday.TimeOfDay(*left.(*DTime))
   962  				t2 := timeofday.TimeOfDay(*right.(*DTime))
   963  				diff := timeofday.Difference(t1, t2)
   964  				return &DInterval{Duration: diff}, nil
   965  			},
   966  			Volatility: VolatilityImmutable,
   967  		},
   968  		&BinOp{
   969  			LeftType:   types.Timestamp,
   970  			RightType:  types.Timestamp,
   971  			ReturnType: types.Interval,
   972  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   973  				nanos := left.(*DTimestamp).Sub(right.(*DTimestamp).Time).Nanoseconds()
   974  				return &DInterval{Duration: duration.MakeDuration(nanos, 0, 0)}, nil
   975  			},
   976  			Volatility: VolatilityImmutable,
   977  		},
   978  		&BinOp{
   979  			LeftType:   types.TimestampTZ,
   980  			RightType:  types.TimestampTZ,
   981  			ReturnType: types.Interval,
   982  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
   983  				nanos := left.(*DTimestampTZ).Sub(right.(*DTimestampTZ).Time).Nanoseconds()
   984  				return &DInterval{Duration: duration.MakeDuration(nanos, 0, 0)}, nil
   985  			},
   986  			Volatility: VolatilityImmutable,
   987  		},
   988  		&BinOp{
   989  			LeftType:   types.Timestamp,
   990  			RightType:  types.TimestampTZ,
   991  			ReturnType: types.Interval,
   992  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
   993  				// These two quantities aren't directly comparable. Convert the
   994  				// TimestampTZ to a timestamp first.
   995  				stripped, err := right.(*DTimestampTZ).stripTimeZone(ctx)
   996  				if err != nil {
   997  					return nil, err
   998  				}
   999  				nanos := left.(*DTimestamp).Sub(stripped.Time).Nanoseconds()
  1000  				return &DInterval{Duration: duration.MakeDuration(nanos, 0, 0)}, nil
  1001  			},
  1002  			Volatility: VolatilityStable,
  1003  		},
  1004  		&BinOp{
  1005  			LeftType:   types.TimestampTZ,
  1006  			RightType:  types.Timestamp,
  1007  			ReturnType: types.Interval,
  1008  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  1009  				// These two quantities aren't directly comparable. Convert the
  1010  				// TimestampTZ to a timestamp first.
  1011  				stripped, err := left.(*DTimestampTZ).stripTimeZone(ctx)
  1012  				if err != nil {
  1013  					return nil, err
  1014  				}
  1015  				nanos := stripped.Sub(right.(*DTimestamp).Time).Nanoseconds()
  1016  				return &DInterval{Duration: duration.MakeDuration(nanos, 0, 0)}, nil
  1017  			},
  1018  			Volatility: VolatilityStable,
  1019  		},
  1020  		&BinOp{
  1021  			LeftType:   types.Time,
  1022  			RightType:  types.Interval,
  1023  			ReturnType: types.Time,
  1024  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1025  				t := timeofday.TimeOfDay(*left.(*DTime))
  1026  				return MakeDTime(t.Add(right.(*DInterval).Duration.Mul(-1))), nil
  1027  			},
  1028  			Volatility: VolatilityImmutable,
  1029  		},
  1030  		&BinOp{
  1031  			LeftType:   types.TimeTZ,
  1032  			RightType:  types.Interval,
  1033  			ReturnType: types.TimeTZ,
  1034  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1035  				t := left.(*DTimeTZ)
  1036  				duration := right.(*DInterval).Duration
  1037  				return NewDTimeTZFromOffset(t.Add(duration.Mul(-1)), t.OffsetSecs), nil
  1038  			},
  1039  			Volatility: VolatilityImmutable,
  1040  		},
  1041  		&BinOp{
  1042  			LeftType:   types.Timestamp,
  1043  			RightType:  types.Interval,
  1044  			ReturnType: types.Timestamp,
  1045  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1046  				return MakeDTimestamp(duration.Add(
  1047  					left.(*DTimestamp).Time, right.(*DInterval).Duration.Mul(-1)), time.Microsecond)
  1048  			},
  1049  			Volatility: VolatilityImmutable,
  1050  		},
  1051  		&BinOp{
  1052  			LeftType:   types.TimestampTZ,
  1053  			RightType:  types.Interval,
  1054  			ReturnType: types.TimestampTZ,
  1055  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  1056  				t := duration.Add(
  1057  					left.(*DTimestampTZ).Time.In(ctx.GetLocation()),
  1058  					right.(*DInterval).Duration.Mul(-1),
  1059  				)
  1060  				return MakeDTimestampTZ(t, time.Microsecond)
  1061  			},
  1062  			Volatility: VolatilityStable,
  1063  		},
  1064  		&BinOp{
  1065  			LeftType:   types.Date,
  1066  			RightType:  types.Interval,
  1067  			ReturnType: types.Timestamp,
  1068  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1069  				leftTime, err := left.(*DDate).ToTime()
  1070  				if err != nil {
  1071  					return nil, err
  1072  				}
  1073  				t := duration.Add(leftTime, right.(*DInterval).Duration.Mul(-1))
  1074  				return MakeDTimestamp(t, time.Microsecond)
  1075  			},
  1076  			Volatility: VolatilityImmutable,
  1077  		},
  1078  		&BinOp{
  1079  			LeftType:   types.Interval,
  1080  			RightType:  types.Interval,
  1081  			ReturnType: types.Interval,
  1082  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1083  				return &DInterval{Duration: left.(*DInterval).Duration.Sub(right.(*DInterval).Duration)}, nil
  1084  			},
  1085  			Volatility: VolatilityImmutable,
  1086  		},
  1087  		&BinOp{
  1088  			LeftType:   types.Jsonb,
  1089  			RightType:  types.String,
  1090  			ReturnType: types.Jsonb,
  1091  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1092  				j, _, err := left.(*DJSON).JSON.RemoveString(string(MustBeDString(right)))
  1093  				if err != nil {
  1094  					return nil, err
  1095  				}
  1096  				return &DJSON{j}, nil
  1097  			},
  1098  			Volatility: VolatilityImmutable,
  1099  		},
  1100  		&BinOp{
  1101  			LeftType:   types.Jsonb,
  1102  			RightType:  types.Int,
  1103  			ReturnType: types.Jsonb,
  1104  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1105  				j, _, err := left.(*DJSON).JSON.RemoveIndex(int(MustBeDInt(right)))
  1106  				if err != nil {
  1107  					return nil, err
  1108  				}
  1109  				return &DJSON{j}, nil
  1110  			},
  1111  			Volatility: VolatilityImmutable,
  1112  		},
  1113  		&BinOp{
  1114  			LeftType:   types.Jsonb,
  1115  			RightType:  types.MakeArray(types.String),
  1116  			ReturnType: types.Jsonb,
  1117  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1118  				j := left.(*DJSON).JSON
  1119  				arr := *MustBeDArray(right)
  1120  
  1121  				for _, str := range arr.Array {
  1122  					if str == DNull {
  1123  						continue
  1124  					}
  1125  					var err error
  1126  					j, _, err = j.RemoveString(string(MustBeDString(str)))
  1127  					if err != nil {
  1128  						return nil, err
  1129  					}
  1130  				}
  1131  				return &DJSON{j}, nil
  1132  			},
  1133  			Volatility: VolatilityImmutable,
  1134  		},
  1135  		&BinOp{
  1136  			LeftType:   types.INet,
  1137  			RightType:  types.INet,
  1138  			ReturnType: types.Int,
  1139  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1140  				ipAddr := MustBeDIPAddr(left).IPAddr
  1141  				other := MustBeDIPAddr(right).IPAddr
  1142  				diff, err := ipAddr.SubIPAddr(&other)
  1143  				return NewDInt(DInt(diff)), err
  1144  			},
  1145  			Volatility: VolatilityImmutable,
  1146  		},
  1147  		&BinOp{
  1148  			// Note: postgres ver 10 does NOT have Int - INet. Throws ERROR: 42883.
  1149  			LeftType:   types.INet,
  1150  			RightType:  types.Int,
  1151  			ReturnType: types.INet,
  1152  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1153  				ipAddr := MustBeDIPAddr(left).IPAddr
  1154  				i := MustBeDInt(right)
  1155  				newIPAddr, err := ipAddr.Sub(int64(i))
  1156  				return NewDIPAddr(DIPAddr{newIPAddr}), err
  1157  			},
  1158  			Volatility: VolatilityImmutable,
  1159  		},
  1160  	},
  1161  
  1162  	Mult: {
  1163  		&BinOp{
  1164  			LeftType:   types.Int,
  1165  			RightType:  types.Int,
  1166  			ReturnType: types.Int,
  1167  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1168  				// See Rob Pike's implementation from
  1169  				// https://groups.google.com/d/msg/golang-nuts/h5oSN5t3Au4/KaNQREhZh0QJ
  1170  
  1171  				a, b := MustBeDInt(left), MustBeDInt(right)
  1172  				c := a * b
  1173  				if a == 0 || b == 0 || a == 1 || b == 1 {
  1174  					// ignore
  1175  				} else if a == math.MinInt64 || b == math.MinInt64 {
  1176  					// This test is required to detect math.MinInt64 * -1.
  1177  					return nil, ErrIntOutOfRange
  1178  				} else if c/b != a {
  1179  					return nil, ErrIntOutOfRange
  1180  				}
  1181  				return NewDInt(c), nil
  1182  			},
  1183  			Volatility: VolatilityImmutable,
  1184  		},
  1185  		&BinOp{
  1186  			LeftType:   types.Float,
  1187  			RightType:  types.Float,
  1188  			ReturnType: types.Float,
  1189  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1190  				return NewDFloat(*left.(*DFloat) * *right.(*DFloat)), nil
  1191  			},
  1192  			Volatility: VolatilityImmutable,
  1193  		},
  1194  		&BinOp{
  1195  			LeftType:   types.Decimal,
  1196  			RightType:  types.Decimal,
  1197  			ReturnType: types.Decimal,
  1198  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1199  				l := &left.(*DDecimal).Decimal
  1200  				r := &right.(*DDecimal).Decimal
  1201  				dd := &DDecimal{}
  1202  				_, err := ExactCtx.Mul(&dd.Decimal, l, r)
  1203  				return dd, err
  1204  			},
  1205  			Volatility: VolatilityImmutable,
  1206  		},
  1207  		// The following two overloads are needed because DInt/DInt = DDecimal. Due
  1208  		// to this operation, normalization may sometimes create a DInt * DDecimal
  1209  		// operation.
  1210  		&BinOp{
  1211  			LeftType:   types.Decimal,
  1212  			RightType:  types.Int,
  1213  			ReturnType: types.Decimal,
  1214  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1215  				l := &left.(*DDecimal).Decimal
  1216  				r := MustBeDInt(right)
  1217  				dd := &DDecimal{}
  1218  				dd.SetFinite(int64(r), 0)
  1219  				_, err := ExactCtx.Mul(&dd.Decimal, l, &dd.Decimal)
  1220  				return dd, err
  1221  			},
  1222  			Volatility: VolatilityImmutable,
  1223  		},
  1224  		&BinOp{
  1225  			LeftType:   types.Int,
  1226  			RightType:  types.Decimal,
  1227  			ReturnType: types.Decimal,
  1228  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1229  				l := MustBeDInt(left)
  1230  				r := &right.(*DDecimal).Decimal
  1231  				dd := &DDecimal{}
  1232  				dd.SetFinite(int64(l), 0)
  1233  				_, err := ExactCtx.Mul(&dd.Decimal, &dd.Decimal, r)
  1234  				return dd, err
  1235  			},
  1236  			Volatility: VolatilityImmutable,
  1237  		},
  1238  		&BinOp{
  1239  			LeftType:   types.Int,
  1240  			RightType:  types.Interval,
  1241  			ReturnType: types.Interval,
  1242  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1243  				return &DInterval{Duration: right.(*DInterval).Duration.Mul(int64(MustBeDInt(left)))}, nil
  1244  			},
  1245  			Volatility: VolatilityImmutable,
  1246  		},
  1247  		&BinOp{
  1248  			LeftType:   types.Interval,
  1249  			RightType:  types.Int,
  1250  			ReturnType: types.Interval,
  1251  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1252  				return &DInterval{Duration: left.(*DInterval).Duration.Mul(int64(MustBeDInt(right)))}, nil
  1253  			},
  1254  			Volatility: VolatilityImmutable,
  1255  		},
  1256  		&BinOp{
  1257  			LeftType:   types.Interval,
  1258  			RightType:  types.Float,
  1259  			ReturnType: types.Interval,
  1260  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1261  				r := float64(*right.(*DFloat))
  1262  				return &DInterval{Duration: left.(*DInterval).Duration.MulFloat(r)}, nil
  1263  			},
  1264  			Volatility: VolatilityImmutable,
  1265  		},
  1266  		&BinOp{
  1267  			LeftType:   types.Float,
  1268  			RightType:  types.Interval,
  1269  			ReturnType: types.Interval,
  1270  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1271  				l := float64(*left.(*DFloat))
  1272  				return &DInterval{Duration: right.(*DInterval).Duration.MulFloat(l)}, nil
  1273  			},
  1274  			Volatility: VolatilityImmutable,
  1275  		},
  1276  		&BinOp{
  1277  			LeftType:   types.Decimal,
  1278  			RightType:  types.Interval,
  1279  			ReturnType: types.Interval,
  1280  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1281  				l := &left.(*DDecimal).Decimal
  1282  				t, err := l.Float64()
  1283  				if err != nil {
  1284  					return nil, err
  1285  				}
  1286  				return &DInterval{Duration: right.(*DInterval).Duration.MulFloat(t)}, nil
  1287  			},
  1288  			Volatility: VolatilityImmutable,
  1289  		},
  1290  		&BinOp{
  1291  			LeftType:   types.Interval,
  1292  			RightType:  types.Decimal,
  1293  			ReturnType: types.Interval,
  1294  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1295  				r := &right.(*DDecimal).Decimal
  1296  				t, err := r.Float64()
  1297  				if err != nil {
  1298  					return nil, err
  1299  				}
  1300  				return &DInterval{Duration: left.(*DInterval).Duration.MulFloat(t)}, nil
  1301  			},
  1302  			Volatility: VolatilityImmutable,
  1303  		},
  1304  	},
  1305  
  1306  	Div: {
  1307  		&BinOp{
  1308  			LeftType:   types.Int,
  1309  			RightType:  types.Int,
  1310  			ReturnType: types.Decimal,
  1311  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  1312  				rInt := MustBeDInt(right)
  1313  				div := ctx.getTmpDec().SetFinite(int64(rInt), 0)
  1314  				dd := &DDecimal{}
  1315  				dd.SetFinite(int64(MustBeDInt(left)), 0)
  1316  				cond, err := DecimalCtx.Quo(&dd.Decimal, &dd.Decimal, div)
  1317  				if cond.DivisionByZero() {
  1318  					return dd, ErrDivByZero
  1319  				}
  1320  				return dd, err
  1321  			},
  1322  			Volatility: VolatilityImmutable,
  1323  		},
  1324  		&BinOp{
  1325  			LeftType:   types.Float,
  1326  			RightType:  types.Float,
  1327  			ReturnType: types.Float,
  1328  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1329  				r := *right.(*DFloat)
  1330  				if r == 0.0 {
  1331  					return nil, ErrDivByZero
  1332  				}
  1333  				return NewDFloat(*left.(*DFloat) / r), nil
  1334  			},
  1335  			Volatility: VolatilityImmutable,
  1336  		},
  1337  		&BinOp{
  1338  			LeftType:   types.Decimal,
  1339  			RightType:  types.Decimal,
  1340  			ReturnType: types.Decimal,
  1341  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1342  				l := &left.(*DDecimal).Decimal
  1343  				r := &right.(*DDecimal).Decimal
  1344  				dd := &DDecimal{}
  1345  				cond, err := DecimalCtx.Quo(&dd.Decimal, l, r)
  1346  				if cond.DivisionByZero() {
  1347  					return dd, ErrDivByZero
  1348  				}
  1349  				return dd, err
  1350  			},
  1351  			Volatility: VolatilityImmutable,
  1352  		},
  1353  		&BinOp{
  1354  			LeftType:   types.Decimal,
  1355  			RightType:  types.Int,
  1356  			ReturnType: types.Decimal,
  1357  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1358  				l := &left.(*DDecimal).Decimal
  1359  				r := MustBeDInt(right)
  1360  				dd := &DDecimal{}
  1361  				dd.SetFinite(int64(r), 0)
  1362  				cond, err := DecimalCtx.Quo(&dd.Decimal, l, &dd.Decimal)
  1363  				if cond.DivisionByZero() {
  1364  					return dd, ErrDivByZero
  1365  				}
  1366  				return dd, err
  1367  			},
  1368  			Volatility: VolatilityImmutable,
  1369  		},
  1370  		&BinOp{
  1371  			LeftType:   types.Int,
  1372  			RightType:  types.Decimal,
  1373  			ReturnType: types.Decimal,
  1374  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1375  				l := MustBeDInt(left)
  1376  				r := &right.(*DDecimal).Decimal
  1377  				dd := &DDecimal{}
  1378  				dd.SetFinite(int64(l), 0)
  1379  				cond, err := DecimalCtx.Quo(&dd.Decimal, &dd.Decimal, r)
  1380  				if cond.DivisionByZero() {
  1381  					return dd, ErrDivByZero
  1382  				}
  1383  				return dd, err
  1384  			},
  1385  			Volatility: VolatilityImmutable,
  1386  		},
  1387  		&BinOp{
  1388  			LeftType:   types.Interval,
  1389  			RightType:  types.Int,
  1390  			ReturnType: types.Interval,
  1391  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1392  				rInt := MustBeDInt(right)
  1393  				if rInt == 0 {
  1394  					return nil, ErrDivByZero
  1395  				}
  1396  				return &DInterval{Duration: left.(*DInterval).Duration.Div(int64(rInt))}, nil
  1397  			},
  1398  			Volatility: VolatilityImmutable,
  1399  		},
  1400  		&BinOp{
  1401  			LeftType:   types.Interval,
  1402  			RightType:  types.Float,
  1403  			ReturnType: types.Interval,
  1404  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1405  				r := float64(*right.(*DFloat))
  1406  				if r == 0.0 {
  1407  					return nil, ErrDivByZero
  1408  				}
  1409  				return &DInterval{Duration: left.(*DInterval).Duration.DivFloat(r)}, nil
  1410  			},
  1411  			Volatility: VolatilityImmutable,
  1412  		},
  1413  	},
  1414  
  1415  	FloorDiv: {
  1416  		&BinOp{
  1417  			LeftType:   types.Int,
  1418  			RightType:  types.Int,
  1419  			ReturnType: types.Int,
  1420  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1421  				rInt := MustBeDInt(right)
  1422  				if rInt == 0 {
  1423  					return nil, ErrDivByZero
  1424  				}
  1425  				return NewDInt(MustBeDInt(left) / rInt), nil
  1426  			},
  1427  			Volatility: VolatilityImmutable,
  1428  		},
  1429  		&BinOp{
  1430  			LeftType:   types.Float,
  1431  			RightType:  types.Float,
  1432  			ReturnType: types.Float,
  1433  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1434  				l := float64(*left.(*DFloat))
  1435  				r := float64(*right.(*DFloat))
  1436  				return NewDFloat(DFloat(math.Trunc(l / r))), nil
  1437  			},
  1438  			Volatility: VolatilityImmutable,
  1439  		},
  1440  		&BinOp{
  1441  			LeftType:   types.Decimal,
  1442  			RightType:  types.Decimal,
  1443  			ReturnType: types.Decimal,
  1444  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1445  				l := &left.(*DDecimal).Decimal
  1446  				r := &right.(*DDecimal).Decimal
  1447  				dd := &DDecimal{}
  1448  				_, err := HighPrecisionCtx.QuoInteger(&dd.Decimal, l, r)
  1449  				return dd, err
  1450  			},
  1451  			Volatility: VolatilityImmutable,
  1452  		},
  1453  		&BinOp{
  1454  			LeftType:   types.Decimal,
  1455  			RightType:  types.Int,
  1456  			ReturnType: types.Decimal,
  1457  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1458  				l := &left.(*DDecimal).Decimal
  1459  				r := MustBeDInt(right)
  1460  				if r == 0 {
  1461  					return nil, ErrDivByZero
  1462  				}
  1463  				dd := &DDecimal{}
  1464  				dd.SetFinite(int64(r), 0)
  1465  				_, err := HighPrecisionCtx.QuoInteger(&dd.Decimal, l, &dd.Decimal)
  1466  				return dd, err
  1467  			},
  1468  			Volatility: VolatilityImmutable,
  1469  		},
  1470  		&BinOp{
  1471  			LeftType:   types.Int,
  1472  			RightType:  types.Decimal,
  1473  			ReturnType: types.Decimal,
  1474  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1475  				l := MustBeDInt(left)
  1476  				r := &right.(*DDecimal).Decimal
  1477  				if r.Sign() == 0 {
  1478  					return nil, ErrDivByZero
  1479  				}
  1480  				dd := &DDecimal{}
  1481  				dd.SetFinite(int64(l), 0)
  1482  				_, err := HighPrecisionCtx.QuoInteger(&dd.Decimal, &dd.Decimal, r)
  1483  				return dd, err
  1484  			},
  1485  			Volatility: VolatilityImmutable,
  1486  		},
  1487  	},
  1488  
  1489  	Mod: {
  1490  		&BinOp{
  1491  			LeftType:   types.Int,
  1492  			RightType:  types.Int,
  1493  			ReturnType: types.Int,
  1494  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1495  				r := MustBeDInt(right)
  1496  				if r == 0 {
  1497  					return nil, ErrZeroModulus
  1498  				}
  1499  				return NewDInt(MustBeDInt(left) % r), nil
  1500  			},
  1501  			Volatility: VolatilityImmutable,
  1502  		},
  1503  		&BinOp{
  1504  			LeftType:   types.Float,
  1505  			RightType:  types.Float,
  1506  			ReturnType: types.Float,
  1507  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1508  				return NewDFloat(DFloat(math.Mod(float64(*left.(*DFloat)), float64(*right.(*DFloat))))), nil
  1509  			},
  1510  			Volatility: VolatilityImmutable,
  1511  		},
  1512  		&BinOp{
  1513  			LeftType:   types.Decimal,
  1514  			RightType:  types.Decimal,
  1515  			ReturnType: types.Decimal,
  1516  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1517  				l := &left.(*DDecimal).Decimal
  1518  				r := &right.(*DDecimal).Decimal
  1519  				dd := &DDecimal{}
  1520  				_, err := HighPrecisionCtx.Rem(&dd.Decimal, l, r)
  1521  				return dd, err
  1522  			},
  1523  			Volatility: VolatilityImmutable,
  1524  		},
  1525  		&BinOp{
  1526  			LeftType:   types.Decimal,
  1527  			RightType:  types.Int,
  1528  			ReturnType: types.Decimal,
  1529  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1530  				l := &left.(*DDecimal).Decimal
  1531  				r := MustBeDInt(right)
  1532  				dd := &DDecimal{}
  1533  				dd.SetFinite(int64(r), 0)
  1534  				_, err := HighPrecisionCtx.Rem(&dd.Decimal, l, &dd.Decimal)
  1535  				return dd, err
  1536  			},
  1537  			Volatility: VolatilityImmutable,
  1538  		},
  1539  		&BinOp{
  1540  			LeftType:   types.Int,
  1541  			RightType:  types.Decimal,
  1542  			ReturnType: types.Decimal,
  1543  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1544  				l := MustBeDInt(left)
  1545  				r := &right.(*DDecimal).Decimal
  1546  				dd := &DDecimal{}
  1547  				dd.SetFinite(int64(l), 0)
  1548  				_, err := HighPrecisionCtx.Rem(&dd.Decimal, &dd.Decimal, r)
  1549  				return dd, err
  1550  			},
  1551  			Volatility: VolatilityImmutable,
  1552  		},
  1553  	},
  1554  
  1555  	Concat: {
  1556  		&BinOp{
  1557  			LeftType:   types.String,
  1558  			RightType:  types.String,
  1559  			ReturnType: types.String,
  1560  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1561  				return NewDString(string(MustBeDString(left) + MustBeDString(right))), nil
  1562  			},
  1563  			Volatility: VolatilityImmutable,
  1564  		},
  1565  		&BinOp{
  1566  			LeftType:   types.Bytes,
  1567  			RightType:  types.Bytes,
  1568  			ReturnType: types.Bytes,
  1569  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1570  				return NewDBytes(*left.(*DBytes) + *right.(*DBytes)), nil
  1571  			},
  1572  			Volatility: VolatilityImmutable,
  1573  		},
  1574  		&BinOp{
  1575  			LeftType:   types.VarBit,
  1576  			RightType:  types.VarBit,
  1577  			ReturnType: types.VarBit,
  1578  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1579  				lhs := MustBeDBitArray(left)
  1580  				rhs := MustBeDBitArray(right)
  1581  				return &DBitArray{
  1582  					BitArray: bitarray.Concat(lhs.BitArray, rhs.BitArray),
  1583  				}, nil
  1584  			},
  1585  			Volatility: VolatilityImmutable,
  1586  		},
  1587  		&BinOp{
  1588  			LeftType:   types.Jsonb,
  1589  			RightType:  types.Jsonb,
  1590  			ReturnType: types.Jsonb,
  1591  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1592  				j, err := MustBeDJSON(left).JSON.Concat(MustBeDJSON(right).JSON)
  1593  				if err != nil {
  1594  					return nil, err
  1595  				}
  1596  				return &DJSON{j}, nil
  1597  			},
  1598  			Volatility: VolatilityImmutable,
  1599  		},
  1600  	},
  1601  
  1602  	// TODO(pmattis): Check that the shift is valid.
  1603  	LShift: {
  1604  		&BinOp{
  1605  			LeftType:   types.Int,
  1606  			RightType:  types.Int,
  1607  			ReturnType: types.Int,
  1608  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1609  				rval := MustBeDInt(right)
  1610  				if rval < 0 || rval >= 64 {
  1611  					telemetry.Inc(sqltelemetry.LargeLShiftArgumentCounter)
  1612  					return nil, pgerror.Newf(pgcode.InvalidParameterValue, "shift argument out of range")
  1613  				}
  1614  				return NewDInt(MustBeDInt(left) << uint(rval)), nil
  1615  			},
  1616  			Volatility: VolatilityImmutable,
  1617  		},
  1618  		&BinOp{
  1619  			LeftType:   types.VarBit,
  1620  			RightType:  types.Int,
  1621  			ReturnType: types.VarBit,
  1622  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1623  				lhs := MustBeDBitArray(left)
  1624  				rhs := MustBeDInt(right)
  1625  				return &DBitArray{
  1626  					BitArray: lhs.BitArray.LeftShiftAny(int64(rhs)),
  1627  				}, nil
  1628  			},
  1629  			Volatility: VolatilityImmutable,
  1630  		},
  1631  		&BinOp{
  1632  			LeftType:   types.INet,
  1633  			RightType:  types.INet,
  1634  			ReturnType: types.Bool,
  1635  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1636  				ipAddr := MustBeDIPAddr(left).IPAddr
  1637  				other := MustBeDIPAddr(right).IPAddr
  1638  				return MakeDBool(DBool(ipAddr.ContainedBy(&other))), nil
  1639  			},
  1640  			Volatility: VolatilityImmutable,
  1641  		},
  1642  	},
  1643  
  1644  	RShift: {
  1645  		&BinOp{
  1646  			LeftType:   types.Int,
  1647  			RightType:  types.Int,
  1648  			ReturnType: types.Int,
  1649  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1650  				rval := MustBeDInt(right)
  1651  				if rval < 0 || rval >= 64 {
  1652  					telemetry.Inc(sqltelemetry.LargeRShiftArgumentCounter)
  1653  					return nil, pgerror.Newf(pgcode.InvalidParameterValue, "shift argument out of range")
  1654  				}
  1655  				return NewDInt(MustBeDInt(left) >> uint(rval)), nil
  1656  			},
  1657  			Volatility: VolatilityImmutable,
  1658  		},
  1659  		&BinOp{
  1660  			LeftType:   types.VarBit,
  1661  			RightType:  types.Int,
  1662  			ReturnType: types.VarBit,
  1663  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1664  				lhs := MustBeDBitArray(left)
  1665  				rhs := MustBeDInt(right)
  1666  				return &DBitArray{
  1667  					BitArray: lhs.BitArray.LeftShiftAny(-int64(rhs)),
  1668  				}, nil
  1669  			},
  1670  			Volatility: VolatilityImmutable,
  1671  		},
  1672  		&BinOp{
  1673  			LeftType:   types.INet,
  1674  			RightType:  types.INet,
  1675  			ReturnType: types.Bool,
  1676  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1677  				ipAddr := MustBeDIPAddr(left).IPAddr
  1678  				other := MustBeDIPAddr(right).IPAddr
  1679  				return MakeDBool(DBool(ipAddr.Contains(&other))), nil
  1680  			},
  1681  			Volatility: VolatilityImmutable,
  1682  		},
  1683  	},
  1684  
  1685  	Pow: {
  1686  		&BinOp{
  1687  			LeftType:   types.Int,
  1688  			RightType:  types.Int,
  1689  			ReturnType: types.Int,
  1690  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1691  				return IntPow(MustBeDInt(left), MustBeDInt(right))
  1692  			},
  1693  			Volatility: VolatilityImmutable,
  1694  		},
  1695  		&BinOp{
  1696  			LeftType:   types.Float,
  1697  			RightType:  types.Float,
  1698  			ReturnType: types.Float,
  1699  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1700  				f := math.Pow(float64(*left.(*DFloat)), float64(*right.(*DFloat)))
  1701  				return NewDFloat(DFloat(f)), nil
  1702  			},
  1703  			Volatility: VolatilityImmutable,
  1704  		},
  1705  		&BinOp{
  1706  			LeftType:   types.Decimal,
  1707  			RightType:  types.Decimal,
  1708  			ReturnType: types.Decimal,
  1709  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1710  				l := &left.(*DDecimal).Decimal
  1711  				r := &right.(*DDecimal).Decimal
  1712  				dd := &DDecimal{}
  1713  				_, err := DecimalCtx.Pow(&dd.Decimal, l, r)
  1714  				return dd, err
  1715  			},
  1716  			Volatility: VolatilityImmutable,
  1717  		},
  1718  		&BinOp{
  1719  			LeftType:   types.Decimal,
  1720  			RightType:  types.Int,
  1721  			ReturnType: types.Decimal,
  1722  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1723  				l := &left.(*DDecimal).Decimal
  1724  				r := MustBeDInt(right)
  1725  				dd := &DDecimal{}
  1726  				dd.SetFinite(int64(r), 0)
  1727  				_, err := DecimalCtx.Pow(&dd.Decimal, l, &dd.Decimal)
  1728  				return dd, err
  1729  			},
  1730  			Volatility: VolatilityImmutable,
  1731  		},
  1732  		&BinOp{
  1733  			LeftType:   types.Int,
  1734  			RightType:  types.Decimal,
  1735  			ReturnType: types.Decimal,
  1736  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1737  				l := MustBeDInt(left)
  1738  				r := &right.(*DDecimal).Decimal
  1739  				dd := &DDecimal{}
  1740  				dd.SetFinite(int64(l), 0)
  1741  				_, err := DecimalCtx.Pow(&dd.Decimal, &dd.Decimal, r)
  1742  				return dd, err
  1743  			},
  1744  			Volatility: VolatilityImmutable,
  1745  		},
  1746  	},
  1747  
  1748  	JSONFetchVal: {
  1749  		&BinOp{
  1750  			LeftType:   types.Jsonb,
  1751  			RightType:  types.String,
  1752  			ReturnType: types.Jsonb,
  1753  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1754  				j, err := left.(*DJSON).JSON.FetchValKey(string(MustBeDString(right)))
  1755  				if err != nil {
  1756  					return nil, err
  1757  				}
  1758  				if j == nil {
  1759  					return DNull, nil
  1760  				}
  1761  				return &DJSON{j}, nil
  1762  			},
  1763  			Volatility: VolatilityImmutable,
  1764  		},
  1765  		&BinOp{
  1766  			LeftType:   types.Jsonb,
  1767  			RightType:  types.Int,
  1768  			ReturnType: types.Jsonb,
  1769  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1770  				j, err := left.(*DJSON).JSON.FetchValIdx(int(MustBeDInt(right)))
  1771  				if err != nil {
  1772  					return nil, err
  1773  				}
  1774  				if j == nil {
  1775  					return DNull, nil
  1776  				}
  1777  				return &DJSON{j}, nil
  1778  			},
  1779  			Volatility: VolatilityImmutable,
  1780  		},
  1781  	},
  1782  
  1783  	JSONFetchValPath: {
  1784  		&BinOp{
  1785  			LeftType:   types.Jsonb,
  1786  			RightType:  types.MakeArray(types.String),
  1787  			ReturnType: types.Jsonb,
  1788  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1789  				return getJSONPath(*left.(*DJSON), *MustBeDArray(right))
  1790  			},
  1791  			Volatility: VolatilityImmutable,
  1792  		},
  1793  	},
  1794  
  1795  	JSONFetchText: {
  1796  		&BinOp{
  1797  			LeftType:   types.Jsonb,
  1798  			RightType:  types.String,
  1799  			ReturnType: types.String,
  1800  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1801  				res, err := left.(*DJSON).JSON.FetchValKey(string(MustBeDString(right)))
  1802  				if err != nil {
  1803  					return nil, err
  1804  				}
  1805  				if res == nil {
  1806  					return DNull, nil
  1807  				}
  1808  				text, err := res.AsText()
  1809  				if err != nil {
  1810  					return nil, err
  1811  				}
  1812  				if text == nil {
  1813  					return DNull, nil
  1814  				}
  1815  				return NewDString(*text), nil
  1816  			},
  1817  			Volatility: VolatilityImmutable,
  1818  		},
  1819  		&BinOp{
  1820  			LeftType:   types.Jsonb,
  1821  			RightType:  types.Int,
  1822  			ReturnType: types.String,
  1823  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1824  				res, err := left.(*DJSON).JSON.FetchValIdx(int(MustBeDInt(right)))
  1825  				if err != nil {
  1826  					return nil, err
  1827  				}
  1828  				if res == nil {
  1829  					return DNull, nil
  1830  				}
  1831  				text, err := res.AsText()
  1832  				if err != nil {
  1833  					return nil, err
  1834  				}
  1835  				if text == nil {
  1836  					return DNull, nil
  1837  				}
  1838  				return NewDString(*text), nil
  1839  			},
  1840  			Volatility: VolatilityImmutable,
  1841  		},
  1842  	},
  1843  
  1844  	JSONFetchTextPath: {
  1845  		&BinOp{
  1846  			LeftType:   types.Jsonb,
  1847  			RightType:  types.MakeArray(types.String),
  1848  			ReturnType: types.String,
  1849  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  1850  				res, err := getJSONPath(*left.(*DJSON), *MustBeDArray(right))
  1851  				if err != nil {
  1852  					return nil, err
  1853  				}
  1854  				if res == DNull {
  1855  					return DNull, nil
  1856  				}
  1857  				text, err := res.(*DJSON).JSON.AsText()
  1858  				if err != nil {
  1859  					return nil, err
  1860  				}
  1861  				if text == nil {
  1862  					return DNull, nil
  1863  				}
  1864  				return NewDString(*text), nil
  1865  			},
  1866  			Volatility: VolatilityImmutable,
  1867  		},
  1868  	},
  1869  }
  1870  
  1871  // timestampMinusBinOp is the implementation of the subtraction
  1872  // between types.TimestampTZ operands.
  1873  var timestampMinusBinOp *BinOp
  1874  
  1875  // TimestampDifference computes the interval difference between two
  1876  // TimestampTZ datums. The result is a DInterval. The caller must
  1877  // ensure that the arguments are of the proper Datum type.
  1878  func TimestampDifference(ctx *EvalContext, start, end Datum) (Datum, error) {
  1879  	return timestampMinusBinOp.Fn(ctx, start, end)
  1880  }
  1881  
  1882  func init() {
  1883  	timestampMinusBinOp, _ = BinOps[Minus].lookupImpl(types.TimestampTZ, types.TimestampTZ)
  1884  }
  1885  
  1886  // CmpOp is a comparison operator.
  1887  type CmpOp struct {
  1888  	LeftType  *types.T
  1889  	RightType *types.T
  1890  
  1891  	// If NullableArgs is false, the operator returns NULL
  1892  	// whenever either argument is NULL.
  1893  	NullableArgs bool
  1894  
  1895  	// Datum return type is a union between *DBool and dNull.
  1896  	Fn func(*EvalContext, Datum, Datum) (Datum, error)
  1897  
  1898  	Volatility Volatility
  1899  
  1900  	types       TypeList
  1901  	isPreferred bool
  1902  
  1903  	// counter, if non-nil, should be incremented every time the
  1904  	// operator is type checked.
  1905  	counter telemetry.Counter
  1906  }
  1907  
  1908  func (op *CmpOp) params() TypeList {
  1909  	return op.types
  1910  }
  1911  
  1912  func (op *CmpOp) matchParams(l, r *types.T) bool {
  1913  	return op.params().MatchAt(l, 0) && op.params().MatchAt(r, 1)
  1914  }
  1915  
  1916  var cmpOpReturnType = FixedReturnType(types.Bool)
  1917  
  1918  func (op *CmpOp) returnType() ReturnTyper {
  1919  	return cmpOpReturnType
  1920  }
  1921  
  1922  func (op *CmpOp) preferred() bool {
  1923  	return op.isPreferred
  1924  }
  1925  
  1926  func cmpOpFixups(cmpOps map[ComparisonOperator]cmpOpOverload) map[ComparisonOperator]cmpOpOverload {
  1927  	findVolatility := func(op ComparisonOperator, t *types.T) Volatility {
  1928  		for _, impl := range cmpOps[EQ] {
  1929  			o := impl.(*CmpOp)
  1930  			if o.LeftType.Equivalent(t) && o.RightType.Equivalent(t) {
  1931  				return o.Volatility
  1932  			}
  1933  		}
  1934  		panic(errors.AssertionFailedf("could not find cmp op %s(%s,%s)", op, t, t))
  1935  	}
  1936  
  1937  	// Array equality comparisons.
  1938  	for _, t := range types.Scalar {
  1939  		cmpOps[EQ] = append(cmpOps[EQ], &CmpOp{
  1940  			LeftType:   types.MakeArray(t),
  1941  			RightType:  types.MakeArray(t),
  1942  			Fn:         cmpOpScalarEQFn,
  1943  			Volatility: findVolatility(EQ, t),
  1944  		})
  1945  		cmpOps[LE] = append(cmpOps[LE], &CmpOp{
  1946  			LeftType:   types.MakeArray(t),
  1947  			RightType:  types.MakeArray(t),
  1948  			Fn:         cmpOpScalarLEFn,
  1949  			Volatility: findVolatility(LE, t),
  1950  		})
  1951  		cmpOps[LT] = append(cmpOps[LT], &CmpOp{
  1952  			LeftType:   types.MakeArray(t),
  1953  			RightType:  types.MakeArray(t),
  1954  			Fn:         cmpOpScalarLTFn,
  1955  			Volatility: findVolatility(LT, t),
  1956  		})
  1957  
  1958  		cmpOps[IsNotDistinctFrom] = append(cmpOps[IsNotDistinctFrom], &CmpOp{
  1959  			LeftType:     types.MakeArray(t),
  1960  			RightType:    types.MakeArray(t),
  1961  			Fn:           cmpOpScalarIsFn,
  1962  			NullableArgs: true,
  1963  			Volatility:   findVolatility(IsNotDistinctFrom, t),
  1964  		})
  1965  	}
  1966  
  1967  	for op, overload := range cmpOps {
  1968  		for i, impl := range overload {
  1969  			casted := impl.(*CmpOp)
  1970  			casted.types = ArgTypes{{"left", casted.LeftType}, {"right", casted.RightType}}
  1971  			cmpOps[op][i] = casted
  1972  		}
  1973  	}
  1974  
  1975  	return cmpOps
  1976  }
  1977  
  1978  // cmpOpOverload is an overloaded set of comparison operator implementations.
  1979  type cmpOpOverload []overloadImpl
  1980  
  1981  func (o cmpOpOverload) LookupImpl(left, right *types.T) (*CmpOp, bool) {
  1982  	for _, fn := range o {
  1983  		casted := fn.(*CmpOp)
  1984  		if casted.matchParams(left, right) {
  1985  			return casted, true
  1986  		}
  1987  	}
  1988  	return nil, false
  1989  }
  1990  
  1991  func makeCmpOpOverload(
  1992  	fn func(ctx *EvalContext, left, right Datum) (Datum, error),
  1993  	a, b *types.T,
  1994  	nullableArgs bool,
  1995  	v Volatility,
  1996  ) *CmpOp {
  1997  	return &CmpOp{
  1998  		LeftType:     a,
  1999  		RightType:    b,
  2000  		Fn:           fn,
  2001  		NullableArgs: nullableArgs,
  2002  		Volatility:   v,
  2003  	}
  2004  }
  2005  
  2006  func makeEqFn(a, b *types.T, v Volatility) *CmpOp {
  2007  	return makeCmpOpOverload(cmpOpScalarEQFn, a, b, false /* NullableArgs */, v)
  2008  }
  2009  func makeLtFn(a, b *types.T, v Volatility) *CmpOp {
  2010  	return makeCmpOpOverload(cmpOpScalarLTFn, a, b, false /* NullableArgs */, v)
  2011  }
  2012  func makeLeFn(a, b *types.T, v Volatility) *CmpOp {
  2013  	return makeCmpOpOverload(cmpOpScalarLEFn, a, b, false /* NullableArgs */, v)
  2014  }
  2015  func makeIsFn(a, b *types.T, v Volatility) *CmpOp {
  2016  	return makeCmpOpOverload(cmpOpScalarIsFn, a, b, true /* NullableArgs */, v)
  2017  }
  2018  
  2019  // CmpOps contains the comparison operations indexed by operation type.
  2020  var CmpOps = cmpOpFixups(map[ComparisonOperator]cmpOpOverload{
  2021  	EQ: {
  2022  		// Single-type comparisons.
  2023  		makeEqFn(types.AnyEnum, types.AnyEnum, VolatilityImmutable),
  2024  		makeEqFn(types.Bool, types.Bool, VolatilityLeakProof),
  2025  		makeEqFn(types.Bytes, types.Bytes, VolatilityLeakProof),
  2026  		makeEqFn(types.Date, types.Date, VolatilityLeakProof),
  2027  		makeEqFn(types.Decimal, types.Decimal, VolatilityImmutable),
  2028  		// Note: it is an error to compare two strings with different collations;
  2029  		// the operator is leak proof under the assumption that these cases will be
  2030  		// detected during type checking.
  2031  		makeEqFn(types.AnyCollatedString, types.AnyCollatedString, VolatilityLeakProof),
  2032  		makeEqFn(types.Float, types.Float, VolatilityLeakProof),
  2033  		makeEqFn(types.Geography, types.Geography, VolatilityLeakProof),
  2034  		makeEqFn(types.Geometry, types.Geometry, VolatilityLeakProof),
  2035  		makeEqFn(types.INet, types.INet, VolatilityLeakProof),
  2036  		makeEqFn(types.Int, types.Int, VolatilityLeakProof),
  2037  		makeEqFn(types.Interval, types.Interval, VolatilityLeakProof),
  2038  		makeEqFn(types.Jsonb, types.Jsonb, VolatilityImmutable),
  2039  		makeEqFn(types.Oid, types.Oid, VolatilityLeakProof),
  2040  		makeEqFn(types.String, types.String, VolatilityLeakProof),
  2041  		makeEqFn(types.Time, types.Time, VolatilityLeakProof),
  2042  		makeEqFn(types.TimeTZ, types.TimeTZ, VolatilityLeakProof),
  2043  		makeEqFn(types.Timestamp, types.Timestamp, VolatilityLeakProof),
  2044  		makeEqFn(types.TimestampTZ, types.TimestampTZ, VolatilityLeakProof),
  2045  		makeEqFn(types.Uuid, types.Uuid, VolatilityLeakProof),
  2046  		makeEqFn(types.VarBit, types.VarBit, VolatilityLeakProof),
  2047  
  2048  		// Mixed-type comparisons.
  2049  		makeEqFn(types.Date, types.Timestamp, VolatilityImmutable),
  2050  		makeEqFn(types.Date, types.TimestampTZ, VolatilityStable),
  2051  		makeEqFn(types.Decimal, types.Float, VolatilityLeakProof),
  2052  		makeEqFn(types.Decimal, types.Int, VolatilityLeakProof),
  2053  		makeEqFn(types.Float, types.Decimal, VolatilityLeakProof),
  2054  		makeEqFn(types.Float, types.Int, VolatilityLeakProof),
  2055  		makeEqFn(types.Int, types.Decimal, VolatilityLeakProof),
  2056  		makeEqFn(types.Int, types.Float, VolatilityLeakProof),
  2057  		makeEqFn(types.Timestamp, types.Date, VolatilityImmutable),
  2058  		makeEqFn(types.Timestamp, types.TimestampTZ, VolatilityStable),
  2059  		makeEqFn(types.TimestampTZ, types.Date, VolatilityStable),
  2060  		makeEqFn(types.TimestampTZ, types.Timestamp, VolatilityStable),
  2061  		makeEqFn(types.Time, types.TimeTZ, VolatilityStable),
  2062  		makeEqFn(types.TimeTZ, types.Time, VolatilityStable),
  2063  
  2064  		// Tuple comparison.
  2065  		&CmpOp{
  2066  			LeftType:  types.AnyTuple,
  2067  			RightType: types.AnyTuple,
  2068  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2069  				return cmpOpTupleFn(ctx, *left.(*DTuple), *right.(*DTuple), EQ), nil
  2070  			},
  2071  			Volatility: VolatilityImmutable,
  2072  		},
  2073  	},
  2074  
  2075  	LT: {
  2076  		// Single-type comparisons.
  2077  		makeLtFn(types.AnyEnum, types.AnyEnum, VolatilityImmutable),
  2078  		makeLtFn(types.Bool, types.Bool, VolatilityLeakProof),
  2079  		makeLtFn(types.Bytes, types.Bytes, VolatilityLeakProof),
  2080  		makeLtFn(types.Date, types.Date, VolatilityLeakProof),
  2081  		makeLtFn(types.Decimal, types.Decimal, VolatilityImmutable),
  2082  		makeLtFn(types.AnyCollatedString, types.AnyCollatedString, VolatilityLeakProof),
  2083  		// Note: it is an error to compare two strings with different collations;
  2084  		// the operator is leak proof under the assumption that these cases will be
  2085  		// detected during type checking.
  2086  		makeLtFn(types.Float, types.Float, VolatilityLeakProof),
  2087  		makeLtFn(types.Geography, types.Geography, VolatilityLeakProof),
  2088  		makeLtFn(types.Geometry, types.Geometry, VolatilityLeakProof),
  2089  		makeLtFn(types.INet, types.INet, VolatilityLeakProof),
  2090  		makeLtFn(types.Int, types.Int, VolatilityLeakProof),
  2091  		makeLtFn(types.Interval, types.Interval, VolatilityLeakProof),
  2092  		makeLtFn(types.Oid, types.Oid, VolatilityLeakProof),
  2093  		makeLtFn(types.String, types.String, VolatilityLeakProof),
  2094  		makeLtFn(types.Time, types.Time, VolatilityLeakProof),
  2095  		makeLtFn(types.TimeTZ, types.TimeTZ, VolatilityLeakProof),
  2096  		makeLtFn(types.Timestamp, types.Timestamp, VolatilityLeakProof),
  2097  		makeLtFn(types.TimestampTZ, types.TimestampTZ, VolatilityLeakProof),
  2098  		makeLtFn(types.Uuid, types.Uuid, VolatilityLeakProof),
  2099  		makeLtFn(types.VarBit, types.VarBit, VolatilityLeakProof),
  2100  
  2101  		// Mixed-type comparisons.
  2102  		makeLtFn(types.Date, types.Timestamp, VolatilityImmutable),
  2103  		makeLtFn(types.Date, types.TimestampTZ, VolatilityStable),
  2104  		makeLtFn(types.Decimal, types.Float, VolatilityLeakProof),
  2105  		makeLtFn(types.Decimal, types.Int, VolatilityLeakProof),
  2106  		makeLtFn(types.Float, types.Decimal, VolatilityLeakProof),
  2107  		makeLtFn(types.Float, types.Int, VolatilityLeakProof),
  2108  		makeLtFn(types.Int, types.Decimal, VolatilityLeakProof),
  2109  		makeLtFn(types.Int, types.Float, VolatilityLeakProof),
  2110  		makeLtFn(types.Timestamp, types.Date, VolatilityImmutable),
  2111  		makeLtFn(types.Timestamp, types.TimestampTZ, VolatilityStable),
  2112  		makeLtFn(types.TimestampTZ, types.Date, VolatilityStable),
  2113  		makeLtFn(types.TimestampTZ, types.Timestamp, VolatilityStable),
  2114  		makeLtFn(types.Time, types.TimeTZ, VolatilityStable),
  2115  		makeLtFn(types.TimeTZ, types.Time, VolatilityStable),
  2116  
  2117  		// Tuple comparison.
  2118  		&CmpOp{
  2119  			LeftType:  types.AnyTuple,
  2120  			RightType: types.AnyTuple,
  2121  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2122  				return cmpOpTupleFn(ctx, *left.(*DTuple), *right.(*DTuple), LT), nil
  2123  			},
  2124  			Volatility: VolatilityImmutable,
  2125  		},
  2126  	},
  2127  
  2128  	LE: {
  2129  		// Single-type comparisons.
  2130  		makeLeFn(types.AnyEnum, types.AnyEnum, VolatilityImmutable),
  2131  		makeLeFn(types.Bool, types.Bool, VolatilityLeakProof),
  2132  		makeLeFn(types.Bytes, types.Bytes, VolatilityLeakProof),
  2133  		makeLeFn(types.Date, types.Date, VolatilityLeakProof),
  2134  		makeLeFn(types.Decimal, types.Decimal, VolatilityImmutable),
  2135  		// Note: it is an error to compare two strings with different collations;
  2136  		// the operator is leak proof under the assumption that these cases will be
  2137  		// detected during type checking.
  2138  		makeLeFn(types.AnyCollatedString, types.AnyCollatedString, VolatilityLeakProof),
  2139  		makeLeFn(types.Float, types.Float, VolatilityLeakProof),
  2140  		makeLeFn(types.Geography, types.Geography, VolatilityLeakProof),
  2141  		makeLeFn(types.Geometry, types.Geometry, VolatilityLeakProof),
  2142  		makeLeFn(types.INet, types.INet, VolatilityLeakProof),
  2143  		makeLeFn(types.Int, types.Int, VolatilityLeakProof),
  2144  		makeLeFn(types.Interval, types.Interval, VolatilityLeakProof),
  2145  		makeLeFn(types.Oid, types.Oid, VolatilityLeakProof),
  2146  		makeLeFn(types.String, types.String, VolatilityLeakProof),
  2147  		makeLeFn(types.Time, types.Time, VolatilityLeakProof),
  2148  		makeLeFn(types.TimeTZ, types.TimeTZ, VolatilityLeakProof),
  2149  		makeLeFn(types.Timestamp, types.Timestamp, VolatilityLeakProof),
  2150  		makeLeFn(types.TimestampTZ, types.TimestampTZ, VolatilityLeakProof),
  2151  		makeLeFn(types.Uuid, types.Uuid, VolatilityLeakProof),
  2152  		makeLeFn(types.VarBit, types.VarBit, VolatilityLeakProof),
  2153  
  2154  		// Mixed-type comparisons.
  2155  		makeLeFn(types.Date, types.Timestamp, VolatilityImmutable),
  2156  		makeLeFn(types.Date, types.TimestampTZ, VolatilityStable),
  2157  		makeLeFn(types.Decimal, types.Float, VolatilityLeakProof),
  2158  		makeLeFn(types.Decimal, types.Int, VolatilityLeakProof),
  2159  		makeLeFn(types.Float, types.Decimal, VolatilityLeakProof),
  2160  		makeLeFn(types.Float, types.Int, VolatilityLeakProof),
  2161  		makeLeFn(types.Int, types.Decimal, VolatilityLeakProof),
  2162  		makeLeFn(types.Int, types.Float, VolatilityLeakProof),
  2163  		makeLeFn(types.Timestamp, types.Date, VolatilityImmutable),
  2164  		makeLeFn(types.Timestamp, types.TimestampTZ, VolatilityStable),
  2165  		makeLeFn(types.TimestampTZ, types.Date, VolatilityStable),
  2166  		makeLeFn(types.TimestampTZ, types.Timestamp, VolatilityStable),
  2167  		makeLeFn(types.Time, types.TimeTZ, VolatilityStable),
  2168  		makeLeFn(types.TimeTZ, types.Time, VolatilityStable),
  2169  
  2170  		// Tuple comparison.
  2171  		&CmpOp{
  2172  			LeftType:  types.AnyTuple,
  2173  			RightType: types.AnyTuple,
  2174  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2175  				return cmpOpTupleFn(ctx, *left.(*DTuple), *right.(*DTuple), LE), nil
  2176  			},
  2177  			Volatility: VolatilityImmutable,
  2178  		},
  2179  	},
  2180  
  2181  	IsNotDistinctFrom: {
  2182  		&CmpOp{
  2183  			LeftType:     types.Unknown,
  2184  			RightType:    types.Unknown,
  2185  			Fn:           cmpOpScalarIsFn,
  2186  			NullableArgs: true,
  2187  			// Avoids ambiguous comparison error for NULL IS NOT DISTINCT FROM NULL>
  2188  			isPreferred: true,
  2189  			Volatility:  VolatilityLeakProof,
  2190  		},
  2191  		// Single-type comparisons.
  2192  		makeIsFn(types.AnyEnum, types.AnyEnum, VolatilityImmutable),
  2193  		makeIsFn(types.Bool, types.Bool, VolatilityLeakProof),
  2194  		makeIsFn(types.Bytes, types.Bytes, VolatilityLeakProof),
  2195  		makeIsFn(types.Date, types.Date, VolatilityLeakProof),
  2196  		makeIsFn(types.Decimal, types.Decimal, VolatilityImmutable),
  2197  		// Note: it is an error to compare two strings with different collations;
  2198  		// the operator is leak proof under the assumption that these cases will be
  2199  		// detected during type checking.
  2200  		makeIsFn(types.AnyCollatedString, types.AnyCollatedString, VolatilityLeakProof),
  2201  		makeIsFn(types.Float, types.Float, VolatilityLeakProof),
  2202  		makeIsFn(types.Geography, types.Geography, VolatilityLeakProof),
  2203  		makeIsFn(types.Geometry, types.Geometry, VolatilityLeakProof),
  2204  		makeIsFn(types.INet, types.INet, VolatilityLeakProof),
  2205  		makeIsFn(types.Int, types.Int, VolatilityLeakProof),
  2206  		makeIsFn(types.Interval, types.Interval, VolatilityLeakProof),
  2207  		makeIsFn(types.Jsonb, types.Jsonb, VolatilityImmutable),
  2208  		makeIsFn(types.Oid, types.Oid, VolatilityLeakProof),
  2209  		makeIsFn(types.String, types.String, VolatilityLeakProof),
  2210  		makeIsFn(types.Time, types.Time, VolatilityLeakProof),
  2211  		makeIsFn(types.TimeTZ, types.TimeTZ, VolatilityLeakProof),
  2212  		makeIsFn(types.Timestamp, types.Timestamp, VolatilityLeakProof),
  2213  		makeIsFn(types.TimestampTZ, types.TimestampTZ, VolatilityLeakProof),
  2214  		makeIsFn(types.Uuid, types.Uuid, VolatilityLeakProof),
  2215  		makeIsFn(types.VarBit, types.VarBit, VolatilityLeakProof),
  2216  
  2217  		// Mixed-type comparisons.
  2218  		makeIsFn(types.Date, types.Timestamp, VolatilityImmutable),
  2219  		makeIsFn(types.Date, types.TimestampTZ, VolatilityStable),
  2220  		makeIsFn(types.Decimal, types.Float, VolatilityLeakProof),
  2221  		makeIsFn(types.Decimal, types.Int, VolatilityLeakProof),
  2222  		makeIsFn(types.Float, types.Decimal, VolatilityLeakProof),
  2223  		makeIsFn(types.Float, types.Int, VolatilityLeakProof),
  2224  		makeIsFn(types.Int, types.Decimal, VolatilityLeakProof),
  2225  		makeIsFn(types.Int, types.Float, VolatilityLeakProof),
  2226  		makeIsFn(types.Timestamp, types.Date, VolatilityImmutable),
  2227  		makeIsFn(types.Timestamp, types.TimestampTZ, VolatilityStable),
  2228  		makeIsFn(types.TimestampTZ, types.Date, VolatilityStable),
  2229  		makeIsFn(types.TimestampTZ, types.Timestamp, VolatilityStable),
  2230  		makeIsFn(types.Time, types.TimeTZ, VolatilityStable),
  2231  		makeIsFn(types.TimeTZ, types.Time, VolatilityStable),
  2232  
  2233  		// Tuple comparison.
  2234  		&CmpOp{
  2235  			LeftType:     types.AnyTuple,
  2236  			RightType:    types.AnyTuple,
  2237  			NullableArgs: true,
  2238  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2239  				if left == DNull || right == DNull {
  2240  					return MakeDBool(left == DNull && right == DNull), nil
  2241  				}
  2242  				return cmpOpTupleFn(ctx, *left.(*DTuple), *right.(*DTuple), IsNotDistinctFrom), nil
  2243  			},
  2244  			Volatility: VolatilityImmutable,
  2245  		},
  2246  	},
  2247  
  2248  	In: {
  2249  		makeEvalTupleIn(types.AnyEnum, VolatilityLeakProof),
  2250  		makeEvalTupleIn(types.Bool, VolatilityLeakProof),
  2251  		makeEvalTupleIn(types.Bytes, VolatilityLeakProof),
  2252  		makeEvalTupleIn(types.Date, VolatilityLeakProof),
  2253  		makeEvalTupleIn(types.Decimal, VolatilityLeakProof),
  2254  		makeEvalTupleIn(types.AnyCollatedString, VolatilityLeakProof),
  2255  		makeEvalTupleIn(types.AnyTuple, VolatilityLeakProof),
  2256  		makeEvalTupleIn(types.Float, VolatilityLeakProof),
  2257  		makeEvalTupleIn(types.Geography, VolatilityLeakProof),
  2258  		makeEvalTupleIn(types.Geometry, VolatilityLeakProof),
  2259  		makeEvalTupleIn(types.INet, VolatilityLeakProof),
  2260  		makeEvalTupleIn(types.Int, VolatilityLeakProof),
  2261  		makeEvalTupleIn(types.Interval, VolatilityLeakProof),
  2262  		makeEvalTupleIn(types.Jsonb, VolatilityLeakProof),
  2263  		makeEvalTupleIn(types.Oid, VolatilityLeakProof),
  2264  		makeEvalTupleIn(types.String, VolatilityLeakProof),
  2265  		makeEvalTupleIn(types.Time, VolatilityLeakProof),
  2266  		makeEvalTupleIn(types.TimeTZ, VolatilityLeakProof),
  2267  		makeEvalTupleIn(types.Timestamp, VolatilityLeakProof),
  2268  		makeEvalTupleIn(types.TimestampTZ, VolatilityLeakProof),
  2269  		makeEvalTupleIn(types.Uuid, VolatilityLeakProof),
  2270  		makeEvalTupleIn(types.VarBit, VolatilityLeakProof),
  2271  	},
  2272  
  2273  	Like: {
  2274  		&CmpOp{
  2275  			LeftType:  types.String,
  2276  			RightType: types.String,
  2277  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2278  				return matchLike(ctx, left, right, false)
  2279  			},
  2280  			Volatility: VolatilityLeakProof,
  2281  		},
  2282  	},
  2283  
  2284  	ILike: {
  2285  		&CmpOp{
  2286  			LeftType:  types.String,
  2287  			RightType: types.String,
  2288  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2289  				return matchLike(ctx, left, right, true)
  2290  			},
  2291  			Volatility: VolatilityLeakProof,
  2292  		},
  2293  	},
  2294  
  2295  	SimilarTo: {
  2296  		&CmpOp{
  2297  			LeftType:  types.String,
  2298  			RightType: types.String,
  2299  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2300  				key := similarToKey{s: string(MustBeDString(right)), escape: '\\'}
  2301  				return matchRegexpWithKey(ctx, left, key)
  2302  			},
  2303  			Volatility: VolatilityLeakProof,
  2304  		},
  2305  	},
  2306  
  2307  	RegMatch: {
  2308  		&CmpOp{
  2309  			LeftType:  types.String,
  2310  			RightType: types.String,
  2311  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2312  				key := regexpKey{s: string(MustBeDString(right)), caseInsensitive: false}
  2313  				return matchRegexpWithKey(ctx, left, key)
  2314  			},
  2315  			Volatility: VolatilityImmutable,
  2316  		},
  2317  	},
  2318  
  2319  	RegIMatch: {
  2320  		&CmpOp{
  2321  			LeftType:  types.String,
  2322  			RightType: types.String,
  2323  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2324  				key := regexpKey{s: string(MustBeDString(right)), caseInsensitive: true}
  2325  				return matchRegexpWithKey(ctx, left, key)
  2326  			},
  2327  			Volatility: VolatilityImmutable,
  2328  		},
  2329  	},
  2330  
  2331  	JSONExists: {
  2332  		&CmpOp{
  2333  			LeftType:  types.Jsonb,
  2334  			RightType: types.String,
  2335  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  2336  				e, err := left.(*DJSON).JSON.Exists(string(MustBeDString(right)))
  2337  				if err != nil {
  2338  					return nil, err
  2339  				}
  2340  				if e {
  2341  					return DBoolTrue, nil
  2342  				}
  2343  				return DBoolFalse, nil
  2344  			},
  2345  			Volatility: VolatilityImmutable,
  2346  		},
  2347  	},
  2348  
  2349  	JSONSomeExists: {
  2350  		&CmpOp{
  2351  			LeftType:  types.Jsonb,
  2352  			RightType: types.StringArray,
  2353  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  2354  				// TODO(justin): this can be optimized.
  2355  				for _, k := range MustBeDArray(right).Array {
  2356  					if k == DNull {
  2357  						continue
  2358  					}
  2359  					e, err := left.(*DJSON).JSON.Exists(string(MustBeDString(k)))
  2360  					if err != nil {
  2361  						return nil, err
  2362  					}
  2363  					if e {
  2364  						return DBoolTrue, nil
  2365  					}
  2366  				}
  2367  				return DBoolFalse, nil
  2368  			},
  2369  			Volatility: VolatilityImmutable,
  2370  		},
  2371  	},
  2372  
  2373  	JSONAllExists: {
  2374  		&CmpOp{
  2375  			LeftType:  types.Jsonb,
  2376  			RightType: types.StringArray,
  2377  			Fn: func(_ *EvalContext, left Datum, right Datum) (Datum, error) {
  2378  				// TODO(justin): this can be optimized.
  2379  				for _, k := range MustBeDArray(right).Array {
  2380  					if k == DNull {
  2381  						continue
  2382  					}
  2383  					e, err := left.(*DJSON).JSON.Exists(string(MustBeDString(k)))
  2384  					if err != nil {
  2385  						return nil, err
  2386  					}
  2387  					if !e {
  2388  						return DBoolFalse, nil
  2389  					}
  2390  				}
  2391  				return DBoolTrue, nil
  2392  			},
  2393  			Volatility: VolatilityImmutable,
  2394  		},
  2395  	},
  2396  
  2397  	Contains: {
  2398  		&CmpOp{
  2399  			LeftType:  types.AnyArray,
  2400  			RightType: types.AnyArray,
  2401  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2402  				haystack := MustBeDArray(left)
  2403  				needles := MustBeDArray(right)
  2404  				return ArrayContains(ctx, haystack, needles)
  2405  			},
  2406  			Volatility: VolatilityImmutable,
  2407  		},
  2408  		&CmpOp{
  2409  			LeftType:  types.Jsonb,
  2410  			RightType: types.Jsonb,
  2411  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2412  				c, err := json.Contains(left.(*DJSON).JSON, right.(*DJSON).JSON)
  2413  				if err != nil {
  2414  					return nil, err
  2415  				}
  2416  				return MakeDBool(DBool(c)), nil
  2417  			},
  2418  			Volatility: VolatilityImmutable,
  2419  		},
  2420  	},
  2421  
  2422  	ContainedBy: {
  2423  		&CmpOp{
  2424  			LeftType:  types.AnyArray,
  2425  			RightType: types.AnyArray,
  2426  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2427  				needles := MustBeDArray(left)
  2428  				haystack := MustBeDArray(right)
  2429  				return ArrayContains(ctx, haystack, needles)
  2430  			},
  2431  			Volatility: VolatilityImmutable,
  2432  		},
  2433  		&CmpOp{
  2434  			LeftType:  types.Jsonb,
  2435  			RightType: types.Jsonb,
  2436  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2437  				c, err := json.Contains(right.(*DJSON).JSON, left.(*DJSON).JSON)
  2438  				if err != nil {
  2439  					return nil, err
  2440  				}
  2441  				return MakeDBool(DBool(c)), nil
  2442  			},
  2443  			Volatility: VolatilityImmutable,
  2444  		},
  2445  	},
  2446  	Overlaps: {
  2447  		&CmpOp{
  2448  			LeftType:  types.AnyArray,
  2449  			RightType: types.AnyArray,
  2450  			Fn: func(ctx *EvalContext, left Datum, right Datum) (Datum, error) {
  2451  				array := MustBeDArray(left)
  2452  				other := MustBeDArray(right)
  2453  				if !array.ParamTyp.Equivalent(other.ParamTyp) {
  2454  					return nil, pgerror.New(pgcode.DatatypeMismatch, "cannot compare arrays with different element types")
  2455  				}
  2456  				for _, needle := range array.Array {
  2457  					// Nulls don't compare to each other in && syntax.
  2458  					if needle == DNull {
  2459  						continue
  2460  					}
  2461  					for _, hay := range other.Array {
  2462  						if needle.Compare(ctx, hay) == 0 {
  2463  							return DBoolTrue, nil
  2464  						}
  2465  					}
  2466  				}
  2467  				return DBoolFalse, nil
  2468  			},
  2469  			Volatility: VolatilityImmutable,
  2470  		},
  2471  		&CmpOp{
  2472  			LeftType:  types.INet,
  2473  			RightType: types.INet,
  2474  			Fn: func(_ *EvalContext, left, right Datum) (Datum, error) {
  2475  				ipAddr := MustBeDIPAddr(left).IPAddr
  2476  				other := MustBeDIPAddr(right).IPAddr
  2477  				return MakeDBool(DBool(ipAddr.ContainsOrContainedBy(&other))), nil
  2478  			},
  2479  			Volatility: VolatilityImmutable,
  2480  		},
  2481  	},
  2482  })
  2483  
  2484  // This map contains the inverses for operators in the CmpOps map that have
  2485  // inverses.
  2486  var cmpOpsInverse map[ComparisonOperator]ComparisonOperator
  2487  
  2488  func init() {
  2489  	cmpOpsInverse = make(map[ComparisonOperator]ComparisonOperator)
  2490  	for cmpOpIdx := range comparisonOpName {
  2491  		cmpOp := ComparisonOperator(cmpOpIdx)
  2492  		newOp, _, _, _, _ := foldComparisonExpr(cmpOp, DNull, DNull)
  2493  		if newOp != cmpOp {
  2494  			cmpOpsInverse[newOp] = cmpOp
  2495  			cmpOpsInverse[cmpOp] = newOp
  2496  		}
  2497  	}
  2498  }
  2499  
  2500  func boolFromCmp(cmp int, op ComparisonOperator) *DBool {
  2501  	switch op {
  2502  	case EQ, IsNotDistinctFrom:
  2503  		return MakeDBool(cmp == 0)
  2504  	case LT:
  2505  		return MakeDBool(cmp < 0)
  2506  	case LE:
  2507  		return MakeDBool(cmp <= 0)
  2508  	default:
  2509  		panic(errors.AssertionFailedf("unexpected ComparisonOperator in boolFromCmp: %v", errors.Safe(op)))
  2510  	}
  2511  }
  2512  
  2513  func cmpOpScalarFn(ctx *EvalContext, left, right Datum, op ComparisonOperator) Datum {
  2514  	// Before deferring to the Datum.Compare method, check for values that should
  2515  	// be handled differently during SQL comparison evaluation than they should when
  2516  	// ordering Datum values.
  2517  	if left == DNull || right == DNull {
  2518  		switch op {
  2519  		case IsNotDistinctFrom:
  2520  			return MakeDBool((left == DNull) == (right == DNull))
  2521  
  2522  		default:
  2523  			// If either Datum is NULL, the result of the comparison is NULL.
  2524  			return DNull
  2525  		}
  2526  	}
  2527  	cmp := left.Compare(ctx, right)
  2528  	return boolFromCmp(cmp, op)
  2529  }
  2530  
  2531  func cmpOpScalarEQFn(ctx *EvalContext, left, right Datum) (Datum, error) {
  2532  	return cmpOpScalarFn(ctx, left, right, EQ), nil
  2533  }
  2534  func cmpOpScalarLTFn(ctx *EvalContext, left, right Datum) (Datum, error) {
  2535  	return cmpOpScalarFn(ctx, left, right, LT), nil
  2536  }
  2537  func cmpOpScalarLEFn(ctx *EvalContext, left, right Datum) (Datum, error) {
  2538  	return cmpOpScalarFn(ctx, left, right, LE), nil
  2539  }
  2540  func cmpOpScalarIsFn(ctx *EvalContext, left, right Datum) (Datum, error) {
  2541  	return cmpOpScalarFn(ctx, left, right, IsNotDistinctFrom), nil
  2542  }
  2543  
  2544  func cmpOpTupleFn(ctx *EvalContext, left, right DTuple, op ComparisonOperator) Datum {
  2545  	cmp := 0
  2546  	sawNull := false
  2547  	for i, leftElem := range left.D {
  2548  		rightElem := right.D[i]
  2549  		// Like with cmpOpScalarFn, check for values that need to be handled
  2550  		// differently than when ordering Datums.
  2551  		if leftElem == DNull || rightElem == DNull {
  2552  			switch op {
  2553  			case EQ:
  2554  				// If either Datum is NULL and the op is EQ, we continue the
  2555  				// comparison and the result is only NULL if the other (non-NULL)
  2556  				// elements are equal. This is because NULL is thought of as "unknown",
  2557  				// so a NULL equality comparison does not prevent the equality from
  2558  				// being proven false, but does prevent it from being proven true.
  2559  				sawNull = true
  2560  
  2561  			case IsNotDistinctFrom:
  2562  				// For IS NOT DISTINCT FROM, NULLs are "equal".
  2563  				if leftElem != DNull || rightElem != DNull {
  2564  					return DBoolFalse
  2565  				}
  2566  
  2567  			default:
  2568  				// If either Datum is NULL and the op is not EQ or IS NOT DISTINCT FROM,
  2569  				// we short-circuit the evaluation and the result of the comparison is
  2570  				// NULL. This is because NULL is thought of as "unknown" and tuple
  2571  				// inequality is defined lexicographically, so once a NULL comparison is
  2572  				// seen, the result of the entire tuple comparison is unknown.
  2573  				return DNull
  2574  			}
  2575  		} else {
  2576  			cmp = leftElem.Compare(ctx, rightElem)
  2577  			if cmp != 0 {
  2578  				break
  2579  			}
  2580  		}
  2581  	}
  2582  	b := boolFromCmp(cmp, op)
  2583  	if b == DBoolTrue && sawNull {
  2584  		// The op is EQ and all non-NULL elements are equal, but we saw at least
  2585  		// one NULL element. Since NULL comparisons are treated as unknown, the
  2586  		// result of the comparison becomes unknown (NULL).
  2587  		return DNull
  2588  	}
  2589  	return b
  2590  }
  2591  
  2592  func makeEvalTupleIn(typ *types.T, v Volatility) *CmpOp {
  2593  	return &CmpOp{
  2594  		LeftType:  typ,
  2595  		RightType: types.AnyTuple,
  2596  		Fn: func(ctx *EvalContext, arg, values Datum) (Datum, error) {
  2597  			vtuple := values.(*DTuple)
  2598  			// If the tuple was sorted during normalization, we can perform an
  2599  			// efficient binary search to find if the arg is in the tuple (as
  2600  			// long as the arg doesn't contain any NULLs).
  2601  			if len(vtuple.D) == 0 {
  2602  				// If the rhs tuple is empty, the result is always false (even if arg is
  2603  				// or contains NULL).
  2604  				return DBoolFalse, nil
  2605  			}
  2606  			if arg == DNull {
  2607  				return DNull, nil
  2608  			}
  2609  			argTuple, argIsTuple := arg.(*DTuple)
  2610  			if vtuple.Sorted() && !(argIsTuple && argTuple.ContainsNull()) {
  2611  				// The right-hand tuple is already sorted and contains no NULLs, and the
  2612  				// left side is not NULL (e.g. `NULL IN (1, 2)`) or a tuple that
  2613  				// contains NULL (e.g. `(1, NULL) IN ((1, 2), (3, 4))`).
  2614  				//
  2615  				// We can use binary search to make a determination in this case. This
  2616  				// is the common case when tuples don't contain NULLs.
  2617  				_, result := vtuple.SearchSorted(ctx, arg)
  2618  				return MakeDBool(DBool(result)), nil
  2619  			}
  2620  
  2621  			sawNull := false
  2622  			if !argIsTuple {
  2623  				// The left-hand side is not a tuple, e.g. `1 IN (1, 2)`.
  2624  				for _, val := range vtuple.D {
  2625  					if val == DNull {
  2626  						sawNull = true
  2627  					} else if val.Compare(ctx, arg) == 0 {
  2628  						return DBoolTrue, nil
  2629  					}
  2630  				}
  2631  			} else {
  2632  				// The left-hand side is a tuple, e.g. `(1, 2) IN ((1, 2), (3, 4))`.
  2633  				for _, val := range vtuple.D {
  2634  					if val == DNull {
  2635  						// We allow for a null value to be in the list of tuples, so we
  2636  						// need to check that upfront.
  2637  						sawNull = true
  2638  					} else {
  2639  						// Use the EQ function which properly handles NULLs.
  2640  						if res := cmpOpTupleFn(ctx, *argTuple, *val.(*DTuple), EQ); res == DNull {
  2641  							sawNull = true
  2642  						} else if res == DBoolTrue {
  2643  							return DBoolTrue, nil
  2644  						}
  2645  					}
  2646  				}
  2647  			}
  2648  			if sawNull {
  2649  				return DNull, nil
  2650  			}
  2651  			return DBoolFalse, nil
  2652  		},
  2653  		NullableArgs: true,
  2654  		Volatility:   v,
  2655  	}
  2656  }
  2657  
  2658  // evalDatumsCmp evaluates Datums (slice of Datum) using the provided
  2659  // sub-operator type (ANY/SOME, ALL) and its CmpOp with the left Datum.
  2660  // It returns the result of the ANY/SOME/ALL predicate.
  2661  //
  2662  // A NULL result is returned if there exists a NULL element and:
  2663  //   ANY/SOME: no comparisons evaluate to true
  2664  //   ALL: no comparisons evaluate to false
  2665  //
  2666  // For example, given 1 < ANY (SELECT * FROM generate_series(1,3))
  2667  // (right is a DTuple), evalTupleCmp would be called with:
  2668  //   evalDatumsCmp(ctx, LT, Any, CmpOp(LT, leftType, rightParamType), leftDatum, rightTuple.D).
  2669  // Similarly, given 1 < ANY (ARRAY[1, 2, 3]) (right is a DArray),
  2670  // evalArrayCmp would be called with:
  2671  //   evalDatumsCmp(ctx, LT, Any, CmpOp(LT, leftType, rightParamType), leftDatum, rightArray.Array).
  2672  func evalDatumsCmp(
  2673  	ctx *EvalContext, op, subOp ComparisonOperator, fn *CmpOp, left Datum, right Datums,
  2674  ) (Datum, error) {
  2675  	all := op == All
  2676  	any := !all
  2677  	sawNull := false
  2678  	for _, elem := range right {
  2679  		if elem == DNull {
  2680  			sawNull = true
  2681  			continue
  2682  		}
  2683  
  2684  		_, newLeft, newRight, _, not := foldComparisonExpr(subOp, left, elem)
  2685  		d, err := fn.Fn(ctx, newLeft.(Datum), newRight.(Datum))
  2686  		if err != nil {
  2687  			return nil, err
  2688  		}
  2689  		if d == DNull {
  2690  			sawNull = true
  2691  			continue
  2692  		}
  2693  
  2694  		b := d.(*DBool)
  2695  		res := *b != DBool(not)
  2696  		if any && res {
  2697  			return DBoolTrue, nil
  2698  		} else if all && !res {
  2699  			return DBoolFalse, nil
  2700  		}
  2701  	}
  2702  
  2703  	if sawNull {
  2704  		// If the right-hand array contains any null elements and no [false,true]
  2705  		// comparison result is obtained, the result of [ALL,ANY] will be null.
  2706  		return DNull, nil
  2707  	}
  2708  
  2709  	if all {
  2710  		// ALL are true && !sawNull
  2711  		return DBoolTrue, nil
  2712  	}
  2713  	// ANY is false && !sawNull
  2714  	return DBoolFalse, nil
  2715  }
  2716  
  2717  // MatchLikeEscape matches 'unescaped' with 'pattern' using custom escape character 'escape' which
  2718  // must be either empty (which disables the escape mechanism) or a single unicode character.
  2719  func MatchLikeEscape(
  2720  	ctx *EvalContext, unescaped, pattern, escape string, caseInsensitive bool,
  2721  ) (Datum, error) {
  2722  	var escapeRune rune
  2723  	if len(escape) > 0 {
  2724  		var width int
  2725  		escapeRune, width = utf8.DecodeRuneInString(escape)
  2726  		if len(escape) > width {
  2727  			return DBoolFalse, pgerror.Newf(pgcode.InvalidEscapeSequence, "invalid escape string")
  2728  		}
  2729  	}
  2730  
  2731  	if len(unescaped) == 0 {
  2732  		// An empty string only matches with an empty pattern or a pattern
  2733  		// consisting only of '%' (if this wildcard is not used as a custom escape
  2734  		// character). To match PostgreSQL's behavior, we have a special handling
  2735  		// of this case.
  2736  		for _, c := range pattern {
  2737  			if c != '%' || (c == '%' && escape == `%`) {
  2738  				return DBoolFalse, nil
  2739  			}
  2740  		}
  2741  		return DBoolTrue, nil
  2742  	}
  2743  
  2744  	like, err := optimizedLikeFunc(pattern, caseInsensitive, escapeRune)
  2745  	if err != nil {
  2746  		return DBoolFalse, pgerror.Newf(
  2747  			pgcode.InvalidRegularExpression, "LIKE regexp compilation failed: %v", err)
  2748  	}
  2749  
  2750  	if like == nil {
  2751  		re, err := ConvertLikeToRegexp(ctx, pattern, caseInsensitive, escapeRune)
  2752  		if err != nil {
  2753  			return DBoolFalse, err
  2754  		}
  2755  		like = func(s string) (bool, error) {
  2756  			return re.MatchString(s), nil
  2757  		}
  2758  	}
  2759  	matches, err := like(unescaped)
  2760  	return MakeDBool(DBool(matches)), err
  2761  }
  2762  
  2763  // ConvertLikeToRegexp compiles the specified LIKE pattern as an equivalent
  2764  // regular expression.
  2765  func ConvertLikeToRegexp(
  2766  	ctx *EvalContext, pattern string, caseInsensitive bool, escape rune,
  2767  ) (*regexp.Regexp, error) {
  2768  	key := likeKey{s: pattern, caseInsensitive: caseInsensitive, escape: escape}
  2769  	re, err := ctx.ReCache.GetRegexp(key)
  2770  	if err != nil {
  2771  		return nil, pgerror.Newf(
  2772  			pgcode.InvalidRegularExpression, "LIKE regexp compilation failed: %v", err)
  2773  	}
  2774  	return re, nil
  2775  }
  2776  
  2777  func matchLike(ctx *EvalContext, left, right Datum, caseInsensitive bool) (Datum, error) {
  2778  	if left == DNull || right == DNull {
  2779  		return DNull, nil
  2780  	}
  2781  	s, pattern := string(MustBeDString(left)), string(MustBeDString(right))
  2782  	if len(s) == 0 {
  2783  		// An empty string only matches with an empty pattern or a pattern
  2784  		// consisting only of '%'. To match PostgreSQL's behavior, we have a
  2785  		// special handling of this case.
  2786  		for _, c := range pattern {
  2787  			if c != '%' {
  2788  				return DBoolFalse, nil
  2789  			}
  2790  		}
  2791  		return DBoolTrue, nil
  2792  	}
  2793  
  2794  	like, err := optimizedLikeFunc(pattern, caseInsensitive, '\\')
  2795  	if err != nil {
  2796  		return DBoolFalse, pgerror.Newf(
  2797  			pgcode.InvalidRegularExpression, "LIKE regexp compilation failed: %v", err)
  2798  	}
  2799  
  2800  	if like == nil {
  2801  		re, err := ConvertLikeToRegexp(ctx, pattern, caseInsensitive, '\\')
  2802  		if err != nil {
  2803  			return DBoolFalse, err
  2804  		}
  2805  		like = func(s string) (bool, error) {
  2806  			return re.MatchString(s), nil
  2807  		}
  2808  	}
  2809  	matches, err := like(s)
  2810  	return MakeDBool(DBool(matches)), err
  2811  }
  2812  
  2813  func matchRegexpWithKey(ctx *EvalContext, str Datum, key RegexpCacheKey) (Datum, error) {
  2814  	re, err := ctx.ReCache.GetRegexp(key)
  2815  	if err != nil {
  2816  		return DBoolFalse, err
  2817  	}
  2818  	return MakeDBool(DBool(re.MatchString(string(MustBeDString(str))))), nil
  2819  }
  2820  
  2821  // MultipleResultsError is returned by QueryRow when more than one result is
  2822  // encountered.
  2823  type MultipleResultsError struct {
  2824  	SQL string // the query that produced this error
  2825  }
  2826  
  2827  func (e *MultipleResultsError) Error() string {
  2828  	return fmt.Sprintf("%s: unexpected multiple results", e.SQL)
  2829  }
  2830  
  2831  // EvalDatabase consists of functions that reference the session database
  2832  // and is to be used from EvalContext.
  2833  type EvalDatabase interface {
  2834  	// ParseQualifiedTableName parses a SQL string of the form
  2835  	// `[ database_name . ] [ schema_name . ] table_name`.
  2836  	// NB: this is deprecated! Use parser.ParseQualifiedTableName when possible.
  2837  	ParseQualifiedTableName(sql string) (*TableName, error)
  2838  
  2839  	// ResolveTableName expands the given table name and
  2840  	// makes it point to a valid object.
  2841  	// If the database name is not given, it uses the search path to find it, and
  2842  	// sets it on the returned TableName.
  2843  	// It returns the ID of the resolved table, and an error if the table doesn't exist.
  2844  	ResolveTableName(ctx context.Context, tn *TableName) (ID, error)
  2845  
  2846  	// LookupSchema looks up the schema with the given name in the given
  2847  	// database.
  2848  	LookupSchema(ctx context.Context, dbName, scName string) (found bool, scMeta SchemaMeta, err error)
  2849  }
  2850  
  2851  // EvalPlanner is a limited planner that can be used from EvalContext.
  2852  type EvalPlanner interface {
  2853  	EvalDatabase
  2854  	// ParseType parses a column type.
  2855  	ParseType(sql string) (*types.T, error)
  2856  
  2857  	// EvalSubquery returns the Datum for the given subquery node.
  2858  	EvalSubquery(expr *Subquery) (Datum, error)
  2859  }
  2860  
  2861  // EvalSessionAccessor is a limited interface to access session variables.
  2862  type EvalSessionAccessor interface {
  2863  	// SetConfig sets a session variable to a new value.
  2864  	//
  2865  	// This interface only supports strings as this is sufficient for
  2866  	// pg_catalog.set_config().
  2867  	SetSessionVar(ctx context.Context, settingName, newValue string) error
  2868  
  2869  	// GetSessionVar retrieves the current value of a session variable.
  2870  	GetSessionVar(ctx context.Context, settingName string, missingOk bool) (bool, string, error)
  2871  
  2872  	// HasAdminRole returns true iff the current session user has the admin role.
  2873  	HasAdminRole(ctx context.Context) (bool, error)
  2874  }
  2875  
  2876  // ClientNoticeSender is a limited interface to send notices to the
  2877  // client.
  2878  //
  2879  // TODO(knz): as of this writing, the implementations of this
  2880  // interface only work on the gateway node (i.e. not from
  2881  // distributed processors).
  2882  type ClientNoticeSender interface {
  2883  	// SendClientNotice sends a notice out-of-band to the client.
  2884  	SendClientNotice(ctx context.Context, notice error)
  2885  }
  2886  
  2887  // InternalExecutor is a subset of sqlutil.InternalExecutor (which, in turn, is
  2888  // implemented by sql.InternalExecutor) used by this sem/tree package which
  2889  // can't even import sqlutil.
  2890  //
  2891  // Note that the functions offered here should be avoided when possible. They
  2892  // execute the query as root if an user hadn't been previously set on the
  2893  // executor through SetSessionData(). These functions are deprecated in
  2894  // sql.InternalExecutor in favor of a safer interface. Unfortunately, those
  2895  // safer functions cannot be exposed through this interface because they depend
  2896  // on sqlbase, and this package cannot import sqlbase. When possible, downcast
  2897  // this to sqlutil.InternalExecutor or sql.InternalExecutor, and use the
  2898  // alternatives.
  2899  type InternalExecutor interface {
  2900  	// Query is part of the sqlutil.InternalExecutor interface.
  2901  	Query(
  2902  		ctx context.Context, opName string, txn *kv.Txn,
  2903  		stmt string, qargs ...interface{},
  2904  	) ([]Datums, error)
  2905  
  2906  	// QueryRow is part of the sqlutil.InternalExecutor interface.
  2907  	QueryRow(
  2908  		ctx context.Context, opName string, txn *kv.Txn, stmt string, qargs ...interface{},
  2909  	) (Datums, error)
  2910  }
  2911  
  2912  // PrivilegedAccessor gives access to certain queries that would otherwise
  2913  // require someone with RootUser access to query a given data source.
  2914  // It is defined independently to prevent a circular dependency on sql, tree and sqlbase.
  2915  type PrivilegedAccessor interface {
  2916  	// LookupNamespaceID returns the id of the namespace given it's parent id and name.
  2917  	// It is meant as a replacement for looking up the system.namespace directly.
  2918  	// Returns the id, a bool representing whether the namespace exists, and an error
  2919  	// if there is one.
  2920  	LookupNamespaceID(
  2921  		ctx context.Context, parentID int64, name string,
  2922  	) (DInt, bool, error)
  2923  
  2924  	// LookupZoneConfig returns the zone config given a namespace id.
  2925  	// It is meant as a replacement for looking up system.zones directly.
  2926  	// Returns the config byte array, a bool representing whether the namespace exists,
  2927  	// and an error if there is one.
  2928  	LookupZoneConfigByNamespaceID(ctx context.Context, id int64) (DBytes, bool, error)
  2929  }
  2930  
  2931  // SequenceOperators is used for various sql related functions that can
  2932  // be used from EvalContext.
  2933  type SequenceOperators interface {
  2934  	EvalDatabase
  2935  	// IncrementSequence increments the given sequence and returns the result.
  2936  	// It returns an error if the given name is not a sequence.
  2937  	// The caller must ensure that seqName is fully qualified already.
  2938  	IncrementSequence(ctx context.Context, seqName *TableName) (int64, error)
  2939  
  2940  	// GetLatestValueInSessionForSequence returns the value most recently obtained by
  2941  	// nextval() for the given sequence in this session.
  2942  	GetLatestValueInSessionForSequence(ctx context.Context, seqName *TableName) (int64, error)
  2943  
  2944  	// SetSequenceValue sets the sequence's value.
  2945  	// If isCalled is false, the sequence is set such that the next time nextval() is called,
  2946  	// `newVal` is returned. Otherwise, the next call to nextval will return
  2947  	// `newVal + seqOpts.Increment`.
  2948  	SetSequenceValue(ctx context.Context, seqName *TableName, newVal int64, isCalled bool) error
  2949  }
  2950  
  2951  // TenantOperator is capable of interacting with tenant state, allowing SQL
  2952  // builtin functions to create and destroy tenants. The methods will return
  2953  // errors when run by any tenant other than the system tenant.
  2954  type TenantOperator interface {
  2955  	// CreateTenant attempts to install a new tenant in the system. It returns
  2956  	// an error if the tenant already exists.
  2957  	CreateTenant(ctx context.Context, tenantID uint64, tenantInfo []byte) error
  2958  
  2959  	// DestroyTenant attempts to uninstall an existing tenant from the system.
  2960  	// It returns an error if the tenant does not exist.
  2961  	DestroyTenant(ctx context.Context, tenantID uint64) error
  2962  }
  2963  
  2964  // EvalContextTestingKnobs contains test knobs.
  2965  type EvalContextTestingKnobs struct {
  2966  	// AssertFuncExprReturnTypes indicates whether FuncExpr evaluations
  2967  	// should assert that the returned Datum matches the expected
  2968  	// ReturnType of the function.
  2969  	AssertFuncExprReturnTypes bool
  2970  	// AssertUnaryExprReturnTypes indicates whether UnaryExpr evaluations
  2971  	// should assert that the returned Datum matches the expected
  2972  	// ReturnType of the function.
  2973  	AssertUnaryExprReturnTypes bool
  2974  	// AssertBinaryExprReturnTypes indicates whether BinaryExpr
  2975  	// evaluations should assert that the returned Datum matches the
  2976  	// expected ReturnType of the function.
  2977  	AssertBinaryExprReturnTypes bool
  2978  	// DisableOptimizerRuleProbability is the probability that any given
  2979  	// transformation rule in the optimizer is disabled.
  2980  	DisableOptimizerRuleProbability float64
  2981  	// OptimizerCostPerturbation is used to randomly perturb the estimated
  2982  	// cost of each expression in the query tree for the purpose of creating
  2983  	// alternate query plans in the optimizer.
  2984  	OptimizerCostPerturbation float64
  2985  
  2986  	CallbackGenerators map[string]*CallbackValueGenerator
  2987  }
  2988  
  2989  var _ base.ModuleTestingKnobs = &EvalContextTestingKnobs{}
  2990  
  2991  // ModuleTestingKnobs is part of the base.ModuleTestingKnobs interface.
  2992  func (*EvalContextTestingKnobs) ModuleTestingKnobs() {}
  2993  
  2994  // EvalContext defines the context in which to evaluate an expression, allowing
  2995  // the retrieval of state such as the node ID or statement start time.
  2996  //
  2997  // ATTENTION: Some fields from this struct (particularly, but not exclusively,
  2998  // from SessionData) are also represented in execinfrapb.EvalContext. Whenever
  2999  // something that affects DistSQL execution is added, it needs to be marshaled
  3000  // through that proto too.
  3001  // TODO(andrei): remove or limit the duplication.
  3002  //
  3003  // NOTE(andrei): EvalContext is dusty; it started as a collection of fields
  3004  // needed by expression evaluation, but it has grown quite large; some of the
  3005  // things in it don't seem to belong in this low-level package (e.g. Planner).
  3006  // In the sql package it is embedded by extendedEvalContext, which adds some
  3007  // more fields from the sql package. Through that extendedEvalContext, this
  3008  // struct now generally used by planNodes.
  3009  type EvalContext struct {
  3010  	// Session variables. This is a read-only copy of the values owned by the
  3011  	// Session.
  3012  	SessionData *sessiondata.SessionData
  3013  	// TxnState is a string representation of the current transactional state.
  3014  	TxnState string
  3015  	// TxnReadOnly specifies if the current transaction is read-only.
  3016  	TxnReadOnly bool
  3017  	TxnImplicit bool
  3018  
  3019  	Settings    *cluster.Settings
  3020  	ClusterID   uuid.UUID
  3021  	ClusterName string
  3022  	NodeID      *base.SQLIDContainer
  3023  	Codec       keys.SQLCodec
  3024  
  3025  	// Locality contains the location of the current node as a set of user-defined
  3026  	// key/value pairs, ordered from most inclusive to least inclusive. If there
  3027  	// are no tiers, then the node's location is not known. Example:
  3028  	//
  3029  	//   [region=us,dc=east]
  3030  	//
  3031  	Locality roachpb.Locality
  3032  
  3033  	// The statement timestamp. May be different for every statement.
  3034  	// Used for statement_timestamp().
  3035  	StmtTimestamp time.Time
  3036  	// The transaction timestamp. Needs to stay stable for the lifetime
  3037  	// of a transaction. Used for now(), current_timestamp(),
  3038  	// transaction_timestamp() and the like.
  3039  	TxnTimestamp time.Time
  3040  
  3041  	// Placeholders relates placeholder names to their type and, later, value.
  3042  	// This pointer should always be set to the location of the PlaceholderInfo
  3043  	// in the corresponding SemaContext during normal execution. Placeholders are
  3044  	// available during Eval to permit lookup of a particular placeholder's
  3045  	// underlying datum, if available.
  3046  	Placeholders *PlaceholderInfo
  3047  
  3048  	// Annotations augments the AST with extra information. This pointer should
  3049  	// always be set to the location of the Annotations in the corresponding
  3050  	// SemaContext.
  3051  	Annotations *Annotations
  3052  
  3053  	// IVarContainer is used to evaluate IndexedVars.
  3054  	IVarContainer IndexedVarContainer
  3055  	// iVarContainerStack is used when we swap out IVarContainers in order to
  3056  	// evaluate an intermediate expression. This keeps track of those which we
  3057  	// need to restore once we finish evaluating it.
  3058  	iVarContainerStack []IndexedVarContainer
  3059  
  3060  	// Context holds the context in which the expression is evaluated.
  3061  	Context context.Context
  3062  
  3063  	// InternalExecutor gives access to an executor to be used for running
  3064  	// "internal" statements. It may seem bizarre that "expression evaluation" may
  3065  	// need to run a statement, and yet many builtin functions do it.
  3066  	// Note that the executor will be "session-bound" - it will inherit session
  3067  	// variables from a parent session.
  3068  	InternalExecutor InternalExecutor
  3069  
  3070  	Planner EvalPlanner
  3071  
  3072  	PrivilegedAccessor PrivilegedAccessor
  3073  
  3074  	SessionAccessor EvalSessionAccessor
  3075  
  3076  	ClientNoticeSender ClientNoticeSender
  3077  
  3078  	Sequence SequenceOperators
  3079  
  3080  	Tenant TenantOperator
  3081  
  3082  	// DistSQLTypeResolver is a type resolver used during execution of DistSQL
  3083  	// flows. It is limited to only provide access to types via ID, meaning that
  3084  	// it cannot perform resolution of qualified names into types. It will be nil
  3085  	// when not in the context of a DistSQL flow.
  3086  	DistSQLTypeResolver TypeReferenceResolver
  3087  
  3088  	// The transaction in which the statement is executing.
  3089  	Txn *kv.Txn
  3090  	// A handle to the database.
  3091  	DB *kv.DB
  3092  
  3093  	ReCache *RegexpCache
  3094  	tmpDec  apd.Decimal
  3095  
  3096  	// TODO(mjibson): remove prepareOnly in favor of a 2-step prepare-exec solution
  3097  	// that is also able to save the plan to skip work during the exec step.
  3098  	PrepareOnly bool
  3099  
  3100  	// SkipNormalize indicates whether expressions should be normalized
  3101  	// (false) or not (true).  It is set to true conditionally by
  3102  	// EXPLAIN(TYPES[, NORMALIZE]).
  3103  	SkipNormalize bool
  3104  
  3105  	CollationEnv CollationEnvironment
  3106  
  3107  	TestingKnobs EvalContextTestingKnobs
  3108  
  3109  	Mon *mon.BytesMonitor
  3110  
  3111  	// SingleDatumAggMemAccount is a memory account that all aggregate builtins
  3112  	// that store a single datum will share to account for the memory needed to
  3113  	// perform the aggregation (i.e. memory not reported by AggregateFunc.Size
  3114  	// method). This memory account exists so that such aggregate functions
  3115  	// could "batch" their reservations - otherwise, we end up a situation
  3116  	// where each aggregate function struct grows its own memory account by
  3117  	// tiny amount, yet the account reserves a lot more resulting in
  3118  	// significantly overestimating the memory usage.
  3119  	SingleDatumAggMemAccount *mon.BoundAccount
  3120  }
  3121  
  3122  // MakeTestingEvalContext returns an EvalContext that includes a MemoryMonitor.
  3123  func MakeTestingEvalContext(st *cluster.Settings) EvalContext {
  3124  	monitor := mon.MakeMonitor(
  3125  		"test-monitor",
  3126  		mon.MemoryResource,
  3127  		nil,           /* curCount */
  3128  		nil,           /* maxHist */
  3129  		-1,            /* increment */
  3130  		math.MaxInt64, /* noteworthy */
  3131  		st,
  3132  	)
  3133  	return MakeTestingEvalContextWithMon(st, &monitor)
  3134  }
  3135  
  3136  // MakeTestingEvalContextWithMon returns an EvalContext with the given
  3137  // MemoryMonitor. Ownership of the memory monitor is transferred to the
  3138  // EvalContext so do not start or close the memory monitor.
  3139  func MakeTestingEvalContextWithMon(st *cluster.Settings, monitor *mon.BytesMonitor) EvalContext {
  3140  	ctx := EvalContext{
  3141  		Codec:       keys.SystemSQLCodec,
  3142  		Txn:         &kv.Txn{},
  3143  		SessionData: &sessiondata.SessionData{},
  3144  		Settings:    st,
  3145  		NodeID:      base.TestingIDContainer,
  3146  	}
  3147  	monitor.Start(context.Background(), nil /* pool */, mon.MakeStandaloneBudget(math.MaxInt64))
  3148  	ctx.Mon = monitor
  3149  	ctx.Context = context.TODO()
  3150  	now := timeutil.Now()
  3151  	ctx.SetTxnTimestamp(now)
  3152  	ctx.SetStmtTimestamp(now)
  3153  	return ctx
  3154  }
  3155  
  3156  // Copy returns a deep copy of ctx.
  3157  func (ctx *EvalContext) Copy() *EvalContext {
  3158  	ctxCopy := *ctx
  3159  	ctxCopy.iVarContainerStack = make([]IndexedVarContainer, len(ctx.iVarContainerStack), cap(ctx.iVarContainerStack))
  3160  	copy(ctxCopy.iVarContainerStack, ctx.iVarContainerStack)
  3161  	return &ctxCopy
  3162  }
  3163  
  3164  // PushIVarContainer replaces the current IVarContainer with a different one -
  3165  // pushing the current one onto a stack to be replaced later once
  3166  // PopIVarContainer is called.
  3167  func (ctx *EvalContext) PushIVarContainer(c IndexedVarContainer) {
  3168  	ctx.iVarContainerStack = append(ctx.iVarContainerStack, ctx.IVarContainer)
  3169  	ctx.IVarContainer = c
  3170  }
  3171  
  3172  // PopIVarContainer discards the current IVarContainer on the EvalContext,
  3173  // replacing it with an older one.
  3174  func (ctx *EvalContext) PopIVarContainer() {
  3175  	ctx.IVarContainer = ctx.iVarContainerStack[len(ctx.iVarContainerStack)-1]
  3176  	ctx.iVarContainerStack = ctx.iVarContainerStack[:len(ctx.iVarContainerStack)-1]
  3177  }
  3178  
  3179  // NewTestingEvalContext is a convenience version of MakeTestingEvalContext
  3180  // that returns a pointer.
  3181  func NewTestingEvalContext(st *cluster.Settings) *EvalContext {
  3182  	ctx := MakeTestingEvalContext(st)
  3183  	return &ctx
  3184  }
  3185  
  3186  // Stop closes out the EvalContext and must be called once it is no longer in use.
  3187  func (ctx *EvalContext) Stop(c context.Context) {
  3188  	ctx.Mon.Stop(c)
  3189  }
  3190  
  3191  // GetStmtTimestamp retrieves the current statement timestamp as per
  3192  // the evaluation context. The timestamp is guaranteed to be nonzero.
  3193  func (ctx *EvalContext) GetStmtTimestamp() time.Time {
  3194  	// TODO(knz): a zero timestamp should never be read, even during
  3195  	// Prepare. This will need to be addressed.
  3196  	if !ctx.PrepareOnly && ctx.StmtTimestamp.IsZero() {
  3197  		panic(errors.AssertionFailedf("zero statement timestamp in EvalContext"))
  3198  	}
  3199  	return ctx.StmtTimestamp
  3200  }
  3201  
  3202  // GetClusterTimestamp retrieves the current cluster timestamp as per
  3203  // the evaluation context. The timestamp is guaranteed to be nonzero.
  3204  func (ctx *EvalContext) GetClusterTimestamp() *DDecimal {
  3205  	ts := ctx.Txn.CommitTimestamp()
  3206  	if ts == (hlc.Timestamp{}) {
  3207  		panic(errors.AssertionFailedf("zero cluster timestamp in txn"))
  3208  	}
  3209  	return TimestampToDecimal(ts)
  3210  }
  3211  
  3212  // HasPlaceholders returns true if this EvalContext's placeholders have been
  3213  // assigned. Will be false during Prepare.
  3214  func (ctx *EvalContext) HasPlaceholders() bool {
  3215  	return ctx.Placeholders != nil
  3216  }
  3217  
  3218  // TimestampToDecimal converts the logical timestamp into a decimal
  3219  // value with the number of nanoseconds in the integer part and the
  3220  // logical counter in the decimal part.
  3221  func TimestampToDecimal(ts hlc.Timestamp) *DDecimal {
  3222  	// Compute Walltime * 10^10 + Logical.
  3223  	// We need 10 decimals for the Logical field because its maximum
  3224  	// value is 4294967295 (2^32-1), a value with 10 decimal digits.
  3225  	var res DDecimal
  3226  	val := &res.Coeff
  3227  	val.SetInt64(ts.WallTime)
  3228  	val.Mul(val, big10E10)
  3229  	val.Add(val, big.NewInt(int64(ts.Logical)))
  3230  
  3231  	// val must be positive. If it was set to a negative value above,
  3232  	// transfer the sign to res.Negative.
  3233  	res.Negative = val.Sign() < 0
  3234  	val.Abs(val)
  3235  
  3236  	// Shift 10 decimals to the right, so that the logical
  3237  	// field appears as fractional part.
  3238  	res.Decimal.Exponent = -10
  3239  	return &res
  3240  }
  3241  
  3242  // TimestampToInexactDTimestamp converts the logical timestamp into an
  3243  // inexact DTimestamp by dropping the logical counter and using the wall
  3244  // time at the microsecond precision.
  3245  func TimestampToInexactDTimestamp(ts hlc.Timestamp) *DTimestamp {
  3246  	return MustMakeDTimestamp(timeutil.Unix(0, ts.WallTime), time.Microsecond)
  3247  }
  3248  
  3249  // GetRelativeParseTime implements ParseTimeContext.
  3250  func (ctx *EvalContext) GetRelativeParseTime() time.Time {
  3251  	ret := ctx.TxnTimestamp
  3252  	if ret.IsZero() {
  3253  		ret = timeutil.Now()
  3254  	}
  3255  	return ret.In(ctx.GetLocation())
  3256  }
  3257  
  3258  // GetTxnTimestamp retrieves the current transaction timestamp as per
  3259  // the evaluation context. The timestamp is guaranteed to be nonzero.
  3260  func (ctx *EvalContext) GetTxnTimestamp(precision time.Duration) *DTimestampTZ {
  3261  	// TODO(knz): a zero timestamp should never be read, even during
  3262  	// Prepare. This will need to be addressed.
  3263  	if !ctx.PrepareOnly && ctx.TxnTimestamp.IsZero() {
  3264  		panic(errors.AssertionFailedf("zero transaction timestamp in EvalContext"))
  3265  	}
  3266  	return MustMakeDTimestampTZ(ctx.GetRelativeParseTime(), precision)
  3267  }
  3268  
  3269  // GetTxnTimestampNoZone retrieves the current transaction timestamp as per
  3270  // the evaluation context. The timestamp is guaranteed to be nonzero.
  3271  func (ctx *EvalContext) GetTxnTimestampNoZone(precision time.Duration) *DTimestamp {
  3272  	// TODO(knz): a zero timestamp should never be read, even during
  3273  	// Prepare. This will need to be addressed.
  3274  	if !ctx.PrepareOnly && ctx.TxnTimestamp.IsZero() {
  3275  		panic(errors.AssertionFailedf("zero transaction timestamp in EvalContext"))
  3276  	}
  3277  	// Move the time to UTC, but keeping the location's time.
  3278  	t := ctx.GetRelativeParseTime()
  3279  	_, offsetSecs := t.Zone()
  3280  	return MustMakeDTimestamp(t.Add(time.Second*time.Duration(offsetSecs)).In(time.UTC), precision)
  3281  }
  3282  
  3283  // GetTxnTime retrieves the current transaction time as per
  3284  // the evaluation context.
  3285  func (ctx *EvalContext) GetTxnTime(precision time.Duration) *DTimeTZ {
  3286  	// TODO(knz): a zero timestamp should never be read, even during
  3287  	// Prepare. This will need to be addressed.
  3288  	if !ctx.PrepareOnly && ctx.TxnTimestamp.IsZero() {
  3289  		panic(errors.AssertionFailedf("zero transaction timestamp in EvalContext"))
  3290  	}
  3291  	return NewDTimeTZFromTime(ctx.GetRelativeParseTime().Round(precision))
  3292  }
  3293  
  3294  // GetTxnTimeNoZone retrieves the current transaction time as per
  3295  // the evaluation context.
  3296  func (ctx *EvalContext) GetTxnTimeNoZone(precision time.Duration) *DTime {
  3297  	// TODO(knz): a zero timestamp should never be read, even during
  3298  	// Prepare. This will need to be addressed.
  3299  	if !ctx.PrepareOnly && ctx.TxnTimestamp.IsZero() {
  3300  		panic(errors.AssertionFailedf("zero transaction timestamp in EvalContext"))
  3301  	}
  3302  	return MakeDTime(timeofday.FromTime(ctx.GetRelativeParseTime().Round(precision)))
  3303  }
  3304  
  3305  // SetTxnTimestamp sets the corresponding timestamp in the EvalContext.
  3306  func (ctx *EvalContext) SetTxnTimestamp(ts time.Time) {
  3307  	ctx.TxnTimestamp = ts
  3308  }
  3309  
  3310  // SetStmtTimestamp sets the corresponding timestamp in the EvalContext.
  3311  func (ctx *EvalContext) SetStmtTimestamp(ts time.Time) {
  3312  	ctx.StmtTimestamp = ts
  3313  }
  3314  
  3315  // GetLocation returns the session timezone.
  3316  func (ctx *EvalContext) GetLocation() *time.Location {
  3317  	if ctx.SessionData == nil || ctx.SessionData.DataConversion.Location == nil {
  3318  		return time.UTC
  3319  	}
  3320  	return ctx.SessionData.DataConversion.Location
  3321  }
  3322  
  3323  // Ctx returns the session's context.
  3324  func (ctx *EvalContext) Ctx() context.Context {
  3325  	return ctx.Context
  3326  }
  3327  
  3328  func (ctx *EvalContext) getTmpDec() *apd.Decimal {
  3329  	return &ctx.tmpDec
  3330  }
  3331  
  3332  // Eval implements the TypedExpr interface.
  3333  func (expr *AndExpr) Eval(ctx *EvalContext) (Datum, error) {
  3334  	left, err := expr.Left.(TypedExpr).Eval(ctx)
  3335  	if err != nil {
  3336  		return nil, err
  3337  	}
  3338  	if left != DNull {
  3339  		if v, err := GetBool(left); err != nil {
  3340  			return nil, err
  3341  		} else if !v {
  3342  			return left, nil
  3343  		}
  3344  	}
  3345  	right, err := expr.Right.(TypedExpr).Eval(ctx)
  3346  	if err != nil {
  3347  		return nil, err
  3348  	}
  3349  	if right == DNull {
  3350  		return DNull, nil
  3351  	}
  3352  	if v, err := GetBool(right); err != nil {
  3353  		return nil, err
  3354  	} else if !v {
  3355  		return right, nil
  3356  	}
  3357  	return left, nil
  3358  }
  3359  
  3360  // Eval implements the TypedExpr interface.
  3361  func (expr *BinaryExpr) Eval(ctx *EvalContext) (Datum, error) {
  3362  	left, err := expr.Left.(TypedExpr).Eval(ctx)
  3363  	if err != nil {
  3364  		return nil, err
  3365  	}
  3366  	if left == DNull && !expr.Fn.NullableArgs {
  3367  		return DNull, nil
  3368  	}
  3369  	right, err := expr.Right.(TypedExpr).Eval(ctx)
  3370  	if err != nil {
  3371  		return nil, err
  3372  	}
  3373  	if right == DNull && !expr.Fn.NullableArgs {
  3374  		return DNull, nil
  3375  	}
  3376  	res, err := expr.Fn.Fn(ctx, left, right)
  3377  	if err != nil {
  3378  		return nil, err
  3379  	}
  3380  	if ctx.TestingKnobs.AssertBinaryExprReturnTypes {
  3381  		if err := ensureExpectedType(expr.Fn.ReturnType, res); err != nil {
  3382  			return nil, errors.NewAssertionErrorWithWrappedErrf(err,
  3383  				"binary op %q", expr)
  3384  		}
  3385  	}
  3386  	return res, err
  3387  }
  3388  
  3389  // Eval implements the TypedExpr interface.
  3390  func (expr *CaseExpr) Eval(ctx *EvalContext) (Datum, error) {
  3391  	if expr.Expr != nil {
  3392  		// CASE <val> WHEN <expr> THEN ...
  3393  		//
  3394  		// For each "when" expression we compare for equality to <val>.
  3395  		val, err := expr.Expr.(TypedExpr).Eval(ctx)
  3396  		if err != nil {
  3397  			return nil, err
  3398  		}
  3399  
  3400  		for _, when := range expr.Whens {
  3401  			arg, err := when.Cond.(TypedExpr).Eval(ctx)
  3402  			if err != nil {
  3403  				return nil, err
  3404  			}
  3405  			d, err := evalComparison(ctx, EQ, val, arg)
  3406  			if err != nil {
  3407  				return nil, err
  3408  			}
  3409  			if v, err := GetBool(d); err != nil {
  3410  				return nil, err
  3411  			} else if v {
  3412  				return when.Val.(TypedExpr).Eval(ctx)
  3413  			}
  3414  		}
  3415  	} else {
  3416  		// CASE WHEN <bool-expr> THEN ...
  3417  		for _, when := range expr.Whens {
  3418  			d, err := when.Cond.(TypedExpr).Eval(ctx)
  3419  			if err != nil {
  3420  				return nil, err
  3421  			}
  3422  			if v, err := GetBool(d); err != nil {
  3423  				return nil, err
  3424  			} else if v {
  3425  				return when.Val.(TypedExpr).Eval(ctx)
  3426  			}
  3427  		}
  3428  	}
  3429  
  3430  	if expr.Else != nil {
  3431  		return expr.Else.(TypedExpr).Eval(ctx)
  3432  	}
  3433  	return DNull, nil
  3434  }
  3435  
  3436  // pgSignatureRegexp matches a Postgres function type signature, capturing the
  3437  // name of the function into group 1.
  3438  // e.g. function(a, b, c) or function( a )
  3439  var pgSignatureRegexp = regexp.MustCompile(`^\s*([\w\.]+)\s*\((?:(?:\s*\w+\s*,)*\s*\w+)?\s*\)\s*$`)
  3440  
  3441  // regTypeInfo contains details on a pg_catalog table that has a reg* type.
  3442  type regTypeInfo struct {
  3443  	tableName string
  3444  	// nameCol is the name of the column that contains the table's entity name.
  3445  	nameCol string
  3446  	// objName is a human-readable name describing the objects in the table.
  3447  	objName string
  3448  	// errType is the pg error code in case the object does not exist.
  3449  	errType string
  3450  }
  3451  
  3452  // regTypeInfos maps an oid.Oid to a regTypeInfo that describes the pg_catalog
  3453  // table that contains the entities of the type of the key.
  3454  var regTypeInfos = map[oid.Oid]regTypeInfo{
  3455  	oid.T_regclass:     {"pg_class", "relname", "relation", pgcode.UndefinedTable},
  3456  	oid.T_regtype:      {"pg_type", "typname", "type", pgcode.UndefinedObject},
  3457  	oid.T_regproc:      {"pg_proc", "proname", "function", pgcode.UndefinedFunction},
  3458  	oid.T_regprocedure: {"pg_proc", "proname", "function", pgcode.UndefinedFunction},
  3459  	oid.T_regnamespace: {"pg_namespace", "nspname", "namespace", pgcode.UndefinedObject},
  3460  }
  3461  
  3462  // queryOidWithJoin looks up the name or OID of an input OID or string in the
  3463  // pg_catalog table that the input oid.Oid belongs to. If the input Datum
  3464  // is a DOid, the relevant table will be queried by OID; if the input is a
  3465  // DString, the table will be queried by its name column.
  3466  //
  3467  // The return value is a fresh DOid of the input oid.Oid with name and OID
  3468  // set to the result of the query. If there was not exactly one result to the
  3469  // query, an error will be returned.
  3470  func queryOidWithJoin(
  3471  	ctx *EvalContext, typ *types.T, d Datum, joinClause string, additionalWhere string,
  3472  ) (*DOid, error) {
  3473  	ret := &DOid{semanticType: typ}
  3474  	info := regTypeInfos[typ.Oid()]
  3475  	var queryCol string
  3476  	switch d.(type) {
  3477  	case *DOid:
  3478  		queryCol = "oid"
  3479  	case *DString:
  3480  		queryCol = info.nameCol
  3481  	default:
  3482  		return nil, errors.AssertionFailedf("invalid argument to OID cast: %s", d)
  3483  	}
  3484  	results, err := ctx.InternalExecutor.QueryRow(
  3485  		ctx.Ctx(), "queryOidWithJoin",
  3486  		ctx.Txn,
  3487  		fmt.Sprintf(
  3488  			"SELECT %s.oid, %s FROM pg_catalog.%s %s WHERE %s = $1 %s",
  3489  			info.tableName, info.nameCol, info.tableName, joinClause, queryCol, additionalWhere),
  3490  		d)
  3491  	if err != nil {
  3492  		if errors.HasType(err, (*MultipleResultsError)(nil)) {
  3493  			return nil, pgerror.Newf(pgcode.AmbiguousAlias,
  3494  				"more than one %s named %s", info.objName, d)
  3495  		}
  3496  		return nil, err
  3497  	}
  3498  	if results.Len() == 0 {
  3499  		return nil, pgerror.Newf(info.errType, "%s %s does not exist", info.objName, d)
  3500  	}
  3501  	ret.DInt = results[0].(*DOid).DInt
  3502  	ret.name = AsStringWithFlags(results[1], FmtBareStrings)
  3503  	return ret, nil
  3504  }
  3505  
  3506  func queryOid(ctx *EvalContext, typ *types.T, d Datum) (*DOid, error) {
  3507  	return queryOidWithJoin(ctx, typ, d, "", "")
  3508  }
  3509  
  3510  // Eval implements the TypedExpr interface.
  3511  func (expr *CastExpr) Eval(ctx *EvalContext) (Datum, error) {
  3512  	d, err := expr.Expr.(TypedExpr).Eval(ctx)
  3513  	if err != nil {
  3514  		return nil, err
  3515  	}
  3516  
  3517  	// NULL cast to anything is NULL.
  3518  	if d == DNull {
  3519  		return d, nil
  3520  	}
  3521  	d = UnwrapDatum(ctx, d)
  3522  	return PerformCast(ctx, d, expr.ResolvedType())
  3523  }
  3524  
  3525  // Eval implements the TypedExpr interface.
  3526  func (expr *IndirectionExpr) Eval(ctx *EvalContext) (Datum, error) {
  3527  	var subscriptIdx int
  3528  	for i, t := range expr.Indirection {
  3529  		if t.Slice || i > 0 {
  3530  			return nil, errors.AssertionFailedf("unsupported feature should have been rejected during planning")
  3531  		}
  3532  
  3533  		d, err := t.Begin.(TypedExpr).Eval(ctx)
  3534  		if err != nil {
  3535  			return nil, err
  3536  		}
  3537  		if d == DNull {
  3538  			return d, nil
  3539  		}
  3540  		subscriptIdx = int(MustBeDInt(d))
  3541  	}
  3542  
  3543  	d, err := expr.Expr.(TypedExpr).Eval(ctx)
  3544  	if err != nil {
  3545  		return nil, err
  3546  	}
  3547  	if d == DNull {
  3548  		return d, nil
  3549  	}
  3550  
  3551  	// Index into the DArray, using 1-indexing.
  3552  	arr := MustBeDArray(d)
  3553  
  3554  	// VECTOR types use 0-indexing.
  3555  	switch arr.customOid {
  3556  	case oid.T_oidvector, oid.T_int2vector:
  3557  		subscriptIdx++
  3558  	}
  3559  	if subscriptIdx < 1 || subscriptIdx > arr.Len() {
  3560  		return DNull, nil
  3561  	}
  3562  	return arr.Array[subscriptIdx-1], nil
  3563  }
  3564  
  3565  // Eval implements the TypedExpr interface.
  3566  func (expr *CollateExpr) Eval(ctx *EvalContext) (Datum, error) {
  3567  	d, err := expr.Expr.(TypedExpr).Eval(ctx)
  3568  	if err != nil {
  3569  		return nil, err
  3570  	}
  3571  	unwrapped := UnwrapDatum(ctx, d)
  3572  	if unwrapped == DNull {
  3573  		return DNull, nil
  3574  	}
  3575  	switch d := unwrapped.(type) {
  3576  	case *DString:
  3577  		return NewDCollatedString(string(*d), expr.Locale, &ctx.CollationEnv)
  3578  	case *DCollatedString:
  3579  		return NewDCollatedString(d.Contents, expr.Locale, &ctx.CollationEnv)
  3580  	default:
  3581  		return nil, pgerror.Newf(pgcode.DatatypeMismatch, "incompatible type for COLLATE: %s", d)
  3582  	}
  3583  }
  3584  
  3585  // Eval implements the TypedExpr interface.
  3586  func (expr *ColumnAccessExpr) Eval(ctx *EvalContext) (Datum, error) {
  3587  	d, err := expr.Expr.(TypedExpr).Eval(ctx)
  3588  	if err != nil {
  3589  		return nil, err
  3590  	}
  3591  	return d.(*DTuple).D[expr.ColIndex], nil
  3592  }
  3593  
  3594  // Eval implements the TypedExpr interface.
  3595  func (expr *CoalesceExpr) Eval(ctx *EvalContext) (Datum, error) {
  3596  	for _, e := range expr.Exprs {
  3597  		d, err := e.(TypedExpr).Eval(ctx)
  3598  		if err != nil {
  3599  			return nil, err
  3600  		}
  3601  		if d != DNull {
  3602  			return d, nil
  3603  		}
  3604  	}
  3605  	return DNull, nil
  3606  }
  3607  
  3608  // Eval implements the TypedExpr interface.
  3609  func (expr *ComparisonExpr) Eval(ctx *EvalContext) (Datum, error) {
  3610  	left, err := expr.Left.(TypedExpr).Eval(ctx)
  3611  	if err != nil {
  3612  		return nil, err
  3613  	}
  3614  	right, err := expr.Right.(TypedExpr).Eval(ctx)
  3615  	if err != nil {
  3616  		return nil, err
  3617  	}
  3618  
  3619  	op := expr.Operator
  3620  	if op.hasSubOperator() {
  3621  		var datums Datums
  3622  		// Right is either a tuple or an array of Datums.
  3623  		if !expr.fn.NullableArgs && right == DNull {
  3624  			return DNull, nil
  3625  		} else if tuple, ok := AsDTuple(right); ok {
  3626  			datums = tuple.D
  3627  		} else if array, ok := AsDArray(right); ok {
  3628  			datums = array.Array
  3629  		} else {
  3630  			return nil, errors.AssertionFailedf("unhandled right expression %s", right)
  3631  		}
  3632  		return evalDatumsCmp(ctx, op, expr.SubOperator, expr.fn, left, datums)
  3633  	}
  3634  
  3635  	_, newLeft, newRight, _, not := foldComparisonExpr(op, left, right)
  3636  	if !expr.fn.NullableArgs && (newLeft == DNull || newRight == DNull) {
  3637  		return DNull, nil
  3638  	}
  3639  	d, err := expr.fn.Fn(ctx, newLeft.(Datum), newRight.(Datum))
  3640  	if err != nil {
  3641  		return nil, err
  3642  	}
  3643  	if b, ok := d.(*DBool); ok {
  3644  		return MakeDBool(*b != DBool(not)), nil
  3645  	}
  3646  	return d, nil
  3647  }
  3648  
  3649  // EvalArgsAndGetGenerator evaluates the arguments and instanciates a
  3650  // ValueGenerator for use by set projections.
  3651  func (expr *FuncExpr) EvalArgsAndGetGenerator(ctx *EvalContext) (ValueGenerator, error) {
  3652  	if expr.fn == nil || expr.fnProps.Class != GeneratorClass {
  3653  		return nil, errors.AssertionFailedf("cannot call EvalArgsAndGetGenerator() on non-aggregate function: %q", ErrString(expr))
  3654  	}
  3655  	nullArg, args, err := expr.evalArgs(ctx)
  3656  	if err != nil || nullArg {
  3657  		return nil, err
  3658  	}
  3659  	return expr.fn.Generator(ctx, args)
  3660  }
  3661  
  3662  // evalArgs evaluates just the function application's arguments.
  3663  // The returned bool indicates that the NULL should be propagated.
  3664  func (expr *FuncExpr) evalArgs(ctx *EvalContext) (bool, Datums, error) {
  3665  	args := make(Datums, len(expr.Exprs))
  3666  	for i, e := range expr.Exprs {
  3667  		arg, err := e.(TypedExpr).Eval(ctx)
  3668  		if err != nil {
  3669  			return false, nil, err
  3670  		}
  3671  		if arg == DNull && !expr.fnProps.NullableArgs {
  3672  			return true, nil, nil
  3673  		}
  3674  		args[i] = arg
  3675  	}
  3676  	return false, args, nil
  3677  }
  3678  
  3679  // Eval implements the TypedExpr interface.
  3680  func (expr *FuncExpr) Eval(ctx *EvalContext) (Datum, error) {
  3681  	nullResult, args, err := expr.evalArgs(ctx)
  3682  	if err != nil {
  3683  		return nil, err
  3684  	}
  3685  	if nullResult {
  3686  		return DNull, err
  3687  	}
  3688  
  3689  	res, err := expr.fn.Fn(ctx, args)
  3690  	if err != nil {
  3691  		// If we are facing an explicit error, propagate it unchanged.
  3692  		fName := expr.Func.String()
  3693  		if fName == `crdb_internal.force_error` {
  3694  			return nil, err
  3695  		}
  3696  		// Otherwise, wrap it with context.
  3697  		newErr := errors.Wrapf(err, "%s()", errors.Safe(fName))
  3698  		// Count function errors as it flows out of the system.  We need
  3699  		// to have this inside a if because if we are facing a retry
  3700  		// error, in particular those generated by
  3701  		// crdb_internal.force_retry(), Wrap() will propagate it as a
  3702  		// non-pgerror error (so that the executor can see it with the
  3703  		// right type).
  3704  		newErr = errors.WithTelemetry(newErr, fName+"()")
  3705  		return nil, newErr
  3706  	}
  3707  	if ctx.TestingKnobs.AssertFuncExprReturnTypes {
  3708  		if err := ensureExpectedType(expr.fn.FixedReturnType(), res); err != nil {
  3709  			return nil, errors.NewAssertionErrorWithWrappedErrf(err, "function %q", expr)
  3710  		}
  3711  	}
  3712  	return res, nil
  3713  }
  3714  
  3715  // ensureExpectedType will return an error if a datum does not match the
  3716  // provided type. If the expected type is Any or if the datum is a Null
  3717  // type, then no error will be returned.
  3718  func ensureExpectedType(exp *types.T, d Datum) error {
  3719  	if !(exp.Family() == types.AnyFamily || d.ResolvedType().Family() == types.UnknownFamily ||
  3720  		d.ResolvedType().Equivalent(exp)) {
  3721  		return errors.AssertionFailedf(
  3722  			"expected return type %q, got: %q", errors.Safe(exp), errors.Safe(d.ResolvedType()))
  3723  	}
  3724  	return nil
  3725  }
  3726  
  3727  // Eval implements the TypedExpr interface.
  3728  func (expr *IfErrExpr) Eval(ctx *EvalContext) (Datum, error) {
  3729  	cond, evalErr := expr.Cond.(TypedExpr).Eval(ctx)
  3730  	if evalErr == nil {
  3731  		if expr.Else == nil {
  3732  			return DBoolFalse, nil
  3733  		}
  3734  		return cond, nil
  3735  	}
  3736  	if expr.ErrCode != nil {
  3737  		errpat, err := expr.ErrCode.(TypedExpr).Eval(ctx)
  3738  		if err != nil {
  3739  			return nil, err
  3740  		}
  3741  		if errpat == DNull {
  3742  			return nil, evalErr
  3743  		}
  3744  		errpatStr := string(MustBeDString(errpat))
  3745  		if code := pgerror.GetPGCode(evalErr); code != errpatStr {
  3746  			return nil, evalErr
  3747  		}
  3748  	}
  3749  	if expr.Else == nil {
  3750  		return DBoolTrue, nil
  3751  	}
  3752  	return expr.Else.(TypedExpr).Eval(ctx)
  3753  }
  3754  
  3755  // Eval implements the TypedExpr interface.
  3756  func (expr *IfExpr) Eval(ctx *EvalContext) (Datum, error) {
  3757  	cond, err := expr.Cond.(TypedExpr).Eval(ctx)
  3758  	if err != nil {
  3759  		return nil, err
  3760  	}
  3761  	if cond == DBoolTrue {
  3762  		return expr.True.(TypedExpr).Eval(ctx)
  3763  	}
  3764  	return expr.Else.(TypedExpr).Eval(ctx)
  3765  }
  3766  
  3767  // Eval implements the TypedExpr interface.
  3768  func (expr *IsOfTypeExpr) Eval(ctx *EvalContext) (Datum, error) {
  3769  	d, err := expr.Expr.(TypedExpr).Eval(ctx)
  3770  	if err != nil {
  3771  		return nil, err
  3772  	}
  3773  	datumTyp := d.ResolvedType()
  3774  
  3775  	for _, t := range expr.ResolvedTypes() {
  3776  		if datumTyp.Equivalent(t) {
  3777  			return MakeDBool(DBool(!expr.Not)), nil
  3778  		}
  3779  	}
  3780  	return MakeDBool(DBool(expr.Not)), nil
  3781  }
  3782  
  3783  // Eval implements the TypedExpr interface.
  3784  func (expr *NotExpr) Eval(ctx *EvalContext) (Datum, error) {
  3785  	d, err := expr.Expr.(TypedExpr).Eval(ctx)
  3786  	if err != nil {
  3787  		return nil, err
  3788  	}
  3789  	if d == DNull {
  3790  		return DNull, nil
  3791  	}
  3792  	v, err := GetBool(d)
  3793  	if err != nil {
  3794  		return nil, err
  3795  	}
  3796  	return MakeDBool(!v), nil
  3797  }
  3798  
  3799  // Eval implements the TypedExpr interface.
  3800  func (expr *IsNullExpr) Eval(ctx *EvalContext) (Datum, error) {
  3801  	d, err := expr.Expr.(TypedExpr).Eval(ctx)
  3802  	if err != nil {
  3803  		return nil, err
  3804  	}
  3805  	if d == DNull {
  3806  		return MakeDBool(true), nil
  3807  	}
  3808  	if t, ok := d.(*DTuple); ok {
  3809  		// A tuple IS NULL if all elements are NULL.
  3810  		for _, tupleDatum := range t.D {
  3811  			if tupleDatum != DNull {
  3812  				return MakeDBool(false), nil
  3813  			}
  3814  		}
  3815  		return MakeDBool(true), nil
  3816  	}
  3817  	return MakeDBool(false), nil
  3818  }
  3819  
  3820  // Eval implements the TypedExpr interface.
  3821  func (expr *IsNotNullExpr) Eval(ctx *EvalContext) (Datum, error) {
  3822  	d, err := expr.Expr.(TypedExpr).Eval(ctx)
  3823  	if err != nil {
  3824  		return nil, err
  3825  	}
  3826  	if d == DNull {
  3827  		return MakeDBool(false), nil
  3828  	}
  3829  	if t, ok := d.(*DTuple); ok {
  3830  		// A tuple IS NOT NULL if all elements are not NULL.
  3831  		for _, tupleDatum := range t.D {
  3832  			if tupleDatum == DNull {
  3833  				return MakeDBool(false), nil
  3834  			}
  3835  		}
  3836  		return MakeDBool(true), nil
  3837  	}
  3838  	return MakeDBool(true), nil
  3839  }
  3840  
  3841  // Eval implements the TypedExpr interface.
  3842  func (expr *NullIfExpr) Eval(ctx *EvalContext) (Datum, error) {
  3843  	expr1, err := expr.Expr1.(TypedExpr).Eval(ctx)
  3844  	if err != nil {
  3845  		return nil, err
  3846  	}
  3847  	expr2, err := expr.Expr2.(TypedExpr).Eval(ctx)
  3848  	if err != nil {
  3849  		return nil, err
  3850  	}
  3851  	cond, err := evalComparison(ctx, EQ, expr1, expr2)
  3852  	if err != nil {
  3853  		return nil, err
  3854  	}
  3855  	if cond == DBoolTrue {
  3856  		return DNull, nil
  3857  	}
  3858  	return expr1, nil
  3859  }
  3860  
  3861  // Eval implements the TypedExpr interface.
  3862  func (expr *OrExpr) Eval(ctx *EvalContext) (Datum, error) {
  3863  	left, err := expr.Left.(TypedExpr).Eval(ctx)
  3864  	if err != nil {
  3865  		return nil, err
  3866  	}
  3867  	if left != DNull {
  3868  		if v, err := GetBool(left); err != nil {
  3869  			return nil, err
  3870  		} else if v {
  3871  			return left, nil
  3872  		}
  3873  	}
  3874  	right, err := expr.Right.(TypedExpr).Eval(ctx)
  3875  	if err != nil {
  3876  		return nil, err
  3877  	}
  3878  	if right == DNull {
  3879  		return DNull, nil
  3880  	}
  3881  	if v, err := GetBool(right); err != nil {
  3882  		return nil, err
  3883  	} else if v {
  3884  		return right, nil
  3885  	}
  3886  	if left == DNull {
  3887  		return DNull, nil
  3888  	}
  3889  	return DBoolFalse, nil
  3890  }
  3891  
  3892  // Eval implements the TypedExpr interface.
  3893  func (expr *ParenExpr) Eval(ctx *EvalContext) (Datum, error) {
  3894  	return expr.Expr.(TypedExpr).Eval(ctx)
  3895  }
  3896  
  3897  // Eval implements the TypedExpr interface.
  3898  func (expr *RangeCond) Eval(ctx *EvalContext) (Datum, error) {
  3899  	return nil, errors.AssertionFailedf("unhandled type %T", expr)
  3900  }
  3901  
  3902  // Eval implements the TypedExpr interface.
  3903  func (expr *UnaryExpr) Eval(ctx *EvalContext) (Datum, error) {
  3904  	d, err := expr.Expr.(TypedExpr).Eval(ctx)
  3905  	if err != nil {
  3906  		return nil, err
  3907  	}
  3908  	if d == DNull {
  3909  		return DNull, nil
  3910  	}
  3911  	res, err := expr.fn.Fn(ctx, d)
  3912  	if err != nil {
  3913  		return nil, err
  3914  	}
  3915  	if ctx.TestingKnobs.AssertUnaryExprReturnTypes {
  3916  		if err := ensureExpectedType(expr.fn.ReturnType, res); err != nil {
  3917  			return nil, errors.NewAssertionErrorWithWrappedErrf(err, "unary op %q", expr)
  3918  		}
  3919  	}
  3920  	return res, err
  3921  }
  3922  
  3923  // Eval implements the TypedExpr interface.
  3924  func (expr DefaultVal) Eval(ctx *EvalContext) (Datum, error) {
  3925  	return nil, errors.AssertionFailedf("unhandled type %T", expr)
  3926  }
  3927  
  3928  // Eval implements the TypedExpr interface.
  3929  func (expr UnqualifiedStar) Eval(ctx *EvalContext) (Datum, error) {
  3930  	return nil, errors.AssertionFailedf("unhandled type %T", expr)
  3931  }
  3932  
  3933  // Eval implements the TypedExpr interface.
  3934  func (expr *UnresolvedName) Eval(ctx *EvalContext) (Datum, error) {
  3935  	return nil, errors.AssertionFailedf("unhandled type %T", expr)
  3936  }
  3937  
  3938  // Eval implements the TypedExpr interface.
  3939  func (expr *AllColumnsSelector) Eval(ctx *EvalContext) (Datum, error) {
  3940  	return nil, errors.AssertionFailedf("unhandled type %T", expr)
  3941  }
  3942  
  3943  // Eval implements the TypedExpr interface.
  3944  func (expr *TupleStar) Eval(ctx *EvalContext) (Datum, error) {
  3945  	return nil, errors.AssertionFailedf("unhandled type %T", expr)
  3946  }
  3947  
  3948  // Eval implements the TypedExpr interface.
  3949  func (expr *ColumnItem) Eval(ctx *EvalContext) (Datum, error) {
  3950  	return nil, errors.AssertionFailedf("unhandled type %T", expr)
  3951  }
  3952  
  3953  // Eval implements the TypedExpr interface.
  3954  func (t *Tuple) Eval(ctx *EvalContext) (Datum, error) {
  3955  	tuple := NewDTupleWithLen(t.typ, len(t.Exprs))
  3956  	for i, v := range t.Exprs {
  3957  		d, err := v.(TypedExpr).Eval(ctx)
  3958  		if err != nil {
  3959  			return nil, err
  3960  		}
  3961  		tuple.D[i] = d
  3962  	}
  3963  	return tuple, nil
  3964  }
  3965  
  3966  // arrayOfType returns a fresh DArray of the input type.
  3967  func arrayOfType(typ *types.T) (*DArray, error) {
  3968  	if typ.Family() != types.ArrayFamily {
  3969  		return nil, errors.AssertionFailedf("array node type (%v) is not types.TArray", typ)
  3970  	}
  3971  	if err := types.CheckArrayElementType(typ.ArrayContents()); err != nil {
  3972  		return nil, err
  3973  	}
  3974  	return NewDArray(typ.ArrayContents()), nil
  3975  }
  3976  
  3977  // Eval implements the TypedExpr interface.
  3978  func (t *Array) Eval(ctx *EvalContext) (Datum, error) {
  3979  	array, err := arrayOfType(t.ResolvedType())
  3980  	if err != nil {
  3981  		return nil, err
  3982  	}
  3983  
  3984  	for _, v := range t.Exprs {
  3985  		d, err := v.(TypedExpr).Eval(ctx)
  3986  		if err != nil {
  3987  			return nil, err
  3988  		}
  3989  		if err := array.Append(d); err != nil {
  3990  			return nil, err
  3991  		}
  3992  	}
  3993  	return array, nil
  3994  }
  3995  
  3996  // Eval implements the TypedExpr interface.
  3997  func (expr *Subquery) Eval(ctx *EvalContext) (Datum, error) {
  3998  	return ctx.Planner.EvalSubquery(expr)
  3999  }
  4000  
  4001  // Eval implements the TypedExpr interface.
  4002  func (t *ArrayFlatten) Eval(ctx *EvalContext) (Datum, error) {
  4003  	array, err := arrayOfType(t.ResolvedType())
  4004  	if err != nil {
  4005  		return nil, err
  4006  	}
  4007  
  4008  	d, err := t.Subquery.(TypedExpr).Eval(ctx)
  4009  	if err != nil {
  4010  		return nil, err
  4011  	}
  4012  
  4013  	tuple, ok := d.(*DTuple)
  4014  	if !ok {
  4015  		return nil, errors.AssertionFailedf("array subquery result (%v) is not DTuple", d)
  4016  	}
  4017  	array.Array = tuple.D
  4018  	return array, nil
  4019  }
  4020  
  4021  // Eval implements the TypedExpr interface.
  4022  func (t *DBitArray) Eval(_ *EvalContext) (Datum, error) {
  4023  	return t, nil
  4024  }
  4025  
  4026  // Eval implements the TypedExpr interface.
  4027  func (t *DBool) Eval(_ *EvalContext) (Datum, error) {
  4028  	return t, nil
  4029  }
  4030  
  4031  // Eval implements the TypedExpr interface.
  4032  func (t *DBytes) Eval(_ *EvalContext) (Datum, error) {
  4033  	return t, nil
  4034  }
  4035  
  4036  // Eval implements the TypedExpr interface.
  4037  func (t *DUuid) Eval(_ *EvalContext) (Datum, error) {
  4038  	return t, nil
  4039  }
  4040  
  4041  // Eval implements the TypedExpr interface.
  4042  func (t *DIPAddr) Eval(_ *EvalContext) (Datum, error) {
  4043  	return t, nil
  4044  }
  4045  
  4046  // Eval implements the TypedExpr interface.
  4047  func (t *DDate) Eval(_ *EvalContext) (Datum, error) {
  4048  	return t, nil
  4049  }
  4050  
  4051  // Eval implements the TypedExpr interface.
  4052  func (t *DTime) Eval(_ *EvalContext) (Datum, error) {
  4053  	return t, nil
  4054  }
  4055  
  4056  // Eval implements the TypedExpr interface.
  4057  func (t *DTimeTZ) Eval(_ *EvalContext) (Datum, error) {
  4058  	return t, nil
  4059  }
  4060  
  4061  // Eval implements the TypedExpr interface.
  4062  func (t *DFloat) Eval(_ *EvalContext) (Datum, error) {
  4063  	return t, nil
  4064  }
  4065  
  4066  // Eval implements the TypedExpr interface.
  4067  func (t *DDecimal) Eval(_ *EvalContext) (Datum, error) {
  4068  	return t, nil
  4069  }
  4070  
  4071  // Eval implements the TypedExpr interface.
  4072  func (t *DInt) Eval(_ *EvalContext) (Datum, error) {
  4073  	return t, nil
  4074  }
  4075  
  4076  // Eval implements the TypedExpr interface.
  4077  func (t *DInterval) Eval(_ *EvalContext) (Datum, error) {
  4078  	return t, nil
  4079  }
  4080  
  4081  // Eval implements the TypedExpr interface.
  4082  func (t *DGeography) Eval(_ *EvalContext) (Datum, error) {
  4083  	return t, nil
  4084  }
  4085  
  4086  // Eval implements the TypedExpr interface.
  4087  func (t *DGeometry) Eval(_ *EvalContext) (Datum, error) {
  4088  	return t, nil
  4089  }
  4090  
  4091  // Eval implements the TypedExpr interface.
  4092  func (t *DEnum) Eval(_ *EvalContext) (Datum, error) {
  4093  	return t, nil
  4094  }
  4095  
  4096  // Eval implements the TypedExpr interface.
  4097  func (t *DJSON) Eval(_ *EvalContext) (Datum, error) {
  4098  	return t, nil
  4099  }
  4100  
  4101  // Eval implements the TypedExpr interface.
  4102  func (t dNull) Eval(_ *EvalContext) (Datum, error) {
  4103  	return t, nil
  4104  }
  4105  
  4106  // Eval implements the TypedExpr interface.
  4107  func (t *DString) Eval(_ *EvalContext) (Datum, error) {
  4108  	return t, nil
  4109  }
  4110  
  4111  // Eval implements the TypedExpr interface.
  4112  func (t *DCollatedString) Eval(_ *EvalContext) (Datum, error) {
  4113  	return t, nil
  4114  }
  4115  
  4116  // Eval implements the TypedExpr interface.
  4117  func (t *DTimestamp) Eval(_ *EvalContext) (Datum, error) {
  4118  	return t, nil
  4119  }
  4120  
  4121  // Eval implements the TypedExpr interface.
  4122  func (t *DTimestampTZ) Eval(_ *EvalContext) (Datum, error) {
  4123  	return t, nil
  4124  }
  4125  
  4126  // Eval implements the TypedExpr interface.
  4127  func (t *DTuple) Eval(_ *EvalContext) (Datum, error) {
  4128  	return t, nil
  4129  }
  4130  
  4131  // Eval implements the TypedExpr interface.
  4132  func (t *DArray) Eval(_ *EvalContext) (Datum, error) {
  4133  	return t, nil
  4134  }
  4135  
  4136  // Eval implements the TypedExpr interface.
  4137  func (t *DOid) Eval(_ *EvalContext) (Datum, error) {
  4138  	return t, nil
  4139  }
  4140  
  4141  // Eval implements the TypedExpr interface.
  4142  func (t *DOidWrapper) Eval(_ *EvalContext) (Datum, error) {
  4143  	return t, nil
  4144  }
  4145  
  4146  // Eval implements the TypedExpr interface.
  4147  func (t *Placeholder) Eval(ctx *EvalContext) (Datum, error) {
  4148  	if !ctx.HasPlaceholders() {
  4149  		// While preparing a query, there will be no available placeholders. A
  4150  		// placeholder evaluates to itself at this point.
  4151  		return t, nil
  4152  	}
  4153  	e, ok := ctx.Placeholders.Value(t.Idx)
  4154  	if !ok {
  4155  		return nil, pgerror.Newf(pgcode.UndefinedParameter,
  4156  			"no value provided for placeholder: %s", t)
  4157  	}
  4158  	// Placeholder expressions cannot contain other placeholders, so we do
  4159  	// not need to recurse.
  4160  	typ := ctx.Placeholders.Types[t.Idx]
  4161  	if typ == nil {
  4162  		// All placeholders should be typed at this point.
  4163  		return nil, errors.AssertionFailedf("missing type for placeholder %s", t)
  4164  	}
  4165  	if !e.ResolvedType().Equivalent(typ) {
  4166  		// This happens when we overrode the placeholder's type during type
  4167  		// checking, since the placeholder's type hint didn't match the desired
  4168  		// type for the placeholder. In this case, we cast the expression to
  4169  		// the desired type.
  4170  		// TODO(jordan): introduce a restriction on what casts are allowed here.
  4171  		cast := NewTypedCastExpr(e, typ)
  4172  		return cast.Eval(ctx)
  4173  	}
  4174  	return e.Eval(ctx)
  4175  }
  4176  
  4177  func evalComparison(ctx *EvalContext, op ComparisonOperator, left, right Datum) (Datum, error) {
  4178  	if left == DNull || right == DNull {
  4179  		return DNull, nil
  4180  	}
  4181  	ltype := left.ResolvedType()
  4182  	rtype := right.ResolvedType()
  4183  	if fn, ok := CmpOps[op].LookupImpl(ltype, rtype); ok {
  4184  		return fn.Fn(ctx, left, right)
  4185  	}
  4186  	return nil, pgerror.Newf(
  4187  		pgcode.UndefinedFunction, "unsupported comparison operator: <%s> %s <%s>", ltype, op, rtype)
  4188  }
  4189  
  4190  // foldComparisonExpr folds a given comparison operation and its expressions
  4191  // into an equivalent operation that will hit in the CmpOps map, returning
  4192  // this new operation, along with potentially flipped operands and "flipped"
  4193  // and "not" flags.
  4194  func foldComparisonExpr(
  4195  	op ComparisonOperator, left, right Expr,
  4196  ) (newOp ComparisonOperator, newLeft Expr, newRight Expr, flipped bool, not bool) {
  4197  	switch op {
  4198  	case NE:
  4199  		// NE(left, right) is implemented as !EQ(left, right).
  4200  		return EQ, left, right, false, true
  4201  	case GT:
  4202  		// GT(left, right) is implemented as LT(right, left)
  4203  		return LT, right, left, true, false
  4204  	case GE:
  4205  		// GE(left, right) is implemented as LE(right, left)
  4206  		return LE, right, left, true, false
  4207  	case NotIn:
  4208  		// NotIn(left, right) is implemented as !IN(left, right)
  4209  		return In, left, right, false, true
  4210  	case NotLike:
  4211  		// NotLike(left, right) is implemented as !Like(left, right)
  4212  		return Like, left, right, false, true
  4213  	case NotILike:
  4214  		// NotILike(left, right) is implemented as !ILike(left, right)
  4215  		return ILike, left, right, false, true
  4216  	case NotSimilarTo:
  4217  		// NotSimilarTo(left, right) is implemented as !SimilarTo(left, right)
  4218  		return SimilarTo, left, right, false, true
  4219  	case NotRegMatch:
  4220  		// NotRegMatch(left, right) is implemented as !RegMatch(left, right)
  4221  		return RegMatch, left, right, false, true
  4222  	case NotRegIMatch:
  4223  		// NotRegIMatch(left, right) is implemented as !RegIMatch(left, right)
  4224  		return RegIMatch, left, right, false, true
  4225  	case IsDistinctFrom:
  4226  		// IsDistinctFrom(left, right) is implemented as !IsNotDistinctFrom(left, right)
  4227  		// Note: this seems backwards, but IS NOT DISTINCT FROM is an extended
  4228  		// version of IS and IS DISTINCT FROM is an extended version of IS NOT.
  4229  		return IsNotDistinctFrom, left, right, false, true
  4230  	}
  4231  	return op, left, right, false, false
  4232  }
  4233  
  4234  // hasUnescapedSuffix returns true if the ending byte is suffix and s has an
  4235  // even number of escapeTokens preceding suffix. Otherwise hasUnescapedSuffix
  4236  // will return false.
  4237  func hasUnescapedSuffix(s string, suffix byte, escapeToken string) bool {
  4238  	if s[len(s)-1] == suffix {
  4239  		var count int
  4240  		idx := len(s) - len(escapeToken) - 1
  4241  		for idx >= 0 && s[idx:idx+len(escapeToken)] == escapeToken {
  4242  			count++
  4243  			idx -= len(escapeToken)
  4244  		}
  4245  		return count%2 == 0
  4246  	}
  4247  	return false
  4248  }
  4249  
  4250  // Simplifies LIKE/ILIKE expressions that do not need full regular expressions to
  4251  // evaluate the condition. For example, when the expression is just checking to see
  4252  // if a string starts with a given pattern.
  4253  func optimizedLikeFunc(
  4254  	pattern string, caseInsensitive bool, escape rune,
  4255  ) (func(string) (bool, error), error) {
  4256  	switch len(pattern) {
  4257  	case 0:
  4258  		return func(s string) (bool, error) {
  4259  			return s == "", nil
  4260  		}, nil
  4261  	case 1:
  4262  		switch pattern[0] {
  4263  		case '%':
  4264  			if escape == '%' {
  4265  				return nil, pgerror.Newf(pgcode.InvalidEscapeSequence, "LIKE pattern must not end with escape character")
  4266  			}
  4267  			return func(s string) (bool, error) {
  4268  				return true, nil
  4269  			}, nil
  4270  		case '_':
  4271  			if escape == '_' {
  4272  				return nil, pgerror.Newf(pgcode.InvalidEscapeSequence, "LIKE pattern must not end with escape character")
  4273  			}
  4274  			return func(s string) (bool, error) {
  4275  				if len(s) == 0 {
  4276  					return false, nil
  4277  				}
  4278  				firstChar, _ := utf8.DecodeRuneInString(s)
  4279  				if firstChar == utf8.RuneError {
  4280  					return false, errors.Errorf("invalid encoding of the first character in string %s", s)
  4281  				}
  4282  				return len(s) == len(string(firstChar)), nil
  4283  			}, nil
  4284  		}
  4285  	default:
  4286  		if !strings.ContainsAny(pattern[1:len(pattern)-1], "_%") {
  4287  			// Patterns with even number of escape characters preceding the ending
  4288  			// `%` will have anyEnd set to true (if `%` itself is not an escape
  4289  			// character). Otherwise anyEnd will be set to false.
  4290  			anyEnd := hasUnescapedSuffix(pattern, '%', string(escape)) && escape != '%'
  4291  			// If '%' is the escape character, then it's not a wildcard.
  4292  			anyStart := pattern[0] == '%' && escape != '%'
  4293  
  4294  			// Patterns with even number of escape characters preceding the ending
  4295  			// `_` will have singleAnyEnd set to true (if `_` itself is not an escape
  4296  			// character). Otherwise singleAnyEnd will be set to false.
  4297  			singleAnyEnd := hasUnescapedSuffix(pattern, '_', string(escape)) && escape != '_'
  4298  			// If '_' is the escape character, then it's not a wildcard.
  4299  			singleAnyStart := pattern[0] == '_' && escape != '_'
  4300  
  4301  			// Since we've already checked for escaped characters
  4302  			// at the end, we can un-escape every character.
  4303  			// This is required since we do direct string
  4304  			// comparison.
  4305  			var err error
  4306  			if pattern, err = unescapePattern(pattern, string(escape), true /* emitEscapeCharacterLastError */); err != nil {
  4307  				return nil, err
  4308  			}
  4309  			switch {
  4310  			case anyEnd && anyStart:
  4311  				return func(s string) (bool, error) {
  4312  					substr := pattern[1 : len(pattern)-1]
  4313  					if caseInsensitive {
  4314  						s, substr = strings.ToUpper(s), strings.ToUpper(substr)
  4315  					}
  4316  					return strings.Contains(s, substr), nil
  4317  				}, nil
  4318  
  4319  			case anyEnd:
  4320  				return func(s string) (bool, error) {
  4321  					prefix := pattern[:len(pattern)-1]
  4322  					if singleAnyStart {
  4323  						if len(s) == 0 {
  4324  							return false, nil
  4325  						}
  4326  						prefix = prefix[1:]
  4327  						firstChar, _ := utf8.DecodeRuneInString(s)
  4328  						if firstChar == utf8.RuneError {
  4329  							return false, errors.Errorf("invalid encoding of the first character in string %s", s)
  4330  						}
  4331  						s = s[len(string(firstChar)):]
  4332  					}
  4333  					if caseInsensitive {
  4334  						s, prefix = strings.ToUpper(s), strings.ToUpper(prefix)
  4335  					}
  4336  					return strings.HasPrefix(s, prefix), nil
  4337  				}, nil
  4338  
  4339  			case anyStart:
  4340  				return func(s string) (bool, error) {
  4341  					suffix := pattern[1:]
  4342  					if singleAnyEnd {
  4343  						if len(s) == 0 {
  4344  							return false, nil
  4345  						}
  4346  
  4347  						suffix = suffix[:len(suffix)-1]
  4348  						lastChar, _ := utf8.DecodeLastRuneInString(s)
  4349  						if lastChar == utf8.RuneError {
  4350  							return false, errors.Errorf("invalid encoding of the last character in string %s", s)
  4351  						}
  4352  						s = s[:len(s)-len(string(lastChar))]
  4353  					}
  4354  					if caseInsensitive {
  4355  						s, suffix = strings.ToUpper(s), strings.ToUpper(suffix)
  4356  					}
  4357  					return strings.HasSuffix(s, suffix), nil
  4358  				}, nil
  4359  
  4360  			case singleAnyStart || singleAnyEnd:
  4361  				return func(s string) (bool, error) {
  4362  					if len(s) < 1 {
  4363  						return false, nil
  4364  					}
  4365  					firstChar, _ := utf8.DecodeRuneInString(s)
  4366  					if firstChar == utf8.RuneError {
  4367  						return false, errors.Errorf("invalid encoding of the first character in string %s", s)
  4368  					}
  4369  					lastChar, _ := utf8.DecodeLastRuneInString(s)
  4370  					if lastChar == utf8.RuneError {
  4371  						return false, errors.Errorf("invalid encoding of the last character in string %s", s)
  4372  					}
  4373  					if singleAnyStart && singleAnyEnd && len(string(firstChar))+len(string(lastChar)) > len(s) {
  4374  						return false, nil
  4375  					}
  4376  
  4377  					if singleAnyStart {
  4378  						pattern = pattern[1:]
  4379  						s = s[len(string(firstChar)):]
  4380  					}
  4381  
  4382  					if singleAnyEnd {
  4383  						pattern = pattern[:len(pattern)-1]
  4384  						s = s[:len(s)-len(string(lastChar))]
  4385  					}
  4386  
  4387  					if caseInsensitive {
  4388  						s, pattern = strings.ToUpper(s), strings.ToUpper(pattern)
  4389  					}
  4390  
  4391  					// We don't have to check for
  4392  					// prefixes/suffixes since we do not
  4393  					// have '%':
  4394  					//  - singleAnyEnd && anyStart handled
  4395  					//    in case anyStart
  4396  					//  - singleAnyStart && anyEnd handled
  4397  					//    in case anyEnd
  4398  					return s == pattern, nil
  4399  				}, nil
  4400  			}
  4401  		}
  4402  	}
  4403  	return nil, nil
  4404  }
  4405  
  4406  type likeKey struct {
  4407  	s               string
  4408  	caseInsensitive bool
  4409  	escape          rune
  4410  }
  4411  
  4412  // unescapePattern unescapes a pattern for a given escape token.
  4413  // It handles escaped escape tokens properly by maintaining them as the escape
  4414  // token in the return string.
  4415  // For example, suppose we have escape token `\` (e.g. `B` is escaped in
  4416  // `A\BC` and `\` is escaped in `A\\C`).
  4417  // We need to convert
  4418  //    `\` --> ``
  4419  //    `\\` --> `\`
  4420  // We cannot simply use strings.Replace for each conversion since the first
  4421  // conversion will incorrectly replace our escaped escape token `\\` with ``.
  4422  // Another example is if our escape token is `\\` (e.g. after
  4423  // regexp.QuoteMeta).
  4424  // We need to convert
  4425  //    `\\` --> ``
  4426  //    `\\\\` --> `\\`
  4427  func unescapePattern(
  4428  	pattern, escapeToken string, emitEscapeCharacterLastError bool,
  4429  ) (string, error) {
  4430  	escapedEscapeToken := escapeToken + escapeToken
  4431  
  4432  	// We need to subtract the escaped escape tokens to avoid double
  4433  	// counting.
  4434  	nEscapes := strings.Count(pattern, escapeToken) - strings.Count(pattern, escapedEscapeToken)
  4435  	if nEscapes == 0 {
  4436  		return pattern, nil
  4437  	}
  4438  
  4439  	// Allocate buffer for final un-escaped pattern.
  4440  	ret := make([]byte, len(pattern)-nEscapes*len(escapeToken))
  4441  	retWidth := 0
  4442  	for i := 0; i < nEscapes; i++ {
  4443  		nextIdx := strings.Index(pattern, escapeToken)
  4444  		if nextIdx == len(pattern)-len(escapeToken) && emitEscapeCharacterLastError {
  4445  			return "", pgerror.Newf(pgcode.InvalidEscapeSequence, `LIKE pattern must not end with escape character`)
  4446  		}
  4447  
  4448  		retWidth += copy(ret[retWidth:], pattern[:nextIdx])
  4449  
  4450  		if nextIdx < len(pattern)-len(escapedEscapeToken) && pattern[nextIdx:nextIdx+len(escapedEscapeToken)] == escapedEscapeToken {
  4451  			// We have an escaped escape token.
  4452  			// We want to keep it as the original escape token in
  4453  			// the return string.
  4454  			retWidth += copy(ret[retWidth:], escapeToken)
  4455  			pattern = pattern[nextIdx+len(escapedEscapeToken):]
  4456  			continue
  4457  		}
  4458  
  4459  		// Skip over the escape character we removed.
  4460  		pattern = pattern[nextIdx+len(escapeToken):]
  4461  	}
  4462  
  4463  	retWidth += copy(ret[retWidth:], pattern)
  4464  	return string(ret[0:retWidth]), nil
  4465  }
  4466  
  4467  // replaceUnescaped replaces all instances of oldStr that are not escaped (read:
  4468  // preceded) with the specified unescape token with newStr.
  4469  // For example, with an escape token of `\\`
  4470  //    replaceUnescaped("TE\\__ST", "_", ".", `\\`) --> "TE\\_.ST"
  4471  //    replaceUnescaped("TE\\%%ST", "%", ".*", `\\`) --> "TE\\%.*ST"
  4472  // If the preceding escape token is escaped, then oldStr will be replaced.
  4473  // For example
  4474  //    replaceUnescaped("TE\\\\_ST", "_", ".", `\\`) --> "TE\\\\.ST"
  4475  func replaceUnescaped(s, oldStr, newStr string, escapeToken string) string {
  4476  	// We count the number of occurrences of 'oldStr'.
  4477  	// This however can be an overestimate since the oldStr token could be
  4478  	// escaped.  e.g. `\\_`.
  4479  	nOld := strings.Count(s, oldStr)
  4480  	if nOld == 0 {
  4481  		return s
  4482  	}
  4483  
  4484  	// Allocate buffer for final string.
  4485  	// This can be an overestimate since some of the oldStr tokens may
  4486  	// be escaped.
  4487  	// This is fine since we keep track of the running number of bytes
  4488  	// actually copied.
  4489  	// It's rather difficult to count the exact number of unescaped
  4490  	// tokens without manually iterating through the entire string and
  4491  	// keeping track of escaped escape tokens.
  4492  	retLen := len(s)
  4493  	// If len(newStr) - len(oldStr) < 0, then this can under-allocate which
  4494  	// will not behave correctly with copy.
  4495  	if addnBytes := nOld * (len(newStr) - len(oldStr)); addnBytes > 0 {
  4496  		retLen += addnBytes
  4497  	}
  4498  	ret := make([]byte, retLen)
  4499  	retWidth := 0
  4500  	start := 0
  4501  OldLoop:
  4502  	for i := 0; i < nOld; i++ {
  4503  		nextIdx := start + strings.Index(s[start:], oldStr)
  4504  
  4505  		escaped := false
  4506  		for {
  4507  			// We need to look behind to check if the escape token
  4508  			// is really an escape token.
  4509  			// E.g. if our specified escape token is `\\` and oldStr
  4510  			// is `_`, then
  4511  			//    `\\_` --> escaped
  4512  			//    `\\\\_` --> not escaped
  4513  			//    `\\\\\\_` --> escaped
  4514  			curIdx := nextIdx
  4515  			lookbehindIdx := curIdx - len(escapeToken)
  4516  			for lookbehindIdx >= 0 && s[lookbehindIdx:curIdx] == escapeToken {
  4517  				escaped = !escaped
  4518  				curIdx = lookbehindIdx
  4519  				lookbehindIdx = curIdx - len(escapeToken)
  4520  			}
  4521  
  4522  			// The token was not be escaped. Proceed.
  4523  			if !escaped {
  4524  				break
  4525  			}
  4526  
  4527  			// Token was escaped. Copy everything over and continue.
  4528  			retWidth += copy(ret[retWidth:], s[start:nextIdx+len(oldStr)])
  4529  			start = nextIdx + len(oldStr)
  4530  
  4531  			// Continue with next oldStr token.
  4532  			continue OldLoop
  4533  		}
  4534  
  4535  		// Token was not escaped so we replace it with newStr.
  4536  		// Two copies is more efficient than concatenating the slices.
  4537  		retWidth += copy(ret[retWidth:], s[start:nextIdx])
  4538  		retWidth += copy(ret[retWidth:], newStr)
  4539  		start = nextIdx + len(oldStr)
  4540  	}
  4541  
  4542  	retWidth += copy(ret[retWidth:], s[start:])
  4543  	return string(ret[0:retWidth])
  4544  }
  4545  
  4546  // Replaces all custom escape characters in s with `\\` only when they are unescaped.          (1)
  4547  // E.g. original pattern       after QuoteMeta       after replaceCustomEscape with '@' as escape
  4548  //        '@w@w'          ->      '@w@w'        ->        '\\w\\w'
  4549  //        '@\@\'          ->      '@\\@\\'      ->        '\\\\\\\\'
  4550  //
  4551  // When an escape character is escaped, we replace it with its single occurrence.              (2)
  4552  // E.g. original pattern       after QuoteMeta       after replaceCustomEscape with '@' as escape
  4553  //        '@@w@w'         ->      '@@w@w'       ->        '@w\\w'
  4554  //        '@@@\'          ->      '@@@\\'       ->        '@\\\\'
  4555  //
  4556  // At the same time, we do not want to confuse original backslashes (which
  4557  // after QuoteMeta are '\\') with backslashes that replace our custom escape characters,
  4558  // so we escape these original backslashes again by converting '\\' into '\\\\'.               (3)
  4559  // E.g. original pattern       after QuoteMeta       after replaceCustomEscape with '@' as escape
  4560  //        '@\'            ->      '@\\'         ->        '\\\\\\'
  4561  //        '@\@@@\'        ->      '@\\@@@\\'    ->        '\\\\\\@\\\\\\'
  4562  //
  4563  // Explanation of the last example:
  4564  // 1. we replace '@' with '\\' since it's unescaped;
  4565  // 2. we escape single original backslash ('\' is not our escape character, so we want
  4566  // the pattern to understand it) by putting an extra backslash in front of it. However,
  4567  // we later will call unescapePattern, so we need to double our double backslashes.
  4568  // Therefore, '\\' is converted into '\\\\'.
  4569  // 3. '@@' is replaced by '@' because it is escaped escape character.
  4570  // 4. '@' is replaced with '\\' since it's unescaped.
  4571  // 5. Similar logic to step 2: '\\' -> '\\\\'.
  4572  //
  4573  // We always need to keep in mind that later call of unescapePattern
  4574  // to actually unescape '\\' and '\\\\' is necessary and that
  4575  // escape must be a single unicode character and not `\`.
  4576  func replaceCustomEscape(s string, escape rune) (string, error) {
  4577  	changed, retLen, err := calculateLengthAfterReplacingCustomEscape(s, escape)
  4578  	if err != nil {
  4579  		return "", err
  4580  	}
  4581  	if !changed {
  4582  		return s, nil
  4583  	}
  4584  
  4585  	sLen := len(s)
  4586  	ret := make([]byte, retLen)
  4587  	retIndex, sIndex := 0, 0
  4588  	for retIndex < retLen {
  4589  		sRune, w := utf8.DecodeRuneInString(s[sIndex:])
  4590  		if sRune == escape {
  4591  			// We encountered an escape character.
  4592  			if sIndex+w < sLen {
  4593  				// Escape character is not the last character in s, so we need
  4594  				// to look ahead to figure out how to process it.
  4595  				tRune, _ := utf8.DecodeRuneInString(s[(sIndex + w):])
  4596  				if tRune == escape {
  4597  					// Escape character is escaped, so we replace its two occurrences with just one. See (2).
  4598  					// We copied only one escape character to ret, so we advance retIndex only by w.
  4599  					// Since we've already processed two characters in s, we advance sIndex by 2*w.
  4600  					utf8.EncodeRune(ret[retIndex:], escape)
  4601  					retIndex += w
  4602  					sIndex += 2 * w
  4603  				} else {
  4604  					// Escape character is unescaped, so we replace it with `\\`. See (1).
  4605  					// Since we've added two bytes to ret, we advance retIndex by 2.
  4606  					// We processed only a single escape character in s, we advance sIndex by w.
  4607  					ret[retIndex] = '\\'
  4608  					ret[retIndex+1] = '\\'
  4609  					retIndex += 2
  4610  					sIndex += w
  4611  				}
  4612  			} else {
  4613  				// Escape character is the last character in s which is an error
  4614  				// that must have been caught in calculateLengthAfterReplacingCustomEscape.
  4615  				return "", errors.AssertionFailedf(
  4616  					"unexpected: escape character is the last one in replaceCustomEscape.")
  4617  			}
  4618  		} else if s[sIndex] == '\\' {
  4619  			// We encountered a backslash, so we need to look ahead to figure out how
  4620  			// to process it.
  4621  			if sIndex+1 == sLen {
  4622  				// This case should never be reached since it should
  4623  				// have been caught in calculateLengthAfterReplacingCustomEscape.
  4624  				return "", errors.AssertionFailedf(
  4625  					"unexpected: a single backslash encountered in replaceCustomEscape.")
  4626  			} else if s[sIndex+1] == '\\' {
  4627  				// We want to escape '\\' to `\\\\` for correct processing later by unescapePattern. See (3).
  4628  				// Since we've added four characters to ret, we advance retIndex by 4.
  4629  				// Since we've already processed two characters in s, we advance sIndex by 2.
  4630  				ret[retIndex] = '\\'
  4631  				ret[retIndex+1] = '\\'
  4632  				ret[retIndex+2] = '\\'
  4633  				ret[retIndex+3] = '\\'
  4634  				retIndex += 4
  4635  				sIndex += 2
  4636  			} else {
  4637  				// A metacharacter other than a backslash is escaped here.
  4638  				// Note: all metacharacters are encoded as a single byte, so it is
  4639  				// correct to just convert it to string and to compare against a char
  4640  				// in s.
  4641  				if string(s[sIndex+1]) == string(escape) {
  4642  					// The metacharacter is our custom escape character. We need to look
  4643  					// ahead to process it.
  4644  					if sIndex+2 == sLen {
  4645  						// Escape character is the last character in s which is an error
  4646  						// that must have been caught in calculateLengthAfterReplacingCustomEscape.
  4647  						return "", errors.AssertionFailedf(
  4648  							"unexpected: escape character is the last one in replaceCustomEscape.")
  4649  					}
  4650  					if sIndex+4 <= sLen {
  4651  						if s[sIndex+2] == '\\' && string(s[sIndex+3]) == string(escape) {
  4652  							// We have a sequence of `\`+escape+`\`+escape which is replaced
  4653  							// by `\`+escape.
  4654  							ret[retIndex] = '\\'
  4655  							// Note: all metacharacters are encoded as a single byte, so it
  4656  							// is safe to just convert it to string and take the first
  4657  							// character.
  4658  							ret[retIndex+1] = string(escape)[0]
  4659  							retIndex += 2
  4660  							sIndex += 4
  4661  							continue
  4662  						}
  4663  					}
  4664  					// The metacharacter is escaping something different than itself, so
  4665  					// `\`+escape will be replaced by `\`.
  4666  					ret[retIndex] = '\\'
  4667  					retIndex++
  4668  					sIndex += 2
  4669  				} else {
  4670  					// The metacharacter is not our custom escape character, so we're
  4671  					// simply copying the backslash and the metacharacter.
  4672  					ret[retIndex] = '\\'
  4673  					ret[retIndex+1] = s[sIndex+1]
  4674  					retIndex += 2
  4675  					sIndex += 2
  4676  				}
  4677  			}
  4678  		} else {
  4679  			// Regular symbol, so we simply copy it.
  4680  			copy(ret[retIndex:], s[sIndex:sIndex+w])
  4681  			retIndex += w
  4682  			sIndex += w
  4683  		}
  4684  	}
  4685  	return string(ret), nil
  4686  }
  4687  
  4688  // calculateLengthAfterReplacingCustomEscape returns whether the pattern changes, the length
  4689  // of the resulting pattern after calling replaceCustomEscape, and any error if found.
  4690  func calculateLengthAfterReplacingCustomEscape(s string, escape rune) (bool, int, error) {
  4691  	changed := false
  4692  	retLen, sLen := 0, len(s)
  4693  	for i := 0; i < sLen; {
  4694  		sRune, w := utf8.DecodeRuneInString(s[i:])
  4695  		if sRune == escape {
  4696  			// We encountered an escape character.
  4697  			if i+w < sLen {
  4698  				// Escape character is not the last character in s, so we need
  4699  				// to look ahead to figure out how to process it.
  4700  				tRune, _ := utf8.DecodeRuneInString(s[(i + w):])
  4701  				if tRune == escape {
  4702  					// Escape character is escaped, so we'll replace its two occurrences with just one.
  4703  					// See (2) in the comment above replaceCustomEscape.
  4704  					changed = true
  4705  					retLen += w
  4706  					i += 2 * w
  4707  				} else {
  4708  					// Escape character is unescaped, so we'll replace it with `\\`.
  4709  					// See (1) in the comment above replaceCustomEscape.
  4710  					changed = true
  4711  					retLen += 2
  4712  					i += w
  4713  				}
  4714  			} else {
  4715  				// Escape character is the last character in s, so we need to return an error.
  4716  				return false, 0, pgerror.Newf(pgcode.InvalidEscapeSequence, "LIKE pattern must not end with escape character")
  4717  			}
  4718  		} else if s[i] == '\\' {
  4719  			// We encountered a backslash, so we need to look ahead to figure out how
  4720  			// to process it.
  4721  			if i+1 == sLen {
  4722  				// This case should never be reached because the backslash should be
  4723  				// escaping one of regexp metacharacters.
  4724  				return false, 0, pgerror.Newf(pgcode.InvalidEscapeSequence, "Unexpected behavior during processing custom escape character.")
  4725  			} else if s[i+1] == '\\' {
  4726  				// We'll want to escape '\\' to `\\\\` for correct processing later by
  4727  				// unescapePattern. See (3) in the comment above replaceCustomEscape.
  4728  				changed = true
  4729  				retLen += 4
  4730  				i += 2
  4731  			} else {
  4732  				// A metacharacter other than a backslash is escaped here.
  4733  				if string(s[i+1]) == string(escape) {
  4734  					// The metacharacter is our custom escape character. We need to look
  4735  					// ahead to process it.
  4736  					if i+2 == sLen {
  4737  						// Escape character is the last character in s, so we need to return an error.
  4738  						return false, 0, pgerror.Newf(pgcode.InvalidEscapeSequence, "LIKE pattern must not end with escape character")
  4739  					}
  4740  					if i+4 <= sLen {
  4741  						if s[i+2] == '\\' && string(s[i+3]) == string(escape) {
  4742  							// We have a sequence of `\`+escape+`\`+escape which will be
  4743  							// replaced by `\`+escape.
  4744  							changed = true
  4745  							retLen += 2
  4746  							i += 4
  4747  							continue
  4748  						}
  4749  					}
  4750  					// The metacharacter is escaping something different than itself, so
  4751  					// `\`+escape will be replaced by `\`.
  4752  					changed = true
  4753  					retLen++
  4754  					i += 2
  4755  				} else {
  4756  					// The metacharacter is not our custom escape character, so we're
  4757  					// simply copying the backslash and the metacharacter.
  4758  					retLen += 2
  4759  					i += 2
  4760  				}
  4761  			}
  4762  		} else {
  4763  			// Regular symbol, so we'll simply copy it.
  4764  			retLen += w
  4765  			i += w
  4766  		}
  4767  	}
  4768  	return changed, retLen, nil
  4769  }
  4770  
  4771  // Pattern implements the RegexpCacheKey interface.
  4772  // The strategy for handling custom escape character
  4773  // is to convert all unescaped escape character into '\'.
  4774  // k.escape can either be empty or a single character.
  4775  func (k likeKey) Pattern() (string, error) {
  4776  	// QuoteMeta escapes all regexp metacharacters (`\.+*?()|[]{}^$`) with a `\`.
  4777  	pattern := regexp.QuoteMeta(k.s)
  4778  	var err error
  4779  	if k.escape == 0 {
  4780  		// Replace all LIKE/ILIKE specific wildcards with standard wildcards
  4781  		// (escape character is empty - escape mechanism is turned off - so
  4782  		// all '%' and '_' are actual wildcards regardless of what precedes them.
  4783  		pattern = strings.Replace(pattern, `%`, `.*`, -1)
  4784  		pattern = strings.Replace(pattern, `_`, `.`, -1)
  4785  	} else if k.escape == '\\' {
  4786  		// Replace LIKE/ILIKE specific wildcards with standard wildcards only when
  4787  		// these wildcards are not escaped by '\\' (equivalent of '\' after QuoteMeta).
  4788  		pattern = replaceUnescaped(pattern, `%`, `.*`, `\\`)
  4789  		pattern = replaceUnescaped(pattern, `_`, `.`, `\\`)
  4790  	} else {
  4791  		// k.escape is non-empty and not `\`.
  4792  		// If `%` is escape character, then it's not a wildcard.
  4793  		if k.escape != '%' {
  4794  			// Replace LIKE/ILIKE specific wildcards '%' only if it's unescaped.
  4795  			if k.escape == '.' {
  4796  				// '.' is the escape character, so for correct processing later by
  4797  				// replaceCustomEscape we need to escape it by itself.
  4798  				pattern = replaceUnescaped(pattern, `%`, `..*`, regexp.QuoteMeta(string(k.escape)))
  4799  			} else if k.escape == '*' {
  4800  				// '*' is the escape character, so for correct processing later by
  4801  				// replaceCustomEscape we need to escape it by itself.
  4802  				pattern = replaceUnescaped(pattern, `%`, `.**`, regexp.QuoteMeta(string(k.escape)))
  4803  			} else {
  4804  				pattern = replaceUnescaped(pattern, `%`, `.*`, regexp.QuoteMeta(string(k.escape)))
  4805  			}
  4806  		}
  4807  		// If `_` is escape character, then it's not a wildcard.
  4808  		if k.escape != '_' {
  4809  			// Replace LIKE/ILIKE specific wildcards '_' only if it's unescaped.
  4810  			if k.escape == '.' {
  4811  				// '.' is the escape character, so for correct processing later by
  4812  				// replaceCustomEscape we need to escape it by itself.
  4813  				pattern = replaceUnescaped(pattern, `_`, `..`, regexp.QuoteMeta(string(k.escape)))
  4814  			} else {
  4815  				pattern = replaceUnescaped(pattern, `_`, `.`, regexp.QuoteMeta(string(k.escape)))
  4816  			}
  4817  		}
  4818  
  4819  		// If a sequence of symbols ` escape+`\\` ` is unescaped, then that escape
  4820  		// character escapes backslash in the original pattern (we need to use double
  4821  		// backslash because of QuoteMeta behavior), so we want to "consume" the escape character.
  4822  		pattern = replaceUnescaped(pattern, string(k.escape)+`\\`, `\\`, regexp.QuoteMeta(string(k.escape)))
  4823  
  4824  		// We want to replace all escape characters with `\\` only
  4825  		// when they are unescaped. When an escape character is escaped,
  4826  		// we replace it with its single occurrence.
  4827  		if pattern, err = replaceCustomEscape(pattern, k.escape); err != nil {
  4828  			return pattern, err
  4829  		}
  4830  	}
  4831  
  4832  	// After QuoteMeta, all '\' were converted to '\\'.
  4833  	// After replaceCustomEscape, our custom unescaped escape characters were converted to `\\`,
  4834  	// so now our pattern contains only '\\' as escape tokens.
  4835  	// We need to unescape escaped escape tokens `\\` (now `\\\\`) and
  4836  	// other escaped characters `\A` (now `\\A`).
  4837  	if k.escape != 0 {
  4838  		// We do not want to return an error when pattern ends with the supposed escape character `\`
  4839  		// whereas the actual escape character is not `\`. The case when the pattern ends with
  4840  		// an actual escape character is handled in replaceCustomEscape. For example, with '-' as
  4841  		// the escape character on pattern 'abc\\' we do not want to return an error 'pattern ends
  4842  		// with escape character' because '\\' is not an escape character in this case.
  4843  		if pattern, err = unescapePattern(
  4844  			pattern,
  4845  			`\\`,
  4846  			k.escape == '\\', /* emitEscapeCharacterLastError */
  4847  		); err != nil {
  4848  			return "", err
  4849  		}
  4850  	}
  4851  
  4852  	return anchorPattern(pattern, k.caseInsensitive), nil
  4853  }
  4854  
  4855  type similarToKey struct {
  4856  	s      string
  4857  	escape rune
  4858  }
  4859  
  4860  // Pattern implements the RegexpCacheKey interface.
  4861  func (k similarToKey) Pattern() (string, error) {
  4862  	pattern := similarEscapeCustomChar(k.s, k.escape, k.escape != 0)
  4863  	return anchorPattern(pattern, false), nil
  4864  }
  4865  
  4866  // SimilarToEscape checks if 'unescaped' is SIMILAR TO 'pattern' using custom escape token 'escape'
  4867  // which must be either empty (which disables the escape mechanism) or a single unicode character.
  4868  func SimilarToEscape(ctx *EvalContext, unescaped, pattern, escape string) (Datum, error) {
  4869  	var escapeRune rune
  4870  	if len(escape) > 0 {
  4871  		var width int
  4872  		escapeRune, width = utf8.DecodeRuneInString(escape)
  4873  		if len(escape) > width {
  4874  			return DBoolFalse, pgerror.Newf(pgcode.InvalidEscapeSequence, "invalid escape string")
  4875  		}
  4876  	}
  4877  	key := similarToKey{s: pattern, escape: escapeRune}
  4878  	return matchRegexpWithKey(ctx, NewDString(unescaped), key)
  4879  }
  4880  
  4881  type regexpKey struct {
  4882  	s               string
  4883  	caseInsensitive bool
  4884  }
  4885  
  4886  // Pattern implements the RegexpCacheKey interface.
  4887  func (k regexpKey) Pattern() (string, error) {
  4888  	if k.caseInsensitive {
  4889  		return caseInsensitive(k.s), nil
  4890  	}
  4891  	return k.s, nil
  4892  }
  4893  
  4894  // SimilarEscape converts a SQL:2008 regexp pattern to POSIX style, so it can
  4895  // be used by our regexp engine.
  4896  func SimilarEscape(pattern string) string {
  4897  	return similarEscapeCustomChar(pattern, '\\', true)
  4898  }
  4899  
  4900  // similarEscapeCustomChar converts a SQL:2008 regexp pattern to POSIX style,
  4901  // so it can be used by our regexp engine. This version of the function allows
  4902  // for a custom escape character.
  4903  // 'isEscapeNonEmpty' signals whether 'escapeChar' should be treated as empty.
  4904  func similarEscapeCustomChar(pattern string, escapeChar rune, isEscapeNonEmpty bool) string {
  4905  	patternBuilder := make([]rune, 0, utf8.RuneCountInString(pattern))
  4906  
  4907  	inCharClass := false
  4908  	afterEscape := false
  4909  	numQuotes := 0
  4910  	for _, c := range pattern {
  4911  		switch {
  4912  		case afterEscape:
  4913  			// For SUBSTRING patterns
  4914  			if c == '"' && !inCharClass {
  4915  				if numQuotes%2 == 0 {
  4916  					patternBuilder = append(patternBuilder, '(')
  4917  				} else {
  4918  					patternBuilder = append(patternBuilder, ')')
  4919  				}
  4920  				numQuotes++
  4921  			} else if c == escapeChar && len(string(escapeChar)) > 1 {
  4922  				// We encountered escaped escape unicode character represented by at least two bytes,
  4923  				// so we keep only its single occurrence and need not to prepend it by '\'.
  4924  				patternBuilder = append(patternBuilder, c)
  4925  			} else {
  4926  				patternBuilder = append(patternBuilder, '\\', c)
  4927  			}
  4928  			afterEscape = false
  4929  		case utf8.ValidRune(escapeChar) && c == escapeChar && isEscapeNonEmpty:
  4930  			// SQL99 escape character; do not immediately send to output
  4931  			afterEscape = true
  4932  		case inCharClass:
  4933  			if c == '\\' {
  4934  				patternBuilder = append(patternBuilder, '\\')
  4935  			}
  4936  			patternBuilder = append(patternBuilder, c)
  4937  			if c == ']' {
  4938  				inCharClass = false
  4939  			}
  4940  		case c == '[':
  4941  			patternBuilder = append(patternBuilder, c)
  4942  			inCharClass = true
  4943  		case c == '%':
  4944  			patternBuilder = append(patternBuilder, '.', '*')
  4945  		case c == '_':
  4946  			patternBuilder = append(patternBuilder, '.')
  4947  		case c == '(':
  4948  			// Convert to non-capturing parenthesis
  4949  			patternBuilder = append(patternBuilder, '(', '?', ':')
  4950  		case c == '\\', c == '.', c == '^', c == '$':
  4951  			// Escape these characters because they are NOT
  4952  			// metacharacters for SQL-style regexp
  4953  			patternBuilder = append(patternBuilder, '\\', c)
  4954  		default:
  4955  			patternBuilder = append(patternBuilder, c)
  4956  		}
  4957  	}
  4958  
  4959  	return string(patternBuilder)
  4960  }
  4961  
  4962  // caseInsensitive surrounds the transformed input string with
  4963  //   (?i: ... )
  4964  // which uses a non-capturing set of parens to turn a case sensitive
  4965  // regular expression pattern into a case insensitive regular
  4966  // expression pattern.
  4967  func caseInsensitive(pattern string) string {
  4968  	return fmt.Sprintf("(?i:%s)", pattern)
  4969  }
  4970  
  4971  // anchorPattern surrounds the transformed input string with
  4972  //   ^(?s: ... )$
  4973  // which requires some explanation.  We need "^" and "$" to force
  4974  // the pattern to match the entire input string as per SQL99 spec.
  4975  // The "(?:" and ")" are a non-capturing set of parens; we have to have
  4976  // parens in case the string contains "|", else the "^" and "$" will
  4977  // be bound into the first and last alternatives which is not what we
  4978  // want, and the parens must be non capturing because we don't want them
  4979  // to count when selecting output for SUBSTRING.
  4980  // "?s" turns on "dot all" mode meaning a dot will match any single character
  4981  // (without turning this mode on, the dot matches any single character except
  4982  // for line breaks).
  4983  func anchorPattern(pattern string, caseInsensitive bool) string {
  4984  	if caseInsensitive {
  4985  		return fmt.Sprintf("^(?si:%s)$", pattern)
  4986  	}
  4987  	return fmt.Sprintf("^(?s:%s)$", pattern)
  4988  }
  4989  
  4990  // FindEqualComparisonFunction looks up an overload of the "=" operator
  4991  // for a given pair of input operand types.
  4992  func FindEqualComparisonFunction(
  4993  	leftType, rightType *types.T,
  4994  ) (func(*EvalContext, Datum, Datum) (Datum, error), bool) {
  4995  	fn, found := CmpOps[EQ].LookupImpl(leftType, rightType)
  4996  	if found {
  4997  		return fn.Fn, true
  4998  	}
  4999  	return nil, false
  5000  }
  5001  
  5002  // IntPow computes the value of x^y.
  5003  func IntPow(x, y DInt) (*DInt, error) {
  5004  	xd := apd.New(int64(x), 0)
  5005  	yd := apd.New(int64(y), 0)
  5006  	_, err := DecimalCtx.Pow(xd, xd, yd)
  5007  	if err != nil {
  5008  		return nil, err
  5009  	}
  5010  	i, err := xd.Int64()
  5011  	if err != nil {
  5012  		return nil, ErrIntOutOfRange
  5013  	}
  5014  	return NewDInt(DInt(i)), nil
  5015  }
  5016  
  5017  // PickFromTuple picks the greatest (or least value) from a tuple.
  5018  func PickFromTuple(ctx *EvalContext, greatest bool, args Datums) (Datum, error) {
  5019  	g := args[0]
  5020  	// Pick a greater (or smaller) value.
  5021  	for _, d := range args[1:] {
  5022  		var eval Datum
  5023  		var err error
  5024  		if greatest {
  5025  			eval, err = evalComparison(ctx, LT, g, d)
  5026  		} else {
  5027  			eval, err = evalComparison(ctx, LT, d, g)
  5028  		}
  5029  		if err != nil {
  5030  			return nil, err
  5031  		}
  5032  		if eval == DBoolTrue ||
  5033  			(eval == DNull && g == DNull) {
  5034  			g = d
  5035  		}
  5036  	}
  5037  	return g, nil
  5038  }
  5039  
  5040  // CallbackValueGenerator is a ValueGenerator that calls a supplied callback for
  5041  // producing the values. To be used with
  5042  // EvalContextTestingKnobs.CallbackGenerators.
  5043  type CallbackValueGenerator struct {
  5044  	// cb is the callback to be called for producing values. It gets passed in 0
  5045  	// as prev initially, and the value it previously returned for subsequent
  5046  	// invocations. Once it returns -1 or an error, it will not be invoked any
  5047  	// more.
  5048  	cb  func(ctx context.Context, prev int, txn *kv.Txn) (int, error)
  5049  	val int
  5050  	txn *kv.Txn
  5051  }
  5052  
  5053  var _ ValueGenerator = &CallbackValueGenerator{}
  5054  
  5055  // NewCallbackValueGenerator creates a new CallbackValueGenerator.
  5056  func NewCallbackValueGenerator(
  5057  	cb func(ctx context.Context, prev int, txn *kv.Txn) (int, error),
  5058  ) *CallbackValueGenerator {
  5059  	return &CallbackValueGenerator{
  5060  		cb: cb,
  5061  	}
  5062  }
  5063  
  5064  // ResolvedType is part of the ValueGenerator interface.
  5065  func (c *CallbackValueGenerator) ResolvedType() *types.T {
  5066  	return types.Int
  5067  }
  5068  
  5069  // Start is part of the ValueGenerator interface.
  5070  func (c *CallbackValueGenerator) Start(_ context.Context, txn *kv.Txn) error {
  5071  	c.txn = txn
  5072  	return nil
  5073  }
  5074  
  5075  // Next is part of the ValueGenerator interface.
  5076  func (c *CallbackValueGenerator) Next(ctx context.Context) (bool, error) {
  5077  	var err error
  5078  	c.val, err = c.cb(ctx, c.val, c.txn)
  5079  	if err != nil {
  5080  		return false, err
  5081  	}
  5082  	if c.val == -1 {
  5083  		return false, nil
  5084  	}
  5085  	return true, nil
  5086  }
  5087  
  5088  // Values is part of the ValueGenerator interface.
  5089  func (c *CallbackValueGenerator) Values() (Datums, error) {
  5090  	return Datums{NewDInt(DInt(c.val))}, nil
  5091  }
  5092  
  5093  // Close is part of the ValueGenerator interface.
  5094  func (c *CallbackValueGenerator) Close() {}
  5095  
  5096  // Sqrt returns the square root of x.
  5097  func Sqrt(x float64) (*DFloat, error) {
  5098  	if x < 0.0 {
  5099  		return nil, errSqrtOfNegNumber
  5100  	}
  5101  	return NewDFloat(DFloat(math.Sqrt(x))), nil
  5102  }
  5103  
  5104  // DecimalSqrt returns the square root of x.
  5105  func DecimalSqrt(x *apd.Decimal) (*DDecimal, error) {
  5106  	if x.Sign() < 0 {
  5107  		return nil, errSqrtOfNegNumber
  5108  	}
  5109  	dd := &DDecimal{}
  5110  	_, err := DecimalCtx.Sqrt(&dd.Decimal, x)
  5111  	return dd, err
  5112  }
  5113  
  5114  // Cbrt returns the cube root of x.
  5115  func Cbrt(x float64) (*DFloat, error) {
  5116  	return NewDFloat(DFloat(math.Cbrt(x))), nil
  5117  }
  5118  
  5119  // DecimalCbrt returns the cube root of x.
  5120  func DecimalCbrt(x *apd.Decimal) (*DDecimal, error) {
  5121  	dd := &DDecimal{}
  5122  	_, err := DecimalCtx.Cbrt(&dd.Decimal, x)
  5123  	return dd, err
  5124  }