Regression: starting with v1.16.0 nil []byte values are not inserted as NULLs anymore
Reproduced with:
go version go1.18.2 darwin/arm64, modernc.org/sqlite@v1.16.0 and higher
Handling of nil byte slices (var x []byte
) changed when inserting such values in v1.16.0. Before v1.16.0 nil byte slices were inserted like NULL values, starting with v1.16.0 they are inserted as zero-sized blobs.
Consider the following test:
func TestNullColumn(t *testing.T) {
db, err := sql.Open("sqlite", ":memory:")
if err != nil {
t.Fatal(err)
}
defer db.Close()
if _, err := db.Exec(`CREATE TABLE t1(Tags TEXT)`); err != nil {
t.Fatal(err)
}
var val []byte // nil value
_, err = db.Exec(`INSERT INTO t1(Tags) VALUES(@tags)`, sql.Named("tags", val))
if err != nil {
t.Fatal(err)
}
var res sql.NullByte
if err = db.QueryRow(`SELECT Tags FROM t1 LIMIT 1`).Scan(&res); err != nil {
t.Fatal(err)
}
if res.Valid {
t.Fatalf("got non-NULL result: %v", res)
}
}
It passes on v1.15.4, but fails on v1.16.0 and higher:
¶ go get modernc.org/sqlite@v1.15.4
go: downgraded modernc.org/sqlite v1.16.0 => v1.15.4
¶ go test -run ^TestNullColumn$
PASS
ok package-name 0.403s
¶ go get modernc.org/sqlite@v1.16.0
go: upgraded modernc.org/sqlite v1.15.4 => v1.16.0
¶ go test -run ^TestNullColumn$
--- FAIL: TestNullColumn (0.00s)
err_test.go:29: sql: Scan error on column index 0, name "Tags": converting driver.Value type []uint8 ("") to a uint8: invalid syntax
FAIL
exit status 1
FAIL package-name 0.159s
If I change the test to use the on-disk database file and later inspect it with sqlite3 cli (3.38.5):
Database created on v1.15.4 has nil []byte
stored as NULL (as expected):
sqlite> select ifnull(Tags,'XXX') from t1;
ifnull(Tags,'XXX')
------------------
XXX
v1.16.0 and higher store nil []byte
as a zero-sized blob instead:
sqlite> select ifnull(Tags,'XXX') from t1;
ifnull(Tags,'XXX')
------------------
sqlite> select typeof(Tags) from t1;
typeof(Tags)
------------
blob
sqlite> select length(Tags) from t1;
length(Tags)
------------
0