github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sem/tree/casts.go (about)

     1  // Copyright 2020 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  	"math"
    15  	"math/big"
    16  	"strconv"
    17  	"strings"
    18  	"time"
    19  
    20  	"github.com/cockroachdb/cockroach/pkg/geo"
    21  	"github.com/cockroachdb/cockroach/pkg/server/telemetry"
    22  	"github.com/cockroachdb/cockroach/pkg/sql/lex"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry"
    26  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    27  	"github.com/cockroachdb/cockroach/pkg/util/bitarray"
    28  	"github.com/cockroachdb/cockroach/pkg/util/duration"
    29  	"github.com/cockroachdb/cockroach/pkg/util/timeofday"
    30  	"github.com/cockroachdb/cockroach/pkg/util/timeutil"
    31  	"github.com/cockroachdb/cockroach/pkg/util/timeutil/pgdate"
    32  	"github.com/lib/pq/oid"
    33  )
    34  
    35  type castInfo struct {
    36  	from       types.Family
    37  	to         types.Family
    38  	volatility Volatility
    39  
    40  	// Telemetry counter; set by init().
    41  	counter telemetry.Counter
    42  
    43  	// If set, the volatility of this cast is not cross-checked against postgres.
    44  	// Use this with caution.
    45  	ignoreVolatilityCheck bool
    46  }
    47  
    48  // validCasts lists all valid explicit casts.
    49  //
    50  // This list must be kept in sync with the capabilities of PerformCast.
    51  //
    52  // Each cast defines a volatility:
    53  //
    54  //  - immutable casts yield the same result on the same arguments in whatever
    55  //    context they are evaluated.
    56  //
    57  //  - stable casts can yield a different result depending on the evaluation context:
    58  //    - session settings (e.g. bytes encoding format)
    59  //    - current timezone
    60  //    - current time (e.g. 'now'::string).
    61  //
    62  // TODO(radu): move the PerformCast code for each cast into functions defined
    63  // within each cast.
    64  //
    65  var validCasts = []castInfo{
    66  	// Casts to BitFamily.
    67  	{from: types.UnknownFamily, to: types.BitFamily, volatility: VolatilityImmutable},
    68  	{from: types.BitFamily, to: types.BitFamily, volatility: VolatilityImmutable},
    69  	{from: types.IntFamily, to: types.BitFamily, volatility: VolatilityImmutable},
    70  	{from: types.StringFamily, to: types.BitFamily, volatility: VolatilityImmutable},
    71  	{from: types.CollatedStringFamily, to: types.BitFamily, volatility: VolatilityImmutable},
    72  
    73  	// Casts to BoolFamily.
    74  	{from: types.UnknownFamily, to: types.BoolFamily, volatility: VolatilityImmutable},
    75  	{from: types.BoolFamily, to: types.BoolFamily, volatility: VolatilityImmutable},
    76  	{from: types.IntFamily, to: types.BoolFamily, volatility: VolatilityImmutable},
    77  	{from: types.FloatFamily, to: types.BoolFamily, volatility: VolatilityImmutable},
    78  	{from: types.DecimalFamily, to: types.BoolFamily, volatility: VolatilityImmutable},
    79  	{from: types.StringFamily, to: types.BoolFamily, volatility: VolatilityImmutable},
    80  	{from: types.CollatedStringFamily, to: types.BoolFamily, volatility: VolatilityImmutable},
    81  
    82  	// Casts to IntFamily.
    83  	{from: types.UnknownFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    84  	{from: types.BoolFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    85  	{from: types.IntFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    86  	{from: types.FloatFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    87  	{from: types.DecimalFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    88  	{from: types.StringFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    89  	{from: types.CollatedStringFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    90  	{from: types.TimestampFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    91  	{from: types.TimestampTZFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    92  	{from: types.DateFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    93  	{from: types.IntervalFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    94  	{from: types.OidFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    95  	{from: types.BitFamily, to: types.IntFamily, volatility: VolatilityImmutable},
    96  
    97  	// Casts to FloatFamily.
    98  	{from: types.UnknownFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
    99  	{from: types.BoolFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
   100  	{from: types.IntFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
   101  	{from: types.FloatFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
   102  	{from: types.DecimalFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
   103  	{from: types.StringFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
   104  	{from: types.CollatedStringFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
   105  	{from: types.TimestampFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
   106  	{from: types.TimestampTZFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
   107  	{from: types.DateFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
   108  	{from: types.IntervalFamily, to: types.FloatFamily, volatility: VolatilityImmutable},
   109  
   110  	// Casts to GeographyFamily.
   111  	{from: types.UnknownFamily, to: types.GeographyFamily, volatility: VolatilityImmutable},
   112  	{from: types.StringFamily, to: types.GeographyFamily, volatility: VolatilityImmutable},
   113  	{from: types.CollatedStringFamily, to: types.GeographyFamily, volatility: VolatilityImmutable},
   114  	{from: types.GeographyFamily, to: types.GeographyFamily, volatility: VolatilityImmutable},
   115  	{from: types.GeometryFamily, to: types.GeographyFamily, volatility: VolatilityImmutable},
   116  
   117  	// Casts to GeographyFamily.
   118  	{from: types.UnknownFamily, to: types.GeometryFamily, volatility: VolatilityImmutable},
   119  	{from: types.StringFamily, to: types.GeometryFamily, volatility: VolatilityImmutable},
   120  	{from: types.CollatedStringFamily, to: types.GeometryFamily, volatility: VolatilityImmutable},
   121  	{from: types.GeographyFamily, to: types.GeometryFamily, volatility: VolatilityImmutable},
   122  	{from: types.GeometryFamily, to: types.GeometryFamily, volatility: VolatilityImmutable},
   123  
   124  	// Casts to DecimalFamily.
   125  	{from: types.UnknownFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   126  	{from: types.BoolFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   127  	{from: types.IntFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   128  	{from: types.FloatFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   129  	{from: types.DecimalFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   130  	{from: types.StringFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   131  	{from: types.CollatedStringFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   132  	{from: types.TimestampFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   133  	{from: types.TimestampTZFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   134  	{from: types.DateFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   135  	{from: types.IntervalFamily, to: types.DecimalFamily, volatility: VolatilityImmutable},
   136  
   137  	// Casts to StringFamily.
   138  	{from: types.UnknownFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   139  	{from: types.BoolFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   140  	{from: types.IntFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   141  	{from: types.FloatFamily, to: types.StringFamily, volatility: VolatilityStable},
   142  	{from: types.DecimalFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   143  	{from: types.StringFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   144  	{from: types.CollatedStringFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   145  	{from: types.BitFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   146  	{from: types.ArrayFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   147  	{from: types.TupleFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   148  	{from: types.GeometryFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   149  	{from: types.GeographyFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   150  	{from: types.BytesFamily, to: types.StringFamily, volatility: VolatilityStable},
   151  	{from: types.TimestampFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   152  	{from: types.TimestampTZFamily, to: types.StringFamily, volatility: VolatilityStable},
   153  	{from: types.IntervalFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   154  	{from: types.UuidFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   155  	{from: types.DateFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   156  	{from: types.TimeFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   157  	{from: types.TimeTZFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   158  	{from: types.OidFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   159  	{from: types.INetFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   160  	{from: types.JsonFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   161  	{from: types.EnumFamily, to: types.StringFamily, volatility: VolatilityImmutable},
   162  
   163  	// Casts to CollatedStringFamily.
   164  	{from: types.UnknownFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   165  	{from: types.BoolFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   166  	{from: types.IntFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   167  	{from: types.FloatFamily, to: types.CollatedStringFamily, volatility: VolatilityStable},
   168  	{from: types.DecimalFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   169  	{from: types.StringFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   170  	{from: types.CollatedStringFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   171  	{from: types.BitFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   172  	{from: types.ArrayFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   173  	{from: types.TupleFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   174  	{from: types.GeometryFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   175  	{from: types.GeographyFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   176  	{from: types.BytesFamily, to: types.CollatedStringFamily, volatility: VolatilityStable},
   177  	{from: types.TimestampFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   178  	{from: types.TimestampTZFamily, to: types.CollatedStringFamily, volatility: VolatilityStable},
   179  	{from: types.IntervalFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   180  	{from: types.UuidFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   181  	{from: types.DateFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   182  	{from: types.TimeFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   183  	{from: types.TimeTZFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   184  	{from: types.OidFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   185  	{from: types.INetFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   186  	{from: types.JsonFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   187  	{from: types.EnumFamily, to: types.CollatedStringFamily, volatility: VolatilityImmutable},
   188  
   189  	// Casts to BytesFamily.
   190  	{from: types.UnknownFamily, to: types.BytesFamily, volatility: VolatilityImmutable},
   191  	{from: types.StringFamily, to: types.BytesFamily, volatility: VolatilityImmutable},
   192  	{from: types.CollatedStringFamily, to: types.BytesFamily, volatility: VolatilityImmutable},
   193  	{from: types.BytesFamily, to: types.BytesFamily, volatility: VolatilityImmutable},
   194  	{from: types.UuidFamily, to: types.BytesFamily, volatility: VolatilityImmutable},
   195  
   196  	// Casts to DateFamily.
   197  	{from: types.UnknownFamily, to: types.DateFamily, volatility: VolatilityImmutable},
   198  	{from: types.StringFamily, to: types.DateFamily, volatility: VolatilityStable},
   199  	{from: types.CollatedStringFamily, to: types.DateFamily, volatility: VolatilityStable},
   200  	{from: types.DateFamily, to: types.DateFamily, volatility: VolatilityImmutable},
   201  	{from: types.TimestampFamily, to: types.DateFamily, volatility: VolatilityImmutable},
   202  	{from: types.TimestampTZFamily, to: types.DateFamily, volatility: VolatilityStable},
   203  	{from: types.IntFamily, to: types.DateFamily, volatility: VolatilityImmutable},
   204  
   205  	// Casts to TimeFamily.
   206  	{from: types.UnknownFamily, to: types.TimeFamily, volatility: VolatilityImmutable},
   207  	{from: types.StringFamily, to: types.TimeFamily, volatility: VolatilityStable},
   208  	{from: types.CollatedStringFamily, to: types.TimeFamily, volatility: VolatilityStable},
   209  	{from: types.TimeFamily, to: types.TimeFamily, volatility: VolatilityImmutable},
   210  	{from: types.TimeTZFamily, to: types.TimeFamily, volatility: VolatilityImmutable},
   211  	{from: types.TimestampFamily, to: types.TimeFamily, volatility: VolatilityImmutable},
   212  	{from: types.TimestampTZFamily, to: types.TimeFamily, volatility: VolatilityStable},
   213  	{from: types.IntervalFamily, to: types.TimeFamily, volatility: VolatilityImmutable},
   214  
   215  	// Casts to TimeTZFamily.
   216  	{from: types.UnknownFamily, to: types.TimeTZFamily, volatility: VolatilityImmutable},
   217  	{from: types.StringFamily, to: types.TimeTZFamily, volatility: VolatilityStable},
   218  	{from: types.CollatedStringFamily, to: types.TimeTZFamily, volatility: VolatilityStable},
   219  	{from: types.TimeFamily, to: types.TimeTZFamily, volatility: VolatilityStable},
   220  	{from: types.TimeTZFamily, to: types.TimeTZFamily, volatility: VolatilityImmutable},
   221  	{from: types.TimestampTZFamily, to: types.TimeTZFamily, volatility: VolatilityStable},
   222  
   223  	// Casts to TimestampFamily.
   224  	{from: types.UnknownFamily, to: types.TimestampFamily, volatility: VolatilityImmutable},
   225  	{from: types.StringFamily, to: types.TimestampFamily, volatility: VolatilityStable},
   226  	{from: types.CollatedStringFamily, to: types.TimestampFamily, volatility: VolatilityStable},
   227  	{from: types.DateFamily, to: types.TimestampFamily, volatility: VolatilityImmutable},
   228  	{from: types.TimestampFamily, to: types.TimestampFamily, volatility: VolatilityImmutable},
   229  	{from: types.TimestampTZFamily, to: types.TimestampFamily, volatility: VolatilityStable},
   230  	{from: types.IntFamily, to: types.TimestampFamily, volatility: VolatilityImmutable},
   231  
   232  	// Casts to TimestampTZFamily.
   233  	{from: types.UnknownFamily, to: types.TimestampTZFamily, volatility: VolatilityImmutable},
   234  	{from: types.StringFamily, to: types.TimestampTZFamily, volatility: VolatilityStable},
   235  	{from: types.CollatedStringFamily, to: types.TimestampTZFamily, volatility: VolatilityStable},
   236  	{from: types.DateFamily, to: types.TimestampTZFamily, volatility: VolatilityStable},
   237  	{from: types.TimestampFamily, to: types.TimestampTZFamily, volatility: VolatilityStable},
   238  	{from: types.TimestampTZFamily, to: types.TimestampTZFamily, volatility: VolatilityImmutable},
   239  	{from: types.IntFamily, to: types.TimestampTZFamily, volatility: VolatilityImmutable},
   240  
   241  	// Casts to IntervalFamily.
   242  	{from: types.UnknownFamily, to: types.IntervalFamily, volatility: VolatilityImmutable},
   243  	{from: types.StringFamily, to: types.IntervalFamily, volatility: VolatilityImmutable},
   244  	{from: types.CollatedStringFamily, to: types.IntervalFamily, volatility: VolatilityImmutable},
   245  	{from: types.IntFamily, to: types.IntervalFamily, volatility: VolatilityImmutable},
   246  	{from: types.TimeFamily, to: types.IntervalFamily, volatility: VolatilityImmutable},
   247  	{from: types.IntervalFamily, to: types.IntervalFamily, volatility: VolatilityImmutable},
   248  	{from: types.FloatFamily, to: types.IntervalFamily, volatility: VolatilityImmutable},
   249  	{from: types.DecimalFamily, to: types.IntervalFamily, volatility: VolatilityImmutable},
   250  
   251  	// Casts to OidFamily.
   252  	{from: types.UnknownFamily, to: types.OidFamily, volatility: VolatilityImmutable},
   253  	{from: types.StringFamily, to: types.OidFamily, volatility: VolatilityStable},
   254  	{from: types.CollatedStringFamily, to: types.OidFamily, volatility: VolatilityStable},
   255  	{from: types.IntFamily, to: types.OidFamily, volatility: VolatilityStable, ignoreVolatilityCheck: true},
   256  	{from: types.OidFamily, to: types.OidFamily, volatility: VolatilityStable},
   257  
   258  	// Casts to UuidFamily.
   259  	{from: types.UnknownFamily, to: types.UuidFamily, volatility: VolatilityImmutable},
   260  	{from: types.StringFamily, to: types.UuidFamily, volatility: VolatilityImmutable},
   261  	{from: types.CollatedStringFamily, to: types.UuidFamily, volatility: VolatilityImmutable},
   262  	{from: types.BytesFamily, to: types.UuidFamily, volatility: VolatilityImmutable},
   263  	{from: types.UuidFamily, to: types.UuidFamily, volatility: VolatilityImmutable},
   264  
   265  	// Casts to INetFamily.
   266  	{from: types.UnknownFamily, to: types.INetFamily, volatility: VolatilityImmutable},
   267  	{from: types.StringFamily, to: types.INetFamily, volatility: VolatilityImmutable},
   268  	{from: types.CollatedStringFamily, to: types.INetFamily, volatility: VolatilityImmutable},
   269  	{from: types.INetFamily, to: types.INetFamily, volatility: VolatilityImmutable},
   270  
   271  	// Casts to ArrayFamily.
   272  	{from: types.UnknownFamily, to: types.ArrayFamily, volatility: VolatilityImmutable},
   273  	{from: types.StringFamily, to: types.ArrayFamily, volatility: VolatilityStable},
   274  
   275  	// Casts to JsonFamily.
   276  	{from: types.UnknownFamily, to: types.JsonFamily, volatility: VolatilityImmutable},
   277  	{from: types.StringFamily, to: types.JsonFamily, volatility: VolatilityImmutable},
   278  	{from: types.JsonFamily, to: types.JsonFamily, volatility: VolatilityImmutable},
   279  
   280  	// Casts to EnumFamily.
   281  	{from: types.UnknownFamily, to: types.EnumFamily, volatility: VolatilityImmutable},
   282  	{from: types.StringFamily, to: types.EnumFamily, volatility: VolatilityImmutable},
   283  	{from: types.EnumFamily, to: types.EnumFamily, volatility: VolatilityImmutable},
   284  	{from: types.BytesFamily, to: types.EnumFamily, volatility: VolatilityImmutable},
   285  }
   286  
   287  type castsMapKey struct {
   288  	from, to types.Family
   289  }
   290  
   291  var castsMap map[castsMapKey]*castInfo
   292  
   293  func init() {
   294  	castsMap = make(map[castsMapKey]*castInfo, len(validCasts))
   295  	for i := range validCasts {
   296  		c := &validCasts[i]
   297  
   298  		// Initialize counter.
   299  		c.counter = sqltelemetry.CastOpCounter(c.from.Name(), c.to.Name())
   300  
   301  		key := castsMapKey{from: c.from, to: c.to}
   302  		castsMap[key] = c
   303  	}
   304  }
   305  
   306  // PerformCast performs a cast from the provided Datum to the specified
   307  // types.T.
   308  func PerformCast(ctx *EvalContext, d Datum, t *types.T) (Datum, error) {
   309  	switch t.Family() {
   310  	case types.BitFamily:
   311  		switch v := d.(type) {
   312  		case *DBitArray:
   313  			if t.Width() == 0 || v.BitLen() == uint(t.Width()) {
   314  				return d, nil
   315  			}
   316  			var a DBitArray
   317  			switch t.Oid() {
   318  			case oid.T_varbit:
   319  				// VARBITs do not have padding attached.
   320  				a.BitArray = v.BitArray.Clone()
   321  				if uint(t.Width()) < a.BitArray.BitLen() {
   322  					a.BitArray = a.BitArray.ToWidth(uint(t.Width()))
   323  				}
   324  			default:
   325  				a.BitArray = v.BitArray.Clone().ToWidth(uint(t.Width()))
   326  			}
   327  			return &a, nil
   328  		case *DInt:
   329  			return NewDBitArrayFromInt(int64(*v), uint(t.Width()))
   330  		case *DString:
   331  			res, err := bitarray.Parse(string(*v))
   332  			if err != nil {
   333  				return nil, err
   334  			}
   335  			if t.Width() > 0 {
   336  				res = res.ToWidth(uint(t.Width()))
   337  			}
   338  			return &DBitArray{BitArray: res}, nil
   339  		case *DCollatedString:
   340  			res, err := bitarray.Parse(v.Contents)
   341  			if err != nil {
   342  				return nil, err
   343  			}
   344  			if t.Width() > 0 {
   345  				res = res.ToWidth(uint(t.Width()))
   346  			}
   347  			return &DBitArray{BitArray: res}, nil
   348  		}
   349  
   350  	case types.BoolFamily:
   351  		switch v := d.(type) {
   352  		case *DBool:
   353  			return d, nil
   354  		case *DInt:
   355  			return MakeDBool(*v != 0), nil
   356  		case *DFloat:
   357  			return MakeDBool(*v != 0), nil
   358  		case *DDecimal:
   359  			return MakeDBool(v.Sign() != 0), nil
   360  		case *DString:
   361  			return ParseDBool(string(*v))
   362  		case *DCollatedString:
   363  			return ParseDBool(v.Contents)
   364  		}
   365  
   366  	case types.IntFamily:
   367  		var res *DInt
   368  		switch v := d.(type) {
   369  		case *DBitArray:
   370  			res = v.AsDInt(uint(t.Width()))
   371  		case *DBool:
   372  			if *v {
   373  				res = NewDInt(1)
   374  			} else {
   375  				res = DZero
   376  			}
   377  		case *DInt:
   378  			// TODO(knz): enforce the coltype width here.
   379  			res = v
   380  		case *DFloat:
   381  			f := float64(*v)
   382  			// Use `<=` and `>=` here instead of just `<` and `>` because when
   383  			// math.MaxInt64 and math.MinInt64 are converted to float64s, they are
   384  			// rounded to numbers with larger absolute values. Note that the first
   385  			// next FP value after and strictly greater than float64(math.MinInt64)
   386  			// is -9223372036854774784 (= float64(math.MinInt64)+513) and the first
   387  			// previous value and strictly smaller than float64(math.MaxInt64)
   388  			// is 9223372036854774784 (= float64(math.MaxInt64)-513), and both are
   389  			// convertible to int without overflow.
   390  			if math.IsNaN(f) || f <= float64(math.MinInt64) || f >= float64(math.MaxInt64) {
   391  				return nil, ErrIntOutOfRange
   392  			}
   393  			res = NewDInt(DInt(f))
   394  		case *DDecimal:
   395  			d := ctx.getTmpDec()
   396  			_, err := DecimalCtx.RoundToIntegralValue(d, &v.Decimal)
   397  			if err != nil {
   398  				return nil, err
   399  			}
   400  			i, err := d.Int64()
   401  			if err != nil {
   402  				return nil, ErrIntOutOfRange
   403  			}
   404  			res = NewDInt(DInt(i))
   405  		case *DString:
   406  			var err error
   407  			if res, err = ParseDInt(string(*v)); err != nil {
   408  				return nil, err
   409  			}
   410  		case *DCollatedString:
   411  			var err error
   412  			if res, err = ParseDInt(v.Contents); err != nil {
   413  				return nil, err
   414  			}
   415  		case *DTimestamp:
   416  			res = NewDInt(DInt(v.Unix()))
   417  		case *DTimestampTZ:
   418  			res = NewDInt(DInt(v.Unix()))
   419  		case *DDate:
   420  			// TODO(mjibson): This cast is unsupported by postgres. Should we remove ours?
   421  			if !v.IsFinite() {
   422  				return nil, ErrIntOutOfRange
   423  			}
   424  			res = NewDInt(DInt(v.UnixEpochDays()))
   425  		case *DInterval:
   426  			iv, ok := v.AsInt64()
   427  			if !ok {
   428  				return nil, ErrIntOutOfRange
   429  			}
   430  			res = NewDInt(DInt(iv))
   431  		case *DOid:
   432  			res = &v.DInt
   433  		}
   434  		if res != nil {
   435  			return res, nil
   436  		}
   437  
   438  	case types.EnumFamily:
   439  		switch v := d.(type) {
   440  		case *DString:
   441  			return MakeDEnumFromLogicalRepresentation(t, string(*v))
   442  		case *DBytes:
   443  			return MakeDEnumFromPhysicalRepresentation(t, []byte(*v))
   444  		case *DEnum:
   445  			return d, nil
   446  		}
   447  
   448  	case types.FloatFamily:
   449  		switch v := d.(type) {
   450  		case *DBool:
   451  			if *v {
   452  				return NewDFloat(1), nil
   453  			}
   454  			return NewDFloat(0), nil
   455  		case *DInt:
   456  			return NewDFloat(DFloat(*v)), nil
   457  		case *DFloat:
   458  			return d, nil
   459  		case *DDecimal:
   460  			f, err := v.Float64()
   461  			if err != nil {
   462  				return nil, ErrFloatOutOfRange
   463  			}
   464  			return NewDFloat(DFloat(f)), nil
   465  		case *DString:
   466  			return ParseDFloat(string(*v))
   467  		case *DCollatedString:
   468  			return ParseDFloat(v.Contents)
   469  		case *DTimestamp:
   470  			micros := float64(v.Nanosecond() / int(time.Microsecond))
   471  			return NewDFloat(DFloat(float64(v.Unix()) + micros*1e-6)), nil
   472  		case *DTimestampTZ:
   473  			micros := float64(v.Nanosecond() / int(time.Microsecond))
   474  			return NewDFloat(DFloat(float64(v.Unix()) + micros*1e-6)), nil
   475  		case *DDate:
   476  			// TODO(mjibson): This cast is unsupported by postgres. Should we remove ours?
   477  			if !v.IsFinite() {
   478  				return nil, ErrFloatOutOfRange
   479  			}
   480  			return NewDFloat(DFloat(float64(v.UnixEpochDays()))), nil
   481  		case *DInterval:
   482  			return NewDFloat(DFloat(v.AsFloat64())), nil
   483  		}
   484  
   485  	case types.DecimalFamily:
   486  		var dd DDecimal
   487  		var err error
   488  		unset := false
   489  		switch v := d.(type) {
   490  		case *DBool:
   491  			if *v {
   492  				dd.SetFinite(1, 0)
   493  			}
   494  		case *DInt:
   495  			dd.SetFinite(int64(*v), 0)
   496  		case *DDate:
   497  			// TODO(mjibson): This cast is unsupported by postgres. Should we remove ours?
   498  			if !v.IsFinite() {
   499  				return nil, errDecOutOfRange
   500  			}
   501  			dd.SetFinite(v.UnixEpochDays(), 0)
   502  		case *DFloat:
   503  			_, err = dd.SetFloat64(float64(*v))
   504  		case *DDecimal:
   505  			// Small optimization to avoid copying into dd in normal case.
   506  			if t.Precision() == 0 {
   507  				return d, nil
   508  			}
   509  			dd.Set(&v.Decimal)
   510  		case *DString:
   511  			err = dd.SetString(string(*v))
   512  		case *DCollatedString:
   513  			err = dd.SetString(v.Contents)
   514  		case *DTimestamp:
   515  			val := &dd.Coeff
   516  			val.SetInt64(v.Unix())
   517  			val.Mul(val, big10E6)
   518  			micros := v.Nanosecond() / int(time.Microsecond)
   519  			val.Add(val, big.NewInt(int64(micros)))
   520  			dd.Exponent = -6
   521  		case *DTimestampTZ:
   522  			val := &dd.Coeff
   523  			val.SetInt64(v.Unix())
   524  			val.Mul(val, big10E6)
   525  			micros := v.Nanosecond() / int(time.Microsecond)
   526  			val.Add(val, big.NewInt(int64(micros)))
   527  			dd.Exponent = -6
   528  		case *DInterval:
   529  			v.AsBigInt(&dd.Coeff)
   530  			dd.Exponent = -9
   531  		default:
   532  			unset = true
   533  		}
   534  		if err != nil {
   535  			return nil, err
   536  		}
   537  		if !unset {
   538  			// dd.Coeff must be positive. If it was set to a negative value
   539  			// above, transfer the sign to dd.Negative.
   540  			if dd.Coeff.Sign() < 0 {
   541  				dd.Negative = true
   542  				dd.Coeff.Abs(&dd.Coeff)
   543  			}
   544  			err = LimitDecimalWidth(&dd.Decimal, int(t.Precision()), int(t.Scale()))
   545  			return &dd, err
   546  		}
   547  
   548  	case types.StringFamily, types.CollatedStringFamily:
   549  		var s string
   550  		switch t := d.(type) {
   551  		case *DBitArray:
   552  			s = t.BitArray.String()
   553  		case *DFloat:
   554  			s = strconv.FormatFloat(float64(*t), 'g',
   555  				ctx.SessionData.DataConversion.GetFloatPrec(), 64)
   556  		case *DBool, *DInt, *DDecimal:
   557  			s = d.String()
   558  		case *DTimestamp, *DDate, *DTime, *DTimeTZ, *DGeography, *DGeometry:
   559  			s = AsStringWithFlags(d, FmtBareStrings)
   560  		case *DTimestampTZ:
   561  			// Convert to context timezone for correct display.
   562  			ts, err := MakeDTimestampTZ(t.In(ctx.GetLocation()), time.Microsecond)
   563  			if err != nil {
   564  				return nil, err
   565  			}
   566  			s = AsStringWithFlags(
   567  				ts,
   568  				FmtBareStrings,
   569  			)
   570  		case *DTuple:
   571  			s = AsStringWithFlags(d, FmtPgwireText)
   572  		case *DArray:
   573  			s = AsStringWithFlags(d, FmtPgwireText)
   574  		case *DInterval:
   575  			// When converting an interval to string, we need a string representation
   576  			// of the duration (e.g. "5s") and not of the interval itself (e.g.
   577  			// "INTERVAL '5s'").
   578  			s = t.ValueAsString()
   579  		case *DUuid:
   580  			s = t.UUID.String()
   581  		case *DIPAddr:
   582  			s = AsStringWithFlags(d, FmtBareStrings)
   583  		case *DString:
   584  			s = string(*t)
   585  		case *DCollatedString:
   586  			s = t.Contents
   587  		case *DBytes:
   588  			s = lex.EncodeByteArrayToRawBytes(string(*t),
   589  				ctx.SessionData.DataConversion.BytesEncodeFormat, false /* skipHexPrefix */)
   590  		case *DOid:
   591  			s = t.String()
   592  		case *DJSON:
   593  			s = t.JSON.String()
   594  		case *DEnum:
   595  			s = t.LogicalRep
   596  		}
   597  		switch t.Family() {
   598  		case types.StringFamily:
   599  			if t.Oid() == oid.T_name {
   600  				return NewDName(s), nil
   601  			}
   602  
   603  			// If the string type specifies a limit we truncate to that limit:
   604  			//   'hello'::CHAR(2) -> 'he'
   605  			// This is true of all the string type variants.
   606  			if t.Width() > 0 && int(t.Width()) < len(s) {
   607  				s = s[:t.Width()]
   608  			}
   609  			return NewDString(s), nil
   610  		case types.CollatedStringFamily:
   611  			// Ditto truncation like for TString.
   612  			if t.Width() > 0 && int(t.Width()) < len(s) {
   613  				s = s[:t.Width()]
   614  			}
   615  			return NewDCollatedString(s, t.Locale(), &ctx.CollationEnv)
   616  		}
   617  
   618  	case types.BytesFamily:
   619  		switch t := d.(type) {
   620  		case *DString:
   621  			return ParseDByte(string(*t))
   622  		case *DCollatedString:
   623  			return NewDBytes(DBytes(t.Contents)), nil
   624  		case *DUuid:
   625  			return NewDBytes(DBytes(t.GetBytes())), nil
   626  		case *DBytes:
   627  			return d, nil
   628  		}
   629  
   630  	case types.UuidFamily:
   631  		switch t := d.(type) {
   632  		case *DString:
   633  			return ParseDUuidFromString(string(*t))
   634  		case *DCollatedString:
   635  			return ParseDUuidFromString(t.Contents)
   636  		case *DBytes:
   637  			return ParseDUuidFromBytes([]byte(*t))
   638  		case *DUuid:
   639  			return d, nil
   640  		}
   641  
   642  	case types.INetFamily:
   643  		switch t := d.(type) {
   644  		case *DString:
   645  			return ParseDIPAddrFromINetString(string(*t))
   646  		case *DCollatedString:
   647  			return ParseDIPAddrFromINetString(t.Contents)
   648  		case *DIPAddr:
   649  			return d, nil
   650  		}
   651  
   652  	case types.GeographyFamily:
   653  		switch d := d.(type) {
   654  		case *DString:
   655  			return ParseDGeography(string(*d))
   656  		case *DCollatedString:
   657  			return ParseDGeography(d.Contents)
   658  		case *DGeography:
   659  			if err := geo.GeospatialTypeFitsColumnMetadata(
   660  				d.Geography,
   661  				t.InternalType.GeoMetadata.SRID,
   662  				t.InternalType.GeoMetadata.Shape,
   663  			); err != nil {
   664  				return nil, err
   665  			}
   666  			return d, nil
   667  		case *DGeometry:
   668  			g, err := d.AsGeography()
   669  			if err != nil {
   670  				return nil, err
   671  			}
   672  			if err := geo.GeospatialTypeFitsColumnMetadata(
   673  				g,
   674  				t.InternalType.GeoMetadata.SRID,
   675  				t.InternalType.GeoMetadata.Shape,
   676  			); err != nil {
   677  				return nil, err
   678  			}
   679  			return &DGeography{g}, nil
   680  		}
   681  	case types.GeometryFamily:
   682  		switch d := d.(type) {
   683  		case *DString:
   684  			return ParseDGeometry(string(*d))
   685  		case *DCollatedString:
   686  			return ParseDGeometry(d.Contents)
   687  		case *DGeometry:
   688  			if err := geo.GeospatialTypeFitsColumnMetadata(
   689  				d.Geometry,
   690  				t.InternalType.GeoMetadata.SRID,
   691  				t.InternalType.GeoMetadata.Shape,
   692  			); err != nil {
   693  				return nil, err
   694  			}
   695  			return d, nil
   696  		case *DGeography:
   697  			if err := geo.GeospatialTypeFitsColumnMetadata(
   698  				d.Geography,
   699  				t.InternalType.GeoMetadata.SRID,
   700  				t.InternalType.GeoMetadata.Shape,
   701  			); err != nil {
   702  				return nil, err
   703  			}
   704  			return &DGeometry{d.AsGeometry()}, nil
   705  		}
   706  
   707  	case types.DateFamily:
   708  		switch d := d.(type) {
   709  		case *DString:
   710  			return ParseDDate(ctx, string(*d))
   711  		case *DCollatedString:
   712  			return ParseDDate(ctx, d.Contents)
   713  		case *DDate:
   714  			return d, nil
   715  		case *DInt:
   716  			// TODO(mjibson): This cast is unsupported by postgres. Should we remove ours?
   717  			t, err := pgdate.MakeDateFromUnixEpoch(int64(*d))
   718  			return NewDDate(t), err
   719  		case *DTimestampTZ:
   720  			return NewDDateFromTime(d.Time.In(ctx.GetLocation()))
   721  		case *DTimestamp:
   722  			return NewDDateFromTime(d.Time)
   723  		}
   724  
   725  	case types.TimeFamily:
   726  		roundTo := TimeFamilyPrecisionToRoundDuration(t.Precision())
   727  		switch d := d.(type) {
   728  		case *DString:
   729  			return ParseDTime(ctx, string(*d), roundTo)
   730  		case *DCollatedString:
   731  			return ParseDTime(ctx, d.Contents, roundTo)
   732  		case *DTime:
   733  			return d.Round(roundTo), nil
   734  		case *DTimeTZ:
   735  			return MakeDTime(d.TimeOfDay.Round(roundTo)), nil
   736  		case *DTimestamp:
   737  			return MakeDTime(timeofday.FromTime(d.Time).Round(roundTo)), nil
   738  		case *DTimestampTZ:
   739  			// Strip time zone. Times don't carry their location.
   740  			stripped, err := d.stripTimeZone(ctx)
   741  			if err != nil {
   742  				return nil, err
   743  			}
   744  			return MakeDTime(timeofday.FromTime(stripped.Time).Round(roundTo)), nil
   745  		case *DInterval:
   746  			return MakeDTime(timeofday.Min.Add(d.Duration).Round(roundTo)), nil
   747  		}
   748  
   749  	case types.TimeTZFamily:
   750  		roundTo := TimeFamilyPrecisionToRoundDuration(t.Precision())
   751  		switch d := d.(type) {
   752  		case *DString:
   753  			return ParseDTimeTZ(ctx, string(*d), roundTo)
   754  		case *DCollatedString:
   755  			return ParseDTimeTZ(ctx, d.Contents, roundTo)
   756  		case *DTime:
   757  			return NewDTimeTZFromLocation(timeofday.TimeOfDay(*d).Round(roundTo), ctx.GetLocation()), nil
   758  		case *DTimeTZ:
   759  			return d.Round(roundTo), nil
   760  		case *DTimestampTZ:
   761  			return NewDTimeTZFromTime(d.Time.In(ctx.GetLocation()).Round(roundTo)), nil
   762  		}
   763  
   764  	case types.TimestampFamily:
   765  		roundTo := TimeFamilyPrecisionToRoundDuration(t.Precision())
   766  		// TODO(knz): Timestamp from float, decimal.
   767  		switch d := d.(type) {
   768  		case *DString:
   769  			return ParseDTimestamp(ctx, string(*d), roundTo)
   770  		case *DCollatedString:
   771  			return ParseDTimestamp(ctx, d.Contents, roundTo)
   772  		case *DDate:
   773  			t, err := d.ToTime()
   774  			if err != nil {
   775  				return nil, err
   776  			}
   777  			return MakeDTimestamp(t, roundTo)
   778  		case *DInt:
   779  			return MakeDTimestamp(timeutil.Unix(int64(*d), 0), roundTo)
   780  		case *DTimestamp:
   781  			return d.Round(roundTo)
   782  		case *DTimestampTZ:
   783  			// Strip time zone. Timestamps don't carry their location.
   784  			stripped, err := d.stripTimeZone(ctx)
   785  			if err != nil {
   786  				return nil, err
   787  			}
   788  			return stripped.Round(roundTo)
   789  		}
   790  
   791  	case types.TimestampTZFamily:
   792  		roundTo := TimeFamilyPrecisionToRoundDuration(t.Precision())
   793  		// TODO(knz): TimestampTZ from float, decimal.
   794  		switch d := d.(type) {
   795  		case *DString:
   796  			return ParseDTimestampTZ(ctx, string(*d), roundTo)
   797  		case *DCollatedString:
   798  			return ParseDTimestampTZ(ctx, d.Contents, roundTo)
   799  		case *DDate:
   800  			t, err := d.ToTime()
   801  			if err != nil {
   802  				return nil, err
   803  			}
   804  			_, before := t.Zone()
   805  			_, after := t.In(ctx.GetLocation()).Zone()
   806  			return MakeDTimestampTZ(t.Add(time.Duration(before-after)*time.Second), roundTo)
   807  		case *DTimestamp:
   808  			_, before := d.Time.Zone()
   809  			_, after := d.Time.In(ctx.GetLocation()).Zone()
   810  			return MakeDTimestampTZ(d.Time.Add(time.Duration(before-after)*time.Second), roundTo)
   811  		case *DInt:
   812  			return MakeDTimestampTZ(timeutil.Unix(int64(*d), 0), roundTo)
   813  		case *DTimestampTZ:
   814  			return d.Round(roundTo)
   815  		}
   816  
   817  	case types.IntervalFamily:
   818  		itm, err := t.IntervalTypeMetadata()
   819  		if err != nil {
   820  			return nil, err
   821  		}
   822  		switch v := d.(type) {
   823  		case *DString:
   824  			return ParseDIntervalWithTypeMetadata(string(*v), itm)
   825  		case *DCollatedString:
   826  			return ParseDIntervalWithTypeMetadata(v.Contents, itm)
   827  		case *DInt:
   828  			return NewDInterval(duration.FromInt64(int64(*v)), itm), nil
   829  		case *DFloat:
   830  			return NewDInterval(duration.FromFloat64(float64(*v)), itm), nil
   831  		case *DTime:
   832  			return NewDInterval(duration.MakeDuration(int64(*v)*1000, 0, 0), itm), nil
   833  		case *DDecimal:
   834  			d := ctx.getTmpDec()
   835  			dnanos := v.Decimal
   836  			dnanos.Exponent += 9
   837  			// We need HighPrecisionCtx because duration values can contain
   838  			// upward of 35 decimal digits and DecimalCtx only provides 25.
   839  			_, err := HighPrecisionCtx.Quantize(d, &dnanos, 0)
   840  			if err != nil {
   841  				return nil, err
   842  			}
   843  			if dnanos.Negative {
   844  				d.Coeff.Neg(&d.Coeff)
   845  			}
   846  			dv, ok := duration.FromBigInt(&d.Coeff)
   847  			if !ok {
   848  				return nil, errDecOutOfRange
   849  			}
   850  			return NewDInterval(dv, itm), nil
   851  		case *DInterval:
   852  			return NewDInterval(v.Duration, itm), nil
   853  		}
   854  	case types.JsonFamily:
   855  		switch v := d.(type) {
   856  		case *DString:
   857  			return ParseDJSON(string(*v))
   858  		case *DJSON:
   859  			return v, nil
   860  		}
   861  	case types.ArrayFamily:
   862  		switch v := d.(type) {
   863  		case *DString:
   864  			return ParseDArrayFromString(ctx, string(*v), t.ArrayContents())
   865  		case *DArray:
   866  			dcast := NewDArray(t.ArrayContents())
   867  			for _, e := range v.Array {
   868  				ecast := DNull
   869  				if e != DNull {
   870  					var err error
   871  					ecast, err = PerformCast(ctx, e, t.ArrayContents())
   872  					if err != nil {
   873  						return nil, err
   874  					}
   875  				}
   876  
   877  				if err := dcast.Append(ecast); err != nil {
   878  					return nil, err
   879  				}
   880  			}
   881  			return dcast, nil
   882  		}
   883  	case types.OidFamily:
   884  		switch v := d.(type) {
   885  		case *DOid:
   886  			switch t.Oid() {
   887  			case oid.T_oid:
   888  				return &DOid{semanticType: t, DInt: v.DInt}, nil
   889  			case oid.T_regtype:
   890  				// Mapping an oid to a regtype is easy: we have a hardcoded map.
   891  				typ, ok := types.OidToType[oid.Oid(v.DInt)]
   892  				ret := &DOid{semanticType: t, DInt: v.DInt}
   893  				if !ok {
   894  					return ret, nil
   895  				}
   896  				ret.name = typ.PGName()
   897  				return ret, nil
   898  			default:
   899  				oid, err := queryOid(ctx, t, v)
   900  				if err != nil {
   901  					oid = NewDOid(v.DInt)
   902  					oid.semanticType = t
   903  				}
   904  				return oid, nil
   905  			}
   906  		case *DInt:
   907  			switch t.Oid() {
   908  			case oid.T_oid:
   909  				return &DOid{semanticType: t, DInt: *v}, nil
   910  			default:
   911  				tmpOid := NewDOid(*v)
   912  				oid, err := queryOid(ctx, t, tmpOid)
   913  				if err != nil {
   914  					oid = tmpOid
   915  					oid.semanticType = t
   916  				}
   917  				return oid, nil
   918  			}
   919  		case *DString:
   920  			s := string(*v)
   921  			// Trim whitespace and unwrap outer quotes if necessary.
   922  			// This is required to mimic postgres.
   923  			s = strings.TrimSpace(s)
   924  			origS := s
   925  			if len(s) > 1 && s[0] == '"' && s[len(s)-1] == '"' {
   926  				s = s[1 : len(s)-1]
   927  			}
   928  
   929  			switch t.Oid() {
   930  			case oid.T_oid:
   931  				i, err := ParseDInt(s)
   932  				if err != nil {
   933  					return nil, err
   934  				}
   935  				return &DOid{semanticType: t, DInt: *i}, nil
   936  			case oid.T_regproc, oid.T_regprocedure:
   937  				// Trim procedure type parameters, e.g. `max(int)` becomes `max`.
   938  				// Postgres only does this when the cast is ::regprocedure, but we're
   939  				// going to always do it.
   940  				// We additionally do not yet implement disambiguation based on type
   941  				// parameters: we return the match iff there is exactly one.
   942  				s = pgSignatureRegexp.ReplaceAllString(s, "$1")
   943  				// Resolve function name.
   944  				substrs := strings.Split(s, ".")
   945  				if len(substrs) > 3 {
   946  					// A fully qualified function name in pg's dialect can contain
   947  					// at most 3 parts: db.schema.funname.
   948  					// For example mydb.pg_catalog.max().
   949  					// Anything longer is always invalid.
   950  					return nil, pgerror.Newf(pgcode.Syntax,
   951  						"invalid function name: %s", s)
   952  				}
   953  				name := UnresolvedName{NumParts: len(substrs)}
   954  				for i := 0; i < len(substrs); i++ {
   955  					name.Parts[i] = substrs[len(substrs)-1-i]
   956  				}
   957  				funcDef, err := name.ResolveFunction(ctx.SessionData.SearchPath)
   958  				if err != nil {
   959  					return nil, err
   960  				}
   961  				return queryOid(ctx, t, NewDString(funcDef.Name))
   962  			case oid.T_regtype:
   963  				parsedTyp, err := ctx.Planner.ParseType(s)
   964  				if err == nil {
   965  					return &DOid{
   966  						semanticType: t,
   967  						DInt:         DInt(parsedTyp.Oid()),
   968  						name:         parsedTyp.SQLStandardName(),
   969  					}, nil
   970  				}
   971  				// Fall back to searching pg_type, since we don't provide syntax for
   972  				// every postgres type that we understand OIDs for.
   973  				// Trim type modifiers, e.g. `numeric(10,3)` becomes `numeric`.
   974  				s = pgSignatureRegexp.ReplaceAllString(s, "$1")
   975  				dOid, missingTypeErr := queryOid(ctx, t, NewDString(s))
   976  				if missingTypeErr == nil {
   977  					return dOid, missingTypeErr
   978  				}
   979  				// Fall back to some special cases that we support for compatibility
   980  				// only. Client use syntax like 'sometype'::regtype to produce the oid
   981  				// for a type that they want to search a catalog table for. Since we
   982  				// don't support that type, we return an artificial OID that will never
   983  				// match anything.
   984  				switch s {
   985  				// We don't support triggers, but some tools search for them
   986  				// specifically.
   987  				case "trigger":
   988  				default:
   989  					return nil, missingTypeErr
   990  				}
   991  				return &DOid{
   992  					semanticType: t,
   993  					// Types we don't support get OID -1, so they won't match anything
   994  					// in catalogs.
   995  					DInt: -1,
   996  					name: s,
   997  				}, nil
   998  
   999  			case oid.T_regclass:
  1000  				tn, err := ctx.Planner.ParseQualifiedTableName(origS)
  1001  				if err != nil {
  1002  					return nil, err
  1003  				}
  1004  				id, err := ctx.Planner.ResolveTableName(ctx.Ctx(), tn)
  1005  				if err != nil {
  1006  					return nil, err
  1007  				}
  1008  				return &DOid{
  1009  					semanticType: t,
  1010  					DInt:         DInt(id),
  1011  					name:         tn.ObjectName.String(),
  1012  				}, nil
  1013  			default:
  1014  				return queryOid(ctx, t, NewDString(s))
  1015  			}
  1016  		}
  1017  	}
  1018  
  1019  	return nil, pgerror.Newf(
  1020  		pgcode.CannotCoerce, "invalid cast: %s -> %s", d.ResolvedType(), t)
  1021  }