Skip to content

Commit

Permalink
improv: type alias handling in TypeInfoCache (#1986)
Browse files Browse the repository at this point in the history
populate the "real" types into the map to avoid case conversions to
check for alternate representations.
populate new mappings to optimize future use
  • Loading branch information
bokken committed Dec 30, 2020
1 parent 2c41ffc commit 0b27e26
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 16 deletions.
45 changes: 29 additions & 16 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 @@ -106,18 +108,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 @@ -666,17 +679,17 @@ public synchronized String getJavaClass(int oid) throws SQLException {
}

public String getTypeForAlias(String alias) {
String type = typeAliases.get(alias);
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 @@ -81,4 +81,13 @@ 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"));
}
}

0 comments on commit 0b27e26

Please sign in to comment.