diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java b/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java
index 86494eec49..a120c3bcdf 100644
--- a/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java
+++ b/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java
@@ -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;
@@ -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.
+ *
+ * Additional values used at runtime (including case variants) will be added to the map.
+ *
*/
- private static final HashMap typeAliases;
+ private static final ConcurrentMap TYPE_ALIASES = new ConcurrentHashMap<>(20);
static {
- typeAliases = new HashMap();
- 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")
@@ -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) {
diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataCacheTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataCacheTest.java
index 2382b6e717..78e10dc40b 100644
--- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataCacheTest.java
+++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataCacheTest.java
@@ -81,4 +81,13 @@ public void testGetTypeInfoUsesCache() throws SQLException {
List 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"));
+ }
}