Skip to content

Commit

Permalink
pgwire: reduce allocations when writing CHAR(N) datums
Browse files Browse the repository at this point in the history
`ResolveBlankPaddedCharBytes` has been replaced with a more efficient
method of padding `CHAR(N)` datums with trailing spaces.

Release note: None
  • Loading branch information
mgartner committed Oct 11, 2024
1 parent 7d88e18 commit 5fb51e4
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 13 deletions.
19 changes: 17 additions & 2 deletions pkg/sql/pgwire/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
11 changes: 0 additions & 11 deletions pkg/sql/sem/tree/pgwire_encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 5fb51e4

Please sign in to comment.