You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2015/06/03 21:51:11 UTC

incubator-calcite git commit: [CALCITE-708] Implement DatabaseMetaData.getTypeInfo (Xavier Leong)

Repository: incubator-calcite
Updated Branches:
  refs/heads/master 3e50232b6 -> 83707f720


[CALCITE-708] Implement DatabaseMetaData.getTypeInfo (Xavier Leong)


Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/83707f72
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/83707f72
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/83707f72

Branch: refs/heads/master
Commit: 83707f720b85c5e8c94426ba33f4339aa6b24350
Parents: 3e50232
Author: Xavier Leong <le...@persistent.my>
Authored: Thu May 14 18:30:33 2015 +0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Tue Jun 2 17:16:15 2015 -0700

----------------------------------------------------------------------
 .../apache/calcite/avatica/jdbc/JdbcMeta.java   |  7 +-
 .../calcite/avatica/RemoteDriverTest.java       | 17 +++++
 .../org/apache/calcite/avatica/MetaImpl.java    | 60 ++++++++++++++-
 .../calcite/avatica/remote/JsonService.java     |  8 ++
 .../calcite/avatica/remote/LocalService.java    |  5 ++
 .../calcite/avatica/remote/RemoteMeta.java      |  6 ++
 .../apache/calcite/avatica/remote/Service.java  | 13 +++-
 .../apache/calcite/jdbc/CalciteMetaImpl.java    | 58 +++++++++++++-
 .../calcite/rel/type/RelDataTypeSystem.java     | 12 +++
 .../calcite/rel/type/RelDataTypeSystemImpl.java | 80 ++++++++++++++++++--
 .../apache/calcite/sql/type/BasicSqlType.java   | 40 +---------
 .../calcite/jdbc/CalciteRemoteDriverTest.java   | 16 ++++
 .../org/apache/calcite/test/CalciteAssert.java  |  2 +-
 13 files changed, 274 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
