diff --git a/pkg/sql/pgwire/types.go b/pkg/sql/pgwire/types.go index 1a0dd3a9f813..d24c4090c793 100644 --- a/pkg/sql/pgwire/types.go +++ b/pkg/sql/pgwire/types.go @@ -515,15 +515,30 @@ func writeBinaryDecimal(b *writeBuffer, v *apd.Decimal) { } } +// spaces is used for padding CHAR(N) datums. +var spaces = [16]byte{ + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', +} + func writeBinaryBytes(b *writeBuffer, v []byte, t *types.T) { - v = tree.ResolveBlankPaddedCharBytes(v, t) if t.Oid() == oid.T_char && len(v) == 0 { // Match Postgres and always explicitly include a null byte if we have // an empty string for the "char" type in the binary format. v = []byte{0} } - b.putInt32(int32(len(v))) + pad := 0 + if t.Oid() == oid.T_bpchar && len(v) < int(t.Width()) { + // Pad spaces on the right of the byte slice to make it of length + // specified in the type t. + pad = int(t.Width()) - len(v) + } + b.putInt32(int32(len(v) + pad)) b.write(v) + for pad > 0 { + n := min(pad, len(spaces)) + b.write(spaces[:n]) + pad -= n + } } func writeBinaryString(b *writeBuffer, v string, t *types.T) { diff --git a/pkg/sql/sem/tree/pgwire_encode.go b/pkg/sql/sem/tree/pgwire_encode.go index d45424afb7af..43503749f3a0 100644 --- a/pkg/sql/sem/tree/pgwire_encode.go +++ b/pkg/sql/sem/tree/pgwire_encode.go @@ -32,17 +32,6 @@ func ResolveBlankPaddedChar(s string, t *types.T) string { return s } -// ResolveBlankPaddedCharBytes is similar to ResolveBlankPaddedChar but operates -// on a slice of bytes instead of a string. -func ResolveBlankPaddedCharBytes(v []byte, t *types.T) []byte { - if t.Oid() == oid.T_bpchar && len(v) < int(t.Width()) { - // Pad spaces on the right of the byte slice to make it of length - // specified in the type t. - return append(v, bytes.Repeat([]byte(" "), int(t.Width())-len(v))...) - } - return v -} - func (d *DTuple) pgwireFormat(ctx *FmtCtx) { // When converting a tuple to text in "postgres mode" there is // special behavior: values are printed in "postgres mode" then the