You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ha...@apache.org on 2013/12/21 02:15:32 UTC

svn commit: r1552854 - in /hive/trunk/ql/src: java/org/apache/hadoop/hive/ql/parse/ test/org/apache/hadoop/hive/ql/parse/ test/queries/clientnegative/ test/queries/clientpositive/ test/results/clientnegative/ test/results/clientpositive/

Author: hashutosh
Date: Sat Dec 21 01:15:32 2013
New Revision: 1552854

URL: http://svn.apache.org/r1552854
Log:
HIVE-5615 : Subquery support: more tests (Harish Butani via Ashutosh Chauhan)

Added:
    hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/parse/TestQBSubQuery.java
    hive/trunk/ql/src/test/queries/clientnegative/subquery_shared_alias.q
    hive/trunk/ql/src/test/queries/clientnegative/subquery_unqual_corr_expr.q
    hive/trunk/ql/src/test/queries/clientpositive/subquery_views.q
    hive/trunk/ql/src/test/results/clientnegative/subquery_shared_alias.q.out
    hive/trunk/ql/src/test/results/clientnegative/subquery_unqual_corr_expr.q.out
    hive/trunk/ql/src/test/results/clientpositive/subquery_views.q.out
Modified:
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBSubQuery.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SubQueryUtils.java

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBSubQuery.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBSubQuery.java?rev=1552854&r1=1552853&r2=1552854&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBSubQuery.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBSubQuery.java Sat Dec 21 01:15:32 2013
@@ -2,6 +2,7 @@ package org.apache.hadoop.hive.ql.parse;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 import java.util.Stack;
 
 import org.apache.hadoop.hive.common.ObjectPair;
@@ -375,12 +376,14 @@ public class QBSubQuery implements ISubQ
     }
     
     public ASTNode getSubQueryAST() {
-      return SubQueryUtils.buildNotInNullCheckQuery(
+      ASTNode ast = SubQueryUtils.buildNotInNullCheckQuery(
           QBSubQuery.this.getSubQueryAST(), 
           QBSubQuery.this.getAlias(), 
           CNT_ALIAS, 
           subQryCorrExprs,
           sqRR);
+      SubQueryUtils.setOriginDeep(ast, QBSubQuery.this.originalSQASTOrigin);
+      return ast;
     }
     
     public String getAlias() {
@@ -392,8 +395,10 @@ public class QBSubQuery implements ISubQ
     }
     
     public ASTNode getJoinConditionAST() {
-      return 
+      ASTNode ast = 
           SubQueryUtils.buildNotInNullJoinCond(getAlias(), CNT_ALIAS);
+      SubQueryUtils.setOriginDeep(ast, QBSubQuery.this.originalSQASTOrigin);
+      return ast;
     }
     
     public QBSubQuery getSubQuery() {
@@ -475,7 +480,8 @@ public class QBSubQuery implements ISubQ
 
   void validateAndRewriteAST(RowResolver outerQueryRR,
 		  boolean forHavingClause,
-		  String outerQueryAlias) throws SemanticException {
+		  String outerQueryAlias,
+		  Set<String> outerQryAliases) throws SemanticException {
 
     ASTNode selectClause = (ASTNode) subQueryAST.getChild(1).getChild(1);
 
@@ -483,6 +489,44 @@ public class QBSubQuery implements ISubQ
     if ( selectClause.getChild(0).getType() == HiveParser.TOK_HINTLIST ) {
       selectExprStart = 1;
     }
+    
+    /*
+     * Restriction.16.s :: Correlated Expression in Outer Query must not contain
+     * unqualified column references.
+     */
+    if ( parentQueryExpression != null && !forHavingClause ) { 
+        ASTNode u = SubQueryUtils.hasUnQualifiedColumnReferences(parentQueryExpression);
+        if ( u != null ) {
+          subQueryAST.setOrigin(originalSQASTOrigin);
+          throw new SemanticException(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(
+              u, "Correlating expression cannot contain unqualified column references."));
+        }
+    }
+    
+    /*
+     * Restriction 17.s :: SubQuery cannot use the same table alias as one used in
+     * the Outer Query.
+     */
+    List<String> sqAliases = SubQueryUtils.getTableAliasesInSubQuery(this);
+    String sharedAlias = null;
+    for(String s : sqAliases ) {
+      if ( outerQryAliases.contains(s) ) {
+        sharedAlias = s;
+      }
+    }
+    if ( sharedAlias != null) {
+      ASTNode whereClause = SubQueryUtils.subQueryWhere(subQueryAST);
+      
+      if ( whereClause != null ) {
+        ASTNode u = SubQueryUtils.hasUnQualifiedColumnReferences(whereClause);
+        if ( u != null ) {
+          subQueryAST.setOrigin(originalSQASTOrigin);
+          throw new SemanticException(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(
+              u, "SubQuery cannot use the table alias: " + sharedAlias + "; " +
+              		"this is also an alias in the Outer Query and SubQuery contains a unqualified column reference"));
+        }
+      }
+    }
 
     /*
      * Check.5.h :: For In and Not In the SubQuery must implicitly or
@@ -491,6 +535,7 @@ public class QBSubQuery implements ISubQ
     if ( operator.getType() != SubQueryType.EXISTS &&
         operator.getType() != SubQueryType.NOT_EXISTS &&
         selectClause.getChildCount() - selectExprStart > 1 ) {
+      subQueryAST.setOrigin(originalSQASTOrigin);
       throw new SemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(
           subQueryAST, "SubQuery can contain only 1 item in Select List."));
     }
@@ -675,11 +720,7 @@ public class QBSubQuery implements ISubQ
 		  boolean forHavingClause,
 		  String outerQueryAlias) throws SemanticException {
     ASTNode selectClause = (ASTNode) subQueryAST.getChild(1).getChild(1);
-    ASTNode whereClause = null;
-    if ( subQueryAST.getChild(1).getChildCount() > 2 &&
-        subQueryAST.getChild(1).getChild(2).getType() == HiveParser.TOK_WHERE ) {
-      whereClause = (ASTNode) subQueryAST.getChild(1).getChild(2);
-    }
+    ASTNode whereClause = SubQueryUtils.subQueryWhere(subQueryAST);
 
     if ( whereClause == null ) {
       return;

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java?rev=1552854&r1=1552853&r2=1552854&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java Sat Dec 21 01:15:32 2013
@@ -2021,7 +2021,7 @@ public class SemanticAnalyzer extends Ba
         	aliasToOpInfo.put(havingInputAlias, input);
         }
 
-        subQuery.validateAndRewriteAST(inputRR, forHavingClause, havingInputAlias);
+        subQuery.validateAndRewriteAST(inputRR, forHavingClause, havingInputAlias, aliasToOpInfo.keySet());
 
         QB qbSQ = new QB(subQuery.getOuterQueryId(), subQuery.getAlias(), true);
         Operator sqPlanTopOp = genPlanForSubQueryPredicate(qbSQ, subQuery);

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SubQueryUtils.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SubQueryUtils.java?rev=1552854&r1=1552853&r2=1552854&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SubQueryUtils.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SubQueryUtils.java Sat Dec 21 01:15:32 2013
@@ -280,6 +280,32 @@ public class SubQueryUtils {
       getTableAliasesInSubQuery(right, aliases);
     }
   }
+  
+  static ASTNode hasUnQualifiedColumnReferences(ASTNode ast) {
+    int type = ast.getType();
+    if ( type == HiveParser.DOT ) {
+      return null;
+    }
+    else if ( type == HiveParser.TOK_TABLE_OR_COL ) {
+      return ast;
+    }
+    
+    for(int i=0; i < ast.getChildCount(); i++ ) {
+      ASTNode c = hasUnQualifiedColumnReferences((ASTNode) ast.getChild(i));
+      if ( c != null ) {
+        return c;
+      }
+    }
+    return null;
+  }
+  
+  static ASTNode subQueryWhere(ASTNode subQueryAST) {
+    if ( subQueryAST.getChild(1).getChildCount() > 2 &&
+        subQueryAST.getChild(1).getChild(2).getType() == HiveParser.TOK_WHERE ) {
+      return (ASTNode) subQueryAST.getChild(1).getChild(2);
+    }
+    return null;
+  }
 
   /*
    * construct the ASTNode for the SQ column that will join with the OuterQuery Expression.

Added: hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/parse/TestQBSubQuery.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/parse/TestQBSubQuery.java?rev=1552854&view=auto
==============================================================================
--- hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/parse/TestQBSubQuery.java (added)
+++ hive/trunk/ql/src/test/org/apache/hadoop/hive/ql/parse/TestQBSubQuery.java Sat Dec 21 01:15:32 2013
@@ -0,0 +1,117 @@
+package org.apache.hadoop.hive.ql.parse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.ql.session.SessionState;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestQBSubQuery {
+  static HiveConf conf;
+  
+  private static String IN_QUERY = " select * " +
+  		"from src " +
+  		"where src.key in (select key from src s1 where s1.key > '9' and s1.value > '9') ";
+  
+  private static String IN_QUERY2 = " select * " +
+      "from src " +
+      "where src.key in (select key from src s1 where s1.key > '9' and s1.value > '9') and value > '9'";
+  
+  private static String QUERY3 = "select p_mfgr, min(p_size), rank() over(partition by p_mfgr) as r from part group by p_mfgr";
+
+  ParseDriver pd;
+  SemanticAnalyzer sA;
+
+  @BeforeClass
+  public static void initialize() {
+    conf = new HiveConf(SemanticAnalyzer.class);
+    SessionState.start(conf);
+  }
+
+  @Before
+  public void setup() throws SemanticException {
+    pd = new ParseDriver();
+    sA = new SemanticAnalyzer(conf);
+  }
+
+  ASTNode parse(String query) throws ParseException {
+    ASTNode nd = pd.parse(query);
+    return (ASTNode) nd.getChild(0);
+  }
+  
+  @Test
+  public void testExtractSubQueries() throws Exception {
+    ASTNode ast = parse(IN_QUERY);
+    ASTNode where = where(ast);
+    List<ASTNode> sqs = SubQueryUtils.findSubQueries((ASTNode) where.getChild(0));
+    Assert.assertEquals(sqs.size(), 1);
+    
+    ASTNode sq = sqs.get(0);
+    Assert.assertEquals(sq.toStringTree(),
+        "(TOK_SUBQUERY_EXPR (TOK_SUBQUERY_OP in) (TOK_QUERY (TOK_FROM (TOK_TABREF (TOK_TABNAME src) s1)) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_TABLE_OR_COL key))) (TOK_WHERE (and (> (. (TOK_TABLE_OR_COL s1) key) '9') (> (. (TOK_TABLE_OR_COL s1) value) '9'))))) (. (TOK_TABLE_OR_COL src) key))"
+        );
+  }
+  
+  @Test
+  public void testExtractConjuncts() throws Exception {
+    ASTNode ast = parse(IN_QUERY);
+    ASTNode where = where(ast);
+    List<ASTNode> sqs = SubQueryUtils.findSubQueries((ASTNode) where.getChild(0));    
+    ASTNode sq = sqs.get(0);
+    
+    ASTNode sqWhere = where((ASTNode) sq.getChild(1));
+    
+    List<ASTNode> conjuncts = new ArrayList<ASTNode>();
+    SubQueryUtils.extractConjuncts((ASTNode) sqWhere.getChild(0), conjuncts);
+    Assert.assertEquals(conjuncts.size(), 2);
+    
+    Assert.assertEquals(conjuncts.get(0).toStringTree(), "(> (. (TOK_TABLE_OR_COL s1) key) '9')");
+    Assert.assertEquals(conjuncts.get(1).toStringTree(), "(> (. (TOK_TABLE_OR_COL s1) value) '9')");
+  }
+  
+  @Test
+  public void testRewriteOuterQueryWhere() throws Exception {
+    ASTNode ast = parse(IN_QUERY);
+    ASTNode where = where(ast);
+    List<ASTNode> sqs = SubQueryUtils.findSubQueries((ASTNode) where.getChild(0));    
+    ASTNode sq = sqs.get(0);
+    
+    ASTNode newWhere = SubQueryUtils.rewriteParentQueryWhere((ASTNode) where.getChild(0), sq);
+    Assert.assertEquals(newWhere.toStringTree(), "(= 1 1)");
+  }
+  
+  @Test
+  public void testRewriteOuterQueryWhere2() throws Exception {
+    ASTNode ast = parse(IN_QUERY2);
+    ASTNode where = where(ast);
+    List<ASTNode> sqs = SubQueryUtils.findSubQueries((ASTNode) where.getChild(0));    
+    ASTNode sq = sqs.get(0);
+    
+    ASTNode newWhere = SubQueryUtils.rewriteParentQueryWhere((ASTNode) where.getChild(0), sq);
+    Assert.assertEquals(newWhere.toStringTree(), "(> (TOK_TABLE_OR_COL value) '9')");
+  }
+  
+  @Test
+  public void testCheckAggOrWindowing() throws Exception {
+    ASTNode ast = parse(QUERY3);
+    ASTNode select = select(ast);
+    
+    Assert.assertEquals(SubQueryUtils.checkAggOrWindowing((ASTNode) select.getChild(0)), 0);
+    Assert.assertEquals(SubQueryUtils.checkAggOrWindowing((ASTNode) select.getChild(1)), 1);
+    Assert.assertEquals(SubQueryUtils.checkAggOrWindowing((ASTNode) select.getChild(2)), 2);
+  }
+  
+  private ASTNode where(ASTNode qry) {
+    return (ASTNode) qry.getChild(1).getChild(2);
+  }
+  
+  private ASTNode select(ASTNode qry) {
+    return (ASTNode) qry.getChild(1).getChild(1);
+  }
+
+}

Added: hive/trunk/ql/src/test/queries/clientnegative/subquery_shared_alias.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/subquery_shared_alias.q?rev=1552854&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientnegative/subquery_shared_alias.q (added)
+++ hive/trunk/ql/src/test/queries/clientnegative/subquery_shared_alias.q Sat Dec 21 01:15:32 2013
@@ -0,0 +1,6 @@
+
+
+select *
+from src
+where src.key in (select key from src where key > '9')
+;
\ No newline at end of file

Added: hive/trunk/ql/src/test/queries/clientnegative/subquery_unqual_corr_expr.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/subquery_unqual_corr_expr.q?rev=1552854&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientnegative/subquery_unqual_corr_expr.q (added)
+++ hive/trunk/ql/src/test/queries/clientnegative/subquery_unqual_corr_expr.q Sat Dec 21 01:15:32 2013
@@ -0,0 +1,6 @@
+
+
+select *
+from src
+where key in (select key from src)
+;
\ No newline at end of file

Added: hive/trunk/ql/src/test/queries/clientpositive/subquery_views.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/subquery_views.q?rev=1552854&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/subquery_views.q (added)
+++ hive/trunk/ql/src/test/queries/clientpositive/subquery_views.q Sat Dec 21 01:15:32 2013
@@ -0,0 +1,48 @@
+
+
+-- exists test
+create view cv1 as 
+select * 
+from src b 
+where exists
+  (select a.key 
+  from src a 
+  where b.value = a.value  and a.key = b.key and a.value > 'val_9')
+;
+
+select * 
+from cv1 where cv1.key in (select key from cv1 c where c.key > '95');
+;
+
+
+-- not in test
+create view cv2 as 
+select * 
+from src b 
+where b.key not in
+  (select a.key 
+  from src a 
+  where b.value = a.value  and a.key = b.key and a.value > 'val_11'
+  )
+;
+
+select * 
+from cv2 where cv2.key in (select key from cv2 c where c.key < '11');
+;
+
+-- in where + having
+create view cv3 as
+select key, value, count(*) 
+from src b
+where b.key in (select key from src where src.key > '8')
+group by key, value
+having count(*) in (select count(*) from src s1 where s1.key > '9' group by s1.key )
+;
+
+select * from cv3;
+
+
+-- join of subquery views
+select *
+from cv3
+where cv3.key in (select key from cv1);
\ No newline at end of file

Added: hive/trunk/ql/src/test/results/clientnegative/subquery_shared_alias.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/subquery_shared_alias.q.out?rev=1552854&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientnegative/subquery_shared_alias.q.out (added)
+++ hive/trunk/ql/src/test/results/clientnegative/subquery_shared_alias.q.out Sat Dec 21 01:15:32 2013
@@ -0,0 +1 @@
+FAILED: SemanticException [Error 10249]: Line 5:44 Unsupported SubQuery Expression 'key': SubQuery cannot use the table alias: src; this is also an alias in the Outer Query and SubQuery contains a unqualified column reference

Added: hive/trunk/ql/src/test/results/clientnegative/subquery_unqual_corr_expr.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/subquery_unqual_corr_expr.q.out?rev=1552854&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientnegative/subquery_unqual_corr_expr.q.out (added)
+++ hive/trunk/ql/src/test/results/clientnegative/subquery_unqual_corr_expr.q.out Sat Dec 21 01:15:32 2013
@@ -0,0 +1 @@
+FAILED: SemanticException [Error 10249]: Line 5:6 Unsupported SubQuery Expression 'key': Correlating expression cannot contain unqualified column references.

Added: hive/trunk/ql/src/test/results/clientpositive/subquery_views.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientpositive/subquery_views.q.out?rev=1552854&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientpositive/subquery_views.q.out (added)
+++ hive/trunk/ql/src/test/results/clientpositive/subquery_views.q.out Sat Dec 21 01:15:32 2013
@@ -0,0 +1,145 @@
+PREHOOK: query: -- exists test
+create view cv1 as 
+select * 
+from src b 
+where exists
+  (select a.key 
+  from src a 
+  where b.value = a.value  and a.key = b.key and a.value > 'val_9')
+PREHOOK: type: CREATEVIEW
+POSTHOOK: query: -- exists test
+create view cv1 as 
+select * 
+from src b 
+where exists
+  (select a.key 
+  from src a 
+  where b.value = a.value  and a.key = b.key and a.value > 'val_9')
+POSTHOOK: type: CREATEVIEW
+POSTHOOK: Output: default@cv1
+PREHOOK: query: select * 
+from cv1 where cv1.key in (select key from cv1 c where c.key > '95')
+PREHOOK: type: QUERY
+PREHOOK: Input: default@cv1
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: select * 
+from cv1 where cv1.key in (select key from cv1 c where c.key > '95')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@cv1
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+96	val_96
+97	val_97
+97	val_97
+98	val_98
+98	val_98
+PREHOOK: query: -- not in test
+create view cv2 as 
+select * 
+from src b 
+where b.key not in
+  (select a.key 
+  from src a 
+  where b.value = a.value  and a.key = b.key and a.value > 'val_11'
+  )
+PREHOOK: type: CREATEVIEW
+POSTHOOK: query: -- not in test
+create view cv2 as 
+select * 
+from src b 
+where b.key not in
+  (select a.key 
+  from src a 
+  where b.value = a.value  and a.key = b.key and a.value > 'val_11'
+  )
+POSTHOOK: type: CREATEVIEW
+POSTHOOK: Output: default@cv2
+PREHOOK: query: select * 
+from cv2 where cv2.key in (select key from cv2 c where c.key < '11')
+PREHOOK: type: QUERY
+PREHOOK: Input: default@cv2
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: select * 
+from cv2 where cv2.key in (select key from cv2 c where c.key < '11')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@cv2
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+0	val_0
+0	val_0
+0	val_0
+10	val_10
+100	val_100
+100	val_100
+103	val_103
+103	val_103
+104	val_104
+104	val_104
+105	val_105
+PREHOOK: query: -- in where + having
+create view cv3 as
+select key, value, count(*) 
+from src b
+where b.key in (select key from src where src.key > '8')
+group by key, value
+having count(*) in (select count(*) from src s1 where s1.key > '9' group by s1.key )
+PREHOOK: type: CREATEVIEW
+POSTHOOK: query: -- in where + having
+create view cv3 as
+select key, value, count(*) 
+from src b
+where b.key in (select key from src where src.key > '8')
+group by key, value
+having count(*) in (select count(*) from src s1 where s1.key > '9' group by s1.key )
+POSTHOOK: type: CREATEVIEW
+POSTHOOK: Output: default@cv3
+PREHOOK: query: select * from cv3
+PREHOOK: type: QUERY
+PREHOOK: Input: default@cv3
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: select * from cv3
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@cv3
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+80	val_80	1
+82	val_82	1
+85	val_85	1
+86	val_86	1
+87	val_87	1
+9	val_9	1
+92	val_92	1
+96	val_96	1
+83	val_83	2
+84	val_84	2
+97	val_97	2
+95	val_95	2
+98	val_98	2
+90	val_90	3
+PREHOOK: query: -- join of subquery views
+select *
+from cv3
+where cv3.key in (select key from cv1)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@cv1
+PREHOOK: Input: default@cv3
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: -- join of subquery views
+select *
+from cv3
+where cv3.key in (select key from cv1)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@cv1
+POSTHOOK: Input: default@cv3
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+90	val_90	3
+92	val_92	1
+95	val_95	2
+96	val_96	1
+97	val_97	2
+98	val_98	2