github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/sem/tree/datum.go (about) 1 // Copyright 2015 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package tree 12 13 import ( 14 "bytes" 15 "encoding/hex" 16 "fmt" 17 "math" 18 "regexp" 19 "sort" 20 "strconv" 21 "strings" 22 "time" 23 "unicode/utf8" 24 "unsafe" 25 26 "github.com/cockroachdb/apd/v3" 27 "github.com/cockroachdb/cockroachdb-parser/pkg/geo" 28 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/lex" 29 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase" 30 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgrepl/lsn" 31 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode" 32 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror" 33 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/sessiondatapb" 34 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/types" 35 "github.com/cockroachdb/cockroachdb-parser/pkg/util" 36 "github.com/cockroachdb/cockroachdb-parser/pkg/util/bitarray" 37 "github.com/cockroachdb/cockroachdb-parser/pkg/util/duration" 38 "github.com/cockroachdb/cockroachdb-parser/pkg/util/encoding" 39 "github.com/cockroachdb/cockroachdb-parser/pkg/util/ipaddr" 40 "github.com/cockroachdb/cockroachdb-parser/pkg/util/json" 41 "github.com/cockroachdb/cockroachdb-parser/pkg/util/stringencoding" 42 "github.com/cockroachdb/cockroachdb-parser/pkg/util/timeofday" 43 "github.com/cockroachdb/cockroachdb-parser/pkg/util/timetz" 44 "github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil" 45 "github.com/cockroachdb/cockroachdb-parser/pkg/util/timeutil/pgdate" 46 "github.com/cockroachdb/cockroachdb-parser/pkg/util/tsearch" 47 "github.com/cockroachdb/cockroachdb-parser/pkg/util/uint128" 48 "github.com/cockroachdb/cockroachdb-parser/pkg/util/uuid" 49 "github.com/cockroachdb/errors" 50 "github.com/cockroachdb/redact" 51 "github.com/lib/pq/oid" 52 "golang.org/x/text/collate" 53 "golang.org/x/text/language" 54 ) 55 56 var ( 57 constDBoolTrue DBool = true 58 constDBoolFalse DBool = false 59 60 // DBoolTrue is a pointer to the DBool(true) value and can be used in 61 // comparisons against Datum types. 62 DBoolTrue = &constDBoolTrue 63 // DBoolFalse is a pointer to the DBool(false) value and can be used in 64 // comparisons against Datum types. 65 DBoolFalse = &constDBoolFalse 66 67 // DNull is the NULL Datum. 68 DNull Datum = dNull{} 69 70 // DZero is the zero-valued integer Datum. 71 DZero = NewDInt(0) 72 73 // DTimeMaxTimeRegex is a compiled regex for parsing the 24:00 time value. 74 DTimeMaxTimeRegex = regexp.MustCompile(`^([0-9-]*(\s|T))?\s*24:00(:00(.0+)?)?\s*$`) 75 76 // The maximum timestamp Golang can represents is represented as UNIX 77 // time timeutil.Unix(-9223372028715321601, 0). 78 // However, this causes errors as we cannot reliably sort as we use 79 // UNIX time in the key encoding, and 9223372036854775807 > -9223372028715321601 80 // but timeutil.Unix(9223372036854775807, 0) < timeutil.Unix(-9223372028715321601, 0). 81 // 82 // To be compatible with pgwire, we only support the published min/max for 83 // postgres 4714 BC (JULIAN = 0) - 4713 in their docs - and 294276 AD. 84 85 // MaxSupportedTime is the maximum time we support parsing. 86 MaxSupportedTime = timeutil.Unix(9224318016000-1, 999999000) // 294276-12-31 23:59:59.999999 87 // MinSupportedTime is the minimum time we support parsing. 88 MinSupportedTime = timeutil.Unix(-210866803200, 0) // 4714-11-24 00:00:00+00 BC 89 ) 90 91 // CompareContext represents the dependencies used to evaluate comparisons 92 // between datums. 93 type CompareContext interface { 94 95 // UnwrapDatum will unwrap the OIDs and potentially the placeholders. 96 UnwrapDatum(d Datum) Datum 97 GetLocation() *time.Location 98 GetRelativeParseTime() time.Time 99 100 // MustGetPlaceholderValue is used to compare Datum 101 MustGetPlaceholderValue(p *Placeholder) Datum 102 } 103 104 // Datum represents a SQL value. 105 type Datum interface { 106 TypedExpr 107 108 // AmbiguousFormat indicates whether the result of formatting this Datum can 109 // be interpreted into more than one type. Used with 110 // fmtFlags.disambiguateDatumTypes. 111 AmbiguousFormat() bool 112 113 // Compare returns -1 if the receiver is less than other, 0 if receiver is 114 // equal to other and +1 if receiver is greater than other. 115 // TODO(rafi): Migrate all usages of this to CompareError, then delete this. 116 Compare(ctx CompareContext, other Datum) int 117 118 // CompareError is the same as Compare, but it returns an error instead of 119 // panicking. 120 CompareError(ctx CompareContext, other Datum) (int, error) 121 122 // Prev returns the previous datum and true, if one exists, or nil and false. 123 // The previous datum satisfies the following definition: if the receiver is 124 // "b" and the returned datum is "a", then for every compatible datum "x", it 125 // holds that "x < b" is true if and only if "x <= a" is true. 126 // 127 // The return value is undefined if IsMin(_ *EvalContext) returns true. 128 // 129 // TODO(#12022): for DTuple, the contract is actually that "x < b" (SQL order, 130 // where NULL < x is unknown for all x) is true only if "x <= a" 131 // (.Compare/encoding order, where NULL <= x is true for all x) is true. This 132 // is okay for now: the returned datum is used only to construct a span, which 133 // uses .Compare/encoding order and is guaranteed to be large enough by this 134 // weaker contract. The original filter expression is left in place to catch 135 // false positives. 136 Prev(ctx CompareContext) (Datum, bool) 137 138 // IsMin returns true if the datum is equal to the minimum value the datum 139 // type can hold. 140 IsMin(ctx CompareContext) bool 141 142 // Next returns the next datum and true, if one exists, or nil and false 143 // otherwise. The next datum satisfies the following definition: if the 144 // receiver is "a" and the returned datum is "b", then for every compatible 145 // datum "x", it holds that "x > a" is true if and only if "x >= b" is true. 146 // 147 // The return value is undefined if IsMax(_ *EvalContext) returns true. 148 // 149 // TODO(#12022): for DTuple, the contract is actually that "x > a" (SQL order, 150 // where x > NULL is unknown for all x) is true only if "x >= b" 151 // (.Compare/encoding order, where x >= NULL is true for all x) is true. This 152 // is okay for now: the returned datum is used only to construct a span, which 153 // uses .Compare/encoding order and is guaranteed to be large enough by this 154 // weaker contract. The original filter expression is left in place to catch 155 // false positives. 156 Next(ctx CompareContext) (Datum, bool) 157 158 // IsMax returns true if the datum is equal to the maximum value the datum 159 // type can hold. 160 IsMax(ctx CompareContext) bool 161 162 // Max returns the upper value and true, if one exists, otherwise 163 // nil and false. Used By Prev(). 164 Max(ctx CompareContext) (Datum, bool) 165 166 // Min returns the lower value, if one exists, otherwise nil and 167 // false. Used by Next(). 168 Min(ctx CompareContext) (Datum, bool) 169 170 // Size returns a lower bound on the total size of the receiver in bytes, 171 // including memory that is pointed at (even if shared between Datum 172 // instances) but excluding allocation overhead. 173 // 174 // It holds for every Datum d that d.Size(). 175 Size() uintptr 176 } 177 178 // Datums is a slice of Datum values. 179 type Datums []Datum 180 181 // Len returns the number of Datum values. 182 func (d Datums) Len() int { return len(d) } 183 184 // Format implements the NodeFormatter interface. 185 func (d *Datums) Format(ctx *FmtCtx) { 186 ctx.WriteByte('(') 187 for i, v := range *d { 188 if i > 0 { 189 ctx.WriteString(", ") 190 } 191 ctx.FormatNode(v) 192 } 193 ctx.WriteByte(')') 194 } 195 196 // Compare does a lexicographical comparison and returns -1 if the receiver 197 // is less than other, 0 if receiver is equal to other and +1 if receiver is 198 // greater than other. 199 func (d Datums) Compare(evalCtx CompareContext, other Datums) int { 200 if len(d) == 0 { 201 panic(errors.AssertionFailedf("empty Datums being compared to other")) 202 } 203 204 for i := range d { 205 if i >= len(other) { 206 return 1 207 } 208 209 compareDatum := d[i].Compare(evalCtx, other[i]) 210 if compareDatum != 0 { 211 return compareDatum 212 } 213 } 214 215 if len(d) < len(other) { 216 return -1 217 } 218 return 0 219 } 220 221 // IsDistinctFrom checks to see if two datums are distinct from each other. Any 222 // change in value is considered distinct, however, a NULL value is NOT 223 // considered distinct from another NULL value. 224 func (d Datums) IsDistinctFrom(evalCtx CompareContext, other Datums) bool { 225 if len(d) != len(other) { 226 return true 227 } 228 for i, val := range d { 229 if val == DNull { 230 if other[i] != DNull { 231 return true 232 } 233 } else { 234 if val.Compare(evalCtx, other[i]) != 0 { 235 return true 236 } 237 } 238 } 239 return false 240 } 241 242 // CompositeDatum is a Datum that may require composite encoding in 243 // indexes. Any Datum implementing this interface must also add itself to 244 // colinfo.HasCompositeKeyEncoding. 245 type CompositeDatum interface { 246 Datum 247 // IsComposite returns true if this datum is not round-tripable in a key 248 // encoding. 249 IsComposite() bool 250 } 251 252 // DBool is the boolean Datum. 253 type DBool bool 254 255 // MakeDBool converts its argument to a *DBool, returning either DBoolTrue or 256 // DBoolFalse. 257 func MakeDBool(d DBool) *DBool { 258 if d { 259 return DBoolTrue 260 } 261 return DBoolFalse 262 } 263 264 // MustBeDBool attempts to retrieve a DBool from an Expr, panicking if the 265 // assertion fails. 266 func MustBeDBool(e Expr) DBool { 267 b, ok := AsDBool(e) 268 if !ok { 269 panic(errors.AssertionFailedf("expected *DBool, found %T", e)) 270 } 271 return b 272 } 273 274 // AsDBool attempts to retrieve a *DBool from an Expr, returning a *DBool and 275 // a flag signifying whether the assertion was successful. The function should 276 // be used instead of direct type assertions. 277 func AsDBool(e Expr) (DBool, bool) { 278 switch t := e.(type) { 279 case *DBool: 280 return *t, true 281 } 282 return false, false 283 } 284 285 // MakeParseError returns a parse error using the provided string and type. An 286 // optional error can be provided, which will be appended to the end of the 287 // error string. 288 func MakeParseError(s string, typ *types.T, err error) error { 289 if err != nil { 290 return pgerror.Wrapf(err, pgcode.InvalidTextRepresentation, 291 "could not parse %q as type %s", s, typ) 292 } 293 return pgerror.Newf(pgcode.InvalidTextRepresentation, 294 "could not parse %q as type %s", s, typ) 295 } 296 297 func makeUnsupportedComparisonMessage(d1, d2 Datum) error { 298 return pgerror.Newf(pgcode.DatatypeMismatch, 299 "unsupported comparison: %s to %s", 300 errors.Safe(d1.ResolvedType()), 301 errors.Safe(d2.ResolvedType()), 302 ) 303 } 304 305 func isCaseInsensitivePrefix(prefix, s string) bool { 306 if len(prefix) > len(s) { 307 return false 308 } 309 return strings.EqualFold(prefix, s[:len(prefix)]) 310 } 311 312 // ParseBool parses and returns the boolean value represented by the provided 313 // string, or an error if parsing is unsuccessful. 314 // See https://github.com/postgres/postgres/blob/90627cf98a8e7d0531789391fd798c9bfcc3bc1a/src/backend/utils/adt/bool.c#L36 315 func ParseBool(s string) (bool, error) { 316 s = strings.TrimSpace(s) 317 if len(s) >= 1 { 318 switch s[0] { 319 case 't', 'T': 320 if isCaseInsensitivePrefix(s, "true") { 321 return true, nil 322 } 323 case 'f', 'F': 324 if isCaseInsensitivePrefix(s, "false") { 325 return false, nil 326 } 327 case 'y', 'Y': 328 if isCaseInsensitivePrefix(s, "yes") { 329 return true, nil 330 } 331 case 'n', 'N': 332 if isCaseInsensitivePrefix(s, "no") { 333 return false, nil 334 } 335 case '1': 336 if s == "1" { 337 return true, nil 338 } 339 case '0': 340 if s == "0" { 341 return false, nil 342 } 343 case 'o', 'O': 344 // Just 'o' is ambiguous between 'on' and 'off'. 345 if len(s) > 1 { 346 if isCaseInsensitivePrefix(s, "on") { 347 return true, nil 348 } 349 if isCaseInsensitivePrefix(s, "off") { 350 return false, nil 351 } 352 } 353 } 354 } 355 return false, MakeParseError(s, types.Bool, pgerror.New(pgcode.InvalidTextRepresentation, "invalid bool value")) 356 } 357 358 // ParseDBool parses and returns the *DBool Datum value represented by the provided 359 // string, or an error if parsing is unsuccessful. 360 // See https://github.com/postgres/postgres/blob/90627cf98a8e7d0531789391fd798c9bfcc3bc1a/src/backend/utils/adt/bool.c#L36 361 func ParseDBool(s string) (*DBool, error) { 362 v, err := ParseBool(s) 363 if err != nil { 364 return nil, err 365 } 366 if v { 367 return DBoolTrue, nil 368 } 369 return DBoolFalse, nil 370 } 371 372 // ParseDByte parses a string representation of hex encoded binary 373 // data. It supports both the hex format, with "\x" followed by a 374 // string of hexadecimal digits (the "\x" prefix occurs just once at 375 // the beginning), and the escaped format, which supports "\\" and 376 // octal escapes. 377 func ParseDByte(s string) (*DBytes, error) { 378 res, err := lex.DecodeRawBytesToByteArrayAuto(encoding.UnsafeConvertStringToBytes(s)) 379 if err != nil { 380 return nil, MakeParseError(s, types.Bytes, err) 381 } 382 return NewDBytes(DBytes(encoding.UnsafeConvertBytesToString(res))), nil 383 } 384 385 // ParseDUuidFromString parses and returns the *DUuid Datum value represented 386 // by the provided input string, or an error. 387 func ParseDUuidFromString(s string) (*DUuid, error) { 388 uv, err := uuid.FromString(s) 389 if err != nil { 390 return nil, MakeParseError(s, types.Uuid, err) 391 } 392 return NewDUuid(DUuid{uv}), nil 393 } 394 395 // ParseDUuidFromBytes parses and returns the *DUuid Datum value represented 396 // by the provided input bytes, or an error. 397 func ParseDUuidFromBytes(b []byte) (*DUuid, error) { 398 uv, err := uuid.FromBytes(b) 399 if err != nil { 400 return nil, MakeParseError(string(b), types.Uuid, err) 401 } 402 return NewDUuid(DUuid{uv}), nil 403 } 404 405 // ParseDIPAddrFromINetString parses and returns the *DIPAddr Datum value 406 // represented by the provided input INet string, or an error. 407 func ParseDIPAddrFromINetString(s string) (*DIPAddr, error) { 408 var d DIPAddr 409 err := ipaddr.ParseINet(s, &d.IPAddr) 410 if err != nil { 411 return nil, err 412 } 413 return &d, nil 414 } 415 416 // GetBool gets DBool or an error (also treats NULL as false, not an error). 417 func GetBool(d Datum) (DBool, error) { 418 if v, ok := d.(*DBool); ok { 419 return *v, nil 420 } 421 if d == DNull { 422 return DBool(false), nil 423 } 424 return false, errors.AssertionFailedf("cannot convert %s to type %s", d.ResolvedType().SQLStringForError(), types.Bool) 425 } 426 427 // ResolvedType implements the TypedExpr interface. 428 func (*DBool) ResolvedType() *types.T { 429 return types.Bool 430 } 431 432 // Compare implements the Datum interface. 433 func (d *DBool) Compare(ctx CompareContext, other Datum) int { 434 res, err := d.CompareError(ctx, other) 435 if err != nil { 436 panic(err) 437 } 438 return res 439 } 440 441 // CompareError implements the Datum interface. 442 func (d *DBool) CompareError(ctx CompareContext, other Datum) (int, error) { 443 if other == DNull { 444 // NULL is less than any non-NULL value. 445 return 1, nil 446 } 447 v, ok := ctx.UnwrapDatum(other).(*DBool) 448 if !ok { 449 return 0, makeUnsupportedComparisonMessage(d, other) 450 } 451 res := CompareBools(bool(*d), bool(*v)) 452 return res, nil 453 } 454 455 // CompareBools compares the input bools according to the SQL comparison rules. 456 func CompareBools(d, v bool) int { 457 if !d && v { 458 return -1 459 } 460 if d && !v { 461 return 1 462 } 463 return 0 464 } 465 466 // Prev implements the Datum interface. 467 func (*DBool) Prev(ctx CompareContext) (Datum, bool) { 468 return DBoolFalse, true 469 } 470 471 // Next implements the Datum interface. 472 func (*DBool) Next(ctx CompareContext) (Datum, bool) { 473 return DBoolTrue, true 474 } 475 476 // IsMax implements the Datum interface. 477 func (d *DBool) IsMax(ctx CompareContext) bool { 478 return bool(*d) 479 } 480 481 // IsMin implements the Datum interface. 482 func (d *DBool) IsMin(ctx CompareContext) bool { 483 return !bool(*d) 484 } 485 486 // Min implements the Datum interface. 487 func (d *DBool) Min(ctx CompareContext) (Datum, bool) { 488 return DBoolFalse, true 489 } 490 491 // Max implements the Datum interface. 492 func (d *DBool) Max(ctx CompareContext) (Datum, bool) { 493 return DBoolTrue, true 494 } 495 496 // AmbiguousFormat implements the Datum interface. 497 func (*DBool) AmbiguousFormat() bool { return false } 498 499 // PgwireFormatBool returns a single byte representing a boolean according to 500 // pgwire encoding. 501 func PgwireFormatBool(d bool) byte { 502 if d { 503 return 't' 504 } 505 return 'f' 506 } 507 508 // Format implements the NodeFormatter interface. 509 func (d *DBool) Format(ctx *FmtCtx) { 510 if ctx.HasFlags(fmtPgwireFormat) { 511 ctx.WriteByte(PgwireFormatBool(bool(*d))) 512 return 513 } 514 ctx.WriteString(strconv.FormatBool(bool(*d))) 515 } 516 517 // Size implements the Datum interface. 518 func (d *DBool) Size() uintptr { 519 return unsafe.Sizeof(*d) 520 } 521 522 // DBitArray is the BIT/VARBIT Datum. 523 type DBitArray struct { 524 bitarray.BitArray 525 } 526 527 // ParseDBitArray parses a string representation of binary digits. 528 func ParseDBitArray(s string) (*DBitArray, error) { 529 var a DBitArray 530 var err error 531 a.BitArray, err = bitarray.Parse(s) 532 if err != nil { 533 return nil, err 534 } 535 return &a, nil 536 } 537 538 // NewDBitArray returns a DBitArray. 539 func NewDBitArray(bitLen uint) *DBitArray { 540 a := MakeDBitArray(bitLen) 541 return &a 542 } 543 544 // MakeDBitArray returns a DBitArray. 545 func MakeDBitArray(bitLen uint) DBitArray { 546 return DBitArray{BitArray: bitarray.MakeZeroBitArray(bitLen)} 547 } 548 549 // MustBeDBitArray attempts to retrieve a DBitArray from an Expr, panicking if the 550 // assertion fails. 551 func MustBeDBitArray(e Expr) *DBitArray { 552 b, ok := AsDBitArray(e) 553 if !ok { 554 panic(errors.AssertionFailedf("expected *DBitArray, found %T", e)) 555 } 556 return b 557 } 558 559 // AsDBitArray attempts to retrieve a *DBitArray from an Expr, returning a *DBitArray and 560 // a flag signifying whether the assertion was successful. The function should 561 // be used instead of direct type assertions. 562 func AsDBitArray(e Expr) (*DBitArray, bool) { 563 switch t := e.(type) { 564 case *DBitArray: 565 return t, true 566 } 567 return nil, false 568 } 569 570 var errCannotCastNegativeIntToBitArray = pgerror.Newf(pgcode.CannotCoerce, 571 "cannot cast negative integer to bit varying with unbounded width") 572 573 // NewDBitArrayFromInt creates a bit array from the specified integer 574 // at the specified width. 575 // If the width is zero, only positive integers can be converted. 576 // If the width is nonzero, the value is truncated to that width. 577 // Negative values are encoded using two's complement. 578 func NewDBitArrayFromInt(i int64, width uint) (*DBitArray, error) { 579 if width == 0 && i < 0 { 580 return nil, errCannotCastNegativeIntToBitArray 581 } 582 return &DBitArray{ 583 BitArray: bitarray.MakeBitArrayFromInt64(width, i, 64), 584 }, nil 585 } 586 587 // AsDInt computes the integer value of the given bit array. 588 // The value is assumed to be encoded using two's complement. 589 // The result is truncated to the given integer number of bits, 590 // if specified. 591 // The given width must be 64 or smaller. The results are undefined 592 // if n is greater than 64. 593 func (d *DBitArray) AsDInt(n uint) *DInt { 594 if n == 0 { 595 n = 64 596 } 597 return NewDInt(DInt(d.BitArray.AsInt64(n))) 598 } 599 600 // ResolvedType implements the TypedExpr interface. 601 func (*DBitArray) ResolvedType() *types.T { 602 return types.VarBit 603 } 604 605 // Compare implements the Datum interface. 606 func (d *DBitArray) Compare(ctx CompareContext, other Datum) int { 607 res, err := d.CompareError(ctx, other) 608 if err != nil { 609 panic(err) 610 } 611 return res 612 } 613 614 // CompareError implements the Datum interface. 615 func (d *DBitArray) CompareError(ctx CompareContext, other Datum) (int, error) { 616 if other == DNull { 617 // NULL is less than any non-NULL value. 618 return 1, nil 619 } 620 v, ok := ctx.UnwrapDatum(other).(*DBitArray) 621 if !ok { 622 return 0, makeUnsupportedComparisonMessage(d, other) 623 } 624 res := bitarray.Compare(d.BitArray, v.BitArray) 625 return res, nil 626 } 627 628 // Prev implements the Datum interface. 629 func (d *DBitArray) Prev(ctx CompareContext) (Datum, bool) { 630 return nil, false 631 } 632 633 // Next implements the Datum interface. 634 func (d *DBitArray) Next(ctx CompareContext) (Datum, bool) { 635 a := bitarray.Next(d.BitArray) 636 return &DBitArray{BitArray: a}, true 637 } 638 639 // IsMax implements the Datum interface. 640 func (d *DBitArray) IsMax(ctx CompareContext) bool { 641 return false 642 } 643 644 // IsMin implements the Datum interface. 645 func (d *DBitArray) IsMin(ctx CompareContext) bool { 646 return d.BitArray.IsEmpty() 647 } 648 649 var bitArrayZero = NewDBitArray(0) 650 651 // Min implements the Datum interface. 652 func (d *DBitArray) Min(ctx CompareContext) (Datum, bool) { 653 return bitArrayZero, true 654 } 655 656 // Max implements the Datum interface. 657 func (d *DBitArray) Max(ctx CompareContext) (Datum, bool) { 658 return nil, false 659 } 660 661 // AmbiguousFormat implements the Datum interface. 662 func (*DBitArray) AmbiguousFormat() bool { return false } 663 664 // Format implements the NodeFormatter interface. 665 func (d *DBitArray) Format(ctx *FmtCtx) { 666 f := ctx.flags 667 if f.HasFlags(fmtPgwireFormat) { 668 d.BitArray.Format(&ctx.Buffer) 669 } else { 670 withQuotes := !f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 671 if withQuotes { 672 ctx.WriteString("B'") 673 } 674 d.BitArray.Format(&ctx.Buffer) 675 if withQuotes { 676 ctx.WriteByte('\'') 677 } 678 } 679 } 680 681 // Size implements the Datum interface. 682 func (d *DBitArray) Size() uintptr { 683 return d.BitArray.Sizeof() 684 } 685 686 // DInt is the int Datum. 687 type DInt int64 688 689 // NewDInt is a helper routine to create a *DInt initialized from its argument. 690 func NewDInt(d DInt) *DInt { 691 return &d 692 } 693 694 // ParseDInt parses and returns the *DInt Datum value represented by the provided 695 // string, or an error if parsing is unsuccessful. 696 func ParseDInt(s string) (*DInt, error) { 697 i, err := strconv.ParseInt(s, 0, 64) 698 if err != nil { 699 return nil, MakeParseError(s, types.Int, err) 700 } 701 return NewDInt(DInt(i)), nil 702 } 703 704 // AsDInt attempts to retrieve a DInt from an Expr, returning a DInt and 705 // a flag signifying whether the assertion was successful. The function should 706 // be used instead of direct type assertions wherever a *DInt wrapped by a 707 // *DOidWrapper is possible. 708 func AsDInt(e Expr) (DInt, bool) { 709 switch t := e.(type) { 710 case *DInt: 711 return *t, true 712 case *DOidWrapper: 713 return AsDInt(t.Wrapped) 714 } 715 return 0, false 716 } 717 718 // MustBeDInt attempts to retrieve a DInt from an Expr, panicking if the 719 // assertion fails. 720 func MustBeDInt(e Expr) DInt { 721 i, ok := AsDInt(e) 722 if !ok { 723 panic(errors.AssertionFailedf("expected *DInt, found %T", e)) 724 } 725 return i 726 } 727 728 // ResolvedType implements the TypedExpr interface. 729 func (*DInt) ResolvedType() *types.T { 730 return types.Int 731 } 732 733 // Compare implements the Datum interface. 734 func (d *DInt) Compare(ctx CompareContext, other Datum) int { 735 res, err := d.CompareError(ctx, other) 736 if err != nil { 737 panic(err) 738 } 739 return res 740 } 741 742 // CompareError implements the Datum interface. 743 func (d *DInt) CompareError(ctx CompareContext, other Datum) (int, error) { 744 if other == DNull { 745 // NULL is less than any non-NULL value. 746 return 1, nil 747 } 748 thisInt := *d 749 var v DInt 750 switch t := ctx.UnwrapDatum(other).(type) { 751 case *DInt: 752 v = *t 753 case *DFloat, *DDecimal: 754 res, err := t.CompareError(ctx, d) 755 if err != nil { 756 return 0, err 757 } 758 return -res, nil 759 case *DOid: 760 // OIDs are always unsigned 32-bit integers. Some languages, like Java, 761 // compare OIDs to signed 32-bit integers, so we implement the comparison 762 // by converting to a uint32 first. This matches Postgres behavior. 763 o, err := IntToOid(thisInt) 764 if err != nil { 765 return 0, err 766 } 767 thisInt = DInt(o.Oid) 768 v = DInt(t.Oid) 769 default: 770 return 0, makeUnsupportedComparisonMessage(d, other) 771 } 772 if thisInt < v { 773 return -1, nil 774 } 775 if thisInt > v { 776 return 1, nil 777 } 778 return 0, nil 779 } 780 781 // Prev implements the Datum interface. 782 func (d *DInt) Prev(ctx CompareContext) (Datum, bool) { 783 return NewDInt(*d - 1), true 784 } 785 786 // Next implements the Datum interface. 787 func (d *DInt) Next(ctx CompareContext) (Datum, bool) { 788 return NewDInt(*d + 1), true 789 } 790 791 // IsMax implements the Datum interface. 792 func (d *DInt) IsMax(ctx CompareContext) bool { 793 return *d == math.MaxInt64 794 } 795 796 // IsMin implements the Datum interface. 797 func (d *DInt) IsMin(ctx CompareContext) bool { 798 return *d == math.MinInt64 799 } 800 801 var dMaxInt = NewDInt(math.MaxInt64) 802 var dMinInt = NewDInt(math.MinInt64) 803 804 // Max implements the Datum interface. 805 func (d *DInt) Max(ctx CompareContext) (Datum, bool) { 806 return dMaxInt, true 807 } 808 809 // Min implements the Datum interface. 810 func (d *DInt) Min(ctx CompareContext) (Datum, bool) { 811 return dMinInt, true 812 } 813 814 // AmbiguousFormat implements the Datum interface. 815 func (*DInt) AmbiguousFormat() bool { return true } 816 817 // Format implements the NodeFormatter interface. 818 func (d *DInt) Format(ctx *FmtCtx) { 819 // If the number is negative, we need to use parens or the `:::INT` type hint 820 // will take precedence over the negation sign. 821 disambiguate := ctx.flags.HasFlags(fmtDisambiguateDatumTypes) 822 parsable := ctx.flags.HasFlags(FmtParsableNumerics) 823 needParens := (disambiguate || parsable) && *d < 0 824 if needParens { 825 ctx.WriteByte('(') 826 } 827 ctx.WriteString(strconv.FormatInt(int64(*d), 10)) 828 if needParens { 829 ctx.WriteByte(')') 830 } 831 } 832 833 // Size implements the Datum interface. 834 func (d *DInt) Size() uintptr { 835 return unsafe.Sizeof(*d) 836 } 837 838 // DFloat is the float Datum. 839 type DFloat float64 840 841 // MustBeDFloat attempts to retrieve a DFloat from an Expr, panicking if the 842 // assertion fails. 843 func MustBeDFloat(e Expr) DFloat { 844 switch t := e.(type) { 845 case *DFloat: 846 return *t 847 } 848 panic(errors.AssertionFailedf("expected *DFloat, found %T", e)) 849 } 850 851 // AsDFloat attempts to retrieve a DFloat from an Expr, returning a DFloat and 852 // a flag signifying whether the assertion was successful. The function should 853 // be used instead of direct type assertions wherever a *DFloat wrapped by a 854 // *DOidWrapper is possible. 855 func AsDFloat(e Expr) (*DFloat, bool) { 856 switch t := e.(type) { 857 case *DFloat: 858 return t, true 859 case *DOidWrapper: 860 return AsDFloat(t.Wrapped) 861 } 862 return nil, false 863 } 864 865 // NewDFloat is a helper routine to create a *DFloat initialized from its 866 // argument. 867 func NewDFloat(d DFloat) *DFloat { 868 return &d 869 } 870 871 // ParseDFloat parses and returns the *DFloat Datum value represented by the provided 872 // string, or an error if parsing is unsuccessful. 873 func ParseDFloat(s string) (*DFloat, error) { 874 f, err := strconv.ParseFloat(s, 64) 875 if err != nil { 876 return nil, MakeParseError(s, types.Float, err) 877 } 878 return NewDFloat(DFloat(f)), nil 879 } 880 881 // ResolvedType implements the TypedExpr interface. 882 func (*DFloat) ResolvedType() *types.T { 883 return types.Float 884 } 885 886 // Compare implements the Datum interface. 887 func (d *DFloat) Compare(ctx CompareContext, other Datum) int { 888 res, err := d.CompareError(ctx, other) 889 if err != nil { 890 panic(err) 891 } 892 return res 893 } 894 895 // CompareError implements the Datum interface. 896 func (d *DFloat) CompareError(ctx CompareContext, other Datum) (int, error) { 897 if other == DNull { 898 // NULL is less than any non-NULL value. 899 return 1, nil 900 } 901 var v DFloat 902 switch t := ctx.UnwrapDatum(other).(type) { 903 case *DFloat: 904 v = *t 905 case *DInt: 906 v = DFloat(MustBeDInt(t)) 907 case *DDecimal: 908 res, err := t.CompareError(ctx, d) 909 if err != nil { 910 return 0, err 911 } 912 return -res, nil 913 default: 914 return 0, makeUnsupportedComparisonMessage(d, other) 915 } 916 if *d < v { 917 return -1, nil 918 } 919 if *d > v { 920 return 1, nil 921 } 922 // NaN sorts before non-NaN (#10109). 923 if *d == v { 924 return 0, nil 925 } 926 if math.IsNaN(float64(*d)) { 927 if math.IsNaN(float64(v)) { 928 return 0, nil 929 } 930 return -1, nil 931 } 932 return 1, nil 933 } 934 935 // Prev implements the Datum interface. 936 func (d *DFloat) Prev(ctx CompareContext) (Datum, bool) { 937 f := float64(*d) 938 if math.IsNaN(f) { 939 return nil, false 940 } 941 if f == math.Inf(-1) { 942 return DNaNFloat, true 943 } 944 return NewDFloat(DFloat(math.Nextafter(f, math.Inf(-1)))), true 945 } 946 947 // Next implements the Datum interface. 948 func (d *DFloat) Next(ctx CompareContext) (Datum, bool) { 949 f := float64(*d) 950 if math.IsNaN(f) { 951 return DNegInfFloat, true 952 } 953 if f == math.Inf(+1) { 954 return nil, false 955 } 956 return NewDFloat(DFloat(math.Nextafter(f, math.Inf(+1)))), true 957 } 958 959 var ( 960 // DZeroFloat is the DFloat for zero. 961 DZeroFloat = NewDFloat(0) 962 // DPosInfFloat is the DFloat for positive infinity. 963 DPosInfFloat = NewDFloat(DFloat(math.Inf(+1))) 964 // DNegInfFloat is the DFloat for negative infinity. 965 DNegInfFloat = NewDFloat(DFloat(math.Inf(-1))) 966 // DNaNFloat is the DFloat for NaN. 967 DNaNFloat = NewDFloat(DFloat(math.NaN())) 968 ) 969 970 // IsMax implements the Datum interface. 971 func (d *DFloat) IsMax(ctx CompareContext) bool { 972 return *d == *DPosInfFloat 973 } 974 975 // IsMin implements the Datum interface. 976 func (d *DFloat) IsMin(ctx CompareContext) bool { 977 return math.IsNaN(float64(*d)) 978 } 979 980 // Max implements the Datum interface. 981 func (d *DFloat) Max(ctx CompareContext) (Datum, bool) { 982 return DPosInfFloat, true 983 } 984 985 // Min implements the Datum interface. 986 func (d *DFloat) Min(ctx CompareContext) (Datum, bool) { 987 return DNaNFloat, true 988 } 989 990 // AmbiguousFormat implements the Datum interface. 991 func (*DFloat) AmbiguousFormat() bool { return true } 992 993 // Format implements the NodeFormatter interface. 994 func (d *DFloat) Format(ctx *FmtCtx) { 995 fl := float64(*d) 996 997 // TODO(#sql-sessions): formatting float4s are broken here as we cannot 998 // differentiate float4 vs float8. 999 // #73743, ##84326, #41689 are partially related. 1000 if ctx.HasFlags(fmtPgwireFormat) { 1001 ctx.Write(PgwireFormatFloat(ctx.scratch[:0], float64(*d), ctx.dataConversionConfig, d.ResolvedType())) 1002 return 1003 } 1004 1005 disambiguate := ctx.flags.HasFlags(fmtDisambiguateDatumTypes) 1006 parsable := ctx.flags.HasFlags(FmtParsableNumerics) 1007 quote := parsable && (math.IsNaN(fl) || math.IsInf(fl, 0)) 1008 // We need to use Signbit here and not just fl < 0 because of -0. 1009 needParens := !quote && (disambiguate || parsable) && math.Signbit(fl) 1010 // If the number is negative, we need to use parens or the `:::INT` type hint 1011 // will take precedence over the negation sign. 1012 if quote { 1013 ctx.WriteByte('\'') 1014 } else if needParens { 1015 ctx.WriteByte('(') 1016 } 1017 if _, frac := math.Modf(fl); frac == 0 && -1000000 < *d && *d < 1000000 { 1018 // d is a small whole number. Ensure it is printed using a decimal point. 1019 ctx.Printf("%.1f", fl) 1020 } else { 1021 ctx.Printf("%g", fl) 1022 } 1023 if quote { 1024 ctx.WriteByte('\'') 1025 } else if needParens { 1026 ctx.WriteByte(')') 1027 } 1028 } 1029 1030 // Size implements the Datum interface. 1031 func (d *DFloat) Size() uintptr { 1032 return unsafe.Sizeof(*d) 1033 } 1034 1035 // IsComposite implements the CompositeDatum interface. 1036 func (d *DFloat) IsComposite() bool { 1037 // -0 is composite. 1038 return math.Float64bits(float64(*d)) == 1<<63 1039 } 1040 1041 // DDecimal is the decimal Datum. 1042 type DDecimal struct { 1043 apd.Decimal 1044 } 1045 1046 // MustBeDDecimal attempts to retrieve a DDecimal from an Expr, panicking if the 1047 // assertion fails. 1048 func MustBeDDecimal(e Expr) DDecimal { 1049 switch t := e.(type) { 1050 case *DDecimal: 1051 return *t 1052 } 1053 panic(errors.AssertionFailedf("expected *DDecimal, found %T", e)) 1054 } 1055 1056 // AsDDecimal attempts to retrieve a DDecimal from an Expr, returning a DDecimal and 1057 // a flag signifying whether the assertion was successful. 1058 func AsDDecimal(e Expr) (*DDecimal, bool) { 1059 switch t := e.(type) { 1060 case *DDecimal: 1061 return t, true 1062 } 1063 return nil, false 1064 } 1065 1066 // ParseDDecimal parses and returns the *DDecimal Datum value represented by the 1067 // provided string, or an error if parsing is unsuccessful. 1068 func ParseDDecimal(s string) (*DDecimal, error) { 1069 dd := &DDecimal{} 1070 err := dd.SetString(s) 1071 return dd, err 1072 } 1073 1074 // SetString sets d to s. Any non-standard NaN values are converted to a 1075 // normal NaN. Any negative zero is converted to positive. 1076 func (d *DDecimal) SetString(s string) error { 1077 return setDecimalString(s, &d.Decimal) 1078 } 1079 1080 func setDecimalString(s string, d *apd.Decimal) error { 1081 // ExactCtx should be able to handle any decimal, but if there is any rounding 1082 // or other inexact conversion, it will result in an error. 1083 // _, res, err := HighPrecisionCtx.SetString(&d.Decimal, s) 1084 _, res, err := ExactCtx.SetString(d, s) 1085 if res != 0 || err != nil { 1086 return MakeParseError(s, types.Decimal, err) 1087 } 1088 switch d.Form { 1089 case apd.NaNSignaling: 1090 d.Form = apd.NaN 1091 d.Negative = false 1092 case apd.NaN: 1093 d.Negative = false 1094 case apd.Finite: 1095 if d.IsZero() && d.Negative { 1096 d.Negative = false 1097 } 1098 } 1099 return nil 1100 } 1101 1102 // ResolvedType implements the TypedExpr interface. 1103 func (*DDecimal) ResolvedType() *types.T { 1104 return types.Decimal 1105 } 1106 1107 // Compare implements the Datum interface. 1108 func (d *DDecimal) Compare(ctx CompareContext, other Datum) int { 1109 res, err := d.CompareError(ctx, other) 1110 if err != nil { 1111 panic(err) 1112 } 1113 return res 1114 } 1115 1116 // CompareError implements the Datum interface. 1117 func (d *DDecimal) CompareError(ctx CompareContext, other Datum) (int, error) { 1118 if other == DNull { 1119 // NULL is less than any non-NULL value. 1120 return 1, nil 1121 } 1122 var v apd.Decimal 1123 switch t := ctx.UnwrapDatum(other).(type) { 1124 case *DDecimal: 1125 v.Set(&t.Decimal) 1126 case *DInt: 1127 v.SetInt64(int64(*t)) 1128 case *DFloat: 1129 if _, err := v.SetFloat64(float64(*t)); err != nil { 1130 panic(errors.NewAssertionErrorWithWrappedErrf(err, "decimal compare, unexpected error")) 1131 } 1132 default: 1133 return 0, makeUnsupportedComparisonMessage(d, other) 1134 } 1135 res := CompareDecimals(&d.Decimal, &v) 1136 return res, nil 1137 } 1138 1139 // CompareDecimals compares 2 apd.Decimals according to the SQL comparison 1140 // rules, making sure that NaNs sort first. 1141 func CompareDecimals(d *apd.Decimal, v *apd.Decimal) int { 1142 // NaNs sort first in SQL. 1143 if dn, vn := d.Form == apd.NaN, v.Form == apd.NaN; dn && !vn { 1144 return -1 1145 } else if !dn && vn { 1146 return 1 1147 } else if dn && vn { 1148 return 0 1149 } 1150 return d.Cmp(v) 1151 } 1152 1153 // Prev implements the Datum interface. 1154 func (d *DDecimal) Prev(ctx CompareContext) (Datum, bool) { 1155 return nil, false 1156 } 1157 1158 // Next implements the Datum interface. 1159 func (d *DDecimal) Next(ctx CompareContext) (Datum, bool) { 1160 return nil, false 1161 } 1162 1163 var ( 1164 // DZeroDecimal is the decimal constant '0'. 1165 DZeroDecimal = &DDecimal{Decimal: apd.Decimal{}} 1166 1167 // dNaNDecimal is the decimal constant 'NaN'. 1168 dNaNDecimal = &DDecimal{Decimal: apd.Decimal{Form: apd.NaN}} 1169 1170 // dPosInfDecimal is the decimal constant 'inf'. 1171 dPosInfDecimal = &DDecimal{Decimal: apd.Decimal{Form: apd.Infinite, Negative: false}} 1172 ) 1173 1174 // IsMax implements the Datum interface. 1175 func (d *DDecimal) IsMax(ctx CompareContext) bool { 1176 return d.Form == apd.Infinite && !d.Negative 1177 } 1178 1179 // IsMin implements the Datum interface. 1180 func (d *DDecimal) IsMin(ctx CompareContext) bool { 1181 return d.Form == apd.NaN 1182 } 1183 1184 // Max implements the Datum interface. 1185 func (d *DDecimal) Max(ctx CompareContext) (Datum, bool) { 1186 return dPosInfDecimal, true 1187 } 1188 1189 // Min implements the Datum interface. 1190 func (d *DDecimal) Min(ctx CompareContext) (Datum, bool) { 1191 return dNaNDecimal, true 1192 } 1193 1194 // AmbiguousFormat implements the Datum interface. 1195 func (*DDecimal) AmbiguousFormat() bool { return true } 1196 1197 // Format implements the NodeFormatter interface. 1198 func (d *DDecimal) Format(ctx *FmtCtx) { 1199 // If the number is negative, we need to use parens or the `:::INT` type hint 1200 // will take precedence over the negation sign. 1201 disambiguate := ctx.flags.HasFlags(fmtDisambiguateDatumTypes) 1202 parsable := ctx.flags.HasFlags(FmtParsableNumerics) 1203 quote := parsable && d.Decimal.Form != apd.Finite 1204 needParens := !quote && (disambiguate || parsable) && d.Negative 1205 if needParens { 1206 ctx.WriteByte('(') 1207 } 1208 if quote { 1209 ctx.WriteByte('\'') 1210 } 1211 ctx.WriteString(d.Decimal.String()) 1212 if quote { 1213 ctx.WriteByte('\'') 1214 } 1215 if needParens { 1216 ctx.WriteByte(')') 1217 } 1218 } 1219 1220 // Size implements the Datum interface. 1221 func (d *DDecimal) Size() uintptr { 1222 return d.Decimal.Size() 1223 } 1224 1225 var ( 1226 decimalNegativeZero = &apd.Decimal{Negative: true} 1227 bigTen = apd.NewBigInt(10) 1228 ) 1229 1230 // IsComposite implements the CompositeDatum interface. 1231 func (d *DDecimal) IsComposite() bool { 1232 // -0 is composite. 1233 if d.Decimal.CmpTotal(decimalNegativeZero) == 0 { 1234 return true 1235 } 1236 1237 // Check if d is divisible by 10. 1238 var r apd.BigInt 1239 r.Rem(&d.Decimal.Coeff, bigTen) 1240 return r.Sign() == 0 1241 } 1242 1243 // DString is the string Datum. 1244 type DString string 1245 1246 // NewDString is a helper routine to create a *DString initialized from its 1247 // argument. 1248 func NewDString(d string) *DString { 1249 r := DString(d) 1250 return &r 1251 } 1252 1253 // AsDString attempts to retrieve a DString from an Expr, returning a DString and 1254 // a flag signifying whether the assertion was successful. The function should 1255 // be used instead of direct type assertions wherever a *DString wrapped by a 1256 // *DOidWrapper is possible. 1257 func AsDString(e Expr) (DString, bool) { 1258 switch t := e.(type) { 1259 case *DString: 1260 return *t, true 1261 case *DOidWrapper: 1262 return AsDString(t.Wrapped) 1263 } 1264 return "", false 1265 } 1266 1267 // MustBeDString attempts to retrieve a DString from an Expr, panicking if the 1268 // assertion fails. 1269 func MustBeDString(e Expr) DString { 1270 i, ok := AsDString(e) 1271 if !ok { 1272 panic(errors.AssertionFailedf("expected *DString, found %T", e)) 1273 } 1274 return i 1275 } 1276 1277 // MustBeDStringOrDNull attempts to retrieve a DString or DNull from an Expr, panicking if the 1278 // assertion fails. 1279 func MustBeDStringOrDNull(e Expr) DString { 1280 i, ok := AsDString(e) 1281 if !ok && e != DNull { 1282 panic(errors.AssertionFailedf("expected *DString or DNull, found %T", e)) 1283 } 1284 return i 1285 } 1286 1287 // ResolvedType implements the TypedExpr interface. 1288 func (*DString) ResolvedType() *types.T { 1289 return types.String 1290 } 1291 1292 // Compare implements the Datum interface. 1293 func (d *DString) Compare(ctx CompareContext, other Datum) int { 1294 res, err := d.CompareError(ctx, other) 1295 if err != nil { 1296 panic(err) 1297 } 1298 return res 1299 } 1300 1301 // CompareError implements the Datum interface. 1302 func (d *DString) CompareError(ctx CompareContext, other Datum) (int, error) { 1303 if other == DNull { 1304 // NULL is less than any non-NULL value. 1305 return 1, nil 1306 } 1307 v, ok := ctx.UnwrapDatum(other).(*DString) 1308 if !ok { 1309 return 0, makeUnsupportedComparisonMessage(d, other) 1310 } 1311 if *d < *v { 1312 return -1, nil 1313 } 1314 if *d > *v { 1315 return 1, nil 1316 } 1317 return 0, nil 1318 } 1319 1320 // Prev implements the Datum interface. 1321 func (d *DString) Prev(ctx CompareContext) (Datum, bool) { 1322 return nil, false 1323 } 1324 1325 // Next implements the Datum interface. 1326 func (d *DString) Next(ctx CompareContext) (Datum, bool) { 1327 return NewDString(string(encoding.BytesNext([]byte(*d)))), true 1328 } 1329 1330 // IsMax implements the Datum interface. 1331 func (*DString) IsMax(ctx CompareContext) bool { 1332 return false 1333 } 1334 1335 // IsMin implements the Datum interface. 1336 func (d *DString) IsMin(ctx CompareContext) bool { 1337 return len(*d) == 0 1338 } 1339 1340 var dEmptyString = NewDString("") 1341 1342 // Min implements the Datum interface. 1343 func (d *DString) Min(ctx CompareContext) (Datum, bool) { 1344 return dEmptyString, true 1345 } 1346 1347 // Max implements the Datum interface. 1348 func (d *DString) Max(ctx CompareContext) (Datum, bool) { 1349 return nil, false 1350 } 1351 1352 // AmbiguousFormat implements the Datum interface. 1353 func (*DString) AmbiguousFormat() bool { return true } 1354 1355 // Format implements the NodeFormatter interface. 1356 func (d *DString) Format(ctx *FmtCtx) { 1357 buf, f := &ctx.Buffer, ctx.flags 1358 if f.HasFlags(fmtRawStrings) || f.HasFlags(fmtPgwireFormat) { 1359 buf.WriteString(string(*d)) 1360 } else { 1361 lexbase.EncodeSQLStringWithFlags(buf, string(*d), f.EncodeFlags()) 1362 } 1363 } 1364 1365 // Size implements the Datum interface. 1366 func (d *DString) Size() uintptr { 1367 return unsafe.Sizeof(*d) + uintptr(len(*d)) 1368 } 1369 1370 // UnsafeBytes returns the raw bytes avoiding allocation. It is "Unsafe" because 1371 // the contract is that callers must not to mutate the bytes but there is 1372 // nothing stopping that from happening. 1373 func (d *DString) UnsafeBytes() []byte { 1374 return encoding.UnsafeConvertStringToBytes(string(*d)) 1375 } 1376 1377 // DCollatedString is the Datum for strings with a locale. The struct members 1378 // are intended to be immutable. 1379 type DCollatedString struct { 1380 Contents string 1381 Locale string 1382 // Key is the collation key. 1383 Key []byte 1384 } 1385 1386 // CollationEnvironment stores the state needed by NewDCollatedString to 1387 // construct collation keys efficiently. 1388 type CollationEnvironment struct { 1389 cache map[string]collationEnvironmentCacheEntry 1390 buffer *collate.Buffer 1391 } 1392 1393 type collationEnvironmentCacheEntry struct { 1394 // locale is interned. 1395 locale string 1396 // collator is an expensive factory. 1397 collator *collate.Collator 1398 } 1399 1400 func (env *CollationEnvironment) getCacheEntry( 1401 locale string, 1402 ) (collationEnvironmentCacheEntry, error) { 1403 entry, ok := env.cache[locale] 1404 if !ok { 1405 if env.cache == nil { 1406 env.cache = make(map[string]collationEnvironmentCacheEntry) 1407 } 1408 tag, err := language.Parse(locale) 1409 if err != nil { 1410 err = errors.NewAssertionErrorWithWrappedErrf(err, "failed to parse locale %q", locale) 1411 return collationEnvironmentCacheEntry{}, err 1412 } 1413 1414 entry = collationEnvironmentCacheEntry{locale, collate.New(tag)} 1415 env.cache[locale] = entry 1416 } 1417 return entry, nil 1418 } 1419 1420 // NewDCollatedString is a helper routine to create a *DCollatedString. Panics 1421 // if locale is invalid. Not safe for concurrent use. 1422 func NewDCollatedString( 1423 contents string, locale string, env *CollationEnvironment, 1424 ) (*DCollatedString, error) { 1425 entry, err := env.getCacheEntry(locale) 1426 if err != nil { 1427 return nil, err 1428 } 1429 if env.buffer == nil { 1430 env.buffer = &collate.Buffer{} 1431 } 1432 key := entry.collator.KeyFromString(env.buffer, contents) 1433 d := DCollatedString{contents, entry.locale, make([]byte, len(key))} 1434 copy(d.Key, key) 1435 env.buffer.Reset() 1436 return &d, nil 1437 } 1438 1439 // AsDCollatedString attempts to retrieve a DString from an Expr, returning a AsDCollatedString and 1440 // a flag signifying whether the assertion was successful. The function should 1441 // be used instead of direct type assertions wherever a *DCollatedString wrapped by a 1442 // *DOidWrapper is possible. 1443 func AsDCollatedString(e Expr) (DCollatedString, bool) { 1444 switch t := e.(type) { 1445 case *DCollatedString: 1446 return *t, true 1447 case *DOidWrapper: 1448 return AsDCollatedString(t.Wrapped) 1449 } 1450 return DCollatedString{}, false 1451 } 1452 1453 // AmbiguousFormat implements the Datum interface. 1454 func (*DCollatedString) AmbiguousFormat() bool { return false } 1455 1456 // Format implements the NodeFormatter interface. 1457 func (d *DCollatedString) Format(ctx *FmtCtx) { 1458 lexbase.EncodeSQLString(&ctx.Buffer, d.Contents) 1459 ctx.WriteString(" COLLATE ") 1460 lex.EncodeLocaleName(&ctx.Buffer, d.Locale) 1461 } 1462 1463 // ResolvedType implements the TypedExpr interface. 1464 func (d *DCollatedString) ResolvedType() *types.T { 1465 return types.MakeCollatedString(types.String, d.Locale) 1466 } 1467 1468 // Compare implements the Datum interface. 1469 func (d *DCollatedString) Compare(ctx CompareContext, other Datum) int { 1470 res, err := d.CompareError(ctx, other) 1471 if err != nil { 1472 panic(err) 1473 } 1474 return res 1475 } 1476 1477 // CompareError implements the Datum interface. 1478 func (d *DCollatedString) CompareError(ctx CompareContext, other Datum) (int, error) { 1479 if other == DNull { 1480 // NULL is less than any non-NULL value. 1481 return 1, nil 1482 } 1483 v, ok := ctx.UnwrapDatum(other).(*DCollatedString) 1484 if !ok || !lex.LocaleNamesAreEqual(d.Locale, v.Locale) { 1485 return 0, makeUnsupportedComparisonMessage(d, other) 1486 } 1487 res := bytes.Compare(d.Key, v.Key) 1488 return res, nil 1489 } 1490 1491 // Prev implements the Datum interface. 1492 func (d *DCollatedString) Prev(ctx CompareContext) (Datum, bool) { 1493 return nil, false 1494 } 1495 1496 // Next implements the Datum interface. 1497 func (d *DCollatedString) Next(ctx CompareContext) (Datum, bool) { 1498 return nil, false 1499 } 1500 1501 // IsMax implements the Datum interface. 1502 func (*DCollatedString) IsMax(ctx CompareContext) bool { 1503 return false 1504 } 1505 1506 // IsMin implements the Datum interface. 1507 func (d *DCollatedString) IsMin(ctx CompareContext) bool { 1508 return d.Contents == "" 1509 } 1510 1511 // Min implements the Datum interface. 1512 func (d *DCollatedString) Min(ctx CompareContext) (Datum, bool) { 1513 return &DCollatedString{"", d.Locale, nil}, true 1514 } 1515 1516 // Max implements the Datum interface. 1517 func (d *DCollatedString) Max(ctx CompareContext) (Datum, bool) { 1518 return nil, false 1519 } 1520 1521 // Size implements the Datum interface. 1522 func (d *DCollatedString) Size() uintptr { 1523 return unsafe.Sizeof(*d) + uintptr(len(d.Contents)) + uintptr(len(d.Locale)) + uintptr(len(d.Key)) 1524 } 1525 1526 // IsComposite implements the CompositeDatum interface. 1527 func (d *DCollatedString) IsComposite() bool { 1528 return true 1529 } 1530 1531 // UnsafeContentBytes returns the raw bytes avoiding allocation. It is "unsafe" 1532 // because the contract is that callers must not to mutate the bytes but there 1533 // is nothing stopping that from happening. 1534 func (d *DCollatedString) UnsafeContentBytes() []byte { 1535 return encoding.UnsafeConvertStringToBytes(d.Contents) 1536 } 1537 1538 // DBytes is the bytes Datum. The underlying type is a string because we want 1539 // the immutability, but this may contain arbitrary bytes. 1540 type DBytes string 1541 1542 // NewDBytes is a helper routine to create a *DBytes initialized from its 1543 // argument. 1544 func NewDBytes(d DBytes) *DBytes { 1545 return &d 1546 } 1547 1548 // MustBeDBytes attempts to convert an Expr into a DBytes, panicking if unsuccessful. 1549 func MustBeDBytes(e Expr) DBytes { 1550 i, ok := AsDBytes(e) 1551 if !ok { 1552 panic(errors.AssertionFailedf("expected *DBytes, found %T", e)) 1553 } 1554 return i 1555 } 1556 1557 // AsDBytes attempts to convert an Expr into a DBytes, returning a flag indicating 1558 // whether it was successful. 1559 func AsDBytes(e Expr) (DBytes, bool) { 1560 switch t := e.(type) { 1561 case *DBytes: 1562 return *t, true 1563 } 1564 return "", false 1565 } 1566 1567 // ResolvedType implements the TypedExpr interface. 1568 func (*DBytes) ResolvedType() *types.T { 1569 return types.Bytes 1570 } 1571 1572 // Compare implements the Datum interface. 1573 func (d *DBytes) Compare(ctx CompareContext, other Datum) int { 1574 res, err := d.CompareError(ctx, other) 1575 if err != nil { 1576 panic(err) 1577 } 1578 return res 1579 } 1580 1581 // CompareError implements the Datum interface. 1582 func (d *DBytes) CompareError(ctx CompareContext, other Datum) (int, error) { 1583 if other == DNull { 1584 // NULL is less than any non-NULL value. 1585 return 1, nil 1586 } 1587 v, ok := ctx.UnwrapDatum(other).(*DBytes) 1588 if !ok { 1589 return 0, makeUnsupportedComparisonMessage(d, other) 1590 } 1591 if *d < *v { 1592 return -1, nil 1593 } 1594 if *d > *v { 1595 return 1, nil 1596 } 1597 return 0, nil 1598 } 1599 1600 // Prev implements the Datum interface. 1601 func (d *DBytes) Prev(ctx CompareContext) (Datum, bool) { 1602 return nil, false 1603 } 1604 1605 // Next implements the Datum interface. 1606 func (d *DBytes) Next(ctx CompareContext) (Datum, bool) { 1607 return NewDBytes(DBytes(encoding.BytesNext([]byte(*d)))), true 1608 } 1609 1610 // IsMax implements the Datum interface. 1611 func (*DBytes) IsMax(ctx CompareContext) bool { 1612 return false 1613 } 1614 1615 // IsMin implements the Datum interface. 1616 func (d *DBytes) IsMin(ctx CompareContext) bool { 1617 return len(*d) == 0 1618 } 1619 1620 var dEmptyBytes = NewDBytes(DBytes("")) 1621 1622 // Min implements the Datum interface. 1623 func (d *DBytes) Min(ctx CompareContext) (Datum, bool) { 1624 return dEmptyBytes, true 1625 } 1626 1627 // Max implements the Datum interface. 1628 func (d *DBytes) Max(ctx CompareContext) (Datum, bool) { 1629 return nil, false 1630 } 1631 1632 // AmbiguousFormat implements the Datum interface. 1633 func (*DBytes) AmbiguousFormat() bool { return true } 1634 1635 func writeAsHexString(ctx *FmtCtx, b string) { 1636 for i := 0; i < len(b); i++ { 1637 ctx.Write(stringencoding.RawHexMap[b[i]]) 1638 } 1639 } 1640 1641 // Format implements the NodeFormatter interface. 1642 func (d *DBytes) Format(ctx *FmtCtx) { 1643 f := ctx.flags 1644 if f.HasFlags(fmtPgwireFormat) { 1645 ctx.WriteString(`\x`) 1646 writeAsHexString(ctx, string(*d)) 1647 } else if f.HasFlags(fmtFormatByteLiterals) { 1648 ctx.WriteByte('x') 1649 ctx.WriteByte('\'') 1650 _, _ = hex.NewEncoder(ctx).Write([]byte(*d)) 1651 ctx.WriteByte('\'') 1652 } else { 1653 withQuotes := !f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 1654 if withQuotes { 1655 ctx.WriteByte('\'') 1656 } 1657 ctx.WriteString("\\x") 1658 writeAsHexString(ctx, string(*d)) 1659 if withQuotes { 1660 ctx.WriteByte('\'') 1661 } 1662 } 1663 } 1664 1665 // Size implements the Datum interface. 1666 func (d *DBytes) Size() uintptr { 1667 return unsafe.Sizeof(*d) + uintptr(len(*d)) 1668 } 1669 1670 // UnsafeBytes returns the raw bytes avoiding allocation. It is "unsafe" because 1671 // the contract is that callers must not to mutate the bytes but there is 1672 // nothing stopping that from happening. 1673 func (d *DBytes) UnsafeBytes() []byte { 1674 return encoding.UnsafeConvertStringToBytes(string(*d)) 1675 } 1676 1677 // DEncodedKey is a special Datum of types.EncodedKey type, used to pass through 1678 // encoded key data. It is similar to DBytes, except when it comes to 1679 // encoding/decoding. It is currently used to pass around inverted index keys, 1680 // which do not fully encode an object. 1681 type DEncodedKey string 1682 1683 // NewDEncodedKey is a helper routine to create a *DEncodedKey initialized from its 1684 // argument. 1685 func NewDEncodedKey(d DEncodedKey) *DEncodedKey { 1686 return &d 1687 } 1688 1689 // ResolvedType implements the TypedExpr interface. 1690 func (*DEncodedKey) ResolvedType() *types.T { 1691 return types.EncodedKey 1692 } 1693 1694 // Compare implements the Datum interface. 1695 func (d *DEncodedKey) Compare(ctx CompareContext, other Datum) int { 1696 panic(errors.AssertionFailedf("not implemented")) 1697 } 1698 1699 // CompareError implements the Datum interface. 1700 func (d *DEncodedKey) CompareError(ctx CompareContext, other Datum) (int, error) { 1701 panic(errors.AssertionFailedf("not implemented")) 1702 } 1703 1704 // Prev implements the Datum interface. 1705 func (d *DEncodedKey) Prev(ctx CompareContext) (Datum, bool) { 1706 return nil, false 1707 } 1708 1709 // Next implements the Datum interface. 1710 func (d *DEncodedKey) Next(ctx CompareContext) (Datum, bool) { 1711 return nil, false 1712 } 1713 1714 // IsMax implements the Datum interface. 1715 func (*DEncodedKey) IsMax(ctx CompareContext) bool { 1716 return false 1717 } 1718 1719 // IsMin implements the Datum interface. 1720 func (d *DEncodedKey) IsMin(ctx CompareContext) bool { 1721 return false 1722 } 1723 1724 // Min implements the Datum interface. 1725 func (d *DEncodedKey) Min(ctx CompareContext) (Datum, bool) { 1726 return nil, false 1727 } 1728 1729 // Max implements the Datum interface. 1730 func (d *DEncodedKey) Max(ctx CompareContext) (Datum, bool) { 1731 return nil, false 1732 } 1733 1734 // AmbiguousFormat implements the Datum interface. 1735 func (*DEncodedKey) AmbiguousFormat() bool { 1736 panic(errors.AssertionFailedf("not implemented")) 1737 } 1738 1739 // Format implements the NodeFormatter interface. 1740 func (d *DEncodedKey) Format(ctx *FmtCtx) { 1741 (*DBytes)(d).Format(ctx) 1742 } 1743 1744 // Size implements the Datum interface. 1745 func (d *DEncodedKey) Size() uintptr { 1746 return unsafe.Sizeof(*d) + uintptr(len(*d)) 1747 } 1748 1749 // UnsafeBytes returns the raw bytes avoiding allocation. It is "unsafe" because 1750 // the contract is that callers must not to mutate the bytes but there is 1751 // nothing stopping that from happening. 1752 func (d *DEncodedKey) UnsafeBytes() []byte { 1753 return encoding.UnsafeConvertStringToBytes(string(*d)) 1754 } 1755 1756 // DUuid is the UUID Datum. 1757 type DUuid struct { 1758 uuid.UUID 1759 } 1760 1761 // NewDUuid is a helper routine to create a *DUuid initialized from its 1762 // argument. 1763 func NewDUuid(d DUuid) *DUuid { 1764 return &d 1765 } 1766 1767 // AsDUuid attempts to retrieve a DUuid from an Expr, returning a DUuid and 1768 // a flag signifying whether the assertion was successful. 1769 func AsDUuid(e Expr) (DUuid, bool) { 1770 switch t := e.(type) { 1771 case *DUuid: 1772 return *t, true 1773 } 1774 return DUuid{}, false 1775 } 1776 1777 // MustBeDUuid attempts to retrieve a DUuid from an Expr, panicking if the 1778 // assertion fails. 1779 func MustBeDUuid(e Expr) DUuid { 1780 i, ok := AsDUuid(e) 1781 if !ok { 1782 panic(errors.AssertionFailedf("expected *DUuid, found %T", e)) 1783 } 1784 return i 1785 } 1786 1787 // ResolvedType implements the TypedExpr interface. 1788 func (*DUuid) ResolvedType() *types.T { 1789 return types.Uuid 1790 } 1791 1792 // Compare implements the Datum interface. 1793 func (d *DUuid) Compare(ctx CompareContext, other Datum) int { 1794 res, err := d.CompareError(ctx, other) 1795 if err != nil { 1796 panic(err) 1797 } 1798 return res 1799 } 1800 1801 // CompareError implements the Datum interface. 1802 func (d *DUuid) CompareError(ctx CompareContext, other Datum) (int, error) { 1803 if other == DNull { 1804 // NULL is less than any non-NULL value. 1805 return 1, nil 1806 } 1807 v, ok := ctx.UnwrapDatum(other).(*DUuid) 1808 if !ok { 1809 return 0, makeUnsupportedComparisonMessage(d, other) 1810 } 1811 res := bytes.Compare(d.GetBytes(), v.GetBytes()) 1812 return res, nil 1813 } 1814 1815 func (d *DUuid) equal(other *DUuid) bool { 1816 return bytes.Equal(d.GetBytes(), other.GetBytes()) 1817 } 1818 1819 // Prev implements the Datum interface. 1820 func (d *DUuid) Prev(ctx CompareContext) (Datum, bool) { 1821 i := d.ToUint128() 1822 u := uuid.FromUint128(i.Sub(1)) 1823 return NewDUuid(DUuid{u}), true 1824 } 1825 1826 // Next implements the Datum interface. 1827 func (d *DUuid) Next(ctx CompareContext) (Datum, bool) { 1828 i := d.ToUint128() 1829 u := uuid.FromUint128(i.Add(1)) 1830 return NewDUuid(DUuid{u}), true 1831 } 1832 1833 // IsMax implements the Datum interface. 1834 func (d *DUuid) IsMax(ctx CompareContext) bool { 1835 return d.equal(DMaxUUID) 1836 } 1837 1838 // IsMin implements the Datum interface. 1839 func (d *DUuid) IsMin(ctx CompareContext) bool { 1840 return d.equal(DMinUUID) 1841 } 1842 1843 // DMinUUID is the min UUID. 1844 var DMinUUID = NewDUuid(DUuid{uuid.UUID{}}) 1845 1846 // DMaxUUID is the max UUID. 1847 var DMaxUUID = NewDUuid(DUuid{uuid.UUID{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1848 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}) 1849 1850 // Min implements the Datum interface. 1851 func (*DUuid) Min(ctx CompareContext) (Datum, bool) { 1852 return DMinUUID, true 1853 } 1854 1855 // Max implements the Datum interface. 1856 func (*DUuid) Max(ctx CompareContext) (Datum, bool) { 1857 return DMaxUUID, true 1858 } 1859 1860 // AmbiguousFormat implements the Datum interface. 1861 func (*DUuid) AmbiguousFormat() bool { return true } 1862 1863 // Format implements the NodeFormatter interface. 1864 func (d *DUuid) Format(ctx *FmtCtx) { 1865 f := ctx.flags 1866 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 1867 if !bareStrings { 1868 ctx.WriteByte('\'') 1869 } 1870 1871 buf := ctx.scratch[:uuid.RFC4122StrSize] 1872 d.UUID.StringBytes(buf) 1873 ctx.Write(buf) 1874 1875 if !bareStrings { 1876 ctx.WriteByte('\'') 1877 } 1878 } 1879 1880 // Size implements the Datum interface. 1881 func (d *DUuid) Size() uintptr { 1882 return unsafe.Sizeof(*d) 1883 } 1884 1885 // DIPAddr is the IPAddr Datum. 1886 type DIPAddr struct { 1887 ipaddr.IPAddr 1888 } 1889 1890 // NewDIPAddr is a helper routine to create a *DIPAddr initialized from its 1891 // argument. 1892 func NewDIPAddr(d DIPAddr) *DIPAddr { 1893 return &d 1894 } 1895 1896 // AsDIPAddr attempts to retrieve a *DIPAddr from an Expr, returning a *DIPAddr and 1897 // a flag signifying whether the assertion was successful. The function should 1898 // be used instead of direct type assertions wherever a *DIPAddr wrapped by a 1899 // *DOidWrapper is possible. 1900 func AsDIPAddr(e Expr) (DIPAddr, bool) { 1901 switch t := e.(type) { 1902 case *DIPAddr: 1903 return *t, true 1904 case *DOidWrapper: 1905 return AsDIPAddr(t.Wrapped) 1906 } 1907 return DIPAddr{}, false 1908 } 1909 1910 // MustBeDIPAddr attempts to retrieve a DIPAddr from an Expr, panicking if the 1911 // assertion fails. 1912 func MustBeDIPAddr(e Expr) DIPAddr { 1913 i, ok := AsDIPAddr(e) 1914 if !ok { 1915 panic(errors.AssertionFailedf("expected *DIPAddr, found %T", e)) 1916 } 1917 return i 1918 } 1919 1920 // ResolvedType implements the TypedExpr interface. 1921 func (*DIPAddr) ResolvedType() *types.T { 1922 return types.INet 1923 } 1924 1925 // Compare implements the Datum interface. 1926 func (d *DIPAddr) Compare(ctx CompareContext, other Datum) int { 1927 res, err := d.CompareError(ctx, other) 1928 if err != nil { 1929 panic(err) 1930 } 1931 return res 1932 } 1933 1934 // CompareError implements the Datum interface. 1935 func (d *DIPAddr) CompareError(ctx CompareContext, other Datum) (int, error) { 1936 if other == DNull { 1937 // NULL is less than any non-NULL value. 1938 return 1, nil 1939 } 1940 v, ok := ctx.UnwrapDatum(other).(*DIPAddr) 1941 if !ok { 1942 return 0, makeUnsupportedComparisonMessage(d, other) 1943 } 1944 1945 res := d.IPAddr.Compare(&v.IPAddr) 1946 return res, nil 1947 } 1948 1949 func (d DIPAddr) equal(other *DIPAddr) bool { 1950 return d.IPAddr.Equal(&other.IPAddr) 1951 } 1952 1953 // Prev implements the Datum interface. 1954 func (d *DIPAddr) Prev(ctx CompareContext) (Datum, bool) { 1955 // We will do one of the following to get the Prev IPAddr: 1956 // - Decrement IP address if we won't underflow the IP. 1957 // - Decrement mask and set the IP to max in family if we will underflow. 1958 // - Jump down from IPv6 to IPv4 if we will underflow both IP and mask. 1959 if d.Family == ipaddr.IPv6family && d.Addr.Equal(dIPv6min) { 1960 if d.Mask == 0 { 1961 // Jump down IP family. 1962 return dMaxIPv4Addr, true 1963 } 1964 // Decrease mask size, wrap IPv6 IP address. 1965 return NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: ipaddr.IPv6family, Addr: dIPv6max, Mask: d.Mask - 1}}), true 1966 } else if d.Family == ipaddr.IPv4family && d.Addr.Equal(dIPv4min) { 1967 // Decrease mask size, wrap IPv4 IP address. 1968 return NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: ipaddr.IPv4family, Addr: dIPv4max, Mask: d.Mask - 1}}), true 1969 } 1970 // Decrement IP address. 1971 return NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: d.Family, Addr: d.Addr.Sub(1), Mask: d.Mask}}), true 1972 } 1973 1974 // Next implements the Datum interface. 1975 func (d *DIPAddr) Next(ctx CompareContext) (Datum, bool) { 1976 // We will do one of a few things to get the Next IP address: 1977 // - Increment IP address if we won't overflow the IP. 1978 // - Increment mask and set the IP to min in family if we will overflow. 1979 // - Jump up from IPv4 to IPv6 if we will overflow both IP and mask. 1980 if d.Family == ipaddr.IPv4family && d.Addr.Equal(dIPv4max) { 1981 if d.Mask == 32 { 1982 // Jump up IP family. 1983 return dMinIPv6Addr, true 1984 } 1985 // Increase mask size, wrap IPv4 IP address. 1986 return NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: ipaddr.IPv4family, Addr: dIPv4min, Mask: d.Mask + 1}}), true 1987 } else if d.Family == ipaddr.IPv6family && d.Addr.Equal(dIPv6max) { 1988 // Increase mask size, wrap IPv6 IP address. 1989 return NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: ipaddr.IPv6family, Addr: dIPv6min, Mask: d.Mask + 1}}), true 1990 } 1991 // Increment IP address. 1992 return NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: d.Family, Addr: d.Addr.Add(1), Mask: d.Mask}}), true 1993 } 1994 1995 // IsMax implements the Datum interface. 1996 func (d *DIPAddr) IsMax(ctx CompareContext) bool { 1997 return d.equal(DMaxIPAddr) 1998 } 1999 2000 // IsMin implements the Datum interface. 2001 func (d *DIPAddr) IsMin(ctx CompareContext) bool { 2002 return d.equal(DMinIPAddr) 2003 } 2004 2005 // dIPv4 and dIPv6 min and maxes use ParseIP because the actual byte constant is 2006 // no equal to solely zeros or ones. For IPv4 there is a 0xffff prefix. Without 2007 // this prefix this makes IP arithmetic invalid. 2008 var dIPv4min = ipaddr.Addr(uint128.FromBytes([]byte(ipaddr.ParseIP("0.0.0.0")))) 2009 var dIPv4max = ipaddr.Addr(uint128.FromBytes([]byte(ipaddr.ParseIP("255.255.255.255")))) 2010 var dIPv6min = ipaddr.Addr(uint128.FromBytes([]byte(ipaddr.ParseIP("::")))) 2011 var dIPv6max = ipaddr.Addr(uint128.FromBytes([]byte(ipaddr.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")))) 2012 2013 // dMaxIPv4Addr and dMinIPv6Addr are used as global constants to prevent extra 2014 // heap extra allocation 2015 var dMaxIPv4Addr = NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: ipaddr.IPv4family, Addr: dIPv4max, Mask: 32}}) 2016 var dMinIPv6Addr = NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: ipaddr.IPv6family, Addr: dIPv6min, Mask: 0}}) 2017 2018 // DMinIPAddr is the min DIPAddr. 2019 var DMinIPAddr = NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: ipaddr.IPv4family, Addr: dIPv4min, Mask: 0}}) 2020 2021 // DMaxIPAddr is the max DIPaddr. 2022 var DMaxIPAddr = NewDIPAddr(DIPAddr{ipaddr.IPAddr{Family: ipaddr.IPv6family, Addr: dIPv6max, Mask: 128}}) 2023 2024 // Min implements the Datum interface. 2025 func (*DIPAddr) Min(ctx CompareContext) (Datum, bool) { 2026 return DMinIPAddr, true 2027 } 2028 2029 // Max implements the Datum interface. 2030 func (*DIPAddr) Max(ctx CompareContext) (Datum, bool) { 2031 return DMaxIPAddr, true 2032 } 2033 2034 // AmbiguousFormat implements the Datum interface. 2035 func (*DIPAddr) AmbiguousFormat() bool { 2036 return true 2037 } 2038 2039 // Format implements the NodeFormatter interface. 2040 func (d *DIPAddr) Format(ctx *FmtCtx) { 2041 f := ctx.flags 2042 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 2043 if !bareStrings { 2044 ctx.WriteByte('\'') 2045 } 2046 ctx.WriteString(d.IPAddr.String()) 2047 if !bareStrings { 2048 ctx.WriteByte('\'') 2049 } 2050 } 2051 2052 // Size implements the Datum interface. 2053 func (d *DIPAddr) Size() uintptr { 2054 return unsafe.Sizeof(*d) 2055 } 2056 2057 // DDate is the date Datum represented as the number of days after 2058 // the Unix epoch. 2059 type DDate struct { 2060 pgdate.Date 2061 } 2062 2063 // NewDDate is a helper routine to create a *DDate initialized from its 2064 // argument. 2065 func NewDDate(d pgdate.Date) *DDate { 2066 return &DDate{Date: d} 2067 } 2068 2069 // MakeDDate makes a DDate from a pgdate.Date. 2070 func MakeDDate(d pgdate.Date) DDate { 2071 return DDate{Date: d} 2072 } 2073 2074 // NewDDateFromTime constructs a *DDate from a time.Time. 2075 func NewDDateFromTime(t time.Time) (*DDate, error) { 2076 d, err := pgdate.MakeDateFromTime(t) 2077 return NewDDate(d), err 2078 } 2079 2080 // ParseContext provides the information necessary for 2081 // parsing dates. 2082 // A nil value is generally acceptable and will result in 2083 // reasonable defaults being applied. 2084 type ParseContext interface { 2085 // GetRelativeParseTime returns the transaction time in the session's 2086 // timezone (i.e. now()). This is used to calculate relative dates, 2087 // like "tomorrow", and also provides a default time.Location for 2088 // parsed times. 2089 GetRelativeParseTime() time.Time 2090 // GetCollationEnv returns the collation environment. 2091 GetCollationEnv() *CollationEnvironment 2092 // GetIntervalStyle returns the interval style in the session. 2093 GetIntervalStyle() duration.IntervalStyle 2094 // GetDateStyle returns the date style in the session. 2095 GetDateStyle() pgdate.DateStyle 2096 // GetParseHelper returns a helper to optmize date parsing. 2097 GetDateHelper() *pgdate.ParseHelper 2098 } 2099 2100 var _ ParseContext = &simpleParseContext{} 2101 2102 // NewParseContextOption is an option to NewParseContext. 2103 type NewParseContextOption func(ret *simpleParseContext) 2104 2105 // NewParseContextOptionDateStyle sets the DateStyle for the context. 2106 func NewParseContextOptionDateStyle(dateStyle pgdate.DateStyle) NewParseContextOption { 2107 return func(ret *simpleParseContext) { 2108 ret.DateStyle = dateStyle 2109 } 2110 } 2111 2112 // NewParseContext constructs a ParseContext that returns 2113 // the given values. 2114 func NewParseContext(relativeParseTime time.Time, opts ...NewParseContextOption) ParseContext { 2115 ret := &simpleParseContext{ 2116 RelativeParseTime: relativeParseTime, 2117 } 2118 for _, opt := range opts { 2119 opt(ret) 2120 } 2121 return ret 2122 } 2123 2124 type simpleParseContext struct { 2125 RelativeParseTime time.Time 2126 CollationEnvironment CollationEnvironment 2127 DateStyle pgdate.DateStyle 2128 IntervalStyle duration.IntervalStyle 2129 dateHelper pgdate.ParseHelper 2130 } 2131 2132 // GetRelativeParseTime implements ParseContext. 2133 func (ctx *simpleParseContext) GetRelativeParseTime() time.Time { 2134 return ctx.RelativeParseTime 2135 } 2136 2137 // GetCollationEnv implements ParseContext. 2138 func (ctx *simpleParseContext) GetCollationEnv() *CollationEnvironment { 2139 return &ctx.CollationEnvironment 2140 } 2141 2142 // GetIntervalStyle implements ParseContext. 2143 func (ctx *simpleParseContext) GetIntervalStyle() duration.IntervalStyle { 2144 return ctx.IntervalStyle 2145 } 2146 2147 // GetDateStyle implements ParseContext. 2148 func (ctx *simpleParseContext) GetDateStyle() pgdate.DateStyle { 2149 return ctx.DateStyle 2150 } 2151 2152 // GetDateHelper implements ParseTimeContext. 2153 func (ctx *simpleParseContext) GetDateHelper() *pgdate.ParseHelper { 2154 return &ctx.dateHelper 2155 } 2156 2157 // relativeParseTime chooses a reasonable "now" value for 2158 // performing date parsing. 2159 func relativeParseTime(ctx ParseContext) time.Time { 2160 if ctx == nil { 2161 return timeutil.Now() 2162 } 2163 return ctx.GetRelativeParseTime() 2164 } 2165 2166 func dateStyle(ctx ParseContext) pgdate.DateStyle { 2167 if ctx == nil { 2168 return pgdate.DefaultDateStyle() 2169 } 2170 return ctx.GetDateStyle() 2171 } 2172 2173 func intervalStyle(ctx ParseContext) duration.IntervalStyle { 2174 if ctx == nil { 2175 return duration.IntervalStyle_POSTGRES 2176 } 2177 return ctx.GetIntervalStyle() 2178 } 2179 2180 func dateParseHelper(ctx ParseContext) *pgdate.ParseHelper { 2181 if ctx == nil { 2182 return nil 2183 } 2184 return ctx.GetDateHelper() 2185 } 2186 2187 // ParseDDate parses and returns the *DDate Datum value represented by the provided 2188 // string in the provided location, or an error if parsing is unsuccessful. 2189 // 2190 // The dependsOnContext return value indicates if we had to consult the 2191 // ParseContext (either for the time or the local timezone). 2192 func ParseDDate(ctx ParseContext, s string) (_ *DDate, dependsOnContext bool, _ error) { 2193 now := relativeParseTime(ctx) 2194 t, dependsOnContext, err := pgdate.ParseDate(now, dateStyle(ctx), s, dateParseHelper(ctx)) 2195 return NewDDate(t), dependsOnContext, err 2196 } 2197 2198 // AsDDate attempts to retrieve a DDate from an Expr, returning a DDate and 2199 // a flag signifying whether the assertion was successful. The function should 2200 // be used instead of direct type assertions wherever a *DDate wrapped by a 2201 // *DOidWrapper is possible. 2202 func AsDDate(e Expr) (DDate, bool) { 2203 switch t := e.(type) { 2204 case *DDate: 2205 return *t, true 2206 case *DOidWrapper: 2207 return AsDDate(t.Wrapped) 2208 } 2209 return DDate{}, false 2210 } 2211 2212 // MustBeDDate attempts to retrieve a DDate from an Expr, panicking if the 2213 // assertion fails. 2214 func MustBeDDate(e Expr) DDate { 2215 t, ok := AsDDate(e) 2216 if !ok { 2217 panic(errors.AssertionFailedf("expected *DDate, found %T", e)) 2218 } 2219 return t 2220 } 2221 2222 // ResolvedType implements the TypedExpr interface. 2223 func (*DDate) ResolvedType() *types.T { 2224 return types.Date 2225 } 2226 2227 // Compare implements the Datum interface. 2228 func (d *DDate) Compare(ctx CompareContext, other Datum) int { 2229 res, err := d.CompareError(ctx, other) 2230 if err != nil { 2231 panic(err) 2232 } 2233 return res 2234 } 2235 2236 // CompareError implements the Datum interface. 2237 func (d *DDate) CompareError(ctx CompareContext, other Datum) (int, error) { 2238 if other == DNull { 2239 // NULL is less than any non-NULL value. 2240 return 1, nil 2241 } 2242 var v DDate 2243 switch t := ctx.UnwrapDatum(other).(type) { 2244 case *DDate: 2245 v = *t 2246 case *DTimestamp, *DTimestampTZ: 2247 return compareTimestamps(ctx, d, other) 2248 default: 2249 return 0, makeUnsupportedComparisonMessage(d, other) 2250 } 2251 res := d.Date.Compare(v.Date) 2252 return res, nil 2253 } 2254 2255 var ( 2256 epochDate, _ = pgdate.MakeDateFromPGEpoch(0) 2257 dEpochDate = NewDDate(epochDate) 2258 dMaxDate = NewDDate(pgdate.PosInfDate) 2259 dMinDate = NewDDate(pgdate.NegInfDate) 2260 dLowDate = NewDDate(pgdate.LowDate) 2261 dHighDate = NewDDate(pgdate.HighDate) 2262 ) 2263 2264 // Prev implements the Datum interface. 2265 func (d *DDate) Prev(ctx CompareContext) (Datum, bool) { 2266 switch d.Date { 2267 case pgdate.PosInfDate: 2268 return dHighDate, true 2269 case pgdate.LowDate: 2270 return dMinDate, true 2271 case pgdate.NegInfDate: 2272 return nil, false 2273 } 2274 n, err := d.AddDays(-1) 2275 if err != nil { 2276 return nil, false 2277 } 2278 return NewDDate(n), true 2279 } 2280 2281 // Next implements the Datum interface. 2282 func (d *DDate) Next(ctx CompareContext) (Datum, bool) { 2283 switch d.Date { 2284 case pgdate.NegInfDate: 2285 return dLowDate, true 2286 case pgdate.HighDate: 2287 return dMaxDate, true 2288 case pgdate.PosInfDate: 2289 return nil, false 2290 } 2291 n, err := d.AddDays(1) 2292 if err != nil { 2293 return nil, false 2294 } 2295 return NewDDate(n), true 2296 } 2297 2298 // IsMax implements the Datum interface. 2299 func (d *DDate) IsMax(ctx CompareContext) bool { 2300 return d.PGEpochDays() == pgdate.PosInfDate.PGEpochDays() 2301 } 2302 2303 // IsMin implements the Datum interface. 2304 func (d *DDate) IsMin(ctx CompareContext) bool { 2305 return d.PGEpochDays() == pgdate.NegInfDate.PGEpochDays() 2306 } 2307 2308 // Max implements the Datum interface. 2309 func (d *DDate) Max(ctx CompareContext) (Datum, bool) { 2310 return dMaxDate, true 2311 } 2312 2313 // Min implements the Datum interface. 2314 func (d *DDate) Min(ctx CompareContext) (Datum, bool) { 2315 return dMinDate, true 2316 } 2317 2318 // AmbiguousFormat implements the Datum interface. 2319 func (*DDate) AmbiguousFormat() bool { return true } 2320 2321 // FormatDate writes d into ctx according to the format flags. 2322 func FormatDate(d pgdate.Date, ctx *FmtCtx) { 2323 f := ctx.flags 2324 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 2325 if !bareStrings { 2326 ctx.WriteByte('\'') 2327 } 2328 d.Format(&ctx.Buffer) 2329 if !bareStrings { 2330 ctx.WriteByte('\'') 2331 } 2332 } 2333 2334 // Format implements the NodeFormatter interface. 2335 func (d *DDate) Format(ctx *FmtCtx) { 2336 FormatDate(d.Date, ctx) 2337 } 2338 2339 // Size implements the Datum interface. 2340 func (d *DDate) Size() uintptr { 2341 return unsafe.Sizeof(*d) 2342 } 2343 2344 // DTime is the time Datum. 2345 type DTime timeofday.TimeOfDay 2346 2347 // MakeDTime creates a DTime from a TimeOfDay. 2348 func MakeDTime(t timeofday.TimeOfDay) *DTime { 2349 d := DTime(t) 2350 return &d 2351 } 2352 2353 // AsDTime attempts to retrieve a DTime from an Expr, returning a DTimestamp and 2354 // a flag signifying whether the assertion was successful. The function should 2355 // be used instead of direct type assertions wherever a *DTime wrapped by a 2356 // *DOidWrapper is possible. 2357 func AsDTime(e Expr) (DTime, bool) { 2358 switch t := e.(type) { 2359 case *DTime: 2360 return *t, true 2361 case *DOidWrapper: 2362 return AsDTime(t.Wrapped) 2363 } 2364 return DTime(timeofday.FromInt(0)), false 2365 } 2366 2367 // ParseDTime parses and returns the *DTime Datum value represented by the 2368 // provided string, or an error if parsing is unsuccessful. 2369 // 2370 // The dependsOnContext return value indicates if we had to consult the 2371 // ParseContext (either for the time or the local timezone). 2372 func ParseDTime( 2373 ctx ParseContext, s string, precision time.Duration, 2374 ) (_ *DTime, dependsOnContext bool, _ error) { 2375 now := relativeParseTime(ctx) 2376 2377 // Special case on 24:00 and 24:00:00 as the parser 2378 // does not handle these correctly. 2379 if DTimeMaxTimeRegex.MatchString(s) { 2380 return MakeDTime(timeofday.Time2400), false, nil 2381 } 2382 2383 s = timeutil.ReplaceLibPQTimePrefix(s) 2384 2385 t, dependsOnContext, err := pgdate.ParseTimeWithoutTimezone(now, dateStyle(ctx), s) 2386 if err != nil { 2387 return nil, false, MakeParseError(s, types.Time, err) 2388 } 2389 return MakeDTime(timeofday.FromTime(t).Round(precision)), dependsOnContext, nil 2390 } 2391 2392 // ResolvedType implements the TypedExpr interface. 2393 func (*DTime) ResolvedType() *types.T { 2394 return types.Time 2395 } 2396 2397 // Compare implements the Datum interface. 2398 func (d *DTime) Compare(ctx CompareContext, other Datum) int { 2399 res, err := d.CompareError(ctx, other) 2400 if err != nil { 2401 panic(err) 2402 } 2403 return res 2404 } 2405 2406 // CompareError implements the Datum interface. 2407 func (d *DTime) CompareError(ctx CompareContext, other Datum) (int, error) { 2408 if other == DNull { 2409 // NULL is less than any non-NULL value. 2410 return 1, nil 2411 } 2412 return compareTimestamps(ctx, d, other) 2413 } 2414 2415 // Prev implements the Datum interface. 2416 func (d *DTime) Prev(ctx CompareContext) (Datum, bool) { 2417 if d.IsMin(ctx) { 2418 return nil, false 2419 } 2420 prev := *d - 1 2421 return &prev, true 2422 } 2423 2424 // Round returns a new DTime to the specified precision. 2425 func (d *DTime) Round(precision time.Duration) *DTime { 2426 return MakeDTime(timeofday.TimeOfDay(*d).Round(precision)) 2427 } 2428 2429 // Next implements the Datum interface. 2430 func (d *DTime) Next(ctx CompareContext) (Datum, bool) { 2431 if d.IsMax(ctx) { 2432 return nil, false 2433 } 2434 next := *d + 1 2435 return &next, true 2436 } 2437 2438 var dTimeMin = MakeDTime(timeofday.Min) 2439 var dTimeMax = MakeDTime(timeofday.Max) 2440 2441 // IsMax implements the Datum interface. 2442 func (d *DTime) IsMax(ctx CompareContext) bool { 2443 return *d == *dTimeMax 2444 } 2445 2446 // IsMin implements the Datum interface. 2447 func (d *DTime) IsMin(ctx CompareContext) bool { 2448 return *d == *dTimeMin 2449 } 2450 2451 // Max implements the Datum interface. 2452 func (d *DTime) Max(ctx CompareContext) (Datum, bool) { 2453 return dTimeMax, true 2454 } 2455 2456 // Min implements the Datum interface. 2457 func (d *DTime) Min(ctx CompareContext) (Datum, bool) { 2458 return dTimeMin, true 2459 } 2460 2461 // AmbiguousFormat implements the Datum interface. 2462 func (*DTime) AmbiguousFormat() bool { return true } 2463 2464 // Format implements the NodeFormatter interface. 2465 func (d *DTime) Format(ctx *FmtCtx) { 2466 f := ctx.flags 2467 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 2468 if !bareStrings { 2469 ctx.WriteByte('\'') 2470 } 2471 ctx.Write(PGWireFormatTime(timeofday.TimeOfDay(*d), ctx.scratch[:0])) 2472 if !bareStrings { 2473 ctx.WriteByte('\'') 2474 } 2475 } 2476 2477 // Size implements the Datum interface. 2478 func (d *DTime) Size() uintptr { 2479 return unsafe.Sizeof(*d) 2480 } 2481 2482 // DTimeTZ is the time with time zone Datum. 2483 type DTimeTZ struct { 2484 timetz.TimeTZ 2485 } 2486 2487 var ( 2488 dZeroTimeTZ = NewDTimeTZFromOffset(timeofday.Min, 0) 2489 // DMinTimeTZ is the min TimeTZ. 2490 DMinTimeTZ = NewDTimeTZFromOffset(timeofday.Min, timetz.MinTimeTZOffsetSecs) 2491 // DMaxTimeTZ is the max TimeTZ. 2492 DMaxTimeTZ = NewDTimeTZFromOffset(timeofday.Max, timetz.MaxTimeTZOffsetSecs) 2493 ) 2494 2495 // NewDTimeTZ creates a DTimeTZ from a timetz.TimeTZ. 2496 func NewDTimeTZ(t timetz.TimeTZ) *DTimeTZ { 2497 return &DTimeTZ{t} 2498 } 2499 2500 // NewDTimeTZFromTime creates a DTimeTZ from time.Time. 2501 func NewDTimeTZFromTime(t time.Time) *DTimeTZ { 2502 return &DTimeTZ{timetz.MakeTimeTZFromTime(t)} 2503 } 2504 2505 // NewDTimeTZFromOffset creates a DTimeTZ from a TimeOfDay and offset. 2506 func NewDTimeTZFromOffset(t timeofday.TimeOfDay, offsetSecs int32) *DTimeTZ { 2507 return &DTimeTZ{timetz.MakeTimeTZ(t, offsetSecs)} 2508 } 2509 2510 // NewDTimeTZFromLocation creates a DTimeTZ from a TimeOfDay and time.Location. 2511 func NewDTimeTZFromLocation(t timeofday.TimeOfDay, loc *time.Location) *DTimeTZ { 2512 return &DTimeTZ{timetz.MakeTimeTZFromLocation(t, loc)} 2513 } 2514 2515 // AsDTimeTZ attempts to retrieve a DTimeTZ from an Expr, returning a DTimeTZ and 2516 // a flag signifying whether the assertion was successful. The function should 2517 // be used instead of direct type assertions wherever a *DTimeTZ wrapped by a 2518 // *DOidWrapper is possible. 2519 func AsDTimeTZ(e Expr) (DTimeTZ, bool) { 2520 switch t := e.(type) { 2521 case *DTimeTZ: 2522 return *t, true 2523 case *DOidWrapper: 2524 return AsDTimeTZ(t.Wrapped) 2525 } 2526 return DTimeTZ{}, false 2527 } 2528 2529 // ParseDTimeTZ parses and returns the *DTime Datum value represented by the 2530 // provided string, or an error if parsing is unsuccessful. 2531 // 2532 // The dependsOnContext return value indicates if we had to consult the 2533 // ParseContext (either for the time or the local timezone). 2534 func ParseDTimeTZ( 2535 ctx ParseContext, s string, precision time.Duration, 2536 ) (_ *DTimeTZ, dependsOnContext bool, _ error) { 2537 now := relativeParseTime(ctx) 2538 d, dependsOnContext, err := timetz.ParseTimeTZ(now, dateStyle(ctx), s, precision) 2539 if err != nil { 2540 return nil, false, err 2541 } 2542 return NewDTimeTZ(d), dependsOnContext, nil 2543 } 2544 2545 // ResolvedType implements the TypedExpr interface. 2546 func (*DTimeTZ) ResolvedType() *types.T { 2547 return types.TimeTZ 2548 } 2549 2550 // Compare implements the Datum interface. 2551 func (d *DTimeTZ) Compare(ctx CompareContext, other Datum) int { 2552 res, err := d.CompareError(ctx, other) 2553 if err != nil { 2554 panic(err) 2555 } 2556 return res 2557 } 2558 2559 // CompareError implements the Datum interface. 2560 func (d *DTimeTZ) CompareError(ctx CompareContext, other Datum) (int, error) { 2561 if other == DNull { 2562 // NULL is less than any non-NULL value. 2563 return 1, nil 2564 } 2565 return compareTimestamps(ctx, d, other) 2566 } 2567 2568 // Prev implements the Datum interface. 2569 func (d *DTimeTZ) Prev(ctx CompareContext) (Datum, bool) { 2570 if d.IsMin(ctx) { 2571 return nil, false 2572 } 2573 // In the common case, the absolute time doesn't change, we simply decrement 2574 // the offset by one second and increment the time of day by one second. Once 2575 // we hit the minimum offset for the current absolute time, then we decrement 2576 // the absolute time by one microsecond and wrap around to the highest offset 2577 // for the new absolute time. This aligns with how Before and After are 2578 // defined for TimeTZ. 2579 var newTimeOfDay timeofday.TimeOfDay 2580 var newOffsetSecs int32 2581 if d.OffsetSecs == timetz.MinTimeTZOffsetSecs || 2582 d.TimeOfDay+duration.MicrosPerSec > timeofday.Max { 2583 newTimeOfDay = d.TimeOfDay - 1 2584 shiftSeconds := int32((newTimeOfDay - timeofday.Min) / duration.MicrosPerSec) 2585 if d.OffsetSecs+shiftSeconds > timetz.MaxTimeTZOffsetSecs { 2586 shiftSeconds = timetz.MaxTimeTZOffsetSecs - d.OffsetSecs 2587 } 2588 newOffsetSecs = d.OffsetSecs + shiftSeconds 2589 newTimeOfDay -= timeofday.TimeOfDay(shiftSeconds) * duration.MicrosPerSec 2590 } else { 2591 newTimeOfDay = d.TimeOfDay + duration.MicrosPerSec 2592 newOffsetSecs = d.OffsetSecs - 1 2593 } 2594 return NewDTimeTZFromOffset(newTimeOfDay, newOffsetSecs), true 2595 } 2596 2597 // Next implements the Datum interface. 2598 func (d *DTimeTZ) Next(ctx CompareContext) (Datum, bool) { 2599 if d.IsMax(ctx) { 2600 return nil, false 2601 } 2602 // In the common case, the absolute time doesn't change, we simply increment 2603 // the offset by one second and decrement the time of day by one second. Once 2604 // we hit the maximum offset for the current absolute time, then we increment 2605 // the absolute time by one microsecond and wrap around to the lowest offset 2606 // for the new absolute time. This aligns with how Before and After are 2607 // defined for TimeTZ. 2608 var newTimeOfDay timeofday.TimeOfDay 2609 var newOffsetSecs int32 2610 if d.OffsetSecs == timetz.MaxTimeTZOffsetSecs || 2611 d.TimeOfDay-duration.MicrosPerSec < timeofday.Min { 2612 newTimeOfDay = d.TimeOfDay + 1 2613 shiftSeconds := int32((timeofday.Max - newTimeOfDay) / duration.MicrosPerSec) 2614 if d.OffsetSecs-shiftSeconds < timetz.MinTimeTZOffsetSecs { 2615 shiftSeconds = d.OffsetSecs - timetz.MinTimeTZOffsetSecs 2616 } 2617 newOffsetSecs = d.OffsetSecs - shiftSeconds 2618 newTimeOfDay += timeofday.TimeOfDay(shiftSeconds) * duration.MicrosPerSec 2619 } else { 2620 newTimeOfDay = d.TimeOfDay - duration.MicrosPerSec 2621 newOffsetSecs = d.OffsetSecs + 1 2622 } 2623 return NewDTimeTZFromOffset(newTimeOfDay, newOffsetSecs), true 2624 } 2625 2626 // IsMax implements the Datum interface. 2627 func (d *DTimeTZ) IsMax(ctx CompareContext) bool { 2628 return d.TimeOfDay == DMaxTimeTZ.TimeOfDay && d.OffsetSecs == timetz.MaxTimeTZOffsetSecs 2629 } 2630 2631 // IsMin implements the Datum interface. 2632 func (d *DTimeTZ) IsMin(ctx CompareContext) bool { 2633 return d.TimeOfDay == DMinTimeTZ.TimeOfDay && d.OffsetSecs == timetz.MinTimeTZOffsetSecs 2634 } 2635 2636 // Max implements the Datum interface. 2637 func (d *DTimeTZ) Max(ctx CompareContext) (Datum, bool) { 2638 return DMaxTimeTZ, true 2639 } 2640 2641 // Round returns a new DTimeTZ to the specified precision. 2642 func (d *DTimeTZ) Round(precision time.Duration) *DTimeTZ { 2643 return NewDTimeTZ(d.TimeTZ.Round(precision)) 2644 } 2645 2646 // Min implements the Datum interface. 2647 func (d *DTimeTZ) Min(ctx CompareContext) (Datum, bool) { 2648 return DMinTimeTZ, true 2649 } 2650 2651 // AmbiguousFormat implements the Datum interface. 2652 func (*DTimeTZ) AmbiguousFormat() bool { return true } 2653 2654 // Format implements the NodeFormatter interface. 2655 func (d *DTimeTZ) Format(ctx *FmtCtx) { 2656 f := ctx.flags 2657 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 2658 if !bareStrings { 2659 ctx.WriteByte('\'') 2660 } 2661 ctx.Write(PGWireFormatTimeTZ(d.TimeTZ, ctx.scratch[:0])) 2662 if !bareStrings { 2663 ctx.WriteByte('\'') 2664 } 2665 } 2666 2667 // Size implements the Datum interface. 2668 func (d *DTimeTZ) Size() uintptr { 2669 return unsafe.Sizeof(*d) 2670 } 2671 2672 // NewTimestampExceedsBoundsError returns a new "exceeds supported timestamp 2673 // bounds" error for the given timestamp, with the correct pgcode. 2674 func NewTimestampExceedsBoundsError(t time.Time) error { 2675 return pgerror.Newf( 2676 pgcode.InvalidTimeZoneDisplacementValue, 2677 "timestamp %q exceeds supported timestamp bounds", 2678 t.Format(time.RFC3339), 2679 ) 2680 } 2681 2682 // DTimestamp is the timestamp Datum. 2683 type DTimestamp struct { 2684 // DTimestamp represents a timezoneless date and time value. It is stored in 2685 // the time.Time as if it had UTC location, regardless of what timezone it 2686 // actually represents (which is unknown within the database). See comment 2687 // above ParseTimestampWithoutTimezone for some examples. 2688 time.Time 2689 } 2690 2691 // MakeDTimestamp creates a DTimestamp with specified precision. 2692 func MakeDTimestamp(t time.Time, precision time.Duration) (*DTimestamp, error) { 2693 ret := t.Round(precision) 2694 if ret.After(MaxSupportedTime) || ret.Before(MinSupportedTime) { 2695 return nil, NewTimestampExceedsBoundsError(ret) 2696 } 2697 return &DTimestamp{Time: ret}, nil 2698 } 2699 2700 // MustMakeDTimestamp wraps MakeDTimestamp but panics if there is an error. 2701 // This is intended for testing applications only. 2702 func MustMakeDTimestamp(t time.Time, precision time.Duration) *DTimestamp { 2703 ret, err := MakeDTimestamp(t, precision) 2704 if err != nil { 2705 panic(err) 2706 } 2707 return ret 2708 } 2709 2710 // DZeroTimestamp is the zero-valued DTimestamp. 2711 var DZeroTimestamp = &DTimestamp{} 2712 2713 // ParseDTimestamp parses and returns the *DTimestamp Datum value represented by 2714 // the provided string in UTC, or an error if parsing is unsuccessful. 2715 // 2716 // The dependsOnContext return value indicates if we had to consult the 2717 // ParseContext (either for the time or the local timezone). 2718 // 2719 // Parts of this function are inlined into ParseAndRequireStringHandler, if this 2720 // changes materially the timestamp case arms there may need to change too. 2721 func ParseDTimestamp( 2722 ctx ParseContext, s string, precision time.Duration, 2723 ) (_ *DTimestamp, dependsOnContext bool, _ error) { 2724 now := relativeParseTime(ctx) 2725 t, dependsOnContext, err := pgdate.ParseTimestampWithoutTimezone(now, dateStyle(ctx), s) 2726 if err != nil { 2727 return nil, false, err 2728 } 2729 d, err := MakeDTimestamp(t, precision) 2730 return d, dependsOnContext, err 2731 } 2732 2733 // AsDTimestamp attempts to retrieve a DTimestamp from an Expr, returning a DTimestamp and 2734 // a flag signifying whether the assertion was successful. The function should 2735 // be used instead of direct type assertions wherever a *DTimestamp wrapped by a 2736 // *DOidWrapper is possible. 2737 func AsDTimestamp(e Expr) (DTimestamp, bool) { 2738 switch t := e.(type) { 2739 case *DTimestamp: 2740 return *t, true 2741 case *DOidWrapper: 2742 return AsDTimestamp(t.Wrapped) 2743 } 2744 return DTimestamp{}, false 2745 } 2746 2747 // MustBeDTimestamp attempts to retrieve a DTimestamp from an Expr, panicking if the 2748 // assertion fails. 2749 func MustBeDTimestamp(e Expr) DTimestamp { 2750 t, ok := AsDTimestamp(e) 2751 if !ok { 2752 panic(errors.AssertionFailedf("expected *DTimestamp, found %T", e)) 2753 } 2754 return t 2755 } 2756 2757 // Round returns a new DTimestamp to the specified precision. 2758 func (d *DTimestamp) Round(precision time.Duration) (*DTimestamp, error) { 2759 return MakeDTimestamp(d.Time, precision) 2760 } 2761 2762 // ResolvedType implements the TypedExpr interface. 2763 func (*DTimestamp) ResolvedType() *types.T { 2764 return types.Timestamp 2765 } 2766 2767 // TimeFromDatumForComparison gets the time from a datum object to use 2768 // strictly for comparison usage. 2769 func TimeFromDatumForComparison(ctx CompareContext, d Datum) (time.Time, error) { 2770 d = ctx.UnwrapDatum(d) 2771 switch t := d.(type) { 2772 case *DDate: 2773 ts, err := MakeDTimestampTZFromDate(ctx.GetLocation(), t) 2774 if err != nil { 2775 return time.Time{}, err 2776 } 2777 return ts.Time, nil 2778 case *DTimestampTZ: 2779 return t.Time, nil 2780 case *DTimestamp: 2781 // Normalize to the timezone of the context. 2782 _, zoneOffset := t.Time.In(ctx.GetLocation()).Zone() 2783 ts := t.Time.In(ctx.GetLocation()).Add(-time.Duration(zoneOffset) * time.Second) 2784 return ts, nil 2785 case *DTime: 2786 // Normalize to the timezone of the context. 2787 toTime := timeofday.TimeOfDay(*t).ToTime() 2788 _, zoneOffsetSecs := toTime.In(ctx.GetLocation()).Zone() 2789 return toTime.In(ctx.GetLocation()).Add(-time.Duration(zoneOffsetSecs) * time.Second), nil 2790 case *DTimeTZ: 2791 return t.ToTime(), nil 2792 default: 2793 return time.Time{}, errors.AssertionFailedf("unexpected type: %s", t.ResolvedType().SQLStringForError()) 2794 } 2795 } 2796 2797 type infiniteDateComparison int 2798 2799 const ( 2800 // Note: the order of the constants here is important. 2801 negativeInfinity infiniteDateComparison = iota 2802 finite 2803 positiveInfinity 2804 ) 2805 2806 func checkInfiniteDate(ctx CompareContext, d Datum) infiniteDateComparison { 2807 if _, isDate := d.(*DDate); isDate { 2808 if d.IsMax(ctx) { 2809 return positiveInfinity 2810 } 2811 if d.IsMin(ctx) { 2812 return negativeInfinity 2813 } 2814 } 2815 return finite 2816 } 2817 2818 // compareTimestamps takes in two time-related datums and compares them as 2819 // timestamps while paying attention to time zones if needed. It returns -1, 0, 2820 // or +1 for "less", "equal", and "greater", respectively. 2821 // 2822 // Datums are allowed to be one of DDate, DTimestamp, DTimestampTZ, DTime, 2823 // DTimeTZ. For all other datum types it will panic; also, comparing two DDates 2824 // is not supported. 2825 func compareTimestamps(ctx CompareContext, l Datum, r Datum) (int, error) { 2826 leftInf := checkInfiniteDate(ctx, l) 2827 rightInf := checkInfiniteDate(ctx, r) 2828 if leftInf != finite || rightInf != finite { 2829 // At least one of the datums is an infinite date. 2830 if leftInf != finite && rightInf != finite { 2831 // Both datums cannot be infinite dates at the same time because we 2832 // wouldn't use this method. 2833 return 0, errors.AssertionFailedf("unexpectedly two infinite dates in compareTimestamps") 2834 } 2835 // Exactly one of the datums is an infinite date and another is a finite 2836 // datums (not necessarily a date). We can just subtract the returned 2837 // values to get the desired result for comparison. 2838 return int(leftInf - rightInf), nil 2839 } 2840 lTime, lErr := TimeFromDatumForComparison(ctx, l) 2841 rTime, rErr := TimeFromDatumForComparison(ctx, r) 2842 if lErr != nil || rErr != nil { 2843 return 0, makeUnsupportedComparisonMessage(l, r) 2844 } 2845 if lTime.Before(rTime) { 2846 return -1, nil 2847 } 2848 if rTime.Before(lTime) { 2849 return 1, nil 2850 } 2851 2852 // If either side is a TimeTZ, then we must compare timezones before 2853 // when comparing. If comparing a non-TimeTZ value, and the times are 2854 // equal, then we must compare relative to the current zone we are at. 2855 // 2856 // This is a special quirk of TimeTZ and does not apply to TimestampTZ, 2857 // as TimestampTZ does not store a timezone offset and is based on 2858 // the current zone. 2859 _, leftIsTimeTZ := l.(*DTimeTZ) 2860 _, rightIsTimeTZ := r.(*DTimeTZ) 2861 2862 // If neither side is TimeTZ, this is always equal at this point. 2863 if !leftIsTimeTZ && !rightIsTimeTZ { 2864 return 0, nil 2865 } 2866 2867 _, zoneOffset := ctx.GetRelativeParseTime().Zone() 2868 lOffset := int32(-zoneOffset) 2869 rOffset := int32(-zoneOffset) 2870 2871 if leftIsTimeTZ { 2872 lOffset = l.(*DTimeTZ).OffsetSecs 2873 } 2874 if rightIsTimeTZ { 2875 rOffset = r.(*DTimeTZ).OffsetSecs 2876 } 2877 2878 if lOffset > rOffset { 2879 return 1, nil 2880 } 2881 if lOffset < rOffset { 2882 return -1, nil 2883 } 2884 return 0, nil 2885 } 2886 2887 // Compare implements the Datum interface. 2888 func (d *DTimestamp) Compare(ctx CompareContext, other Datum) int { 2889 res, err := d.CompareError(ctx, other) 2890 if err != nil { 2891 panic(err) 2892 } 2893 return res 2894 } 2895 2896 // CompareError implements the Datum interface. 2897 func (d *DTimestamp) CompareError(ctx CompareContext, other Datum) (int, error) { 2898 if other == DNull { 2899 // NULL is less than any non-NULL value. 2900 return 1, nil 2901 } 2902 return compareTimestamps(ctx, d, other) 2903 } 2904 2905 // Prev implements the Datum interface. 2906 func (d *DTimestamp) Prev(ctx CompareContext) (Datum, bool) { 2907 if d.IsMin(ctx) { 2908 return nil, false 2909 } 2910 return &DTimestamp{Time: d.Add(-time.Microsecond)}, true 2911 } 2912 2913 // Next implements the Datum interface. 2914 func (d *DTimestamp) Next(ctx CompareContext) (Datum, bool) { 2915 if d.IsMax(ctx) { 2916 return nil, false 2917 } 2918 return &DTimestamp{Time: d.Add(time.Microsecond)}, true 2919 } 2920 2921 // IsMax implements the Datum interface. 2922 func (d *DTimestamp) IsMax(ctx CompareContext) bool { 2923 return d.Equal(MaxSupportedTime) 2924 } 2925 2926 // IsMin implements the Datum interface. 2927 func (d *DTimestamp) IsMin(ctx CompareContext) bool { 2928 return d.Equal(MinSupportedTime) 2929 } 2930 2931 // Min implements the Datum interface. 2932 func (d *DTimestamp) Min(ctx CompareContext) (Datum, bool) { 2933 return &DTimestamp{Time: MinSupportedTime}, true 2934 } 2935 2936 // Max implements the Datum interface. 2937 func (d *DTimestamp) Max(ctx CompareContext) (Datum, bool) { 2938 return &DTimestamp{Time: MaxSupportedTime}, true 2939 } 2940 2941 // AmbiguousFormat implements the Datum interface. 2942 func (*DTimestamp) AmbiguousFormat() bool { return true } 2943 2944 // Format implements the NodeFormatter interface. 2945 func (d *DTimestamp) Format(ctx *FmtCtx) { 2946 f := ctx.flags 2947 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 2948 if !bareStrings { 2949 ctx.WriteByte('\'') 2950 } 2951 2952 ctx.Write(PGWireFormatTimestamp(d.Time, nil, ctx.scratch[:0])) 2953 2954 if !bareStrings { 2955 ctx.WriteByte('\'') 2956 } 2957 } 2958 2959 // Size implements the Datum interface. 2960 func (d *DTimestamp) Size() uintptr { 2961 return unsafe.Sizeof(*d) 2962 } 2963 2964 // DTimestampTZ is the timestamp Datum that is rendered with session offset. 2965 type DTimestampTZ struct { 2966 // Just like time.Time, DTimestampTZ represents an instant in global time that 2967 // is stored internally in UTC and converted to local time when rendering. 2968 // 2969 // Functions that render the TimestampTZ typically take the session time zone 2970 // as an argument and ignore the Time's set location, but we do sometimes set 2971 // the Time's location (e.g. when it comes from ParseDTimestampTZ). 2972 time.Time 2973 } 2974 2975 func checkTimeBounds(t time.Time, precision time.Duration) (time.Time, error) { 2976 ret := t.Round(precision) 2977 if ret.After(MaxSupportedTime) || ret.Before(MinSupportedTime) { 2978 return time.Time{}, NewTimestampExceedsBoundsError(ret) 2979 } 2980 return ret, nil 2981 } 2982 2983 // MakeDTimestampTZ creates a DTimestampTZ with specified precision. 2984 func MakeDTimestampTZ(t time.Time, precision time.Duration) (_ *DTimestampTZ, err error) { 2985 if t, err = checkTimeBounds(t, precision); err != nil { 2986 return nil, err 2987 } 2988 return &DTimestampTZ{Time: t}, nil 2989 } 2990 2991 // MustMakeDTimestampTZ wraps MakeDTimestampTZ but panics if there is an error. 2992 // This is intended for testing applications only. 2993 func MustMakeDTimestampTZ(t time.Time, precision time.Duration) *DTimestampTZ { 2994 ret, err := MakeDTimestampTZ(t, precision) 2995 if err != nil { 2996 panic(err) 2997 } 2998 return ret 2999 } 3000 3001 // MakeDTimestampTZFromDate creates a DTimestampTZ from a DDate. 3002 // This will be equivalent to the midnight of the given zone. 3003 func MakeDTimestampTZFromDate(loc *time.Location, d *DDate) (*DTimestampTZ, error) { 3004 t, err := d.ToTime() 3005 if err != nil { 3006 return nil, err 3007 } 3008 // Normalize to the correct zone. 3009 t = t.In(loc) 3010 _, offset := t.Zone() 3011 return MakeDTimestampTZ(t.Add(time.Duration(-offset)*time.Second), time.Microsecond) 3012 } 3013 3014 // ParseDTimestampTZ parses and returns the *DTimestampTZ Datum value represented by 3015 // the provided string in the provided location, or an error if parsing is unsuccessful. 3016 // 3017 // The dependsOnContext return value indicates if we had to consult the 3018 // ParseContext (either for the time or the local timezone). 3019 // 3020 // Parts of this function are inlined into ParseAndRequireStringHandler, if this 3021 // changes materially the timestamp case arms there may need to change too. 3022 func ParseDTimestampTZ( 3023 ctx ParseContext, s string, precision time.Duration, 3024 ) (_ *DTimestampTZ, dependsOnContext bool, _ error) { 3025 now := relativeParseTime(ctx) 3026 t, dependsOnContext, err := pgdate.ParseTimestamp(now, dateStyle(ctx), s) 3027 if err != nil { 3028 return nil, false, err 3029 } 3030 // Always normalize time to the current location. 3031 d, err := MakeDTimestampTZ(t, precision) 3032 return d, dependsOnContext, err 3033 } 3034 3035 // DZeroTimestampTZ is the zero-valued DTimestampTZ. 3036 var DZeroTimestampTZ = &DTimestampTZ{} 3037 3038 // AsDTimestampTZ attempts to retrieve a DTimestampTZ from an Expr, returning a 3039 // DTimestampTZ and a flag signifying whether the assertion was successful. The 3040 // function should be used instead of direct type assertions wherever a 3041 // *DTimestamp wrapped by a *DOidWrapper is possible. 3042 func AsDTimestampTZ(e Expr) (DTimestampTZ, bool) { 3043 switch t := e.(type) { 3044 case *DTimestampTZ: 3045 return *t, true 3046 case *DOidWrapper: 3047 return AsDTimestampTZ(t.Wrapped) 3048 } 3049 return DTimestampTZ{}, false 3050 } 3051 3052 // MustBeDTimestampTZ attempts to retrieve a DTimestampTZ from an Expr, 3053 // panicking if the assertion fails. 3054 func MustBeDTimestampTZ(e Expr) DTimestampTZ { 3055 t, ok := AsDTimestampTZ(e) 3056 if !ok { 3057 panic(errors.AssertionFailedf("expected *DTimestampTZ, found %T", e)) 3058 } 3059 return t 3060 } 3061 3062 // Round returns a new DTimestampTZ to the specified precision. 3063 func (d *DTimestampTZ) Round(precision time.Duration) (*DTimestampTZ, error) { 3064 return MakeDTimestampTZ(d.Time, precision) 3065 } 3066 3067 // ResolvedType implements the TypedExpr interface. 3068 func (*DTimestampTZ) ResolvedType() *types.T { 3069 return types.TimestampTZ 3070 } 3071 3072 // Compare implements the Datum interface. 3073 func (d *DTimestampTZ) Compare(ctx CompareContext, other Datum) int { 3074 res, err := d.CompareError(ctx, other) 3075 if err != nil { 3076 panic(err) 3077 } 3078 return res 3079 } 3080 3081 // CompareError implements the Datum interface. 3082 func (d *DTimestampTZ) CompareError(ctx CompareContext, other Datum) (int, error) { 3083 if other == DNull { 3084 // NULL is less than any non-NULL value. 3085 return 1, nil 3086 } 3087 return compareTimestamps(ctx, d, other) 3088 } 3089 3090 // Prev implements the Datum interface. 3091 func (d *DTimestampTZ) Prev(ctx CompareContext) (Datum, bool) { 3092 if d.IsMin(ctx) { 3093 return nil, false 3094 } 3095 return &DTimestampTZ{Time: d.Add(-time.Microsecond)}, true 3096 } 3097 3098 // Next implements the Datum interface. 3099 func (d *DTimestampTZ) Next(ctx CompareContext) (Datum, bool) { 3100 if d.IsMax(ctx) { 3101 return nil, false 3102 } 3103 return &DTimestampTZ{Time: d.Add(time.Microsecond)}, true 3104 } 3105 3106 // IsMax implements the Datum interface. 3107 func (d *DTimestampTZ) IsMax(ctx CompareContext) bool { 3108 return d.Equal(MaxSupportedTime) 3109 } 3110 3111 // IsMin implements the Datum interface. 3112 func (d *DTimestampTZ) IsMin(ctx CompareContext) bool { 3113 return d.Equal(MinSupportedTime) 3114 } 3115 3116 // Min implements the Datum interface. 3117 func (d *DTimestampTZ) Min(ctx CompareContext) (Datum, bool) { 3118 return &DTimestampTZ{Time: MinSupportedTime}, true 3119 } 3120 3121 // Max implements the Datum interface. 3122 func (d *DTimestampTZ) Max(ctx CompareContext) (Datum, bool) { 3123 return &DTimestampTZ{Time: MaxSupportedTime}, true 3124 } 3125 3126 // AmbiguousFormat implements the Datum interface. 3127 func (*DTimestampTZ) AmbiguousFormat() bool { return true } 3128 3129 // Format implements the NodeFormatter interface. 3130 func (d *DTimestampTZ) Format(ctx *FmtCtx) { 3131 f := ctx.flags 3132 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 3133 if !bareStrings { 3134 ctx.WriteByte('\'') 3135 } 3136 // By default, rely on the ctx location. 3137 loc := ctx.location 3138 // We sometimes set location correctly in DTimestampTZ. 3139 if loc == nil { 3140 loc = d.Location() 3141 } 3142 if f.HasFlags(fmtPgwireFormat) { 3143 // This assertion should be in place everywhere, but that's a 3144 // huge change for a different day. 3145 if loc == nil { 3146 panic(errors.AssertionFailedf("location on ctx for fmtPgwireFormat must be set for TimestampTZ types")) 3147 } 3148 } 3149 ctx.Write(PGWireFormatTimestamp(d.Time, loc, ctx.scratch[:0])) 3150 if !bareStrings { 3151 ctx.WriteByte('\'') 3152 } 3153 } 3154 3155 // Size implements the Datum interface. 3156 func (d *DTimestampTZ) Size() uintptr { 3157 return unsafe.Sizeof(*d) 3158 } 3159 3160 // EvalAtAndRemoveTimeZone evaluates this TimestampTZ as if it were in the 3161 // supplied location, and then removes the timezone, returning a timestamp 3162 // without a timezone. This is identical to pgdate.stripTimezone but uses the 3163 // provided location instead of the DTimestampTZ's location. It is the inverse 3164 // of AddTimeZone. 3165 func (d *DTimestampTZ) EvalAtAndRemoveTimeZone( 3166 loc *time.Location, precision time.Duration, 3167 ) (*DTimestamp, error) { 3168 // First shift by the location offset to render the TimestampTZ in the session 3169 // timezone, then store that local time as if it were UTC. 3170 _, locOffset := d.Time.In(loc).Zone() 3171 t := d.Time.Add(time.Duration(locOffset) * time.Second) 3172 return MakeDTimestamp(t.UTC(), precision) 3173 } 3174 3175 // AddTimeZone uses the supplied location to convert this Timestamp to a 3176 // timestamp with a timezone. It is the inverse of EvalAtAndRemoveTimeZone. 3177 func (d *DTimestamp) AddTimeZone( 3178 loc *time.Location, precision time.Duration, 3179 ) (*DTimestampTZ, error) { 3180 // Treat the Timestamp as if it were already shifted by the location offset, 3181 // and shift by the negative offset to convert it to UTC. 3182 _, locOffset := d.Time.In(loc).Zone() 3183 t := d.Time.Add(time.Duration(-locOffset) * time.Second) 3184 return MakeDTimestampTZ(t.UTC(), precision) 3185 } 3186 3187 // DInterval is the interval Datum. 3188 type DInterval struct { 3189 duration.Duration 3190 } 3191 3192 // AsDInterval attempts to retrieve a DInterval from an Expr, returning a DInterval and 3193 // a flag signifying whether the assertion was successful. The function should 3194 // be used instead of direct type assertions wherever a *DInterval wrapped by a 3195 // *DOidWrapper is possible. 3196 func AsDInterval(e Expr) (*DInterval, bool) { 3197 switch t := e.(type) { 3198 case *DInterval: 3199 return t, true 3200 case *DOidWrapper: 3201 return AsDInterval(t.Wrapped) 3202 } 3203 return nil, false 3204 } 3205 3206 // MustBeDInterval attempts to retrieve a DInterval from an Expr, panicking if the 3207 // assertion fails. 3208 func MustBeDInterval(e Expr) *DInterval { 3209 t, ok := AsDInterval(e) 3210 if ok { 3211 return t 3212 } 3213 panic(errors.AssertionFailedf("expected *DInterval, found %T", e)) 3214 } 3215 3216 // NewDInterval creates a new DInterval. 3217 func NewDInterval(d duration.Duration, itm types.IntervalTypeMetadata) *DInterval { 3218 truncateInterval(&d, itm) 3219 return &DInterval{Duration: d} 3220 } 3221 3222 // ParseDInterval parses and returns the *DInterval Datum value represented by the provided 3223 // string, or an error if parsing is unsuccessful. 3224 func ParseDInterval(style duration.IntervalStyle, s string) (*DInterval, error) { 3225 return ParseDIntervalWithTypeMetadata(style, s, types.DefaultIntervalTypeMetadata) 3226 } 3227 3228 // truncateInterval truncates the input interval downward to the nearest 3229 // interval quantity specified by the DurationField input. 3230 // If precision is set for seconds, this will instead round at the second layer. 3231 func truncateInterval(d *duration.Duration, itm types.IntervalTypeMetadata) { 3232 switch itm.DurationField.DurationType { 3233 case types.IntervalDurationType_YEAR: 3234 d.Months = d.Months - d.Months%12 3235 d.Days = 0 3236 d.SetNanos(0) 3237 case types.IntervalDurationType_MONTH: 3238 d.Days = 0 3239 d.SetNanos(0) 3240 case types.IntervalDurationType_DAY: 3241 d.SetNanos(0) 3242 case types.IntervalDurationType_HOUR: 3243 d.SetNanos(d.Nanos() - d.Nanos()%time.Hour.Nanoseconds()) 3244 case types.IntervalDurationType_MINUTE: 3245 d.SetNanos(d.Nanos() - d.Nanos()%time.Minute.Nanoseconds()) 3246 case types.IntervalDurationType_SECOND, types.IntervalDurationType_UNSET: 3247 if itm.PrecisionIsSet || itm.Precision > 0 { 3248 prec := TimeFamilyPrecisionToRoundDuration(itm.Precision) 3249 d.SetNanos(time.Duration(d.Nanos()).Round(prec).Nanoseconds()) 3250 } 3251 } 3252 } 3253 3254 // ParseDIntervalWithTypeMetadata is like ParseDInterval, but it also takes a 3255 // types.IntervalTypeMetadata that both specifies the units for unitless, numeric intervals 3256 // and also specifies the precision of the interval. 3257 func ParseDIntervalWithTypeMetadata( 3258 style duration.IntervalStyle, s string, itm types.IntervalTypeMetadata, 3259 ) (*DInterval, error) { 3260 d, err := ParseIntervalWithTypeMetadata(style, s, itm) 3261 if err != nil { 3262 return nil, err 3263 } 3264 return &DInterval{Duration: d}, nil 3265 } 3266 3267 // ParseIntervalWithTypeMetadata is the same as ParseDIntervalWithTypeMetadata 3268 // but returns a duration.Duration. 3269 func ParseIntervalWithTypeMetadata( 3270 style duration.IntervalStyle, s string, itm types.IntervalTypeMetadata, 3271 ) (duration.Duration, error) { 3272 d, err := duration.ParseInterval(style, s, itm) 3273 if err != nil { 3274 return d, err 3275 } 3276 truncateInterval(&d, itm) 3277 return d, nil 3278 } 3279 3280 // ResolvedType implements the TypedExpr interface. 3281 func (*DInterval) ResolvedType() *types.T { 3282 return types.Interval 3283 } 3284 3285 // Compare implements the Datum interface. 3286 func (d *DInterval) Compare(ctx CompareContext, other Datum) int { 3287 res, err := d.CompareError(ctx, other) 3288 if err != nil { 3289 panic(err) 3290 } 3291 return res 3292 } 3293 3294 // CompareError implements the Datum interface. 3295 func (d *DInterval) CompareError(ctx CompareContext, other Datum) (int, error) { 3296 if other == DNull { 3297 // NULL is less than any non-NULL value. 3298 return 1, nil 3299 } 3300 v, ok := ctx.UnwrapDatum(other).(*DInterval) 3301 if !ok { 3302 return 0, makeUnsupportedComparisonMessage(d, other) 3303 } 3304 res := d.Duration.Compare(v.Duration) 3305 return res, nil 3306 } 3307 3308 // Prev implements the Datum interface. 3309 func (d *DInterval) Prev(ctx CompareContext) (Datum, bool) { 3310 return nil, false 3311 } 3312 3313 // Next implements the Datum interface. 3314 func (d *DInterval) Next(ctx CompareContext) (Datum, bool) { 3315 return nil, false 3316 } 3317 3318 // IsMax implements the Datum interface. 3319 func (d *DInterval) IsMax(ctx CompareContext) bool { 3320 return d.Duration == dMaxInterval.Duration 3321 } 3322 3323 // IsMin implements the Datum interface. 3324 func (d *DInterval) IsMin(ctx CompareContext) bool { 3325 return d.Duration == dMinInterval.Duration 3326 } 3327 3328 var ( 3329 dZeroInterval = &DInterval{} 3330 dMaxInterval = &DInterval{duration.MakeDuration(math.MaxInt64, math.MaxInt64, math.MaxInt64)} 3331 dMinInterval = &DInterval{duration.MakeDuration(math.MinInt64, math.MinInt64, math.MinInt64)} 3332 ) 3333 3334 // Max implements the Datum interface. 3335 func (d *DInterval) Max(ctx CompareContext) (Datum, bool) { 3336 return dMaxInterval, true 3337 } 3338 3339 // Min implements the Datum interface. 3340 func (d *DInterval) Min(ctx CompareContext) (Datum, bool) { 3341 return dMinInterval, true 3342 } 3343 3344 // ValueAsISO8601String returns the interval as an ISO 8601 Duration string (e.g. "P1Y2MT6S"). 3345 func (d *DInterval) ValueAsISO8601String() string { 3346 return d.Duration.ISO8601String() 3347 } 3348 3349 // AmbiguousFormat implements the Datum interface. 3350 func (*DInterval) AmbiguousFormat() bool { return true } 3351 3352 // FormatDuration writes d into ctx according to the format flags. 3353 func FormatDuration(d duration.Duration, ctx *FmtCtx) { 3354 f := ctx.flags 3355 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 3356 if !bareStrings { 3357 ctx.WriteByte('\'') 3358 } 3359 d.FormatWithStyle(&ctx.Buffer, ctx.dataConversionConfig.IntervalStyle) 3360 if !bareStrings { 3361 ctx.WriteByte('\'') 3362 } 3363 } 3364 3365 // Format implements the NodeFormatter interface. 3366 func (d *DInterval) Format(ctx *FmtCtx) { 3367 FormatDuration(d.Duration, ctx) 3368 } 3369 3370 // Size implements the Datum interface. 3371 func (d *DInterval) Size() uintptr { 3372 return unsafe.Sizeof(*d) 3373 } 3374 3375 // DGeography is the Geometry Datum. 3376 type DGeography struct { 3377 geo.Geography 3378 } 3379 3380 // NewDGeography returns a new Geography Datum. 3381 func NewDGeography(g geo.Geography) *DGeography { 3382 return &DGeography{Geography: g} 3383 } 3384 3385 // AsDGeography attempts to retrieve a *DGeography from an Expr, returning a 3386 // *DGeography and a flag signifying whether the assertion was successful. The 3387 // function should be used instead of direct type assertions wherever a 3388 // *DGeography wrapped by a *DOidWrapper is possible. 3389 func AsDGeography(e Expr) (*DGeography, bool) { 3390 switch t := e.(type) { 3391 case *DGeography: 3392 return t, true 3393 case *DOidWrapper: 3394 return AsDGeography(t.Wrapped) 3395 } 3396 return nil, false 3397 } 3398 3399 // MustBeDGeography attempts to retrieve a *DGeography from an Expr, panicking 3400 // if the assertion fails. 3401 func MustBeDGeography(e Expr) *DGeography { 3402 i, ok := AsDGeography(e) 3403 if !ok { 3404 panic(errors.AssertionFailedf("expected *DGeography, found %T", e)) 3405 } 3406 return i 3407 } 3408 3409 // ParseDGeography attempts to pass `str` as a Geography type. 3410 func ParseDGeography(str string) (*DGeography, error) { 3411 g, err := geo.ParseGeography(str) 3412 if err != nil { 3413 return nil, errors.Wrapf(err, "could not parse geography") 3414 } 3415 return &DGeography{Geography: g}, nil 3416 } 3417 3418 // ResolvedType implements the TypedExpr interface. 3419 func (*DGeography) ResolvedType() *types.T { 3420 return types.Geography 3421 } 3422 3423 // Compare implements the Datum interface. 3424 func (d *DGeography) Compare(ctx CompareContext, other Datum) int { 3425 res, err := d.CompareError(ctx, other) 3426 if err != nil { 3427 panic(err) 3428 } 3429 return res 3430 } 3431 3432 // CompareError implements the Datum interface. 3433 func (d *DGeography) CompareError(ctx CompareContext, other Datum) (int, error) { 3434 if other == DNull { 3435 // NULL is less than any non-NULL value. 3436 return 1, nil 3437 } 3438 v, ok := ctx.UnwrapDatum(other).(*DGeography) 3439 if !ok { 3440 return 0, makeUnsupportedComparisonMessage(d, other) 3441 } 3442 res := d.Geography.Compare(v.Geography) 3443 return res, nil 3444 } 3445 3446 // Prev implements the Datum interface. 3447 func (d *DGeography) Prev(ctx CompareContext) (Datum, bool) { 3448 return nil, false 3449 } 3450 3451 // Next implements the Datum interface. 3452 func (d *DGeography) Next(ctx CompareContext) (Datum, bool) { 3453 return nil, false 3454 } 3455 3456 // IsMax implements the Datum interface. 3457 func (d *DGeography) IsMax(ctx CompareContext) bool { 3458 return false 3459 } 3460 3461 // IsMin implements the Datum interface. 3462 func (d *DGeography) IsMin(ctx CompareContext) bool { 3463 return false 3464 } 3465 3466 // Max implements the Datum interface. 3467 func (d *DGeography) Max(ctx CompareContext) (Datum, bool) { 3468 return nil, false 3469 } 3470 3471 // Min implements the Datum interface. 3472 func (d *DGeography) Min(ctx CompareContext) (Datum, bool) { 3473 return nil, false 3474 } 3475 3476 // AmbiguousFormat implements the Datum interface. 3477 func (*DGeography) AmbiguousFormat() bool { return true } 3478 3479 // Format implements the NodeFormatter interface. 3480 func (d *DGeography) Format(ctx *FmtCtx) { 3481 f := ctx.flags 3482 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 3483 if !bareStrings { 3484 ctx.WriteByte('\'') 3485 } 3486 ctx.WriteString(d.Geography.EWKBHex()) 3487 if !bareStrings { 3488 ctx.WriteByte('\'') 3489 } 3490 } 3491 3492 // Size implements the Datum interface. 3493 func (d *DGeography) Size() uintptr { 3494 return d.Geography.SpatialObjectRef().MemSize() 3495 } 3496 3497 // DGeometry is the Geometry Datum. 3498 type DGeometry struct { 3499 geo.Geometry 3500 } 3501 3502 // NewDGeometry returns a new Geometry Datum. 3503 func NewDGeometry(g geo.Geometry) *DGeometry { 3504 return &DGeometry{Geometry: g} 3505 } 3506 3507 // AsDGeometry attempts to retrieve a *DGeometry from an Expr, returning a 3508 // *DGeometry and a flag signifying whether the assertion was successful. The 3509 // function should be used instead of direct type assertions wherever a 3510 // *DGeometry wrapped by a *DOidWrapper is possible. 3511 func AsDGeometry(e Expr) (*DGeometry, bool) { 3512 switch t := e.(type) { 3513 case *DGeometry: 3514 return t, true 3515 case *DOidWrapper: 3516 return AsDGeometry(t.Wrapped) 3517 } 3518 return nil, false 3519 } 3520 3521 // MustBeDGeometry attempts to retrieve a *DGeometry from an Expr, panicking 3522 // if the assertion fails. 3523 func MustBeDGeometry(e Expr) *DGeometry { 3524 i, ok := AsDGeometry(e) 3525 if !ok { 3526 panic(errors.AssertionFailedf("expected *DGeometry, found %T", e)) 3527 } 3528 return i 3529 } 3530 3531 // ParseDGeometry attempts to pass `str` as a Geometry type. 3532 func ParseDGeometry(str string) (*DGeometry, error) { 3533 g, err := geo.ParseGeometry(str) 3534 if err != nil { 3535 return nil, errors.Wrapf(err, "could not parse geometry") 3536 } 3537 return &DGeometry{Geometry: g}, nil 3538 } 3539 3540 // ResolvedType implements the TypedExpr interface. 3541 func (*DGeometry) ResolvedType() *types.T { 3542 return types.Geometry 3543 } 3544 3545 // Compare implements the Datum interface. 3546 func (d *DGeometry) Compare(ctx CompareContext, other Datum) int { 3547 res, err := d.CompareError(ctx, other) 3548 if err != nil { 3549 panic(err) 3550 } 3551 return res 3552 } 3553 3554 // CompareError implements the Datum interface. 3555 func (d *DGeometry) CompareError(ctx CompareContext, other Datum) (int, error) { 3556 if other == DNull { 3557 // NULL is less than any non-NULL value. 3558 return 1, nil 3559 } 3560 v, ok := ctx.UnwrapDatum(other).(*DGeometry) 3561 if !ok { 3562 return 0, makeUnsupportedComparisonMessage(d, other) 3563 } 3564 res := d.Geometry.Compare(v.Geometry) 3565 return res, nil 3566 } 3567 3568 // Prev implements the Datum interface. 3569 func (d *DGeometry) Prev(ctx CompareContext) (Datum, bool) { 3570 return nil, false 3571 } 3572 3573 // Next implements the Datum interface. 3574 func (d *DGeometry) Next(ctx CompareContext) (Datum, bool) { 3575 return nil, false 3576 } 3577 3578 // IsMax implements the Datum interface. 3579 func (d *DGeometry) IsMax(ctx CompareContext) bool { 3580 return false 3581 } 3582 3583 // IsMin implements the Datum interface. 3584 func (d *DGeometry) IsMin(ctx CompareContext) bool { 3585 return false 3586 } 3587 3588 // Max implements the Datum interface. 3589 func (d *DGeometry) Max(ctx CompareContext) (Datum, bool) { 3590 return nil, false 3591 } 3592 3593 // Min implements the Datum interface. 3594 func (d *DGeometry) Min(ctx CompareContext) (Datum, bool) { 3595 return nil, false 3596 } 3597 3598 // AmbiguousFormat implements the Datum interface. 3599 func (*DGeometry) AmbiguousFormat() bool { return true } 3600 3601 // Format implements the NodeFormatter interface. 3602 func (d *DGeometry) Format(ctx *FmtCtx) { 3603 f := ctx.flags 3604 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 3605 if !bareStrings { 3606 ctx.WriteByte('\'') 3607 } 3608 ctx.WriteString(d.Geometry.EWKBHex()) 3609 if !bareStrings { 3610 ctx.WriteByte('\'') 3611 } 3612 } 3613 3614 // Size implements the Datum interface. 3615 func (d *DGeometry) Size() uintptr { 3616 return d.Geometry.SpatialObjectRef().MemSize() 3617 } 3618 3619 type DPGLSN struct { 3620 lsn.LSN 3621 } 3622 3623 // NewDPGLSN returns a new PGLSN Datum. 3624 func NewDPGLSN(l lsn.LSN) *DPGLSN { 3625 return &DPGLSN{LSN: l} 3626 } 3627 3628 // ParseDPGLSN attempts to pass `str` as a PGLSN type. 3629 func ParseDPGLSN(str string) (*DPGLSN, error) { 3630 v, err := lsn.ParseLSN(str) 3631 if err != nil { 3632 return nil, pgerror.Newf(pgcode.InvalidTextRepresentation, 3633 "invalid input syntax for type pg_lsn: \"%s\"", str, 3634 ) 3635 } 3636 return NewDPGLSN(v), nil 3637 } 3638 3639 // AsDPGLSN attempts to retrieve a *DPGLSN from an Expr, returning a 3640 // *DPGLSN and a flag signifying whether the assertion was successful. The 3641 // function should be used instead of direct type assertions wherever a 3642 // *DPGLSN wrapped by a *DOidWrapper is possible. 3643 func AsDPGLSN(e Expr) (*DPGLSN, bool) { 3644 switch t := e.(type) { 3645 case *DPGLSN: 3646 return t, true 3647 case *DOidWrapper: 3648 return AsDPGLSN(t.Wrapped) 3649 } 3650 return nil, false 3651 } 3652 3653 // MustBeDPGLSN attempts to retrieve a *DPGLSN from an Expr, panicking 3654 // if the assertion fails. 3655 func MustBeDPGLSN(e Expr) *DPGLSN { 3656 i, ok := AsDPGLSN(e) 3657 if !ok { 3658 panic(errors.AssertionFailedf("expected *DPGLSN, found %T", e)) 3659 } 3660 return i 3661 } 3662 3663 // ResolvedType implements the TypedExpr interface. 3664 func (*DPGLSN) ResolvedType() *types.T { 3665 return types.PGLSN 3666 } 3667 3668 // Compare implements the Datum interface. 3669 func (d *DPGLSN) Compare(ctx CompareContext, other Datum) int { 3670 res, err := d.CompareError(ctx, other) 3671 if err != nil { 3672 panic(err) 3673 } 3674 return res 3675 } 3676 3677 // CompareError implements the Datum interface. 3678 func (d *DPGLSN) CompareError(ctx CompareContext, other Datum) (int, error) { 3679 if other == DNull { 3680 // NULL is less than any non-NULL value. 3681 return 1, nil 3682 } 3683 v, ok := ctx.UnwrapDatum(other).(*DPGLSN) 3684 if !ok { 3685 return 0, makeUnsupportedComparisonMessage(d, other) 3686 } 3687 return d.LSN.Compare(v.LSN), nil 3688 } 3689 3690 // Prev implements the Datum interface. 3691 func (d *DPGLSN) Prev(ctx CompareContext) (Datum, bool) { 3692 if d.IsMin(ctx) { 3693 return nil, false 3694 } 3695 return NewDPGLSN(d.LSN.Sub(1)), true 3696 } 3697 3698 // Next implements the Datum interface. 3699 func (d *DPGLSN) Next(ctx CompareContext) (Datum, bool) { 3700 if d.IsMax(ctx) { 3701 return nil, false 3702 } 3703 return NewDPGLSN(d.LSN.Add(1)), true 3704 } 3705 3706 // IsMax implements the Datum interface. 3707 func (d *DPGLSN) IsMax(ctx CompareContext) bool { 3708 return d.LSN == math.MaxUint64 3709 } 3710 3711 // IsMin implements the Datum interface. 3712 func (d *DPGLSN) IsMin(ctx CompareContext) bool { 3713 return d.LSN == 0 3714 } 3715 3716 // Max implements the Datum interface. 3717 func (d *DPGLSN) Max(ctx CompareContext) (Datum, bool) { 3718 return NewDPGLSN(math.MaxUint64), false 3719 } 3720 3721 // Min implements the Datum interface. 3722 func (d *DPGLSN) Min(ctx CompareContext) (Datum, bool) { 3723 return NewDPGLSN(0), false 3724 } 3725 3726 // AmbiguousFormat implements the Datum interface. 3727 func (*DPGLSN) AmbiguousFormat() bool { return true } 3728 3729 // Format implements the NodeFormatter interface. 3730 func (d *DPGLSN) Format(ctx *FmtCtx) { 3731 f := ctx.flags 3732 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 3733 if !bareStrings { 3734 ctx.WriteByte('\'') 3735 } 3736 ctx.WriteString(d.LSN.String()) 3737 if !bareStrings { 3738 ctx.WriteByte('\'') 3739 } 3740 } 3741 3742 // Size implements the Datum interface. 3743 func (d *DPGLSN) Size() uintptr { 3744 return unsafe.Sizeof(*d) 3745 } 3746 3747 // DBox2D is the Datum representation of the Box2D type. 3748 type DBox2D struct { 3749 geo.CartesianBoundingBox 3750 } 3751 3752 // NewDBox2D returns a new Box2D Datum. 3753 func NewDBox2D(b geo.CartesianBoundingBox) *DBox2D { 3754 return &DBox2D{CartesianBoundingBox: b} 3755 } 3756 3757 // ParseDBox2D attempts to pass `str` as a Box2D type. 3758 func ParseDBox2D(str string) (*DBox2D, error) { 3759 b, err := geo.ParseCartesianBoundingBox(str) 3760 if err != nil { 3761 return nil, errors.Wrapf(err, "could not parse geometry") 3762 } 3763 return &DBox2D{CartesianBoundingBox: b}, nil 3764 } 3765 3766 // AsDBox2D attempts to retrieve a *DBox2D from an Expr, returning a 3767 // *DBox2D and a flag signifying whether the assertion was successful. The 3768 // function should be used instead of direct type assertions wherever a 3769 // *DBox2D wrapped by a *DOidWrapper is possible. 3770 func AsDBox2D(e Expr) (*DBox2D, bool) { 3771 switch t := e.(type) { 3772 case *DBox2D: 3773 return t, true 3774 case *DOidWrapper: 3775 return AsDBox2D(t.Wrapped) 3776 } 3777 return nil, false 3778 } 3779 3780 // MustBeDBox2D attempts to retrieve a *DBox2D from an Expr, panicking 3781 // if the assertion fails. 3782 func MustBeDBox2D(e Expr) *DBox2D { 3783 i, ok := AsDBox2D(e) 3784 if !ok { 3785 panic(errors.AssertionFailedf("expected *DBox2D, found %T", e)) 3786 } 3787 return i 3788 } 3789 3790 // ResolvedType implements the TypedExpr interface. 3791 func (*DBox2D) ResolvedType() *types.T { 3792 return types.Box2D 3793 } 3794 3795 // Compare implements the Datum interface. 3796 func (d *DBox2D) Compare(ctx CompareContext, other Datum) int { 3797 res, err := d.CompareError(ctx, other) 3798 if err != nil { 3799 panic(err) 3800 } 3801 return res 3802 } 3803 3804 // CompareError implements the Datum interface. 3805 func (d *DBox2D) CompareError(ctx CompareContext, other Datum) (int, error) { 3806 if other == DNull { 3807 // NULL is less than any non-NULL value. 3808 return 1, nil 3809 } 3810 v, ok := ctx.UnwrapDatum(other).(*DBox2D) 3811 if !ok { 3812 return 0, makeUnsupportedComparisonMessage(d, other) 3813 } 3814 res := d.CartesianBoundingBox.Compare(&v.CartesianBoundingBox) 3815 return res, nil 3816 } 3817 3818 // Prev implements the Datum interface. 3819 func (d *DBox2D) Prev(ctx CompareContext) (Datum, bool) { 3820 return nil, false 3821 } 3822 3823 // Next implements the Datum interface. 3824 func (d *DBox2D) Next(ctx CompareContext) (Datum, bool) { 3825 return nil, false 3826 } 3827 3828 // IsMax implements the Datum interface. 3829 func (d *DBox2D) IsMax(ctx CompareContext) bool { 3830 return false 3831 } 3832 3833 // IsMin implements the Datum interface. 3834 func (d *DBox2D) IsMin(ctx CompareContext) bool { 3835 return false 3836 } 3837 3838 // Max implements the Datum interface. 3839 func (d *DBox2D) Max(ctx CompareContext) (Datum, bool) { 3840 return nil, false 3841 } 3842 3843 // Min implements the Datum interface. 3844 func (d *DBox2D) Min(ctx CompareContext) (Datum, bool) { 3845 return nil, false 3846 } 3847 3848 // AmbiguousFormat implements the Datum interface. 3849 func (*DBox2D) AmbiguousFormat() bool { return true } 3850 3851 // Format implements the NodeFormatter interface. 3852 func (d *DBox2D) Format(ctx *FmtCtx) { 3853 f := ctx.flags 3854 bareStrings := f.HasFlags(FmtFlags(lexbase.EncBareStrings)) 3855 if !bareStrings { 3856 ctx.WriteByte('\'') 3857 } 3858 ctx.Write(d.CartesianBoundingBox.AppendFormat(ctx.scratch[:0])) 3859 if !bareStrings { 3860 ctx.WriteByte('\'') 3861 } 3862 } 3863 3864 // Size implements the Datum interface. 3865 func (d *DBox2D) Size() uintptr { 3866 return unsafe.Sizeof(*d) + unsafe.Sizeof(d.CartesianBoundingBox) 3867 } 3868 3869 // DJSON is the JSON Datum. 3870 type DJSON struct{ json.JSON } 3871 3872 // NewDJSON is a helper routine to create a DJSON initialized from its argument. 3873 func NewDJSON(j json.JSON) *DJSON { 3874 return &DJSON{j} 3875 } 3876 3877 // IsComposite implements the CompositeDatum interface. 3878 func (d *DJSON) IsComposite() bool { 3879 switch d.JSON.Type() { 3880 case json.NumberJSONType: 3881 dec, ok := d.JSON.AsDecimal() 3882 if !ok { 3883 panic(errors.AssertionFailedf("could not convert into JSON Decimal")) 3884 } 3885 DDec := DDecimal{Decimal: *dec} 3886 return DDec.IsComposite() 3887 case json.ArrayJSONType: 3888 jsonArray, ok := d.AsArray() 3889 if !ok { 3890 panic(errors.AssertionFailedf("could not extract the JSON Array")) 3891 } 3892 for _, elem := range jsonArray { 3893 dJsonVal := DJSON{elem} 3894 if dJsonVal.IsComposite() { 3895 return true 3896 } 3897 } 3898 case json.ObjectJSONType: 3899 if it, err := d.ObjectIter(); it != nil && err == nil { 3900 // Assumption: no collated strings are present as JSON keys. 3901 // Thus, JSON keys are not being checked if they are 3902 // composite or not. 3903 for it.Next() { 3904 valDJSON := NewDJSON(it.Value()) 3905 if valDJSON.IsComposite() { 3906 return true 3907 } 3908 } 3909 } else if err != nil { 3910 panic(errors.NewAssertionErrorWithWrappedErrf(err, "could not receive an ObjectKeyIterator")) 3911 } 3912 } 3913 return false 3914 } 3915 3916 // ParseDJSON takes a string of JSON and returns a DJSON value. 3917 func ParseDJSON(s string) (Datum, error) { 3918 j, err := json.ParseJSON(s) 3919 if err != nil { 3920 return nil, pgerror.Wrapf(err, pgcode.Syntax, "could not parse JSON") 3921 } 3922 return NewDJSON(j), nil 3923 } 3924 3925 // MakeDJSON returns a JSON value given a Go-style representation of JSON. 3926 // * JSON null is Go `nil`, 3927 // * JSON true is Go `true`, 3928 // * JSON false is Go `false`, 3929 // * JSON numbers are json.Number | int | int64 | float64, 3930 // * JSON string is a Go string, 3931 // * JSON array is a Go []interface{}, 3932 // * JSON object is a Go map[string]interface{}. 3933 func MakeDJSON(d interface{}) (Datum, error) { 3934 j, err := json.MakeJSON(d) 3935 if err != nil { 3936 return nil, err 3937 } 3938 return &DJSON{j}, nil 3939 } 3940 3941 var dNullJSON = NewDJSON(json.NullJSONValue) 3942 3943 // AsDJSON attempts to retrieve a *DJSON from an Expr, returning a *DJSON and 3944 // a flag signifying whether the assertion was successful. The function should 3945 // be used instead of direct type assertions wherever a *DJSON wrapped by a 3946 // *DOidWrapper is possible. 3947 func AsDJSON(e Expr) (*DJSON, bool) { 3948 switch t := e.(type) { 3949 case *DJSON: 3950 return t, true 3951 case *DOidWrapper: 3952 return AsDJSON(t.Wrapped) 3953 } 3954 return nil, false 3955 } 3956 3957 // MustBeDJSON attempts to retrieve a DJSON from an Expr, panicking if the 3958 // assertion fails. 3959 func MustBeDJSON(e Expr) DJSON { 3960 i, ok := AsDJSON(e) 3961 if !ok { 3962 panic(errors.AssertionFailedf("expected *DJSON, found %T", e)) 3963 } 3964 return *i 3965 } 3966 3967 // AsJSON converts a datum into our standard json representation. 3968 func AsJSON( 3969 d Datum, dcc sessiondatapb.DataConversionConfig, loc *time.Location, 3970 ) (json.JSON, error) { 3971 d = UnwrapDOidWrapper(d) 3972 switch t := d.(type) { 3973 case *DBool: 3974 return json.FromBool(bool(*t)), nil 3975 case *DInt: 3976 return json.FromInt(int(*t)), nil 3977 case *DFloat: 3978 return json.FromFloat64(float64(*t)) 3979 case *DDecimal: 3980 return json.FromDecimal(t.Decimal), nil 3981 case *DString: 3982 return json.FromString(string(*t)), nil 3983 case *DCollatedString: 3984 return json.FromString(t.Contents), nil 3985 case *DEnum: 3986 return json.FromString(t.LogicalRep), nil 3987 case *DJSON: 3988 return t.JSON, nil 3989 case *DArray: 3990 builder := json.NewArrayBuilder(t.Len()) 3991 for _, e := range t.Array { 3992 j, err := AsJSON(e, dcc, loc) 3993 if err != nil { 3994 return nil, err 3995 } 3996 builder.Add(j) 3997 } 3998 return builder.Build(), nil 3999 case *DTuple: 4000 builder := json.NewObjectBuilder(len(t.D)) 4001 // We need to make sure that t.typ is initialized before getting the tuple 4002 // labels (it is valid for t.typ be left uninitialized when instantiating a 4003 // DTuple). 4004 t.maybePopulateType() 4005 labels := t.typ.TupleLabels() 4006 for i, e := range t.D { 4007 j, err := AsJSON(e, dcc, loc) 4008 if err != nil { 4009 return nil, err 4010 } 4011 var key string 4012 if i >= len(labels) { 4013 key = fmt.Sprintf("f%d", i+1) 4014 } else { 4015 key = labels[i] 4016 } 4017 builder.Add(key, j) 4018 } 4019 return builder.Build(), nil 4020 case *DTimestampTZ: 4021 // Our normal timestamp-formatting code uses a variation on RFC 3339, 4022 // without the T separator. This causes some compatibility problems 4023 // with certain JSON consumers, so we'll use an alternate formatting 4024 // path here to maintain consistency with PostgreSQL. 4025 return json.FromString(formatTime(t.Time.In(loc), time.RFC3339Nano)), nil 4026 case *DTimestamp: 4027 // This is RFC3339Nano, but without the TZ fields. 4028 return json.FromString(formatTime(t.UTC(), "2006-01-02T15:04:05.999999999")), nil 4029 case *DDate, *DUuid, *DOid, *DInterval, *DBytes, *DIPAddr, *DTime, *DTimeTZ, *DBitArray, *DBox2D, 4030 *DTSVector, *DTSQuery, *DPGLSN: 4031 return json.FromString( 4032 AsStringWithFlags(t, FmtBareStrings, FmtDataConversionConfig(dcc), FmtLocation(loc)), 4033 ), nil 4034 case *DGeometry: 4035 return json.FromSpatialObject(t.Geometry.SpatialObject(), geo.DefaultGeoJSONDecimalDigits) 4036 case *DGeography: 4037 return json.FromSpatialObject(t.Geography.SpatialObject(), geo.DefaultGeoJSONDecimalDigits) 4038 case *DVoid: 4039 return json.FromString(AsStringWithFlags(t, fmtRawStrings)), nil 4040 default: 4041 if d == DNull { 4042 return json.NullJSONValue, nil 4043 } 4044 4045 return nil, errors.AssertionFailedf("unexpected type %T for AsJSON", d) 4046 } 4047 } 4048 4049 // formatTime formats time with specified layout. 4050 // TODO(yuzefovich): consider using this function in more places. 4051 func formatTime(t time.Time, layout string) string { 4052 // We only need FmtCtx to access its buffer so 4053 // that we get 0 amortized allocations. 4054 ctx := NewFmtCtx(FmtSimple) 4055 ctx.Write(t.AppendFormat(ctx.scratch[:0], layout)) 4056 return ctx.CloseAndGetString() 4057 } 4058 4059 // ResolvedType implements the TypedExpr interface. 4060 func (*DJSON) ResolvedType() *types.T { 4061 return types.Jsonb 4062 } 4063 4064 // Compare implements the Datum interface. 4065 func (d *DJSON) Compare(ctx CompareContext, other Datum) int { 4066 res, err := d.CompareError(ctx, other) 4067 if err != nil { 4068 panic(err) 4069 } 4070 return res 4071 } 4072 4073 // CompareError implements the Datum interface. 4074 func (d *DJSON) CompareError(ctx CompareContext, other Datum) (int, error) { 4075 if other == DNull { 4076 // NULL is less than any non-NULL value. 4077 return 1, nil 4078 } 4079 v, ok := ctx.UnwrapDatum(other).(*DJSON) 4080 if !ok { 4081 return 0, makeUnsupportedComparisonMessage(d, other) 4082 } 4083 c, err := d.JSON.Compare(v.JSON) 4084 if err != nil { 4085 return 0, err 4086 } 4087 return c, nil 4088 } 4089 4090 // Prev implements the Datum interface. 4091 func (d *DJSON) Prev(ctx CompareContext) (Datum, bool) { 4092 return nil, false 4093 } 4094 4095 // Next implements the Datum interface. 4096 func (d *DJSON) Next(ctx CompareContext) (Datum, bool) { 4097 return nil, false 4098 } 4099 4100 // IsMax implements the Datum interface. 4101 func (d *DJSON) IsMax(ctx CompareContext) bool { 4102 return false 4103 } 4104 4105 // IsMin implements the Datum interface. 4106 func (d *DJSON) IsMin(ctx CompareContext) bool { 4107 return d.JSON == json.NullJSONValue 4108 } 4109 4110 // Max implements the Datum interface. 4111 func (d *DJSON) Max(ctx CompareContext) (Datum, bool) { 4112 return nil, false 4113 } 4114 4115 // Min implements the Datum interface. 4116 func (d *DJSON) Min(ctx CompareContext) (Datum, bool) { 4117 return &DJSON{json.NullJSONValue}, true 4118 } 4119 4120 // AmbiguousFormat implements the Datum interface. 4121 func (*DJSON) AmbiguousFormat() bool { return true } 4122 4123 // Format implements the NodeFormatter interface. 4124 func (d *DJSON) Format(ctx *FmtCtx) { 4125 // TODO(justin): ideally the JSON string encoder should know it needs to 4126 // escape things to be inside SQL strings in order to avoid this allocation. 4127 s := d.JSON.String() 4128 if ctx.HasFlags(fmtRawStrings) || ctx.HasFlags(fmtPgwireFormat) { 4129 ctx.WriteString(s) 4130 } else { 4131 // TODO(knz): This seems incorrect, 4132 // see https://github.com/cockroachdb/cockroachdb-parser/issues/60673 4133 lexbase.EncodeSQLStringWithFlags(&ctx.Buffer, s, ctx.flags.EncodeFlags()) 4134 } 4135 } 4136 4137 // Size implements the Datum interface. 4138 // TODO(justin): is this a frequently-called method? Should we be caching the computed size? 4139 func (d *DJSON) Size() uintptr { 4140 return unsafe.Sizeof(*d) + d.JSON.Size() 4141 } 4142 4143 // DTSQuery is the tsquery Datum. 4144 type DTSQuery struct { 4145 tsearch.TSQuery 4146 } 4147 4148 // Format implements the NodeFormatter interface. 4149 func (d *DTSQuery) Format(ctx *FmtCtx) { 4150 bareStrings := ctx.HasFlags(FmtFlags(lexbase.EncBareStrings)) 4151 if !bareStrings { 4152 ctx.WriteByte('\'') 4153 } 4154 str := d.TSQuery.String() 4155 if !bareStrings { 4156 str = strings.ReplaceAll(str, `'`, `''`) 4157 } 4158 ctx.WriteString(str) 4159 if !bareStrings { 4160 ctx.WriteByte('\'') 4161 } 4162 } 4163 4164 // ResolvedType implements the TypedExpr interface. 4165 func (d *DTSQuery) ResolvedType() *types.T { 4166 return types.TSQuery 4167 } 4168 4169 // AmbiguousFormat implements the Datum interface. 4170 func (d *DTSQuery) AmbiguousFormat() bool { return true } 4171 4172 // Compare implements the Datum interface. 4173 func (d *DTSQuery) Compare(ctx CompareContext, other Datum) int { 4174 res, err := d.CompareError(ctx, other) 4175 if err != nil { 4176 panic(err) 4177 } 4178 return res 4179 } 4180 4181 // CompareError implements the Datum interface. 4182 func (d *DTSQuery) CompareError(ctx CompareContext, other Datum) (int, error) { 4183 if other == DNull { 4184 // NULL is less than any non-NULL value. 4185 return 1, nil 4186 } 4187 v, ok := ctx.UnwrapDatum(other).(*DTSQuery) 4188 if !ok { 4189 return 0, makeUnsupportedComparisonMessage(d, other) 4190 } 4191 l, r := d.String(), v.String() 4192 if l < r { 4193 return -1, nil 4194 } else if l > r { 4195 return 1, nil 4196 } 4197 return 0, nil 4198 } 4199 4200 // Prev implements the Datum interface. 4201 func (d *DTSQuery) Prev(_ CompareContext) (Datum, bool) { 4202 return nil, false 4203 } 4204 4205 // Next implements the Datum interface. 4206 func (d *DTSQuery) Next(_ CompareContext) (Datum, bool) { 4207 return nil, false 4208 } 4209 4210 // IsMin implements the Datum interface. 4211 func (d *DTSQuery) IsMin(_ CompareContext) bool { 4212 return len(d.String()) == 0 4213 } 4214 4215 // IsMax implements the Datum interface. 4216 func (d *DTSQuery) IsMax(ctx CompareContext) bool { 4217 return false 4218 } 4219 4220 // Max implements the Datum interface. 4221 func (d *DTSQuery) Max(ctx CompareContext) (Datum, bool) { 4222 return nil, false 4223 } 4224 4225 // Min implements the Datum interface. 4226 func (d *DTSQuery) Min(ctx CompareContext) (Datum, bool) { 4227 return &DTSQuery{}, false 4228 } 4229 4230 // Size implements the Datum interface. 4231 func (d *DTSQuery) Size() uintptr { 4232 return uintptr(len(d.TSQuery.String())) 4233 } 4234 4235 // AsDTSQuery attempts to retrieve a DTSQuery from an Expr, returning a 4236 // DTSQuery and a flag signifying whether the assertion was successful. The 4237 // function should be used instead of direct type assertions wherever a 4238 // *DTSQuery wrapped by a *DOidWrapper is possible. 4239 func AsDTSQuery(e Expr) (*DTSQuery, bool) { 4240 switch t := e.(type) { 4241 case *DTSQuery: 4242 return t, true 4243 case *DOidWrapper: 4244 return AsDTSQuery(t.Wrapped) 4245 } 4246 return nil, false 4247 } 4248 4249 // MustBeDTSQuery attempts to retrieve a DTSQuery from an Expr, panicking if the 4250 // assertion fails. 4251 func MustBeDTSQuery(e Expr) *DTSQuery { 4252 v, ok := AsDTSQuery(e) 4253 if !ok { 4254 panic(errors.AssertionFailedf("expected *DTSQuery, found %T", e)) 4255 } 4256 return v 4257 } 4258 4259 // NewDTSQuery is a helper routine to create a DTSQuery initialized from its 4260 // argument. 4261 func NewDTSQuery(q tsearch.TSQuery) *DTSQuery { 4262 return &DTSQuery{TSQuery: q} 4263 } 4264 4265 // ParseDTSQuery takes a string of TSQuery and returns a DTSQuery value. 4266 func ParseDTSQuery(s string) (Datum, error) { 4267 v, err := tsearch.ParseTSQuery(s) 4268 if err != nil { 4269 return nil, pgerror.Wrapf(err, pgcode.Syntax, "could not parse tsquery") 4270 } 4271 return NewDTSQuery(v), nil 4272 } 4273 4274 // DTSVector is the tsvector Datum. 4275 type DTSVector struct { 4276 tsearch.TSVector 4277 } 4278 4279 // Format implements the NodeFormatter interface. 4280 func (d *DTSVector) Format(ctx *FmtCtx) { 4281 bareStrings := ctx.HasFlags(FmtFlags(lexbase.EncBareStrings)) 4282 if !bareStrings { 4283 ctx.WriteByte('\'') 4284 } 4285 str := d.TSVector.String() 4286 if !bareStrings { 4287 str = strings.ReplaceAll(str, `'`, `''`) 4288 } 4289 ctx.WriteString(str) 4290 if !bareStrings { 4291 ctx.WriteByte('\'') 4292 } 4293 } 4294 4295 // ResolvedType implements the TypedExpr interface. 4296 func (d *DTSVector) ResolvedType() *types.T { 4297 return types.TSVector 4298 } 4299 4300 // AmbiguousFormat implements the Datum interface. 4301 func (d *DTSVector) AmbiguousFormat() bool { return true } 4302 4303 // Compare implements the Datum interface. 4304 func (d *DTSVector) Compare(ctx CompareContext, other Datum) int { 4305 res, err := d.CompareError(ctx, other) 4306 if err != nil { 4307 panic(err) 4308 } 4309 return res 4310 } 4311 4312 // CompareError implements the Datum interface. 4313 func (d *DTSVector) CompareError(ctx CompareContext, other Datum) (int, error) { 4314 if other == DNull { 4315 // NULL is less than any non-NULL value. 4316 return 1, nil 4317 } 4318 v, ok := ctx.UnwrapDatum(other).(*DTSVector) 4319 if !ok { 4320 return 0, makeUnsupportedComparisonMessage(d, other) 4321 } 4322 l, r := d.String(), v.String() 4323 if l < r { 4324 return -1, nil 4325 } else if l > r { 4326 return 1, nil 4327 } 4328 return 0, nil 4329 } 4330 4331 // Prev implements the Datum interface. 4332 func (d *DTSVector) Prev(_ CompareContext) (Datum, bool) { 4333 return nil, false 4334 } 4335 4336 // Next implements the Datum interface. 4337 func (d *DTSVector) Next(_ CompareContext) (Datum, bool) { 4338 return nil, false 4339 } 4340 4341 // IsMin implements the Datum interface. 4342 func (d *DTSVector) IsMin(_ CompareContext) bool { 4343 return len(d.String()) == 0 4344 } 4345 4346 // IsMax implements the Datum interface. 4347 func (d *DTSVector) IsMax(_ CompareContext) bool { 4348 return false 4349 } 4350 4351 // Max implements the Datum interface. 4352 func (d *DTSVector) Max(_ CompareContext) (Datum, bool) { 4353 return nil, false 4354 } 4355 4356 // Min implements the Datum interface. 4357 func (d *DTSVector) Min(_ CompareContext) (Datum, bool) { 4358 return &DTSVector{}, false 4359 } 4360 4361 // Size implements the Datum interface. 4362 func (d *DTSVector) Size() uintptr { 4363 return uintptr(d.TSVector.StringSize()) 4364 } 4365 4366 // AsDTSVector attempts to retrieve a DTSVector from an Expr, returning a 4367 // DTSVector and a flag signifying whether the assertion was successful. The 4368 // function should be used instead of direct type assertions wherever a 4369 // *DTSVector wrapped by a *DOidWrapper is possible. 4370 func AsDTSVector(e Expr) (*DTSVector, bool) { 4371 switch t := e.(type) { 4372 case *DTSVector: 4373 return t, true 4374 case *DOidWrapper: 4375 return AsDTSVector(t.Wrapped) 4376 } 4377 return nil, false 4378 } 4379 4380 // MustBeDTSVector attempts to retrieve a DTSVector from an Expr, panicking if the 4381 // assertion fails. 4382 func MustBeDTSVector(e Expr) *DTSVector { 4383 v, ok := AsDTSVector(e) 4384 if !ok { 4385 panic(errors.AssertionFailedf("expected *DTSVector, found %T", e)) 4386 } 4387 return v 4388 } 4389 4390 // NewDTSVector is a helper routine to create a DTSVector initialized from its 4391 // argument. 4392 func NewDTSVector(v tsearch.TSVector) *DTSVector { 4393 return &DTSVector{TSVector: v} 4394 } 4395 4396 // ParseDTSVector takes a string of TSVector and returns a DTSVector value. 4397 func ParseDTSVector(s string) (Datum, error) { 4398 v, err := tsearch.ParseTSVector(s) 4399 if err != nil { 4400 return nil, pgerror.Wrapf(err, pgcode.Syntax, "could not parse tsvector") 4401 } 4402 return NewDTSVector(v), nil 4403 } 4404 4405 // DTuple is the tuple Datum. 4406 type DTuple struct { 4407 D Datums 4408 4409 // sorted indicates that the values in D are pre-sorted. 4410 // This is used to accelerate IN comparisons. 4411 sorted bool 4412 4413 // typ is the tuple's type. 4414 // 4415 // The Types sub-field can be initially uninitialized, and is then 4416 // populated upon first invocation of ResolvedTypes(). If 4417 // initialized it must have the same arity as D. 4418 // 4419 // The Labels sub-field can be left nil. If populated, it must have 4420 // the same arity as D. 4421 typ *types.T 4422 } 4423 4424 // NewDTuple creates a *DTuple with the provided datums. When creating a new 4425 // DTuple with Datums that are known to be sorted in ascending order, chain 4426 // this call with DTuple.SetSorted. 4427 func NewDTuple(typ *types.T, d ...Datum) *DTuple { 4428 return &DTuple{D: d, typ: typ} 4429 } 4430 4431 // NewDTupleWithLen creates a *DTuple with the provided length. 4432 func NewDTupleWithLen(typ *types.T, l int) *DTuple { 4433 return &DTuple{D: make(Datums, l), typ: typ} 4434 } 4435 4436 // MakeDTuple creates a DTuple with the provided datums. See NewDTuple. 4437 func MakeDTuple(typ *types.T, d ...Datum) DTuple { 4438 return DTuple{D: d, typ: typ} 4439 } 4440 4441 // AsDTuple attempts to retrieve a *DTuple from an Expr, returning a *DTuple and 4442 // a flag signifying whether the assertion was successful. The function should 4443 // be used instead of direct type assertions wherever a *DTuple wrapped by a 4444 // *DOidWrapper is possible. 4445 func AsDTuple(e Expr) (*DTuple, bool) { 4446 switch t := e.(type) { 4447 case *DTuple: 4448 return t, true 4449 case *DOidWrapper: 4450 return AsDTuple(t.Wrapped) 4451 } 4452 return nil, false 4453 } 4454 4455 // MustBeDTuple attempts to retrieve a *DTuple from an Expr, panicking if the 4456 // assertion fails. 4457 func MustBeDTuple(e Expr) *DTuple { 4458 i, ok := AsDTuple(e) 4459 if !ok { 4460 panic(errors.AssertionFailedf("expected *DTuple, found %T", e)) 4461 } 4462 return i 4463 } 4464 4465 // maybePopulateType populates the tuple's type if it hasn't yet been 4466 // populated. 4467 func (d *DTuple) maybePopulateType() { 4468 if d.typ == nil { 4469 contents := make([]*types.T, len(d.D)) 4470 for i, v := range d.D { 4471 contents[i] = v.ResolvedType() 4472 } 4473 d.typ = types.MakeTuple(contents) 4474 } 4475 } 4476 4477 // ResolvedType implements the TypedExpr interface. 4478 func (d *DTuple) ResolvedType() *types.T { 4479 d.maybePopulateType() 4480 return d.typ 4481 } 4482 4483 // Compare implements the Datum interface. 4484 func (d *DTuple) Compare(ctx CompareContext, other Datum) int { 4485 res, err := d.CompareError(ctx, other) 4486 if err != nil { 4487 panic(err) 4488 } 4489 return res 4490 } 4491 4492 // CompareError implements the Datum interface. 4493 func (d *DTuple) CompareError(ctx CompareContext, other Datum) (int, error) { 4494 if other == DNull { 4495 // NULL is less than any non-NULL value. 4496 return 1, nil 4497 } 4498 v, ok := ctx.UnwrapDatum(other).(*DTuple) 4499 if !ok { 4500 return 0, makeUnsupportedComparisonMessage(d, other) 4501 } 4502 n := len(d.D) 4503 if n > len(v.D) { 4504 n = len(v.D) 4505 } 4506 for i := 0; i < n; i++ { 4507 c, err := d.D[i].CompareError(ctx, v.D[i]) 4508 if err != nil { 4509 return 0, errors.WithDetailf(err, "type mismatch at record column %d", redact.SafeInt(i+1)) 4510 } 4511 if c != 0 { 4512 return c, nil 4513 } 4514 } 4515 if len(d.D) < len(v.D) { 4516 return -1, nil 4517 } 4518 if len(d.D) > len(v.D) { 4519 return 1, nil 4520 } 4521 return 0, nil 4522 } 4523 4524 // Prev implements the Datum interface. 4525 func (d *DTuple) Prev(ctx CompareContext) (Datum, bool) { 4526 // Note: (a:decimal, b:int, c:int) has a prev value; that's (a, b, 4527 // c-1). With an exception if c is MinInt64, in which case the prev 4528 // value is (a, b-1, max(_ *EvalContext)). However, (a:int, b:decimal) does not 4529 // have a prev value, because decimal doesn't have one. 4530 // 4531 // In general, a tuple has a prev value if and only if it ends with 4532 // zero or more values that are a minimum and a maximum value of the 4533 // same type exists, and the first element before that has a prev 4534 // value. 4535 res := NewDTupleWithLen(d.typ, len(d.D)) 4536 copy(res.D, d.D) 4537 for i := len(res.D) - 1; i >= 0; i-- { 4538 if !res.D[i].IsMin(ctx) { 4539 prevVal, ok := res.D[i].Prev(ctx) 4540 if !ok { 4541 return nil, false 4542 } 4543 res.D[i] = prevVal 4544 break 4545 } 4546 maxVal, ok := res.D[i].Max(ctx) 4547 if !ok { 4548 return nil, false 4549 } 4550 res.D[i] = maxVal 4551 } 4552 return res, true 4553 } 4554 4555 // Next implements the Datum interface. 4556 func (d *DTuple) Next(ctx CompareContext) (Datum, bool) { 4557 // Note: (a:decimal, b:int, c:int) has a next value; that's (a, b, 4558 // c+1). With an exception if c is MaxInt64, in which case the next 4559 // value is (a, b+1, min(_ *EvalContext)). However, (a:int, b:decimal) does not 4560 // have a next value, because decimal doesn't have one. 4561 // 4562 // In general, a tuple has a next value if and only if it ends with 4563 // zero or more values that are a maximum and a minimum value of the 4564 // same type exists, and the first element before that has a next 4565 // value. 4566 res := NewDTupleWithLen(d.typ, len(d.D)) 4567 copy(res.D, d.D) 4568 for i := len(res.D) - 1; i >= 0; i-- { 4569 if !res.D[i].IsMax(ctx) { 4570 nextVal, ok := res.D[i].Next(ctx) 4571 if !ok { 4572 return nil, false 4573 } 4574 res.D[i] = nextVal 4575 break 4576 } 4577 // TODO(#12022): temporary workaround; see the interface comment. 4578 res.D[i] = DNull 4579 } 4580 return res, true 4581 } 4582 4583 // Max implements the Datum interface. 4584 func (d *DTuple) Max(ctx CompareContext) (Datum, bool) { 4585 res := NewDTupleWithLen(d.typ, len(d.D)) 4586 for i, v := range d.D { 4587 m, ok := v.Max(ctx) 4588 if !ok { 4589 return nil, false 4590 } 4591 res.D[i] = m 4592 } 4593 return res, true 4594 } 4595 4596 // Min implements the Datum interface. 4597 func (d *DTuple) Min(ctx CompareContext) (Datum, bool) { 4598 res := NewDTupleWithLen(d.typ, len(d.D)) 4599 for i, v := range d.D { 4600 m, ok := v.Min(ctx) 4601 if !ok { 4602 return nil, false 4603 } 4604 res.D[i] = m 4605 } 4606 return res, true 4607 } 4608 4609 // IsMax implements the Datum interface. 4610 func (d *DTuple) IsMax(ctx CompareContext) bool { 4611 for _, v := range d.D { 4612 if !v.IsMax(ctx) { 4613 return false 4614 } 4615 } 4616 return true 4617 } 4618 4619 // IsMin implements the Datum interface. 4620 func (d *DTuple) IsMin(ctx CompareContext) bool { 4621 for _, v := range d.D { 4622 if !v.IsMin(ctx) { 4623 return false 4624 } 4625 } 4626 return true 4627 } 4628 4629 // AmbiguousFormat implements the Datum interface. 4630 func (*DTuple) AmbiguousFormat() bool { return false } 4631 4632 // Format implements the NodeFormatter interface. 4633 func (d *DTuple) Format(ctx *FmtCtx) { 4634 if ctx.HasFlags(fmtPgwireFormat) { 4635 d.pgwireFormat(ctx) 4636 return 4637 } 4638 4639 typ := d.ResolvedType() 4640 tupleContents := typ.TupleContents() 4641 showLabels := len(typ.TupleLabels()) > 0 4642 if showLabels { 4643 ctx.WriteByte('(') 4644 } 4645 ctx.WriteByte('(') 4646 comma := "" 4647 parsable := ctx.HasFlags(FmtParsable) 4648 for i, v := range d.D { 4649 ctx.WriteString(comma) 4650 ctx.FormatNode(v) 4651 if parsable && (v == DNull) && len(tupleContents) > i { 4652 // If Tuple has types.Unknown for this slot, then we can't determine 4653 // the column type to write this annotation. Somebody else will provide 4654 // an error message in this case, if necessary, so just skip the 4655 // annotation and continue. 4656 if tupleContents[i].Family() != types.UnknownFamily { 4657 nullType := tupleContents[i] 4658 if ctx.HasFlags(fmtDisambiguateDatumTypes) { 4659 ctx.WriteString(":::") 4660 ctx.FormatTypeReference(nullType) 4661 } else { 4662 ctx.WriteString("::") 4663 ctx.WriteString(nullType.SQLString()) 4664 } 4665 } 4666 } 4667 comma = ", " 4668 } 4669 if len(d.D) == 1 { 4670 // Ensure the pretty-printed 1-value tuple is not ambiguous with 4671 // the equivalent value enclosed in grouping parentheses. 4672 ctx.WriteByte(',') 4673 } 4674 ctx.WriteByte(')') 4675 if showLabels { 4676 ctx.WriteString(" AS ") 4677 comma := "" 4678 for i := range typ.TupleLabels() { 4679 ctx.WriteString(comma) 4680 ctx.FormatNode((*Name)(&typ.TupleLabels()[i])) 4681 comma = ", " 4682 } 4683 ctx.WriteByte(')') 4684 } 4685 } 4686 4687 // Sorted returns true if the tuple is known to be sorted (and contains no 4688 // NULLs). 4689 func (d *DTuple) Sorted() bool { 4690 return d.sorted 4691 } 4692 4693 // SetSorted sets the sorted flag on the DTuple. This should be used when a 4694 // DTuple is known to be sorted based on the datums added to it. 4695 func (d *DTuple) SetSorted() *DTuple { 4696 if d.ContainsNull() { 4697 // A DTuple that contains a NULL (see ContainsNull) cannot be marked as sorted. 4698 return d 4699 } 4700 d.sorted = true 4701 return d 4702 } 4703 4704 // AssertSorted asserts that the DTuple is sorted. 4705 func (d *DTuple) AssertSorted() { 4706 if !d.sorted { 4707 panic(errors.AssertionFailedf("expected sorted tuple, found %#v", d)) 4708 } 4709 } 4710 4711 // SearchSorted searches the tuple for the target Datum, returning an int with 4712 // the same contract as sort.Search and a boolean flag signifying whether the datum 4713 // was found. It assumes that the DTuple is sorted and panics if it is not. 4714 // 4715 // The target Datum cannot be NULL or a DTuple that contains NULLs (we cannot 4716 // binary search in this case; for example `(1, NULL) IN ((1, 2), ..)` needs to 4717 // be 4718 func (d *DTuple) SearchSorted(ctx CompareContext, target Datum) (int, bool) { 4719 d.AssertSorted() 4720 if target == DNull { 4721 panic(errors.AssertionFailedf("NULL target (d: %s)", d)) 4722 } 4723 if t, ok := target.(*DTuple); ok && t.ContainsNull() { 4724 panic(errors.AssertionFailedf("target containing NULLs: %#v (d: %s)", target, d)) 4725 } 4726 i := sort.Search(len(d.D), func(i int) bool { 4727 return d.D[i].Compare(ctx, target) >= 0 4728 }) 4729 found := i < len(d.D) && d.D[i].Compare(ctx, target) == 0 4730 return i, found 4731 } 4732 4733 // Normalize sorts and uniques the datum tuple. 4734 func (d *DTuple) Normalize(ctx CompareContext) { 4735 d.sort(ctx) 4736 d.makeUnique(ctx) 4737 } 4738 4739 func (d *DTuple) sort(ctx CompareContext) { 4740 if !d.sorted { 4741 lessFn := func(i, j int) bool { 4742 return d.D[i].Compare(ctx, d.D[j]) < 0 4743 } 4744 4745 // It is possible for the tuple to be sorted even though the sorted flag 4746 // is not true. So before we perform the sort we check that it is not 4747 // already sorted. 4748 if !sort.SliceIsSorted(d.D, lessFn) { 4749 sort.Slice(d.D, lessFn) 4750 } 4751 d.SetSorted() 4752 } 4753 } 4754 4755 func (d *DTuple) makeUnique(ctx CompareContext) { 4756 n := 0 4757 for i := 0; i < len(d.D); i++ { 4758 if n == 0 || d.D[n-1].Compare(ctx, d.D[i]) < 0 { 4759 d.D[n] = d.D[i] 4760 n++ 4761 } 4762 } 4763 d.D = d.D[:n] 4764 } 4765 4766 // Size implements the Datum interface. 4767 func (d *DTuple) Size() uintptr { 4768 sz := unsafe.Sizeof(*d) 4769 for _, e := range d.D { 4770 dsz := e.Size() 4771 sz += dsz 4772 } 4773 return sz 4774 } 4775 4776 // ContainsNull returns true if the tuple contains NULL, possibly nested inside 4777 // other tuples. For example, all the following tuples contain NULL: 4778 // 4779 // (1, 2, NULL) 4780 // ((1, 1), (2, NULL)) 4781 // (((1, 1), (2, 2)), ((3, 3), (4, NULL))) 4782 func (d *DTuple) ContainsNull() bool { 4783 for _, r := range d.D { 4784 if r == DNull { 4785 return true 4786 } 4787 if t, ok := r.(*DTuple); ok { 4788 if t.ContainsNull() { 4789 return true 4790 } 4791 } 4792 } 4793 return false 4794 } 4795 4796 type dNull struct{} 4797 4798 // ResolvedType implements the TypedExpr interface. 4799 func (dNull) ResolvedType() *types.T { 4800 return types.Unknown 4801 } 4802 4803 // Compare implements the Datum interface. 4804 func (d dNull) Compare(ctx CompareContext, other Datum) int { 4805 res, err := d.CompareError(ctx, other) 4806 if err != nil { 4807 panic(err) 4808 } 4809 return res 4810 } 4811 4812 // CompareError implements the Datum interface. 4813 func (d dNull) CompareError(ctx CompareContext, other Datum) (int, error) { 4814 if other == DNull { 4815 return 0, nil 4816 } 4817 return -1, nil 4818 } 4819 4820 // Prev implements the Datum interface. 4821 func (d dNull) Prev(ctx CompareContext) (Datum, bool) { 4822 return nil, false 4823 } 4824 4825 // Next implements the Datum interface. 4826 func (d dNull) Next(ctx CompareContext) (Datum, bool) { 4827 return nil, false 4828 } 4829 4830 // IsMax implements the Datum interface. 4831 func (dNull) IsMax(ctx CompareContext) bool { 4832 return true 4833 } 4834 4835 // IsMin implements the Datum interface. 4836 func (dNull) IsMin(ctx CompareContext) bool { 4837 return true 4838 } 4839 4840 // Max implements the Datum interface. 4841 func (dNull) Max(ctx CompareContext) (Datum, bool) { 4842 return DNull, true 4843 } 4844 4845 // Min implements the Datum interface. 4846 func (dNull) Min(ctx CompareContext) (Datum, bool) { 4847 return DNull, true 4848 } 4849 4850 // AmbiguousFormat implements the Datum interface. 4851 func (dNull) AmbiguousFormat() bool { return false } 4852 4853 // Format implements the NodeFormatter interface. 4854 func (dNull) Format(ctx *FmtCtx) { 4855 if ctx.HasFlags(fmtPgwireFormat) { 4856 // NULL sub-expressions in pgwire text values are represented with 4857 // the empty string. 4858 return 4859 } 4860 ctx.WriteString("NULL") 4861 } 4862 4863 // Size implements the Datum interface. 4864 func (d dNull) Size() uintptr { 4865 return unsafe.Sizeof(d) 4866 } 4867 4868 // DArray is the array Datum. Any Datum inserted into a DArray are treated as 4869 // text during serialization. 4870 type DArray struct { 4871 ParamTyp *types.T 4872 Array Datums 4873 // HasNulls is set to true if any of the datums within the array are null. 4874 // This is used in the binary array serialization format. 4875 HasNulls bool 4876 // HasNonNulls is set to true if any of the datums within the are non-null. 4877 // This is used in expression serialization (FmtParsable). 4878 HasNonNulls bool 4879 4880 // customOid, if non-0, is the oid of this array datum. 4881 customOid oid.Oid 4882 } 4883 4884 // NewDArray returns a DArray containing elements of the specified type. 4885 func NewDArray(paramTyp *types.T) *DArray { 4886 return &DArray{ParamTyp: paramTyp} 4887 } 4888 4889 // AsDArray attempts to retrieve a *DArray from an Expr, returning a *DArray and 4890 // a flag signifying whether the assertion was successful. The function should 4891 // be used instead of direct type assertions wherever a *DArray wrapped by a 4892 // *DOidWrapper is possible. 4893 func AsDArray(e Expr) (*DArray, bool) { 4894 switch t := e.(type) { 4895 case *DArray: 4896 return t, true 4897 case *DOidWrapper: 4898 return AsDArray(t.Wrapped) 4899 } 4900 return nil, false 4901 } 4902 4903 // MustBeDArray attempts to retrieve a *DArray from an Expr, panicking if the 4904 // assertion fails. 4905 func MustBeDArray(e Expr) *DArray { 4906 i, ok := AsDArray(e) 4907 if !ok { 4908 panic(errors.AssertionFailedf("expected *DArray, found %T", e)) 4909 } 4910 return i 4911 } 4912 4913 // MaybeSetCustomOid checks whether t has a special oid that we want to set into 4914 // d. Must be kept in sync with DArray.ResolvedType. Returns an error if t is 4915 // not an array type. 4916 func (d *DArray) MaybeSetCustomOid(t *types.T) error { 4917 if t.Family() != types.ArrayFamily { 4918 return errors.AssertionFailedf("expected array type, got %s", t.SQLStringForError()) 4919 } 4920 switch t.Oid() { 4921 case oid.T_int2vector: 4922 d.customOid = oid.T_int2vector 4923 case oid.T_oidvector: 4924 d.customOid = oid.T_oidvector 4925 } 4926 return nil 4927 } 4928 4929 // ResolvedType implements the TypedExpr interface. Must be kept in sync with 4930 // DArray.MaybeSetCustomOid. 4931 func (d *DArray) ResolvedType() *types.T { 4932 switch d.customOid { 4933 case oid.T_int2vector: 4934 return types.Int2Vector 4935 case oid.T_oidvector: 4936 return types.OidVector 4937 } 4938 return types.MakeArray(d.ParamTyp) 4939 } 4940 4941 // IsComposite implements the CompositeDatum interface. 4942 func (d *DArray) IsComposite() bool { 4943 for _, elem := range d.Array { 4944 if cdatum, ok := elem.(CompositeDatum); ok && cdatum.IsComposite() { 4945 return true 4946 } 4947 } 4948 return false 4949 } 4950 4951 // FirstIndex returns the first index of the array. 1 for normal SQL arrays, 4952 // which are 1-indexed, and 0 for the special Postgers vector types which are 4953 // 0-indexed. 4954 func (d *DArray) FirstIndex() int { 4955 switch d.customOid { 4956 case oid.T_int2vector, oid.T_oidvector: 4957 return 0 4958 } 4959 return 1 4960 } 4961 4962 // Compare implements the Datum interface. 4963 func (d *DArray) Compare(ctx CompareContext, other Datum) int { 4964 res, err := d.CompareError(ctx, other) 4965 if err != nil { 4966 panic(err) 4967 } 4968 return res 4969 } 4970 4971 // CompareError implements the Datum interface. 4972 func (d *DArray) CompareError(ctx CompareContext, other Datum) (int, error) { 4973 if other == DNull { 4974 // NULL is less than any non-NULL value. 4975 return 1, nil 4976 } 4977 v, ok := ctx.UnwrapDatum(other).(*DArray) 4978 if !ok { 4979 return 0, makeUnsupportedComparisonMessage(d, other) 4980 } 4981 n := d.Len() 4982 if n > v.Len() { 4983 n = v.Len() 4984 } 4985 for i := 0; i < n; i++ { 4986 c, err := d.Array[i].CompareError(ctx, v.Array[i]) 4987 if err != nil { 4988 return 0, err 4989 } 4990 if c != 0 { 4991 return c, nil 4992 } 4993 } 4994 if d.Len() < v.Len() { 4995 return -1, nil 4996 } 4997 if d.Len() > v.Len() { 4998 return 1, nil 4999 } 5000 return 0, nil 5001 } 5002 5003 // Prev implements the Datum interface. 5004 func (d *DArray) Prev(ctx CompareContext) (Datum, bool) { 5005 return nil, false 5006 } 5007 5008 // Next implements the Datum interface. 5009 func (d *DArray) Next(ctx CompareContext) (Datum, bool) { 5010 a := DArray{ParamTyp: d.ParamTyp, Array: make(Datums, d.Len()+1)} 5011 copy(a.Array, d.Array) 5012 a.Array[len(a.Array)-1] = DNull 5013 return &a, true 5014 } 5015 5016 // Max implements the Datum interface. 5017 func (d *DArray) Max(ctx CompareContext) (Datum, bool) { 5018 return nil, false 5019 } 5020 5021 // Min implements the Datum interface. 5022 func (d *DArray) Min(ctx CompareContext) (Datum, bool) { 5023 return &DArray{ParamTyp: d.ParamTyp}, true 5024 } 5025 5026 // IsMax implements the Datum interface. 5027 func (d *DArray) IsMax(ctx CompareContext) bool { 5028 return false 5029 } 5030 5031 // IsMin implements the Datum interface. 5032 func (d *DArray) IsMin(ctx CompareContext) bool { 5033 return d.Len() == 0 5034 } 5035 5036 // AmbiguousFormat implements the Datum interface. 5037 func (d *DArray) AmbiguousFormat() bool { 5038 // The type of the array is ambiguous if it is empty or all-null; when 5039 // serializing we need to annotate it with the type. 5040 if d.ParamTyp.Family() == types.UnknownFamily { 5041 // If the array's type is unknown, marking it as ambiguous would cause the 5042 // expression formatter to try to annotate it with UNKNOWN[], which is not 5043 // a valid type. So an array of unknown type is (paradoxically) unambiguous. 5044 return false 5045 } 5046 return !d.HasNonNulls 5047 } 5048 5049 // Format implements the NodeFormatter interface. 5050 func (d *DArray) Format(ctx *FmtCtx) { 5051 if ctx.flags.HasAnyFlags(fmtPgwireFormat | FmtPGCatalog) { 5052 d.pgwireFormat(ctx) 5053 return 5054 } 5055 5056 // If we want to export arrays, we need to ensure that 5057 // the datums within the arrays are formatted with enclosing quotes etc. 5058 if ctx.HasFlags(FmtExport) { 5059 oldFlags := ctx.flags 5060 ctx.flags = oldFlags & ^FmtExport | FmtParsable 5061 defer func() { ctx.flags = oldFlags }() 5062 } 5063 5064 ctx.WriteString("ARRAY[") 5065 comma := "" 5066 for _, v := range d.Array { 5067 ctx.WriteString(comma) 5068 ctx.FormatNode(v) 5069 comma = "," 5070 } 5071 ctx.WriteByte(']') 5072 } 5073 5074 const maxArrayLength = math.MaxInt32 5075 5076 var errArrayTooLongError = errors.New("ARRAYs can be at most 2^31-1 elements long") 5077 5078 // Validate checks that the given array is valid, 5079 // for example, that it's not too big. 5080 func (d *DArray) Validate() error { 5081 if d.Len() > maxArrayLength { 5082 return errors.WithStack(errArrayTooLongError) 5083 } 5084 return nil 5085 } 5086 5087 // Len returns the length of the Datum array. 5088 func (d *DArray) Len() int { 5089 return len(d.Array) 5090 } 5091 5092 // Size implements the Datum interface. 5093 func (d *DArray) Size() uintptr { 5094 sz := unsafe.Sizeof(*d) 5095 for _, e := range d.Array { 5096 dsz := e.Size() 5097 sz += dsz 5098 } 5099 return sz 5100 } 5101 5102 var errNonHomogeneousArray = pgerror.New(pgcode.ArraySubscript, "multidimensional arrays must have array expressions with matching dimensions") 5103 5104 // Append appends a Datum to the array, whose parameterized type must be 5105 // consistent with the type of the Datum. 5106 func (d *DArray) Append(v Datum) error { 5107 // v.ResolvedType() must be the left-hand side because EquivalentOrNull 5108 // only allows null tuple elements on the left-hand side. 5109 if !v.ResolvedType().EquivalentOrNull(d.ParamTyp, true /* allowNullTupleEquivalence */) { 5110 return errors.AssertionFailedf( 5111 "cannot append %s to array containing %s", 5112 v.ResolvedType().SQLStringForError(), d.ParamTyp.SQLStringForError(), 5113 ) 5114 } 5115 if d.Len() >= maxArrayLength { 5116 return errors.WithStack(errArrayTooLongError) 5117 } 5118 if d.ParamTyp.Family() == types.ArrayFamily { 5119 if v == DNull { 5120 return errNonHomogeneousArray 5121 } 5122 if d.Len() > 0 { 5123 prevItem := d.Array[d.Len()-1] 5124 if prevItem == DNull { 5125 return errNonHomogeneousArray 5126 } 5127 expectedLen := MustBeDArray(prevItem).Len() 5128 if MustBeDArray(v).Len() != expectedLen { 5129 return errNonHomogeneousArray 5130 } 5131 } 5132 } 5133 if v == DNull { 5134 d.HasNulls = true 5135 } else { 5136 d.HasNonNulls = true 5137 } 5138 d.Array = append(d.Array, v) 5139 return d.Validate() 5140 } 5141 5142 // DVoid represents a void type. 5143 type DVoid struct{} 5144 5145 // DVoidDatum is an instance of the DVoid datum. 5146 var DVoidDatum = &DVoid{} 5147 5148 // ResolvedType implements the TypedExpr interface. 5149 func (*DVoid) ResolvedType() *types.T { 5150 return types.Void 5151 } 5152 5153 // Compare implements the Datum interface. 5154 func (d *DVoid) Compare(ctx CompareContext, other Datum) int { 5155 ret, err := d.CompareError(ctx, other) 5156 if err != nil { 5157 panic(err) 5158 } 5159 return ret 5160 } 5161 5162 // CompareError implements the Datum interface. 5163 func (d *DVoid) CompareError(ctx CompareContext, other Datum) (int, error) { 5164 if other == DNull { 5165 // NULL is less than any non-NULL value. 5166 return 1, nil 5167 } 5168 5169 _, ok := ctx.UnwrapDatum(other).(*DVoid) 5170 if !ok { 5171 return 0, makeUnsupportedComparisonMessage(d, other) 5172 } 5173 return 0, nil 5174 } 5175 5176 // Prev implements the Datum interface. 5177 func (d *DVoid) Prev(ctx CompareContext) (Datum, bool) { 5178 return nil, false 5179 } 5180 5181 // Next implements the Datum interface. 5182 func (d *DVoid) Next(ctx CompareContext) (Datum, bool) { 5183 return nil, false 5184 } 5185 5186 // IsMax implements the Datum interface. 5187 func (d *DVoid) IsMax(ctx CompareContext) bool { 5188 return false 5189 } 5190 5191 // IsMin implements the Datum interface. 5192 func (d *DVoid) IsMin(ctx CompareContext) bool { 5193 return false 5194 } 5195 5196 // Max implements the Datum interface. 5197 func (d *DVoid) Max(ctx CompareContext) (Datum, bool) { 5198 return nil, false 5199 } 5200 5201 // Min implements the Datum interface. 5202 func (d *DVoid) Min(ctx CompareContext) (Datum, bool) { 5203 return nil, false 5204 } 5205 5206 // AmbiguousFormat implements the Datum interface. 5207 func (*DVoid) AmbiguousFormat() bool { return true } 5208 5209 // Format implements the NodeFormatter interface. 5210 func (d *DVoid) Format(ctx *FmtCtx) { 5211 buf, f := &ctx.Buffer, ctx.flags 5212 if !f.HasFlags(fmtRawStrings) { 5213 // void is an empty string. 5214 lexbase.EncodeSQLStringWithFlags(buf, "", f.EncodeFlags()) 5215 } 5216 } 5217 5218 // Size implements the Datum interface. 5219 func (d *DVoid) Size() uintptr { 5220 return unsafe.Sizeof(*d) 5221 } 5222 5223 // DEnum represents an ENUM value. 5224 type DEnum struct { 5225 // EnumType is the hydrated type of this enum. 5226 EnumTyp *types.T 5227 // PhysicalRep is a slice containing the encodable and ordered physical 5228 // representation of this datum. It is used for comparisons and encoding. 5229 PhysicalRep []byte 5230 // LogicalRep is a string containing the user visible value of the enum. 5231 LogicalRep string 5232 } 5233 5234 // Size implements the Datum interface. 5235 func (d *DEnum) Size() uintptr { 5236 // When creating DEnums, we store pointers back into the type enum 5237 // metadata, so enums themselves don't pay for the memory of their 5238 // physical and logical representations. 5239 return unsafe.Sizeof(d.EnumTyp) + 5240 unsafe.Sizeof(d.PhysicalRep) + 5241 unsafe.Sizeof(d.LogicalRep) 5242 } 5243 5244 // GetEnumComponentsFromPhysicalRep returns the physical and logical components 5245 // for an enum of the requested type. It returns an error if it cannot find a 5246 // matching physical representation. 5247 func GetEnumComponentsFromPhysicalRep(typ *types.T, rep []byte) ([]byte, string, error) { 5248 idx, err := typ.EnumGetIdxOfPhysical(rep) 5249 if err != nil { 5250 return nil, "", err 5251 } 5252 meta := typ.TypeMeta.EnumData 5253 // Take a pointer into the enum metadata rather than holding on 5254 // to a pointer to the input bytes. 5255 return meta.PhysicalRepresentations[idx], meta.LogicalRepresentations[idx], nil 5256 } 5257 5258 // GetEnumComponentsFromLogicalRep returns the physical and logical components 5259 // for an enum of the requested type. It returns an error if it cannot find a 5260 // matching logical representation. 5261 func GetEnumComponentsFromLogicalRep(typ *types.T, rep string) ([]byte, string, error) { 5262 idx, err := typ.EnumGetIdxOfLogical(rep) 5263 if err != nil { 5264 return nil, "", err 5265 } 5266 meta := typ.TypeMeta.EnumData 5267 return meta.PhysicalRepresentations[idx], meta.LogicalRepresentations[idx], nil 5268 } 5269 5270 // NewDEnum initializes a new DEnum from its argument. 5271 func NewDEnum(e DEnum) *DEnum { 5272 return &e 5273 } 5274 5275 // AsDEnum attempts to retrieve a DEnum from an Expr, returning a DEnum and 5276 // a flag signifying whether the assertion was successful. The function should 5277 // // be used instead of direct type assertions wherever a *DEnum wrapped by a 5278 // // *DOidWrapper is possible. 5279 func AsDEnum(e Expr) (*DEnum, bool) { 5280 switch t := e.(type) { 5281 case *DEnum: 5282 return t, true 5283 case *DOidWrapper: 5284 return AsDEnum(t.Wrapped) 5285 } 5286 return nil, false 5287 } 5288 5289 // MakeDEnumFromPhysicalRepresentation creates a DEnum of the input type 5290 // and the input physical representation. 5291 func MakeDEnumFromPhysicalRepresentation(typ *types.T, rep []byte) (DEnum, error) { 5292 // Return a nice error if the input requested type is types.AnyEnum. 5293 if typ.Oid() == oid.T_anyenum { 5294 return DEnum{}, errors.New("cannot create enum of unspecified type") 5295 } 5296 phys, log, err := GetEnumComponentsFromPhysicalRep(typ, rep) 5297 if err != nil { 5298 return DEnum{}, err 5299 } 5300 return DEnum{ 5301 EnumTyp: typ, 5302 PhysicalRep: phys, 5303 LogicalRep: log, 5304 }, nil 5305 } 5306 5307 // MakeDEnumFromLogicalRepresentation creates a DEnum of the input type 5308 // and input logical representation. It returns an error if the input 5309 // logical representation is invalid. 5310 func MakeDEnumFromLogicalRepresentation(typ *types.T, rep string) (DEnum, error) { 5311 // Return a nice error if the input requested type is types.AnyEnum. 5312 if typ.Oid() == oid.T_anyenum { 5313 return DEnum{}, errors.New("cannot create enum of unspecified type") 5314 } 5315 // Take a pointer into the enum metadata rather than holding on 5316 // to a pointer to the input string. 5317 idx, err := typ.EnumGetIdxOfLogical(rep) 5318 if err != nil { 5319 return DEnum{}, err 5320 } 5321 return DEnum{ 5322 EnumTyp: typ, 5323 PhysicalRep: typ.TypeMeta.EnumData.PhysicalRepresentations[idx], 5324 LogicalRep: typ.TypeMeta.EnumData.LogicalRepresentations[idx], 5325 }, nil 5326 } 5327 5328 // MakeAllDEnumsInType generates a slice of all values in an enum. 5329 func MakeAllDEnumsInType(typ *types.T) []Datum { 5330 result := make([]Datum, len(typ.TypeMeta.EnumData.LogicalRepresentations)) 5331 for i := 0; i < len(result); i++ { 5332 result[i] = &DEnum{ 5333 EnumTyp: typ, 5334 PhysicalRep: typ.TypeMeta.EnumData.PhysicalRepresentations[i], 5335 LogicalRep: typ.TypeMeta.EnumData.LogicalRepresentations[i], 5336 } 5337 } 5338 return result 5339 } 5340 5341 // Format implements the NodeFormatter interface. 5342 func (d *DEnum) Format(ctx *FmtCtx) { 5343 if ctx.HasFlags(fmtStaticallyFormatUserDefinedTypes) { 5344 s := DBytes(d.PhysicalRep) 5345 // We use the fmtFormatByteLiterals flag here so that the bytes 5346 // get formatted as byte literals. Consider an enum of type t with physical 5347 // representation \x80. If we don't format this as a bytes literal then 5348 // it gets emitted as '\x80':::t. '\x80' is scanned as a string, and we try 5349 // to find a logical representation matching '\x80', which won't exist. 5350 // Instead, we want to emit b'\x80'::: so that '\x80' is scanned as bytes, 5351 // triggering the logic to cast the bytes \x80 to t. 5352 ctx.WithFlags(ctx.flags|fmtFormatByteLiterals, func() { 5353 s.Format(ctx) 5354 }) 5355 } else if ctx.HasFlags(FmtPgwireText) { 5356 ctx.WriteString(d.LogicalRep) 5357 } else { 5358 s := DString(d.LogicalRep) 5359 s.Format(ctx) 5360 } 5361 } 5362 5363 func (d *DEnum) String() string { 5364 return AsString(d) 5365 } 5366 5367 // ResolvedType implements the Datum interface. 5368 func (d *DEnum) ResolvedType() *types.T { 5369 return d.EnumTyp 5370 } 5371 5372 // Compare implements the Datum interface. 5373 func (d *DEnum) Compare(ctx CompareContext, other Datum) int { 5374 res, err := d.CompareError(ctx, other) 5375 if err != nil { 5376 panic(err) 5377 } 5378 return res 5379 } 5380 5381 // CompareError implements the Datum interface. 5382 func (d *DEnum) CompareError(ctx CompareContext, other Datum) (int, error) { 5383 if other == DNull { 5384 return 1, nil 5385 } 5386 v, ok := ctx.UnwrapDatum(other).(*DEnum) 5387 if !ok { 5388 return 0, makeUnsupportedComparisonMessage(d, other) 5389 } 5390 res := bytes.Compare(d.PhysicalRep, v.PhysicalRep) 5391 return res, nil 5392 } 5393 5394 // Prev implements the Datum interface. 5395 func (d *DEnum) Prev(ctx CompareContext) (Datum, bool) { 5396 idx, err := d.EnumTyp.EnumGetIdxOfPhysical(d.PhysicalRep) 5397 if err != nil { 5398 panic(err) 5399 } 5400 if idx == 0 { 5401 return nil, false 5402 } 5403 enumData := d.EnumTyp.TypeMeta.EnumData 5404 return &DEnum{ 5405 EnumTyp: d.EnumTyp, 5406 PhysicalRep: enumData.PhysicalRepresentations[idx-1], 5407 LogicalRep: enumData.LogicalRepresentations[idx-1], 5408 }, true 5409 } 5410 5411 // Next implements the Datum interface. 5412 func (d *DEnum) Next(ctx CompareContext) (Datum, bool) { 5413 idx, err := d.EnumTyp.EnumGetIdxOfPhysical(d.PhysicalRep) 5414 if err != nil { 5415 panic(err) 5416 } 5417 enumData := d.EnumTyp.TypeMeta.EnumData 5418 if idx == len(enumData.PhysicalRepresentations)-1 { 5419 return nil, false 5420 } 5421 return &DEnum{ 5422 EnumTyp: d.EnumTyp, 5423 PhysicalRep: enumData.PhysicalRepresentations[idx+1], 5424 LogicalRep: enumData.LogicalRepresentations[idx+1], 5425 }, true 5426 } 5427 5428 // Max implements the Datum interface. 5429 func (d *DEnum) Max(ctx CompareContext) (Datum, bool) { 5430 enumData := d.EnumTyp.TypeMeta.EnumData 5431 if len(enumData.PhysicalRepresentations) == 0 { 5432 return nil, false 5433 } 5434 idx := len(enumData.PhysicalRepresentations) - 1 5435 return &DEnum{ 5436 EnumTyp: d.EnumTyp, 5437 PhysicalRep: enumData.PhysicalRepresentations[idx], 5438 LogicalRep: enumData.LogicalRepresentations[idx], 5439 }, true 5440 } 5441 5442 // Min implements the Datum interface. 5443 func (d *DEnum) Min(ctx CompareContext) (Datum, bool) { 5444 enumData := d.EnumTyp.TypeMeta.EnumData 5445 if len(enumData.PhysicalRepresentations) == 0 { 5446 return nil, false 5447 } 5448 return &DEnum{ 5449 EnumTyp: d.EnumTyp, 5450 PhysicalRep: enumData.PhysicalRepresentations[0], 5451 LogicalRep: enumData.LogicalRepresentations[0], 5452 }, true 5453 } 5454 5455 // IsMax implements the Datum interface. 5456 func (d *DEnum) IsMax(ctx CompareContext) bool { 5457 physReps := d.EnumTyp.TypeMeta.EnumData.PhysicalRepresentations 5458 idx, err := d.EnumTyp.EnumGetIdxOfPhysical(d.PhysicalRep) 5459 if err != nil { 5460 panic(err) 5461 } 5462 return idx == len(physReps)-1 5463 } 5464 5465 // IsMin implements the Datum interface. 5466 func (d *DEnum) IsMin(ctx CompareContext) bool { 5467 idx, err := d.EnumTyp.EnumGetIdxOfPhysical(d.PhysicalRep) 5468 if err != nil { 5469 panic(err) 5470 } 5471 return idx == 0 5472 } 5473 5474 // AmbiguousFormat implements the Datum interface. 5475 func (d *DEnum) AmbiguousFormat() bool { 5476 return true 5477 } 5478 5479 // MaxWriteable returns the largest member of the enum that is writeable. 5480 func (d *DEnum) MaxWriteable() (Datum, bool) { 5481 enumData := d.EnumTyp.TypeMeta.EnumData 5482 if len(enumData.PhysicalRepresentations) == 0 { 5483 return nil, false 5484 } 5485 for i := len(enumData.PhysicalRepresentations) - 1; i >= 0; i-- { 5486 if !enumData.IsMemberReadOnly[i] { 5487 return &DEnum{ 5488 EnumTyp: d.EnumTyp, 5489 PhysicalRep: enumData.PhysicalRepresentations[i], 5490 LogicalRep: enumData.LogicalRepresentations[i], 5491 }, true 5492 } 5493 } 5494 return nil, false 5495 } 5496 5497 // MinWriteable returns the smallest member of the enum that is writeable. 5498 func (d *DEnum) MinWriteable() (Datum, bool) { 5499 enumData := d.EnumTyp.TypeMeta.EnumData 5500 if len(enumData.PhysicalRepresentations) == 0 { 5501 return nil, false 5502 } 5503 for i := 0; i < len(enumData.PhysicalRepresentations); i++ { 5504 if !enumData.IsMemberReadOnly[i] { 5505 return &DEnum{ 5506 EnumTyp: d.EnumTyp, 5507 PhysicalRep: enumData.PhysicalRepresentations[i], 5508 LogicalRep: enumData.LogicalRepresentations[i], 5509 }, true 5510 } 5511 } 5512 return nil, false 5513 } 5514 5515 // DOid is the Postgres OID datum. It can represent either an OID type or any 5516 // of the reg* types, such as regproc or regclass. An OID must only be 5517 // 32 bits, since this width encoding is enforced in the pgwire protocol. 5518 // OIDs are not guaranteed to be globally unique. 5519 type DOid struct { 5520 // A DOid embeds a oid.Oid, the underlying integer OID for this OID datum. 5521 Oid oid.Oid 5522 // semanticType indicates the particular variety of OID this datum is, whether raw 5523 // Oid or a reg* type. 5524 semanticType *types.T 5525 // name is set to the resolved name of this OID, if available. 5526 name string 5527 } 5528 5529 // IntToOid is a helper that turns a DInt into a *DOid and checks that the value 5530 // is in range. 5531 func IntToOid(i DInt) (*DOid, error) { 5532 if intIsOutOfOIDRange(i) { 5533 return nil, pgerror.Newf( 5534 pgcode.NumericValueOutOfRange, "OID out of range: %d", i, 5535 ) 5536 } 5537 return NewDOid(oid.Oid(i)), nil 5538 } 5539 5540 func intIsOutOfOIDRange(i DInt) bool { 5541 return i > math.MaxUint32 || i < math.MinInt32 5542 } 5543 5544 // MakeDOid is a helper routine to create a DOid initialized from a DInt. 5545 func MakeDOid(d oid.Oid, semanticType *types.T) DOid { 5546 return DOid{Oid: d, semanticType: semanticType, name: ""} 5547 } 5548 5549 // NewDOidWithType constructs a DOid with the given type and no name. 5550 func NewDOidWithType(d oid.Oid, semanticType *types.T) *DOid { 5551 oid := DOid{Oid: d, semanticType: semanticType} 5552 return &oid 5553 } 5554 5555 // NewDOidWithTypeAndName constructs a DOid with the given type and name. 5556 func NewDOidWithTypeAndName(d oid.Oid, semanticType *types.T, name string) *DOid { 5557 oid := DOid{Oid: d, semanticType: semanticType, name: name} 5558 return &oid 5559 } 5560 5561 // NewDOid is a helper routine to create a *DOid initialized from a DInt. 5562 func NewDOid(d oid.Oid) *DOid { 5563 // TODO(yuzefovich): audit the callers of NewDOid to see whether any want to 5564 // create a DOid with a semantic type different from types.Oid. 5565 oid := MakeDOid(d, types.Oid) 5566 return &oid 5567 } 5568 5569 // AsDOid attempts to retrieve a DOid from an Expr, returning a DOid and 5570 // a flag signifying whether the assertion was successful. The function should 5571 // be used instead of direct type assertions wherever a *DOid wrapped by a 5572 // *DOidWrapper is possible. 5573 func AsDOid(e Expr) (*DOid, bool) { 5574 switch t := e.(type) { 5575 case *DOid: 5576 return t, true 5577 case *DOidWrapper: 5578 return AsDOid(t.Wrapped) 5579 } 5580 return NewDOid(0), false 5581 } 5582 5583 // MustBeDOid attempts to retrieve a DOid from an Expr, panicking if the 5584 // assertion fails. 5585 func MustBeDOid(e Expr) *DOid { 5586 i, ok := AsDOid(e) 5587 if !ok { 5588 panic(errors.AssertionFailedf("expected *DOid, found %T", e)) 5589 } 5590 return i 5591 } 5592 5593 // NewDOidWithName is a helper routine to create a *DOid initialized from a DInt 5594 // and a string. 5595 func NewDOidWithName(d oid.Oid, typ *types.T, name string) *DOid { 5596 return &DOid{ 5597 Oid: d, 5598 semanticType: typ, 5599 name: name, 5600 } 5601 } 5602 5603 // AsRegProc changes the input DOid into a regproc with the given name and 5604 // returns it. 5605 func (d *DOid) AsRegProc(name string) *DOid { 5606 d.name = name 5607 d.semanticType = types.RegProc 5608 return d 5609 } 5610 5611 // AmbiguousFormat implements the Datum interface. 5612 func (*DOid) AmbiguousFormat() bool { return true } 5613 5614 // Compare implements the Datum interface. 5615 func (d *DOid) Compare(ctx CompareContext, other Datum) int { 5616 res, err := d.CompareError(ctx, other) 5617 if err != nil { 5618 panic(err) 5619 } 5620 return res 5621 } 5622 5623 // CompareError implements the Datum interface. 5624 func (d *DOid) CompareError(ctx CompareContext, other Datum) (int, error) { 5625 if other == DNull { 5626 // NULL is less than any non-NULL value. 5627 return 1, nil 5628 } 5629 var v oid.Oid 5630 switch t := ctx.UnwrapDatum(other).(type) { 5631 case *DOid: 5632 v = t.Oid 5633 case *DInt: 5634 // OIDs are always unsigned 32-bit integers. Some languages, like Java, 5635 // compare OIDs to signed 32-bit integers, so we implement the comparison 5636 // by converting to a uint32 first. This matches Postgres behavior. 5637 o, err := IntToOid(*t) 5638 if err != nil { 5639 return 0, err 5640 } 5641 v = o.Oid 5642 default: 5643 return 0, makeUnsupportedComparisonMessage(d, other) 5644 } 5645 5646 if d.Oid < v { 5647 return -1, nil 5648 } 5649 if d.Oid > v { 5650 return 1, nil 5651 } 5652 return 0, nil 5653 } 5654 5655 // Format implements the Datum interface. 5656 func (d *DOid) Format(ctx *FmtCtx) { 5657 if d.semanticType.Oid() == oid.T_oid || d.name == "" { 5658 ctx.Write(strconv.AppendUint(ctx.scratch[:0], uint64(d.Oid), 10)) 5659 } else if ctx.HasFlags(fmtDisambiguateDatumTypes) { 5660 ctx.WriteString("crdb_internal.create_") 5661 ctx.WriteString(d.semanticType.SQLStandardName()) 5662 ctx.WriteByte('(') 5663 ctx.Write(strconv.AppendUint(ctx.scratch[:0], uint64(d.Oid), 10)) 5664 ctx.WriteByte(',') 5665 lexbase.EncodeSQLStringWithFlags(&ctx.Buffer, d.name, lexbase.EncNoFlags) 5666 ctx.WriteByte(')') 5667 } else { 5668 // This is used to print the name of pseudo-procedures in e.g. 5669 // pg_catalog.pg_type.typinput 5670 lexbase.EncodeSQLStringWithFlags(&ctx.Buffer, d.name, lexbase.EncBareStrings) 5671 } 5672 } 5673 5674 // IsMax implements the Datum interface. 5675 func (d *DOid) IsMax(ctx CompareContext) bool { 5676 return d.Oid == math.MaxUint32 5677 } 5678 5679 // IsMin implements the Datum interface. 5680 func (d *DOid) IsMin(ctx CompareContext) bool { 5681 return d.Oid == 0 5682 } 5683 5684 // Next implements the Datum interface. 5685 func (d *DOid) Next(ctx CompareContext) (Datum, bool) { 5686 next := d.Oid + 1 5687 return &DOid{next, d.semanticType, ""}, true 5688 } 5689 5690 // Prev implements the Datum interface. 5691 func (d *DOid) Prev(ctx CompareContext) (Datum, bool) { 5692 prev := d.Oid - 1 5693 return &DOid{prev, d.semanticType, ""}, true 5694 } 5695 5696 // ResolvedType implements the Datum interface. 5697 func (d *DOid) ResolvedType() *types.T { 5698 return d.semanticType 5699 } 5700 5701 // Size implements the Datum interface. 5702 func (d *DOid) Size() uintptr { return unsafe.Sizeof(*d) } 5703 5704 // Max implements the Datum interface. 5705 func (d *DOid) Max(ctx CompareContext) (Datum, bool) { 5706 return &DOid{math.MaxUint32, d.semanticType, ""}, true 5707 } 5708 5709 // Min implements the Datum interface. 5710 func (d *DOid) Min(ctx CompareContext) (Datum, bool) { 5711 return &DOid{0, d.semanticType, ""}, true 5712 } 5713 5714 // Name returns the name associated with this DOid. 5715 func (d *DOid) Name() string { 5716 return d.name 5717 } 5718 5719 // DOidWrapper is a Datum implementation which is a wrapper around a Datum, allowing 5720 // custom Oid values to be attached to the Datum and its types.T. 5721 // The reason the Datum type was introduced was to permit the introduction of Datum 5722 // types with new Object IDs while maintaining identical behavior to current Datum 5723 // types. Specifically, it obviates the need to define a new tree.Datum type for 5724 // each possible Oid value. 5725 // 5726 // Instead, DOidWrapper allows a standard Datum to be wrapped with a new Oid. 5727 // This approach provides two major advantages: 5728 // - performance of the existing Datum types are not affected because they 5729 // do not need to have custom oid.Oids added to their structure. 5730 // - the introduction of new Datum aliases is straightforward and does not require 5731 // additions to typing rules or type-dependent evaluation behavior. 5732 // 5733 // Types that currently benefit from DOidWrapper are: 5734 // - DName => DOidWrapper(*DString, oid.T_name) 5735 // - DRefCursor => DOidWrapper(*DString, oid.T_refcursor) 5736 type DOidWrapper struct { 5737 Wrapped Datum 5738 Oid oid.Oid 5739 } 5740 5741 // ZeroOidValue represents the 0 oid value as '-', which matches the Postgres 5742 // representation. 5743 const ZeroOidValue = "-" 5744 5745 // wrapWithOid wraps a Datum with a custom Oid. 5746 func wrapWithOid(d Datum, oid oid.Oid) Datum { 5747 switch v := d.(type) { 5748 case nil: 5749 return nil 5750 case *DInt: 5751 case *DString: 5752 case *DArray: 5753 case dNull, *DOidWrapper: 5754 panic(errors.AssertionFailedf("cannot wrap %T with an Oid", v)) 5755 default: 5756 // Currently only *DInt, *DString, *DArray are hooked up to work with 5757 // *DOidWrapper. To support another base Datum type, replace all type 5758 // assertions to that type with calls to functions like AsDInt and 5759 // MustBeDInt. 5760 panic(errors.AssertionFailedf("unsupported Datum type passed to wrapWithOid: %T", d)) 5761 } 5762 return &DOidWrapper{ 5763 Wrapped: d, 5764 Oid: oid, 5765 } 5766 } 5767 5768 // WrapAsZeroOid wraps ZeroOidValue with a custom Oid. 5769 func WrapAsZeroOid(t *types.T) Datum { 5770 tmpOid := NewDOid(0) 5771 tmpOid.semanticType = t 5772 if t.Oid() != oid.T_oid { 5773 tmpOid.name = ZeroOidValue 5774 } 5775 return tmpOid 5776 } 5777 5778 // UnwrapDOidWrapper exposes the wrapped datum from a *DOidWrapper. 5779 func UnwrapDOidWrapper(d Datum) Datum { 5780 if w, ok := d.(*DOidWrapper); ok { 5781 return w.Wrapped 5782 } 5783 return d 5784 } 5785 5786 // ResolvedType implements the TypedExpr interface. 5787 func (d *DOidWrapper) ResolvedType() *types.T { 5788 return types.OidToType[d.Oid] 5789 } 5790 5791 // Compare implements the Datum interface. 5792 func (d *DOidWrapper) Compare(ctx CompareContext, other Datum) int { 5793 res, err := d.CompareError(ctx, other) 5794 if err != nil { 5795 panic(err) 5796 } 5797 return res 5798 } 5799 5800 // CompareError implements the Datum interface. 5801 func (d *DOidWrapper) CompareError(ctx CompareContext, other Datum) (int, error) { 5802 if other == DNull { 5803 // NULL is less than any non-NULL value. 5804 return 1, nil 5805 } 5806 if v, ok := other.(*DOidWrapper); ok { 5807 return d.Wrapped.CompareError(ctx, v.Wrapped) 5808 } 5809 return d.Wrapped.CompareError(ctx, other) 5810 } 5811 5812 // Prev implements the Datum interface. 5813 func (d *DOidWrapper) Prev(ctx CompareContext) (Datum, bool) { 5814 prev, ok := d.Wrapped.Prev(ctx) 5815 return wrapWithOid(prev, d.Oid), ok 5816 } 5817 5818 // Next implements the Datum interface. 5819 func (d *DOidWrapper) Next(ctx CompareContext) (Datum, bool) { 5820 next, ok := d.Wrapped.Next(ctx) 5821 return wrapWithOid(next, d.Oid), ok 5822 } 5823 5824 // IsMax implements the Datum interface. 5825 func (d *DOidWrapper) IsMax(ctx CompareContext) bool { 5826 return d.Wrapped.IsMax(ctx) 5827 } 5828 5829 // IsMin implements the Datum interface. 5830 func (d *DOidWrapper) IsMin(ctx CompareContext) bool { 5831 return d.Wrapped.IsMin(ctx) 5832 } 5833 5834 // Max implements the Datum interface. 5835 func (d *DOidWrapper) Max(ctx CompareContext) (Datum, bool) { 5836 max, ok := d.Wrapped.Max(ctx) 5837 return wrapWithOid(max, d.Oid), ok 5838 } 5839 5840 // Min implements the Datum interface. 5841 func (d *DOidWrapper) Min(ctx CompareContext) (Datum, bool) { 5842 min, ok := d.Wrapped.Min(ctx) 5843 return wrapWithOid(min, d.Oid), ok 5844 } 5845 5846 // AmbiguousFormat implements the Datum interface. 5847 func (d *DOidWrapper) AmbiguousFormat() bool { 5848 return d.Wrapped.AmbiguousFormat() 5849 } 5850 5851 // Format implements the NodeFormatter interface. 5852 func (d *DOidWrapper) Format(ctx *FmtCtx) { 5853 if d.Oid == oid.T_refcursor { 5854 wrapped := MustBeDString(d.Wrapped) 5855 wrapped.Format(ctx) 5856 return 5857 } 5858 ctx.FormatNode(d.Wrapped) 5859 } 5860 5861 // Size implements the Datum interface. 5862 func (d *DOidWrapper) Size() uintptr { 5863 return unsafe.Sizeof(*d) + d.Wrapped.Size() 5864 } 5865 5866 // AmbiguousFormat implements the Datum interface. 5867 func (d *Placeholder) AmbiguousFormat() bool { 5868 return true 5869 } 5870 5871 // Compare implements the Datum interface. 5872 func (d *Placeholder) Compare(ctx CompareContext, other Datum) int { 5873 res, err := d.CompareError(ctx, other) 5874 if err != nil { 5875 panic(err) 5876 } 5877 return res 5878 } 5879 5880 // CompareError implements the Datum interface. 5881 func (d *Placeholder) CompareError(ctx CompareContext, other Datum) (int, error) { 5882 return ctx.MustGetPlaceholderValue(d).CompareError(ctx, other) 5883 } 5884 5885 // Prev implements the Datum interface. 5886 func (d *Placeholder) Prev(ctx CompareContext) (Datum, bool) { 5887 return ctx.MustGetPlaceholderValue(d).Prev(ctx) 5888 } 5889 5890 // IsMin implements the Datum interface. 5891 func (d *Placeholder) IsMin(ctx CompareContext) bool { 5892 return ctx.MustGetPlaceholderValue(d).IsMin(ctx) 5893 } 5894 5895 // Next implements the Datum interface. 5896 func (d *Placeholder) Next(ctx CompareContext) (Datum, bool) { 5897 return ctx.MustGetPlaceholderValue(d).Next(ctx) 5898 } 5899 5900 // IsMax implements the Datum interface. 5901 func (d *Placeholder) IsMax(ctx CompareContext) bool { 5902 return ctx.MustGetPlaceholderValue(d).IsMax(ctx) 5903 } 5904 5905 // Max implements the Datum interface. 5906 func (d *Placeholder) Max(ctx CompareContext) (Datum, bool) { 5907 return ctx.MustGetPlaceholderValue(d).Max(ctx) 5908 } 5909 5910 // Min implements the Datum interface. 5911 func (d *Placeholder) Min(ctx CompareContext) (Datum, bool) { 5912 return ctx.MustGetPlaceholderValue(d).Min(ctx) 5913 } 5914 5915 // Size implements the Datum interface. 5916 func (d *Placeholder) Size() uintptr { 5917 panic(errors.AssertionFailedf("shouldn't get called")) 5918 } 5919 5920 // NewDNameFromDString is a helper routine to create a *DName (implemented as 5921 // a *DOidWrapper) initialized from an existing *DString. 5922 func NewDNameFromDString(d *DString) Datum { 5923 return wrapWithOid(d, oid.T_name) 5924 } 5925 5926 // NewDName is a helper routine to create a *DName (implemented as a *DOidWrapper) 5927 // initialized from a string. 5928 func NewDName(d string) Datum { 5929 return NewDNameFromDString(NewDString(d)) 5930 } 5931 5932 // NewDRefCursorFromDString is a helper routine to create a *DRefCursor 5933 // (implemented as a *DOidWrapper) initialized from an existing *DString. 5934 func NewDRefCursorFromDString(d *DString) Datum { 5935 return wrapWithOid(d, oid.T_refcursor) 5936 } 5937 5938 // NewDRefCursor is a helper routine to create a *DRefCursor (implemented as a 5939 // *DOidWrapper) initialized from a string. 5940 func NewDRefCursor(d string) Datum { 5941 return NewDRefCursorFromDString(NewDString(d)) 5942 } 5943 5944 // NewDIntVectorFromDArray is a helper routine to create a new *DArray, 5945 // initialized from an existing *DArray, with the special oid for IntVector. 5946 func NewDIntVectorFromDArray(d *DArray) Datum { 5947 // Sanity: Validate the type of the array, since it should be int2. 5948 if d.ParamTyp != types.Int2 { 5949 panic(errors.AssertionFailedf("int2vector can only be made from int2 not %s", d.ParamTyp.SQLStringForError())) 5950 } 5951 ret := new(DArray) 5952 *ret = *d 5953 ret.customOid = oid.T_int2vector 5954 return ret 5955 } 5956 5957 // NewDOidVectorFromDArray is a helper routine to create a new *DArray, 5958 // initialized from an existing *DArray, with the special oid for OidVector. 5959 func NewDOidVectorFromDArray(d *DArray) Datum { 5960 ret := new(DArray) 5961 *ret = *d 5962 ret.customOid = oid.T_oidvector 5963 return ret 5964 } 5965 5966 // NewDefaultDatum returns a default non-NULL datum value for the given type. 5967 // This is used when updating non-NULL columns that are being added or dropped 5968 // from a table, and there is no user-defined DEFAULT value available. 5969 func NewDefaultDatum(collationEnv *CollationEnvironment, t *types.T) (d Datum, err error) { 5970 switch t.Family() { 5971 case types.BoolFamily: 5972 return DBoolFalse, nil 5973 case types.IntFamily: 5974 return DZero, nil 5975 case types.FloatFamily: 5976 return DZeroFloat, nil 5977 case types.DecimalFamily: 5978 return DZeroDecimal, nil 5979 case types.DateFamily: 5980 return dEpochDate, nil 5981 case types.TimestampFamily: 5982 return DZeroTimestamp, nil 5983 case types.IntervalFamily: 5984 return dZeroInterval, nil 5985 case types.StringFamily: 5986 return dEmptyString, nil 5987 case types.BytesFamily: 5988 return dEmptyBytes, nil 5989 case types.TimestampTZFamily: 5990 return DZeroTimestampTZ, nil 5991 case types.CollatedStringFamily: 5992 return NewDCollatedString("", t.Locale(), collationEnv) 5993 case types.OidFamily: 5994 return NewDOidWithName(t.Oid(), t, t.SQLStandardName()), nil 5995 case types.UnknownFamily: 5996 return DNull, nil 5997 case types.UuidFamily: 5998 return DMinUUID, nil 5999 case types.ArrayFamily: 6000 return NewDArray(t.ArrayContents()), nil 6001 case types.INetFamily: 6002 return DMinIPAddr, nil 6003 case types.TimeFamily: 6004 return dTimeMin, nil 6005 case types.JsonFamily: 6006 return dNullJSON, nil 6007 case types.TimeTZFamily: 6008 return dZeroTimeTZ, nil 6009 case types.GeometryFamily, types.GeographyFamily, types.Box2DFamily: 6010 // TODO(otan): force Geometry/Geography to not allow `NOT NULL` columns to 6011 // make this impossible. 6012 return nil, pgerror.Newf( 6013 pgcode.FeatureNotSupported, 6014 "%s must be set or be NULL", 6015 t.Name(), 6016 ) 6017 case types.TupleFamily: 6018 contents := t.TupleContents() 6019 datums := make([]Datum, len(contents)) 6020 for i, subT := range contents { 6021 datums[i], err = NewDefaultDatum(collationEnv, subT) 6022 if err != nil { 6023 return nil, err 6024 } 6025 } 6026 return NewDTuple(t, datums...), nil 6027 case types.BitFamily: 6028 return bitArrayZero, nil 6029 case types.EnumFamily: 6030 // The scenario in which this arises is when the column is being dropped and 6031 // is NOT NULL. If there are no values for this enum, there's nothing that 6032 // can be put here so we'll return 6033 if len(t.TypeMeta.EnumData.PhysicalRepresentations) == 0 { 6034 return nil, pgerror.Newf( 6035 pgcode.NotNullViolation, 6036 "%s has no values which can be used to satisfy the NOT NULL "+ 6037 "constraint while adding or dropping", 6038 t.Name(), 6039 ) 6040 } 6041 // We fall back to using the smallest enum value during the dropping period. 6042 e, err := MakeDEnumFromPhysicalRepresentation(t, t.TypeMeta.EnumData.PhysicalRepresentations[0]) 6043 if err != nil { 6044 return nil, err 6045 } 6046 return NewDEnum(e), nil 6047 default: 6048 return nil, errors.AssertionFailedf("unhandled type %s", t.SQLStringForError()) 6049 } 6050 } 6051 6052 // PGWireTypeSize is the size of the type as reported in pg_catalog and over 6053 // the wire protocol. 6054 func PGWireTypeSize(t *types.T) int { 6055 tOid := t.Oid() 6056 if tOid == oid.T_timestamptz || tOid == oid.T_timestamp || tOid == oid.T_time { 6057 return 8 6058 } 6059 if tOid == oid.T_timetz { 6060 return 12 6061 } 6062 if tOid == oid.T_date { 6063 return 4 6064 } 6065 if sz, variable := DatumTypeSize(t); !variable { 6066 return int(sz) 6067 } 6068 return -1 6069 } 6070 6071 // DatumTypeSize returns a lower bound on the total size of a Datum 6072 // of the given type in bytes, including memory that is 6073 // pointed at (even if shared between Datum instances) but excluding 6074 // allocation overhead. 6075 // 6076 // The second return value indicates whether data of this type have different 6077 // sizes. 6078 // 6079 // It holds for every Datum d that d.Size() >= DatumSize(d.ResolvedType()) 6080 func DatumTypeSize(t *types.T) (size uintptr, isVarlen bool) { 6081 // The following are composite types or types that support multiple widths. 6082 switch t.Family() { 6083 case types.TupleFamily: 6084 if types.IsWildcardTupleType(t) { 6085 return uintptr(0), false 6086 } 6087 sz := uintptr(0) 6088 variable := false 6089 for i := range t.TupleContents() { 6090 typsz, typvariable := DatumTypeSize(t.TupleContents()[i]) 6091 sz += typsz 6092 variable = variable || typvariable 6093 } 6094 return sz, variable 6095 case types.IntFamily, types.FloatFamily: 6096 return uintptr(t.Width() / 8), false 6097 6098 case types.StringFamily: 6099 // T_char is a special string type that has a fixed size of 1. We have to 6100 // report its size accurately, and that it's not a variable-length datatype. 6101 if t.Oid() == oid.T_char { 6102 return 1, false 6103 } 6104 } 6105 6106 // All the primary types have fixed size information. 6107 if bSzInfo, ok := baseDatumTypeSizes[t.Family()]; ok { 6108 return bSzInfo.sz, bSzInfo.variable 6109 } 6110 6111 panic(errors.AssertionFailedf("unknown type: %s", t.SQLStringForError())) 6112 } 6113 6114 const ( 6115 fixedSize = false 6116 variableSize = true 6117 ) 6118 6119 var baseDatumTypeSizes = map[types.Family]struct { 6120 sz uintptr 6121 variable bool 6122 }{ 6123 types.UnknownFamily: {unsafe.Sizeof(dNull{}), fixedSize}, 6124 types.BoolFamily: {unsafe.Sizeof(DBool(false)), fixedSize}, 6125 types.Box2DFamily: {unsafe.Sizeof(DBox2D{CartesianBoundingBox: geo.CartesianBoundingBox{}}), fixedSize}, 6126 types.BitFamily: {unsafe.Sizeof(DBitArray{}), variableSize}, 6127 types.IntFamily: {unsafe.Sizeof(DInt(0)), fixedSize}, 6128 types.FloatFamily: {unsafe.Sizeof(DFloat(0.0)), fixedSize}, 6129 types.DecimalFamily: {unsafe.Sizeof(DDecimal{}), variableSize}, 6130 types.StringFamily: {unsafe.Sizeof(DString("")), variableSize}, 6131 types.CollatedStringFamily: {unsafe.Sizeof(DCollatedString{"", "", nil}), variableSize}, 6132 types.BytesFamily: {unsafe.Sizeof(DBytes("")), variableSize}, 6133 types.EncodedKeyFamily: {unsafe.Sizeof(DBytes("")), variableSize}, 6134 types.DateFamily: {unsafe.Sizeof(DDate{}), fixedSize}, 6135 types.GeographyFamily: {unsafe.Sizeof(DGeography{}), variableSize}, 6136 types.GeometryFamily: {unsafe.Sizeof(DGeometry{}), variableSize}, 6137 types.PGLSNFamily: {unsafe.Sizeof(DPGLSN{}), fixedSize}, 6138 types.RefCursorFamily: {unsafe.Sizeof(DString("")), variableSize}, 6139 types.TimeFamily: {unsafe.Sizeof(DTime(0)), fixedSize}, 6140 types.TimeTZFamily: {unsafe.Sizeof(DTimeTZ{}), fixedSize}, 6141 types.TimestampFamily: {unsafe.Sizeof(DTimestamp{}), fixedSize}, 6142 types.TimestampTZFamily: {unsafe.Sizeof(DTimestampTZ{}), fixedSize}, 6143 types.TSQueryFamily: {unsafe.Sizeof(DTSQuery{}), variableSize}, 6144 types.TSVectorFamily: {unsafe.Sizeof(DTSVector{}), variableSize}, 6145 types.IntervalFamily: {unsafe.Sizeof(DInterval{}), fixedSize}, 6146 types.JsonFamily: {unsafe.Sizeof(DJSON{}), variableSize}, 6147 types.UuidFamily: {unsafe.Sizeof(DUuid{}), fixedSize}, 6148 types.INetFamily: {unsafe.Sizeof(DIPAddr{}), fixedSize}, 6149 types.OidFamily: {unsafe.Sizeof(DOid{}.Oid), fixedSize}, 6150 types.EnumFamily: {unsafe.Sizeof(DEnum{}), variableSize}, 6151 6152 types.VoidFamily: {sz: unsafe.Sizeof(DVoid{}), variable: fixedSize}, 6153 // TODO(jordan,justin): This seems suspicious. 6154 types.ArrayFamily: {unsafe.Sizeof(DString("")), variableSize}, 6155 6156 // TODO(jordan,justin): This seems suspicious. 6157 types.AnyFamily: {unsafe.Sizeof(DString("")), variableSize}, 6158 } 6159 6160 // MaxDistinctCount returns the maximum number of distinct values between the 6161 // given datums (inclusive). This is possible if: 6162 // 6163 // a. the types of the datums are equivalent and countable, or 6164 // b. the datums have the same value (in which case the distinct count is 1). 6165 // 6166 // If neither of these conditions hold, MaxDistinctCount returns ok=false. 6167 // Additionally, it must be the case that first <= last, otherwise 6168 // MaxDistinctCount returns ok=false. 6169 func MaxDistinctCount(evalCtx CompareContext, first, last Datum) (_ int64, ok bool) { 6170 if !first.ResolvedType().Equivalent(last.ResolvedType()) { 6171 // The datums must be of the same type. 6172 return 0, false 6173 } 6174 if first.Compare(evalCtx, last) == 0 { 6175 // If the datums are equal, the distinct count is 1. 6176 return 1, true 6177 } 6178 6179 // If the datums are a countable type, return the distinct count between them. 6180 var start, end int64 6181 6182 switch t := first.(type) { 6183 case *DInt: 6184 otherDInt, otherOk := AsDInt(last) 6185 if otherOk { 6186 start = int64(*t) 6187 end = int64(otherDInt) 6188 } 6189 6190 case *DOid: 6191 otherDOid, otherOk := AsDOid(last) 6192 if otherOk { 6193 start = int64(t.Oid) 6194 end = int64(otherDOid.Oid) 6195 } 6196 6197 case *DDate: 6198 otherDDate, otherOk := last.(*DDate) 6199 if otherOk { 6200 if !t.IsFinite() || !otherDDate.IsFinite() { 6201 // One of the DDates isn't finite, so we can't extract a distinct count. 6202 return 0, false 6203 } 6204 start = int64((*t).PGEpochDays()) 6205 end = int64(otherDDate.PGEpochDays()) 6206 } 6207 6208 case *DEnum: 6209 otherDEnum, otherOk := last.(*DEnum) 6210 if otherOk { 6211 startIdx, err := t.EnumTyp.EnumGetIdxOfPhysical(t.PhysicalRep) 6212 if err != nil { 6213 panic(err) 6214 } 6215 endIdx, err := t.EnumTyp.EnumGetIdxOfPhysical(otherDEnum.PhysicalRep) 6216 if err != nil { 6217 panic(err) 6218 } 6219 start, end = int64(startIdx), int64(endIdx) 6220 } 6221 6222 case *DBool: 6223 otherDBool, otherOk := last.(*DBool) 6224 if otherOk { 6225 if *t { 6226 start = 1 6227 } 6228 if *otherDBool { 6229 end = 1 6230 } 6231 } 6232 6233 default: 6234 // Uncountable type. 6235 return 0, false 6236 } 6237 6238 if start > end { 6239 // Incorrect ordering. 6240 return 0, false 6241 } 6242 6243 delta := (end - start) + 1 6244 if delta <= 0 { 6245 // Overflow or underflow. 6246 return 0, false 6247 } 6248 return delta, true 6249 } 6250 6251 // ParsePath splits a string of the form "/foo/bar" into strings ["foo", "bar"]. 6252 // An empty string is allowed, otherwise the string must start with /. 6253 func ParsePath(str string) []string { 6254 if str == "" { 6255 return nil 6256 } 6257 if str[0] != '/' { 6258 panic(str) 6259 } 6260 return strings.Split(str, "/")[1:] 6261 } 6262 6263 // InferTypes takes a list of strings produced by ParsePath and returns a slice 6264 // of datum types inferred from the strings. Type DInt will be used if possible, 6265 // otherwise DString. For example, a vals slice ["1", "foo"] will give a types 6266 // slice [Dint, DString]. 6267 func InferTypes(vals []string) []types.Family { 6268 // Infer the datum types and populate typs accordingly. 6269 typs := make([]types.Family, len(vals)) 6270 for i := 0; i < len(vals); i++ { 6271 typ := types.IntFamily 6272 _, err := ParseDInt(vals[i]) 6273 if err != nil { 6274 typ = types.StringFamily 6275 } 6276 typs[i] = typ 6277 } 6278 return typs 6279 } 6280 6281 // AdjustValueToType checks that the width (for strings, byte arrays, and bit 6282 // strings) and scale (decimal). and, shape/srid (for geospatial types) fits the 6283 // specified column type. 6284 // 6285 // Additionally, some precision truncation may occur for the specified column type. 6286 // 6287 // In case of decimals, it can truncate fractional digits in the input 6288 // value in order to fit the target column. If the input value fits the target 6289 // column, it is returned unchanged. If the input value can be truncated to fit, 6290 // then a truncated copy is returned. Otherwise, an error is returned. 6291 // 6292 // In the case of time, it can truncate fractional digits of time datums 6293 // to its relevant rounding for the given type definition. 6294 // 6295 // In the case of geospatial types, it will check whether the SRID and Shape in the 6296 // datum matches the type definition. 6297 // 6298 // This method is used by casts and parsing. It is important to note that this 6299 // function will error if the given value is too wide for the given type. For 6300 // explicit casts and parsing, inVal should be truncated before this function is 6301 // called so that an error is not returned. For assignment casts, inVal should 6302 // not be truncated before this function is called, so that an error is 6303 // returned. The one exception for assignment casts is for the special "char" 6304 // type. An assignment cast to "char" does not error and truncates a value if 6305 // the width of the value is wider than a single character. For this exception, 6306 // AdjustValueToType performs the truncation itself. 6307 func AdjustValueToType(typ *types.T, inVal Datum) (outVal Datum, err error) { 6308 switch typ.Family() { 6309 case types.StringFamily, types.CollatedStringFamily: 6310 var sv string 6311 if v, ok := AsDString(inVal); ok { 6312 sv = string(v) 6313 } else if v, ok := inVal.(*DCollatedString); ok { 6314 sv = v.Contents 6315 } 6316 switch typ.Oid() { 6317 case oid.T_char: 6318 // "char" is supposed to truncate long values. 6319 sv = util.TruncateString(sv, 1) 6320 case oid.T_bpchar: 6321 // bpchar types truncate trailing whitespace. 6322 sv = strings.TrimRight(sv, " ") 6323 } 6324 if typ.Width() > 0 && utf8.RuneCountInString(sv) > int(typ.Width()) { 6325 return nil, pgerror.Newf(pgcode.StringDataRightTruncation, 6326 "value too long for type %s", 6327 typ.SQLString()) 6328 } 6329 6330 if typ.Oid() == oid.T_bpchar || typ.Oid() == oid.T_char { 6331 if _, ok := AsDString(inVal); ok { 6332 return NewDString(sv), nil 6333 } else if _, ok := inVal.(*DCollatedString); ok { 6334 return NewDCollatedString(sv, typ.Locale(), &CollationEnvironment{}) 6335 } 6336 } 6337 case types.IntFamily: 6338 if v, ok := AsDInt(inVal); ok { 6339 if typ.Width() == 32 || typ.Width() == 16 { 6340 // Width is defined in bits. 6341 width := uint(typ.Width() - 1) 6342 6343 // We're performing range checks in line with Go's 6344 // implementation of math.(Max|Min)(16|32) numbers that store 6345 // the boundaries of the allowed range. 6346 // NOTE: when updating the code below, make sure to update 6347 // execgen/cast_gen_util.go as well. 6348 shifted := v >> width 6349 if (v >= 0 && shifted > 0) || (v < 0 && shifted < -1) { 6350 if typ.Width() == 16 { 6351 return nil, ErrInt2OutOfRange 6352 } 6353 return nil, ErrInt4OutOfRange 6354 } 6355 } 6356 } 6357 case types.BitFamily: 6358 if v, ok := AsDBitArray(inVal); ok { 6359 if typ.Width() > 0 { 6360 bitLen := v.BitLen() 6361 switch typ.Oid() { 6362 case oid.T_varbit: 6363 if bitLen > uint(typ.Width()) { 6364 return nil, pgerror.Newf(pgcode.StringDataRightTruncation, 6365 "bit string length %d too large for type %s", bitLen, typ.SQLString()) 6366 } 6367 default: 6368 if bitLen != uint(typ.Width()) { 6369 return nil, pgerror.Newf(pgcode.StringDataLengthMismatch, 6370 "bit string length %d does not match type %s", bitLen, typ.SQLString()) 6371 } 6372 } 6373 } 6374 } 6375 case types.DecimalFamily: 6376 if inDec, ok := inVal.(*DDecimal); ok { 6377 if inDec.Form != apd.Finite || typ.Precision() == 0 { 6378 // Non-finite form or unlimited target precision, so no need to limit. 6379 break 6380 } 6381 if int64(typ.Precision()) >= inDec.NumDigits() && typ.Scale() == inDec.Exponent { 6382 // Precision and scale of target column are sufficient. 6383 break 6384 } 6385 6386 var outDec DDecimal 6387 outDec.Set(&inDec.Decimal) 6388 err := LimitDecimalWidth(&outDec.Decimal, int(typ.Precision()), int(typ.Scale())) 6389 if err != nil { 6390 return nil, errors.Wrapf(err, "type %s", typ.SQLString()) 6391 } 6392 return &outDec, nil 6393 } 6394 case types.ArrayFamily: 6395 if inArr, ok := inVal.(*DArray); ok { 6396 var outArr *DArray 6397 elementType := typ.ArrayContents() 6398 for i, inElem := range inArr.Array { 6399 outElem, err := AdjustValueToType(elementType, inElem) 6400 if err != nil { 6401 return nil, err 6402 } 6403 if outElem != inElem { 6404 if outArr == nil { 6405 outArr = &DArray{} 6406 *outArr = *inArr 6407 outArr.Array = make(Datums, len(inArr.Array)) 6408 copy(outArr.Array, inArr.Array[:i]) 6409 } 6410 } 6411 if outArr != nil { 6412 outArr.Array[i] = inElem 6413 } 6414 } 6415 if outArr != nil { 6416 return outArr, nil 6417 } 6418 } 6419 case types.TimeFamily: 6420 if in, ok := inVal.(*DTime); ok { 6421 return in.Round(TimeFamilyPrecisionToRoundDuration(typ.Precision())), nil 6422 } 6423 case types.TimestampFamily: 6424 if in, ok := inVal.(*DTimestamp); ok { 6425 return in.Round(TimeFamilyPrecisionToRoundDuration(typ.Precision())) 6426 } 6427 case types.TimestampTZFamily: 6428 if in, ok := inVal.(*DTimestampTZ); ok { 6429 return in.Round(TimeFamilyPrecisionToRoundDuration(typ.Precision())) 6430 } 6431 case types.TimeTZFamily: 6432 if in, ok := inVal.(*DTimeTZ); ok { 6433 return in.Round(TimeFamilyPrecisionToRoundDuration(typ.Precision())), nil 6434 } 6435 case types.IntervalFamily: 6436 if in, ok := inVal.(*DInterval); ok { 6437 itm, err := typ.IntervalTypeMetadata() 6438 if err != nil { 6439 return nil, err 6440 } 6441 return NewDInterval(in.Duration, itm), nil 6442 } 6443 case types.GeometryFamily: 6444 if in, ok := inVal.(*DGeometry); ok { 6445 if err := geo.SpatialObjectFitsColumnMetadata( 6446 in.Geometry.SpatialObject(), 6447 typ.InternalType.GeoMetadata.SRID, 6448 typ.InternalType.GeoMetadata.ShapeType, 6449 ); err != nil { 6450 return nil, err 6451 } 6452 } 6453 case types.GeographyFamily: 6454 if in, ok := inVal.(*DGeography); ok { 6455 if err := geo.SpatialObjectFitsColumnMetadata( 6456 in.Geography.SpatialObject(), 6457 typ.InternalType.GeoMetadata.SRID, 6458 typ.InternalType.GeoMetadata.ShapeType, 6459 ); err != nil { 6460 return nil, err 6461 } 6462 } 6463 } 6464 return inVal, nil 6465 } 6466 6467 // DatumPrev returns a datum that is "previous" to the given one. For many types 6468 // it just delegates to Datum.Prev, but for some types that don't have an 6469 // implementation of that function this method makes the best effort to come up 6470 // with a reasonable previous datum that is smaller than the given one. 6471 // 6472 // The return value is undefined if Datum.IsMin returns true or if the value is 6473 // NaN or an infinity (for floats and decimals). 6474 func DatumPrev( 6475 datum Datum, cmpCtx CompareContext, collationEnv *CollationEnvironment, 6476 ) (Datum, bool) { 6477 datum = UnwrapDOidWrapper(datum) 6478 prevString := func(s string) (string, bool) { 6479 // In order to obtain a previous string we subtract 1 from the last 6480 // non-zero byte. 6481 b := []byte(s) 6482 lastNonZeroByteIdx := len(b) - 1 6483 for ; lastNonZeroByteIdx >= 0 && b[lastNonZeroByteIdx] == 0; lastNonZeroByteIdx-- { 6484 } 6485 if lastNonZeroByteIdx < 0 { 6486 return "", false 6487 } 6488 b[lastNonZeroByteIdx]-- 6489 return string(b), true 6490 } 6491 switch d := datum.(type) { 6492 case *DDecimal: 6493 var prev DDecimal 6494 var sub apd.Decimal 6495 _, err := sub.SetFloat64(1e-6) 6496 if err != nil { 6497 return nil, false 6498 } 6499 _, err = ExactCtx.Sub(&prev.Decimal, &d.Decimal, &sub) 6500 if err != nil { 6501 return nil, false 6502 } 6503 return &prev, true 6504 case *DString: 6505 prev, ok := prevString(string(*d)) 6506 if !ok { 6507 return nil, false 6508 } 6509 return NewDString(prev), true 6510 case *DBytes: 6511 prev, ok := prevString(string(*d)) 6512 if !ok { 6513 return nil, false 6514 } 6515 return NewDBytes(DBytes(prev)), true 6516 case *DInterval: 6517 // Subtract 1ms. 6518 prev := d.Sub(duration.MakeDuration(1000000 /* nanos */, 0 /* days */, 0 /* months */)) 6519 return NewDInterval(prev, types.DefaultIntervalTypeMetadata), true 6520 default: 6521 // TODO(yuzefovich): consider adding support for other datums that don't 6522 // have Datum.Prev implementation (DCollatedString, DBitArray, 6523 // DGeography, DGeometry, DBox2D, DJSON, DArray). 6524 return datum.Prev(cmpCtx) 6525 } 6526 } 6527 6528 // DatumNext returns a datum that is "next" to the given one. For many types it 6529 // just delegates to Datum.Next, but for some types that don't have an 6530 // implementation of that function this method makes the best effort to come up 6531 // with a reasonable next datum that is greater than the given one. 6532 // 6533 // The return value is undefined if Datum.IsMax returns true or if the value is 6534 // NaN or an infinity (for floats and decimals). 6535 func DatumNext( 6536 datum Datum, cmpCtx CompareContext, collationEnv *CollationEnvironment, 6537 ) (Datum, bool) { 6538 datum = UnwrapDOidWrapper(datum) 6539 switch d := datum.(type) { 6540 case *DDecimal: 6541 var next DDecimal 6542 var add apd.Decimal 6543 _, err := add.SetFloat64(1e-6) 6544 if err != nil { 6545 return nil, false 6546 } 6547 _, err = ExactCtx.Add(&next.Decimal, &d.Decimal, &add) 6548 if err != nil { 6549 return nil, false 6550 } 6551 return &next, true 6552 case *DInterval: 6553 next := d.Add(duration.MakeDuration(1000000 /* nanos */, 0 /* days */, 0 /* months */)) 6554 return NewDInterval(next, types.DefaultIntervalTypeMetadata), true 6555 default: 6556 // TODO(yuzefovich): consider adding support for other datums that don't 6557 // have Datum.Next implementation (DCollatedString, DGeography, 6558 // DGeometry, DBox2D, DJSON). 6559 return datum.Next(cmpCtx) 6560 } 6561 }