Support sql.Scanner on renamed base type

https://github.com/jackc/pgtype/issues/197
pull/1451/head
Jack Christensen 2022-12-23 14:15:45 -06:00
parent c514b2e0c3
commit d4fcd4a897
2 changed files with 27 additions and 4 deletions

View File

@ -1227,6 +1227,16 @@ func (m *Map) planScan(oid uint32, formatCode int16, target any) ScanPlan {
}
}
// This needs to happen before trying m.TryWrapScanPlanFuncs. Otherwise, a sql.Scanner would not get called if it was
// defined on a type that could be unwrapped such as `type myString string`.
//
// https://github.com/jackc/pgtype/issues/197
if dt == nil {
if _, ok := target.(sql.Scanner); ok {
return &scanPlanSQLScanner{formatCode: formatCode}
}
}
for _, f := range m.TryWrapScanPlanFuncs {
if wrapperPlan, nextDst, ok := f(target); ok {
if nextPlan := m.planScan(oid, formatCode, nextDst); nextPlan != nil {
@ -1248,10 +1258,6 @@ func (m *Map) planScan(oid uint32, formatCode int16, target any) ScanPlan {
}
}
if _, ok := target.(sql.Scanner); ok {
return &scanPlanSQLScanner{formatCode: formatCode}
}
return &scanPlanFail{m: m, oid: oid, formatCode: formatCode}
}

View File

@ -223,6 +223,23 @@ func TestMapScanUnknownOIDIntoSQLScanner(t *testing.T) {
assert.False(t, s.Valid)
}
type scannerString string
func (ss *scannerString) Scan(v any) error {
*ss = scannerString("scanned")
return nil
}
// https://github.com/jackc/pgtype/issues/197
func TestMapScanUnregisteredOIDIntoRenamedStringSQLScanner(t *testing.T) {
m := pgtype.NewMap()
var s scannerString
err := m.Scan(unregisteredOID, pgx.TextFormatCode, []byte(nil), &s)
assert.NoError(t, err)
assert.Equal(t, "scanned", string(s))
}
type pgCustomInt int64
func (ci *pgCustomInt) Scan(src interface{}) error {