diff --git a/CHANGELOG.md b/CHANGELOG.md index ffcc9594..a9d70ee0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# Unreleased + +## Fixes + +* Oid underlying type changed to uint32, previously it was incorrectly int32 + # 2.9.0 (August 26, 2016) ## Fixes diff --git a/messages.go b/messages.go index 053a4c13..fec34dbb 100644 --- a/messages.go +++ b/messages.go @@ -53,6 +53,10 @@ func (s *startupMessage) Bytes() (buf []byte) { return buf } +// Oid (Object Identifier Type) is, according to https://www.postgresql.org/docs/current/static/datatype-oid.html, +// used internally by PostgreSQL as a primary key for various system tables. It is currently implemented +// as an unsigned four-byte integer. Its definition can be found in src/include/postgres_ext.h +// in the PostgreSQL sources. type Oid uint32 type FieldDescription struct { @@ -140,7 +144,7 @@ func (wb *WriteBuf) WriteInt32(n int32) { func (wb *WriteBuf) WriteUint32(n uint32) { b := make([]byte, 4) - binary.BigEndian.PutUint32(b, uint32(n)) + binary.BigEndian.PutUint32(b, n) wb.buf = append(wb.buf, b...) } diff --git a/values.go b/values.go index d2c56b92..e3486bed 100644 --- a/values.go +++ b/values.go @@ -1346,19 +1346,19 @@ func decodeInt4(vr *ValueReader) int32 { func decodeOid(vr *ValueReader) Oid { if vr.Len() == -1 { vr.Fatal(ProtocolError("Cannot decode null into Oid")) - return 0 + return Oid(0) } if vr.Type().DataType != OidOid { vr.Fatal(ProtocolError(fmt.Sprintf("Cannot decode oid %v into pgx.Oid", vr.Type().DataType))) - return 0 + return Oid(0) } // Oid needs to decode text format because it is used in loadPgTypes switch vr.Type().FormatCode { case TextFormatCode: s := vr.ReadString(vr.Len()) - n, err := strconv.ParseInt(s, 10, 32) + n, err := strconv.ParseUint(s, 10, 32) if err != nil { vr.Fatal(ProtocolError(fmt.Sprintf("Received invalid Oid: %v", s))) } @@ -1366,7 +1366,7 @@ func decodeOid(vr *ValueReader) Oid { case BinaryFormatCode: if vr.Len() != 4 { vr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for an Oid: %d", vr.Len()))) - return 0 + return Oid(0) } return Oid(vr.ReadInt32()) default: @@ -1381,7 +1381,7 @@ func encodeOid(w *WriteBuf, oid Oid, value Oid) error { } w.WriteInt32(4) - w.WriteInt32(int32(value)) + w.WriteUint32(uint32(value)) return nil }