Message-ID: From: "beikov (@beikov)" To: "pgjdbc/pgjdbc" Date: Thu, 30 Nov 2023 19:19:56 +0000 Subject: Re: [pgjdbc/pgjdbc] issue #3049: TypeInfoCache should be clearable/resetable In-Reply-To: References: List-Id: X-GitHub-Author-Login: beikov X-GitHub-Comment-Id: 1834407304 X-GitHub-Comment-Type: issue_comment X-GitHub-Edited-At: 2023-11-30T19:20:11Z X-GitHub-Issue: 3049 X-GitHub-Repo: pgjdbc/pgjdbc X-GitHub-Type: comment X-GitHub-Url: https://github.com/pgjdbc/pgjdbc/issues/3049#issuecomment-1834407304 Content-Type: text/plain; charset=utf-8 In case anyone else runs into the same issue, here is the code I'm using to clear the cache: ```java final Class pgConnection = Class.forName( "org.postgresql.jdbc.PgConnection" ); final Object connection = c.unwrap( pgConnection ); final Object typeInfo = pgConnection.getMethod( "getTypeInfo" ).invoke( connection ); final Class typeInfoCacheClass = Class.forName( "org.postgresql.jdbc.TypeInfoCache" ); final Field oidToPgNameField = typeInfoCacheClass.getDeclaredField( "oidToPgName" ); final Field pgNameToOidField = typeInfoCacheClass.getDeclaredField( "pgNameToOid" ); final Field pgNameToSQLTypeField = typeInfoCacheClass.getDeclaredField( "pgNameToSQLType" ); final Field oidToSQLTypeField = typeInfoCacheClass.getDeclaredField( "oidToSQLType" ); oidToPgNameField.setAccessible( true ); pgNameToOidField.setAccessible( true ); pgNameToSQLTypeField.setAccessible( true ); oidToSQLTypeField.setAccessible( true ); //noinspection unchecked final Map oidToPgName = (Map) oidToPgNameField.get( typeInfo ); //noinspection unchecked final Map pgNameToOid = (Map) pgNameToOidField.get( typeInfo ); //noinspection unchecked final Map pgNameToSQLType = (Map) pgNameToSQLTypeField.get( typeInfo ); //noinspection unchecked final Map oidToSQLType = (Map) oidToSQLTypeField.get( typeInfo ); for ( Iterator> iter = pgNameToOid.entrySet().iterator(); iter.hasNext(); ) { Map.Entry entry = iter.next(); final String typeName = entry.getKey(); if ( !PGJDBC_STANDARD_TYPE_NAMES.contains( typeName ) ) { final Integer oid = entry.getValue(); oidToPgName.remove( oid ); oidToSQLType.remove( oid ); pgNameToSQLType.remove( typeName ); iter.remove(); } } ``` with this utility: ```java private static final Set PGJDBC_STANDARD_TYPE_NAMES = buildTypeNames( Set.of( "int2", "int4", "oid", "int8", "money", "numeric", "float4", "float8", "char", "bpchar", "varchar", "text", "name", "bytea", "bool", "bit", "date", "time", "timetz", "timestamp", "timestamptz", "refcursor", "json", "jsonb", "box", "point", "uuid", "xml" ) ); private static Set buildTypeNames(Set baseTypeNames) { final HashSet typeNames = new HashSet<>( baseTypeNames.size() * 3 ); for ( String baseTypeName : baseTypeNames ) { typeNames.add( baseTypeName ); typeNames.add( "_" + baseTypeName ); typeNames.add( baseTypeName + "[]" ); } return typeNames; } ```