Repository: hive
Updated Branches:
  refs/heads/hbase-metastore afe1b5e3a -> 1a64664ae


HIVE-10875 : Select query with view in subquery adds underlying table as direct 
input (Thejas Nair, reviewed by Ashutosh Chauhan)


Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/2b8d5474
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/2b8d5474
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/2b8d5474

Branch: refs/heads/hbase-metastore
Commit: 2b8d5474e2c34f8a4a69172f1ef5f05da6299760
Parents: fac9ee9
Author: Thejas Nair <the...@hortonworks.com>
Authored: Mon Jun 1 08:41:28 2015 -0700
Committer: Thejas Nair <the...@hortonworks.com>
Committed: Mon Jun 1 08:41:48 2015 -0700

----------------------------------------------------------------------
 .../apache/hadoop/hive/ql/plan/PlanUtils.java   |  6 ++-
 .../hadoop/hive/ql/plan/TestViewEntity.java     | 53 ++++++++++++++++----
 .../clientpositive/authorization_view_sqlstd.q  |  4 ++
 .../authorization_view_sqlstd.q.out             | 14 ++++++
 4 files changed, 66 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/2b8d5474/ql/src/java/org/apache/hadoop/hive/ql/plan/PlanUtils.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/plan/PlanUtils.java 
b/ql/src/java/org/apache/hadoop/hive/ql/plan/PlanUtils.java
index c8ae235..cb0b680 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/plan/PlanUtils.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/plan/PlanUtils.java
@@ -983,7 +983,11 @@ public final class PlanUtils {
       currentAlias = currentAlias.replace(SemanticAnalyzer.SUBQUERY_TAG_1, "")
           .replace(SemanticAnalyzer.SUBQUERY_TAG_2, "");
       ReadEntity input = viewAliasToInput.get(currentAlias);
-      if (input == null) {
+      if (input == null && currentInput != null) {
+        // To handle the case of - select * from (select * from V1) A;
+        // the currentInput != null check above is needed.
+        // the alias list that case would be A:V1:T. Lookup on A would return 
null,
+        // we need to go further to find the view inside it.
         return currentInput;
       }
       currentInput = input;

http://git-wip-us.apache.org/repos/asf/hive/blob/2b8d5474/ql/src/test/org/apache/hadoop/hive/ql/plan/TestViewEntity.java
----------------------------------------------------------------------
diff --git a/ql/src/test/org/apache/hadoop/hive/ql/plan/TestViewEntity.java 
b/ql/src/test/org/apache/hadoop/hive/ql/plan/TestViewEntity.java
index 17a4e06..e24208e 100644
--- a/ql/src/test/org/apache/hadoop/hive/ql/plan/TestViewEntity.java
+++ b/ql/src/test/org/apache/hadoop/hive/ql/plan/TestViewEntity.java
@@ -54,6 +54,7 @@ public class TestViewEntity {
   }
 
   private static Driver driver;
+  private final String NAME_PREFIX = "TestViewEntity5".toLowerCase();
 
   @BeforeClass
   public static void onetimeSetup() throws Exception {
@@ -79,30 +80,62 @@ public class TestViewEntity {
    */
   @Test
   public void testUnionView() throws Exception {
-    int ret = driver.run("create table t1(id int)").getResponseCode();
+    String prefix = "tunionview" + NAME_PREFIX;
+    final String tab1 = prefix + "t1";
+    final String tab2 = prefix + "t2";
+    final String view1 = prefix + "v1";
+    int ret = driver.run("create table " + tab1 + "(id 
int)").getResponseCode();
     assertEquals("Checking command success", 0, ret);
-    ret = driver.run("create table t2(id int)").getResponseCode();
+    ret = driver.run("create table " + tab2 + "(id int)").getResponseCode();
     assertEquals("Checking command success", 0, ret);
-    ret = driver.run("create view v1 as select t.id from "
-            + "(select t1.id from t1 union all select t2.id from t2) as t")
+    ret = driver.run("create view " + view1 + " as select t.id from "
+            + "(select " + tab1 + ".id from " + tab1 + " union all select " + 
tab2 + ".id from " + tab2 + ") as t")
         .getResponseCode();
     assertEquals("Checking command success", 0, ret);
 
-    driver.compile("select * from v1");
+    driver.compile("select * from " + view1 );
     // view entity
-    assertEquals("default@v1", CheckInputReadEntity.readEntities[0].getName());
+    assertEquals("default@" + view1, 
CheckInputReadEntity.readEntities[0].getName());
 
     // first table in union query with view as parent
-    assertEquals("default@t1", CheckInputReadEntity.readEntities[1].getName());
-    assertEquals("default@v1", CheckInputReadEntity.readEntities[1]
+    assertEquals("default@" + tab1, 
CheckInputReadEntity.readEntities[1].getName());
+    assertFalse("Table is not direct input", 
CheckInputReadEntity.readEntities[1].isDirect());
+    assertEquals("default@" + view1, CheckInputReadEntity.readEntities[1]
         .getParents()
         .iterator().next().getName());
     // second table in union query with view as parent
-    assertEquals("default@t2", CheckInputReadEntity.readEntities[2].getName());
-    assertEquals("default@v1", CheckInputReadEntity.readEntities[2]
+    assertEquals("default@" + tab2, 
CheckInputReadEntity.readEntities[2].getName());
+    assertFalse("Table is not direct input", 
CheckInputReadEntity.readEntities[2].isDirect());
+    assertEquals("default@" + view1, CheckInputReadEntity.readEntities[2]
         .getParents()
         .iterator().next().getName());
 
   }
 
+
+  /**
+   * Verify that the parent entities are captured correctly for view in 
subquery
+   * @throws Exception
+   */
+  @Test
+  public void testViewInSubQuery() throws Exception {
+    String prefix = "tvsubquery" + NAME_PREFIX;
+    final String tab1 = prefix + "t";
+    final String view1 = prefix + "v";
+
+    int ret = driver.run("create table " + tab1 + "(id 
int)").getResponseCode();
+    assertEquals("Checking command success", 0, ret);
+    ret = driver.run("create view " + view1 + " as select * from " + 
tab1).getResponseCode();
+    assertEquals("Checking command success", 0, ret);
+
+    driver.compile("select * from " + view1 );
+    // view entity
+    assertEquals("default@" + view1, 
CheckInputReadEntity.readEntities[0].getName());
+
+    // table as second read entity
+    assertEquals("default@" + tab1, 
CheckInputReadEntity.readEntities[1].getName());
+    assertFalse("Table is not direct input", 
CheckInputReadEntity.readEntities[1].isDirect());
+
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/hive/blob/2b8d5474/ql/src/test/queries/clientpositive/authorization_view_sqlstd.q
----------------------------------------------------------------------
diff --git a/ql/src/test/queries/clientpositive/authorization_view_sqlstd.q 
b/ql/src/test/queries/clientpositive/authorization_view_sqlstd.q
index 85d3ca3..8467c16 100644
--- a/ql/src/test/queries/clientpositive/authorization_view_sqlstd.q
+++ b/ql/src/test/queries/clientpositive/authorization_view_sqlstd.q
@@ -34,6 +34,10 @@ set user.name=user2;
 explain authorization select * from vt1;
 select * from vt1;
 
+-- verify input objects required does not include table
+-- even if view is within a sub query
+select * from (select * from vt1) a;
+
 set user.name=user1;
 
 grant all on table vt2 to user user2;

http://git-wip-us.apache.org/repos/asf/hive/blob/2b8d5474/ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out
----------------------------------------------------------------------
diff --git a/ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out 
b/ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out
index 54c4ce7..461490b 100644
--- a/ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out
+++ b/ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out
@@ -109,6 +109,20 @@ POSTHOOK: type: QUERY
 POSTHOOK: Input: default@t1
 POSTHOOK: Input: default@vt1
 #### A masked pattern was here ####
+PREHOOK: query: -- verify input objects required does not include table
+-- even if view is within a sub query
+select * from (select * from vt1) a
+PREHOOK: type: QUERY
+PREHOOK: Input: default@t1
+PREHOOK: Input: default@vt1
+#### A masked pattern was here ####
+POSTHOOK: query: -- verify input objects required does not include table
+-- even if view is within a sub query
+select * from (select * from vt1) a
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@t1
+POSTHOOK: Input: default@vt1
+#### A masked pattern was here ####
 PREHOOK: query: grant all on table vt2 to user user2
 PREHOOK: type: GRANT_PRIVILEGE
 PREHOOK: Output: default@vt2

Reply via email to