Skip to content

Commit

Permalink
HIVE-9113 : Explain on query failed with NPE (Navis reviewed by Szeho…
Browse files Browse the repository at this point in the history
…n Ho)

git-svn-id: https://svn.apache.org/repos/asf/hive/trunk@1646390 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
navis committed Dec 18, 2014
1 parent 08b8e0d commit 358242f
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 17 deletions.
30 changes: 21 additions & 9 deletions ql/src/java/org/apache/hadoop/hive/ql/parse/QBSubQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ class NotInCheck implements ISubQueryJoinInfo {
/*
* row resolver of the SubQuery.
* Set by the SemanticAnalyzer after the Plan for the SubQuery is genned.
* This is neede in case the SubQuery select list contains a TOK_ALLCOLREF
* This is needed in case the SubQuery select list contains a TOK_ALLCOLREF
*/
RowResolver sqRR;

Expand Down Expand Up @@ -513,7 +513,10 @@ void validateAndRewriteAST(RowResolver outerQueryRR,
String outerQueryAlias,
Set<String> outerQryAliases) throws SemanticException {

ASTNode selectClause = (ASTNode) subQueryAST.getChild(1).getChild(1);
ASTNode fromClause = getChildFromSubqueryAST("From", HiveParser.TOK_FROM);
ASTNode insertClause = getChildFromSubqueryAST("Insert", HiveParser.TOK_INSERT);

ASTNode selectClause = (ASTNode) insertClause.getChild(1);

int selectExprStart = 0;
if ( selectClause.getChild(0).getType() == HiveParser.TOK_HINTLIST ) {
Expand All @@ -537,15 +540,15 @@ void validateAndRewriteAST(RowResolver outerQueryRR,
* Restriction 17.s :: SubQuery cannot use the same table alias as one used in
* the Outer Query.
*/
List<String> sqAliases = SubQueryUtils.getTableAliasesInSubQuery(this);
List<String> sqAliases = SubQueryUtils.getTableAliasesInSubQuery(fromClause);
String sharedAlias = null;
for(String s : sqAliases ) {
if ( outerQryAliases.contains(s) ) {
sharedAlias = s;
}
}
if ( sharedAlias != null) {
ASTNode whereClause = SubQueryUtils.subQueryWhere(subQueryAST);
ASTNode whereClause = SubQueryUtils.subQueryWhere(insertClause);

if ( whereClause != null ) {
ASTNode u = SubQueryUtils.hasUnQualifiedColumnReferences(whereClause);
Expand Down Expand Up @@ -581,7 +584,7 @@ void validateAndRewriteAST(RowResolver outerQueryRR,
containsAggregationExprs = containsAggregationExprs | ( r == 1 );
}

rewrite(outerQueryRR, forHavingClause, outerQueryAlias);
rewrite(outerQueryRR, forHavingClause, outerQueryAlias, insertClause, selectClause);

SubQueryUtils.setOriginDeep(subQueryAST, originalSQASTOrigin);

Expand Down Expand Up @@ -631,6 +634,16 @@ void validateAndRewriteAST(RowResolver outerQueryRR,

}

private ASTNode getChildFromSubqueryAST(String errorMsg, int type) throws SemanticException {
ASTNode childAST = (ASTNode) subQueryAST.getFirstChildWithType(type);
if (childAST == null && errorMsg != null) {
subQueryAST.setOrigin(originalSQASTOrigin);
throw new SemanticException(ErrorMsg.INVALID_SUBQUERY_EXPRESSION.getMsg(
subQueryAST, errorMsg + " clause is missing in SubQuery."));
}
return childAST;
}

private void setJoinType() {
if ( operator.getType() == SubQueryType.NOT_IN ||
operator.getType() == SubQueryType.NOT_EXISTS ) {
Expand Down Expand Up @@ -744,7 +757,7 @@ String getNextCorrExprAlias() {
* R2.x = min(R1.y)
* Where R1 is an outer table reference, and R2 is a SubQuery table reference.
* b. When hoisting the correlation predicate to a join predicate, we need to
* rewrite it to be in the form the Join code allows: so the predicte needs
* rewrite it to be in the form the Join code allows: so the predict needs
* to contain a qualified column references.
* We handle this by generating a new name for the aggregation expression,
* like R1._gby_sq_col_1 and adding this mapping to the Outer Query's
Expand All @@ -753,9 +766,8 @@ String getNextCorrExprAlias() {
*/
private void rewrite(RowResolver parentQueryRR,
boolean forHavingClause,
String outerQueryAlias) throws SemanticException {
ASTNode selectClause = (ASTNode) subQueryAST.getChild(1).getChild(1);
ASTNode whereClause = SubQueryUtils.subQueryWhere(subQueryAST);
String outerQueryAlias, ASTNode insertClause, ASTNode selectClause) throws SemanticException {
ASTNode whereClause = SubQueryUtils.subQueryWhere(insertClause);

if ( whereClause == null ) {
return;
Expand Down
15 changes: 7 additions & 8 deletions ql/src/java/org/apache/hadoop/hive/ql/parse/SubQueryUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static void extractConjuncts(ASTNode node, List<ASTNode> conjuncts) {
}

/*
* Remove the SubQuery from the Where CLause Tree.
* Remove the SubQuery from the Where Clause Tree.
* return the remaining WhereClause.
*/
static ASTNode rewriteParentQueryWhere(ASTNode whereCond, ASTNode subQuery)
Expand Down Expand Up @@ -271,10 +271,9 @@ static int checkAggOrWindowing(ASTNode expressionTree) throws SemanticException
return r;
}

static List<String> getTableAliasesInSubQuery(QBSubQuery sq) {
static List<String> getTableAliasesInSubQuery(ASTNode fromClause) {
List<String> aliases = new ArrayList<String>();
ASTNode joinAST = (ASTNode) sq.getSubQueryAST().getChild(0);
getTableAliasesInSubQuery((ASTNode) joinAST.getChild(0), aliases);
getTableAliasesInSubQuery((ASTNode) fromClause.getChild(0), aliases);
return aliases;
}

Expand Down Expand Up @@ -318,10 +317,10 @@ else if ( type == HiveParser.TOK_TABLE_OR_COL ) {
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);
static ASTNode subQueryWhere(ASTNode insertClause) {
if (insertClause.getChildCount() > 2 &&
insertClause.getChild(2).getType() == HiveParser.TOK_WHERE ) {
return (ASTNode) insertClause.getChild(2);
}
return null;
}
Expand Down
1 change: 1 addition & 0 deletions ql/src/test/queries/clientnegative/subquery_missing_from.q
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
select * from src where src.key in (select key);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FAILED: SemanticException Line 0:-1 Invalid SubQuery expression 'key' in definition of SubQuery sq_1 [
src.key in (select key)
] used as sq_1 at Line 1:32: From clause is missing in SubQuery.

0 comments on commit 358242f

Please sign in to comment.