mirror of https://github.com/jackc/pgx.git
Fix json scan of non-string pointer to pointer
https://github.com/jackc/pgx/issues/1691pull/1693/head
parent
ef9e26a5d5
commit
d58fe2d53c
|
@ -92,6 +92,23 @@ func (JSONCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan
|
|||
switch target.(type) {
|
||||
case *string:
|
||||
return scanPlanAnyToString{}
|
||||
|
||||
case **string:
|
||||
// This is to fix **string scanning. It seems wrong to special case **string, but it's not clear what a better
|
||||
// solution would be.
|
||||
//
|
||||
// https://github.com/jackc/pgx/issues/1470 -- **string
|
||||
// https://github.com/jackc/pgx/issues/1691 -- ** anything else
|
||||
|
||||
if wrapperPlan, nextDst, ok := TryPointerPointerScanPlan(target); ok {
|
||||
if nextPlan := m.planScan(oid, format, nextDst); nextPlan != nil {
|
||||
if _, failed := nextPlan.(*scanPlanFail); !failed {
|
||||
wrapperPlan.SetNext(nextPlan)
|
||||
return wrapperPlan
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case *[]byte:
|
||||
return scanPlanJSONToByteSlice{}
|
||||
case BytesScanner:
|
||||
|
@ -104,19 +121,6 @@ func (JSONCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan
|
|||
return &scanPlanSQLScanner{formatCode: format}
|
||||
}
|
||||
|
||||
// This is to fix **string scanning. It seems wrong to special case sql.Scanner and pointer to pointer, but it's not
|
||||
// clear what a better solution would be.
|
||||
//
|
||||
// https://github.com/jackc/pgx/issues/1470
|
||||
if wrapperPlan, nextDst, ok := TryPointerPointerScanPlan(target); ok {
|
||||
if nextPlan := m.planScan(oid, format, nextDst); nextPlan != nil {
|
||||
if _, failed := nextPlan.(*scanPlanFail); !failed {
|
||||
wrapperPlan.SetNext(nextPlan)
|
||||
return wrapperPlan
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return scanPlanJSONToJSONUnmarshal{}
|
||||
}
|
||||
|
||||
|
|
|
@ -121,6 +121,32 @@ func TestJSONCodecPointerToPointerToString(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
// https://github.com/jackc/pgx/issues/1691
|
||||
func TestJSONCodecPointerToPointerToInt(t *testing.T) {
|
||||
defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||
n := 44
|
||||
p := &n
|
||||
err := conn.QueryRow(ctx, "select 'null'::jsonb").Scan(&p)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, p)
|
||||
})
|
||||
}
|
||||
|
||||
// https://github.com/jackc/pgx/issues/1691
|
||||
func TestJSONCodecPointerToPointerToStruct(t *testing.T) {
|
||||
defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||
type ImageSize struct {
|
||||
Height int `json:"height"`
|
||||
Width int `json:"width"`
|
||||
Str string `json:"str"`
|
||||
}
|
||||
is := &ImageSize{Height: 100, Width: 100, Str: "str"}
|
||||
err := conn.QueryRow(ctx, `select 'null'::jsonb`).Scan(&is)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, is)
|
||||
})
|
||||
}
|
||||
|
||||
func TestJSONCodecClearExistingValueBeforeUnmarshal(t *testing.T) {
|
||||
defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||
m := map[string]any{}
|
||||
|
|
Loading…
Reference in New Issue