From 693c7c7f7d4fa9d306af6c9ba911c26a0e62bf3c Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Sat, 11 Sep 2021 10:59:26 -0500 Subject: [PATCH] Fix NULL being lost when scanning unknown OID into sql.Scanner https://github.com/jackc/pgx/issues/1078 --- pgtype.go | 6 +++++- pgtype_test.go | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/pgtype.go b/pgtype.go index 4a680844..200fb562 100644 --- a/pgtype.go +++ b/pgtype.go @@ -588,7 +588,11 @@ type scanPlanSQLScanner struct{} func (scanPlanSQLScanner) Scan(ci *ConnInfo, oid uint32, formatCode int16, src []byte, dst interface{}) error { scanner := dst.(sql.Scanner) - if formatCode == BinaryFormatCode { + if src == nil { + // This is necessary because interface value []byte:nil does not equal nil:nil for the binary format path and the + // text format path would be converted to empty string. + return scanner.Scan(nil) + } else if formatCode == BinaryFormatCode { return scanner.Scan(src) } else { return scanner.Scan(string(src)) diff --git a/pgtype_test.go b/pgtype_test.go index 2506e0a3..85ca55e9 100644 --- a/pgtype_test.go +++ b/pgtype_test.go @@ -2,6 +2,7 @@ package pgtype_test import ( "bytes" + "database/sql" "errors" "net" "testing" @@ -211,6 +212,16 @@ func TestConnInfoScanUnknownOIDTextFormat(t *testing.T) { assert.EqualValues(t, 123, n) } +func TestConnInfoScanUnknownOIDIntoSQLScanner(t *testing.T) { + ci := pgtype.NewConnInfo() + + var s sql.NullString + err := ci.Scan(0, pgx.TextFormatCode, []byte(nil), &s) + assert.NoError(t, err) + assert.Equal(t, "", s.String) + assert.False(t, s.Valid) +} + func BenchmarkConnInfoScanInt4IntoBinaryDecoder(b *testing.B) { ci := pgtype.NewConnInfo() src := []byte{0, 0, 0, 42}