Index: ql/src/java/org/apache/hadoop/hive/ql/hooks/ReadEntity.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/hooks/ReadEntity.java (revision 1466623) +++ ql/src/java/org/apache/hadoop/hive/ql/hooks/ReadEntity.java (working copy) @@ -82,6 +82,16 @@ initParent(parent); } + /** + * Initialize the parents set with the contents of the passed in set of parents + * + * @param parents + */ + public void initParents(Set parents) { + this.parents = new HashSet(); + this.parents.addAll(parents); + } + public Set getParents() { return parents; } Index: ql/src/java/org/apache/hadoop/hive/ql/plan/PlanUtils.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/plan/PlanUtils.java (revision 1466623) +++ ql/src/java/org/apache/hadoop/hive/ql/plan/PlanUtils.java (working copy) @@ -783,7 +783,18 @@ for (ReadEntity input : inputs) { if (input.equals(newInput)) { if ((newInput.getParents() != null) && (!newInput.getParents().isEmpty())) { - input.getParents().addAll(newInput.getParents()); + if (input.getParents() == null) { + // Consider the query: + // select * from (select * from V1 union all select * from V2) subq; + // where V2 depends on V1 + // V1 is initially added to the inputs with no parents + // When addInput is called for V1 as an input to V2, the copy of V1 in inputs + // doesn't have its parents initialized, so initialize them with parent V2 + // The inputs will contain (V2, no parent), (v1, parents(V2)) + input.initParents(newInput.getParents()); + } else { + input.getParents().addAll(newInput.getParents()); + } } return input; } Index: ql/src/test/queries/clientpositive/view_inputs.q =================================================================== --- ql/src/test/queries/clientpositive/view_inputs.q (revision 0) +++ ql/src/test/queries/clientpositive/view_inputs.q (working copy) @@ -0,0 +1,7 @@ +-- Tests that selecting from a view and another view that selects from that same view + +CREATE VIEW test_view1 AS SELECT * FROM src; + +CREATE VIEW test_view2 AS SELECT * FROM test_view1; + +SELECT COUNT(*) FROM test_view1 a JOIN test_view2 b ON a.key = b.key; Index: ql/src/test/results/clientpositive/view_inputs.q.out =================================================================== --- ql/src/test/results/clientpositive/view_inputs.q.out (revision 0) +++ ql/src/test/results/clientpositive/view_inputs.q.out (working copy) @@ -0,0 +1,29 @@ +PREHOOK: query: -- Tests that selecting from a view and another view that selects from that same view + +CREATE VIEW test_view1 AS SELECT * FROM src +PREHOOK: type: CREATEVIEW +POSTHOOK: query: -- Tests that selecting from a view and another view that selects from that same view + +CREATE VIEW test_view1 AS SELECT * FROM src +POSTHOOK: type: CREATEVIEW +POSTHOOK: Output: default@test_view1 +PREHOOK: query: CREATE VIEW test_view2 AS SELECT * FROM test_view1 +PREHOOK: type: CREATEVIEW +PREHOOK: Input: default@test_view1 +POSTHOOK: query: CREATE VIEW test_view2 AS SELECT * FROM test_view1 +POSTHOOK: type: CREATEVIEW +POSTHOOK: Input: default@test_view1 +POSTHOOK: Output: default@test_view2 +PREHOOK: query: SELECT COUNT(*) FROM test_view1 a JOIN test_view2 b ON a.key = b.key +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Input: default@test_view1 +PREHOOK: Input: default@test_view2 +#### A masked pattern was here #### +POSTHOOK: query: SELECT COUNT(*) FROM test_view1 a JOIN test_view2 b ON a.key = b.key +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Input: default@test_view1 +POSTHOOK: Input: default@test_view2 +#### A masked pattern was here #### +1028