diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java index cd3c86064df3e7febcc16e03aab6ce407e0dc8a0..c8868f5ea71af2a4d180e773005b3e34d7df43cf 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -297,6 +297,9 @@ // derived from the alias V3:V2:V1:T private final Map viewAliasToInput; + //need merge isDirect flag to input even if the newInput does not have a parent + private boolean mergeIsDirect; + // flag for no scan during analyze ... compute statistics protected boolean noscan; @@ -377,6 +380,7 @@ public SemanticAnalyzer(QueryState queryState) throws SemanticException { aliasToCTEs = new HashMap(); globalLimitCtx = new GlobalLimitCtx(); viewAliasToInput = new HashMap(); + mergeIsDirect = true; noscan = partialscan = false; tabNameToTabObject = new HashMap<>(); } @@ -386,6 +390,9 @@ protected void reset(boolean clearPartsCache) { super.reset(true); if(clearPartsCache) { prunedPartitions.clear(); + mergeIsDirect = true; + } else { + mergeIsDirect = false; } tabNameToTabObject.clear(); loadTableWork.clear(); @@ -1948,7 +1955,12 @@ private void getMetaData(QB qb, ReadEntity parentInput) ReadEntity viewInput = new ReadEntity(tab, parentInput, !qb.isInsideView()); viewInput = PlanUtils.addInput(inputs, viewInput); aliasToViewInfo.put(alias, new ObjectPair(fullViewName, viewInput)); - viewAliasToInput.put(getAliasId(alias, qb), viewInput); + String aliasId = getAliasId(alias, qb); + if (aliasId != null) { + aliasId = aliasId.replace(SemanticAnalyzer.SUBQUERY_TAG_1, "") + .replace(SemanticAnalyzer.SUBQUERY_TAG_2, ""); + } + viewAliasToInput.put(aliasId, viewInput); continue; } @@ -2000,7 +2012,7 @@ private void getMetaData(QB qb, ReadEntity parentInput) ReadEntity parentViewInfo = PlanUtils.getParentViewInfo(getAliasId(alias, qb), viewAliasToInput); PlanUtils.addInput(inputs, - new ReadEntity(tab, parentViewInfo, parentViewInfo == null)); + new ReadEntity(tab, parentViewInfo, parentViewInfo == null),mergeIsDirect); } LOG.info("Get metadata for subqueries"); 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 9c385d1650ea756d489a6fc3ec05477e6dbcf657..59ac84def18f8bcbde949531f05b309f69f4eb52 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 @@ -905,6 +905,10 @@ private PlanUtils() { // prevent instantiation } + public static ReadEntity addInput(Set inputs, ReadEntity newInput) { + return addInput(inputs,newInput,false); + } + // Add the input 'newInput' to the set of inputs for the query. // The input may or may not be already present. // The ReadEntity also contains the parents from it is derived (only populated @@ -922,7 +926,8 @@ private PlanUtils() { // // If the ReadEntity is already present and another ReadEntity with same name is // added, then the isDirect flag is updated to be the OR of values of both. - public static ReadEntity addInput(Set inputs, ReadEntity newInput) { + // mergeIsDirectFlag, need to merge isDirect flag even newInput does not have parent + public static ReadEntity addInput(Set inputs, ReadEntity newInput, boolean mergeIsDirectFlag) { // If the input is already present, make sure the new parent is added to the input. if (inputs.contains(newInput)) { for (ReadEntity input : inputs) { @@ -930,6 +935,8 @@ public static ReadEntity addInput(Set inputs, ReadEntity newInput) { if ((newInput.getParents() != null) && (!newInput.getParents().isEmpty())) { input.getParents().addAll(newInput.getParents()); input.setDirect(input.isDirect() || newInput.isDirect()); + } else if (mergeIsDirectFlag) { + input.setDirect(input.isDirect() || newInput.isDirect()); } return input; } diff --git a/ql/src/test/queries/clientpositive/authorization_view_sqlstd.q b/ql/src/test/queries/clientpositive/authorization_view_sqlstd.q index 8467c16b6632b7fd7e82fc9a1998b8588c6d5dbe..14044bff151fa80d8f5115ea02951aa11a8557e9 100644 --- a/ql/src/test/queries/clientpositive/authorization_view_sqlstd.q +++ b/ql/src/test/queries/clientpositive/authorization_view_sqlstd.q @@ -38,6 +38,8 @@ select * from vt1; -- even if view is within a sub query select * from (select * from vt1) a; +select * from vt1 union all select * from vt1; + set user.name=user1; grant all on table vt2 to user user2; 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 461490bbfc8fb3b0ae7e01c05d9a4fdc4cbc8470..d2fab2f8f0c3c7bddf77acf0fa376efecc87b4a8 100644 --- a/ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out +++ b/ql/src/test/results/clientpositive/authorization_view_sqlstd.q.out @@ -123,6 +123,16 @@ POSTHOOK: type: QUERY POSTHOOK: Input: default@t1 POSTHOOK: Input: default@vt1 #### A masked pattern was here #### +PREHOOK: query: select * from vt1 union all select * from vt1 +PREHOOK: type: QUERY +PREHOOK: Input: default@t1 +PREHOOK: Input: default@vt1 +#### A masked pattern was here #### +POSTHOOK: query: select * from vt1 union all select * from vt1 +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