Skip to content

Commit

Permalink
fix: backpatch type alias handling in TypeInfoCache PR pgjdbc#1986
Browse files Browse the repository at this point in the history
  • Loading branch information
davecramer committed Jul 30, 2021
1 parent be1d4aa commit 1cab2f8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
50 changes: 33 additions & 17 deletions pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java
Expand Up @@ -28,6 +28,8 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -108,18 +110,29 @@ public class TypeInfoCache implements TypeInfo {
/**
* PG maps several alias to real type names. When we do queries against pg_catalog, we must use
* the real type, not an alias, so use this mapping.
* <p>
* Additional values used at runtime (including case variants) will be added to the map.
* </p>
*/
private static final HashMap<String, String> typeAliases;
private static final ConcurrentMap<String, String> TYPE_ALIASES = new ConcurrentHashMap<>(20);

static {
typeAliases = new HashMap<String, String>();
typeAliases.put("smallint", "int2");
typeAliases.put("integer", "int4");
typeAliases.put("int", "int4");
typeAliases.put("bigint", "int8");
typeAliases.put("float", "float8");
typeAliases.put("boolean", "bool");
typeAliases.put("decimal", "numeric");
TYPE_ALIASES.put("bool", "bool");
TYPE_ALIASES.put("boolean", "bool");
TYPE_ALIASES.put("smallint", "int2");
TYPE_ALIASES.put("int2", "int2");
TYPE_ALIASES.put("int", "int4");
TYPE_ALIASES.put("integer", "int4");
TYPE_ALIASES.put("int4", "int4");
TYPE_ALIASES.put("long", "int8");
TYPE_ALIASES.put("int8", "int8");
TYPE_ALIASES.put("bigint", "int8");
TYPE_ALIASES.put("float", "float4");
TYPE_ALIASES.put("float4", "float4");
TYPE_ALIASES.put("double", "float8");
TYPE_ALIASES.put("float8", "float8");
TYPE_ALIASES.put("decimal", "numeric");
TYPE_ALIASES.put("numeric", "numeric");
}

@SuppressWarnings("method.invocation.invalid")
Expand Down Expand Up @@ -667,18 +680,21 @@ public synchronized String getJavaClass(int oid) throws SQLException {
return result == null ? "java.lang.String" : result;
}

public String getTypeForAlias(String alias) {
String type = typeAliases.get(alias);
public String getTypeForAlias(@Nullable String alias) {
if (alias == null) {
return null;
}
String type = TYPE_ALIASES.get(alias);
if (type != null) {
return type;
}
if (alias.indexOf('"') == -1) {
type = typeAliases.get(alias.toLowerCase());
if (type != null) {
return type;
}
type = TYPE_ALIASES.get(alias.toLowerCase());
if (type == null) {
type = alias;
}
return alias;
//populate for future use
TYPE_ALIASES.put(alias, type);
return type;
}

public int getPrecision(int oid, int typmod) {
Expand Down
Expand Up @@ -6,6 +6,7 @@
package org.postgresql.test.jdbc2;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import org.postgresql.core.TypeInfo;
import org.postgresql.jdbc.PgConnection;
Expand Down Expand Up @@ -81,4 +82,14 @@ public void testGetTypeInfoUsesCache() throws SQLException {
List<LogRecord> typeQueries = log.getRecordsMatching(SQL_TYPE_QUERY_LOG_FILTER);
assertEquals("PgDatabaseMetadata.getTypeInfo() resulted in individual queries for SQL typecodes", 0, typeQueries.size());
}

@Test
public void testTypeForAlias() {
TypeInfo ti = con.getTypeInfo();
assertEquals("bool", ti.getTypeForAlias("boolean"));
assertEquals("bool", ti.getTypeForAlias("Boolean"));
assertEquals("bool", ti.getTypeForAlias("Bool"));
assertEquals("bogus", ti.getTypeForAlias("bogus"));
assertNull(ti.getTypeForAlias(null));
}
}

0 comments on commit 1cab2f8

Please sign in to comment.