diff --git a/buffer.go b/buffer.go index 19486bd6f..d9ae7f52e 100644 --- a/buffer.go +++ b/buffer.go @@ -37,6 +37,27 @@ func newBuffer(nc net.Conn) buffer { } } +// discard trims b.buf[:b.idx] to prohibit it reused. +// +// This is required by Rows.Close(). +// See https://github.com/golang/go/commit/651ddbdb5056ded455f47f9c494c67b389622a47 +func (b *buffer) discard() { + if len(b.buf)-b.idx >= defaultBufSize { + b.buf = b.buf[b.idx:] + b.idx = 0 + return + } + + bufSize := defaultBufSize + if bufSize < b.length { + bufSize = b.length + } + newBuf := make([]byte, bufSize) + copy(newBuf, b.buf[b.idx:b.idx+b.length]) + b.buf = newBuf + b.idx = 0 +} + // fill reads into the buffer until at least _need_ bytes are in it func (b *buffer) fill(need int) error { n := b.length diff --git a/rows.go b/rows.go index d3b1e2822..5fc6f23e4 100644 --- a/rows.go +++ b/rows.go @@ -111,6 +111,10 @@ func (rows *mysqlRows) Close() (err error) { return err } + // We can't reuse receive buffer when rows.Close() is called. + // See https://github.com/golang/go/commit/651ddbdb5056ded455f47f9c494c67b389622a47 + mc.buf.discard() + // Remove unread packets from stream if !rows.rs.done { err = mc.readUntilEOF()