From 84bbb7b732504ca1cff6152073ac0d244c6c0ce7 Mon Sep 17 00:00:00 2001 From: Nick Tobey Date: Mon, 7 Apr 2025 18:03:57 -0700 Subject: [PATCH] converting a nil value should return nil, not a panic. Most uses of `convertValue` checked if the input was nil, but `Binary.Eval` didn't. This is always the desired behavior, so just put the check here. --- enginetest/queries/queries.go | 11 ++++++++++ enginetest/scriptgen/setup/scripts/niltable | 23 +++++++++++++++++++++ enginetest/scriptgen/setup/setup_data.sg.go | 8 +++++++ sql/expression/convert.go | 3 +++ 4 files changed, 45 insertions(+) diff --git a/enginetest/queries/queries.go b/enginetest/queries/queries.go index cc9aaa28e2..e64b4a916e 100644 --- a/enginetest/queries/queries.go +++ b/enginetest/queries/queries.go @@ -5206,6 +5206,17 @@ SELECT * FROM cte WHERE d = 2;`, Query: "SELECT CAST(-3 AS DOUBLE) FROM dual", Expected: []sql.Row{{-3.0}}, }, + { + Query: "SELECT BINARY c, BINARY vc, BINARY t, BINARY b, BINARY vb, BINARY bl FROM niltexttable", + Expected: []sql.Row{ + {nil, nil, nil, nil, nil, nil}, + {[]byte("2"), nil, []byte("2"), nil, []byte("2"), nil}, + {nil, []byte("3"), []byte("3"), nil, nil, []byte("3")}, + {[]byte("4"), []byte("4"), nil, []byte("4\x00"), nil, nil}, + {nil, nil, nil, []byte("5\x00"), []byte("5"), []byte("5")}, + {[]byte("6"), []byte("6"), []byte("6"), []byte("6\x00"), []byte("6"), []byte("6")}, + }, + }, { Query: `SELECT CONVERT("-3.9876", FLOAT) FROM dual`, Expected: []sql.Row{{float32(-3.9876)}}, diff --git a/enginetest/scriptgen/setup/scripts/niltable b/enginetest/scriptgen/setup/scripts/niltable index 8ebe370c59..2ab65b016d 100644 --- a/enginetest/scriptgen/setup/scripts/niltable +++ b/enginetest/scriptgen/setup/scripts/niltable @@ -21,3 +21,26 @@ insert into niltable values exec create index niltable_i2 on niltable (i2) ---- + +exec +CREATE TABLE `niltexttable` ( + `i` bigint NOT NULL, + `c` char(2), + `vc` varchar(2), + `t` text, + `b` binary(2), + `vb` varbinary(2), + `bl` blob, + PRIMARY KEY (`i`) +) +---- + +exec +insert into niltexttable values + (1, null, null, null, null, null, null), + (2, '2', null, '2', null, '2', null), + (3, null, '3', '3', null, null, '3'), + (4, '4', '4', null, '4', null, null), + (5, null, null, null, '5', '5', '5'), + (6, '6', '6', '6', '6', '6', '6') +---- \ No newline at end of file diff --git a/enginetest/scriptgen/setup/setup_data.sg.go b/enginetest/scriptgen/setup/setup_data.sg.go index b986162c4c..b7d8c8dab9 100755 --- a/enginetest/scriptgen/setup/setup_data.sg.go +++ b/enginetest/scriptgen/setup/setup_data.sg.go @@ -3028,6 +3028,14 @@ var NiltableData = []SetupScript{{ (5,null,1,5.0), (6,6,0,6.0)`, `create index niltable_i2 on niltable (i2)`, + "CREATE TABLE `niltexttable` ( `i` bigint NOT NULL, `c` char(2), `vc` varchar(2), `t` text, `b` binary(2), `vb` varbinary(2), `bl` blob, PRIMARY KEY (`i`) )", + `insert into niltexttable values + (1, null, null, null, null, null, null), + (2, '2', null, '2', null, '2', null), + (3, null, '3', '3', null, null, '3'), + (4, '4', '4', null, '4', null, null), + (5, null, null, null, '5', '5', '5'), + (6, '6', '6', '6', '6', '6', '6')`, }} var Null_rangesData = []SetupScript{{ diff --git a/sql/expression/convert.go b/sql/expression/convert.go index f528ff2a44..022501a212 100644 --- a/sql/expression/convert.go +++ b/sql/expression/convert.go @@ -284,6 +284,9 @@ func (c *Convert) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) { // converted type where applicable (e.g. Char conversion supports only |typeLength|, Decimal conversion supports // |typeLength| and |typeScale|). func convertValue(ctx *sql.Context, val interface{}, castTo string, originType sql.Type, typeLength, typeScale int) (interface{}, error) { + if val == nil { + return nil, nil + } switch strings.ToLower(castTo) { case ConvertToBinary: b, _, err := types.LongBlob.Convert(ctx, val)