Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The method 'PgResultSet.getInt' will fail with OID values bigger than 2GB (signed 32bit int) in 'pg_type.oid' #2215

Closed
ConiKost opened this issue Jul 19, 2021 · 5 comments

Comments

@ConiKost
Copy link

ConiKost commented Jul 19, 2021

Describe the issue
If 'pg_type.oid' contains OID values, which are bigger than 2GB values (more than 32bit signed int), the method PgResultSet.getInt' will fail. Example: Caused by: org.postgresql.util.PSQLException: bad value for type int: 3539503657

This seems to be an JDBC driver problem, as the official PostgreQSL documentation states: The oid type is currently implemented as an unsigned four-byte integer. Other parts of the JDBC driver also use PgResultSet.getLong, which won't suffer from the problem. So 'PgResultSet.getInt' should be never used for getting OID, as it could fail with bigger values.

Driver Version?
42.2.23

Java Version?

OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04)
OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing)

OS Version?
Ubuntu 20.04 LTS

PostgreSQL Version?
12.7-1.pgdg20.04+1

To Reproduce
'pg_type.oid' contains OID values, which are bigger than 2GB values (more than 32bit signed int)

Expected behaviour
If OID values bigger than 32bit signed integer (2GB) are used, it should not fail.

@ConiKost
Copy link
Author

After investigation, I think, that this issue was introduced by this commit: 375cb37#diff-60f28e44064b930bbce27330687834ae571161f1c664a787b83c4e938a0a28fd

You can get those big OID values with such SQL:

SELECT t.typname,t.oid FROM pg_catalog.pg_type t
JOIN pg_catalog.pg_namespace n ON (t.typnamespace = n.oid)
WHERE n.nspname  != 'pg_toast'
AND (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) order by t.oid desc

A rewrite of the code in TypeInfoCache to use Long won't be probably easy, as there is always used 'Integer' for OID values.

@MMeent
Copy link
Contributor

MMeent commented Jul 20, 2021

First of all, sorry for that. Mostly due to surrounding code, I hadn't realized that oids are uint32 instead of int32 and the problems related to that.

Second of all, this should be fixable without changing all signatures to long, by doing oid extraction/insertion through intermediate long results, and subsequently casting int values to positive long values, such that the full oid space can be extracted from the database. I've created a PR #2217 that should fix this issue for you, could you validate that?

@ConiKost
Copy link
Author

I've created a PR #2217 that should fix this issue for you, could you validate that?

Thank you very much, I can confirm, that your patch fixes the problem.

MMeent pushed a commit to MMeent/pgjdbc that referenced this issue Jul 27, 2021
Correctly handle the non-signedness of OIDs in relation to signed java integers in the new OID-based type cache.

Previously, this would cause 'bad value for type int'-errors, now this is correctly handled both ways in this part of the code.
davecramer pushed a commit that referenced this issue Jul 29, 2021
Correctly handle the non-signedness of OIDs in relation to signed java integers in the new OID-based type cache.

Previously, this would cause 'bad value for type int'-errors, now this is correctly handled both ways in this part of the code.

Co-authored-by: Matthias van de Meent <matthias.vandemeent@cofano.nl>
davecramer added a commit to davecramer/pgjdbc that referenced this issue Jul 29, 2021
…tegers and were not being handled correctly when they exceeded the size of signed integers
davecramer added a commit that referenced this issue Jul 29, 2021
* fix: backpatch PR#2217 to fix issue #2215. OIDs are unsigned integers and were not being handled correctly when they exceeded the size of signed integers

* Underscores are not allowed in java 6
@fprochazka
Copy link

fprochazka commented Sep 14, 2021

We've also run into this issue and I'm glad to see you've already fixed it! Thank you!

I'm pasting here my error code for future reference :)

org.hibernate.engine.jdbc.spi.TypeInfo: HHH000362: Unable to retrieve type info result set : 
org.postgresql.util.PSQLException: Bad value for type int : 2776994393  

We're on AWS RDS Aurora PostgreSQL, Engine version 11.9

PostgreSQL 11.9 on x86_64-pc-linux-gnu, compiled by x86_64-pc-linux-gnu-gcc (GCC) 7.4.0, 64-bit

@davecramer
Copy link
Member

fixed with be1d4aa

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants