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

improv: type alias handling in TypeInfoCache #1986

Merged
merged 1 commit into from Dec 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check for input alias. If it is NPE it will result in NPE.

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());
davecramer marked this conversation as resolved.
Show resolved Hide resolved
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"));
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to add null as testcase.

}