github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/sem/tree/constant.go (about)

     1  // Copyright 2016 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  	"go/constant"
    16  	"go/token"
    17  	"math"
    18  	"strings"
    19  	"time"
    20  
    21  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase"
    22  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
    23  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
    24  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
    25  	"github.com/cockroachdb/cockroachdb-parser/pkg/util/intsets"
    26  	"github.com/cockroachdb/errors"
    27  	"github.com/lib/pq/oid"
    28  )
    29  
    30  // Constant is an constant literal expression which may be resolved to more than one type.
    31  type Constant interface {
    32  	Expr
    33  	// AvailableTypes returns the ordered set of types that the Constant is able to
    34  	// be resolved into. The order of the type slice provides a notion of precedence,
    35  	// with the first element in the ordering being the Constant's "natural type".
    36  	AvailableTypes() []*types.T
    37  	// DesirableTypes returns the ordered set of types that the constant would
    38  	// prefer to be resolved into. As in AvailableTypes, the order of the returned
    39  	// type slice provides a notion of precedence, with the first element in the
    40  	// ordering being the Constant's "natural type." The function is meant to be
    41  	// differentiated from AvailableTypes in that it will exclude certain types
    42  	// that are possible, but not desirable.
    43  	//
    44  	// An example of this is a floating point numeric constant without a value
    45  	// past the decimal point. It is possible to resolve this constant as a
    46  	// decimal, but it is not desirable.
    47  	DesirableTypes() []*types.T
    48  	// ResolveAsType resolves the Constant as the specified type, or returns an
    49  	// error if the Constant could not be resolved as that type. The method should
    50  	// only be passed a type returned from AvailableTypes and should never be
    51  	// called more than once for a given Constant.
    52  	//
    53  	// The returned expression is either a Datum or a CastExpr wrapping a Datum;
    54  	// the latter is necessary for cases where the result would depend on the
    55  	// context (like the timezone or the current time).
    56  	ResolveAsType(context.Context, *SemaContext, *types.T) (TypedExpr, error)
    57  }
    58  
    59  var _ Constant = &NumVal{}
    60  var _ Constant = &StrVal{}
    61  
    62  func isConstant(expr Expr) bool {
    63  	_, ok := expr.(Constant)
    64  	return ok
    65  }
    66  
    67  func isPlaceholder(expr Expr) bool {
    68  	_, isPlaceholder := StripParens(expr).(*Placeholder)
    69  	return isPlaceholder
    70  }
    71  
    72  func typeCheckConstant(
    73  	ctx context.Context, semaCtx *SemaContext, c Constant, desired *types.T,
    74  ) (ret TypedExpr, err error) {
    75  	avail := c.AvailableTypes()
    76  	if !desired.IsAmbiguous() {
    77  		for _, typ := range avail {
    78  			if desired.Equivalent(typ) {
    79  				return c.ResolveAsType(ctx, semaCtx, desired)
    80  			}
    81  		}
    82  	}
    83  
    84  	// If a numeric constant will be promoted to a DECIMAL because it was out
    85  	// of range of an INT, but an INT is desired, throw an error here so that
    86  	// the error message specifically mentions the overflow.
    87  	if desired.Family() == types.IntFamily {
    88  		if n, ok := c.(*NumVal); ok {
    89  			_, err := n.AsInt64()
    90  			switch {
    91  			case errors.Is(err, errConstOutOfRange64):
    92  				return nil, err
    93  			case errors.Is(err, errConstNotInt):
    94  			default:
    95  				return nil, errors.NewAssertionErrorWithWrappedErrf(err, "unexpected error")
    96  			}
    97  		}
    98  	}
    99  
   100  	natural := avail[0]
   101  	return c.ResolveAsType(ctx, semaCtx, natural)
   102  }
   103  
   104  func naturalConstantType(c Constant) *types.T {
   105  	return c.AvailableTypes()[0]
   106  }
   107  
   108  // canConstantBecome returns whether the provided Constant can become resolved
   109  // as a type that is Equivalent to the given type.
   110  func canConstantBecome(c Constant, typ *types.T) bool {
   111  	avail := c.AvailableTypes()
   112  	for _, availTyp := range avail {
   113  		if availTyp.Equivalent(typ) {
   114  			return true
   115  		}
   116  	}
   117  	return false
   118  }
   119  
   120  // NumVal represents a constant numeric value.
   121  type NumVal struct {
   122  	// value is the constant number, without any sign information.
   123  	value constant.Value
   124  	// negative is the sign bit to add to any interpretation of the
   125  	// value or origString fields.
   126  	negative bool
   127  	// origString is the "original" string representation (before
   128  	// folding). This should remain sign-less.
   129  	origString string
   130  
   131  	// The following fields are used to avoid allocating Datums on type
   132  	// resolution.
   133  	resInt64   DInt
   134  	resInt32   DInt
   135  	resFloat   DFloat
   136  	resDecimal DDecimal
   137  	// The following fields indicate whether the NumVal has already been
   138  	// resolved as the corresponding Datum.
   139  	resAsInt64   bool
   140  	resAsInt32   bool
   141  	resAsFloat   bool
   142  	resAsDecimal bool
   143  }
   144  
   145  var _ Constant = &NumVal{}
   146  
   147  // NewNumVal constructs a new NumVal instance. This is used during parsing and
   148  // in tests.
   149  func NewNumVal(value constant.Value, origString string, negative bool) *NumVal {
   150  	return &NumVal{value: value, origString: origString, negative: negative}
   151  }
   152  
   153  // Kind implements the constant.Value interface.
   154  func (expr *NumVal) Kind() constant.Kind {
   155  	return expr.value.Kind()
   156  }
   157  
   158  // ExactString implements the constant.Value interface.
   159  func (expr *NumVal) ExactString() string {
   160  	return expr.value.ExactString()
   161  }
   162  
   163  // OrigString returns the origString field.
   164  func (expr *NumVal) OrigString() string {
   165  	return expr.origString
   166  }
   167  
   168  // SetNegative sets the negative field to true. The parser calls this when it
   169  // identifies a negative constant.
   170  func (expr *NumVal) SetNegative() {
   171  	expr.negative = true
   172  }
   173  
   174  // Negate sets the negative field to the opposite of its current value. The
   175  // parser calls this to simplify unary negation expressions.
   176  func (expr *NumVal) Negate() {
   177  	expr.negative = !expr.negative
   178  }
   179  
   180  // Format implements the NodeFormatter interface.
   181  func (expr *NumVal) Format(ctx *FmtCtx) {
   182  	s := expr.origString
   183  	if s == "" {
   184  		s = expr.value.String()
   185  	} else if strings.EqualFold(s, "NaN") {
   186  		s = "'NaN'"
   187  	}
   188  	if expr.negative {
   189  		ctx.WriteByte('-')
   190  	}
   191  	ctx.WriteString(s)
   192  }
   193  
   194  // canBeInt64 checks if it's possible for the value to become an int64:
   195  //
   196  //	1   = yes
   197  //	1.0 = yes
   198  //	1.1 = no
   199  //	123...overflow...456 = no
   200  func (expr *NumVal) canBeInt64() bool {
   201  	_, err := expr.AsInt64()
   202  	return err == nil
   203  }
   204  
   205  // ShouldBeInt64 checks if the value naturally is an int64:
   206  //
   207  //	1   = yes
   208  //	1.0 = no
   209  //	1.1 = no
   210  //	123...overflow...456 = no
   211  func (expr *NumVal) ShouldBeInt64() bool {
   212  	return expr.Kind() == constant.Int && expr.canBeInt64()
   213  }
   214  
   215  // These errors are statically allocated, because they are returned in the
   216  // common path of AsInt64.
   217  var errConstNotInt = pgerror.New(pgcode.NumericValueOutOfRange, "cannot represent numeric constant as an int")
   218  var errConstOutOfRange64 = pgerror.New(pgcode.NumericValueOutOfRange, "numeric constant out of int64 range")
   219  var errConstOutOfRange32 = pgerror.New(pgcode.NumericValueOutOfRange, "numeric constant out of int32 range")
   220  
   221  // AsInt64 returns the value as a 64-bit integer if possible, or returns an
   222  // error if not possible. The method will set expr.resInt64 to the value of
   223  // this int64 if it is successful, avoiding the need to call the method again.
   224  func (expr *NumVal) AsInt64() (int64, error) {
   225  	if expr.resAsInt64 {
   226  		return int64(expr.resInt64), nil
   227  	}
   228  	intVal, ok := expr.AsConstantInt()
   229  	if !ok {
   230  		return 0, errConstNotInt
   231  	}
   232  	i, exact := constant.Int64Val(intVal)
   233  	if !exact {
   234  		return 0, errConstOutOfRange64
   235  	}
   236  	expr.resInt64 = DInt(i)
   237  	expr.resAsInt64 = true
   238  	return i, nil
   239  }
   240  
   241  // AsInt32 returns the value as 32-bit integer if possible, or returns
   242  // an error if not possible. The method will set expr.resInt32 to the
   243  // value of this int32 if it is successful, avoiding the need to call
   244  // the method again.
   245  func (expr *NumVal) AsInt32() (int32, error) {
   246  	if expr.resAsInt32 {
   247  		return int32(expr.resInt32), nil
   248  	}
   249  	intVal, ok := expr.AsConstantInt()
   250  	if !ok {
   251  		return 0, errConstNotInt
   252  	}
   253  	i, exact := constant.Int64Val(intVal)
   254  	if !exact {
   255  		return 0, errConstOutOfRange32
   256  	}
   257  	if i > math.MaxInt32 || i < math.MinInt32 {
   258  		return 0, errConstOutOfRange32
   259  	}
   260  	expr.resInt32 = DInt(i)
   261  	expr.resAsInt32 = true
   262  	return int32(i), nil
   263  }
   264  
   265  // AsConstantValue returns the value as a constant numerical value, with the proper sign
   266  // as given by expr.negative.
   267  func (expr *NumVal) AsConstantValue() constant.Value {
   268  	v := expr.value
   269  	if expr.negative {
   270  		v = constant.UnaryOp(token.SUB, v, 0)
   271  	}
   272  	return v
   273  }
   274  
   275  // AsConstantInt returns the value as an constant.Int if possible, along
   276  // with a flag indicating whether the conversion was possible.
   277  // The result contains the proper sign as per expr.negative.
   278  func (expr *NumVal) AsConstantInt() (constant.Value, bool) {
   279  	v := expr.AsConstantValue()
   280  	intVal := constant.ToInt(v)
   281  	if intVal.Kind() == constant.Int {
   282  		return intVal, true
   283  	}
   284  	return nil, false
   285  }
   286  
   287  var (
   288  	intLikeTypes     = []*types.T{types.Int, types.Oid}
   289  	decimalLikeTypes = []*types.T{types.Decimal, types.Float}
   290  
   291  	// NumValAvailInteger is the set of available integer types.
   292  	NumValAvailInteger = append(intLikeTypes, decimalLikeTypes...)
   293  	// NumValAvailIntegerNoOid is the set of available integer types except for OID.
   294  	NumValAvailIntegerNoOid = append([]*types.T{types.Int}, decimalLikeTypes...)
   295  	// NumValAvailDecimalNoFraction is the set of available integral numeric types.
   296  	NumValAvailDecimalNoFraction = append(decimalLikeTypes, intLikeTypes...)
   297  	// NumValAvailDecimalNoFractionNoOid is the set of available integral numeric types except for OID.
   298  	NumValAvailDecimalNoFractionNoOid = append(decimalLikeTypes, types.Int)
   299  	// NumValAvailDecimalWithFraction is the set of available fractional numeric types.
   300  	NumValAvailDecimalWithFraction = decimalLikeTypes
   301  )
   302  
   303  // AvailableTypes implements the Constant interface.
   304  func (expr *NumVal) AvailableTypes() []*types.T {
   305  	if i, err := expr.AsInt64(); err == nil {
   306  		noOid := intIsOutOfOIDRange(DInt(i))
   307  		intKind := expr.Kind() == constant.Int
   308  		switch {
   309  		case noOid && intKind:
   310  			return NumValAvailIntegerNoOid
   311  		case noOid && !intKind:
   312  			return NumValAvailDecimalNoFractionNoOid
   313  		case !noOid && intKind:
   314  			return NumValAvailInteger
   315  		case !noOid && !intKind:
   316  			return NumValAvailDecimalNoFraction
   317  		}
   318  	}
   319  	return NumValAvailDecimalWithFraction
   320  }
   321  
   322  // DesirableTypes implements the Constant interface.
   323  func (expr *NumVal) DesirableTypes() []*types.T {
   324  	if expr.ShouldBeInt64() {
   325  		return NumValAvailInteger
   326  	}
   327  	return NumValAvailDecimalWithFraction
   328  }
   329  
   330  // ResolveAsType implements the Constant interface.
   331  func (expr *NumVal) ResolveAsType(
   332  	ctx context.Context, semaCtx *SemaContext, typ *types.T,
   333  ) (TypedExpr, error) {
   334  	switch typ.Family() {
   335  	case types.IntFamily:
   336  		// We may have already set expr.resInt64 in AsInt64.
   337  		if !expr.resAsInt64 {
   338  			if _, err := expr.AsInt64(); err != nil {
   339  				return nil, err
   340  			}
   341  		}
   342  		return AdjustValueToType(typ, &expr.resInt64)
   343  	case types.FloatFamily:
   344  		if !expr.resAsFloat {
   345  			if strings.EqualFold(expr.origString, "NaN") {
   346  				// We need to check NaN separately since expr.value is
   347  				// unknownVal for NaN.
   348  				// TODO(sql-sessions): unknownVal is also used for +Inf and
   349  				// -Inf, so we may need to handle those in the future too.
   350  				expr.resFloat = DFloat(math.NaN())
   351  			} else {
   352  				f, _ := constant.Float64Val(expr.value)
   353  				if expr.negative {
   354  					f = -f
   355  				}
   356  				expr.resFloat = DFloat(f)
   357  			}
   358  			expr.resAsFloat = true
   359  		}
   360  		return &expr.resFloat, nil
   361  	case types.DecimalFamily:
   362  		dd := &expr.resDecimal
   363  		if !expr.resAsDecimal {
   364  			s := expr.origString
   365  			if s == "" {
   366  				// TODO(nvanbenschoten): We should propagate width through
   367  				// constant folding so that we can control precision on folded
   368  				// values as well.
   369  				s = expr.ExactString()
   370  			}
   371  			if idx := strings.IndexRune(s, '/'); idx != -1 {
   372  				// Handle constant.ratVal, which will return a rational string
   373  				// like 6/7. If only we could call big.Rat.FloatString() on
   374  				// it...
   375  				num, den := s[:idx], s[idx+1:]
   376  				if err := dd.SetString(num); err != nil {
   377  					return nil, pgerror.Wrapf(err, pgcode.Syntax,
   378  						"could not evaluate numerator of %v as Datum type DDecimal from string %q",
   379  						expr, num)
   380  				}
   381  				// TODO(nvanbenschoten): Should we try to avoid this allocation?
   382  				denDec, err := ParseDDecimal(den)
   383  				if err != nil {
   384  					return nil, pgerror.Wrapf(err, pgcode.Syntax,
   385  						"could not evaluate denominator %v as Datum type DDecimal from string %q",
   386  						expr, den)
   387  				}
   388  				if cond, err := DecimalCtx.Quo(&dd.Decimal, &dd.Decimal, &denDec.Decimal); err != nil {
   389  					if cond.DivisionByZero() {
   390  						return nil, ErrDivByZero
   391  					}
   392  					return nil, err
   393  				}
   394  			} else {
   395  				if err := dd.SetString(s); err != nil {
   396  					return nil, pgerror.Wrapf(err, pgcode.Syntax,
   397  						"could not evaluate %v as Datum type DDecimal from string %q", expr, s)
   398  				}
   399  			}
   400  			if !dd.IsZero() {
   401  				// Negative zero does not exist for DECIMAL, in that case we
   402  				// ignore the sign. Otherwise XOR the signs of the expr and the
   403  				// decimal value contained in the expr, since the negative may
   404  				// have been folded into the inner decimal.
   405  				dd.Negative = dd.Negative != expr.negative
   406  			}
   407  			expr.resAsDecimal = true
   408  		}
   409  		return dd, nil
   410  	case types.OidFamily:
   411  		d, err := expr.ResolveAsType(ctx, semaCtx, types.Int)
   412  		if err != nil {
   413  			return nil, err
   414  		}
   415  		dInt := MustBeDInt(d)
   416  		return IntToOid(dInt)
   417  	default:
   418  		return nil, errors.AssertionFailedf("could not resolve %T %v into a %s", expr, expr, typ.SQLStringForError())
   419  	}
   420  }
   421  
   422  // intersectTypeSlices returns a slice of all the types that are in both of the
   423  // input slices that have the same OID.
   424  func intersectTypeSlices(xs, ys []*types.T) (out []*types.T) {
   425  	seen := make(map[oid.Oid]struct{})
   426  	for _, x := range xs {
   427  		for _, y := range ys {
   428  			_, ok := seen[x.Oid()]
   429  			if x.Oid() == y.Oid() && !ok {
   430  				out = append(out, x)
   431  			}
   432  		}
   433  		seen[x.Oid()] = struct{}{}
   434  	}
   435  	return out
   436  }
   437  
   438  // commonConstantType returns the most constrained type which is mutually
   439  // resolvable between a set of provided constants.
   440  //
   441  // The function takes a slice of Exprs and indexes, but expects all the indexed
   442  // Exprs to wrap a Constant. The reason it does no take a slice of Constants
   443  // instead is to avoid forcing callers to allocate separate slices of Constant.
   444  func commonConstantType(vals []Expr, idxs intsets.Fast) (*types.T, bool) {
   445  	var candidates []*types.T
   446  
   447  	for i, ok := idxs.Next(0); ok; i, ok = idxs.Next(i + 1) {
   448  		availableTypes := vals[i].(Constant).DesirableTypes()
   449  		if candidates == nil {
   450  			candidates = availableTypes
   451  		} else {
   452  			candidates = intersectTypeSlices(candidates, availableTypes)
   453  		}
   454  	}
   455  
   456  	if len(candidates) > 0 {
   457  		return candidates[0], true
   458  	}
   459  	return nil, false
   460  }
   461  
   462  // StrVal represents a constant string value.
   463  type StrVal struct {
   464  	// We could embed a constant.Value here (like NumVal) and use the stringVal implementation,
   465  	// but that would have extra overhead without much of a benefit. However, it would make
   466  	// constant folding (below) a little more straightforward.
   467  	s string
   468  
   469  	// scannedAsBytes is true iff the input syntax was using b'...' or
   470  	// x'....'. If false, the string is guaranteed to be a valid UTF-8
   471  	// sequence.
   472  	scannedAsBytes bool
   473  
   474  	// The following fields are used to avoid allocating Datums on type resolution.
   475  	resString DString
   476  	resBytes  DBytes
   477  }
   478  
   479  // NewStrVal constructs a StrVal instance. This is used during
   480  // parsing when interpreting a token of type SCONST, i.e. *not* using
   481  // the b'...' or x'...' syntax.
   482  func NewStrVal(s string) *StrVal {
   483  	return &StrVal{s: s}
   484  }
   485  
   486  // NewBytesStrVal constructs a StrVal instance suitable as byte array.
   487  // This is used during parsing when interpreting a token of type BCONST,
   488  // i.e. using the b'...' or x'...' syntax.
   489  func NewBytesStrVal(s string) *StrVal {
   490  	return &StrVal{s: s, scannedAsBytes: true}
   491  }
   492  
   493  // RawString retrieves the underlying string of the StrVal.
   494  func (expr *StrVal) RawString() string {
   495  	return expr.s
   496  }
   497  
   498  // Format implements the NodeFormatter interface.
   499  func (expr *StrVal) Format(ctx *FmtCtx) {
   500  	buf, f := &ctx.Buffer, ctx.flags
   501  	if expr.scannedAsBytes {
   502  		lexbase.EncodeSQLBytes(buf, expr.s)
   503  	} else {
   504  		lexbase.EncodeSQLStringWithFlags(buf, expr.s, f.EncodeFlags())
   505  	}
   506  }
   507  
   508  var (
   509  	// StrValAvailAllParsable is the set of parsable string types.
   510  	StrValAvailAllParsable = []*types.T{
   511  		// Note: String is deliberately first, to make sure that "string" is the
   512  		// default type that raw strings get parsed into, without any casts or type
   513  		// assertions.
   514  		types.String,
   515  		types.Bytes,
   516  		types.Bool,
   517  		types.Int,
   518  		types.Float,
   519  		types.Decimal,
   520  		types.Date,
   521  		types.StringArray,
   522  		types.BytesArray,
   523  		types.IntArray,
   524  		types.FloatArray,
   525  		types.DecimalArray,
   526  		types.BoolArray,
   527  		types.Box2D,
   528  		types.Geography,
   529  		types.Geometry,
   530  		types.Time,
   531  		types.TimeTZ,
   532  		types.Timestamp,
   533  		types.TimestampTZ,
   534  		types.Interval,
   535  		types.Uuid,
   536  		types.DateArray,
   537  		types.TimeArray,
   538  		types.TimeTZArray,
   539  		types.TimestampArray,
   540  		types.TimestampTZArray,
   541  		types.IntervalArray,
   542  		types.UUIDArray,
   543  		types.INet,
   544  		types.Jsonb,
   545  		types.PGLSN,
   546  		types.PGLSNArray,
   547  		types.RefCursor,
   548  		types.RefCursorArray,
   549  		types.TSQuery,
   550  		types.TSVector,
   551  		types.VarBit,
   552  		types.AnyEnum,
   553  		types.AnyEnumArray,
   554  		types.INetArray,
   555  		types.VarBitArray,
   556  		types.AnyTuple,
   557  		types.AnyTupleArray,
   558  	}
   559  	// StrValAvailBytes is the set of types convertible to byte array.
   560  	StrValAvailBytes = []*types.T{types.Bytes, types.Uuid, types.String, types.AnyEnum}
   561  )
   562  
   563  // AvailableTypes implements the Constant interface.
   564  //
   565  // To fully take advantage of literal type inference, this method would
   566  // determine exactly which types are available for a given string. This would
   567  // entail attempting to parse the literal string as a date, a timestamp, an
   568  // interval, etc. and having more fine-grained results than StrValAvailAllParsable.
   569  // However, this is not feasible in practice because of the associated parsing
   570  // overhead.
   571  //
   572  // Conservative approaches like checking the string's length have been investigated
   573  // to reduce ambiguity and improve type inference in some cases. When doing so, the
   574  // length of the string literal was compared against all valid date and timestamp
   575  // formats to quickly gain limited insight into whether parsing the string as the
   576  // respective datum types could succeed. The hope was to eliminate impossibilities
   577  // and constrain the returned type sets as much as possible. Unfortunately, two issues
   578  // were found with this approach:
   579  //   - date and timestamp formats do not always imply a fixed-length valid input. For
   580  //     instance, timestamp formats that take fractional seconds can successfully parse
   581  //     inputs of varied length.
   582  //   - the set of date and timestamp formats are not disjoint, which means that ambiguity
   583  //     can not be eliminated when inferring the type of string literals that use these
   584  //     shared formats.
   585  //
   586  // While these limitations still permitted improved type inference in many cases, they
   587  // resulted in behavior that was ultimately incomplete, resulted in unpredictable levels
   588  // of inference, and occasionally failed to eliminate ambiguity. Further heuristics could
   589  // have been applied to improve the accuracy of the inference, like checking that all
   590  // or some characters were digits, but it would not have circumvented the fundamental
   591  // issues here. Fully parsing the literal into each type would be the only way to
   592  // concretely avoid the issue of unpredictable inference behavior.
   593  func (expr *StrVal) AvailableTypes() []*types.T {
   594  	if expr.scannedAsBytes {
   595  		return StrValAvailBytes
   596  	}
   597  	return StrValAvailAllParsable
   598  }
   599  
   600  // DesirableTypes implements the Constant interface.
   601  func (expr *StrVal) DesirableTypes() []*types.T {
   602  	return expr.AvailableTypes()
   603  }
   604  
   605  // ResolveAsType implements the Constant interface.
   606  func (expr *StrVal) ResolveAsType(
   607  	ctx context.Context, semaCtx *SemaContext, typ *types.T,
   608  ) (TypedExpr, error) {
   609  	if expr.scannedAsBytes {
   610  		// We're looking at typing a byte literal constant into some value type.
   611  		switch typ.Family() {
   612  		case types.BytesFamily:
   613  			expr.resBytes = DBytes(expr.s)
   614  			return &expr.resBytes, nil
   615  		case types.EnumFamily:
   616  			e, err := MakeDEnumFromPhysicalRepresentation(typ, []byte(expr.s))
   617  			if err != nil {
   618  				return nil, err
   619  			}
   620  			return NewDEnum(e), nil
   621  		case types.UuidFamily:
   622  			return ParseDUuidFromBytes([]byte(expr.s))
   623  		case types.StringFamily:
   624  			expr.resString = DString(expr.s)
   625  			return &expr.resString, nil
   626  		}
   627  		return nil, errors.AssertionFailedf("attempt to type byte array literal to %s", typ.SQLStringForError())
   628  	}
   629  
   630  	// Typing a string literal constant into some value type.
   631  	switch typ.Family() {
   632  	case types.StringFamily:
   633  		if typ.Oid() == oid.T_name {
   634  			expr.resString = DString(expr.s)
   635  			return NewDNameFromDString(&expr.resString), nil
   636  		}
   637  		expr.resString = DString(expr.s)
   638  		return &expr.resString, nil
   639  
   640  	case types.BytesFamily:
   641  		return ParseDByte(expr.s)
   642  
   643  	default:
   644  		ptCtx := &simpleParseContext{
   645  			// We can return any time, but not the zero value - it causes an error when
   646  			// parsing "yesterday".
   647  			RelativeParseTime: time.Date(2000, time.January, 2, 3, 4, 5, 0, time.UTC),
   648  		}
   649  		if semaCtx != nil {
   650  			ptCtx.DateStyle = semaCtx.DateStyle
   651  			ptCtx.IntervalStyle = semaCtx.IntervalStyle
   652  		}
   653  		if typ.UserDefined() && !typ.IsHydrated() {
   654  			var err error
   655  			if semaCtx == nil || semaCtx.TypeResolver == nil {
   656  				return nil, errors.AssertionFailedf("unable to hydrate type for resolution")
   657  			}
   658  			typ, err = semaCtx.TypeResolver.ResolveTypeByOID(ctx, typ.Oid())
   659  			if err != nil {
   660  				return nil, err
   661  			}
   662  		}
   663  		val, dependsOnContext, err := ParseAndRequireString(typ, expr.s, ptCtx)
   664  		if err != nil {
   665  			return nil, err
   666  		}
   667  		if !dependsOnContext {
   668  			return val, nil
   669  		}
   670  		// Interpreting a string as one of these types may depend on the timezone or
   671  		// the current time; the value won't be safe to reuse later. So in this case
   672  		// we return a CastExpr and let the conversion happen at evaluation time. We
   673  		// still want to error out if the conversion is not possible though (this is
   674  		// used when resolving overloads).
   675  		expr.resString = DString(expr.s)
   676  		c := NewTypedCastExpr(&expr.resString, typ)
   677  		return c.TypeCheck(ctx, semaCtx, typ)
   678  	}
   679  }