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/10/23 16:54:18 UTC
svn commit: r1535040 [1/3] - in /hive/trunk/ql/src:
java/org/apache/hadoop/hive/ql/ java/org/apache/hadoop/hive/ql/parse/
test/queries/clientnegative/ test/queries/clientpositive/
test/results/clientnegative/ test/results/clientpositive/
Author: hashutosh
Date: Wed Oct 23 14:54:17 2013
New Revision: 1535040
URL: http://svn.apache.org/r1535040
Log:
HIVE-784 : Support uncorrelated subqueries in the WHERE clause (Harish Butani via Ashutosh Chauhan)
Added:
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBSubQuery.java
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SubQueryUtils.java
hive/trunk/ql/src/test/queries/clientnegative/subquery_exists_implicit_gby.q
hive/trunk/ql/src/test/queries/clientnegative/subquery_in_groupby.q
hive/trunk/ql/src/test/queries/clientnegative/subquery_in_select.q
hive/trunk/ql/src/test/queries/clientnegative/subquery_multiple_cols_in_select.q
hive/trunk/ql/src/test/queries/clientnegative/subquery_notexists_implicit_gby.q
hive/trunk/ql/src/test/queries/clientnegative/subquery_subquery_chain.q
hive/trunk/ql/src/test/queries/clientnegative/subquery_windowing_corr.q
hive/trunk/ql/src/test/queries/clientnegative/subquery_with_or_cond.q
hive/trunk/ql/src/test/queries/clientpositive/subquery_exists.q
hive/trunk/ql/src/test/queries/clientpositive/subquery_in.q
hive/trunk/ql/src/test/queries/clientpositive/subquery_multiinsert.q
hive/trunk/ql/src/test/queries/clientpositive/subquery_notexists.q
hive/trunk/ql/src/test/queries/clientpositive/subquery_notin.q
hive/trunk/ql/src/test/results/clientnegative/subquery_exists_implicit_gby.q.out
hive/trunk/ql/src/test/results/clientnegative/subquery_in_groupby.q.out
hive/trunk/ql/src/test/results/clientnegative/subquery_in_select.q.out
hive/trunk/ql/src/test/results/clientnegative/subquery_multiple_cols_in_select.q.out
hive/trunk/ql/src/test/results/clientnegative/subquery_notexists_implicit_gby.q.out
hive/trunk/ql/src/test/results/clientnegative/subquery_subquery_chain.q.out
hive/trunk/ql/src/test/results/clientnegative/subquery_windowing_corr.q.out
hive/trunk/ql/src/test/results/clientnegative/subquery_with_or_cond.q.out
hive/trunk/ql/src/test/results/clientpositive/subquery_exists.q.out
hive/trunk/ql/src/test/results/clientpositive/subquery_in.q.out
hive/trunk/ql/src/test/results/clientpositive/subquery_multiinsert.q.out
hive/trunk/ql/src/test/results/clientpositive/subquery_notexists.q.out
hive/trunk/ql/src/test/results/clientpositive/subquery_notin.q.out
Modified:
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java
Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java?rev=1535040&r1=1535039&r2=1535040&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/ErrorMsg.java Wed Oct 23 14:54:17 2013
@@ -363,6 +363,8 @@ public enum ErrorMsg {
INVALID_BIGTABLE_MAPJOIN(10246, "{0} table chosen for streaming is not valid", true),
MISSING_OVER_CLAUSE(10247, "Missing over clause for function : "),
PARTITION_SPEC_TYPE_MISMATCH(10248, "Cannot add partition column {0} of type {1} as it cannot be converted to type {2}", true),
+ UNSUPPORTED_SUBQUERY_EXPRESSION(10249, "Unsupported SubQuery Expression"),
+ INVALID_SUBQUERY_EXPRESSION(10250, "Invalid SubQuery expression"),
SCRIPT_INIT_ERROR(20000, "Unable to initialize custom script."),
SCRIPT_IO_ERROR(20001, "An error occurred while reading or writing to your custom script. "
Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g?rev=1535040&r1=1535039&r2=1535040&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g Wed Oct 23 14:54:17 2013
@@ -301,6 +301,10 @@ TOK_WINDOWVALUES;
TOK_WINDOWRANGE;
TOK_IGNOREPROTECTION;
TOK_EXCHANGEPARTITION;
+TOK_SUBQUERY_EXPR;
+TOK_SUBQUERY_OP;
+TOK_SUBQUERY_OP_NOTIN;
+TOK_SUBQUERY_OP_NOTEXISTS;
}
Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g?rev=1535040&r1=1535039&r2=1535040&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g Wed Oct 23 14:54:17 2013
@@ -371,6 +371,11 @@ precedenceEqualOperator
precedenceEqualNegatableOperator | EQUAL | EQUAL_NS | NOTEQUAL | LESSTHANOREQUALTO | LESSTHAN | GREATERTHANOREQUALTO | GREATERTHAN
;
+subQueryExpression
+ :
+ LPAREN! selectStatement RPAREN!
+ ;
+
precedenceEqualExpression
:
(left=precedenceBitwiseOrExpression -> $left)
@@ -379,8 +384,12 @@ precedenceEqualExpression
-> ^(KW_NOT ^(precedenceEqualNegatableOperator $precedenceEqualExpression $notExpr))
| (precedenceEqualOperator equalExpr=precedenceBitwiseOrExpression)
-> ^(precedenceEqualOperator $precedenceEqualExpression $equalExpr)
+ | (KW_NOT KW_IN LPAREN KW_SELECT)=> (KW_NOT KW_IN subQueryExpression)
+ -> ^(KW_NOT ^(TOK_SUBQUERY_EXPR ^(TOK_SUBQUERY_OP KW_IN) subQueryExpression $precedenceEqualExpression))
| (KW_NOT KW_IN expressions)
-> ^(KW_NOT ^(TOK_FUNCTION KW_IN $precedenceEqualExpression expressions))
+ | (KW_IN LPAREN KW_SELECT)=> (KW_IN subQueryExpression)
+ -> ^(TOK_SUBQUERY_EXPR ^(TOK_SUBQUERY_OP KW_IN) subQueryExpression $precedenceEqualExpression)
| (KW_IN expressions)
-> ^(TOK_FUNCTION KW_IN $precedenceEqualExpression expressions)
| ( KW_NOT KW_BETWEEN (min=precedenceBitwiseOrExpression) KW_AND (max=precedenceBitwiseOrExpression) )
@@ -388,6 +397,7 @@ precedenceEqualExpression
| ( KW_BETWEEN (min=precedenceBitwiseOrExpression) KW_AND (max=precedenceBitwiseOrExpression) )
-> ^(TOK_FUNCTION Identifier["between"] KW_FALSE $left $min $max)
)*
+ | (KW_EXISTS LPAREN KW_SELECT)=> (KW_EXISTS subQueryExpression) -> ^(TOK_SUBQUERY_EXPR ^(TOK_SUBQUERY_OP KW_EXISTS) subQueryExpression)
;
expressions
Added: 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=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBSubQuery.java (added)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBSubQuery.java Wed Oct 23 14:54:17 2013
@@ -0,0 +1,645 @@
+package org.apache.hadoop.hive.ql.parse;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.hadoop.hive.ql.Context;
+import org.apache.hadoop.hive.ql.ErrorMsg;
+import org.apache.hadoop.hive.ql.lib.Node;
+import org.apache.hadoop.hive.ql.lib.NodeProcessor;
+import org.apache.hadoop.hive.ql.parse.TypeCheckProcFactory.DefaultExprProcessor;
+import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+
+public class QBSubQuery {
+
+ public static enum SubQueryType {
+ EXISTS,
+ NOT_EXISTS,
+ IN,
+ NOT_IN;
+
+ public static SubQueryType get(ASTNode opNode) throws SemanticException {
+ switch(opNode.getType()) {
+ case HiveParser.KW_EXISTS:
+ return EXISTS;
+ case HiveParser.TOK_SUBQUERY_OP_NOTEXISTS:
+ return NOT_EXISTS;
+ case HiveParser.KW_IN:
+ return IN;
+ case HiveParser.TOK_SUBQUERY_OP_NOTIN:
+ return NOT_IN;
+ default:
+ throw new SemanticException(SemanticAnalyzer.generateErrorMessage(opNode,
+ "Operator not supported in SubQuery use."));
+ }
+ }
+ }
+
+ public static class SubQueryTypeDef {
+ private final ASTNode ast;
+ private final SubQueryType type;
+
+ public SubQueryTypeDef(ASTNode ast, SubQueryType type) {
+ super();
+ this.ast = ast;
+ this.type = type;
+ }
+
+ public ASTNode getAst() {
+ return ast;
+ }
+
+ public SubQueryType getType() {
+ return type;
+ }
+
+ }
+
+ /*
+ * An expression is either the left/right side of an Equality predicate in the SubQuery where
+ * clause; or it is the entire conjunct. For e.g. if the Where Clause for a SubQuery is:
+ * where R1.X = R2.Y and R2.Z > 7
+ * Then the expressions analyzed are R1.X, R2.X ( the left and right sides of the Equality
+ * predicate); and R2.Z > 7.
+ *
+ * The ExprType tracks whether the expr:
+ * - has a reference to a SubQuery table source
+ * - has a reference to Outer(parent) Query table source
+ */
+ static enum ExprType {
+ REFERS_NONE(false, false) {
+ @Override
+ public ExprType combine(ExprType other) {
+ return other;
+ }
+ },
+ REFERS_PARENT(true, false) {
+ @Override
+ public ExprType combine(ExprType other) {
+ switch(other) {
+ case REFERS_SUBQUERY:
+ case REFERS_BOTH:
+ return REFERS_BOTH;
+ default:
+ return this;
+ }
+ }
+ },
+ REFERS_SUBQUERY(false, true) {
+ @Override
+ public ExprType combine(ExprType other) {
+ switch(other) {
+ case REFERS_PARENT:
+ case REFERS_BOTH:
+ return REFERS_BOTH;
+ default:
+ return this;
+ }
+ }
+ },
+ REFERS_BOTH(true,true) {
+ @Override
+ public ExprType combine(ExprType other) {
+ return this;
+ }
+ };
+
+ final boolean refersParent;
+ final boolean refersSubQuery;
+
+ ExprType(boolean refersParent, boolean refersSubQuery) {
+ this.refersParent = refersParent;
+ this.refersSubQuery = refersSubQuery;
+ }
+
+ public boolean refersParent() {
+ return refersParent;
+ }
+ public boolean refersSubQuery() {
+ return refersSubQuery;
+ }
+ public abstract ExprType combine(ExprType other);
+ }
+
+ static class Conjunct {
+ private final ASTNode leftExpr;
+ private final ASTNode rightExpr;
+ private final ExprType leftExprType;
+ private final ExprType rightExprType;
+
+ public Conjunct(ASTNode leftExpr, ASTNode rightExpr, ExprType leftExprType,
+ ExprType rightExprType) {
+ super();
+ this.leftExpr = leftExpr;
+ this.rightExpr = rightExpr;
+ this.leftExprType = leftExprType;
+ this.rightExprType = rightExprType;
+ }
+ public ASTNode getLeftExpr() {
+ return leftExpr;
+ }
+ public ASTNode getRightExpr() {
+ return rightExpr;
+ }
+ public ExprType getLeftExprType() {
+ return leftExprType;
+ }
+ public ExprType getRightExprType() {
+ return rightExprType;
+ }
+
+ boolean eitherSideRefersBoth() {
+ if ( leftExprType == ExprType.REFERS_BOTH ) {
+ return true;
+ } else if ( rightExpr != null ) {
+ return rightExprType == ExprType.REFERS_BOTH;
+ }
+ return false;
+ }
+
+ boolean isCorrelated() {
+ if ( rightExpr != null ) {
+ return leftExprType.combine(rightExprType) == ExprType.REFERS_BOTH;
+ }
+ return false;
+ }
+
+ boolean refersOuterOnly() {
+ if ( rightExpr == null ) {
+ return leftExprType == ExprType.REFERS_PARENT;
+ }
+ return leftExprType.combine(rightExprType) == ExprType.REFERS_PARENT;
+ }
+ }
+
+ class ConjunctAnalyzer {
+ RowResolver parentQueryRR;
+ NodeProcessor defaultExprProcessor;
+ Stack<Node> stack;
+
+ ConjunctAnalyzer(RowResolver parentQueryRR) {
+ this.parentQueryRR = parentQueryRR;
+ defaultExprProcessor = new DefaultExprProcessor();
+ stack = new Stack<Node>();
+ }
+
+ /*
+ * 1. On encountering a DOT, we attempt to resolve the leftmost name
+ * to the Parent Query.
+ * 2. An unqualified name is assumed to be a SubQuery reference.
+ * We don't attempt to resolve this to the Parent; because
+ * we require all Parent column references to be qualified.
+ * 3. All other expressions have a Type based on their children.
+ * An Expr w/o children is assumed to refer to neither.
+ */
+ private ExprType analyzeExpr(ASTNode expr) {
+ ExprNodeDesc exprNode;
+ if ( expr.getType() == HiveParser.DOT) {
+ ASTNode dot = firstDot(expr);
+ exprNode = resolveDot(dot);
+ if ( exprNode != null ) {
+ return ExprType.REFERS_PARENT;
+ }
+ return ExprType.REFERS_SUBQUERY;
+ } else if ( expr.getType() == HiveParser.TOK_TABLE_OR_COL ) {
+ return ExprType.REFERS_SUBQUERY;
+ } else {
+ ExprType exprType = ExprType.REFERS_NONE;
+ int cnt = expr.getChildCount();
+ for(int i=0; i < cnt; i++) {
+ ASTNode child = (ASTNode) expr.getChild(i);
+ exprType = exprType.combine(analyzeExpr(child));
+ }
+ return exprType;
+ }
+ }
+
+ /*
+ * 1. The only correlation operator we check for is EQUAL; because that is
+ * the one for which we can do a Algebraic transformation.
+ * 2. For expressions that are not an EQUAL predicate, we treat them as conjuncts
+ * having only 1 side. These should only contain references to the SubQuery
+ * table sources.
+ * 3. For expressions that are an EQUAL predicate; we analyze each side and let the
+ * left and right exprs in the Conjunct object.
+ *
+ * @return Conjunct contains details on the left and right side of the conjunct expression.
+ */
+ Conjunct analyzeConjunct(ASTNode conjunct) throws SemanticException {
+ int type = conjunct.getType();
+
+ if ( type == HiveParser.EQUAL ) {
+ ASTNode left = (ASTNode) conjunct.getChild(0);
+ ASTNode right = (ASTNode) conjunct.getChild(1);
+ ExprType leftType = analyzeExpr(left);
+ ExprType rightType = analyzeExpr(right);
+
+ return new Conjunct(left, right, leftType, rightType);
+ } else {
+ ExprType sqExprType = analyzeExpr(conjunct);
+ return new Conjunct(conjunct, null, sqExprType, null);
+ }
+ }
+
+ /*
+ * Try to resolve a qualified name as a column reference on the Parent Query's RowResolver.
+ * Apply this logic on the leftmost(first) dot in an AST tree.
+ */
+ protected ExprNodeDesc resolveDot(ASTNode node) {
+ try {
+ TypeCheckCtx tcCtx = new TypeCheckCtx(parentQueryRR);
+ String str = BaseSemanticAnalyzer.unescapeIdentifier(node.getChild(1).getText());
+ ExprNodeDesc idDesc = new ExprNodeConstantDesc(TypeInfoFactory.stringTypeInfo, str);
+ return (ExprNodeDesc)
+ defaultExprProcessor.process(node, stack, tcCtx, (Object) null, idDesc);
+ } catch(SemanticException se) {
+ return null;
+ }
+ }
+
+ /*
+ * We want to resolve the leftmost name to the Parent Query's RR.
+ * Hence we do a left walk down the AST, until we reach the bottom most DOT.
+ */
+ protected ASTNode firstDot(ASTNode dot) {
+ ASTNode firstChild = (ASTNode) dot.getChild(0);
+ if ( firstChild != null && firstChild.getType() == HiveParser.DOT) {
+ return firstDot(firstChild);
+ }
+ return dot;
+ }
+
+ }
+
+ private final String outerQueryId;
+ private final int sqIdx;
+ private final String alias;
+ private final ASTNode subQueryAST;
+ private final ASTNode parentQueryExpression;
+ private final SubQueryTypeDef operator;
+ private boolean containsAggregationExprs;
+ private boolean hasCorrelation;
+ private ASTNode joinConditionAST;
+ private JoinType joinType;
+ private ASTNode postJoinConditionAST;
+ private int numCorrExprsinSQ;
+ private List<ASTNode> subQueryJoinAliasExprs;
+ private transient final ASTNodeOrigin originalSQASTOrigin;
+
+ /*
+ * tracks number of exprs from correlated predicates added to SQ select list.
+ */
+ private int numOfCorrelationExprsAddedToSQSelect;
+
+ private boolean groupbyAddedToSQ;
+
+ public QBSubQuery(String outerQueryId,
+ int sqIdx,
+ ASTNode subQueryAST,
+ ASTNode parentQueryExpression,
+ SubQueryTypeDef operator,
+ ASTNode originalSQAST,
+ Context ctx) {
+ super();
+ this.subQueryAST = subQueryAST;
+ this.parentQueryExpression = parentQueryExpression;
+ this.operator = operator;
+ this.outerQueryId = outerQueryId;
+ this.sqIdx = sqIdx;
+ this.alias = "sq_" + this.sqIdx;
+ this.numCorrExprsinSQ = 0;
+ String s = ctx.getTokenRewriteStream().toString(
+ originalSQAST.getTokenStartIndex(), originalSQAST.getTokenStopIndex());
+ originalSQASTOrigin = new ASTNodeOrigin("SubQuery", alias, s, alias, originalSQAST);
+ numOfCorrelationExprsAddedToSQSelect = 0;
+ groupbyAddedToSQ = false;
+ }
+
+ public ASTNode getSubQueryAST() {
+ return subQueryAST;
+ }
+ public ASTNode getOuterQueryExpression() {
+ return parentQueryExpression;
+ }
+ public SubQueryTypeDef getOperator() {
+ return operator;
+ }
+
+ void validateAndRewriteAST(RowResolver outerQueryRR) throws SemanticException {
+
+ ASTNode selectClause = (ASTNode) subQueryAST.getChild(1).getChild(1);
+
+ int selectExprStart = 0;
+ if ( selectClause.getChild(0).getType() == HiveParser.TOK_HINTLIST ) {
+ selectExprStart = 1;
+ }
+
+ /*
+ * Check.5.h :: For In and Not In the SubQuery must implicitly or
+ * explicitly only contain one select item.
+ */
+ if ( operator.getType() != SubQueryType.EXISTS &&
+ operator.getType() != SubQueryType.NOT_EXISTS &&
+ selectClause.getChildCount() - selectExprStart > 1 ) {
+ throw new SemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(
+ subQueryAST, "SubQuery can contain only 1 item in Select List."));
+ }
+
+ containsAggregationExprs = false;
+ boolean containsWindowing = false;
+ for(int i= selectExprStart; i < selectClause.getChildCount(); i++ ) {
+
+ ASTNode selectItem = (ASTNode) selectClause.getChild(i);
+ int r = SubQueryUtils.checkAggOrWindowing(selectItem);
+
+ containsWindowing = containsWindowing | ( r == 2);
+ containsAggregationExprs = containsAggregationExprs | ( r == 1 );
+ }
+
+ rewrite(outerQueryRR);
+
+ SubQueryUtils.setOriginDeep(subQueryAST, originalSQASTOrigin);
+
+ /*
+ * Restriction.13.m :: In the case of an implied Group By on a
+ * correlated SubQuery, the SubQuery always returns 1 row.
+ * An exists on a SubQuery with an implied GBy will always return true.
+ * Whereas Algebraically transforming to a Join may not return true. See
+ * Specification doc for details.
+ * Similarly a not exists on a SubQuery with a implied GBY will always return false.
+ */
+ if ( operator.getType() == SubQueryType.EXISTS &&
+ containsAggregationExprs &&
+ groupbyAddedToSQ ) {
+ throw new SemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(
+ subQueryAST,
+ "An Exists predicate on SubQuery with implicit Aggregation(no Group By clause) " +
+ "cannot be rewritten. (predicate will always return true)."));
+ }
+ if ( operator.getType() == SubQueryType.NOT_EXISTS &&
+ containsAggregationExprs &&
+ groupbyAddedToSQ ) {
+ throw new SemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(
+ subQueryAST,
+ "A Not Exists predicate on SubQuery with implicit Aggregation(no Group By clause) " +
+ "cannot be rewritten. (predicate will always return false)."));
+ }
+
+ /*
+ * Restriction.14.h :: Correlated Sub Queries cannot contain Windowing clauses.
+ */
+ if ( containsWindowing && hasCorrelation ) {
+ throw new SemanticException(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(
+ subQueryAST, "Correlated Sub Queries cannot contain Windowing clauses."));
+ }
+
+ /*
+ * Check.4.h :: For Exists and Not Exists, the Sub Query must
+ * have 1 or more correlated predicates.
+ */
+ if ( ( operator.getType() == SubQueryType.EXISTS ||
+ operator.getType() == SubQueryType.NOT_EXISTS ) &&
+ !hasCorrelation ) {
+ throw new SemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(
+ subQueryAST, "For Exists/Not Exists operator SubQuery must be Correlated."));
+ }
+
+ }
+
+ private void setJoinType() {
+ if ( operator.getType() == SubQueryType.NOT_IN ||
+ operator.getType() == SubQueryType.NOT_EXISTS ) {
+ joinType = JoinType.LEFTOUTER;
+ } else {
+ joinType = JoinType.LEFTSEMI;
+ }
+ }
+
+ void buildJoinCondition(RowResolver outerQueryRR, RowResolver sqRR) throws SemanticException {
+ ASTNode parentQueryJoinCond = null;
+
+ if ( parentQueryExpression != null ) {
+ parentQueryJoinCond = SubQueryUtils.buildOuterQryToSQJoinCond(
+ getOuterQueryExpression(),
+ alias,
+ sqRR);
+ }
+ joinConditionAST = SubQueryUtils.andAST(parentQueryJoinCond, joinConditionAST);
+ setJoinType();
+
+ if ( joinType == JoinType.LEFTOUTER ) {
+ if ( operator.getType() == SubQueryType.NOT_EXISTS && hasCorrelation ) {
+ postJoinConditionAST = SubQueryUtils.buildPostJoinNullCheck(subQueryJoinAliasExprs);
+ } else if ( operator.getType() == SubQueryType.NOT_IN ) {
+ postJoinConditionAST = SubQueryUtils.buildOuterJoinPostCond(alias, sqRR);
+ }
+ }
+
+ SubQueryUtils.setOriginDeep(joinConditionAST, originalSQASTOrigin);
+ SubQueryUtils.setOriginDeep(postJoinConditionAST, originalSQASTOrigin);
+ }
+
+ ASTNode updateOuterQueryFilter(ASTNode outerQryFilter) {
+ if (postJoinConditionAST == null ) {
+ return outerQryFilter;
+ } else if ( outerQryFilter == null ) {
+ return postJoinConditionAST;
+ }
+ ASTNode node = SubQueryUtils.andAST(outerQryFilter, postJoinConditionAST);
+ node.setOrigin(originalSQASTOrigin);
+ return node;
+ }
+
+ String getNextCorrExprAlias() {
+ return "sq_corr_" + numCorrExprsinSQ++;
+ }
+
+ /*
+ * - If the SubQuery has no where clause, there is nothing to rewrite.
+ * - Decompose SubQuery where clause into list of Top level conjuncts.
+ * - For each conjunct
+ * - Break down the conjunct into (LeftExpr, LeftExprType, RightExpr,
+ * RightExprType)
+ * - If the top level operator is an Equality Operator we will break
+ * it down into left and right; in all other case there is only a
+ * lhs.
+ * - The ExprType is based on whether the Expr. refers to the Parent
+ * Query table sources, refers to the SubQuery sources or both.
+ * - We assume an unqualified Column refers to a SubQuery table source.
+ * This is because we require Parent Column references to be qualified
+ * within the SubQuery.
+ * - If the lhs or rhs expr refers to both Parent and SubQuery sources,
+ * we flag this as Unsupported.
+ * - If the conjunct as a whole, only refers to the Parent Query sources,
+ * we flag this as an Error.
+ * - A conjunct is Correlated if the lhs refers to SubQuery sources and rhs
+ * refers to Parent Query sources or the reverse.
+ * - Say the lhs refers to SubQuery and rhs refers to Parent Query sources; the
+ * other case is handled analogously.
+ * - remove this conjunct from the SubQuery where clause.
+ * - for the SubQuery expression(lhs) construct a new alias
+ * - in the correlated predicate, replace the SubQuery
+ * expression(lhs) with the alias AST.
+ * - add this altered predicate to the Join predicate tracked by the
+ * QBSubQuery object.
+ * - add the alias AST to a list of subQueryJoinAliasExprs. This
+ * list is used in the case of Outer Joins to add null check
+ * predicates to the Outer Query's where clause.
+ * - Add the SubQuery expression with the alias as a SelectItem to
+ * the SubQuery's SelectList.
+ * - In case this SubQuery contains aggregation expressions add this SubQuery
+ * expression to its GroupBy; add it to the front of the GroupBy.
+ * - If predicate is not correlated, let it remain in the SubQuery
+ * where clause.
+ */
+ private void rewrite(RowResolver parentQueryRR) 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);
+ }
+
+ if ( whereClause == null ) {
+ return;
+ }
+
+ ASTNode searchCond = (ASTNode) whereClause.getChild(0);
+ List<ASTNode> conjuncts = new ArrayList<ASTNode>();
+ SubQueryUtils.extractConjuncts(searchCond, conjuncts);
+
+ ConjunctAnalyzer conjunctAnalyzer = new ConjunctAnalyzer(parentQueryRR);
+ ASTNode sqNewSearchCond = null;
+
+ for(ASTNode conjunctAST : conjuncts) {
+ Conjunct conjunct = conjunctAnalyzer.analyzeConjunct(conjunctAST);
+
+ /*
+ * Restriction.11.m :: A SubQuery predicate that refers to an Outer
+ * Query column must be a valid Join predicate.
+ */
+ if ( conjunct.eitherSideRefersBoth() ) {
+ throw new SemanticException(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(
+ conjunctAST,
+ "SubQuery expression refers to both Parent and SubQuery expressions and " +
+ "is not a valid join condition."));
+ }
+
+ /*
+ * Check.12.h :: SubQuery predicates cannot only refer to Outer Query columns.
+ */
+ if ( conjunct.refersOuterOnly() ) {
+ throw new SemanticException(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(
+ conjunctAST,
+ "SubQuery expression refers to Outer query expressions only."));
+ }
+
+ if ( conjunct.isCorrelated() ) {
+ hasCorrelation = true;
+ subQueryJoinAliasExprs = new ArrayList<ASTNode>();
+ String exprAlias = getNextCorrExprAlias();
+ ASTNode sqExprAlias = SubQueryUtils.createAliasAST(exprAlias);
+ ASTNode sqExprForCorr = SubQueryUtils.createColRefAST(alias, exprAlias);
+
+ if ( conjunct.getLeftExprType().refersSubQuery() ) {
+ ASTNode joinPredciate = SubQueryUtils.alterCorrelatedPredicate(
+ conjunctAST, sqExprForCorr, true);
+ joinConditionAST = SubQueryUtils.andAST(joinConditionAST, joinPredciate);
+ subQueryJoinAliasExprs.add(sqExprForCorr);
+ ASTNode selExpr = SubQueryUtils.createSelectItem(conjunct.getLeftExpr(), sqExprAlias);
+ selectClause.addChild(selExpr);
+ numOfCorrelationExprsAddedToSQSelect++;
+ if ( containsAggregationExprs ) {
+ ASTNode gBy = getSubQueryGroupByAST();
+ SubQueryUtils.addGroupExpressionToFront(gBy, conjunct.getLeftExpr());
+ }
+ } else {
+ ASTNode joinPredciate = SubQueryUtils.alterCorrelatedPredicate(
+ conjunctAST, sqExprForCorr, false);
+ joinConditionAST = SubQueryUtils.andAST(joinConditionAST, joinPredciate);
+ subQueryJoinAliasExprs.add(sqExprForCorr);
+ ASTNode selExpr = SubQueryUtils.createSelectItem(conjunct.getRightExpr(), sqExprAlias);
+ selectClause.addChild(selExpr);
+ numOfCorrelationExprsAddedToSQSelect++;
+ if ( containsAggregationExprs ) {
+ ASTNode gBy = getSubQueryGroupByAST();
+ SubQueryUtils.addGroupExpressionToFront(gBy, conjunct.getRightExpr());
+ }
+ }
+ } else {
+ sqNewSearchCond = SubQueryUtils.andAST(sqNewSearchCond, conjunctAST);
+ }
+ }
+
+ if ( sqNewSearchCond != searchCond ) {
+ if ( sqNewSearchCond == null ) {
+ /*
+ * for now just adding a true condition(1=1) to where clause.
+ * Can remove the where clause from the AST; requires moving all subsequent children
+ * left.
+ */
+ sqNewSearchCond = SubQueryUtils.constructTrueCond();
+ }
+ whereClause.setChild(0, sqNewSearchCond);
+ }
+
+ }
+
+ /*
+ * called if the SubQuery is Agg and Correlated.
+ * if SQ doesn't have a GroupBy, it is added to the SQ AST.
+ */
+ private ASTNode getSubQueryGroupByAST() {
+ ASTNode groupBy = null;
+ if ( subQueryAST.getChild(1).getChildCount() > 3 &&
+ subQueryAST.getChild(1).getChild(3).getType() == HiveParser.TOK_GROUPBY ) {
+ groupBy = (ASTNode) subQueryAST.getChild(1).getChild(3);
+ }
+
+ if ( groupBy != null ) {
+ return groupBy;
+ }
+
+ groupBy = SubQueryUtils.buildGroupBy();
+ groupbyAddedToSQ = true;
+
+ List<ASTNode> newChildren = new ArrayList<ASTNode>();
+ newChildren.add(groupBy);
+ if ( subQueryAST.getChildCount() > 3) {
+ for( int i = subQueryAST.getChildCount() - 1; i >= 3; i-- ) {
+ ASTNode child = (ASTNode) subQueryAST.getChild(i);
+ newChildren.add(child);
+ }
+ }
+
+ for(ASTNode child : newChildren ) {
+ subQueryAST.addChild(child);
+ }
+
+ return groupBy;
+ }
+
+
+ public String getOuterQueryId() {
+ return outerQueryId;
+ }
+
+ public JoinType getJoinType() {
+ return joinType;
+ }
+
+ public String getAlias() {
+ return alias;
+ }
+
+ public ASTNode getJoinConditionAST() {
+ return joinConditionAST;
+ }
+
+ public int getNumOfCorrelationExprsAddedToSQSelect() {
+ return numOfCorrelationExprsAddedToSQSelect;
+ }
+}
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=1535040&r1=1535039&r2=1535040&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 Wed Oct 23 14:54:17 2013
@@ -99,6 +99,7 @@ import org.apache.hadoop.hive.ql.parse.P
import org.apache.hadoop.hive.ql.parse.PTFInvocationSpec.PartitionSpec;
import org.apache.hadoop.hive.ql.parse.PTFInvocationSpec.PartitionedTableFunctionSpec;
import org.apache.hadoop.hive.ql.parse.PTFInvocationSpec.PartitioningSpec;
+import org.apache.hadoop.hive.ql.parse.QBSubQuery.SubQueryType;
import org.apache.hadoop.hive.ql.parse.WindowingSpec.BoundarySpec;
import org.apache.hadoop.hive.ql.parse.WindowingSpec.CurrentRowSpec;
import org.apache.hadoop.hive.ql.parse.WindowingSpec.Direction;
@@ -1758,11 +1759,105 @@ public class SemanticAnalyzer extends Ba
}
@SuppressWarnings("nls")
- private Operator genFilterPlan(String dest, QB qb, Operator input)
+ private Operator genFilterPlan(String dest, QB qb, Operator input,
+ Map<String, Operator> aliasToOpInfo)
throws SemanticException {
+ OpParseContext inputCtx = opParseCtx.get(input);
+ RowResolver inputRR = inputCtx.getRowResolver();
ASTNode whereExpr = qb.getParseInfo().getWhrForClause(dest);
- return genFilterPlan(qb, (ASTNode) whereExpr.getChild(0), input);
+
+ /*
+ * Handling of SubQuery Expressions:
+ * if "Where clause contains no SubQuery expressions" then
+ * -->[true] ===CONTINUE_FILTER_PROCESSING===
+ * else
+ * -->[false] "extract SubQuery expressions\n from Where clause"
+ * if "this is a nested SubQuery or \nthere are more than 1 SubQuery expressions" then
+ * -->[yes] "throw Unsupported Error"
+ * else
+ * --> "Rewrite Search condition to \nremove SubQuery predicate"
+ * --> "build QBSubQuery"
+ * --> "extract correlated predicates \nfrom Where Clause"
+ * --> "add correlated Items to \nSelect List and Group By"
+ * --> "construct Join Predicate \nfrom correlation predicates"
+ * --> "Generate Plan for\n modified SubQuery"
+ * --> "Build the Join Condition\n for Parent Query to SubQuery join"
+ * --> "Build the QBJoinTree from the Join condition"
+ * --> "Update Parent Query Filter\n with any Post Join conditions"
+ * --> ===CONTINUE_FILTER_PROCESSING===
+ * endif
+ * endif
+ */
+ ASTNode searchCond = (ASTNode) whereExpr.getChild(0);
+ List<ASTNode> subQueriesInOriginalTree = SubQueryUtils.findSubQueries(searchCond);
+
+ if ( subQueriesInOriginalTree != null ) {
+
+ /*
+ * Restriction.8.m :: We allow only 1 SubQuery expression per Query.
+ */
+ if (subQueriesInOriginalTree.size() > 1 ) {
+
+ throw new SemanticException(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(
+ subQueriesInOriginalTree.get(1), "Only 1 SubQuery expression is supported."));
+ }
+
+ /*
+ * Clone the Search AST; apply all rewrites on the clone.
+ */
+ ASTNode clonedSearchCond = (ASTNode) ParseDriver.adaptor.dupTree(searchCond);
+ List<ASTNode> subQueries = SubQueryUtils.findSubQueries(clonedSearchCond);
+
+ for(int i=0; i < subQueries.size(); i++) {
+ ASTNode subQueryAST = subQueries.get(i);
+ ASTNode originalSubQueryAST = subQueriesInOriginalTree.get(i);
+
+ int sqIdx = i+1;
+ clonedSearchCond = SubQueryUtils.rewriteParentQueryWhere(clonedSearchCond, subQueryAST);
+
+ QBSubQuery subQuery = SubQueryUtils.buildSubQuery(qb.getId(),
+ sqIdx, subQueryAST, originalSubQueryAST, ctx);
+
+ subQuery.validateAndRewriteAST(inputRR);
+
+ QB qbSQ = new QB(subQuery.getOuterQueryId(), subQuery.getAlias(), true);
+ Phase1Ctx ctx_1 = initPhase1Ctx();
+ doPhase1(subQuery.getSubQueryAST(), qbSQ, ctx_1);
+ getMetaData(qbSQ);
+ Operator sqPlanTopOp = genPlan(qbSQ);
+ aliasToOpInfo.put(subQuery.getAlias(), sqPlanTopOp);
+ RowResolver sqRR = opParseCtx.get(sqPlanTopOp).getRowResolver();
+
+ /*
+ * Check.5.h :: For In and Not In the SubQuery must implicitly or
+ * explicitly only contain one select item.
+ */
+ if ( subQuery.getOperator().getType() != SubQueryType.EXISTS &&
+ subQuery.getOperator().getType() != SubQueryType.NOT_EXISTS &&
+ sqRR.getColumnInfos().size() -
+ subQuery.getNumOfCorrelationExprsAddedToSQSelect() > 1 ) {
+ throw new SemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(
+ subQueryAST, "SubQuery can contain only 1 item in Select List."));
+ }
+
+ /*
+ * Gen Join between outer Operator and SQ op
+ */
+ subQuery.buildJoinCondition(inputRR, sqRR);
+ QBJoinTree joinTree = genSQJoinTree(qb, subQuery,
+ input,
+ aliasToOpInfo);
+ /*
+ * push filters only for this QBJoinTree. Child QBJoinTrees have already been handled.
+ */
+ pushJoinFilters(qb, joinTree, aliasToOpInfo, false);
+ input = genJoinOperator(qbSQ, joinTree, aliasToOpInfo, input);
+ searchCond = subQuery.updateOuterQueryFilter(clonedSearchCond);
+ }
+ }
+
+ return genFilterPlan(qb, searchCond, input);
}
/**
@@ -4038,7 +4133,8 @@ public class SemanticAnalyzer extends Ba
}
@SuppressWarnings({"nls"})
- private Operator genGroupByPlan1ReduceMultiGBY(List<String> dests, QB qb, Operator input)
+ private Operator genGroupByPlan1ReduceMultiGBY(List<String> dests, QB qb, Operator input,
+ Map<String, Operator> aliasToOpInfo)
throws SemanticException {
QBParseInfo parseInfo = qb.getParseInfo();
@@ -4118,7 +4214,7 @@ public class SemanticAnalyzer extends Ba
curr = forwardOp;
if (parseInfo.getWhrForClause(dest) != null) {
- curr = genFilterPlan(dest, qb, forwardOp);
+ curr = genFilterPlan(dest, qb, forwardOp, aliasToOpInfo);
}
// Generate GroupbyOperator
@@ -6035,17 +6131,21 @@ public class SemanticAnalyzer extends Ba
}
private Operator genJoinOperator(QB qb, QBJoinTree joinTree,
- Map<String, Operator> map) throws SemanticException {
+ Map<String, Operator> map,
+ Operator joiningOp) throws SemanticException {
QBJoinTree leftChild = joinTree.getJoinSrc();
- Operator joinSrcOp = null;
- if (leftChild != null) {
- Operator joinOp = genJoinOperator(qb, leftChild, map);
+ Operator joinSrcOp = joiningOp instanceof JoinOperator ? joiningOp : null;
+
+ if (joinSrcOp == null && leftChild != null) {
+ joinSrcOp = genJoinOperator(qb, leftChild, map, null);
+ }
+
+ if ( joinSrcOp != null ) {
ArrayList<ASTNode> filter = joinTree.getFiltersForPushing().get(0);
for (ASTNode cond : filter) {
- joinOp = genFilterPlan(qb, cond, joinOp);
+ joinSrcOp = genFilterPlan(qb, cond, joinSrcOp);
}
-
- joinSrcOp = genJoinReduceSinkChild(qb, joinTree, joinOp, null, 0);
+ joinSrcOp = genJoinReduceSinkChild(qb, joinTree, joinSrcOp, null, 0);
}
Operator[] srcOps = new Operator[joinTree.getBaseSrc().length];
@@ -6240,7 +6340,7 @@ public class SemanticAnalyzer extends Ba
private Operator genJoinPlan(QB qb, Map<String, Operator> map)
throws SemanticException {
QBJoinTree joinTree = qb.getQbJoinTree();
- Operator joinOp = genJoinOperator(qb, joinTree, map);
+ Operator joinOp = genJoinOperator(qb, joinTree, map, null);
return joinOp;
}
@@ -6250,8 +6350,20 @@ public class SemanticAnalyzer extends Ba
*/
private void pushJoinFilters(QB qb, QBJoinTree joinTree,
Map<String, Operator> map) throws SemanticException {
- if (joinTree.getJoinSrc() != null) {
- pushJoinFilters(qb, joinTree.getJoinSrc(), map);
+ pushJoinFilters(qb, joinTree, map, true);
+ }
+
+ /**
+ * Extract the filters from the join condition and push them on top of the
+ * source operators. This procedure traverses the query tree recursively,
+ */
+ private void pushJoinFilters(QB qb, QBJoinTree joinTree,
+ Map<String, Operator> map,
+ boolean recursively) throws SemanticException {
+ if ( recursively ) {
+ if (joinTree.getJoinSrc() != null) {
+ pushJoinFilters(qb, joinTree.getJoinSrc(), map);
+ }
}
ArrayList<ArrayList<ASTNode>> filters = joinTree.getFiltersForPushing();
int pos = 0;
@@ -6404,6 +6516,134 @@ public class SemanticAnalyzer extends Ba
return joinTree;
}
+ /*
+ * Setup a QBJoinTree between a SubQuery and its Parent Query. The Parent Query
+ * is the lhs of the Join.
+ *
+ * The Parent Query is represented by the last Operator needed to process its From Clause.
+ * In case of a single table Query this will be a TableScan, but it can be a Join Operator
+ * if the Parent Query contains Join clauses, or in case of a single source from clause,
+ * the source could be a SubQuery or a PTF invocation.
+ *
+ * We setup the QBJoinTree with the above constrains in place. So:
+ * - the lhs of the QBJoinTree can be a another QBJoinTree if the Parent Query operator
+ * is a JoinOperator. In this case we get its QBJoinTree from the 'joinContext'
+ * - the rhs is always a reference to the SubQuery. Its alias is obtained from the
+ * QBSubQuery object.
+ *
+ * The QBSubQuery also provides the Joining Condition AST. The Joining Condition has been
+ * transformed in QBSubQuery setup, before this call. The Joining condition has any correlated
+ * predicates and a predicate for joining the Parent Query expression with the SubQuery.
+ *
+ * The QBSubQuery also specifies what kind of Join to construct.
+ *
+ * Given this information, once we initialize the QBJoinTree, we call the 'parseJoinCondition'
+ * method to validate and parse Join conditions.
+ */
+ private QBJoinTree genSQJoinTree(QB qb, QBSubQuery subQuery,
+ Operator joiningOp,
+ Map<String, Operator> aliasToOpInfo)
+ throws SemanticException {
+ QBJoinTree joinTree = new QBJoinTree();
+ JoinCond[] condn = new JoinCond[1];
+
+ switch (subQuery.getJoinType()) {
+ case LEFTOUTER:
+ joinTree.setNoOuterJoin(false);
+ condn[0] = new JoinCond(0, 1, JoinType.LEFTOUTER);
+ break;
+ case RIGHTOUTER:
+ joinTree.setNoOuterJoin(false);
+ condn[0] = new JoinCond(0, 1, JoinType.RIGHTOUTER);
+ break;
+ case FULLOUTER:
+ joinTree.setNoOuterJoin(false);
+ condn[0] = new JoinCond(0, 1, JoinType.FULLOUTER);
+ break;
+ case LEFTSEMI:
+ joinTree.setNoSemiJoin(false);
+ condn[0] = new JoinCond(0, 1, JoinType.LEFTSEMI);
+ break;
+ default:
+ condn[0] = new JoinCond(0, 1, JoinType.INNER);
+ joinTree.setNoOuterJoin(true);
+ break;
+ }
+ joinTree.setJoinCond(condn);
+
+ if ( joiningOp instanceof JoinOperator ) {
+ QBJoinTree leftTree = joinContext.get(joiningOp);
+ joinTree.setJoinSrc(leftTree);
+ String[] leftChildAliases = leftTree.getLeftAliases();
+ String leftAliases[] = new String[leftChildAliases.length + 1];
+ for (int i = 0; i < leftChildAliases.length; i++) {
+ leftAliases[i] = leftChildAliases[i];
+ }
+ leftAliases[leftChildAliases.length] = leftTree.getRightAliases()[0];
+ joinTree.setLeftAliases(leftAliases);
+ } else {
+ String alias = unescapeIdentifier(
+ SubQueryUtils.getAlias(joiningOp, aliasToOpInfo).toLowerCase());
+ joinTree.setLeftAlias(alias);
+ String[] leftAliases = new String[1];
+ leftAliases[0] = alias;
+ joinTree.setLeftAliases(leftAliases);
+ String[] children = new String[2];
+ children[0] = alias;
+ joinTree.setBaseSrc(children);
+ joinTree.setId(qb.getId());
+ joinTree.getAliasToOpInfo().put(
+ getModifiedAlias(qb, alias), aliasToOpInfo.get(alias));
+ }
+
+ String rightalias = unescapeIdentifier(subQuery.getAlias().toLowerCase());
+ String[] rightAliases = new String[1];
+ rightAliases[0] = rightalias;
+ joinTree.setRightAliases(rightAliases);
+ String[] children = joinTree.getBaseSrc();
+ if (children == null) {
+ children = new String[2];
+ }
+ children[1] = rightalias;
+ joinTree.setBaseSrc(children);
+ joinTree.setId(qb.getId());
+ joinTree.getAliasToOpInfo().put(
+ getModifiedAlias(qb, rightalias), aliasToOpInfo.get(rightalias));
+ // remember rhs table for semijoin
+ if (joinTree.getNoSemiJoin() == false) {
+ joinTree.addRHSSemijoin(rightalias);
+ }
+
+ ArrayList<ArrayList<ASTNode>> expressions = new ArrayList<ArrayList<ASTNode>>();
+ expressions.add(new ArrayList<ASTNode>());
+ expressions.add(new ArrayList<ASTNode>());
+ joinTree.setExpressions(expressions);
+
+ ArrayList<Boolean> nullsafes = new ArrayList<Boolean>();
+ joinTree.setNullSafes(nullsafes);
+
+ ArrayList<ArrayList<ASTNode>> filters = new ArrayList<ArrayList<ASTNode>>();
+ filters.add(new ArrayList<ASTNode>());
+ filters.add(new ArrayList<ASTNode>());
+ joinTree.setFilters(filters);
+ joinTree.setFilterMap(new int[2][]);
+
+ ArrayList<ArrayList<ASTNode>> filtersForPushing =
+ new ArrayList<ArrayList<ASTNode>>();
+ filtersForPushing.add(new ArrayList<ASTNode>());
+ filtersForPushing.add(new ArrayList<ASTNode>());
+ joinTree.setFiltersForPushing(filtersForPushing);
+
+ ASTNode joinCond = subQuery.getJoinConditionAST();
+ ArrayList<String> leftSrc = new ArrayList<String>();
+ parseJoinCondition(joinTree, joinCond, leftSrc);
+ if (leftSrc.size() == 1) {
+ joinTree.setLeftAlias(leftSrc.get(0));
+ }
+
+ return joinTree;
+ }
+
private QBJoinTree genJoinTree(QB qb, ASTNode joinParseTree,
Map<String, Operator> aliasToOpInfo)
throws SemanticException {
@@ -7194,7 +7434,8 @@ public class SemanticAnalyzer extends Ba
}
@SuppressWarnings("nls")
- private Operator genBodyPlan(QB qb, Operator input) throws SemanticException {
+ private Operator genBodyPlan(QB qb, Operator input, Map<String, Operator> aliasToOpInfo)
+ throws SemanticException {
QBParseInfo qbp = qb.getParseInfo();
TreeSet<String> ks = new TreeSet<String>(qbp.getClauseNames());
@@ -7290,7 +7531,7 @@ public class SemanticAnalyzer extends Ba
curr = inputs.get(dest);
if (qbp.getWhrForClause(dest) != null) {
- curr = genFilterPlan(dest, qb, curr);
+ curr = genFilterPlan(dest, qb, curr, aliasToOpInfo);
}
if (qbp.getAggregationExprsForClause(dest).size() != 0
@@ -7320,7 +7561,7 @@ public class SemanticAnalyzer extends Ba
curr = genPostGroupByBodyPlan(curr, dest, qb);
}
} else {
- curr = genGroupByPlan1ReduceMultiGBY(commonGroupByDestGroup, qb, input);
+ curr = genGroupByPlan1ReduceMultiGBY(commonGroupByDestGroup, qb, input, aliasToOpInfo);
}
}
}
@@ -8120,7 +8361,7 @@ public class SemanticAnalyzer extends Ba
srcOpInfo = lastPTFOp != null ? lastPTFOp : srcOpInfo;
}
- Operator bodyOpInfo = genBodyPlan(qb, srcOpInfo);
+ Operator bodyOpInfo = genBodyPlan(qb, srcOpInfo, aliasToOpInfo);
if (LOG.isDebugEnabled()) {
LOG.debug("Created Plan for Query Block " + qb.getId());
Added: 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=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SubQueryUtils.java (added)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SubQueryUtils.java Wed Oct 23 14:54:17 2013
@@ -0,0 +1,418 @@
+package org.apache.hadoop.hive.ql.parse;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.antlr.runtime.tree.TreeWizard;
+import org.antlr.runtime.tree.TreeWizard.ContextVisitor;
+import org.apache.hadoop.hive.ql.Context;
+import org.apache.hadoop.hive.ql.ErrorMsg;
+import org.apache.hadoop.hive.ql.exec.ColumnInfo;
+import org.apache.hadoop.hive.ql.exec.FunctionRegistry;
+import org.apache.hadoop.hive.ql.exec.Operator;
+import org.apache.hadoop.hive.ql.parse.QBSubQuery.SubQueryType;
+import org.apache.hadoop.hive.ql.parse.QBSubQuery.SubQueryTypeDef;
+
+public class SubQueryUtils {
+
+ static void extractConjuncts(ASTNode node, List<ASTNode> conjuncts) {
+ if (node.getType() != HiveParser.KW_AND ) {
+ conjuncts.add(node);
+ return;
+ }
+ extractConjuncts((ASTNode)node.getChild(0), conjuncts);
+ extractConjuncts((ASTNode)node.getChild(1), conjuncts);
+ }
+
+ /*
+ * Remove the SubQuery from the Where CLause Tree.
+ * return the remaining WhereClause.
+ */
+ static ASTNode rewriteParentQueryWhere(ASTNode whereCond, ASTNode subQuery)
+ throws SemanticException {
+ ParentQueryWhereClauseRewrite rewrite =
+ new ParentQueryWhereClauseRewrite(whereCond, subQuery);
+ return rewrite.remove();
+ }
+
+ static ASTNode constructTrueCond() {
+ ASTNode eq = (ASTNode) ParseDriver.adaptor.create(HiveParser.EQUAL, "=");
+ ASTNode lhs = (ASTNode) ParseDriver.adaptor.create(HiveParser.Number, "1");
+ ASTNode rhs = (ASTNode) ParseDriver.adaptor.create(HiveParser.Number, "1");
+ ParseDriver.adaptor.addChild(eq, lhs);
+ ParseDriver.adaptor.addChild(eq, rhs);
+ return eq;
+ }
+
+ static ASTNode andAST(ASTNode left, ASTNode right) {
+ if ( left == null ) {
+ return right;
+ } else if ( right == null ) {
+ return left;
+ } else {
+ Object o = ParseDriver.adaptor.create(HiveParser.KW_AND, "AND");
+ ParseDriver.adaptor.addChild(o, left);
+ ParseDriver.adaptor.addChild(o, right);
+ return (ASTNode) o;
+ }
+ }
+
+ static ASTNode orAST(ASTNode left, ASTNode right) {
+ if ( left == null ) {
+ return right;
+ } else if ( right == null ) {
+ return left;
+ } else {
+ Object o = ParseDriver.adaptor.create(HiveParser.KW_OR, "OR");
+ ParseDriver.adaptor.addChild(o, left);
+ ParseDriver.adaptor.addChild(o, right);
+ return (ASTNode) o;
+ }
+ }
+
+ static ASTNode isNull(ASTNode expr) {
+ ASTNode node = (ASTNode) ParseDriver.adaptor.create(HiveParser.TOK_FUNCTION, "TOK_FUNCTION");
+ node.addChild((ASTNode) ParseDriver.adaptor.create(HiveParser.TOK_ISNULL, "TOK_ISNULL"));
+ node.addChild(expr);
+ return node;
+ }
+
+
+ /*
+ * Check that SubQuery is a top level conjuncts.
+ * Remove it from the Where Clause AST.
+ */
+ static class ParentQueryWhereClauseRewrite {
+ ASTNode root;
+ ASTNode subQuery;
+
+ ParentQueryWhereClauseRewrite(ASTNode root, ASTNode subQuery) {
+ this.root = root;
+ this.subQuery = subQuery;
+ }
+
+ ASTNode getParentInWhereClause(ASTNode node) {
+ if (node == null || node == root) {
+ return null;
+ }
+ return (ASTNode) node.getParent();
+ }
+
+ boolean removeSubQuery(ASTNode node) {
+ if (node.getType() == HiveParser.KW_AND) {
+ boolean r = removeSubQuery((ASTNode) node.getChild(0));
+ if (!r) {
+ r = removeSubQuery((ASTNode) node.getChild(1));
+ }
+ return r;
+ } else if (node.getType() == HiveParser.KW_NOT) {
+ ASTNode child = (ASTNode) node.getChild(0);
+ if (child == subQuery) {
+ ASTNode sqOpType = (ASTNode) subQuery.getChild(0).getChild(0);
+ if (sqOpType.getType() == HiveParser.KW_EXISTS) {
+ sqOpType.getToken().setType(HiveParser.TOK_SUBQUERY_OP_NOTEXISTS);
+ } else {
+ sqOpType.getToken().setType(HiveParser.TOK_SUBQUERY_OP_NOTIN);
+ }
+ ASTNode parent = getParentInWhereClause(node);
+ if (parent == null) {
+ root = subQuery;
+ } else {
+ int nodeIdx = node.getChildIndex();
+ parent.setChild(nodeIdx, subQuery);
+ }
+ return removeSubQuery(subQuery);
+
+ }
+ return false;
+ } else if (node == subQuery) {
+ ASTNode parent = getParentInWhereClause(node);
+ ASTNode gParent = getParentInWhereClause(parent);
+ ASTNode sibling = null;
+
+ if (parent != null) {
+ if (subQuery.getChildIndex() == 0) {
+ sibling = (ASTNode) parent.getChild(1);
+ } else {
+ sibling = (ASTNode) parent.getChild(0);
+ }
+ }
+
+ /*
+ * SubQuery was only condition in where clause
+ */
+ if (sibling == null) {
+ root = constructTrueCond();
+ } // SubQuery was just one conjunct
+ else if (gParent == null) {
+ root = sibling;
+ } else {
+ // otherwise replace parent by sibling.
+ int pIdx = parent.getChildIndex();
+ gParent.setChild(pIdx, sibling);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ ASTNode remove() throws SemanticException {
+ boolean r = removeSubQuery(root);
+ if (r) {
+ return root;
+ }
+ /*
+ * Restriction.7.h :: SubQuery predicates can appear only as top level conjuncts.
+ */
+ throw new SemanticException(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(
+ subQuery, "Only SubQuery expressions that are top level conjuncts are allowed"));
+ }
+ }
+
+ static List<ASTNode> findSubQueries(ASTNode node)
+ throws SemanticException {
+ TreeWizard tw = new TreeWizard(ParseDriver.adaptor, HiveParser.tokenNames);
+ SubQueryVisitor visitor = new SubQueryVisitor();
+ tw.visit(node, HiveParser.TOK_SUBQUERY_EXPR, visitor);
+ return visitor.getSubQueries();
+ }
+
+ static class SubQueryVisitor implements ContextVisitor {
+ String errMsg;
+ boolean throwError = false;
+ ASTNode errorNode;
+ List<ASTNode> subQueries;
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public void visit(Object t, Object parent, int childIndex, Map labels) {
+ if (subQueries == null ) {
+ subQueries = new ArrayList<ASTNode>();
+ }
+ subQueries.add((ASTNode)t);
+ }
+
+ public List<ASTNode> getSubQueries() {
+ return subQueries;
+ }
+
+ }
+
+ static QBSubQuery buildSubQuery(String outerQueryId,
+ int sqIdx,
+ ASTNode sqAST,
+ ASTNode originalSQAST,
+ Context ctx) throws SemanticException {
+ ASTNode sqOp = (ASTNode) sqAST.getChild(0);
+ ASTNode sq = (ASTNode) sqAST.getChild(1);
+ ASTNode outerQueryExpr = (ASTNode) sqAST.getChild(2);
+ return new QBSubQuery(outerQueryId, sqIdx, sq, outerQueryExpr,
+ buildSQOperator(sqOp),
+ originalSQAST,
+ ctx);
+ }
+
+ static SubQueryTypeDef buildSQOperator(ASTNode astSQOp) throws SemanticException {
+ ASTNode opAST = (ASTNode) astSQOp.getChild(0);
+ SubQueryType type = SubQueryType.get(opAST);
+ return new SubQueryTypeDef(opAST, type);
+ }
+
+ /*
+ * is this expr a UDAF invocation; does it imply windowing
+ * @return
+ * 0 if implies neither
+ * 1 if implies aggregation
+ * 2 if implies windowing
+ */
+ static int checkAggOrWindowing(ASTNode expressionTree) throws SemanticException {
+ int exprTokenType = expressionTree.getToken().getType();
+ if (exprTokenType == HiveParser.TOK_FUNCTION
+ || exprTokenType == HiveParser.TOK_FUNCTIONDI
+ || exprTokenType == HiveParser.TOK_FUNCTIONSTAR) {
+ assert (expressionTree.getChildCount() != 0);
+ if (expressionTree.getChild(expressionTree.getChildCount()-1).getType()
+ == HiveParser.TOK_WINDOWSPEC) {
+ return 2;
+ }
+ if (expressionTree.getChild(0).getType() == HiveParser.Identifier) {
+ String functionName = SemanticAnalyzer.unescapeIdentifier(expressionTree.getChild(0)
+ .getText());
+ if (FunctionRegistry.getGenericUDAFResolver(functionName) != null) {
+ return 1;
+ }
+ }
+ }
+ int r = 0;
+ for (int i = 0; i < expressionTree.getChildCount(); i++) {
+ int c = checkAggOrWindowing((ASTNode) expressionTree.getChild(i));
+ r = Math.max(r, c);
+ }
+ return r;
+ }
+
+ static List<String> getTableAliasesInSubQuery(QBSubQuery sq) {
+ List<String> aliases = new ArrayList<String>();
+ ASTNode joinAST = (ASTNode) sq.getSubQueryAST().getChild(0);
+ getTableAliasesInSubQuery((ASTNode) joinAST.getChild(0), aliases);
+ return aliases;
+ }
+
+ private static void getTableAliasesInSubQuery(ASTNode joinNode, List<String> aliases) {
+
+ if ((joinNode.getToken().getType() == HiveParser.TOK_TABREF)
+ || (joinNode.getToken().getType() == HiveParser.TOK_SUBQUERY)
+ || (joinNode.getToken().getType() == HiveParser.TOK_PTBLFUNCTION)) {
+ String tableName = SemanticAnalyzer.getUnescapedUnqualifiedTableName((ASTNode) joinNode.getChild(0))
+ .toLowerCase();
+ String alias = joinNode.getChildCount() == 1 ? tableName
+ : SemanticAnalyzer.unescapeIdentifier(joinNode.getChild(joinNode.getChildCount() - 1)
+ .getText().toLowerCase());
+ alias = (joinNode.getToken().getType() == HiveParser.TOK_PTBLFUNCTION) ?
+ SemanticAnalyzer.unescapeIdentifier(joinNode.getChild(1).getText().toLowerCase()) :
+ alias;
+ aliases.add(alias);
+ } else {
+ ASTNode left = (ASTNode) joinNode.getChild(0);
+ ASTNode right = (ASTNode) joinNode.getChild(1);
+ getTableAliasesInSubQuery(left, aliases);
+ getTableAliasesInSubQuery(right, aliases);
+ }
+ }
+
+ /*
+ * construct the ASTNode for the SQ column that will join with the OuterQuery Expression.
+ * So for 'select ... from R1 where A in (select B from R2...)'
+ * this will build (= outerQueryExpr 'ast returned by call to buildSQJoinExpr')
+ */
+ static ASTNode buildOuterQryToSQJoinCond(ASTNode outerQueryExpr,
+ String sqAlias,
+ RowResolver sqRR) {
+ ASTNode node = (ASTNode) ParseDriver.adaptor.create(HiveParser.EQUAL, "=");
+ node.addChild(outerQueryExpr);
+ node.addChild(buildSQJoinExpr(sqAlias, sqRR, false));
+ return node;
+ }
+
+ /*
+ * construct the ASTNode for the SQ column that will join with the OuterQuery Expression.
+ * So for 'select ... from R1 where A in (select B from R2...)'
+ * this will build (. (TOK_TABLE_OR_COL Identifier[SQ_1]) Identifier[B])
+ * where 'SQ_1' is the alias generated for the SubQuery.
+ */
+ static ASTNode buildSQJoinExpr(String sqAlias, RowResolver sqRR,
+ boolean useInternalName) {
+
+ List<ColumnInfo> signature = sqRR.getRowSchema().getSignature();
+ ColumnInfo joinColumn = signature.get(0);
+ String[] joinColName = sqRR.reverseLookup(joinColumn.getInternalName());
+ return createColRefAST(sqAlias, useInternalName ?
+ joinColumn.getInternalName() : joinColName[1]);
+ }
+
+ static ASTNode buildOuterJoinPostCond(String sqAlias, RowResolver sqRR) {
+ return isNull(buildSQJoinExpr(sqAlias, sqRR, false));
+ }
+
+ @SuppressWarnings("rawtypes")
+ static String getAlias(Operator o, Map<String, Operator> aliasToOpInfo) {
+ for(Map.Entry<String, Operator> e : aliasToOpInfo.entrySet()) {
+ if ( e.getValue() == o) {
+ return e.getKey();
+ }
+ }
+ return null;
+ }
+
+ static ASTNode createColRefAST(String tabAlias, String colName) {
+ ASTNode dot = (ASTNode) ParseDriver.adaptor.create(HiveParser.DOT, ".");
+ ASTNode tabAst = createTabRefAST(tabAlias);
+ ASTNode colAst = (ASTNode) ParseDriver.adaptor.create(HiveParser.Identifier, colName);
+ dot.addChild(tabAst);
+ dot.addChild(colAst);
+ return dot;
+ }
+
+ static ASTNode createAliasAST(String colName) {
+ return (ASTNode) ParseDriver.adaptor.create(HiveParser.Identifier, colName);
+ }
+
+ static ASTNode createTabRefAST(String tabAlias) {
+ ASTNode tabAst = (ASTNode)
+ ParseDriver.adaptor.create(HiveParser.TOK_TABLE_OR_COL, "TOK_TABLE_OR_COL");
+ ASTNode tabName = (ASTNode) ParseDriver.adaptor.create(HiveParser.Identifier, tabAlias);
+ tabAst.addChild(tabName);
+ return tabAst;
+ }
+
+ static ASTNode buildSelectExpr(ASTNode expression) {
+ ASTNode selAst = (ASTNode) ParseDriver.adaptor.create(HiveParser.TOK_SELEXPR, "TOK_SELEXPR");
+ selAst.addChild(expression);
+ return selAst;
+ }
+
+ static ASTNode buildGroupBy() {
+ ASTNode gBy = (ASTNode) ParseDriver.adaptor.create(HiveParser.TOK_GROUPBY, "TOK_GROUPBY");
+ return gBy;
+ }
+
+ static ASTNode createSelectItem(ASTNode expr, ASTNode alias) {
+ ASTNode selectItem = (ASTNode)
+ ParseDriver.adaptor.create(HiveParser.TOK_SELEXPR, "TOK_SELEXPR");
+ selectItem.addChild(expr);
+ selectItem.addChild(alias);
+ return selectItem;
+ }
+
+ static ASTNode alterCorrelatedPredicate(ASTNode correlatedExpr, ASTNode sqAlias, boolean left) {
+ if ( left ) {
+ correlatedExpr.setChild(0, sqAlias);
+ } else {
+ correlatedExpr.setChild(1, sqAlias);
+ }
+ return correlatedExpr;
+ }
+
+ static void addGroupExpressionToFront(ASTNode gBy, ASTNode expr) {
+ ASTNode grpExpr = (ASTNode)
+ ParseDriver.adaptor.create(HiveParser.TOK_GROUPING_SETS_EXPRESSION,
+ "TOK_GROUPING_SETS_EXPRESSION");
+ grpExpr.addChild(expr);
+ List<ASTNode> newChildren = new ArrayList<ASTNode>();
+ newChildren.add(expr);
+ int i = gBy.getChildCount() - 1;
+ while ( i >= 0 ) {
+ newChildren.add((ASTNode) gBy.deleteChild(i));
+ i--;
+ }
+ for(ASTNode child : newChildren ) {
+ gBy.addChild(child);
+ }
+ }
+
+ static ASTNode buildPostJoinNullCheck(List<ASTNode> subQueryJoinAliasExprs) {
+ ASTNode check = null;
+ for(ASTNode expr : subQueryJoinAliasExprs) {
+ check = orAST(check, isNull(expr));
+ }
+ return check;
+ }
+
+ static void setOriginDeep(ASTNode node, ASTNodeOrigin origin) {
+ if ( node == null ) {
+ return;
+ }
+ node.setOrigin(origin);
+ int childCnt = node.getChildCount();
+ for(int i=0; i<childCnt; i++) {
+ setOriginDeep((ASTNode)node.getChild(i), origin);
+ }
+ }
+
+}
+
+
+
+
Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java?rev=1535040&r1=1535039&r2=1535040&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java Wed Oct 23 14:54:17 2013
@@ -70,6 +70,7 @@ import org.apache.hadoop.hive.serde2.typ
import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
import org.apache.hadoop.hive.serde2.typeinfo.VarcharTypeInfo;
+
/**
* The Factory for creating typecheck processors. The typecheck processors are
* used to processes the syntax trees for expressions and convert them into
@@ -156,13 +157,16 @@ public final class TypeCheckProcFactory
+ "%|" + HiveParser.KW_IF + "%|" + HiveParser.KW_CASE + "%|"
+ HiveParser.KW_WHEN + "%|" + HiveParser.KW_IN + "%|"
+ HiveParser.KW_ARRAY + "%|" + HiveParser.KW_MAP + "%|"
- + HiveParser.KW_STRUCT + "%"),
+ + HiveParser.KW_STRUCT + "%|" + HiveParser.KW_EXISTS + "%|"
+ + HiveParser.TOK_SUBQUERY_OP_NOTIN + "%"),
getStrExprProcessor());
opRules.put(new RuleRegExp("R4", HiveParser.KW_TRUE + "%|"
+ HiveParser.KW_FALSE + "%"), getBoolExprProcessor());
opRules.put(new RuleRegExp("R5", HiveParser.TOK_DATELITERAL + "%"), getDateExprProcessor());
opRules.put(new RuleRegExp("R6", HiveParser.TOK_TABLE_OR_COL + "%"),
getColumnExprProcessor());
+ opRules.put(new RuleRegExp("R7", HiveParser.TOK_SUBQUERY_OP + "%"),
+ getSubQueryExprProcessor());
// The dispatcher fires the processor corresponding to the closest matching
// rule and passes the context along
@@ -1120,4 +1124,44 @@ public final class TypeCheckProcFactory
public static DefaultExprProcessor getDefaultExprProcessor() {
return new DefaultExprProcessor();
}
+
+ /**
+ * Processor for subquery expressions..
+ */
+ public static class SubQueryExprProcessor implements NodeProcessor {
+
+ @Override
+ public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
+ Object... nodeOutputs) throws SemanticException {
+
+ TypeCheckCtx ctx = (TypeCheckCtx) procCtx;
+ if (ctx.getError() != null) {
+ return null;
+ }
+
+ ExprNodeDesc desc = TypeCheckProcFactory.processGByExpr(nd, procCtx);
+ if (desc != null) {
+ return desc;
+ }
+
+ ASTNode expr = (ASTNode) nd;
+ ASTNode sqNode = (ASTNode) expr.getParent().getChild(1);
+ /*
+ * Restriction.1.h :: SubQueries only supported in the SQL Where Clause.
+ */
+ ctx.setError(ErrorMsg.UNSUPPORTED_SUBQUERY_EXPRESSION.getMsg(sqNode,
+ "Currently SubQuery expressions are only allowed as Where Clause predicates"),
+ sqNode);
+ return null;
+ }
+ }
+
+ /**
+ * Factory method to get SubQueryExprProcessor.
+ *
+ * @return DateExprProcessor.
+ */
+ public static SubQueryExprProcessor getSubQueryExprProcessor() {
+ return new SubQueryExprProcessor();
+ }
}
Added: hive/trunk/ql/src/test/queries/clientnegative/subquery_exists_implicit_gby.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/subquery_exists_implicit_gby.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientnegative/subquery_exists_implicit_gby.q (added)
+++ hive/trunk/ql/src/test/queries/clientnegative/subquery_exists_implicit_gby.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,10 @@
+
+
+select *
+from src b
+where exists
+ (select count(*)
+ from src a
+ where b.value = a.value and a.key = b.key and a.value > 'val_9'
+ )
+;
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientnegative/subquery_in_groupby.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/subquery_in_groupby.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientnegative/subquery_in_groupby.q (added)
+++ hive/trunk/ql/src/test/queries/clientnegative/subquery_in_groupby.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,5 @@
+
+
+select count(*)
+from src
+group by src.key in (select key from src s1 where s1.key > '9')
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientnegative/subquery_in_select.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/subquery_in_select.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientnegative/subquery_in_select.q (added)
+++ hive/trunk/ql/src/test/queries/clientnegative/subquery_in_select.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,6 @@
+
+
+
+select src.key in (select key from src s1 where s1.key > '9')
+from src
+;
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientnegative/subquery_multiple_cols_in_select.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/subquery_multiple_cols_in_select.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientnegative/subquery_multiple_cols_in_select.q (added)
+++ hive/trunk/ql/src/test/queries/clientnegative/subquery_multiple_cols_in_select.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,7 @@
+
+
+explain
+ select *
+from src
+where src.key in (select * from src s1 where s1.key > '9')
+;
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientnegative/subquery_notexists_implicit_gby.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/subquery_notexists_implicit_gby.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientnegative/subquery_notexists_implicit_gby.q (added)
+++ hive/trunk/ql/src/test/queries/clientnegative/subquery_notexists_implicit_gby.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,10 @@
+
+
+select *
+from src b
+where not exists
+ (select sum(1)
+ from src a
+ where b.value = a.value and a.key = b.key and a.value > 'val_9'
+ )
+;
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientnegative/subquery_subquery_chain.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/subquery_subquery_chain.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientnegative/subquery_subquery_chain.q (added)
+++ hive/trunk/ql/src/test/queries/clientnegative/subquery_subquery_chain.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,6 @@
+
+explain
+select *
+from src
+where src.key in (select key from src) in (select key from src)
+;
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientnegative/subquery_windowing_corr.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/subquery_windowing_corr.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientnegative/subquery_windowing_corr.q (added)
+++ hive/trunk/ql/src/test/queries/clientnegative/subquery_windowing_corr.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,26 @@
+DROP TABLE part;
+
+-- data setup
+CREATE TABLE part(
+ p_partkey INT,
+ p_name STRING,
+ p_mfgr STRING,
+ p_brand STRING,
+ p_type STRING,
+ p_size INT,
+ p_container STRING,
+ p_retailprice DOUBLE,
+ p_comment STRING
+);
+
+LOAD DATA LOCAL INPATH '../data/files/part_tiny.txt' overwrite into table part;
+
+
+-- corr and windowing
+select p_mfgr, p_name, p_size
+from part a
+where a.p_size in
+ (select first_value(p_size) over(partition by p_mfgr order by p_size)
+ from part b
+ where a.p_brand = b.p_brand)
+;
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientnegative/subquery_with_or_cond.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/subquery_with_or_cond.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientnegative/subquery_with_or_cond.q (added)
+++ hive/trunk/ql/src/test/queries/clientnegative/subquery_with_or_cond.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,5 @@
+
+select count(*)
+from src
+where src.key in (select key from src s1 where s1.key > '9') or src.value is not null
+;
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientpositive/subquery_exists.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/subquery_exists.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/subquery_exists.q (added)
+++ hive/trunk/ql/src/test/queries/clientpositive/subquery_exists.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,45 @@
+
+
+-- no agg, corr
+explain
+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 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'
+ )
+;
+
+-- view 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
+;
+
+-- sq in from
+select *
+from (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')
+ ) a
+;
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientpositive/subquery_in.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/subquery_in.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/subquery_in.q (added)
+++ hive/trunk/ql/src/test/queries/clientpositive/subquery_in.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,155 @@
+DROP TABLE part;
+
+-- data setup
+CREATE TABLE part(
+ p_partkey INT,
+ p_name STRING,
+ p_mfgr STRING,
+ p_brand STRING,
+ p_type STRING,
+ p_size INT,
+ p_container STRING,
+ p_retailprice DOUBLE,
+ p_comment STRING
+);
+
+LOAD DATA LOCAL INPATH '../data/files/part_tiny.txt' overwrite into table part;
+
+DROP TABLE lineitem;
+CREATE TABLE lineitem (L_ORDERKEY INT,
+ L_PARTKEY INT,
+ L_SUPPKEY INT,
+ L_LINENUMBER INT,
+ L_QUANTITY DOUBLE,
+ L_EXTENDEDPRICE DOUBLE,
+ L_DISCOUNT DOUBLE,
+ L_TAX DOUBLE,
+ L_RETURNFLAG STRING,
+ L_LINESTATUS STRING,
+ l_shipdate STRING,
+ L_COMMITDATE STRING,
+ L_RECEIPTDATE STRING,
+ L_SHIPINSTRUCT STRING,
+ L_SHIPMODE STRING,
+ L_COMMENT STRING)
+ROW FORMAT DELIMITED
+FIELDS TERMINATED BY '|';
+
+LOAD DATA LOCAL INPATH '../data/files/lineitem.txt' OVERWRITE INTO TABLE lineitem;
+
+-- non agg, non corr
+explain
+ select *
+from src
+where src.key in (select key from src s1 where s1.key > '9')
+;
+
+select *
+from src
+where src.key in (select key from src s1 where s1.key > '9')
+;
+
+-- non agg, corr
+explain
+select *
+from src b
+where b.key in
+ (select a.key
+ from src a
+ where b.value = a.value and a.key > '9'
+ )
+;
+
+select *
+from src b
+where b.key in
+ (select a.key
+ from src a
+ where b.value = a.value and a.key > '9'
+ )
+;
+
+-- agg, non corr
+explain
+select p_name, p_size
+from
+part where part.p_size in
+ (select avg(p_size)
+ from (select p_size, rank() over(partition by p_mfgr order by p_size) as r from part) a
+ where r <= 2
+ )
+;
+select p_name, p_size
+from
+part where part.p_size in
+ (select avg(p_size)
+ from (select p_size, rank() over(partition by p_mfgr order by p_size) as r from part) a
+ where r <= 2
+ )
+;
+
+-- agg, corr
+explain
+select p_mfgr, p_name, p_size
+from part b where b.p_size in
+ (select min(p_size)
+ from (select p_mfgr, p_size, rank() over(partition by p_mfgr order by p_size) as r from part) a
+ where r <= 2 and b.p_mfgr = a.p_mfgr
+ )
+;
+
+select p_mfgr, p_name, p_size
+from part b where b.p_size in
+ (select min(p_size)
+ from (select p_mfgr, p_size, rank() over(partition by p_mfgr order by p_size) as r from part) a
+ where r <= 2 and b.p_mfgr = a.p_mfgr
+ )
+;
+
+-- distinct, corr
+explain
+select *
+from src b
+where b.key in
+ (select distinct a.key
+ from src a
+ where b.value = a.value and a.key > '9'
+ )
+;
+
+select *
+from src b
+where b.key in
+ (select distinct a.key
+ from src a
+ where b.value = a.value and a.key > '9'
+ )
+;
+
+-- non agg, non corr, windowing
+select p_mfgr, p_name, p_size
+from part
+where part.p_size in
+ (select first_value(p_size) over(partition by p_mfgr order by p_size) from part)
+;
+
+-- non agg, non corr, with join in Parent Query
+explain
+select p.p_partkey, li.l_suppkey
+from (select distinct l_partkey as p_partkey from lineitem) p join lineitem li on p.p_partkey = li.l_partkey
+where li.l_linenumber = 1 and
+ li.l_orderkey in (select l_orderkey from lineitem where l_shipmode = 'AIR')
+;
+
+select p.p_partkey, li.l_suppkey
+from (select distinct l_partkey as p_partkey from lineitem) p join lineitem li on p.p_partkey = li.l_partkey
+where li.l_linenumber = 1 and
+ li.l_orderkey in (select l_orderkey from lineitem where l_shipmode = 'AIR')
+;
+
+-- non agg, corr, with join in Parent Query
+select p.p_partkey, li.l_suppkey
+from (select distinct l_partkey as p_partkey from lineitem) p join lineitem li on p.p_partkey = li.l_partkey
+where li.l_linenumber = 1 and
+ li.l_orderkey in (select l_orderkey from lineitem where l_shipmode = 'AIR' and l_linenumber = li.l_linenumber)
+;
Added: hive/trunk/ql/src/test/queries/clientpositive/subquery_multiinsert.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/subquery_multiinsert.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/subquery_multiinsert.q (added)
+++ hive/trunk/ql/src/test/queries/clientpositive/subquery_multiinsert.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,45 @@
+CREATE TABLE src_4(
+ key STRING,
+ value STRING
+)
+;
+
+CREATE TABLE src_5(
+ key STRING,
+ value STRING
+)
+;
+
+explain
+from src b
+INSERT OVERWRITE TABLE src_4
+ select *
+ where b.key in
+ (select a.key
+ from src a
+ where b.value = a.value and a.key > '9'
+ )
+INSERT OVERWRITE TABLE src_5
+ select *
+ where b.key not in ( select key from src s1 where s1.key > '2')
+ order by key
+;
+
+from src b
+INSERT OVERWRITE TABLE src_4
+ select *
+ where b.key in
+ (select a.key
+ from src a
+ where b.value = a.value and a.key > '9'
+ )
+INSERT OVERWRITE TABLE src_5
+ select *
+ where b.key not in ( select key from src s1 where s1.key > '2')
+ order by key
+;
+
+select * from src_4
+;
+select * from src_5
+;
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientpositive/subquery_notexists.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/subquery_notexists.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/subquery_notexists.q (added)
+++ hive/trunk/ql/src/test/queries/clientpositive/subquery_notexists.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,41 @@
+
+
+-- no agg, corr
+explain
+select *
+from src b
+where not exists
+ (select a.key
+ from src a
+ where b.value = a.value and a.key = b.key and a.value > 'val_2'
+ )
+;
+
+select *
+from src b
+where not exists
+ (select a.key
+ from src a
+ where b.value = a.value and a.key = b.key and a.value > 'val_2'
+ )
+;
+
+-- distinct, corr
+explain
+select *
+from src b
+where not exists
+ (select distinct a.key
+ from src a
+ where b.value = a.value and a.value > 'val_2'
+ )
+;
+
+select *
+from src b
+where not exists
+ (select a.key
+ from src a
+ where b.value = a.value and a.value > 'val_2'
+ )
+;
\ No newline at end of file
Added: hive/trunk/ql/src/test/queries/clientpositive/subquery_notin.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/subquery_notin.q?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/subquery_notin.q (added)
+++ hive/trunk/ql/src/test/queries/clientpositive/subquery_notin.q Wed Oct 23 14:54:17 2013
@@ -0,0 +1,129 @@
+DROP TABLE part;
+
+-- data setup
+CREATE TABLE part(
+ p_partkey INT,
+ p_name STRING,
+ p_mfgr STRING,
+ p_brand STRING,
+ p_type STRING,
+ p_size INT,
+ p_container STRING,
+ p_retailprice DOUBLE,
+ p_comment STRING
+);
+
+LOAD DATA LOCAL INPATH '../data/files/part_tiny.txt' overwrite into table part;
+
+DROP TABLE lineitem;
+CREATE TABLE lineitem (L_ORDERKEY INT,
+ L_PARTKEY INT,
+ L_SUPPKEY INT,
+ L_LINENUMBER INT,
+ L_QUANTITY DOUBLE,
+ L_EXTENDEDPRICE DOUBLE,
+ L_DISCOUNT DOUBLE,
+ L_TAX DOUBLE,
+ L_RETURNFLAG STRING,
+ L_LINESTATUS STRING,
+ l_shipdate STRING,
+ L_COMMITDATE STRING,
+ L_RECEIPTDATE STRING,
+ L_SHIPINSTRUCT STRING,
+ L_SHIPMODE STRING,
+ L_COMMENT STRING)
+ROW FORMAT DELIMITED
+FIELDS TERMINATED BY '|';
+
+LOAD DATA LOCAL INPATH '../data/files/lineitem.txt' OVERWRITE INTO TABLE lineitem;
+
+-- non agg, non corr
+explain
+select *
+from src
+where src.key not in
+ ( select key from src s1
+ where s1.key > '2'
+ )
+;
+
+select *
+from src
+where src.key not in ( select key from src s1 where s1.key > '2')
+order by key
+;
+
+-- non agg, corr
+explain
+select p_mfgr, b.p_name, p_size
+from part b
+where b.p_name not in
+ (select p_name
+ from (select p_mfgr, p_name, p_size, rank() over(partition by p_mfgr order by p_size) as r from part) a
+ where r <= 2 and b.p_mfgr = a.p_mfgr
+ )
+;
+
+select p_mfgr, b.p_name, p_size
+from part b
+where b.p_name not in
+ (select p_name
+ from (select p_mfgr, p_name, p_size, rank() over(partition by p_mfgr order by p_size) as r from part) a
+ where r <= 2 and b.p_mfgr = a.p_mfgr
+ )
+order by p_mfgr, b.p_name
+;
+
+-- agg, non corr
+explain
+select p_name, p_size
+from
+part where part.p_size not in
+ (select avg(p_size)
+ from (select p_size, rank() over(partition by p_mfgr order by p_size) as r from part) a
+ where r <= 2
+ )
+;
+select p_name, p_size
+from
+part where part.p_size not in
+ (select avg(p_size)
+ from (select p_size, rank() over(partition by p_mfgr order by p_size) as r from part) a
+ where r <= 2
+ )
+order by p_name, p_size
+;
+
+-- agg, corr
+explain
+select p_mfgr, p_name, p_size
+from part b where b.p_size not in
+ (select min(p_size)
+ from (select p_mfgr, p_size, rank() over(partition by p_mfgr order by p_size) as r from part) a
+ where r <= 2 and b.p_mfgr = a.p_mfgr
+ )
+;
+
+select p_mfgr, p_name, p_size
+from part b where b.p_size not in
+ (select min(p_size)
+ from (select p_mfgr, p_size, rank() over(partition by p_mfgr order by p_size) as r from part) a
+ where r <= 2 and b.p_mfgr = a.p_mfgr
+ )
+order by p_mfgr, p_size
+;
+
+-- non agg, non corr, Group By in Parent Query
+select li.l_partkey, count(*)
+from lineitem li
+where li.l_linenumber = 1 and
+ li.l_orderkey not in (select l_orderkey from lineitem where l_shipmode = 'AIR')
+group by li.l_partkey
+;
+
+-- alternate not in syntax
+select *
+from src
+where not src.key in ( select key from src s1 where s1.key > '2')
+order by key
+;
Added: hive/trunk/ql/src/test/results/clientnegative/subquery_exists_implicit_gby.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/subquery_exists_implicit_gby.q.out?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientnegative/subquery_exists_implicit_gby.q.out (added)
+++ hive/trunk/ql/src/test/results/clientnegative/subquery_exists_implicit_gby.q.out Wed Oct 23 14:54:17 2013
@@ -0,0 +1,7 @@
+FAILED: SemanticException Line 7:7 Invalid SubQuery expression 'key' in definition of SubQuery sq_1 [
+exists
+ (select count(*)
+ from src a
+ where b.value = a.value and a.key = b.key and a.value > 'val_9'
+ )
+] used as sq_1 at Line 5:6: An Exists predicate on SubQuery with implicit Aggregation(no Group By clause) cannot be rewritten. (predicate will always return true).
Added: hive/trunk/ql/src/test/results/clientnegative/subquery_in_groupby.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/subquery_in_groupby.q.out?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientnegative/subquery_in_groupby.q.out (added)
+++ hive/trunk/ql/src/test/results/clientnegative/subquery_in_groupby.q.out Wed Oct 23 14:54:17 2013
@@ -0,0 +1 @@
+FAILED: SemanticException [Error 10249]: Line 5:37 Unsupported SubQuery Expression ''9'': Currently SubQuery expressions are only allowed as Where Clause predicates
Added: hive/trunk/ql/src/test/results/clientnegative/subquery_in_select.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/subquery_in_select.q.out?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientnegative/subquery_in_select.q.out (added)
+++ hive/trunk/ql/src/test/results/clientnegative/subquery_in_select.q.out Wed Oct 23 14:54:17 2013
@@ -0,0 +1 @@
+FAILED: SemanticException [Error 10249]: Line 4:35 Unsupported SubQuery Expression ''9'': Currently SubQuery expressions are only allowed as Where Clause predicates
Added: hive/trunk/ql/src/test/results/clientnegative/subquery_multiple_cols_in_select.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/subquery_multiple_cols_in_select.q.out?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientnegative/subquery_multiple_cols_in_select.q.out (added)
+++ hive/trunk/ql/src/test/results/clientnegative/subquery_multiple_cols_in_select.q.out Wed Oct 23 14:54:17 2013
@@ -0,0 +1 @@
+FAILED: SemanticException [Error 10250]: Line 6:14 Invalid SubQuery expression 'key': SubQuery can contain only 1 item in Select List.
Added: hive/trunk/ql/src/test/results/clientnegative/subquery_notexists_implicit_gby.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/subquery_notexists_implicit_gby.q.out?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientnegative/subquery_notexists_implicit_gby.q.out (added)
+++ hive/trunk/ql/src/test/results/clientnegative/subquery_notexists_implicit_gby.q.out Wed Oct 23 14:54:17 2013
@@ -0,0 +1,7 @@
+FAILED: SemanticException Line 7:7 Invalid SubQuery expression 'key' in definition of SubQuery sq_1 [
+exists
+ (select sum(1)
+ from src a
+ where b.value = a.value and a.key = b.key and a.value > 'val_9'
+ )
+] used as sq_1 at Line 5:10: A Not Exists predicate on SubQuery with implicit Aggregation(no Group By clause) cannot be rewritten. (predicate will always return false).
Added: hive/trunk/ql/src/test/results/clientnegative/subquery_subquery_chain.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/subquery_subquery_chain.q.out?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientnegative/subquery_subquery_chain.q.out (added)
+++ hive/trunk/ql/src/test/results/clientnegative/subquery_subquery_chain.q.out Wed Oct 23 14:54:17 2013
@@ -0,0 +1 @@
+FAILED: SemanticException [Error 10249]: Line 5:14 Unsupported SubQuery Expression 'key': Only 1 SubQuery expression is supported.
Added: hive/trunk/ql/src/test/results/clientnegative/subquery_windowing_corr.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/subquery_windowing_corr.q.out?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientnegative/subquery_windowing_corr.q.out (added)
+++ hive/trunk/ql/src/test/results/clientnegative/subquery_windowing_corr.q.out Wed Oct 23 14:54:17 2013
@@ -0,0 +1,43 @@
+PREHOOK: query: DROP TABLE part
+PREHOOK: type: DROPTABLE
+POSTHOOK: query: DROP TABLE part
+POSTHOOK: type: DROPTABLE
+PREHOOK: query: -- data setup
+CREATE TABLE part(
+ p_partkey INT,
+ p_name STRING,
+ p_mfgr STRING,
+ p_brand STRING,
+ p_type STRING,
+ p_size INT,
+ p_container STRING,
+ p_retailprice DOUBLE,
+ p_comment STRING
+)
+PREHOOK: type: CREATETABLE
+POSTHOOK: query: -- data setup
+CREATE TABLE part(
+ p_partkey INT,
+ p_name STRING,
+ p_mfgr STRING,
+ p_brand STRING,
+ p_type STRING,
+ p_size INT,
+ p_container STRING,
+ p_retailprice DOUBLE,
+ p_comment STRING
+)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: default@part
+PREHOOK: query: LOAD DATA LOCAL INPATH '../data/files/part_tiny.txt' overwrite into table part
+PREHOOK: type: LOAD
+PREHOOK: Output: default@part
+POSTHOOK: query: LOAD DATA LOCAL INPATH '../data/files/part_tiny.txt' overwrite into table part
+POSTHOOK: type: LOAD
+POSTHOOK: Output: default@part
+FAILED: SemanticException Line 9:8 Unsupported SubQuery Expression '1' in definition of SubQuery sq_1 [
+a.p_size in
+ (select first_value(p_size) over(partition by p_mfgr order by p_size)
+ from part b
+ where a.p_brand = b.p_brand)
+] used as sq_1 at Line 7:15: Correlated Sub Queries cannot contain Windowing clauses.
Added: hive/trunk/ql/src/test/results/clientnegative/subquery_with_or_cond.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/subquery_with_or_cond.q.out?rev=1535040&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientnegative/subquery_with_or_cond.q.out (added)
+++ hive/trunk/ql/src/test/results/clientnegative/subquery_with_or_cond.q.out Wed Oct 23 14:54:17 2013
@@ -0,0 +1 @@
+FAILED: SemanticException [Error 10249]: Line 4:14 Unsupported SubQuery Expression 'key': Only SubQuery expressions that are top level conjuncts are allowed