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 }