@@ -1173,12 +1173,12 @@ func TestConnQueryDatabaseSQLDriverValuerWithAutoGeneratedPointerReceiver(t *tes
1173
1173
ensureConnValid (t , conn )
1174
1174
}
1175
1175
1176
- type nilAsEmptyJSONObject struct {
1176
+ type nilPointerAsEmptyJSONObject struct {
1177
1177
ID string
1178
1178
Name string
1179
1179
}
1180
1180
1181
- func (v * nilAsEmptyJSONObject ) Value () (driver.Value , error ) {
1181
+ func (v * nilPointerAsEmptyJSONObject ) Value () (driver.Value , error ) {
1182
1182
if v == nil {
1183
1183
return "{}" , nil
1184
1184
}
@@ -1187,15 +1187,15 @@ func (v *nilAsEmptyJSONObject) Value() (driver.Value, error) {
1187
1187
}
1188
1188
1189
1189
// https://github.com/jackc/pgx/issues/1566
1190
- func TestConnQueryDatabaseSQLDriverValuerCalledOnPointerImplementers (t * testing.T ) {
1190
+ func TestConnQueryDatabaseSQLDriverValuerCalledOnNilPointerImplementers (t * testing.T ) {
1191
1191
t .Parallel ()
1192
1192
1193
1193
conn := mustConnectString (t , os .Getenv ("PGX_TEST_DATABASE" ))
1194
1194
defer closeConn (t , conn )
1195
1195
1196
1196
mustExec (t , conn , "create temporary table t(v json not null)" )
1197
1197
1198
- var v * nilAsEmptyJSONObject
1198
+ var v * nilPointerAsEmptyJSONObject
1199
1199
commandTag , err := conn .Exec (context .Background (), `insert into t(v) values($1)` , v )
1200
1200
require .NoError (t , err )
1201
1201
require .Equal (t , "INSERT 0 1" , commandTag .String ())
@@ -1208,12 +1208,119 @@ func TestConnQueryDatabaseSQLDriverValuerCalledOnPointerImplementers(t *testing.
1208
1208
_ , err = conn .Exec (context .Background (), `delete from t` )
1209
1209
require .NoError (t , err )
1210
1210
1211
- v = & nilAsEmptyJSONObject {ID : "1" , Name : "foo" }
1211
+ v = & nilPointerAsEmptyJSONObject {ID : "1" , Name : "foo" }
1212
1212
commandTag , err = conn .Exec (context .Background (), `insert into t(v) values($1)` , v )
1213
1213
require .NoError (t , err )
1214
1214
require .Equal (t , "INSERT 0 1" , commandTag .String ())
1215
1215
1216
- var v2 * nilAsEmptyJSONObject
1216
+ var v2 * nilPointerAsEmptyJSONObject
1217
+ err = conn .QueryRow (context .Background (), "select v from t" ).Scan (& v2 )
1218
+ require .NoError (t , err )
1219
+ require .Equal (t , v , v2 )
1220
+
1221
+ ensureConnValid (t , conn )
1222
+ }
1223
+
1224
+ type nilSliceAsEmptySlice []byte
1225
+
1226
+ func (j nilSliceAsEmptySlice ) Value () (driver.Value , error ) {
1227
+ if len (j ) == 0 {
1228
+ return []byte ("[]" ), nil
1229
+ }
1230
+
1231
+ return []byte (j ), nil
1232
+ }
1233
+
1234
+ func (j * nilSliceAsEmptySlice ) UnmarshalJSON (data []byte ) error {
1235
+ * j = bytes .Clone (data )
1236
+ return nil
1237
+ }
1238
+
1239
+ // https://github.com/jackc/pgx/issues/1860
1240
+ func TestConnQueryDatabaseSQLDriverValuerCalledOnNilSliceImplementers (t * testing.T ) {
1241
+ t .Parallel ()
1242
+
1243
+ conn := mustConnectString (t , os .Getenv ("PGX_TEST_DATABASE" ))
1244
+ defer closeConn (t , conn )
1245
+
1246
+ mustExec (t , conn , "create temporary table t(v json not null)" )
1247
+
1248
+ var v nilSliceAsEmptySlice
1249
+ commandTag , err := conn .Exec (context .Background (), `insert into t(v) values($1)` , v )
1250
+ require .NoError (t , err )
1251
+ require .Equal (t , "INSERT 0 1" , commandTag .String ())
1252
+
1253
+ var s string
1254
+ err = conn .QueryRow (context .Background (), "select v from t" ).Scan (& s )
1255
+ require .NoError (t , err )
1256
+ require .Equal (t , "[]" , s )
1257
+
1258
+ _ , err = conn .Exec (context .Background (), `delete from t` )
1259
+ require .NoError (t , err )
1260
+
1261
+ v = nilSliceAsEmptySlice (`{"name": "foo"}` )
1262
+ commandTag , err = conn .Exec (context .Background (), `insert into t(v) values($1)` , v )
1263
+ require .NoError (t , err )
1264
+ require .Equal (t , "INSERT 0 1" , commandTag .String ())
1265
+
1266
+ var v2 nilSliceAsEmptySlice
1267
+ err = conn .QueryRow (context .Background (), "select v from t" ).Scan (& v2 )
1268
+ require .NoError (t , err )
1269
+ require .Equal (t , v , v2 )
1270
+
1271
+ ensureConnValid (t , conn )
1272
+ }
1273
+
1274
+ type nilMapAsEmptyObject map [string ]any
1275
+
1276
+ func (j nilMapAsEmptyObject ) Value () (driver.Value , error ) {
1277
+ if j == nil {
1278
+ return []byte ("{}" ), nil
1279
+ }
1280
+
1281
+ return json .Marshal (j )
1282
+ }
1283
+
1284
+ func (j * nilMapAsEmptyObject ) UnmarshalJSON (data []byte ) error {
1285
+ var m map [string ]any
1286
+ err := json .Unmarshal (data , & m )
1287
+ if err != nil {
1288
+ return err
1289
+ }
1290
+
1291
+ * j = m
1292
+
1293
+ return nil
1294
+ }
1295
+
1296
+ // https://github.com/jackc/pgx/pull/2019#discussion_r1605806751
1297
+ func TestConnQueryDatabaseSQLDriverValuerCalledOnNilMapImplementers (t * testing.T ) {
1298
+ t .Parallel ()
1299
+
1300
+ conn := mustConnectString (t , os .Getenv ("PGX_TEST_DATABASE" ))
1301
+ defer closeConn (t , conn )
1302
+
1303
+ mustExec (t , conn , "create temporary table t(v json not null)" )
1304
+
1305
+ var v nilMapAsEmptyObject
1306
+ commandTag , err := conn .Exec (context .Background (), `insert into t(v) values($1)` , v )
1307
+ require .NoError (t , err )
1308
+ require .Equal (t , "INSERT 0 1" , commandTag .String ())
1309
+
1310
+ var s string
1311
+ err = conn .QueryRow (context .Background (), "select v from t" ).Scan (& s )
1312
+ require .NoError (t , err )
1313
+ require .Equal (t , "{}" , s )
1314
+
1315
+ _ , err = conn .Exec (context .Background (), `delete from t` )
1316
+ require .NoError (t , err )
1317
+
1318
+ v = nilMapAsEmptyObject {"name" : "foo" }
1319
+ commandTag , err = conn .Exec (context .Background (), `insert into t(v) values($1)` , v )
1320
+ require .NoError (t , err )
1321
+ require .Equal (t , "INSERT 0 1" , commandTag .String ())
1322
+
1323
+ var v2 nilMapAsEmptyObject
1217
1324
err = conn .QueryRow (context .Background (), "select v from t" ).Scan (& v2 )
1218
1325
require .NoError (t , err )
1219
1326
require .Equal (t , v , v2 )
0 commit comments