You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by ja...@apache.org on 2014/06/11 05:52:25 UTC
[40/61] [abbrv] git commit: DRILL-736: Fix DESCRIBE issues when the
selected table exists in more than one schema.
DRILL-736: Fix DESCRIBE issues when the selected table exists in more than one schema.
Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/299d1bf1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/299d1bf1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/299d1bf1
Branch: refs/heads/master
Commit: 299d1bf1c053da7bcf9902e7bf1ad870b9337c61
Parents: 0c3bad9
Author: vkorukanti <ve...@gmail.com>
Authored: Mon Jun 9 15:48:55 2014 -0700
Committer: vkorukanti <ve...@gmail.com>
Committed: Mon Jun 9 15:48:55 2014 -0700
----------------------------------------------------------------------
.../sql/handlers/AbstractSqlHandler.java | 4 +
.../sql/handlers/DescribeTableHandler.java | 81 ++++++++++++--------
.../apache/drill/jdbc/test/TestMetadataDDL.java | 43 ++++++++++-
3 files changed, 93 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/299d1bf1/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/AbstractSqlHandler.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/AbstractSqlHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/AbstractSqlHandler.java
index 4a3584c..3504505 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/AbstractSqlHandler.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/AbstractSqlHandler.java
@@ -79,6 +79,10 @@ public abstract class AbstractSqlHandler {
throw new Exception(String.format("Invalid schema path '%s'.", Joiner.on(".").join(schemaPath)));
}
+ public static boolean isRootSchema(SchemaPlus schema) {
+ return schema.getParentSchema() == null;
+ }
+
private static SchemaPlus searchSchemaTree(SchemaPlus schema, List<String> schemaPath) {
for (String schemaName : schemaPath) {
schema = schema.getSubSchema(schemaName);
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/299d1bf1/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DescribeTableHandler.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DescribeTableHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DescribeTableHandler.java
index d6849f4..1020757 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DescribeTableHandler.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DescribeTableHandler.java
@@ -19,11 +19,13 @@
package org.apache.drill.exec.planner.sql.handlers;
import com.google.common.collect.ImmutableList;
+import net.hydromatic.optiq.SchemaPlus;
import net.hydromatic.optiq.tools.Planner;
import net.hydromatic.optiq.tools.RelConversionException;
import org.apache.drill.exec.ops.QueryContext;
import org.apache.drill.exec.planner.sql.parser.DrillParserUtil;
import org.apache.drill.exec.planner.sql.parser.SqlDescribeTable;
+import org.apache.drill.exec.store.AbstractSchema;
import org.eigenbase.sql.*;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
import org.eigenbase.sql.parser.SqlParserPos;
@@ -39,50 +41,61 @@ public class DescribeTableHandler extends DefaultSqlHandler {
/** Rewrite the parse tree as SELECT ... FROM INFORMATION_SCHEMA.COLUMNS ... */
@Override
- public SqlNode rewrite(SqlNode sqlNode) throws RelConversionException{
+ public SqlNode rewrite(SqlNode sqlNode) throws RelConversionException {
SqlDescribeTable node = unwrap(sqlNode, SqlDescribeTable.class);
- List<SqlNode> selectList = ImmutableList.of((SqlNode)new SqlIdentifier("COLUMN_NAME", SqlParserPos.ZERO),
- new SqlIdentifier("DATA_TYPE", SqlParserPos.ZERO),
- new SqlIdentifier("IS_NULLABLE", SqlParserPos.ZERO));
+ try {
+ List<SqlNode> selectList = ImmutableList.of((SqlNode) new SqlIdentifier("COLUMN_NAME", SqlParserPos.ZERO),
+ new SqlIdentifier("DATA_TYPE", SqlParserPos.ZERO),
+ new SqlIdentifier("IS_NULLABLE", SqlParserPos.ZERO));
- SqlNode fromClause = new SqlIdentifier(
- ImmutableList.of("INFORMATION_SCHEMA", "COLUMNS"), null, SqlParserPos.ZERO, null);
+ SqlNode fromClause = new SqlIdentifier(
+ ImmutableList.of("INFORMATION_SCHEMA", "COLUMNS"), null, SqlParserPos.ZERO, null);
- final SqlIdentifier table = node.getTable();
- final int numLevels = table.names.size();
+ final SqlIdentifier table = node.getTable();
+ final SchemaPlus schema = findSchema(context.getRootSchema(), context.getNewDefaultSchema(),
+ Util.skipLast(table.names));
+ final String tableName = Util.last(table.names);
- SqlNode schemaCondition = null;
- if (numLevels > 1) {
- schemaCondition = DrillParserUtil.createCondition(
- new SqlIdentifier("TABLE_SCHEMA", SqlParserPos.ZERO),
- SqlStdOperatorTable.EQUALS,
- SqlLiteral.createCharString(Util.sepList(table.names.subList(0, numLevels - 1), "."),
- CHARSET, SqlParserPos.ZERO)
- );
- }
+ if (schema.getTable(tableName) == null) {
+ throw new RelConversionException(String.format("Table %s is not valid", Util.sepList(table.names, ".")));
+ }
- SqlNode where = DrillParserUtil.createCondition(
- new SqlIdentifier("TABLE_NAME", SqlParserPos.ZERO),
- SqlStdOperatorTable.EQUALS,
- SqlLiteral.createCharString(table.names.get(numLevels-1), CHARSET, SqlParserPos.ZERO));
+ SqlNode schemaCondition = null;
+ if (!isRootSchema(schema)) {
+ AbstractSchema drillSchema = getDrillSchema(schema);
- where = DrillParserUtil.createCondition(schemaCondition, SqlStdOperatorTable.AND, where);
+ schemaCondition = DrillParserUtil.createCondition(
+ new SqlIdentifier("TABLE_SCHEMA", SqlParserPos.ZERO),
+ SqlStdOperatorTable.EQUALS,
+ SqlLiteral.createCharString(drillSchema.getFullSchemaName(), CHARSET, SqlParserPos.ZERO)
+ );
+ }
- SqlNode columnFilter = null;
- if (node.getColumn() != null) {
- columnFilter = DrillParserUtil.createCondition(new SqlIdentifier("COLUMN_NAME", SqlParserPos.ZERO),
+ SqlNode where = DrillParserUtil.createCondition(
+ new SqlIdentifier("TABLE_NAME", SqlParserPos.ZERO),
SqlStdOperatorTable.EQUALS,
- SqlLiteral.createCharString(node.getColumn().toString(), CHARSET, SqlParserPos.ZERO));
- } else if (node.getColumnQualifier() != null) {
- columnFilter = DrillParserUtil.createCondition(new SqlIdentifier("COLUMN_NAME", SqlParserPos.ZERO),
- SqlStdOperatorTable.LIKE, node.getColumnQualifier());
+ SqlLiteral.createCharString(tableName, CHARSET, SqlParserPos.ZERO));
+
+ where = DrillParserUtil.createCondition(schemaCondition, SqlStdOperatorTable.AND, where);
+
+ SqlNode columnFilter = null;
+ if (node.getColumn() != null) {
+ columnFilter = DrillParserUtil.createCondition(new SqlIdentifier("COLUMN_NAME", SqlParserPos.ZERO),
+ SqlStdOperatorTable.EQUALS,
+ SqlLiteral.createCharString(node.getColumn().toString(), CHARSET, SqlParserPos.ZERO));
+ } else if (node.getColumnQualifier() != null) {
+ columnFilter = DrillParserUtil.createCondition(new SqlIdentifier("COLUMN_NAME", SqlParserPos.ZERO),
+ SqlStdOperatorTable.LIKE, node.getColumnQualifier());
+ }
+
+ where = DrillParserUtil.createCondition(where, SqlStdOperatorTable.AND, columnFilter);
+
+ return new SqlSelect(SqlParserPos.ZERO, null, new SqlNodeList(selectList, SqlParserPos.ZERO),
+ fromClause, where, null, null, null, null, null, null);
+ } catch (Exception ex) {
+ throw new RelConversionException("Error while rewriting DESCRIBE query: " + ex.getMessage(), ex);
}
-
- where = DrillParserUtil.createCondition(where, SqlStdOperatorTable.AND, columnFilter);
-
- return new SqlSelect(SqlParserPos.ZERO, null, new SqlNodeList(selectList, SqlParserPos.ZERO),
- fromClause, where, null, null, null, null, null, null);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/299d1bf1/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestMetadataDDL.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestMetadataDDL.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestMetadataDDL.java
index 59e2d03..06a671d 100644
--- a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestMetadataDDL.java
+++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestMetadataDDL.java
@@ -129,7 +129,7 @@ public class TestMetadataDDL extends TestJdbcQuery {
@Test
public void testDescribeTable() throws Exception{
- JdbcAssert.withNoDefaultSchema()
+ JdbcAssert.withFull("INFORMATION_SCHEMA")
.sql("DESCRIBE CATALOGS")
.returns(
"COLUMN_NAME=CATALOG_NAME; DATA_TYPE=VARCHAR; IS_NULLABLE=NO\n"+
@@ -149,6 +149,47 @@ public class TestMetadataDDL extends TestJdbcQuery {
}
@Test
+ public void testDescribeSameTableInMultipleSchemas() throws Exception{
+ JdbcAssert.withNoDefaultSchema().withConnection(new Function<Connection, Void>() {
+ public Void apply(Connection connection) {
+ try {
+ Statement statement = connection.createStatement();
+ statement.executeQuery("USE dfs.tmp").close();
+
+ // INFORMATION_SCHEMA already has a table named "TABLES". Now create a table with same name in "dfs.tmp" schema
+ statement.executeQuery("CREATE OR REPLACE VIEW `TABLES` AS SELECT key FROM hive.kv").close();
+
+ // Test describe of `TABLES` with no schema qualifier
+ ResultSet resultSet = statement.executeQuery("DESCRIBE `TABLES`");
+ String result = JdbcAssert.toString(resultSet).trim();
+ resultSet.close();
+ String expected = "COLUMN_NAME=key; DATA_TYPE=INTEGER; IS_NULLABLE=NO";
+ assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, expected), expected.equals(result));
+
+ // Test describe of `TABLES` with a schema qualifier which is not in default schema
+ resultSet = statement.executeQuery("DESCRIBE INFORMATION_SCHEMA.`TABLES`");
+ result = JdbcAssert.toString(resultSet).trim();
+ resultSet.close();
+ expected =
+ "COLUMN_NAME=TABLE_CATALOG; DATA_TYPE=VARCHAR; IS_NULLABLE=NO\n" +
+ "COLUMN_NAME=TABLE_SCHEMA; DATA_TYPE=VARCHAR; IS_NULLABLE=NO\n" +
+ "COLUMN_NAME=TABLE_NAME; DATA_TYPE=VARCHAR; IS_NULLABLE=NO\n" +
+ "COLUMN_NAME=TABLE_TYPE; DATA_TYPE=VARCHAR; IS_NULLABLE=NO";
+ assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, expected), expected.equals(result));
+
+ // drop created view
+ statement.executeQuery("DROP VIEW `TABLES`").close();
+
+ statement.close();
+ return null;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ }
+
+ @Test
public void testDescribeTableWithColumnName() throws Exception{
JdbcAssert.withFull("INFORMATION_SCHEMA")
.sql("DESCRIBE `TABLES` TABLE_CATALOG")