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  )