The postgresql documentation states "The oid type is currently implemented as an unsigned four-byte integer". Its C typedef in postgres_ext.h is:
typedef unsigned int Oid;
We've hit a case in our DB where a data type (hstore) in pg_type has OID 2163584298, which is below 2^32 but slightly higher than 2^31
When we do a select on a table which returns columns of that type, res.ftype( column_number ) returns a corrupted negative number
I believe the bug is in pg_result.c function pgresult_ftype:
... return INT2NUM(PQftype(result, i));
This takes the 32-bit unsigned Oid and passes it to INT2NUM which treats it as a signed int, causing the corruption.
The fix I've applied locally is very simply to call UINT2NUM instead. #ftype then returns the correct positive Oid (which is needed in rails as it joins it on data collected from pg_type)