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