index e574fe6..cbaab45 100644
--- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
+++ b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
@@ -527,7 +527,12 @@ public class JdbcMeta implements Meta {
   }
 
   public MetaResultSet getTypeInfo() {
-    return null;
+    try {
+      return JdbcResultSet.create(DEFAULT_CONN_ID, -1,
+          connection.getMetaData().getTypeInfo());
+    } catch (SQLException e) {
+      throw new RuntimeException(e);
+    }
   }
 
   public MetaResultSet getIndexInfo(String catalog, String schema, String table,

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
----------------------------------------------------------------------
diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
index 21989ed..2e0f04b 100644
--- a/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
+++ b/avatica-server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
@@ -177,6 +177,23 @@ public class RemoteDriverTest {
     connection.close();
   }
 
+  @Test public void testTypeInfo() throws Exception {
+    final Connection connection = ljs();
+    final ResultSet resultSet =
+        connection.getMetaData().getTypeInfo();
+    assertTrue(resultSet.next());
+    final ResultSetMetaData metaData = resultSet.getMetaData();
+    assertTrue(metaData.getColumnCount() >= 18);
+    assertEquals("TYPE_NAME", metaData.getColumnName(1));
+    assertEquals("DATA_TYPE", metaData.getColumnName(2));
+    assertEquals("PRECISION", metaData.getColumnName(3));
+    assertEquals("SQL_DATA_TYPE", metaData.getColumnName(16));
+    assertEquals("SQL_DATETIME_SUB", metaData.getColumnName(17));
+    assertEquals("NUM_PREC_RADIX", metaData.getColumnName(18));
+    resultSet.close();
+    connection.close();
+  }
+
   @Ignore
   @Test public void testNoFactory() throws Exception {
     final Connection connection =

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java b/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
index fe1687c..223830d 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/MetaImpl.java
@@ -325,6 +325,8 @@ public abstract class MetaImpl implements Meta {
     }
   }
 
+  /** Metadata describing a TypeInfo. */
+
   /** Metadata describing a table. */
   public static class MetaTable implements Named {
     public final String tableCat;
@@ -471,7 +473,63 @@ public abstract class MetaImpl implements Meta {
   }
 
   /** Metadata describing type info. */
-  public static class MetaTypeInfo {
+  public static class MetaTypeInfo implements Named {
+    public final String typeName;
+    public final int dataType;
+    public final int precision;
+    public final String literalPrefix;
+    public final String literalSuffix;
+    //TODO: Add create parameter for type on DDL
+    public final String createParams = null;
+    public final int nullable;
+    public final boolean caseSensitive;
+    public final int searchable;
+    public final boolean unsignedAttribute;
+    public final boolean fixedPrecScale;
+    public final boolean autoIncrement;
+    public final String localTypeName;
+    public final int minimumScale;
+    public final int maximumScale;
+    public final int sqlDataType = 0;
+    public final int sqlDatetimeSub = 0;
+    public final Integer numPrecRadix; //nullable int
+
+    public MetaTypeInfo(
+        String typeName,
+        int dataType,
+        int precision,
+        String literalPrefix,
+        String literalSuffix,
+        int nullable,
+        boolean caseSensitive,
+        int searchable,
+        boolean unsignedAttribute,
+        boolean fixedPrecScale,
+        boolean autoIncrement,
+        int minimumScale,
+        int maximumScale,
+        int numPrecRadix) {
+      this.typeName = typeName;
+      this.dataType = dataType;
+      this.precision = precision;
+      this.literalPrefix = literalPrefix;
+      this.literalSuffix = literalSuffix;
+      this.nullable = nullable;
+      this.caseSensitive = caseSensitive;
+      this.searchable = searchable;
+      this.unsignedAttribute = unsignedAttribute;
+      this.fixedPrecScale = fixedPrecScale;
+      this.autoIncrement = autoIncrement;
+      this.localTypeName = typeName;
+      // Make min to be 0 instead of -1
+      this.minimumScale = minimumScale == -1 ? 0 : minimumScale;
+      this.maximumScale = maximumScale == -1 ? 0 : maximumScale;
+      this.numPrecRadix = numPrecRadix == 0 ? null : numPrecRadix;
+    }
+
+    public String getName() {
+      return typeName;
+    }
   }
 
   /** Metadata describing index info. */

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
index cabd6c1..c2119db 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
@@ -186,6 +186,14 @@ public abstract class JsonService implements Service {
     }
   }
 
+  public ResultSetResponse apply(TypeInfoRequest request) {
+    try {
+      return decode(apply(encode(request)), ResultSetResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
   public ResultSetResponse apply(ColumnsRequest request) {
     try {
       return decode(apply(encode(request)), ResultSetResponse.class);

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
index 88a6d59..ae4c9d0 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
@@ -113,6 +113,11 @@ public class LocalService implements Service {
     return toResponse(resultSet);
   }
 
+  public ResultSetResponse apply(TypeInfoRequest request) {
+    final Meta.MetaResultSet resultSet = meta.getTypeInfo();
+    return toResponse(resultSet);
+  }
+
   public ResultSetResponse apply(ColumnsRequest request) {
     final Meta.MetaResultSet resultSet =
         meta.getColumns(request.catalog,

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
index a585c2f..456cf08 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
@@ -142,6 +142,12 @@ class RemoteMeta extends MetaImpl {
     return toResultSet(MetaTableType.class, response);
   }
 
+  @Override public MetaResultSet getTypeInfo() {
+    final Service.ResultSetResponse response =
+        service.apply(new Service.TypeInfoRequest());
+    return toResultSet(MetaTypeInfo.class, response);
+  }
+
   @Override public MetaResultSet getColumns(String catalog, Pat schemaPattern,
       Pat tableNamePattern, Pat columnNamePattern) {
     final Service.ResultSetResponse response =

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
index 8fe888e..951b34e 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
@@ -35,6 +35,7 @@ public interface Service {
   ResultSetResponse apply(SchemasRequest request);
   ResultSetResponse apply(TablesRequest request);
   ResultSetResponse apply(TableTypesRequest request);
+  ResultSetResponse apply(TypeInfoRequest request);
   ResultSetResponse apply(ColumnsRequest request);
   PrepareResponse apply(PrepareRequest request);
   ExecuteResponse apply(PrepareAndExecuteRequest request);
@@ -59,8 +60,8 @@ public interface Service {
       @JsonSubTypes.Type(value = CatalogsRequest.class, name = "getCatalogs"),
       @JsonSubTypes.Type(value = SchemasRequest.class, name = "getSchemas"),
       @JsonSubTypes.Type(value = TablesRequest.class, name = "getTables"),
-      @JsonSubTypes.Type(value = TableTypesRequest.class,
-          name = "getTableTypes"),
+      @JsonSubTypes.Type(value = TableTypesRequest.class, name = "getTableTypes"),
+      @JsonSubTypes.Type(value = TypeInfoRequest.class, name = "getTypeInfo"),
       @JsonSubTypes.Type(value = ColumnsRequest.class, name = "getColumns"),
       @JsonSubTypes.Type(value = PrepareRequest.class, name = "prepare"),
       @JsonSubTypes.Type(value = PrepareAndExecuteRequest.class,
@@ -194,6 +195,14 @@ public interface Service {
     }
   }
 
+  /** Request for
+   * {@link Meta#getTypeInfo()}. */
+  class TypeInfoRequest extends Request {
+    @Override ResultSetResponse accept(Service service) {
+      return service.apply(this);
+    }
+  }
+
   /** Response that contains a result set.
    *
    * <p>Regular result sets have {@code updateCount} -1;

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java b/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
index c2ea970..1fca967 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
@@ -38,6 +38,7 @@ import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rel.type.RelDataTypeFactoryImpl;
 import org.apache.calcite.rel.type.RelDataTypeField;
+import org.apache.calcite.rel.type.RelDataTypeSystem;
 import org.apache.calcite.runtime.FlatLists;
 import org.apache.calcite.schema.Schema;
 import org.apache.calcite.schema.SchemaPlus;
@@ -46,6 +47,7 @@ import org.apache.calcite.schema.impl.AbstractTableQueryable;
 import org.apache.calcite.server.CalciteServerStatement;
 import org.apache.calcite.sql.SqlJdbcFunctionCall;
 import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.util.Util;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -53,7 +55,6 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
-
 import java.lang.reflect.Field;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
@@ -277,6 +278,29 @@ public class CalciteMetaImpl extends MetaImpl {
         "REF_GENERATION");
   }
 
+  public MetaResultSet getTypeInfo() {
+    return createResultSet(allTypeInfo(),
+        MetaTypeInfo.class,
+        "TYPE_NAME",
+        "DATA_TYPE",
+        "PRECISION",
+        "LITERAL_PREFIX",
+        "LITERAL_SUFFIX",
+        "CREATE_PARAMS",
+        "NULLABLE",
+        "CASE_SENSITIVE",
+        "SEARCHABLE",
+        "UNSIGNED_ATTRIBUTE",
+        "FIXED_PREC_SCALE",
+        "AUTO_INCREMENT",
+        "LOCAL_TYPE_NAME",
+        "MINIMUM_SCALE",
+        "MAXIMUM_SCALE",
+        "SQL_DATA_TYPE",
+        "SQL_DATETIME_SUB",
+        "NUM_PREC_RADIX");
+  }
+
   public MetaResultSet getColumns(String catalog,
       Pat schemaPattern,
       Pat tableNamePattern,
@@ -411,6 +435,38 @@ public class CalciteMetaImpl extends MetaImpl {
             });
   }
 
+  private ImmutableList<MetaTypeInfo> getAllDefaultType() {
+    final ImmutableList.Builder<MetaTypeInfo> allTypeList =
+        new ImmutableList.Builder<>();
+    final CalciteConnectionImpl conn = (CalciteConnectionImpl) connection;
+    final RelDataTypeSystem typeSystem = conn.typeFactory.getTypeSystem();
+    for (SqlTypeName sqlTypeName : SqlTypeName.values()) {
+      allTypeList.add(
+          new MetaTypeInfo(sqlTypeName.getName(),
+              sqlTypeName.getJdbcOrdinal(),
+              typeSystem.getMaxPrecision(sqlTypeName),
+              typeSystem.getLiteral(sqlTypeName, true),
+              typeSystem.getLiteral(sqlTypeName, false),
+              // All types are nullable
+              DatabaseMetaData.typeNullable,
+              typeSystem.isCaseSensitive(sqlTypeName),
+              // Making all type searchable; we may want to
+              // be specific and declare under SqlTypeName
+              DatabaseMetaData.typeSearchable,
+              false,
+              false,
+              typeSystem.isAutoincrement(sqlTypeName),
+              sqlTypeName.getMinScale(),
+              typeSystem.getMaxScale(sqlTypeName),
+              typeSystem.getNumTypeRadix(sqlTypeName)));
+    }
+    return allTypeList.build();
+  }
+
+  protected Enumerable<MetaTypeInfo> allTypeInfo() {
+    return Linq4j.asEnumerable(getAllDefaultType());
+  }
+
   public Enumerable<MetaColumn> columns(final MetaTable table_) {
     final CalciteMetaTable table = (CalciteMetaTable) table_;
     final RelDataType rowType =

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystem.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystem.java b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystem.java
index 737a644..cddaf94 100644
--- a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystem.java
+++ b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystem.java
@@ -55,6 +55,18 @@ public interface RelDataTypeSystem {
 
   /** Returns the maximum precision of a NUMERIC or DECIMAL type. */
   int getMaxNumericPrecision();
+
+  /** Returns the LITERAL string for the type, either PREFIX/SUFFIX. */
+  String getLiteral(SqlTypeName typeName, boolean isPrefix);
+
+  /** Returns if the type is case sensitive true or not (false) */
+  boolean isCaseSensitive(SqlTypeName typeName);
+
+  /** Returns if the type can be auto increment true or not (false) */
+  boolean isAutoincrement(SqlTypeName typeName);
+
+  /** Returns the numeric type Radix, 2 or 10. 0 represent not applicable*/
+  int getNumTypeRadix(SqlTypeName typeName);
 }
 
 // End RelDataTypeSystem.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java
index ea639c0..4611b4b 100644
--- a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java
+++ b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java
@@ -16,6 +16,7 @@
  */
 package org.apache.calcite.rel.type;
 
+import org.apache.calcite.sql.type.SqlTypeFamily;
 import org.apache.calcite.sql.type.SqlTypeName;
 
 /** Default implementation of
@@ -45,23 +46,41 @@ public abstract class RelDataTypeSystemImpl implements RelDataTypeSystem {
   }
 
   public int getDefaultPrecision(SqlTypeName typeName) {
+    //Following BasicSqlType precision as the default
     switch (typeName) {
     case CHAR:
     case BINARY:
     case VARCHAR:
     case VARBINARY:
       return 1;
-    case TIME:
-      return 0;
-    case TIMESTAMP:
-      // TODO jvs 26-July-2004:  should be 6 for microseconds,
-      // but we can't support that yet
-      return 0;
     case DECIMAL:
       return getMaxNumericPrecision();
     case INTERVAL_DAY_TIME:
     case INTERVAL_YEAR_MONTH:
       return SqlTypeName.DEFAULT_INTERVAL_START_PRECISION;
+    case BOOLEAN:
+      return 1;
+    case TINYINT:
+      return 3;
+    case SMALLINT:
+      return 5;
+    case INTEGER:
+      return 10;
+    case BIGINT:
+      return 19;
+    case REAL:
+      return 7;
+    case FLOAT:
+    case DOUBLE:
+      return 15;
+    case TIME:
+    case DATE:
+      return 0; // SQL99 part 2 section 6.1 syntax rule 30
+    case TIMESTAMP:
+      // farrago supports only 0 (see
+      // SqlTypeName.getDefaultPrecision), but it should be 6
+      // (microseconds) per SQL99 part 2 section 6.1 syntax rule 30.
+      return 0;
     default:
       return -1;
     }
@@ -84,7 +103,7 @@ public abstract class RelDataTypeSystemImpl implements RelDataTypeSystem {
     case INTERVAL_YEAR_MONTH:
       return SqlTypeName.MAX_INTERVAL_START_PRECISION;
     default:
-      return -1;
+      return getDefaultPrecision(typeName);
     }
   }
 
@@ -95,6 +114,53 @@ public abstract class RelDataTypeSystemImpl implements RelDataTypeSystem {
   public int getMaxNumericPrecision() {
     return 19;
   }
+
+  public String getLiteral(SqlTypeName typeName, boolean isPrefix) {
+    switch(typeName) {
+    case VARBINARY:
+    case VARCHAR:
+    case CHAR:
+      return "'";
+    case BINARY:
+      return isPrefix ? "x'" : "'";
+    case TIMESTAMP:
+      return isPrefix ? "TIMESTAMP '" : "'";
+    case INTERVAL_DAY_TIME:
+      return isPrefix ? "INTERVAL '" : "' DAY";
+    case INTERVAL_YEAR_MONTH:
+      return isPrefix ? "INTERVAL '" : "' YEAR TO MONTH";
+    case TIME:
+      return isPrefix ? "TIME '" : "'";
+    case DATE:
+      return isPrefix ? "DATE '" : "'";
+    case ARRAY:
+      return isPrefix ? "(" : ")";
+    default:
+      return null;
+    }
+  }
+
+  public boolean isCaseSensitive(SqlTypeName typeName) {
+    switch(typeName) {
+    case CHAR:
+    case VARCHAR:
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  public boolean isAutoincrement(SqlTypeName typeName) {
+    return false;
+  }
+
+  public int getNumTypeRadix(SqlTypeName typeName) {
+    if (typeName.getFamily() == SqlTypeFamily.NUMERIC
+      && getDefaultPrecision(typeName) != -1) {
+      return 10;
+    }
+    return 0;
+  }
 }
 
 // End RelDataTypeSystemImpl.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/core/src/main/java/org/apache/calcite/sql/type/BasicSqlType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/type/BasicSqlType.java b/core/src/main/java/org/apache/calcite/sql/type/BasicSqlType.java
index 949019f..421960d 100644
--- a/core/src/main/java/org/apache/calcite/sql/type/BasicSqlType.java
+++ b/core/src/main/java/org/apache/calcite/sql/type/BasicSqlType.java
@@ -133,42 +133,7 @@ public class BasicSqlType extends AbstractSqlType {
   // implement RelDataType
   public int getPrecision() {
     if (precision == PRECISION_NOT_SPECIFIED) {
-      switch (typeName) {
-      case BOOLEAN:
-        return 1;
-      case TINYINT:
-        return 3;
-      case SMALLINT:
-        return 5;
-      case INTEGER:
-        return 10;
-      case BIGINT:
-        return 19;
-      case DECIMAL:
-        return RelDataTypeSystem.DEFAULT.getMaxNumericPrecision(); // FIXME
-      case REAL:
-        return 7;
-      case FLOAT:
-      case DOUBLE:
-        return 15;
-      case TIME:
-        return 0; // SQL99 part 2 section 6.1 syntax rule 30
-      case TIMESTAMP:
-
-        // farrago supports only 0 (see
-        // SqlTypeName.getDefaultPrecision), but it should be 6
-        // (microseconds) per SQL99 part 2 section 6.1 syntax rule 30.
-        return 0;
-      case DATE:
-        return 0;
-      case CHAR:
-      case VARCHAR:
-      case BINARY:
-      case VARBINARY:
-        return 1; // SQL2003 part 2 section 6.1 syntax rule 5
-      default:
-        // fall through
-      }
+      return typeSystem.getDefaultPrecision(typeName);
     }
     return precision;
   }
@@ -213,7 +178,8 @@ public class BasicSqlType extends AbstractSqlType {
     // since (for instance) TIME is equivalent to TIME(0).
     if (withDetail) {
       // -1 means there is no default value for precision
-      if (typeSystem.getDefaultPrecision(typeName) > -1) {
+      if (typeName.allowsPrec()
+        && typeSystem.getDefaultPrecision(typeName) > -1) {
         printPrecision = true;
       }
       if (typeName.getDefaultScale() > -1) {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/core/src/test/java/org/apache/calcite/jdbc/CalciteRemoteDriverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/jdbc/CalciteRemoteDriverTest.java b/core/src/test/java/org/apache/calcite/jdbc/CalciteRemoteDriverTest.java
index b9e09a2..c8a39f6 100644
--- a/core/src/test/java/org/apache/calcite/jdbc/CalciteRemoteDriverTest.java
+++ b/core/src/test/java/org/apache/calcite/jdbc/CalciteRemoteDriverTest.java
@@ -122,6 +122,16 @@ public class CalciteRemoteDriverTest {
           }
         }
       };
+  private static final Function<Connection, ResultSet> GET_TYPEINFO =
+      new Function<Connection, ResultSet>() {
+        public ResultSet apply(Connection input) {
+          try {
+            return input.getMetaData().getTypeInfo();
+          } catch (SQLException e) {
+            throw new RuntimeException(e);
+          }
+        }
+      };
   private static final Function<Connection, ResultSet> GET_TABLE_TYPES =
       new Function<Connection, ResultSet>() {
         public ResultSet apply(Connection input) {
@@ -249,6 +259,12 @@ public class CalciteRemoteDriverTest {
         .returns(CalciteAssert.checkResultContains("COLUMN_NAME=EMPNO"));
   }
 
+  @Test public void testRemoteTypeInfo() throws Exception {
+    CalciteAssert.hr().with(REMOTE_CONNECTION_FACTORY)
+        .metaData(GET_TYPEINFO)
+        .returns(CalciteAssert.checkResultCount(30));
+  }
+
   @Test public void testRemoteTableTypes() throws Exception {
     CalciteAssert.hr().with(REMOTE_CONNECTION_FACTORY)
         .metaData(GET_TABLE_TYPES)

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/83707f72/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
index 7a64672..39ed982 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
@@ -277,7 +277,7 @@ public class CalciteAssert {
     };
   }
 
-  static Function<ResultSet, Void> checkResultCount(final int expected) {
+  public static Function<ResultSet, Void> checkResultCount(final int expected) {
     return new Function<ResultSet, Void>() {
       public Void apply(ResultSet resultSet) {
         try {