You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@drill.apache.org by ja...@apache.org on 2014/05/08 04:50:44 UTC
[1/5] git commit: DRILL-627: Fix memory leaks in hash join and hash
aggregate
Repository: incubator-drill
Updated Branches:
refs/heads/master 85d52c744 -> b7bf00cbb
DRILL-627: Fix memory leaks in hash join and hash aggregate
Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/d870b6e0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/d870b6e0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/d870b6e0
Branch: refs/heads/master
Commit: d870b6e0ccd5765ca0738b3642ee459a1d15cceb
Parents: 85d52c7
Author: Mehant Baid <me...@gmail.com>
Authored: Sun May 4 13:52:08 2014 -0700
Committer: Jacques Nadeau <ja...@apache.org>
Committed: Wed May 7 18:43:08 2014 -0700
----------------------------------------------------------------------
.../impl/aggregate/HashAggTemplate.java | 4 +
.../exec/physical/impl/join/HashJoinBatch.java | 71 ++++---
.../impl/join/HashJoinProbeTemplate.java | 16 +-
.../exec/physical/impl/join/TestHashJoin.java | 33 +++-
.../src/test/resources/join/hj_exchanges1.json | 197 +++++++++++++++++++
5 files changed, 287 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/d870b6e0/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/aggregate/HashAggTemplate.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/aggregate/HashAggTemplate.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/aggregate/HashAggTemplate.java
index d7abcd2..c50a86a 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/aggregate/HashAggTemplate.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/aggregate/HashAggTemplate.java
@@ -229,6 +229,10 @@ public abstract class HashAggTemplate implements HashAggregator {
try{
while(true){
+ // Cleanup the previous batch since we are done processing it.
+ for (VectorWrapper<?> v : incoming) {
+ v.getValueVector().clear();
+ }
IterOutcome out = incoming.next();
if(EXTRA_DEBUG_1) logger.debug("Received IterOutcome of {}", out);
switch(out){
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/d870b6e0/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/HashJoinBatch.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/HashJoinBatch.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/HashJoinBatch.java
index b624b30..883052a 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/HashJoinBatch.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/HashJoinBatch.java
@@ -159,35 +159,52 @@ public class HashJoinBatch extends AbstractRecordBatch<HashJoinPOP> {
hashJoinProbe = setupHashJoinProbe();
}
- // Allocate the memory for the vectors in the output container
- allocateVectors();
-
// Store the number of records projected
- outputRecords = hashJoinProbe.probeAndProject();
+ if (hashTable != null) {
- /* We are here because of one the following
- * 1. Completed processing of all the records and we are done
- * 2. We've filled up the outgoing batch to the maximum and we need to return upstream
- * Either case build the output container's schema and return
- */
- if (outputRecords > 0) {
+ // Allocate the memory for the vectors in the output container
+ allocateVectors();
+
+ outputRecords = hashJoinProbe.probeAndProject();
+
+ /* We are here because of one the following
+ * 1. Completed processing of all the records and we are done
+ * 2. We've filled up the outgoing batch to the maximum and we need to return upstream
+ * Either case build the output container's schema and return
+ */
+ if (outputRecords > 0) {
- // Build the container schema and set the counts
- container.buildSchema(BatchSchema.SelectionVectorMode.NONE);
- container.setRecordCount(outputRecords);
+ // Build the container schema and set the counts
+ container.buildSchema(BatchSchema.SelectionVectorMode.NONE);
+ container.setRecordCount(outputRecords);
- for (VectorWrapper<?> v : container) {
+ for (VectorWrapper<?> v : container) {
v.getValueVector().getMutator().setValueCount(outputRecords);
- }
+ }
- // First output batch, return OK_NEW_SCHEMA
- if (firstOutputBatch == true) {
+ // First output batch, return OK_NEW_SCHEMA
+ if (firstOutputBatch == true) {
firstOutputBatch = false;
return IterOutcome.OK_NEW_SCHEMA;
- }
+ }
- // Not the first output batch
- return IterOutcome.OK;
+ // Not the first output batch
+ return IterOutcome.OK;
+ }
+ } else {
+ // Our build side is empty, we won't have any matches, clear the probe side
+ if (leftUpstream == IterOutcome.OK_NEW_SCHEMA || leftUpstream == IterOutcome.OK) {
+ for (VectorWrapper<?> wrapper : left) {
+ wrapper.getValueVector().clear();
+ }
+ leftUpstream = left.next();
+ while (leftUpstream == IterOutcome.OK_NEW_SCHEMA || leftUpstream == IterOutcome.OK) {
+ for (VectorWrapper<?> wrapper : left) {
+ wrapper.getValueVector().clear();
+ }
+ leftUpstream = left.next();
+ }
+ }
}
// No more output records, clean up and return
@@ -220,11 +237,14 @@ public class HashJoinBatch extends AbstractRecordBatch<HashJoinPOP> {
// Set the left named expression to be null if the probe batch is empty.
if (leftUpstream != IterOutcome.OK_NEW_SCHEMA && leftUpstream != IterOutcome.OK) {
leftExpr = null;
+ } else {
+ if (left.getSchema().getSelectionVectorMode() != BatchSchema.SelectionVectorMode.NONE) {
+ throw new SchemaChangeException("Hash join does not support probe batch with selection vectors");
+ }
}
HashTableConfig htConfig = new HashTableConfig(HashTable.DEFAULT_INITIAL_CAPACITY, HashTable.DEFAULT_LOAD_FACTOR, rightExpr, leftExpr);
-
// Create the chained hash table
ChainedHashTable ht = new ChainedHashTable(htConfig, context, oContext.getAllocator(), this.right, this.left, null);
hashTable = ht.createAndSetupHashTable(null);
@@ -250,6 +270,10 @@ public class HashJoinBatch extends AbstractRecordBatch<HashJoinPOP> {
case OK_NEW_SCHEMA:
if (rightSchema == null) {
rightSchema = right.getSchema();
+
+ if (rightSchema.getSelectionVectorMode() != BatchSchema.SelectionVectorMode.NONE) {
+ throw new SchemaChangeException("Hash join does not support build batch with selection vectors");
+ }
setupHashTable();
} else {
throw new SchemaChangeException("Hash join does not support schema changes");
@@ -395,13 +419,14 @@ public class HashJoinBatch extends AbstractRecordBatch<HashJoinPOP> {
@Override
public void cleanup() {
- hyperContainer.clear();
hjHelper.clear();
- container.clear();
// If we didn't receive any data, hyperContainer may be null, check before clearing
if (hyperContainer != null) {
hyperContainer.clear();
+ }
+
+ if (hashTable != null) {
hashTable.clear();
}
super.cleanup();
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/d870b6e0/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/HashJoinProbeTemplate.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/HashJoinProbeTemplate.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/HashJoinProbeTemplate.java
index 0abf678..a3e3b74 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/HashJoinProbeTemplate.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/HashJoinProbeTemplate.java
@@ -22,19 +22,13 @@ import javax.inject.Named;
import org.apache.drill.exec.exception.ClassTransformationException;
import org.apache.drill.exec.exception.SchemaChangeException;
import org.apache.drill.exec.ops.FragmentContext;
-import org.apache.drill.exec.physical.impl.common.ChainedHashTable;
import org.apache.drill.exec.physical.impl.common.HashTable;
-import org.apache.drill.exec.physical.impl.common.HashTableConfig;
-import org.apache.drill.exec.physical.impl.sort.RecordBatchData;
-import org.apache.drill.exec.record.BatchSchema;
-import org.apache.drill.exec.record.ExpandableHyperContainer;
+import org.apache.drill.exec.record.VectorWrapper;
import org.apache.drill.exec.record.RecordBatch;
import org.apache.drill.exec.record.RecordBatch.IterOutcome;
import org.apache.drill.exec.record.VectorContainer;
-import org.apache.drill.exec.vector.allocator.VectorAllocator;
-import org.apache.drill.exec.expr.holders.IntHolder;
+
import org.eigenbase.rel.JoinRelType;
-import org.eigenbase.sql2rel.StandardConvertletTable;
import java.io.IOException;
import java.util.List;
@@ -104,6 +98,12 @@ public abstract class HashJoinProbeTemplate implements HashJoinProbe {
// Check if we have processed all records in this batch we need to invoke next
if (recordsProcessed == recordsToProcess) {
+
+ // Done processing all records in the previous batch, clean up!
+ for (VectorWrapper<?> wrapper : probeBatch) {
+ wrapper.getValueVector().clear();
+ }
+
IterOutcome leftUpstream = probeBatch.next();
switch (leftUpstream) {
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/d870b6e0/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/join/TestHashJoin.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/join/TestHashJoin.java b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/join/TestHashJoin.java
index 722d54f..ea83534 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/join/TestHashJoin.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/join/TestHashJoin.java
@@ -119,7 +119,7 @@ public class TestHashJoin extends PopUnitTestBase{
@Test
public void simpleEqualityJoin() throws Throwable {
- // Function checks for casting from Float, Double to Decimal data types
+ // Function checks hash join with single equality condition
try (RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet();
Drillbit bit = new Drillbit(CONFIG, serviceSet);
DrillClient client = new DrillClient(CONFIG, serviceSet.getCoordinator())) {
@@ -157,7 +157,7 @@ public class TestHashJoin extends PopUnitTestBase{
public void hjWithExchange(@Injectable final DrillbitContext bitContext,
@Injectable UserServer.UserClientConnection connection) throws Throwable {
- // Function checks for casting from Float, Double to Decimal data types
+ // Function tests with hash join with exchanges
try (RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet();
Drillbit bit = new Drillbit(CONFIG, serviceSet);
DrillClient client = new DrillClient(CONFIG, serviceSet.getCoordinator())) {
@@ -183,7 +183,7 @@ public class TestHashJoin extends PopUnitTestBase{
public void multipleConditionJoin(@Injectable final DrillbitContext bitContext,
@Injectable UserServer.UserClientConnection connection) throws Throwable {
- // Function checks for casting from Float, Double to Decimal data types
+ // Function tests hash join with multiple join conditions
try (RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet();
Drillbit bit = new Drillbit(CONFIG, serviceSet);
DrillClient client = new DrillClient(CONFIG, serviceSet.getCoordinator())) {
@@ -219,4 +219,31 @@ public class TestHashJoin extends PopUnitTestBase{
assertEquals(3, intAccessor1.getValueCount());
}
}
+
+
+ @Test
+ public void hjWithExchange1(@Injectable final DrillbitContext bitContext,
+ @Injectable UserServer.UserClientConnection connection) throws Throwable {
+
+ // Another test for hash join with exchanges
+ try (RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet();
+ Drillbit bit = new Drillbit(CONFIG, serviceSet);
+ DrillClient client = new DrillClient(CONFIG, serviceSet.getCoordinator())) {
+
+ // run query.
+ bit.run();
+ client.connect();
+ List<QueryResultBatch> results = client.runQuery(UserProtos.QueryType.PHYSICAL,
+ Files.toString(FileUtils.getResourceAsFile("/join/hj_exchanges1.json"), Charsets.UTF_8));
+
+ int count = 0;
+ for(QueryResultBatch b : results) {
+ if (b.getHeader().getRowCount() != 0)
+ count += b.getHeader().getRowCount();
+ }
+
+ System.out.println("Total records: " + count);
+ assertEquals(272, count);
+ }
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/d870b6e0/exec/java-exec/src/test/resources/join/hj_exchanges1.json
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/resources/join/hj_exchanges1.json b/exec/java-exec/src/test/resources/join/hj_exchanges1.json
new file mode 100644
index 0000000..7ccc324
--- /dev/null
+++ b/exec/java-exec/src/test/resources/join/hj_exchanges1.json
@@ -0,0 +1,197 @@
+{
+ "head" : {
+ "version" : 1,
+ "generator" : {
+ "type" : "DefaultSqlHandler",
+ "info" : ""
+ },
+ "type" : "APACHE_DRILL_PHYSICAL",
+ "resultMode" : "EXEC"
+ },
+ "graph" : [ {
+ "pop" : "parquet-scan",
+ "@id" : 1,
+ "entries" : [ {
+ "path" : "/tpch/customer.parquet"
+ } ],
+ "storage" : {
+ "type" : "file",
+ "connection" : "classpath:///",
+ "workspaces" : null,
+ "formats" : {
+ "json" : {
+ "type" : "json"
+ },
+ "parquet" : {
+ "type" : "parquet"
+ }
+ }
+ },
+ "format" : {
+ "type" : "parquet"
+ },
+ "selectionRoot" : "/tpch/customer.parquet"
+ }, {
+ "pop" : "filter",
+ "@id" : 2,
+ "child" : 1,
+ "expr" : "equal(cast( (`c_mktsegment` ) as VARCHAR(9) ), 'HOUSEHOLD') "
+ }, {
+ "pop" : "selection-vector-remover",
+ "@id" : 3,
+ "child" : 2
+ }, {
+ "pop" : "hash-to-random-exchange",
+ "@id" : 4,
+ "child" : 3,
+ "expr" : "hash(`c_custkey`) "
+ }, {
+ "pop" : "parquet-scan",
+ "@id" : 5,
+ "entries" : [ {
+ "path" : "/tpch/lineitem.parquet"
+ } ],
+ "storage" : {
+ "type" : "file",
+ "connection" : "classpath:///",
+ "workspaces" : null,
+ "formats" : {
+ "json" : {
+ "type" : "json"
+ },
+ "parquet" : {
+ "type" : "parquet"
+ }
+ }
+ },
+ "format" : {
+ "type" : "parquet"
+ },
+ "selectionRoot" : "/tpch/lineitem.parquet"
+ }, {
+ "pop" : "filter",
+ "@id" : 6,
+ "child" : 5,
+ "expr" : "greater_than(`l_shipdate`, cast( 796089600000 as DATE)) "
+ }, {
+ "pop" : "selection-vector-remover",
+ "@id" : 7,
+ "child" : 6
+ }, {
+ "pop" : "hash-to-random-exchange",
+ "@id" : 8,
+ "child" : 7,
+ "expr" : "hash(`l_orderkey`) "
+ }, {
+ "pop" : "project",
+ "@id" : 9,
+ "exprs" : [ {
+ "ref" : "`*1`",
+ "expr" : "`*`"
+ }, {
+ "ref" : "`l_orderkey`",
+ "expr" : "`l_orderkey`"
+ }, {
+ "ref" : "`l_shipdate`",
+ "expr" : "`l_shipdate`"
+ } ],
+ "child" : 8
+ }, {
+ "pop" : "parquet-scan",
+ "@id" : 10,
+ "entries" : [ {
+ "path" : "/tpch/orders.parquet"
+ } ],
+ "storage" : {
+ "type" : "file",
+ "connection" : "classpath:///",
+ "workspaces" : null,
+ "formats" : {
+ "json" : {
+ "type" : "json"
+ },
+ "parquet" : {
+ "type" : "parquet"
+ }
+ }
+ },
+ "format" : {
+ "type" : "parquet"
+ },
+ "selectionRoot" : "/tpch/orders.parquet"
+ }, {
+ "pop" : "filter",
+ "@id" : 11,
+ "child" : 10,
+ "expr" : "less_than(`o_orderdate`, cast( 796089600000 as DATE)) "
+ }, {
+ "pop" : "selection-vector-remover",
+ "@id" : 12,
+ "child" : 11
+ }, {
+ "pop" : "hash-to-random-exchange",
+ "@id" : 13,
+ "child" : 12,
+ "expr" : "hash(`o_custkey`) "
+ }, {
+ "pop" : "project",
+ "@id" : 14,
+ "exprs" : [ {
+ "ref" : "`*0`",
+ "expr" : "`*`"
+ }, {
+ "ref" : "`o_orderdate`",
+ "expr" : "`o_orderdate`"
+ }, {
+ "ref" : "`o_custkey`",
+ "expr" : "`o_custkey`"
+ }, {
+ "ref" : "`o_orderkey`",
+ "expr" : "`o_orderkey`"
+ } ],
+ "child" : 13
+ }, {
+ "pop" : "hash-join",
+ "@id" : 15,
+ "left" : 4,
+ "right" : 14,
+ "conditions" : [ {
+ "relationship" : "==",
+ "left" : "`c_custkey`",
+ "right" : "`o_custkey`"
+ } ],
+ "joinType" : "INNER"
+ }, {
+ "pop" : "hash-to-random-exchange",
+ "@id" : 16,
+ "child" : 15,
+ "expr" : "hash(`o_orderkey`) "
+ }, {
+ "pop" : "hash-join",
+ "@id" : 17,
+ "left" : 16,
+ "right" : 9,
+ "conditions" : [ {
+ "relationship" : "==",
+ "left" : "`o_orderkey`",
+ "right" : "`l_orderkey`"
+ } ],
+ "joinType" : "INNER"
+ }, {
+ "pop" : "project",
+ "@id" : 18,
+ "exprs" : [ {
+ "ref" : "`EXPR$0`",
+ "expr" : "1"
+ } ],
+ "child" : 17
+ }, {
+ "pop" : "union-exchange",
+ "@id" : 19,
+ "child" : 18
+ }, {
+ "pop" : "screen",
+ "@id" : 20,
+ "child" : 19
+ } ]
+}
[3/5] git commit: DRILL-577: Two way implicit casts
Posted by ja...@apache.org.
DRILL-577: Two way implicit casts
Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/cd4f281e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/cd4f281e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/cd4f281e
Branch: refs/heads/master
Commit: cd4f281e0c41707f79ccf3777d6245a13befeb18
Parents: f2ff2c9
Author: Mehant Baid <me...@gmail.com>
Authored: Wed May 7 12:25:39 2014 -0700
Committer: Jacques Nadeau <ja...@apache.org>
Committed: Wed May 7 18:43:18 2014 -0700
----------------------------------------------------------------------
.../exec/expr/ExpressionTreeMaterializer.java | 10 ++-
.../exec/resolver/ResolverTypePrecedence.java | 55 +++++++++++++-
.../drill/exec/resolver/TypeCastRules.java | 45 +++++++++--
.../physical/impl/TestReverseImplicitCast.java | 78 ++++++++++++++++++++
.../functions/cast/two_way_implicit_cast.json | 36 +++++++++
5 files changed, 217 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/cd4f281e/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
index a602d82..95d341b 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/ExpressionTreeMaterializer.java
@@ -156,7 +156,15 @@ public class ExpressionTreeMaterializer {
List<LogicalExpression> castArgs = Lists.newArrayList();
castArgs.add(call.args.get(i)); //input_expr
- if (parmType.getMinorType().name().startsWith("DECIMAL")) {
+ if (!Types.isFixedWidthType(parmType)) {
+
+ /* We are implicitly casting to VARCHAR so we don't have a max length,
+ * using an arbitrary value. We trim down the size of the stored bytes
+ * to the actual size so this size doesn't really matter.
+ */
+ castArgs.add(new ValueExpressions.LongExpression(65536, null));
+ }
+ else if (parmType.getMinorType().name().startsWith("DECIMAL")) {
// Add the scale and precision to the arguments of the implicit cast
castArgs.add(new ValueExpressions.LongExpression(currentArg.getMajorType().getPrecision(), null));
castArgs.add(new ValueExpressions.LongExpression(currentArg.getMajorType().getScale(), null));
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/cd4f281e/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ResolverTypePrecedence.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ResolverTypePrecedence.java b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ResolverTypePrecedence.java
index f6d83e2..71bf616 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ResolverTypePrecedence.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/ResolverTypePrecedence.java
@@ -19,7 +19,9 @@
package org.apache.drill.exec.resolver;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import org.apache.drill.common.types.TypeProtos.DataMode;
import org.apache.drill.common.types.TypeProtos.MinorType;
@@ -27,7 +29,9 @@ import org.apache.drill.common.types.TypeProtos.MinorType;
public class ResolverTypePrecedence {
-public static final Map<MinorType, Integer> precedenceMap;
+ public static final Map<MinorType, Integer> precedenceMap;
+ public static final Map<MinorType, Set<MinorType>> secondaryImplicitCastRules;
+ public static int MAX_IMPLICIT_CAST_COST;
static {
/* The precedenceMap is used to decide whether it's allowed to implicitly "promote"
@@ -74,6 +78,55 @@ public static final Map<MinorType, Integer> precedenceMap;
precedenceMap.put(MinorType.INTERVALDAY, i+= 2);
precedenceMap.put(MinorType.INTERVALYEAR, i+= 2);
precedenceMap.put(MinorType.INTERVAL, i+= 2);
+
+ MAX_IMPLICIT_CAST_COST = i;
+
+ /* Currently implicit cast follows the precedence rules.
+ * It may be useful to perform an implicit cast in
+ * the opposite direction as specified by the precedence rules.
+ *
+ * For example: As per the precedence rules we can implicitly cast
+ * from VARCHAR ---> BIGINT , but based upon some functions (eg: substr, concat)
+ * it may be useful to implicitly cast from BIGINT ---> VARCHAR.
+ *
+ * To allow for such cases we have a secondary set of rules which will allow the reverse
+ * implicit casts. Currently we only allow the reverse implicit cast to VARCHAR so we don't
+ * need any cost associated with it, if we add more of these that may collide we can add costs.
+ */
+ secondaryImplicitCastRules = new HashMap<>();
+ HashSet<MinorType> rule = new HashSet<>();
+
+ // Following cast functions should exist
+ rule.add(MinorType.TINYINT);
+ rule.add(MinorType.SMALLINT);
+ rule.add(MinorType.INT);
+ rule.add(MinorType.BIGINT);
+ rule.add(MinorType.UINT1);
+ rule.add(MinorType.UINT2);
+ rule.add(MinorType.UINT4);
+ rule.add(MinorType.UINT8);
+ rule.add(MinorType.DECIMAL9);
+ rule.add(MinorType.DECIMAL18);
+ rule.add(MinorType.DECIMAL28SPARSE);
+ rule.add(MinorType.DECIMAL28DENSE);
+ rule.add(MinorType.DECIMAL38SPARSE);
+ rule.add(MinorType.DECIMAL38DENSE);
+ rule.add(MinorType.MONEY);
+ rule.add(MinorType.FLOAT4);
+ rule.add(MinorType.FLOAT8);
+ rule.add(MinorType.BIT);
+ rule.add(MinorType.FIXEDCHAR);
+ rule.add(MinorType.FIXED16CHAR);
+ rule.add(MinorType.VARCHAR);
+ rule.add(MinorType.DATE);
+ rule.add(MinorType.TIME);
+ rule.add(MinorType.TIMESTAMP);
+ rule.add(MinorType.TIMESTAMPTZ);
+ rule.add(MinorType.INTERVAL);
+ rule.add(MinorType.INTERVALYEAR);
+ rule.add(MinorType.INTERVALDAY);
+
+ secondaryImplicitCastRules.put(MinorType.VARCHAR, rule);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/cd4f281e/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
index 3aab08f..515843d 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
@@ -778,6 +778,8 @@ public class TypeCastRules {
(rules.get(to.getMinorType()) == null ? false : rules.get(to.getMinorType()).contains(from.getMinorType()));
}
+ private static final int DATAMODE_CAST_COST = 1;
+
/*
* code decide whether it's legal to do implicit cast. -1 : not allowed for
* implicit cast > 0: cost associated with implicit cast. ==0: parms are
@@ -789,7 +791,13 @@ public class TypeCastRules {
if (call.args.size() != holder.getParamCount()) {
return -1;
}
-
+
+ // Indicates whether we used secondary cast rules
+ boolean secondaryCast = false;
+
+ // number of arguments that could implicitly casts using precedence map or didn't require casting at all
+ int nCasts = 0;
+
for (int i = 0; i < holder.getParamCount(); i++) {
MajorType argType = call.args.get(i).getMajorType();
MajorType parmType = holder.getParmMajorType(i);
@@ -816,9 +824,18 @@ public class TypeCastRules {
}
if (parmVal - argVal < 0) {
- return -1;
+
+ /* Precedence rules does not allow to implicitly cast, however check
+ * if the seconday rules allow us to cast
+ */
+ Set<MinorType> rules;
+ if ((rules = (ResolverTypePrecedence.secondaryImplicitCastRules.get(parmType.getMinorType()))) != null &&
+ rules.contains(argType.getMinorType()) != false) {
+ secondaryCast = true;
+ } else {
+ return -1;
+ }
}
-
// Check null vs non-null, using same logic as that in Types.softEqual()
// Only when the function uses NULL_IF_NULL, nullable and non-nullable are inter-changable.
// Otherwise, the function implementation is not a match.
@@ -839,12 +856,30 @@ public class TypeCastRules {
return -1;
}
else if (parmType.getMode() == DataMode.OPTIONAL && argType.getMode() == DataMode.REQUIRED) {
- cost++;
+ cost+= DATAMODE_CAST_COST;
}
}
}
- cost += (parmVal - argVal);
+ int castCost;
+
+ if ((castCost = (parmVal - argVal)) >= 0) {
+ nCasts++;
+ cost += castCost;
+ }
+ }
+
+ if (secondaryCast) {
+ // We have a secondary cast for one or more of the arguments, determine the cost associated
+ int secondaryCastCost = Integer.MAX_VALUE - 1;
+
+ // Subtract maximum possible implicit costs from the secondary cast cost
+ secondaryCastCost -= (nCasts * (ResolverTypePrecedence.MAX_IMPLICIT_CAST_COST + DATAMODE_CAST_COST));
+
+ // Add cost of implicitly casting the rest of the arguments that didn't use secondary casting
+ secondaryCastCost += cost;
+
+ return secondaryCastCost;
}
return cost;
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/cd4f281e/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestReverseImplicitCast.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestReverseImplicitCast.java b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestReverseImplicitCast.java
new file mode 100644
index 0000000..a0b77a5
--- /dev/null
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/TestReverseImplicitCast.java
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.physical.impl;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import mockit.Injectable;
+import org.apache.drill.common.util.FileUtils;
+import org.apache.drill.exec.client.DrillClient;
+import org.apache.drill.exec.pop.PopUnitTestBase;
+import org.apache.drill.exec.proto.UserProtos;
+import org.apache.drill.exec.record.RecordBatchLoader;
+import org.apache.drill.exec.record.VectorWrapper;
+import org.apache.drill.exec.rpc.user.QueryResultBatch;
+import org.apache.drill.exec.rpc.user.UserServer;
+import org.apache.drill.exec.server.Drillbit;
+import org.apache.drill.exec.server.DrillbitContext;
+import org.apache.drill.exec.server.RemoteServiceSet;
+import org.apache.drill.exec.vector.ValueVector;
+import org.junit.Test;
+
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestReverseImplicitCast extends PopUnitTestBase {
+
+ @Test
+ public void twoWayCast(@Injectable final DrillbitContext bitContext,
+ @Injectable UserServer.UserClientConnection connection) throws Throwable {
+
+ // Function checks for casting from Float, Double to Decimal data types
+ try (RemoteServiceSet serviceSet = RemoteServiceSet.getLocalServiceSet();
+ Drillbit bit = new Drillbit(CONFIG, serviceSet);
+ DrillClient client = new DrillClient(CONFIG, serviceSet.getCoordinator())) {
+
+ // run query.
+ bit.run();
+ client.connect();
+ List<QueryResultBatch> results = client.runQuery(UserProtos.QueryType.PHYSICAL,
+ Files.toString(FileUtils.getResourceAsFile("/functions/cast/two_way_implicit_cast.json"), Charsets.UTF_8));
+
+ RecordBatchLoader batchLoader = new RecordBatchLoader(bit.getContext().getAllocator());
+
+ QueryResultBatch batch = results.get(0);
+ assertTrue(batchLoader.load(batch.getHeader().getDef(), batch.getData()));
+
+ Iterator<VectorWrapper<?>> itr = batchLoader.iterator();
+
+ ValueVector.Accessor intAccessor1 = itr.next().getValueVector().getAccessor();
+ ValueVector.Accessor varcharAccessor1 = itr.next().getValueVector().getAccessor();
+
+ for (int i = 0; i < intAccessor1.getValueCount(); i++) {
+ System.out.println(intAccessor1.getObject(i));
+ assertEquals(intAccessor1.getObject(i), 10);
+ System.out.println(varcharAccessor1.getObject(i));
+ assertEquals(varcharAccessor1.getObject(i), "101");
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/cd4f281e/exec/java-exec/src/test/resources/functions/cast/two_way_implicit_cast.json
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/resources/functions/cast/two_way_implicit_cast.json b/exec/java-exec/src/test/resources/functions/cast/two_way_implicit_cast.json
new file mode 100644
index 0000000..31cf541
--- /dev/null
+++ b/exec/java-exec/src/test/resources/functions/cast/two_way_implicit_cast.json
@@ -0,0 +1,36 @@
+{
+ head:{
+ type:"APACHE_DRILL_PHYSICAL",
+ version:"1",
+ generator:{
+ type:"manual"
+ }
+ },
+ graph:[
+ {
+ @id:1,
+ pop:"mock-scan",
+ url: "http://apache.org",
+ entries:[
+ {records: 1, types: [
+ {name: "col1", type: "FLOAT4", mode: "REQUIRED"},
+ {name: "col2", type: "FLOAT8", mode: "REQUIRED"}
+ ]}
+ ]
+ },
+ {
+ @id:2,
+ child: 1,
+ pop:"project",
+ exprs: [
+ {ref: "str_to_int_cast", expr:"8 + '2'" },
+ {ref: "int_to_str_cast", expr:"substr(10123, 1, 3)" }
+ ]
+ },
+ {
+ @id: 3,
+ child: 2,
+ pop: "screen"
+ }
+ ]
+}
[2/5] git commit: DRILL-640: Fix memory leak in limit operator
Posted by ja...@apache.org.
DRILL-640: Fix memory leak in limit operator
Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/f2ff2c9d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/f2ff2c9d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/f2ff2c9d
Branch: refs/heads/master
Commit: f2ff2c9d2aad429f042da8250ca6e1ef1f160318
Parents: d870b6e
Author: Mehant Baid <me...@gmail.com>
Authored: Mon May 5 14:48:18 2014 -0700
Committer: Jacques Nadeau <ja...@apache.org>
Committed: Wed May 7 18:43:13 2014 -0700
----------------------------------------------------------------------
.../physical/impl/limit/LimitRecordBatch.java | 12 +++
.../impl/limit/TestLimitWithExchanges.java | 29 +++++++
.../test/resources/limit/limit_exchanges.json | 87 ++++++++++++++++++++
3 files changed, 128 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/f2ff2c9d/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/limit/LimitRecordBatch.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/limit/LimitRecordBatch.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/limit/LimitRecordBatch.java
index 3f2ec27..ed56e79 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/limit/LimitRecordBatch.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/limit/LimitRecordBatch.java
@@ -81,6 +81,18 @@ public class LimitRecordBatch extends AbstractSingleRecordBatch<Limit> {
public IterOutcome next() {
if(!noEndLimit && recordsLeft <= 0) {
// don't kill incoming batches or call cleanup yet, as this could close allocators before the buffers have been cleared
+ // Drain the incoming record batch and clear the memory
+ IterOutcome upStream = incoming.next();
+
+ while (upStream == IterOutcome.OK || upStream == IterOutcome.OK_NEW_SCHEMA) {
+
+ // Clear the memory for the incoming batch
+ for (VectorWrapper<?> wrapper : incoming) {
+ wrapper.getValueVector().clear();
+ }
+ upStream = incoming.next();
+ }
+
return IterOutcome.NONE;
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/f2ff2c9d/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestLimitWithExchanges.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestLimitWithExchanges.java b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestLimitWithExchanges.java
new file mode 100644
index 0000000..0e4d734
--- /dev/null
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/physical/impl/limit/TestLimitWithExchanges.java
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.physical.impl.limit;
+
+import org.apache.drill.BaseTestQuery;
+import org.junit.Test;
+
+public class TestLimitWithExchanges extends BaseTestQuery {
+
+ @Test
+ public void testLimitWithExchanges() throws Exception{
+ testPhysicalFromFile("limit/limit_exchanges.json");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/f2ff2c9d/exec/java-exec/src/test/resources/limit/limit_exchanges.json
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/resources/limit/limit_exchanges.json b/exec/java-exec/src/test/resources/limit/limit_exchanges.json
new file mode 100644
index 0000000..5ad56be
--- /dev/null
+++ b/exec/java-exec/src/test/resources/limit/limit_exchanges.json
@@ -0,0 +1,87 @@
+{
+ "head" : {
+ "version" : 1,
+ "generator" : {
+ "type" : "DefaultSqlHandler",
+ "info" : ""
+ },
+ "type" : "APACHE_DRILL_PHYSICAL",
+ "resultMode" : "EXEC"
+ },
+ "graph" : [ {
+ "pop" : "parquet-scan",
+ "@id" : 1,
+ "entries" : [ {
+ "path" : "/tpch/nation.parquet"
+ } ],
+ "storage" : {
+ "type" : "file",
+ "connection" : "classpath:///",
+ "workspaces" : null,
+ "formats" : {
+ "psv" : {
+ "type" : "text",
+ "extensions" : [ "tbl" ],
+ "delimiter" : "|"
+ },
+ "csv" : {
+ "type" : "text",
+ "extensions" : [ "csv" ],
+ "delimiter" : ","
+ },
+ "tsv" : {
+ "type" : "text",
+ "extensions" : [ "tsv" ],
+ "delimiter" : "\t"
+ },
+ "parquet" : {
+ "type" : "parquet"
+ },
+ "json" : {
+ "type" : "json"
+ }
+ }
+ },
+ "format" : {
+ "type" : "parquet"
+ },
+ "selectionRoot" : "/Users/mbaid/sources/drill/tpch-work/sample-data/nationsMF"
+ }, {
+ "pop" : "project",
+ "@id" : 2,
+ "exprs" : [ {
+ "ref" : "`N_NATIONKEY`",
+ "expr" : "`N_NATIONKEY`"
+ } ],
+ "child" : 1
+ }, {
+ "pop" : "hash-to-random-exchange",
+ "@id" : 3,
+ "child" : 2,
+ "expr" : "hash(`N_NATIONKEY`) "
+ }, {
+ "pop" : "union-exchange",
+ "@id" : 4,
+ "child" : 3
+ },
+{
+ "pop" : "project",
+ "@id" : 5,
+ "exprs" : [ {
+ "ref" : "`N_NATIONKEY`",
+ "expr" : "`N_NATIONKEY`"
+ } ],
+ "child" : 4
+ },
+{
+ "pop" : "limit",
+ "@id" : 6,
+ "child" : 5,
+ "first" : 0,
+ "last" : 1
+ }, {
+ "pop" : "screen",
+ "@id" : 7,
+ "child" : 6
+ } ]
+}
[5/5] git commit: DRILL-438: Add support for Views (CREATE,
DROP and select)
Posted by ja...@apache.org.
DRILL-438: Add support for Views (CREATE, DROP and select)
Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/b7bf00cb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/b7bf00cb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/b7bf00cb
Branch: refs/heads/master
Commit: b7bf00cbbdc410861061e59b122a40083b527564
Parents: cd4f281
Author: vkorukanti <ve...@gmail.com>
Authored: Thu Apr 24 11:57:44 2014 -0700
Committer: Jacques Nadeau <ja...@apache.org>
Committed: Wed May 7 19:18:42 2014 -0700
----------------------------------------------------------------------
.../exec/store/hbase/HBaseSchemaFactory.java | 11 +-
.../exec/store/hbase/HBaseStoragePlugin.java | 5 +-
exec/java-exec/src/main/codegen/data/Parser.tdd | 7 +-
.../src/main/codegen/includes/parserImpls.ftl | 52 ++++
.../apache/drill/exec/ops/FragmentContext.java | 12 +-
.../org/apache/drill/exec/ops/QueryContext.java | 2 +-
.../drill/exec/planner/logical/DrillOptiq.java | 1 +
.../exec/planner/logical/DrillViewTable.java | 66 +++++
.../drill/exec/planner/sql/DrillSqlWorker.java | 17 +-
.../exec/planner/sql/handlers/ViewHandler.java | 146 +++++++++++
.../exec/planner/sql/parser/DrillSqlCall.java | 39 +++
.../exec/planner/sql/parser/SqlCreateView.java | 100 ++++++++
.../planner/sql/parser/SqlDescribeTable.java | 11 +-
.../exec/planner/sql/parser/SqlDropView.java | 65 +++++
.../exec/planner/sql/parser/SqlShowSchemas.java | 10 +-
.../exec/planner/sql/parser/SqlShowTables.java | 11 +-
.../exec/planner/sql/parser/SqlUseSchema.java | 11 +-
.../types/DrillFixedRelDataTypeImpl.java | 104 ++++++++
.../apache/drill/exec/rpc/user/UserSession.java | 5 +
.../apache/drill/exec/rpc/user/ViewStore.java | 93 +++++++
.../apache/drill/exec/store/AbstractSchema.java | 17 +-
.../apache/drill/exec/store/SchemaFactory.java | 3 +-
.../drill/exec/store/StoragePluginRegistry.java | 5 +-
.../drill/exec/store/dfs/FileSystemPlugin.java | 10 +-
.../exec/store/dfs/FileSystemSchemaFactory.java | 19 +-
.../exec/store/dfs/WorkspaceSchemaFactory.java | 35 ++-
.../exec/store/hive/HiveStoragePlugin.java | 6 +-
.../store/hive/schema/HiveDatabaseSchema.java | 5 +-
.../store/hive/schema/HiveSchemaFactory.java | 8 +-
.../store/ischema/InfoSchemaStoragePlugin.java | 9 +-
.../exec/store/mock/MockStorageEngine.java | 3 +-
.../drill/exec/store/sys/SystemTablePlugin.java | 7 +-
.../java/org/apache/drill/PlanningBase.java | 2 +-
.../org/apache/drill/TestTpchSingleMode.java | 2 +-
.../drill/exec/store/TestOrphanSchema.java | 3 +-
.../drill/exec/store/ischema/OrphanSchema.java | 3 +-
.../src/test/resources/queries/tpch/15.sql | 2 +
.../apache/drill/jdbc/test/TestJdbcQuery.java | 251 ++++++++++++++++++-
38 files changed, 1082 insertions(+), 76 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseSchemaFactory.java
----------------------------------------------------------------------
diff --git a/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseSchemaFactory.java b/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseSchemaFactory.java
index 7f67f83..c4ac08c 100644
--- a/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseSchemaFactory.java
+++ b/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseSchemaFactory.java
@@ -19,14 +19,17 @@ package org.apache.drill.exec.store.hbase;
import java.io.IOException;
import java.util.Collections;
+import java.util.List;
import java.util.Set;
+import com.google.common.collect.ImmutableList;
import net.hydromatic.optiq.Schema;
import net.hydromatic.optiq.SchemaPlus;
+import net.hydromatic.optiq.Table;
import org.apache.drill.exec.planner.logical.DrillTable;
import org.apache.drill.exec.planner.logical.DynamicDrillTable;
-import org.apache.drill.exec.rpc.user.DrillUser;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.store.AbstractSchema;
import org.apache.drill.exec.store.SchemaFactory;
import org.apache.hadoop.hbase.HTableDescriptor;
@@ -46,7 +49,7 @@ public class HBaseSchemaFactory implements SchemaFactory {
}
@Override
- public void registerSchemas(DrillUser user, SchemaPlus parent) {
+ public void registerSchemas(UserSession session, SchemaPlus parent) {
HBaseSchema schema = new HBaseSchema(schemaName);
SchemaPlus hPlus = parent.add(schemaName, schema);
schema.setHolder(hPlus);
@@ -55,7 +58,7 @@ public class HBaseSchemaFactory implements SchemaFactory {
class HBaseSchema extends AbstractSchema {
public HBaseSchema(String name) {
- super(name);
+ super(ImmutableList.<String>of(), name);
}
public void setHolder(SchemaPlus plusOfThis) {
@@ -72,7 +75,7 @@ public class HBaseSchemaFactory implements SchemaFactory {
}
@Override
- public DrillTable getTable(String name) {
+ public Table getTable(String name) {
Object selection = new HBaseScanSpec(name);
return new DynamicDrillTable(plugin, schemaName, selection, plugin.getConfig());
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseStoragePlugin.java
----------------------------------------------------------------------
diff --git a/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseStoragePlugin.java b/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseStoragePlugin.java
index c1fb6af..ea1550d 100644
--- a/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseStoragePlugin.java
+++ b/contrib/storage-hbase/src/main/java/org/apache/drill/exec/store/hbase/HBaseStoragePlugin.java
@@ -27,6 +27,7 @@ import org.apache.drill.common.JSONOptions;
import org.apache.drill.exec.rpc.user.DrillUser;
import org.apache.drill.common.expression.SchemaPath;
import org.apache.drill.common.logical.StoragePluginConfig;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.store.AbstractStoragePlugin;
import org.apache.drill.exec.store.StoragePluginOptimizerRule;
@@ -67,8 +68,8 @@ public class HBaseStoragePlugin extends AbstractStoragePlugin {
}
@Override
- public void registerSchemas(DrillUser user, SchemaPlus parent) {
- schemaFactory.registerSchemas(user, parent);
+ public void registerSchemas(UserSession session, SchemaPlus parent) {
+ schemaFactory.registerSchemas(session, parent);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/codegen/data/Parser.tdd
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/data/Parser.tdd b/exec/java-exec/src/main/codegen/data/Parser.tdd
index 4f47795..176ee79 100644
--- a/exec/java-exec/src/main/codegen/data/Parser.tdd
+++ b/exec/java-exec/src/main/codegen/data/Parser.tdd
@@ -29,9 +29,10 @@
# List of keywords.
keywords: [
"DATABASES",
+ "REPLACE",
"SCHEMAS",
"SHOW",
- "TABLES"
+ "TABLES",
"USE"
]
@@ -40,7 +41,9 @@
"SqlShowTables()",
"SqlShowSchemas()",
"SqlDescribeTable()",
- "SqlUseSchema()"
+ "SqlUseSchema()",
+ "SqlCreateOrReplaceView()",
+ "SqlDropView()"
]
# List of methods for parsing custom literals.
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/codegen/includes/parserImpls.ftl
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/includes/parserImpls.ftl b/exec/java-exec/src/main/codegen/includes/parserImpls.ftl
index cd5ee72..5b6e2b5 100644
--- a/exec/java-exec/src/main/codegen/includes/parserImpls.ftl
+++ b/exec/java-exec/src/main/codegen/includes/parserImpls.ftl
@@ -113,3 +113,55 @@ SqlNode SqlUseSchema():
return new SqlUseSchema(pos, schema);
}
}
+
+/**
+ * Parses a create view or replace existing view statement.
+ * CREATE [OR REPLACE] VIEW view_name AS select_statement
+ */
+SqlNode SqlCreateOrReplaceView() :
+{
+ SqlParserPos pos;
+ boolean replaceView = false;
+ SqlIdentifier viewName;
+ SqlNode query;
+ SqlNodeList fieldList = null;
+}
+{
+ <CREATE> { pos = getPos(); }
+ [ <OR> <REPLACE> { replaceView = true; } ]
+ <VIEW>
+ viewName = CompoundIdentifier()
+ [
+ <LPAREN>
+ fieldList = SimpleIdentifierCommaList()
+ <RPAREN>
+ {
+ for(SqlNode node : fieldList)
+ {
+ if (((SqlIdentifier)node).isStar())
+ throw new ParseException("View's field list has a '*', which is invalid.");
+ }
+ }
+ ]
+ <AS>
+ query = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
+ {
+ return new SqlCreateView(pos, viewName, fieldList, query, replaceView);
+ }
+}
+
+/**
+ * Parses a drop view statement.
+ * DROP VIEW view_name;
+ */
+SqlNode SqlDropView() :
+{
+ SqlParserPos pos;
+}
+{
+ <DROP> { pos = getPos(); }
+ <VIEW>
+ {
+ return new SqlDropView(pos, CompoundIdentifier());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/ops/FragmentContext.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/ops/FragmentContext.java b/exec/java-exec/src/main/java/org/apache/drill/exec/ops/FragmentContext.java
index 2a6ab0e..38d76e0 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/ops/FragmentContext.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/ops/FragmentContext.java
@@ -123,9 +123,15 @@ public class FragmentContext implements Closeable {
}
public SchemaPlus getRootSchema(){
- SchemaPlus root = Frameworks.createRootSchema();
- context.getStorage().getSchemaFactory().registerSchemas(null, root);
- return root;
+ if (connection == null) {
+ fail(new UnsupportedOperationException("Schema tree can only be created in root fragment. " +
+ "This is a non-root fragment."));
+ return null;
+ } else {
+ SchemaPlus root = Frameworks.createRootSchema();
+ context.getStorage().getSchemaFactory().registerSchemas(connection.getSession(), root);
+ return root;
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/ops/QueryContext.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/ops/QueryContext.java b/exec/java-exec/src/main/java/org/apache/drill/exec/ops/QueryContext.java
index f6ce04f..e3d2f54 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/ops/QueryContext.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/ops/QueryContext.java
@@ -79,7 +79,7 @@ public class QueryContext{
public SchemaPlus getRootSchema(){
SchemaPlus rootSchema = Frameworks.createRootSchema();
- drillbitContext.getSchemaFactory().registerSchemas(session.getUser(), rootSchema);
+ drillbitContext.getSchemaFactory().registerSchemas(session, rootSchema);
return rootSchema;
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
index 2e61970..aee6da4 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
@@ -249,6 +249,7 @@ public class DrillOptiq {
case "INTERVAL_YEAR_MONTH": castType = Types.required(MinorType.INTERVALYEAR); break;
case "INTERVAL_DAY_TIME": castType = Types.required(MinorType.INTERVALDAY); break;
+ case "ANY": return arg; // Type will be same as argument.
default: castType = Types.required(MinorType.valueOf(call.getType().getSqlTypeName().getName()));
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillViewTable.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillViewTable.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillViewTable.java
new file mode 100644
index 0000000..6415869
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillViewTable.java
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.planner.logical;
+
+import com.google.common.collect.ImmutableList;
+import net.hydromatic.optiq.impl.ViewTable;
+import org.apache.drill.exec.planner.types.DrillFixedRelDataTypeImpl;
+import org.apache.drill.exec.planner.types.RelDataTypeDrillImpl;
+import org.apache.drill.exec.planner.types.RelDataTypeHolder;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptTable;
+import org.eigenbase.relopt.RelOptTable.ToRelContext;
+import org.eigenbase.relopt.RelOptUtil;
+import org.eigenbase.reltype.*;
+
+import java.util.List;
+
+public class DrillViewTable extends ViewTable {
+ private RelDataType rowType;
+ private boolean starSchema = false; // is the view schema "*"?
+ private RelDataTypeHolder holder = new RelDataTypeHolder();
+
+ public DrillViewTable(String viewSql, List<String> schemaPath, RelDataType rowType) {
+ super(Object.class, null, viewSql, schemaPath);
+
+ this.rowType = rowType;
+ if (rowType.getFieldCount() == 1 && rowType.getFieldNames().get(0).equals("*"))
+ starSchema = true;
+ }
+
+ @Override
+ public RelDataType getRowType(RelDataTypeFactory typeFactory) {
+ // if the view's schema is a "*" schema, create dynamic row type. Otherwise create fixed row type.
+ if (starSchema)
+ return new RelDataTypeDrillImpl(holder, typeFactory);
+
+ return rowType;
+ }
+
+ @Override
+ public RelNode toRel(ToRelContext context, RelOptTable relOptTable) {
+ RelDataType rowType = relOptTable.getRowType();
+ RelNode rel = context.expandView(rowType, getViewSql(), getSchemaPath());
+
+ // if the View's field list is not "*", try to create a cast.
+ if (!starSchema)
+ return RelOptUtil.createCastRel(rel, rowType, true);
+
+ return rel;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
index 048d116..6e9a00f 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/DrillSqlWorker.java
@@ -34,17 +34,10 @@ import org.apache.drill.exec.physical.PhysicalPlan;
import org.apache.drill.exec.planner.logical.DrillRuleSets;
import org.apache.drill.exec.planner.physical.DrillDistributionTraitDef;
import org.apache.drill.exec.planner.sql.handlers.DefaultSqlHandler;
-import org.apache.drill.exec.planner.sql.handlers.DescribeTableHandler;
import org.apache.drill.exec.planner.sql.handlers.ExplainHandler;
import org.apache.drill.exec.planner.sql.handlers.SetOptionHandler;
-import org.apache.drill.exec.planner.sql.handlers.ShowSchemasHandler;
-import org.apache.drill.exec.planner.sql.handlers.ShowTablesHandler;
import org.apache.drill.exec.planner.sql.handlers.SqlHandler;
-import org.apache.drill.exec.planner.sql.handlers.UseSchemaHandler;
-import org.apache.drill.exec.planner.sql.parser.SqlDescribeTable;
-import org.apache.drill.exec.planner.sql.parser.SqlShowSchemas;
-import org.apache.drill.exec.planner.sql.parser.SqlShowTables;
-import org.apache.drill.exec.planner.sql.parser.SqlUseSchema;
+import org.apache.drill.exec.planner.sql.parser.DrillSqlCall;
import org.apache.drill.exec.planner.sql.parser.impl.DrillParserImpl;
import org.apache.drill.exec.store.StoragePluginRegistry;
import org.eigenbase.rel.RelCollationTraitDef;
@@ -113,10 +106,10 @@ public class DrillSqlWorker {
handler = new SetOptionHandler(context);
break;
case OTHER:
- if (sqlNode instanceof SqlShowTables){ handler = new ShowTablesHandler(planner, context); break; }
- else if (sqlNode instanceof SqlShowSchemas){ handler = new ShowSchemasHandler(planner, context); break; }
- else if (sqlNode instanceof SqlDescribeTable){ handler = new DescribeTableHandler(planner, context); break; }
- else if (sqlNode instanceof SqlUseSchema){ handler = new UseSchemaHandler(context); break; }
+ if (sqlNode instanceof DrillSqlCall) {
+ handler = ((DrillSqlCall)sqlNode).getSqlHandler(planner, context);
+ break;
+ }
// fallthrough
default:
handler = new DefaultSqlHandler(planner, context);
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ViewHandler.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ViewHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ViewHandler.java
new file mode 100644
index 0000000..a78c54f
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/ViewHandler.java
@@ -0,0 +1,146 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.planner.sql.handlers;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.google.common.base.Joiner;
+import net.hydromatic.optiq.SchemaPlus;
+import net.hydromatic.optiq.impl.ViewTable;
+import net.hydromatic.optiq.tools.Planner;
+import net.hydromatic.optiq.tools.RelConversionException;
+import net.hydromatic.optiq.tools.ValidationException;
+
+import org.apache.drill.exec.ops.QueryContext;
+import org.apache.drill.exec.physical.PhysicalPlan;
+import org.apache.drill.exec.planner.logical.DrillViewTable;
+import org.apache.drill.exec.planner.sql.DirectPlan;
+import org.apache.drill.exec.planner.sql.parser.SqlCreateView;
+import org.apache.drill.exec.planner.sql.parser.SqlDropView;
+import org.apache.drill.exec.planner.types.DrillFixedRelDataTypeImpl;
+import org.apache.drill.exec.store.AbstractSchema;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.sql.SqlNode;
+
+public abstract class ViewHandler implements SqlHandler{
+ static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ViewHandler.class);
+
+ protected Planner planner;
+ protected QueryContext context;
+
+ public ViewHandler(Planner planner, QueryContext context) {
+ this.planner = planner;
+ this.context = context;
+ }
+
+ /** From a given SchemaPlus return a mutable Drill schema object AbstractSchema if exists. Otherwise throw errors. */
+ protected static AbstractSchema getDrillSchema(SchemaPlus schemaPlus) throws Exception{
+ AbstractSchema drillSchema;
+ try {
+ drillSchema = schemaPlus.unwrap(AbstractSchema.class);
+ } catch(ClassCastException e) {
+ throw new Exception(String.format("Can't create view in schema '%s'", schemaPlus.getName()), e);
+ }
+
+ if (!drillSchema.isMutable())
+ throw new Exception(String.format("Views are not allowed in schema '%s'", schemaPlus.getName()));
+
+ return drillSchema;
+ }
+
+ /** Handler for Create View DDL command */
+ public static class CreateView extends ViewHandler {
+
+ public CreateView(Planner planner, QueryContext context) {
+ super(planner, context);
+ }
+
+ @Override
+ public PhysicalPlan getPlan(SqlNode sqlNode) throws ValidationException, RelConversionException, IOException {
+ SqlCreateView createView = DefaultSqlHandler.unwrap(sqlNode, SqlCreateView.class);
+
+ try {
+ AbstractSchema drillSchema = getDrillSchema(context.getNewDefaultSchema());
+
+ String viewSql = createView.getQuery().toString();
+
+ SqlNode validatedQuery = planner.validate(createView.getQuery());
+ RelNode validatedRelNode = planner.convert(validatedQuery);
+
+ // If view's field list is specified then its size should match view's query field list size.
+ RelDataType queryRowType = validatedRelNode.getRowType();
+
+ List<String> viewFieldNames = createView.getFieldNames();
+ if (viewFieldNames.size() > 0) {
+ // number of fields match.
+ if (viewFieldNames.size() != queryRowType.getFieldCount())
+ throw new Exception("View's field list and View's query field list have different counts.");
+
+ // make sure View's query field list has no "*"
+ for(String field : queryRowType.getFieldNames()) {
+ if (field.equals("*"))
+ throw new Exception("View's query field list has a '*', which is invalid when View's field list is specified.");
+ }
+
+ queryRowType = new DrillFixedRelDataTypeImpl(planner.getTypeFactory(), viewFieldNames);
+ }
+
+ ViewTable viewTable = new DrillViewTable(viewSql, drillSchema.getSchemaPath(), queryRowType);
+
+ String schemaPath = Joiner.on(".").join(drillSchema.getSchemaPath());
+
+ boolean replaced = context.getSession().getViewStore().addView(
+ schemaPath, createView.getViewName(), viewTable, createView.getReplace());
+
+ String summary = String.format("View '%s' %s successfully in '%s' schema",
+ createView.getViewName(), replaced ? "replaced" : "created", schemaPath);
+
+ return DirectPlan.createDirectPlan(context, true, summary);
+ } catch(Exception e) {
+ logger.error("Failed to create view '{}'", createView.getViewName(), e);
+ return DirectPlan.createDirectPlan(context, false, String.format("Error: %s", e.getMessage()));
+ }
+ }
+ }
+
+ /** Handler for Drop View DDL command. */
+ public static class DropView extends ViewHandler {
+ public DropView(QueryContext context) {
+ super(null, context);
+ }
+
+ @Override
+ public PhysicalPlan getPlan(SqlNode sqlNode) throws ValidationException, RelConversionException, IOException {
+ SqlDropView createView = DefaultSqlHandler.unwrap(sqlNode, SqlDropView.class);
+
+ try {
+ AbstractSchema drillSchema = getDrillSchema(context.getNewDefaultSchema());
+ String schemaPath = Joiner.on(".").join(drillSchema.getSchemaPath());
+ context.getSession().getViewStore().dropView(schemaPath, createView.getViewName());
+
+ return DirectPlan.createDirectPlan(context, true,
+ String.format("View '%s' deleted successfully from '%s' schema", createView.getViewName(), schemaPath));
+ } catch(Exception e) {
+ logger.debug("Failed to delete view {}", createView.getViewName(), e);
+ return DirectPlan.createDirectPlan(context, false, String.format("Error: %s", e.getMessage()));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/DrillSqlCall.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/DrillSqlCall.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/DrillSqlCall.java
new file mode 100644
index 0000000..32f57b4
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/DrillSqlCall.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.planner.sql.parser;
+
+import net.hydromatic.optiq.tools.Planner;
+import org.apache.drill.exec.ops.QueryContext;
+import org.apache.drill.exec.planner.sql.handlers.DefaultSqlHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandler;
+import org.eigenbase.sql.SqlCall;
+import org.eigenbase.sql.parser.SqlParserPos;
+
+/**
+ * SqlCall interface with addition of method to get the handler.
+ */
+public abstract class DrillSqlCall extends SqlCall {
+
+ public DrillSqlCall(SqlParserPos pos) {
+ super(pos);
+ }
+
+ public SqlHandler getSqlHandler(Planner planner, QueryContext context) {
+ return new DefaultSqlHandler(planner, context);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateView.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateView.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateView.java
new file mode 100644
index 0000000..b124e1d
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlCreateView.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.planner.sql.parser;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.ImmutableList;
+import net.hydromatic.optiq.tools.Planner;
+import org.apache.drill.exec.ops.QueryContext;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandler;
+import org.apache.drill.exec.planner.sql.handlers.ViewHandler;
+import org.eigenbase.sql.*;
+import org.eigenbase.sql.parser.SqlParserPos;
+
+import java.util.List;
+
+public class SqlCreateView extends DrillSqlCall {
+ public static final SqlSpecialOperator OPERATOR = new SqlSpecialOperator("CREATE_VIEW", SqlKind.OTHER);
+
+ private SqlIdentifier viewName;
+ private SqlNodeList fieldList;
+ private SqlNode query;
+ private boolean replaceView;
+
+ public SqlCreateView(SqlParserPos pos, SqlIdentifier viewName, SqlNodeList fieldList,
+ SqlNode query, boolean replaceView) {
+ super(pos);
+ this.viewName = viewName;
+ this.query = query;
+ this.replaceView = replaceView;
+ this.fieldList = fieldList;
+ }
+
+ @Override
+ public SqlOperator getOperator() {
+ return OPERATOR;
+ }
+
+ @Override
+ public List<SqlNode> getOperandList() {
+ return ImmutableList.of(viewName, fieldList, query,
+ SqlLiteral.createBoolean(replaceView, SqlParserPos.ZERO));
+ }
+
+ @Override
+ public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
+ writer.keyword("CREATE");
+ if (replaceView) {
+ writer.keyword("OR");
+ writer.keyword("REPLACE");
+ }
+ writer.keyword("VIEW");
+ viewName.unparse(writer, leftPrec, rightPrec);
+ if (fieldList != null && fieldList.size() > 0) {
+ writer.keyword("(");
+ fieldList.get(0).unparse(writer, leftPrec, rightPrec);
+ for(int i=1; i<fieldList.size(); i++) {
+ writer.keyword(",");
+ fieldList.get(i).unparse(writer, leftPrec, rightPrec);
+ }
+ writer.keyword(")");
+ }
+ writer.keyword("AS");
+ query.unparse(writer, leftPrec, rightPrec);
+ }
+
+ @Override
+ public SqlHandler getSqlHandler(Planner planner, QueryContext context) {
+ return new ViewHandler.CreateView(planner, context);
+ }
+
+ public String getViewName() { return viewName.getSimple(); }
+
+ public List<String> getFieldNames() {
+ if (fieldList == null) return ImmutableList.of();
+
+ List<String> fieldNames = Lists.newArrayList();
+ for(SqlNode node : fieldList.getList()) {
+ fieldNames.add(node.toString());
+ }
+ return fieldNames;
+ }
+
+ public SqlNode getQuery() { return query; }
+ public boolean getReplace() { return replaceView; }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDescribeTable.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDescribeTable.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDescribeTable.java
index 24c2d03..0a666de 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDescribeTable.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDescribeTable.java
@@ -18,6 +18,10 @@
package org.apache.drill.exec.planner.sql.parser;
import com.google.common.collect.Lists;
+import net.hydromatic.optiq.tools.Planner;
+import org.apache.drill.exec.ops.QueryContext;
+import org.apache.drill.exec.planner.sql.handlers.DescribeTableHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandler;
import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.SqlParserPos;
@@ -27,7 +31,7 @@ import java.util.List;
* Sql parser tree node to represent statement:
* { DESCRIBE | DESC } tblname [col_name | wildcard ]
*/
-public class SqlDescribeTable extends SqlCall {
+public class SqlDescribeTable extends DrillSqlCall {
private final SqlIdentifier table;
private final SqlIdentifier column;
@@ -66,6 +70,11 @@ public class SqlDescribeTable extends SqlCall {
if (columnQualifier != null) columnQualifier.unparse(writer, leftPrec, rightPrec);
}
+ @Override
+ public SqlHandler getSqlHandler(Planner planner, QueryContext context) {
+ return new DescribeTableHandler(planner, context);
+ }
+
public SqlIdentifier getTable() { return table; }
public SqlIdentifier getColumn() { return column; }
public SqlNode getColumnQualifier() { return columnQualifier; }
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDropView.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDropView.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDropView.java
new file mode 100644
index 0000000..8ba7edd
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlDropView.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.planner.sql.parser;
+
+import com.google.common.collect.ImmutableList;
+import net.hydromatic.optiq.tools.Planner;
+import org.apache.drill.exec.ops.QueryContext;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandler;
+import org.apache.drill.exec.planner.sql.handlers.ViewHandler.DropView;
+import org.eigenbase.sql.*;
+import org.eigenbase.sql.parser.SqlParserPos;
+
+import java.util.List;
+
+public class SqlDropView extends DrillSqlCall {
+ public static final SqlSpecialOperator OPERATOR = new SqlSpecialOperator("DROP_VIEW", SqlKind.OTHER);
+
+ private SqlIdentifier viewName;
+
+ public SqlDropView(SqlParserPos pos, SqlIdentifier viewName) {
+ super(pos);
+ this.viewName = viewName;
+ }
+
+ @Override
+ public SqlOperator getOperator() {
+ return OPERATOR;
+ }
+
+ @Override
+ public List<SqlNode> getOperandList() {
+ return ImmutableList.of((SqlNode)viewName);
+ }
+
+ @Override
+ public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
+ writer.keyword("DROP");
+ writer.keyword("VIEW");
+ viewName.unparse(writer, leftPrec, rightPrec);
+ }
+
+ @Override
+ public SqlHandler getSqlHandler(Planner planner, QueryContext context) {
+ return new DropView(context);
+ }
+
+ public String getViewName() {
+ return viewName.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowSchemas.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowSchemas.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowSchemas.java
index 526ae04..aa212a7 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowSchemas.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowSchemas.java
@@ -20,7 +20,8 @@ package org.apache.drill.exec.planner.sql.parser;
import com.google.common.collect.Lists;
import net.hydromatic.optiq.tools.Planner;
import org.apache.drill.exec.ops.QueryContext;
-import org.apache.drill.exec.planner.sql.handlers.DefaultSqlHandler;
+import org.apache.drill.exec.planner.sql.handlers.ShowSchemasHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandler;
import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.SqlParserPos;
@@ -30,7 +31,7 @@ import java.util.List;
* Sql parse tree node to represent statement:
* SHOW {DATABASES | SCHEMAS} [LIKE 'pattern' | WHERE expr]
*/
-public class SqlShowSchemas extends SqlCall {
+public class SqlShowSchemas extends DrillSqlCall {
private final SqlNode likePattern;
private final SqlNode whereClause;
@@ -68,6 +69,11 @@ public class SqlShowSchemas extends SqlCall {
if (whereClause != null) whereClause.unparse(writer, leftPrec, rightPrec);
}
+ @Override
+ public SqlHandler getSqlHandler(Planner planner, QueryContext context) {
+ return new ShowSchemasHandler(planner, context);
+ }
+
public SqlNode getLikePattern() { return likePattern; }
public SqlNode getWhereClause() { return whereClause; }
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowTables.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowTables.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowTables.java
index aad5ca5..e3be378 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowTables.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlShowTables.java
@@ -18,6 +18,10 @@
package org.apache.drill.exec.planner.sql.parser;
import com.google.common.collect.Lists;
+import net.hydromatic.optiq.tools.Planner;
+import org.apache.drill.exec.ops.QueryContext;
+import org.apache.drill.exec.planner.sql.handlers.ShowTablesHandler;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandler;
import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.SqlParserPos;
@@ -27,7 +31,7 @@ import java.util.List;
* Sql parse tree node to represent statement:
* SHOW TABLES [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr]
*/
-public class SqlShowTables extends SqlCall {
+public class SqlShowTables extends DrillSqlCall {
private final SqlIdentifier db;
private final SqlNode likePattern;
@@ -69,6 +73,11 @@ public class SqlShowTables extends SqlCall {
if (whereClause != null) whereClause.unparse(writer, leftPrec, rightPrec);
}
+ @Override
+ public SqlHandler getSqlHandler(Planner planner, QueryContext context) {
+ return new ShowTablesHandler(planner, context);
+ }
+
public SqlIdentifier getDb() { return db; }
public SqlNode getLikePattern() { return likePattern; }
public SqlNode getWhereClause() { return whereClause; }
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlUseSchema.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlUseSchema.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlUseSchema.java
index a48963e..92d3aff 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlUseSchema.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/SqlUseSchema.java
@@ -18,6 +18,10 @@
package org.apache.drill.exec.planner.sql.parser;
import com.google.common.collect.ImmutableList;
+import net.hydromatic.optiq.tools.Planner;
+import org.apache.drill.exec.ops.QueryContext;
+import org.apache.drill.exec.planner.sql.handlers.SqlHandler;
+import org.apache.drill.exec.planner.sql.handlers.UseSchemaHandler;
import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.SqlParserPos;
@@ -26,7 +30,7 @@ import java.util.List;
/**
* Sql parser tree node to represent <code>USE SCHEMA</code> statement.
*/
-public class SqlUseSchema extends SqlCall {
+public class SqlUseSchema extends DrillSqlCall {
public static final SqlSpecialOperator OPERATOR =
new SqlSpecialOperator("USE_SCHEMA", SqlKind.OTHER);
@@ -54,6 +58,11 @@ public class SqlUseSchema extends SqlCall {
schema.unparse(writer, leftPrec, rightPrec);
}
+ @Override
+ public SqlHandler getSqlHandler(Planner planner, QueryContext context) {
+ return new UseSchemaHandler(context);
+ }
+
/**
* Get the schema name. A schema identifier can contain more than one level of schema.
* Ex: "dfs.home" identifier contains two levels "dfs" and "home".
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/DrillFixedRelDataTypeImpl.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/DrillFixedRelDataTypeImpl.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/DrillFixedRelDataTypeImpl.java
new file mode 100644
index 0000000..f20a174
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/types/DrillFixedRelDataTypeImpl.java
@@ -0,0 +1,104 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.planner.types;
+
+import com.google.common.collect.Lists;
+import org.eigenbase.reltype.RelDataTypeFactory;
+import org.eigenbase.reltype.RelDataTypeField;
+import org.eigenbase.reltype.RelDataTypeFieldImpl;
+import org.eigenbase.reltype.RelDataTypeImpl;
+import org.eigenbase.reltype.RelDataTypePrecedenceList;
+import org.eigenbase.sql.type.SqlTypeExplicitPrecedenceList;
+import org.eigenbase.sql.type.SqlTypeName;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Implements RowType for fixed field list with ANY type.
+ */
+public class DrillFixedRelDataTypeImpl extends RelDataTypeImpl {
+ private List<RelDataTypeField> fields = Lists.newArrayList();
+ private final RelDataTypeFactory typeFactory;
+
+ public DrillFixedRelDataTypeImpl(RelDataTypeFactory typeFactory, List<String> columnNames) {
+ this.typeFactory = typeFactory;
+
+ // Add the initial list of columns.
+ for (String column : columnNames)
+ addField(column);
+ computeDigest();
+ }
+
+ private void addField(String columnName) {
+ RelDataTypeField newField = new RelDataTypeFieldImpl(
+ columnName, fields.size(), typeFactory.createSqlType(SqlTypeName.ANY));
+ fields.add(newField);
+ }
+
+ @Override
+ public List<RelDataTypeField> getFieldList() {
+ return fields;
+ }
+
+ @Override
+ public int getFieldCount() {
+ return fields.size();
+ }
+
+ @Override
+ public RelDataTypeField getField(String fieldName, boolean caseSensitive) {
+ // return the field with given name if available.
+ for (RelDataTypeField f : fields) {
+ if (fieldName.equalsIgnoreCase(f.getName())) {
+ return f;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public List<String> getFieldNames() {
+ List<String> fieldNames = Lists.newArrayList();
+ for(RelDataTypeField f : fields){
+ fieldNames.add(f.getName());
+ }
+
+ return fieldNames;
+ }
+
+ @Override
+ public SqlTypeName getSqlTypeName() {
+ return SqlTypeName.ANY;
+ }
+
+ @Override
+ public RelDataTypePrecedenceList getPrecedenceList() {
+ return new SqlTypeExplicitPrecedenceList((List<SqlTypeName>) (List) Collections.emptyList());
+ }
+
+ @Override
+ protected void generateTypeString(StringBuilder sb, boolean withDetail) {
+ sb.append("(DrillFixedRecordRow" + getFieldNames() + ")");
+ }
+
+ @Override
+ public boolean isStruct() {
+ return true;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserSession.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserSession.java b/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserSession.java
index 86c4bad..1607179 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserSession.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/UserSession.java
@@ -41,11 +41,14 @@ public class UserSession {
private UserCredentials credentials;
private Map<String, String> properties;
private OptionManager options;
+ private ViewStore viewStore;
public UserSession(OptionManager systemOptions, UserCredentials credentials, UserProperties properties) throws IOException{
this.credentials = credentials;
this.options = new SessionOptionManager(systemOptions);
this.properties = Maps.newHashMap();
+ this.viewStore = new ViewStore();
+
if (properties == null) return;
for (int i=0; i<properties.getPropertiesCount(); i++) {
Property prop = properties.getProperties(i);
@@ -61,6 +64,8 @@ public class UserSession {
return user;
}
+ public ViewStore getViewStore() { return viewStore; }
+
/**
* Update the schema path for the session.
* @param fullPath The desired path to set to.
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/ViewStore.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/ViewStore.java b/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/ViewStore.java
new file mode 100644
index 0000000..f5de489
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/rpc/user/ViewStore.java
@@ -0,0 +1,93 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.rpc.user;
+
+import com.google.common.collect.*;
+import net.hydromatic.optiq.impl.ViewTable;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * ViewStore for holding and managing the views created in a user session.
+ *
+ * Note: Currently these views are for session only and doesn't persist across session.
+ */
+public class ViewStore {
+ // Map of views associated in a schema
+ private Map<String, Map<String, ViewTable>> viewMap = Maps.newHashMap();
+
+ /**
+ * Get all views belonging to the given schema.
+ * @param schemaPath
+ * @return Map of (viewName, ViewTable) entries.
+ */
+ public Map<String, ViewTable> getViews(String schemaPath) {
+ if (viewMap.containsKey(schemaPath))
+ return viewMap.get(schemaPath);
+
+ return Collections.emptyMap();
+ }
+
+ /**
+ * Add the given view to store.
+ *
+ * @param schemaPath
+ * @param viewName Name of the view.
+ * @param view {@link ViewTable} object.
+ * @param replace If a view with given name already exists, replace it.
+ * @return True if a view is replaced.
+ */
+ public boolean addView(String schemaPath, String viewName, ViewTable view, boolean replace) throws ViewAlreadyExistsException {
+ if (!viewMap.containsKey(schemaPath)) {
+ Map<String, ViewTable> viewNameMap = Maps.newHashMap();
+ viewMap.put(schemaPath, viewNameMap);
+ }
+
+ boolean replaced = false;
+ if (viewMap.get(schemaPath).get(viewName) != null) {
+ if (replace)
+ replaced = true;
+ else
+ throw new ViewAlreadyExistsException(schemaPath, viewName);
+ }
+ viewMap.get(schemaPath).put(viewName, view);
+
+ return replaced;
+ }
+
+ /** Delete the ViewTable with given parameters from store. */
+ public void dropView(String schemaPath, String viewName) throws NoSuchViewExistsException {
+ if (viewMap.containsKey(schemaPath) && viewMap.get(schemaPath).containsKey(viewName))
+ viewMap.get(schemaPath).remove(viewName);
+ else
+ throw new NoSuchViewExistsException(schemaPath, viewName);
+ }
+
+ public static class ViewAlreadyExistsException extends Exception {
+ public ViewAlreadyExistsException(String schemaPath, String viewName){
+ super(String.format("Schema '%s' already contains a view view name '%s'.", schemaPath, viewName));
+ }
+ }
+
+ public static class NoSuchViewExistsException extends Exception {
+ public NoSuchViewExistsException(String schemaPath, String viewName){
+ super(String.format("Schema '%s' has no view named '%s'", schemaPath, viewName));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/AbstractSchema.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/AbstractSchema.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/AbstractSchema.java
index 64087f5..5806ca7 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/AbstractSchema.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/AbstractSchema.java
@@ -19,24 +19,31 @@ package org.apache.drill.exec.store;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.Set;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
import net.hydromatic.linq4j.expressions.DefaultExpression;
import net.hydromatic.linq4j.expressions.Expression;
import net.hydromatic.optiq.Function;
import net.hydromatic.optiq.Schema;
import net.hydromatic.optiq.SchemaPlus;
+import net.hydromatic.optiq.Table;
import org.apache.drill.exec.planner.logical.DrillTable;
public abstract class AbstractSchema implements Schema{
static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(AbstractSchema.class);
+ protected final List<String> schemaPath;
protected final String name;
private static final Expression EXPRESSION = new DefaultExpression(Object.class);
- public AbstractSchema(String name) {
- super();
+ public AbstractSchema(List<String> parentSchemaPath, String name) {
+ schemaPath = Lists.newArrayList();
+ schemaPath.addAll(parentSchemaPath);
+ schemaPath.add(name);
this.name = name;
}
@@ -44,6 +51,10 @@ public abstract class AbstractSchema implements Schema{
return name;
}
+ public List<String> getSchemaPath() {
+ return schemaPath;
+ }
+
@Override
public Collection<Function> getFunctions(String name) {
return Collections.emptyList();
@@ -70,7 +81,7 @@ public abstract class AbstractSchema implements Schema{
}
@Override
- public DrillTable getTable(String name){
+ public Table getTable(String name){
return null;
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/SchemaFactory.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/SchemaFactory.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/SchemaFactory.java
index 60ccbe8..5acbe78 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/SchemaFactory.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/SchemaFactory.java
@@ -20,9 +20,10 @@ package org.apache.drill.exec.store;
import net.hydromatic.optiq.SchemaPlus;
import org.apache.drill.exec.rpc.user.DrillUser;
+import org.apache.drill.exec.rpc.user.UserSession;
public interface SchemaFactory {
static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SchemaFactory.class);
- public void registerSchemas(DrillUser user, SchemaPlus parent);
+ public void registerSchemas(UserSession session, SchemaPlus parent);
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java
index 948c74f..ad9a7db 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/StoragePluginRegistry.java
@@ -44,6 +44,7 @@ import org.apache.drill.exec.exception.DrillbitStartupException;
import org.apache.drill.exec.planner.logical.DrillRuleSets;
import org.apache.drill.exec.planner.logical.StoragePlugins;
import org.apache.drill.exec.rpc.user.DrillUser;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.store.dfs.FileSystemPlugin;
import org.apache.drill.exec.store.dfs.FormatPlugin;
@@ -223,9 +224,9 @@ public class StoragePluginRegistry implements Iterable<Map.Entry<String, Storage
public class DrillSchemaFactory implements SchemaFactory{
@Override
- public void registerSchemas(DrillUser user, SchemaPlus parent) {
+ public void registerSchemas(UserSession session, SchemaPlus parent) {
for(Map.Entry<String, StoragePlugin> e : plugins.entrySet()){
- e.getValue().registerSchemas(user, parent);
+ e.getValue().registerSchemas(session, parent);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/FileSystemPlugin.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/FileSystemPlugin.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/FileSystemPlugin.java
index dd0cef4..6ade4ee 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/FileSystemPlugin.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/FileSystemPlugin.java
@@ -83,16 +83,16 @@ public class FileSystemPlugin extends AbstractStoragePlugin{
List<WorkspaceSchemaFactory> factories = null;
if(config.workspaces == null || config.workspaces.isEmpty()){
- factories = Collections.singletonList(new WorkspaceSchemaFactory(this, "default", name, fs, "/", matchers));
+ factories = Collections.singletonList(new WorkspaceSchemaFactory(this, "default", name, fs, "/", matchers, true/*TODO*/));
}else{
factories = Lists.newArrayList();
for(Map.Entry<String, String> space : config.workspaces.entrySet()){
- factories.add(new WorkspaceSchemaFactory(this, space.getKey(), name, fs, space.getValue(), matchers));
+ factories.add(new WorkspaceSchemaFactory(this, space.getKey(), name, fs, space.getValue(), matchers, true/*TODO*/));
}
// if the "default" workspace is not given add one.
if (!config.workspaces.containsKey("default")) {
- factories.add(new WorkspaceSchemaFactory(this, "default", name, fs, "/", matchers));
+ factories.add(new WorkspaceSchemaFactory(this, "default", name, fs, "/", matchers, true/*TODO*/));
}
}
this.schemaFactory = new FileSystemSchemaFactory(name, factories);
@@ -130,8 +130,8 @@ public class FileSystemPlugin extends AbstractStoragePlugin{
}
@Override
- public void registerSchemas(DrillUser user, SchemaPlus parent) {
- schemaFactory.registerSchemas(user, parent);
+ public void registerSchemas(UserSession session, SchemaPlus parent) {
+ schemaFactory.registerSchemas(session, parent);
}
public FormatPlugin getFormatPlugin(String name){
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/FileSystemSchemaFactory.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/FileSystemSchemaFactory.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/FileSystemSchemaFactory.java
index 93bac0c..92a1efc 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/FileSystemSchemaFactory.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/FileSystemSchemaFactory.java
@@ -22,12 +22,15 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import com.google.common.collect.ImmutableList;
import net.hydromatic.optiq.Function;
import net.hydromatic.optiq.Schema;
import net.hydromatic.optiq.SchemaPlus;
+import net.hydromatic.optiq.Table;
import org.apache.drill.exec.planner.logical.DrillTable;
import org.apache.drill.exec.rpc.user.DrillUser;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.store.AbstractSchema;
import org.apache.drill.exec.store.SchemaFactory;
import org.apache.drill.exec.store.dfs.WorkspaceSchemaFactory.WorkspaceSchema;
@@ -52,8 +55,8 @@ public class FileSystemSchemaFactory implements SchemaFactory{
}
@Override
- public void registerSchemas(DrillUser user, SchemaPlus parent) {
- FileSystemSchema schema = new FileSystemSchema(schemaName);
+ public void registerSchemas(UserSession session, SchemaPlus parent) {
+ FileSystemSchema schema = new FileSystemSchema(schemaName, session);
SchemaPlus plusOfThis = parent.add(schema.getName(), schema);
schema.setPlus(plusOfThis);
}
@@ -63,10 +66,10 @@ public class FileSystemSchemaFactory implements SchemaFactory{
private final WorkspaceSchema defaultSchema;
private final Map<String, WorkspaceSchema> schemaMap = Maps.newHashMap();
- public FileSystemSchema(String name) {
- super(name);
+ public FileSystemSchema(String name, UserSession session) {
+ super(ImmutableList.<String>of(), name);
for(WorkspaceSchemaFactory f : factories){
- WorkspaceSchema s = f.createSchema();
+ WorkspaceSchema s = f.createSchema(getSchemaPath(), session);
schemaMap.put(s.getName(), s);
}
@@ -80,7 +83,7 @@ public class FileSystemSchemaFactory implements SchemaFactory{
}
@Override
- public DrillTable getTable(String name) {
+ public Table getTable(String name) {
return defaultSchema.getTable(name);
}
@@ -109,6 +112,10 @@ public class FileSystemSchemaFactory implements SchemaFactory{
return defaultSchema.getTableNames();
}
+ @Override
+ public boolean isMutable() {
+ return defaultSchema.isMutable();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/WorkspaceSchemaFactory.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/WorkspaceSchemaFactory.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/WorkspaceSchemaFactory.java
index 1551e5a..cbaf651 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/WorkspaceSchemaFactory.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/dfs/WorkspaceSchemaFactory.java
@@ -21,10 +21,14 @@ import java.io.IOException;
import java.util.List;
import java.util.Set;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Sets;
+import net.hydromatic.optiq.Table;
import org.apache.drill.common.exceptions.ExecutionSetupException;
import org.apache.drill.exec.planner.logical.DrillTable;
import org.apache.drill.exec.planner.logical.DynamicDrillTable;
import org.apache.drill.exec.planner.sql.ExpandingConcurrentMap;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.store.AbstractSchema;
import org.apache.drill.exec.store.dfs.shim.DrillFileSystem;
import org.apache.hadoop.fs.Path;
@@ -42,9 +46,10 @@ public class WorkspaceSchemaFactory implements ExpandingConcurrentMap.MapValueFa
private final String storageEngineName;
private final String schemaName;
private final FileSystemPlugin plugin;
+ private final boolean isMutable;
public WorkspaceSchemaFactory(FileSystemPlugin plugin, String schemaName, String storageEngineName, DrillFileSystem fileSystem, String path,
- List<FormatMatcher> formatMatchers) throws ExecutionSetupException {
+ List<FormatMatcher> formatMatchers, boolean isMutable) throws ExecutionSetupException {
this.fs = fileSystem;
this.plugin = plugin;
this.root = new Path(path);
@@ -58,10 +63,11 @@ public class WorkspaceSchemaFactory implements ExpandingConcurrentMap.MapValueFa
}
this.storageEngineName = storageEngineName;
this.schemaName = schemaName;
+ this.isMutable = isMutable;
}
- public WorkspaceSchema createSchema() {
- return new WorkspaceSchema(schemaName);
+ public WorkspaceSchema createSchema(List<String> parentSchemaPath, UserSession session) {
+ return new WorkspaceSchema(parentSchemaPath, schemaName, isMutable, session);
}
@Override
@@ -105,21 +111,32 @@ public class WorkspaceSchemaFactory implements ExpandingConcurrentMap.MapValueFa
public class WorkspaceSchema extends AbstractSchema {
private ExpandingConcurrentMap<String, DrillTable> tables = new ExpandingConcurrentMap<String, DrillTable>(WorkspaceSchemaFactory.this);
-
- public WorkspaceSchema(String name) {
- super(name);
+ private boolean isMutable;
+ private UserSession session;
+
+ public WorkspaceSchema(List<String> parentSchemaPath, String name, boolean isMutable, UserSession session) {
+ super(parentSchemaPath, name);
+ this.isMutable = isMutable;
+ this.session = session;
}
@Override
public Set<String> getTableNames() {
- return tables.keySet();
+ return Sets.union(tables.keySet(), session.getViewStore().getViews(Joiner.on(".").join(getSchemaPath())).keySet());
}
@Override
- public DrillTable getTable(String name) {
- return tables.get(name);
+ public Table getTable(String name) {
+ if (tables.containsKey(name))
+ return tables.get(name);
+
+ return session.getViewStore().getViews(Joiner.on(".").join(getSchemaPath())).get(name);
}
+ @Override
+ public boolean isMutable() {
+ return isMutable;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/HiveStoragePlugin.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/HiveStoragePlugin.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/HiveStoragePlugin.java
index 0a70b20..6d5f6d2 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/HiveStoragePlugin.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/HiveStoragePlugin.java
@@ -25,8 +25,8 @@ import net.hydromatic.optiq.SchemaPlus;
import org.apache.drill.common.JSONOptions;
import org.apache.drill.common.exceptions.ExecutionSetupException;
-import org.apache.drill.exec.rpc.user.DrillUser;
import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.store.AbstractStoragePlugin;
import org.apache.drill.exec.store.hive.schema.HiveSchemaFactory;
@@ -74,8 +74,8 @@ public class HiveStoragePlugin extends AbstractStoragePlugin {
}
@Override
- public void registerSchemas(DrillUser user, SchemaPlus parent) {
- schemaFactory.registerSchemas(user, parent);
+ public void registerSchemas(UserSession session, SchemaPlus parent) {
+ schemaFactory.registerSchemas(session, parent);
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/schema/HiveDatabaseSchema.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/schema/HiveDatabaseSchema.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/schema/HiveDatabaseSchema.java
index 3608ea7..4390d74 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/schema/HiveDatabaseSchema.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/schema/HiveDatabaseSchema.java
@@ -20,6 +20,7 @@ package org.apache.drill.exec.store.hive.schema;
import java.util.List;
import java.util.Set;
+import net.hydromatic.optiq.Table;
import org.apache.drill.exec.planner.logical.DrillTable;
import org.apache.drill.exec.store.AbstractSchema;
import org.apache.drill.exec.store.hive.schema.HiveSchemaFactory.HiveSchema;
@@ -36,13 +37,13 @@ public class HiveDatabaseSchema extends AbstractSchema{
List<String> tableList, //
HiveSchema hiveSchema, //
String name) {
- super(name);
+ super(hiveSchema.getSchemaPath(), name);
this.hiveSchema = hiveSchema;
this.tables = Sets.newHashSet(tableList);
}
@Override
- public DrillTable getTable(String tableName) {
+ public Table getTable(String tableName) {
return hiveSchema.getDrillTable(this.name, tableName);
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/schema/HiveSchemaFactory.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/schema/HiveSchemaFactory.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/schema/HiveSchemaFactory.java
index 7b30a41..4b22942 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/schema/HiveSchemaFactory.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/hive/schema/HiveSchemaFactory.java
@@ -23,12 +23,14 @@ import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
+import com.google.common.collect.ImmutableList;
import net.hydromatic.optiq.Schema;
import net.hydromatic.optiq.SchemaPlus;
import org.apache.drill.common.exceptions.ExecutionSetupException;
import org.apache.drill.exec.planner.logical.DrillTable;
import org.apache.drill.exec.rpc.user.DrillUser;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.store.AbstractSchema;
import org.apache.drill.exec.store.SchemaFactory;
import org.apache.drill.exec.store.hive.HiveReadEntry;
@@ -171,7 +173,7 @@ public class HiveSchemaFactory implements SchemaFactory {
}
@Override
- public void registerSchemas(DrillUser user, SchemaPlus parent) {
+ public void registerSchemas(UserSession session, SchemaPlus parent) {
HiveSchema schema = new HiveSchema(schemaName);
SchemaPlus hPlus = parent.add(schemaName, schema);
schema.setHolder(hPlus);
@@ -182,7 +184,7 @@ public class HiveSchemaFactory implements SchemaFactory {
private HiveDatabaseSchema defaultSchema;
public HiveSchema(String name) {
- super(name);
+ super(ImmutableList.<String>of(), name);
getSubSchema("default");
}
@@ -223,7 +225,7 @@ public class HiveSchemaFactory implements SchemaFactory {
}
@Override
- public DrillTable getTable(String name) {
+ public net.hydromatic.optiq.Table getTable(String name) {
if(defaultSchema == null){
return super.getTable(name);
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/ischema/InfoSchemaStoragePlugin.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/ischema/InfoSchemaStoragePlugin.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/ischema/InfoSchemaStoragePlugin.java
index e7e3f37..ecf5a8b 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/ischema/InfoSchemaStoragePlugin.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/ischema/InfoSchemaStoragePlugin.java
@@ -22,13 +22,16 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import com.google.common.collect.ImmutableList;
import net.hydromatic.optiq.SchemaPlus;
+import net.hydromatic.optiq.Table;
import org.apache.drill.common.JSONOptions;
import org.apache.drill.common.expression.SchemaPath;
import org.apache.drill.common.logical.StoragePluginConfig;
import org.apache.drill.exec.planner.logical.DrillTable;
import org.apache.drill.exec.rpc.user.DrillUser;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.store.AbstractSchema;
import org.apache.drill.exec.store.AbstractStoragePlugin;
@@ -66,7 +69,7 @@ public class InfoSchemaStoragePlugin extends AbstractStoragePlugin{
}
@Override
- public void registerSchemas(DrillUser user, SchemaPlus parent) {
+ public void registerSchemas(UserSession session, SchemaPlus parent) {
ISchema s = new ISchema(parent, this);
parent.add(s.getName(), s);
}
@@ -74,7 +77,7 @@ public class InfoSchemaStoragePlugin extends AbstractStoragePlugin{
private class ISchema extends AbstractSchema{
private Map<String, InfoSchemaDrillTable> tables;
public ISchema(SchemaPlus parent, InfoSchemaStoragePlugin plugin){
- super("INFORMATION_SCHEMA");
+ super(ImmutableList.<String>of(), "INFORMATION_SCHEMA");
Map<String, InfoSchemaDrillTable> tbls = Maps.newHashMap();
for(SelectedTable tbl : SelectedTable.values()){
tbls.put(tbl.name(), new InfoSchemaDrillTable(plugin, "INFORMATION_SCHEMA", tbl, config));
@@ -83,7 +86,7 @@ public class InfoSchemaStoragePlugin extends AbstractStoragePlugin{
}
@Override
- public DrillTable getTable(String name) {
+ public Table getTable(String name) {
return tables.get(name);
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/MockStorageEngine.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/MockStorageEngine.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/MockStorageEngine.java
index 4fe1d1b..1adbacc 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/MockStorageEngine.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/mock/MockStorageEngine.java
@@ -28,6 +28,7 @@ import org.apache.drill.common.expression.SchemaPath;
import org.apache.drill.common.logical.StoragePluginConfig;
import org.apache.drill.exec.physical.base.AbstractGroupScan;
import org.apache.drill.exec.rpc.user.DrillUser;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.store.AbstractStoragePlugin;
import org.apache.drill.exec.store.mock.MockGroupScanPOP.MockScanEntry;
@@ -55,7 +56,7 @@ public class MockStorageEngine extends AbstractStoragePlugin {
}
@Override
- public void registerSchemas(DrillUser user, SchemaPlus parent) {
+ public void registerSchemas(UserSession session, SchemaPlus parent) {
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/main/java/org/apache/drill/exec/store/sys/SystemTablePlugin.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/store/sys/SystemTablePlugin.java b/exec/java-exec/src/main/java/org/apache/drill/exec/store/sys/SystemTablePlugin.java
index 7fb8b6c..fd3a898 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/store/sys/SystemTablePlugin.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/store/sys/SystemTablePlugin.java
@@ -22,6 +22,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import com.google.common.collect.ImmutableList;
import net.hydromatic.optiq.SchemaPlus;
import org.apache.drill.common.JSONOptions;
@@ -30,7 +31,7 @@ import org.apache.drill.common.logical.StoragePluginConfig;
import org.apache.drill.exec.ops.FragmentContext;
import org.apache.drill.exec.physical.base.AbstractGroupScan;
import org.apache.drill.exec.planner.logical.DrillTable;
-import org.apache.drill.exec.rpc.user.DrillUser;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.server.options.DrillConfigIterator;
import org.apache.drill.exec.server.options.OptionValue;
@@ -60,7 +61,7 @@ public class SystemTablePlugin extends AbstractStoragePlugin{
}
@Override
- public void registerSchemas(DrillUser user, SchemaPlus parent) {
+ public void registerSchemas(UserSession session, SchemaPlus parent) {
parent.add(schema.getName(), schema);
}
@@ -89,7 +90,7 @@ public class SystemTablePlugin extends AbstractStoragePlugin{
private Set<String> tableNames;
public SystemSchema() {
- super("sys");
+ super(ImmutableList.<String>of(), "sys");
Set<String> names = Sets.newHashSet();
for(SystemTable t : SystemTable.values()){
names.add(t.getTableName());
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/test/java/org/apache/drill/PlanningBase.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/PlanningBase.java b/exec/java-exec/src/test/java/org/apache/drill/PlanningBase.java
index 6770ee7..e030da5 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/PlanningBase.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/PlanningBase.java
@@ -94,7 +94,7 @@ public class PlanningBase extends ExecTest{
registry.init();
final FunctionImplementationRegistry functionRegistry = new FunctionImplementationRegistry(config);
final SchemaPlus root = Frameworks.createRootSchema();
- registry.getSchemaFactory().registerSchemas(null, root);
+ registry.getSchemaFactory().registerSchemas(new UserSession(null, null, null), root);
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/test/java/org/apache/drill/TestTpchSingleMode.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/TestTpchSingleMode.java b/exec/java-exec/src/test/java/org/apache/drill/TestTpchSingleMode.java
index a459bef..63a5727 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/TestTpchSingleMode.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/TestTpchSingleMode.java
@@ -111,7 +111,7 @@ public class TestTpchSingleMode extends BaseTestQuery{
}
@Test
- @Ignore // requires views.
+ @Ignore // Fails with CannotPlanException
public void tpch15() throws Exception{
testSingleMode("queries/tpch/15.sql");
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/test/java/org/apache/drill/exec/store/TestOrphanSchema.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/store/TestOrphanSchema.java b/exec/java-exec/src/test/java/org/apache/drill/exec/store/TestOrphanSchema.java
index d7e74cb..864793a 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/store/TestOrphanSchema.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/store/TestOrphanSchema.java
@@ -25,6 +25,7 @@ import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.exec.ExecTest;
import org.apache.drill.exec.cache.LocalCache;
import org.apache.drill.exec.memory.TopLevelAllocator;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.server.DrillbitContext;
import org.junit.Test;
@@ -56,7 +57,7 @@ public class TestOrphanSchema extends ExecTest {
StoragePluginRegistry r = new StoragePluginRegistry(bitContext);
SchemaPlus plus = Frameworks.createRootSchema();
r.init();
- r.getSchemaFactory().registerSchemas(null, plus);
+ r.getSchemaFactory().registerSchemas(new UserSession(null, null, null), plus);
printSchema(plus, 0);
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/test/java/org/apache/drill/exec/store/ischema/OrphanSchema.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/store/ischema/OrphanSchema.java b/exec/java-exec/src/test/java/org/apache/drill/exec/store/ischema/OrphanSchema.java
index 1f1b367..b4ed88a 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/store/ischema/OrphanSchema.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/store/ischema/OrphanSchema.java
@@ -25,6 +25,7 @@ import net.hydromatic.optiq.tools.Frameworks;
import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.exec.cache.LocalCache;
import org.apache.drill.exec.memory.TopLevelAllocator;
+import org.apache.drill.exec.rpc.user.UserSession;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.store.StoragePluginRegistry;
import org.junit.Test;
@@ -55,7 +56,7 @@ public class OrphanSchema {
StoragePluginRegistry r = new StoragePluginRegistry(bitContext);
r.init();
SchemaPlus plus = Frameworks.createRootSchema();
- r.getSchemaFactory().registerSchemas(null, plus);
+ r.getSchemaFactory().registerSchemas(new UserSession(null, null, null), plus);
return plus;
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/java-exec/src/test/resources/queries/tpch/15.sql
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/resources/queries/tpch/15.sql b/exec/java-exec/src/test/resources/queries/tpch/15.sql
index 251631d..0ffa896 100644
--- a/exec/java-exec/src/test/resources/queries/tpch/15.sql
+++ b/exec/java-exec/src/test/resources/queries/tpch/15.sql
@@ -1,4 +1,6 @@
-- tpch15 using 1395599672 as a seed to the RNG
+use dfs.`default`; -- views can only be created in dfs schema
+
create view revenue0 (supplier_no, total_revenue) as
select
l_suppkey,
[4/5] DRILL-438: Add support for Views (CREATE, DROP and select)
Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b7bf00cb/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestJdbcQuery.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestJdbcQuery.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestJdbcQuery.java
index 8130a33..ded0848 100644
--- a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestJdbcQuery.java
+++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/TestJdbcQuery.java
@@ -22,6 +22,7 @@ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.TimeUnit;
@@ -39,6 +40,9 @@ import org.junit.rules.TestRule;
import com.google.common.base.Function;
import com.google.common.base.Stopwatch;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
public class TestJdbcQuery extends JdbcTest{
static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TestJdbcQuery.class);
@@ -482,13 +486,256 @@ public class TestJdbcQuery extends JdbcTest{
ResultSet resultSet = statement.executeQuery("USE hive.db1");
String result = JdbcAssert.toString(resultSet).trim();
String expected = "ok=true; summary=Default schema changed to 'hive.db1'";
- Assert.assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, expected), expected.equals(result));
+ assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, expected), expected.equals(result));
resultSet = statement.executeQuery("SELECT * FROM kv_db1 LIMIT 2");
result = JdbcAssert.toString(resultSet).trim();
expected = "key=1; value= key_1\nkey=2; value= key_2";
- Assert.assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, expected), expected.equals(result));
+ assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, expected), expected.equals(result));
+ statement.close();
+ return null;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ }
+
+ /** Helper test method for view tests */
+ private void testViewHelper(final String viewCreate, final String viewName,
+ final String viewQuery, final String queryResult) throws Exception{
+ JdbcAssert.withNoDefaultSchema().withConnection(new Function<Connection, Void>() {
+ public Void apply(Connection connection) {
+ try {
+ Statement statement = connection.createStatement();
+
+ // change default schema
+ statement.executeQuery("USE dfs.`default`");
+
+ // create view
+ ResultSet resultSet = statement.executeQuery(viewCreate);
+ String result = JdbcAssert.toString(resultSet).trim();
+ String viewCreateResult = "ok=true; summary=View '" + viewName + "' created successfully in 'dfs.default' schema";
+ assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, viewCreateResult),
+ viewCreateResult.equals(result));
+
+ // query from view
+ resultSet = statement.executeQuery(viewQuery);
+ result = JdbcAssert.toString(resultSet).trim();
+ assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, queryResult),
+ queryResult.equals(result));
+
+ statement.close();
+ return null;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ }
+
+ @Test
+ public void testView1() throws Exception{
+ testViewHelper(
+ "CREATE VIEW testview1 AS SELECT * FROM cp.`region.json`",
+ "testview1",
+ "SELECT * FROM testview1 LIMIT 1",
+ "region_id=0; sales_city=None; sales_state_province=None; sales_district=No District; " +
+ "sales_region=No Region; sales_country=No Country; sales_district_id=0");
+ }
+
+ @Test
+ public void testView2() throws Exception{
+ testViewHelper(
+ "CREATE VIEW testview2 AS SELECT region_id, sales_city FROM cp.`region.json`",
+ "testview2",
+ "SELECT * FROM testview2 LIMIT 2",
+ "region_id=0; sales_city=None\nregion_id=1; sales_city=San Francisco");
+ }
+
+ @Test
+ public void testView3() throws Exception{
+ testViewHelper(
+ "CREATE VIEW testview3(regionid, salescity) AS SELECT region_id, sales_city FROM cp.`region.json`",
+ "testview3",
+ "SELECT * FROM testview3 LIMIT 2",
+ "regionid=0; salescity=None\nregionid=1; salescity=San Francisco");
+ }
+
+ @Test
+ @Ignore // See DRILL-595 - can't project columns from inner query.
+ public void testView4() throws Exception{
+ testViewHelper(
+ "CREATE VIEW testview1 AS SELECT * FROM cp.`region.json`",
+ "testview1",
+ "SELECT region_id, sales_city FROM testview1 LIMIT 2",
+ "");
+ }
+
+ @Test
+ public void testView5() throws Exception{
+ testViewHelper(
+ "CREATE VIEW testview2 AS SELECT region_id, sales_city FROM cp.`region.json`",
+ "testview2",
+ "SELECT region_id, sales_city FROM testview2 LIMIT 2",
+ "region_id=0; sales_city=None\nregion_id=1; sales_city=San Francisco");
+ }
+
+ @Test
+ public void testView6() throws Exception{
+ testViewHelper(
+ "CREATE VIEW testview2 AS SELECT region_id, sales_city FROM cp.`region.json`",
+ "testview2",
+ "SELECT sales_city FROM testview2 LIMIT 2",
+ "sales_city=None\nsales_city=San Francisco");
+ }
+
+ @Test
+ public void testView7() throws Exception{
+ testViewHelper(
+ "CREATE VIEW testview3(regionid, salescity) AS SELECT region_id, sales_city FROM cp.`region.json` LIMIT 2",
+ "testview3",
+ "SELECT regionid, salescity FROM testview3",
+ "regionid=0; salescity=None\nregionid=1; salescity=San Francisco");
+ }
+
+ @Test
+ public void testView8() throws Exception{
+ testViewHelper(
+ "CREATE VIEW testview3(regionid, salescity) AS " +
+ "SELECT region_id, sales_city FROM cp.`region.json` ORDER BY region_id DESC",
+ "testview3",
+ "SELECT regionid FROM testview3 LIMIT 2",
+ "regionid=109\nregionid=108");
+ }
+
+ @Test
+ @Ignore // Query on testview2 fails with CannotPlanException. Seems to be an issue with Union.
+ public void testView9() throws Exception{
+ testViewHelper(
+ "CREATE VIEW testview2 AS " +
+ "SELECT region_id FROM cp.`region.json` " +
+ "UNION " +
+ "SELECT employee_id FROM cp.`employee.json`",
+ "testview2",
+ "SELECT sales_city FROM testview2 LIMIT 2",
+ "sales_city=None\nsales_city=San Francisco");
+ }
+
+ @Test
+ public void testViewOnHiveTable1() throws Exception{
+ testViewHelper(
+ "CREATE VIEW hiveview AS SELECT * FROM hive.kv",
+ "hiveview",
+ "SELECT * FROM hiveview LIMIT 1",
+ "key=1; value= key_1");
+ }
+
+ @Test
+ public void testViewOnHiveTable2() throws Exception{
+ testViewHelper(
+ "CREATE VIEW hiveview AS SELECT * FROM hive.kv",
+ "hiveview",
+ "SELECT key, `value` FROM hiveview LIMIT 1",
+ "key=1; value= key_1");
+ }
+
+ @Test
+ public void testViewOnHiveTable3() throws Exception{
+ testViewHelper(
+ "CREATE VIEW hiveview AS SELECT * FROM hive.kv",
+ "hiveview",
+ "SELECT `value` FROM hiveview LIMIT 1",
+ "value= key_1");
+ }
+
+ @Test
+ public void testViewOnHiveTable4() throws Exception{
+ testViewHelper(
+ "CREATE VIEW hiveview AS SELECT key, `value` FROM hive.kv",
+ "hiveview",
+ "SELECT * FROM hiveview LIMIT 1",
+ "key=1; value= key_1");
+ }
+
+ @Test
+ public void testViewOnHiveTable5() throws Exception{
+ testViewHelper(
+ "CREATE VIEW hiveview AS SELECT key, `value` FROM hive.kv",
+ "hiveview",
+ "SELECT key, `value` FROM hiveview LIMIT 1",
+ "key=1; value= key_1");
+ }
+
+ @Test
+ public void testDropView() throws Exception{
+ JdbcAssert.withNoDefaultSchema().withConnection(new Function<Connection, Void>() {
+ public Void apply(Connection connection) {
+ try {
+ Statement statement = connection.createStatement();
+
+ // change default schema
+ statement.executeQuery("USE dfs.`default`");
+
+ // create view
+ statement.executeQuery(
+ "CREATE VIEW testview3(regionid) AS SELECT region_id FROM cp.`region.json`");
+
+ // query from view
+ ResultSet resultSet = statement.executeQuery("SELECT regionid FROM testview3 LIMIT 1");
+ String result = JdbcAssert.toString(resultSet).trim();
+ String expected = "regionid=0";
+ assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, expected),
+ expected.equals(result));
+
+ resultSet = statement.executeQuery("DROP VIEW testview3");
+ result = JdbcAssert.toString(resultSet).trim();
+ expected = "ok=true; summary=View 'testview3' deleted successfully from 'dfs.default' schema";
+ assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, expected),
+ expected.equals(result));
+
+ statement.close();
+ return null;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ }
+
+ @Test
+ public void testShowDescribeTablesWithView() throws Exception{
+ JdbcAssert.withNoDefaultSchema().withConnection(new Function<Connection, Void>() {
+ public Void apply(Connection connection) {
+ try {
+ Statement statement = connection.createStatement();
+
+ // change default schema
+ statement.executeQuery("USE dfs.`default`");
+
+ // create view
+ statement.executeQuery(
+ "CREATE VIEW testview3 AS SELECT * FROM hive.kv");
+
+ // show tables on view
+ ResultSet resultSet = statement.executeQuery("SHOW TABLES like 'testview3'");
+ String result = JdbcAssert.toString(resultSet).trim();
+ String expected =
+ "TABLE_SCHEMA=dfs.default; TABLE_NAME=testview3\n" +
+ "TABLE_SCHEMA=dfs; TABLE_NAME=testview3";
+ assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, expected),
+ expected.equals(result));
+
+ // describe a view
+ resultSet = statement.executeQuery("DESCRIBE dfs.`default`.testview3");
+ result = JdbcAssert.toString(resultSet).trim();
+ expected =
+ "COLUMN_NAME=key; DATA_TYPE=INTEGER; IS_NULLABLE=NO\n" +
+ "COLUMN_NAME=value; DATA_TYPE=VARCHAR; IS_NULLABLE=NO";
+ assertTrue(String.format("Generated string:\n%s\ndoes not match:\n%s", result, expected),
+ expected.equals(result));
+
statement.close();
return null;
} catch (Exception e) {