github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/pgwire/pgwirebase/encoding.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 pgwirebase 12 13 import ( 14 "bufio" 15 "bytes" 16 "encoding/binary" 17 "io" 18 "math" 19 "strconv" 20 "time" 21 "unicode/utf8" 22 "unsafe" 23 24 "github.com/cockroachdb/cockroach/pkg/sql/lex" 25 "github.com/cockroachdb/cockroach/pkg/sql/oidext" 26 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 27 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 28 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 29 "github.com/cockroachdb/cockroach/pkg/sql/types" 30 "github.com/cockroachdb/cockroach/pkg/util/bitarray" 31 "github.com/cockroachdb/cockroach/pkg/util/duration" 32 "github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented" 33 "github.com/cockroachdb/cockroach/pkg/util/ipaddr" 34 "github.com/cockroachdb/cockroach/pkg/util/timeofday" 35 "github.com/cockroachdb/cockroach/pkg/util/timeutil/pgdate" 36 "github.com/cockroachdb/cockroach/pkg/util/uint128" 37 "github.com/cockroachdb/errors" 38 "github.com/jackc/pgx/pgtype" 39 "github.com/lib/pq/oid" 40 ) 41 42 const maxMessageSize = 1 << 24 43 44 // FormatCode represents a pgwire data format. 45 // 46 //go:generate stringer -type=FormatCode 47 type FormatCode uint16 48 49 const ( 50 // FormatText is the default, text format. 51 FormatText FormatCode = 0 52 // FormatBinary is an alternative, binary, encoding. 53 FormatBinary FormatCode = 1 54 ) 55 56 var _ BufferedReader = &bufio.Reader{} 57 var _ BufferedReader = &bytes.Buffer{} 58 59 // BufferedReader extended io.Reader with some convenience methods. 60 type BufferedReader interface { 61 io.Reader 62 ReadString(delim byte) (string, error) 63 ReadByte() (byte, error) 64 } 65 66 // ReadBuffer provides a convenient way to read pgwire protocol messages. 67 type ReadBuffer struct { 68 Msg []byte 69 tmp [4]byte 70 } 71 72 // reset sets b.Msg to exactly size, attempting to use spare capacity 73 // at the end of the existing slice when possible and allocating a new 74 // slice when necessary. 75 func (b *ReadBuffer) reset(size int) { 76 if b.Msg != nil { 77 b.Msg = b.Msg[len(b.Msg):] 78 } 79 80 if cap(b.Msg) >= size { 81 b.Msg = b.Msg[:size] 82 return 83 } 84 85 allocSize := size 86 if allocSize < 4096 { 87 allocSize = 4096 88 } 89 b.Msg = make([]byte, size, allocSize) 90 } 91 92 // ReadUntypedMsg reads a length-prefixed message. It is only used directly 93 // during the authentication phase of the protocol; readTypedMsg is used at all 94 // other times. This returns the number of bytes read and an error, if there 95 // was one. The number of bytes returned can be non-zero even with an error 96 // (e.g. if data was read but didn't validate) so that we can more accurately 97 // measure network traffic. 98 func (b *ReadBuffer) ReadUntypedMsg(rd io.Reader) (int, error) { 99 nread, err := io.ReadFull(rd, b.tmp[:]) 100 if err != nil { 101 return nread, err 102 } 103 size := int(binary.BigEndian.Uint32(b.tmp[:])) 104 // size includes itself. 105 size -= 4 106 if size > maxMessageSize || size < 0 { 107 return nread, NewProtocolViolationErrorf("message size %d out of bounds (0..%d)", 108 size, maxMessageSize) 109 } 110 111 b.reset(size) 112 n, err := io.ReadFull(rd, b.Msg) 113 return nread + n, err 114 } 115 116 // ReadTypedMsg reads a message from the provided reader, returning its type code and body. 117 // It returns the message type, number of bytes read, and an error if there was one. 118 func (b *ReadBuffer) ReadTypedMsg(rd BufferedReader) (ClientMessageType, int, error) { 119 typ, err := rd.ReadByte() 120 if err != nil { 121 return 0, 0, err 122 } 123 n, err := b.ReadUntypedMsg(rd) 124 return ClientMessageType(typ), n, err 125 } 126 127 // GetString reads a null-terminated string. 128 func (b *ReadBuffer) GetString() (string, error) { 129 pos := bytes.IndexByte(b.Msg, 0) 130 if pos == -1 { 131 return "", NewProtocolViolationErrorf("NUL terminator not found") 132 } 133 // Note: this is a conversion from a byte slice to a string which avoids 134 // allocation and copying. It is safe because we never reuse the bytes in our 135 // read buffer. It is effectively the same as: "s := string(b.Msg[:pos])" 136 s := b.Msg[:pos] 137 b.Msg = b.Msg[pos+1:] 138 return *((*string)(unsafe.Pointer(&s))), nil 139 } 140 141 // GetPrepareType returns the buffer's contents as a PrepareType. 142 func (b *ReadBuffer) GetPrepareType() (PrepareType, error) { 143 v, err := b.GetBytes(1) 144 if err != nil { 145 return 0, err 146 } 147 return PrepareType(v[0]), nil 148 } 149 150 // GetBytes returns the buffer's contents as a []byte. 151 func (b *ReadBuffer) GetBytes(n int) ([]byte, error) { 152 if len(b.Msg) < n { 153 return nil, NewProtocolViolationErrorf("insufficient data: %d", len(b.Msg)) 154 } 155 v := b.Msg[:n] 156 b.Msg = b.Msg[n:] 157 return v, nil 158 } 159 160 // GetUint16 returns the buffer's contents as a uint16. 161 func (b *ReadBuffer) GetUint16() (uint16, error) { 162 if len(b.Msg) < 2 { 163 return 0, NewProtocolViolationErrorf("insufficient data: %d", len(b.Msg)) 164 } 165 v := binary.BigEndian.Uint16(b.Msg[:2]) 166 b.Msg = b.Msg[2:] 167 return v, nil 168 } 169 170 // GetUint32 returns the buffer's contents as a uint32. 171 func (b *ReadBuffer) GetUint32() (uint32, error) { 172 if len(b.Msg) < 4 { 173 return 0, NewProtocolViolationErrorf("insufficient data: %d", len(b.Msg)) 174 } 175 v := binary.BigEndian.Uint32(b.Msg[:4]) 176 b.Msg = b.Msg[4:] 177 return v, nil 178 } 179 180 // NewUnrecognizedMsgTypeErr creates an error for an unrecognized pgwire 181 // message. 182 func NewUnrecognizedMsgTypeErr(typ ClientMessageType) error { 183 return NewProtocolViolationErrorf("unrecognized client message type %v", typ) 184 } 185 186 // NewProtocolViolationErrorf creates a pgwire ProtocolViolationError. 187 func NewProtocolViolationErrorf(format string, args ...interface{}) error { 188 return pgerror.Newf(pgcode.ProtocolViolation, format, args...) 189 } 190 191 // NewInvalidBinaryRepresentationErrorf creates a pgwire InvalidBinaryRepresentation. 192 func NewInvalidBinaryRepresentationErrorf(format string, args ...interface{}) error { 193 return pgerror.Newf(pgcode.InvalidBinaryRepresentation, format, args...) 194 } 195 196 // validateArrayDimensions takes the number of dimensions and elements and 197 // returns an error if we don't support that combination. 198 func validateArrayDimensions(nDimensions int, nElements int) error { 199 switch nDimensions { 200 case 1: 201 break 202 case 0: 203 // 0-dimensional array means 0-length array: validate that. 204 if nElements == 0 { 205 break 206 } 207 fallthrough 208 default: 209 return unimplemented.NewWithIssuef(32552, 210 "%d-dimension arrays not supported; only 1-dimension", nDimensions) 211 } 212 return nil 213 } 214 215 // DecodeOidDatum decodes bytes with specified Oid and format code into 216 // a datum. If the ParseTimeContext is nil, reasonable defaults 217 // will be applied. 218 func DecodeOidDatum( 219 ctx tree.ParseTimeContext, id oid.Oid, code FormatCode, b []byte, 220 ) (tree.Datum, error) { 221 switch code { 222 case FormatText: 223 switch id { 224 case oid.T_bool: 225 t, err := strconv.ParseBool(string(b)) 226 if err != nil { 227 return nil, err 228 } 229 return tree.MakeDBool(tree.DBool(t)), nil 230 case oid.T_bit, oid.T_varbit: 231 t, err := tree.ParseDBitArray(string(b)) 232 if err != nil { 233 return nil, err 234 } 235 return t, nil 236 case oid.T_int2, oid.T_int4, oid.T_int8: 237 i, err := strconv.ParseInt(string(b), 10, 64) 238 if err != nil { 239 return nil, err 240 } 241 return tree.NewDInt(tree.DInt(i)), nil 242 case oid.T_oid: 243 u, err := strconv.ParseUint(string(b), 10, 32) 244 if err != nil { 245 return nil, err 246 } 247 return tree.NewDOid(tree.DInt(u)), nil 248 case oid.T_float4, oid.T_float8: 249 f, err := strconv.ParseFloat(string(b), 64) 250 if err != nil { 251 return nil, err 252 } 253 return tree.NewDFloat(tree.DFloat(f)), nil 254 case oidext.T_geography: 255 d, err := tree.ParseDGeography(string(b)) 256 if err != nil { 257 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as geography", b) 258 } 259 return d, nil 260 case oidext.T_geometry: 261 d, err := tree.ParseDGeometry(string(b)) 262 if err != nil { 263 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as geometry", b) 264 } 265 return d, nil 266 case oid.T_numeric: 267 d, err := tree.ParseDDecimal(string(b)) 268 if err != nil { 269 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as decimal", b) 270 } 271 return d, nil 272 case oid.T_bytea: 273 res, err := lex.DecodeRawBytesToByteArrayAuto(b) 274 if err != nil { 275 return nil, err 276 } 277 return tree.NewDBytes(tree.DBytes(res)), nil 278 case oid.T_timestamp: 279 d, err := tree.ParseDTimestamp(ctx, string(b), time.Microsecond) 280 if err != nil { 281 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as timestamp", b) 282 } 283 return d, nil 284 case oid.T_timestamptz: 285 d, err := tree.ParseDTimestampTZ(ctx, string(b), time.Microsecond) 286 if err != nil { 287 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as timestamptz", b) 288 } 289 return d, nil 290 case oid.T_date: 291 d, err := tree.ParseDDate(ctx, string(b)) 292 if err != nil { 293 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as date", b) 294 } 295 return d, nil 296 case oid.T_time: 297 d, err := tree.ParseDTime(nil, string(b), time.Microsecond) 298 if err != nil { 299 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as time", b) 300 } 301 return d, nil 302 case oid.T_timetz: 303 d, err := tree.ParseDTimeTZ(ctx, string(b), time.Microsecond) 304 if err != nil { 305 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as timetz", b) 306 } 307 return d, nil 308 case oid.T_interval: 309 d, err := tree.ParseDInterval(string(b)) 310 if err != nil { 311 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as interval", b) 312 } 313 return d, nil 314 case oid.T_uuid: 315 d, err := tree.ParseDUuidFromString(string(b)) 316 if err != nil { 317 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as uuid", b) 318 } 319 return d, nil 320 case oid.T_inet: 321 d, err := tree.ParseDIPAddrFromINetString(string(b)) 322 if err != nil { 323 return nil, pgerror.Newf(pgcode.Syntax, 324 "could not parse string %q as inet", b) 325 } 326 return d, nil 327 case oid.T__int2, oid.T__int4, oid.T__int8: 328 var arr pgtype.Int8Array 329 if err := arr.DecodeText(nil, b); err != nil { 330 return nil, pgerror.Wrapf(err, pgcode.Syntax, 331 "could not parse string %q as int array", b) 332 } 333 if arr.Status != pgtype.Present { 334 return tree.DNull, nil 335 } 336 if err := validateArrayDimensions(len(arr.Dimensions), len(arr.Elements)); err != nil { 337 return nil, err 338 } 339 out := tree.NewDArray(types.Int) 340 var d tree.Datum 341 for _, v := range arr.Elements { 342 if v.Status != pgtype.Present { 343 d = tree.DNull 344 } else { 345 d = tree.NewDInt(tree.DInt(v.Int)) 346 } 347 if err := out.Append(d); err != nil { 348 return nil, err 349 } 350 } 351 return out, nil 352 case oid.T__text, oid.T__name: 353 var arr pgtype.TextArray 354 if err := arr.DecodeText(nil, b); err != nil { 355 return nil, pgerror.Wrapf(err, pgcode.Syntax, 356 "could not parse string %q as text array", b) 357 } 358 if arr.Status != pgtype.Present { 359 return tree.DNull, nil 360 } 361 if err := validateArrayDimensions(len(arr.Dimensions), len(arr.Elements)); err != nil { 362 return nil, err 363 } 364 out := tree.NewDArray(types.String) 365 if id == oid.T__name { 366 out.ParamTyp = types.Name 367 } 368 var d tree.Datum 369 for _, v := range arr.Elements { 370 if v.Status != pgtype.Present { 371 d = tree.DNull 372 } else { 373 d = tree.NewDString(v.String) 374 if id == oid.T__name { 375 d = tree.NewDNameFromDString(d.(*tree.DString)) 376 } 377 } 378 if err := out.Append(d); err != nil { 379 return nil, err 380 } 381 } 382 return out, nil 383 case oid.T_jsonb: 384 if err := validateStringBytes(b); err != nil { 385 return nil, err 386 } 387 return tree.ParseDJSON(string(b)) 388 } 389 if _, ok := types.ArrayOids[id]; ok { 390 // Arrays come in in their string form, so we parse them as such and later 391 // convert them to their actual datum form. 392 if err := validateStringBytes(b); err != nil { 393 return nil, err 394 } 395 return tree.NewDString(string(b)), nil 396 } 397 case FormatBinary: 398 switch id { 399 case oid.T_bool: 400 if len(b) > 0 { 401 switch b[0] { 402 case 0: 403 return tree.MakeDBool(false), nil 404 case 1: 405 return tree.MakeDBool(true), nil 406 } 407 } 408 return nil, pgerror.Newf(pgcode.Syntax, "unsupported binary bool: %x", b) 409 case oid.T_int2: 410 if len(b) < 2 { 411 return nil, pgerror.Newf(pgcode.Syntax, "int2 requires 2 bytes for binary format") 412 } 413 i := int16(binary.BigEndian.Uint16(b)) 414 return tree.NewDInt(tree.DInt(i)), nil 415 case oid.T_int4: 416 if len(b) < 4 { 417 return nil, pgerror.Newf(pgcode.Syntax, "int4 requires 4 bytes for binary format") 418 } 419 i := int32(binary.BigEndian.Uint32(b)) 420 return tree.NewDInt(tree.DInt(i)), nil 421 case oid.T_int8: 422 if len(b) < 8 { 423 return nil, pgerror.Newf(pgcode.Syntax, "int8 requires 8 bytes for binary format") 424 } 425 i := int64(binary.BigEndian.Uint64(b)) 426 return tree.NewDInt(tree.DInt(i)), nil 427 case oid.T_oid: 428 if len(b) < 4 { 429 return nil, pgerror.Newf(pgcode.Syntax, "oid requires 4 bytes for binary format") 430 } 431 u := binary.BigEndian.Uint32(b) 432 return tree.NewDOid(tree.DInt(u)), nil 433 case oid.T_float4: 434 if len(b) < 4 { 435 return nil, pgerror.Newf(pgcode.Syntax, "float4 requires 4 bytes for binary format") 436 } 437 f := math.Float32frombits(binary.BigEndian.Uint32(b)) 438 return tree.NewDFloat(tree.DFloat(f)), nil 439 case oid.T_float8: 440 if len(b) < 8 { 441 return nil, pgerror.Newf(pgcode.Syntax, "float8 requires 8 bytes for binary format") 442 } 443 f := math.Float64frombits(binary.BigEndian.Uint64(b)) 444 return tree.NewDFloat(tree.DFloat(f)), nil 445 case oid.T_numeric: 446 r := bytes.NewReader(b) 447 448 alloc := struct { 449 pgNum PGNumeric 450 i16 int16 451 452 dd tree.DDecimal 453 }{} 454 455 for _, ptr := range []interface{}{ 456 &alloc.pgNum.Ndigits, 457 &alloc.pgNum.Weight, 458 &alloc.pgNum.Sign, 459 &alloc.pgNum.Dscale, 460 } { 461 if err := binary.Read(r, binary.BigEndian, ptr); err != nil { 462 return nil, err 463 } 464 } 465 466 if alloc.pgNum.Ndigits > 0 { 467 decDigits := make([]byte, 0, int(alloc.pgNum.Ndigits)*PGDecDigits) 468 for i := int16(0); i < alloc.pgNum.Ndigits; i++ { 469 if err := binary.Read(r, binary.BigEndian, &alloc.i16); err != nil { 470 return nil, err 471 } 472 // Each 16-bit "digit" can represent a 4 digit number. 473 // In the case where each digit is not 4 digits, we must append 474 // padding to the beginning, i.e. 475 // * "1234" stays "1234" 476 // * "123" becomes "0123" 477 // * "12" becomes "0012" 478 // * "1" becomes "0001" 479 // * "0" becomes "0000" 480 // * "123456" becomes ["0012", "3456"] 481 // * "123456.789" becomes ["0012", "3456", "7890"] 482 // * "120123.45678" becomes ["0012", "0123", "4567", "8000"] 483 numZeroes := PGDecDigits 484 for i16 := alloc.i16; i16 > 0; i16 /= 10 { 485 numZeroes-- 486 } 487 for ; numZeroes > 0; numZeroes-- { 488 decDigits = append(decDigits, '0') 489 } 490 if alloc.i16 > 0 { 491 decDigits = strconv.AppendUint(decDigits, uint64(alloc.i16), 10) 492 } 493 } 494 495 // In the case of padding zeros at the end, we may have padded too many 496 // digits in the loop. This can be determined if the weight (defined as 497 // number of 4 digit groups left of the decimal point - 1) + the scale 498 // (total number of digits on the RHS of the decimal point) is less 499 // than the number of digits given. 500 // 501 // In Postgres, this is handled by the "remove trailing zeros" in 502 // `make_result_opt_error`, as well as `trunc_var`. 503 // Any zeroes are implicitly added back in when operating on the decimal 504 // value. 505 // 506 // Examples (with "," in the digit string for clarity): 507 // * for "1234", we have digits ["1234", "0"] for scale 0, which would 508 // make the digit string "1234,0000". For scale 0, we need to cut it back 509 // to "1234". 510 // * for "1234.0", we have digits ["1234", "0"] for scale 1, which would 511 // make the digit string "1234,0000". For scale 1, we need to cut it back 512 // to "1234.0". 513 // * for "1234.000000" we have digits ["1234", "0", "0"] with scale 6, 514 // which would make the digit string "1234,0000,0000". We need to cut it 515 // back to "1234,0000,00" for this to be correct. 516 // * for "123456.00000", we have digits ["12", "3456", "0", "0"] with 517 // scale 5, which would make digit string "0012,3456,0000,0000". We need 518 // to cut it back to "0012,3456,0000,0" for this to be correct. 519 // * for "123456.000000000", we may have digits ["12", "3456", "0", "0", "0"] 520 // with scale 5, which would make digit string "0012,3456,0000,0000". 521 // We need to cut it back to "0012,3456,0000,0" for this to be correct. 522 // 523 // This is handled by the below code, which truncates the decDigits 524 // such that it fits into the desired dscale. To do this: 525 // * ndigits [number of digits provided] - (weight+1) gives the number 526 // of digits on the RHS of the decimal place value as determined by 527 // the given input. Note dscale can be negative, meaning we truncated 528 // the leading zeroes at the front, giving a higher exponent (e.g. 0042,0000 529 // can omit the trailing 0000, giving dscale of -4, which makes the exponent 4). 530 // * if the digits we have in the buffer on the RHS, as calculated above, 531 // is larger than our calculated dscale, truncate our buffer to match the 532 // desired dscale. 533 dscale := (alloc.pgNum.Ndigits - (alloc.pgNum.Weight + 1)) * PGDecDigits 534 if overScale := dscale - alloc.pgNum.Dscale; overScale > 0 { 535 dscale -= overScale 536 decDigits = decDigits[:len(decDigits)-int(overScale)] 537 } 538 539 decString := string(decDigits) 540 if _, ok := alloc.dd.Coeff.SetString(decString, 10); !ok { 541 return nil, pgerror.Newf(pgcode.Syntax, "could not parse string %q as decimal", decString) 542 } 543 alloc.dd.Exponent = -int32(dscale) 544 } 545 546 switch alloc.pgNum.Sign { 547 case PGNumericPos: 548 case PGNumericNeg: 549 alloc.dd.Neg(&alloc.dd.Decimal) 550 case 0xc000: 551 // https://github.com/postgres/postgres/blob/ffa4cbd623dd69f9fa99e5e92426928a5782cf1a/src/backend/utils/adt/numeric.c#L169 552 return tree.ParseDDecimal("NaN") 553 default: 554 return nil, pgerror.Newf(pgcode.Syntax, "unsupported numeric sign: %d", alloc.pgNum.Sign) 555 } 556 557 return &alloc.dd, nil 558 case oid.T_bytea: 559 return tree.NewDBytes(tree.DBytes(b)), nil 560 case oid.T_timestamp: 561 if len(b) < 8 { 562 return nil, pgerror.Newf(pgcode.Syntax, "timestamp requires 8 bytes for binary format") 563 } 564 i := int64(binary.BigEndian.Uint64(b)) 565 return tree.MakeDTimestamp(pgBinaryToTime(i), time.Microsecond) 566 case oid.T_timestamptz: 567 if len(b) < 8 { 568 return nil, pgerror.Newf(pgcode.Syntax, "timestamptz requires 8 bytes for binary format") 569 } 570 i := int64(binary.BigEndian.Uint64(b)) 571 return tree.MakeDTimestampTZ(pgBinaryToTime(i), time.Microsecond) 572 case oid.T_date: 573 if len(b) < 4 { 574 return nil, pgerror.Newf(pgcode.Syntax, "date requires 4 bytes for binary format") 575 } 576 i := int32(binary.BigEndian.Uint32(b)) 577 return pgBinaryToDate(i) 578 case oid.T_time: 579 if len(b) < 8 { 580 return nil, pgerror.Newf(pgcode.Syntax, "time requires 8 bytes for binary format") 581 } 582 i := int64(binary.BigEndian.Uint64(b)) 583 return tree.MakeDTime(timeofday.TimeOfDay(i)), nil 584 case oid.T_timetz: 585 if len(b) < 12 { 586 return nil, pgerror.Newf(pgcode.Syntax, "timetz requires 12 bytes for binary format") 587 } 588 timeOfDayMicros := int64(binary.BigEndian.Uint64(b)) 589 offsetSecs := int32(binary.BigEndian.Uint32(b)) 590 return tree.NewDTimeTZFromOffset(timeofday.TimeOfDay(timeOfDayMicros), offsetSecs), nil 591 case oid.T_interval: 592 if len(b) < 16 { 593 return nil, pgerror.Newf(pgcode.Syntax, "interval requires 16 bytes for binary format") 594 } 595 nanos := (int64(binary.BigEndian.Uint64(b)) / int64(time.Nanosecond)) * int64(time.Microsecond) 596 days := int32(binary.BigEndian.Uint32(b[8:])) 597 months := int32(binary.BigEndian.Uint32(b[12:])) 598 599 duration := duration.MakeDuration(nanos, int64(days), int64(months)) 600 return &tree.DInterval{Duration: duration}, nil 601 case oid.T_uuid: 602 u, err := tree.ParseDUuidFromBytes(b) 603 if err != nil { 604 return nil, err 605 } 606 return u, nil 607 case oid.T_inet: 608 ipAddr, err := pgBinaryToIPAddr(b) 609 if err != nil { 610 return nil, err 611 } 612 return tree.NewDIPAddr(tree.DIPAddr{IPAddr: ipAddr}), nil 613 case oid.T_jsonb: 614 if len(b) < 1 { 615 return nil, NewProtocolViolationErrorf("no data to decode") 616 } 617 if b[0] != 1 { 618 return nil, NewProtocolViolationErrorf("expected JSONB version 1") 619 } 620 // Skip over the version number. 621 b = b[1:] 622 if err := validateStringBytes(b); err != nil { 623 return nil, err 624 } 625 return tree.ParseDJSON(string(b)) 626 case oid.T_varbit, oid.T_bit: 627 if len(b) < 4 { 628 return nil, NewProtocolViolationErrorf("insufficient data: %d", len(b)) 629 } 630 bitlen := binary.BigEndian.Uint32(b) 631 b = b[4:] 632 lastBitsUsed := uint64(bitlen % 64) 633 if bitlen != 0 && lastBitsUsed == 0 { 634 lastBitsUsed = 64 635 } 636 if len(b)*8 < int(bitlen) { 637 return nil, pgerror.Newf(pgcode.Syntax, "unexpected varbit bitlen %d (b: %d)", bitlen, len(b)) 638 } 639 words := make([]uint64, (len(b)+7)/8) 640 // We need two loops here. The first loop does full 8-byte decoding. The 641 // last word is not guaranteed to be a full 8 bytes, and so the second loop 642 // does manual per-byte decoding. 643 for i := 0; i < len(words)-1; i++ { 644 words[i] = binary.BigEndian.Uint64(b) 645 b = b[8:] 646 } 647 if len(words) > 0 { 648 var w uint64 649 i := uint(0) 650 for ; i < uint(lastBitsUsed); i += 8 { 651 if len(b) == 0 { 652 return nil, NewInvalidBinaryRepresentationErrorf("incorrect binary data") 653 } 654 w = (w << 8) | uint64(b[0]) 655 b = b[1:] 656 } 657 words[len(words)-1] = w << (64 - i) 658 } 659 ba, err := bitarray.FromEncodingParts(words, lastBitsUsed) 660 return &tree.DBitArray{BitArray: ba}, err 661 default: 662 if _, ok := types.ArrayOids[id]; ok { 663 innerOid := types.OidToType[id].ArrayContents().Oid() 664 return decodeBinaryArray(ctx, innerOid, b, code) 665 } 666 } 667 default: 668 return nil, errors.AssertionFailedf( 669 "unexpected format code: %d", errors.Safe(code)) 670 } 671 672 // Types with identical text/binary handling. 673 switch id { 674 case oid.T_text, oid.T_varchar, oid.T_bpchar: 675 if err := validateStringBytes(b); err != nil { 676 return nil, err 677 } 678 return tree.NewDString(string(b)), nil 679 case oid.T_name: 680 if err := validateStringBytes(b); err != nil { 681 return nil, err 682 } 683 return tree.NewDName(string(b)), nil 684 default: 685 return nil, errors.AssertionFailedf( 686 "unsupported OID %v with format code %s", errors.Safe(id), errors.Safe(code)) 687 } 688 } 689 690 // Values which are going to be converted to strings (STRING and NAME) need to 691 // be valid UTF-8 for us to accept them. 692 func validateStringBytes(b []byte) error { 693 if !utf8.Valid(b) { 694 return invalidUTF8Error 695 } 696 return nil 697 } 698 699 //PGNumericSign indicates the sign of a numeric. 700 //go:generate stringer -type=PGNumericSign 701 type PGNumericSign uint16 702 703 const ( 704 // PGNumericPos represents the + sign. 705 PGNumericPos PGNumericSign = 0x0000 706 // PGNumericNeg represents the - sign. 707 PGNumericNeg PGNumericSign = 0x4000 708 // PGNumericNan PGNumericSign = 0xC000 709 ) 710 711 // PGDecDigits represents the number of decimal digits per int16 Postgres "digit". 712 const PGDecDigits = 4 713 714 // PGNumeric represents a numeric. 715 type PGNumeric struct { 716 Ndigits, Weight, Dscale int16 717 Sign PGNumericSign 718 } 719 720 // pgBinaryToTime takes an int64 and interprets it as the Postgres binary format 721 // for a timestamp. To create a timestamp from this value, it takes the microseconds 722 // delta and adds it to PGEpochJDate. 723 func pgBinaryToTime(i int64) time.Time { 724 return duration.AddMicros(PGEpochJDate, i) 725 } 726 727 // pgBinaryToDate takes an int32 and interprets it as the Postgres binary format 728 // for a date. To create a date from this value, it takes the day delta and adds 729 // it to PGEpochJDate. 730 func pgBinaryToDate(i int32) (*tree.DDate, error) { 731 d, err := pgdate.MakeDateFromPGEpoch(i) 732 if err != nil { 733 return nil, err 734 } 735 return tree.NewDDate(d), nil 736 } 737 738 // pgBinaryToIPAddr takes an IPAddr and interprets it as the Postgres binary 739 // format. See https://github.com/postgres/postgres/blob/81c5e46c490e2426db243eada186995da5bb0ba7/src/backend/utils/adt/network.c#L144 740 // for the binary spec. 741 func pgBinaryToIPAddr(b []byte) (ipaddr.IPAddr, error) { 742 if len(b) < 4 { 743 return ipaddr.IPAddr{}, NewProtocolViolationErrorf("insufficient data: %d", len(b)) 744 } 745 746 mask := b[1] 747 familyByte := b[0] 748 var addr ipaddr.Addr 749 var family ipaddr.IPFamily 750 b = b[4:] 751 752 if familyByte == PGBinaryIPv4family { 753 family = ipaddr.IPv4family 754 } else if familyByte == PGBinaryIPv6family { 755 family = ipaddr.IPv6family 756 } else { 757 return ipaddr.IPAddr{}, NewInvalidBinaryRepresentationErrorf("unknown family received: %d", familyByte) 758 } 759 760 // Get the IP address bytes. The IP address length is byte 3 but is ignored. 761 if family == ipaddr.IPv4family { 762 if len(b) != 4 { 763 return ipaddr.IPAddr{}, NewInvalidBinaryRepresentationErrorf("unexpected data: %d", len(b)) 764 } 765 // Add the IPv4-mapped IPv6 prefix of 0xFF. 766 var tmp [16]byte 767 tmp[10] = 0xff 768 tmp[11] = 0xff 769 copy(tmp[12:], b) 770 addr = ipaddr.Addr(uint128.FromBytes(tmp[:])) 771 } else { 772 if len(b) != 16 { 773 return ipaddr.IPAddr{}, NewInvalidBinaryRepresentationErrorf("unexpected data: %d", len(b)) 774 } 775 addr = ipaddr.Addr(uint128.FromBytes(b)) 776 } 777 778 return ipaddr.IPAddr{ 779 Family: family, 780 Mask: mask, 781 Addr: addr, 782 }, nil 783 } 784 785 func decodeBinaryArray( 786 ctx tree.ParseTimeContext, elemOid oid.Oid, b []byte, code FormatCode, 787 ) (tree.Datum, error) { 788 var hdr struct { 789 Ndims int32 790 // Nullflag 791 _ int32 792 ElemOid int32 793 } 794 var dim struct { 795 // The next two fields should be arrays of size Ndims. However, since 796 // we only support 1-dimensional arrays for now, for convenience we can 797 // leave them in this struct as such for `binary.Read` to parse for us. 798 DimSize int32 799 // Dim lower bound 800 _ int32 801 } 802 r := bytes.NewBuffer(b) 803 if err := binary.Read(r, binary.BigEndian, &hdr); err != nil { 804 return nil, err 805 } 806 if elemOid != oid.Oid(hdr.ElemOid) { 807 return nil, pgerror.Newf(pgcode.DatatypeMismatch, "wrong element type") 808 } 809 arr := tree.NewDArray(types.OidToType[elemOid]) 810 if hdr.Ndims == 0 { 811 return arr, nil 812 } 813 if err := binary.Read(r, binary.BigEndian, &dim); err != nil { 814 return nil, err 815 } 816 if err := validateArrayDimensions(int(hdr.Ndims), int(dim.DimSize)); err != nil { 817 return nil, err 818 } 819 var vlen int32 820 for i := int32(0); i < dim.DimSize; i++ { 821 if err := binary.Read(r, binary.BigEndian, &vlen); err != nil { 822 return nil, err 823 } 824 if vlen < 0 { 825 if err := arr.Append(tree.DNull); err != nil { 826 return nil, err 827 } 828 continue 829 } 830 buf := r.Next(int(vlen)) 831 elem, err := DecodeOidDatum(ctx, elemOid, code, buf) 832 if err != nil { 833 return nil, err 834 } 835 if err := arr.Append(elem); err != nil { 836 return nil, err 837 } 838 } 839 return arr, nil 840 } 841 842 var invalidUTF8Error = pgerror.Newf(pgcode.CharacterNotInRepertoire, "invalid UTF-8 sequence") 843 844 var ( 845 // PGEpochJDate represents the pg epoch. 846 PGEpochJDate = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC) 847 ) 848 849 const ( 850 // PGBinaryIPv4family is the pgwire constant for IPv4. It is defined as 851 // AF_INET. 852 PGBinaryIPv4family byte = 2 853 // PGBinaryIPv6family is the pgwire constant for IPv4. It is defined as 854 // AF_NET + 1. 855 PGBinaryIPv6family byte = 3 856 )