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/09/04 09:35:02 UTC
[04/10] incubator-calcite git commit: [CALCITE-865] Unknown table
type causes NullPointerException in JdbcSchema
[CALCITE-865] Unknown table type causes NullPointerException in JdbcSchema
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/d69f2c20
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/d69f2c20
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/d69f2c20
Branch: refs/heads/master
Commit: d69f2c20c5a75977d50c182565d8e7b8e011515e
Parents: f98ed96
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Sep 3 15:09:32 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Sep 3 15:09:32 2015 -0700
----------------------------------------------------------------------
.../java/org/apache/calcite/avatica/Meta.java | 4 +
.../apache/calcite/adapter/jdbc/JdbcSchema.java | 6 +-
.../apache/calcite/adapter/jdbc/JdbcTable.java | 3 +-
.../java/org/apache/calcite/schema/Schema.java | 105 +++++++++++++++----
.../main/java/org/apache/calcite/util/Util.java | 22 +++-
.../apache/calcite/test/JdbcAdapterTest.java | 35 +++++++
6 files changed, 153 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/d69f2c20/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/Meta.java b/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
index d9fab4d..fe61aaf 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/Meta.java
@@ -260,6 +260,10 @@ public interface Meta {
this.s = s;
}
+ @Override public String toString() {
+ return "Pat[" + s + "]";
+ }
+
@JsonCreator
public static Pat of(@JsonProperty("s") String name) {
return new Pat(name);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/d69f2c20/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java
index 6495574..b83c76c 100644
--- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java
+++ b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcSchema.java
@@ -201,6 +201,7 @@ public class JdbcSchema implements Schema {
// returned by Phoenix among others, maps to TableType.SYSTEM_TABLE.
// We know enum constants are upper-case without spaces, so we can't
// make things worse.
+ //
// PostgreSQL returns tableTypeName==null for pg_toast* tables
// This can happen if you start JdbcSchema off a "public" PG schema
// The tables are not designed to be queried by users, however we do
@@ -210,7 +211,10 @@ public class JdbcSchema implements Schema {
? null
: tableTypeName.toUpperCase().replace(' ', '_');
final TableType tableType =
- Util.enumVal(TableType.class, tableTypeName2);
+ Util.enumVal(TableType.OTHER, tableTypeName2);
+ if (tableType == TableType.OTHER && tableTypeName2 != null) {
+ System.out.println("Unknown table type: " + tableTypeName2);
+ }
final JdbcTable table =
new JdbcTable(this, catalogName, schemaName, tableName, tableType);
builder.put(tableName, table);
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/d69f2c20/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcTable.java b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcTable.java
index fe6da60..f820c28 100644
--- a/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/jdbc/JdbcTable.java
@@ -47,6 +47,7 @@ import org.apache.calcite.util.Pair;
import org.apache.calcite.util.Util;
import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import java.sql.SQLException;
@@ -80,7 +81,7 @@ class JdbcTable extends AbstractQueryableTable
this.jdbcCatalogName = jdbcCatalogName;
this.jdbcSchemaName = jdbcSchemaName;
this.jdbcTableName = tableName;
- this.jdbcTableType = jdbcTableType;
+ this.jdbcTableType = Preconditions.checkNotNull(jdbcTableType);
}
public String toString() {
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/d69f2c20/core/src/main/java/org/apache/calcite/schema/Schema.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/schema/Schema.java b/core/src/main/java/org/apache/calcite/schema/Schema.java
index 065ec5d..6745e21 100644
--- a/core/src/main/java/org/apache/calcite/schema/Schema.java
+++ b/core/src/main/java/org/apache/calcite/schema/Schema.java
@@ -144,31 +144,30 @@ public interface Schema {
/** Table type. */
enum TableType {
- /** A regular table. */
+ /** A regular table.
+ *
+ * <p>Used by PostgreSQL, MySQL and others. */
TABLE,
/** A relation whose contents are calculated by evaluating a SQL
- * expression. */
+ * expression.
+ *
+ * <p>Used by PostgreSQL and others. */
VIEW,
- /** A table maintained by the system. Data dictionary tables, such as the
- * "TABLES" and "COLUMNS" table in the "metamodel" schema, examples of
- * system tables. */
- SYSTEM_TABLE,
-
- /** A table that is only visible to one connection. */
- LOCAL_TEMPORARY,
+ /** Foreign table.
+ *
+ * <p>Used by PostgreSQL. */
+ FOREIGN_TABLE,
- /** A structure, similar to a view, that is the basis for auto-generated
- * materializations. It is either a single table or a collection of tables
- * that are joined via many-to-one relationships from a central hub table.
- * It is not available for queries, but is just used as an intermediate
- * structure during query planning. */
- STAR,
+ /** Materialized view.
+ *
+ * <p>Used by PostgreSQL. */
+ MATERIALIZED_VIEW,
/** Index table.
*
- * <p>Used by Apache Phoenix. */
+ * <p>Used by Apache Phoenix, PostgreSQL. */
INDEX,
/** Join table.
@@ -178,12 +177,82 @@ public interface Schema {
/** Sequence table.
*
- * <p>Used by Apache Phoenix, and others. Must have a single BIGINT column
- * called "$seq". */
+ * <p>Used by Apache Phoenix, PostgreSQL and others.
+ * In Phoenix, must have a single BIGINT column called "$seq". */
SEQUENCE,
+ /** A structure, similar to a view, that is the basis for auto-generated
+ * materializations. It is either a single table or a collection of tables
+ * that are joined via many-to-one relationships from a central hub table.
+ * It is not available for queries, but is just used as an intermediate
+ * structure during query planning. */
+ STAR,
+
/** Stream. */
STREAM,
+
+ /** Type.
+ *
+ * <p>Used by PostgreSQL. */
+ TYPE,
+
+ /** A table maintained by the system. Data dictionary tables, such as the
+ * "TABLES" and "COLUMNS" table in the "metamodel" schema, examples of
+ * system tables.
+ *
+ * <p>Used by PostgreSQL, MySQL and others. */
+ SYSTEM_TABLE,
+
+ /** System view.
+ *
+ * <p>Used by PostgreSQL, MySQL. */
+ SYSTEM_VIEW,
+
+ /** System index.
+ *
+ * <p>Used by PostgreSQL. */
+ SYSTEM_INDEX,
+
+ /** System TOAST index.
+ *
+ * <p>Used by PostgreSQL. */
+ SYSTEM_TOAST_INDEX,
+
+ /** System TOAST table.
+ *
+ * <p>Used by PostgreSQL. */
+ SYSTEM_TOAST_TABLE,
+
+ /** Temporary index.
+ *
+ * <p>Used by PostgreSQL. */
+ TEMPORARY_INDEX,
+
+ /** Temporary sequence.
+ *
+ * <p>Used by PostgreSQL. */
+ TEMPORARY_SEQUENCE,
+
+ /** Temporary table.
+ *
+ * <p>Used by PostgreSQL. */
+ TEMPORARY_TABLE,
+
+ /** Temporary view.
+ *
+ * <p>Used by PostgreSQL. */
+ TEMPORARY_VIEW,
+
+ /** A table that is only visible to one connection.
+ *
+ * <p>Used by PostgreSQL, MySQL. */
+ LOCAL_TEMPORARY,
+
+ /** Table type not known to Calcite.
+ *
+ * <p>If you get one of these, please fix the problem by adding an enum
+ * value. */
+ OTHER,
}
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/d69f2c20/core/src/main/java/org/apache/calcite/util/Util.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/Util.java b/core/src/main/java/org/apache/calcite/util/Util.java
index 040775f..dbaf0a8 100644
--- a/core/src/main/java/org/apache/calcite/util/Util.java
+++ b/core/src/main/java/org/apache/calcite/util/Util.java
@@ -1859,11 +1859,29 @@ public class Util {
* @param <T> Enum class type
* @return Enum constant or null
*/
- @SuppressWarnings({"unchecked" })
public static synchronized <T extends Enum<T>> T enumVal(
Class<T> clazz,
String name) {
- return (T) ENUM_CONSTANTS.getUnchecked(clazz).get(name);
+ return clazz.cast(ENUM_CONSTANTS.getUnchecked(clazz).get(name));
+ }
+
+ /**
+ * Returns the value of an enumeration with a particular or default value if
+ * not found.
+ *
+ * @param default_ Default value (not null)
+ * @param name Name of enum constant
+ * @param <T> Enum class type
+ * @return Enum constant, never null
+ */
+ public static synchronized <T extends Enum<T>> T enumVal(T default_,
+ String name) {
+ final Class<T> clazz = default_.getDeclaringClass();
+ final T t = clazz.cast(ENUM_CONSTANTS.getUnchecked(clazz).get(name));
+ if (t == null) {
+ return default_;
+ }
+ return t;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/d69f2c20/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
index ea69cae..cc7ec8c 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
@@ -16,17 +16,25 @@
*/
package org.apache.calcite.test;
+import org.apache.calcite.jdbc.CalciteConnection;
+
+import com.google.common.base.Function;
+import com.google.common.base.Throwables;
+
import org.hsqldb.jdbcDriver;
+
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
+import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
/**
@@ -350,6 +358,33 @@ public class JdbcAdapterTest {
.explainContains("SINGLE_VALUE")
.throws_(expected);
}
+
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-865">[CALCITE-865]
+ * Unknown table type causes NullPointerException in JdbcSchema</a>. The issue
+ * occurred because of the "SYSTEM_INDEX" table type when run against
+ * PostgreSQL. */
+ @Test public void testMetadataTables() throws Exception {
+ // The troublesome tables occur in PostgreSQL's system schema.
+ final String model =
+ JdbcTest.FOODMART_MODEL.replace("jdbcSchema: 'foodmart'",
+ "jdbcSchema: null");
+ CalciteAssert.model(
+ model)
+ .doWithConnection(
+ new Function<CalciteConnection, Void>() {
+ public Void apply(CalciteConnection connection) {
+ try {
+ final ResultSet resultSet =
+ connection.getMetaData().getTables(null, null, "%", null);
+ assertFalse(CalciteAssert.toString(resultSet).isEmpty());
+ return null;
+ } catch (SQLException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+ });
+ }
}
// End JdbcAdapterTest.java