diff --git a/pgtype/pgtype.go b/pgtype/pgtype.go index 50483fa7..904c99fa 100644 --- a/pgtype/pgtype.go +++ b/pgtype/pgtype.go @@ -582,6 +582,7 @@ func (scanPlanAnyTextToBytes) Scan(src []byte, dst any) error { } type scanPlanFail struct { + m *Map oid uint32 formatCode int16 } @@ -597,7 +598,14 @@ func (plan *scanPlanFail) Scan(src []byte, dst any) error { format = fmt.Sprintf("unknown %d", plan.formatCode) } - return fmt.Errorf("cannot scan OID %v in %v format into %T", plan.oid, format, dst) + var dataTypeName string + if t, ok := plan.m.oidToType[plan.oid]; ok { + dataTypeName = t.Name + } else { + dataTypeName = "unknown type" + } + + return fmt.Errorf("cannot scan %s (OID %d) in %v format into %T", dataTypeName, plan.oid, format, dst) } // TryWrapScanPlanFunc is a function that tries to create a wrapper plan for target. If successful it returns a plan @@ -1201,7 +1209,7 @@ func (m *Map) planScan(oid uint32, formatCode int16, target any) ScanPlan { return &scanPlanSQLScanner{formatCode: formatCode} } - return &scanPlanFail{oid: oid, formatCode: formatCode} + return &scanPlanFail{m: m, oid: oid, formatCode: formatCode} } func (m *Map) Scan(oid uint32, formatCode int16, src []byte, dst any) error { diff --git a/query_test.go b/query_test.go index dad93eaf..59cf9355 100644 --- a/query_test.go +++ b/query_test.go @@ -274,8 +274,8 @@ func TestRowsScanDoesNotAllowScanningBinaryFormatValuesIntoString(t *testing.T) var s string err := conn.QueryRow(context.Background(), "select point(1,2)").Scan(&s) - if err == nil || !(strings.Contains(err.Error(), "cannot scan OID 600 in binary format into *string")) { - t.Fatalf("Expected Scan to fail to encode binary value into string but: %v", err) + if err == nil || !(strings.Contains(err.Error(), "cannot scan point (OID 600) in binary format into *string")) { + t.Fatalf("Expected Scan to fail to scan binary value into string but: %v", err) } ensureConnValid(t, conn) @@ -397,7 +397,7 @@ func TestConnQueryReadWrongTypeError(t *testing.T) { t.Fatal("Expected Rows to have an error after an improper read but it didn't") } - if rows.Err().Error() != "can't scan into dest[0]: cannot scan OID 23 in binary format into *time.Time" { + if rows.Err().Error() != "can't scan into dest[0]: cannot scan int4 (OID 23) in binary format into *time.Time" { t.Fatalf("Expected different Rows.Err(): %v", rows.Err()) } @@ -983,7 +983,7 @@ func TestQueryRowErrors(t *testing.T) { }{ {"select $1::badtype", []any{"Jack"}, []any{&actual.i16}, `type "badtype" does not exist`}, {"SYNTAX ERROR", []any{}, []any{&actual.i16}, "SQLSTATE 42601"}, - {"select $1::text", []any{"Jack"}, []any{&actual.i16}, "cannot scan OID 25 in text format into *int16"}, + {"select $1::text", []any{"Jack"}, []any{&actual.i16}, "cannot scan text (OID 25) in text format into *int16"}, {"select $1::point", []any{int(705)}, []any{&actual.s}, "unable to encode 705 into binary format for point (OID 600)"}, } diff --git a/rows_test.go b/rows_test.go index 0e3bc179..cbc26887 100644 --- a/rows_test.go +++ b/rows_test.go @@ -79,7 +79,7 @@ func TestForEachRowScanError(t *testing.T) { actualResults = append(actualResults, []any{a, b}) return nil }) - require.EqualError(t, err, "can't scan into dest[0]: cannot scan OID 25 in text format into *int") + require.EqualError(t, err, "can't scan into dest[0]: cannot scan text (OID 25) in text format into *int") require.Equal(t, pgconn.CommandTag{}, ct) }) }