diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java index ab63ce2bc3..8e5667d6ba 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java @@ -3318,6 +3318,7 @@ private boolean genSubQueryRelNode(QB qb, ASTNode node, RelNode srcRel, boolean } String sbQueryAlias = "sq_" + qb.incrNumSubQueryPredicates(); QB qbSQ = new QB(qb.getId(), sbQueryAlias, true); + qbSQ.setInsideView(qb.isInsideView()); Phase1Ctx ctx1 = initPhase1Ctx(); doPhase1((ASTNode) next.getChild(1), qbSQ, ctx1, null); getMetaData(qbSQ); diff --git ql/src/test/org/apache/hadoop/hive/ql/plan/TestViewEntity.java ql/src/test/org/apache/hadoop/hive/ql/plan/TestViewEntity.java index 6ad38b8467..f90728598a 100644 --- ql/src/test/org/apache/hadoop/hive/ql/plan/TestViewEntity.java +++ ql/src/test/org/apache/hadoop/hive/ql/plan/TestViewEntity.java @@ -138,6 +138,65 @@ public void testViewInSubQuery() throws Exception { } + + /** + * Verify that the parent entities are captured correctly for view in subquery with WHERE + * subquery referencing a view. + * @throws Exception + */ + @Test + public void testViewInSubQueryWithWhereClause() throws Exception { + String prefix = "tvsubquerywithwhereclause" + NAME_PREFIX; + final String tab1 = prefix + "t"; + final String view1 = prefix + "v"; + final String view2 = prefix + "v2"; + final String tab1row1 = "'x','y','z'"; + final String tab1cell1 = "'x'"; + final String tab1row2 = "'a','b','c'"; + + //create tab1 + int ret = driver.run("create table " + tab1 + "(col1 string, col2 string, col3 string)") + .getResponseCode(); + assertEquals("Checking command success", 0, ret); + ret = driver.run("insert into " + tab1 + " values (" + tab1row1 + ")").getResponseCode(); + assertEquals("Checking command success", 0, ret); + + //create view1 + ret = driver.run("create view " + view1 + " as select " + + tab1 + ".col1, " + tab1 + ".col2, " + tab1 + ".col3 " + + " from " + tab1).getResponseCode(); + assertEquals("Checking command success", 0, ret); + + ret = driver.run("insert into " + tab1 + " values (" + tab1row2 + ")").getResponseCode(); + assertEquals("Checking command success", 0, ret); + + //create view2 + ret = driver.run( + "create view " + view2 + " as select " + + tab1 + ".col1, " + tab1 + ".col2, " + tab1 + ".col3 " + + " from " + tab1 + + " where " + tab1 + ".col1 NOT IN (" + + "SELECT " + view1 + ".col1 FROM " + view1 + ")").getResponseCode(); + assertEquals("Checking command success", 0, ret); + + //select from view2 + driver.compile("select * from " + view2 ); + + //verify that only view2 is direct input in above query + ReadEntity[] readEntities = CheckInputReadEntity.readEntities; + for (ReadEntity readEntity : readEntities) { + String name = readEntity.getName(); + if (name.equals("default@" + tab1)) { + assertFalse("Table should not be direct input", readEntity.isDirect()); + } else if (name.equals("default@" + view1)) { + assertFalse("View1 should not be direct input", readEntity.isDirect()); + } else if (name.equals("default@" + view2)) { + assertTrue("View2 should be direct input", readEntity.isDirect()); + } + } + } + + /** * Verify that the the query with the subquery inside a view will have the correct * direct and indirect inputs.