Repository: hive Updated Branches: refs/heads/branch-1 e91480f9d -> 505c5585c refs/heads/master 48aefe450 -> a6155b75e
HIVE-13298 : nested join support causes undecipherable errors in SemanticAnalyzer (Sergey Shelukhin, reviewed by Ashutosh Chauhan) Project: http://git-wip-us.apache.org/repos/asf/hive/repo Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/a6155b75 Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/a6155b75 Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/a6155b75 Branch: refs/heads/master Commit: a6155b75e3067803d264c9b03ec84e72a9624d38 Parents: 48aefe4 Author: Sergey Shelukhin <ser...@apache.org> Authored: Mon Mar 21 11:14:41 2016 -0700 Committer: Sergey Shelukhin <ser...@apache.org> Committed: Mon Mar 21 11:14:41 2016 -0700 ---------------------------------------------------------------------- .../hadoop/hive/ql/parse/SemanticAnalyzer.java | 38 +++++++++++++++----- .../queries/clientnegative/right_side_join.q | 12 +++++++ .../clientnegative/right_side_join.q.out | 1 + 3 files changed, 43 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hive/blob/a6155b75/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java ---------------------------------------------------------------------- diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java index 58887d2..d9db1d5 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -8379,6 +8379,7 @@ public class SemanticAnalyzer extends BaseSemanticAnalyzer { QBJoinTree joinTree = new QBJoinTree(); JoinCond[] condn = new JoinCond[1]; + int joinType = joinParseTree.getToken().getType(); switch (joinParseTree.getToken().getType()) { case HiveParser.TOK_LEFTOUTERJOIN: joinTree.setNoOuterJoin(false); @@ -8406,10 +8407,27 @@ public class SemanticAnalyzer extends BaseSemanticAnalyzer { ASTNode left = (ASTNode) joinParseTree.getChild(0); ASTNode right = (ASTNode) joinParseTree.getChild(1); - - if ((left.getToken().getType() == HiveParser.TOK_TABREF) - || (left.getToken().getType() == HiveParser.TOK_SUBQUERY) - || (left.getToken().getType() == HiveParser.TOK_PTBLFUNCTION)) { + boolean isValidLeftToken = isValidJoinSide(left); + boolean isJoinLeftToken = !isValidLeftToken && isJoinToken(left); + boolean isValidRightToken = isValidJoinSide(right); + boolean isJoinRightToken = !isValidRightToken && isJoinToken(right); + // TODO: if we didn't care about the column order, we could switch join sides here + // for TOK_JOIN and TOK_FULLOUTERJOIN. + if (!isValidLeftToken && !isJoinLeftToken) { + throw new SemanticException("Invalid token on the left side of the join: " + + left.getToken().getText() + "; please rewrite your query"); + } else if (!isValidRightToken) { + String advice= ""; + if (isJoinRightToken && !isJoinLeftToken) { + advice = "; for example, put the nested join on the left side, or nest joins differently"; + } else if (isJoinRightToken) { + advice = "; for example, nest joins differently"; + } + throw new SemanticException("Invalid token on the right side of the join: " + + right.getToken().getText() + "; please rewrite your query" + advice); + } + + if (isValidLeftToken) { String tableName = getUnescapedUnqualifiedTableName((ASTNode) left.getChild(0)) .toLowerCase(); String alias = extractJoinAlias(left, tableName); @@ -8423,7 +8441,7 @@ public class SemanticAnalyzer extends BaseSemanticAnalyzer { joinTree.setId(qb.getId()); joinTree.getAliasToOpInfo().put( getModifiedAlias(qb, alias), aliasToOpInfo.get(alias)); - } else if (isJoinToken(left)) { + } else if (isJoinLeftToken) { QBJoinTree leftTree = genJoinTree(qb, left, aliasToOpInfo); joinTree.setJoinSrc(leftTree); String[] leftChildAliases = leftTree.getLeftAliases(); @@ -8437,9 +8455,7 @@ public class SemanticAnalyzer extends BaseSemanticAnalyzer { assert (false); } - if ((right.getToken().getType() == HiveParser.TOK_TABREF) - || (right.getToken().getType() == HiveParser.TOK_SUBQUERY) - || (right.getToken().getType() == HiveParser.TOK_PTBLFUNCTION)) { + if (isValidRightToken) { String tableName = getUnescapedUnqualifiedTableName((ASTNode) right.getChild(0)) .toLowerCase(); String alias = extractJoinAlias(right, tableName); @@ -8529,6 +8545,12 @@ public class SemanticAnalyzer extends BaseSemanticAnalyzer { return joinTree; } + private static boolean isValidJoinSide(ASTNode right) { + return (right.getToken().getType() == HiveParser.TOK_TABREF) + || (right.getToken().getType() == HiveParser.TOK_SUBQUERY) + || (right.getToken().getType() == HiveParser.TOK_PTBLFUNCTION); + } + private String extractJoinAlias(ASTNode node, String tableName) { // ptf node form is: // ^(TOK_PTBLFUNCTION $name $alias? partitionTableFunctionSource partitioningSpec? expression*) http://git-wip-us.apache.org/repos/asf/hive/blob/a6155b75/ql/src/test/queries/clientnegative/right_side_join.q ---------------------------------------------------------------------- diff --git a/ql/src/test/queries/clientnegative/right_side_join.q b/ql/src/test/queries/clientnegative/right_side_join.q new file mode 100644 index 0000000..78771c8 --- /dev/null +++ b/ql/src/test/queries/clientnegative/right_side_join.q @@ -0,0 +1,12 @@ +set hive.cbo.enable=false; + +explain +select * + from alltypesorc, +( + (select csmallint from alltypesorc) a + left join + (select csmallint from alltypesorc) b + on a.csmallint = b.csmallint +); + http://git-wip-us.apache.org/repos/asf/hive/blob/a6155b75/ql/src/test/results/clientnegative/right_side_join.q.out ---------------------------------------------------------------------- diff --git a/ql/src/test/results/clientnegative/right_side_join.q.out b/ql/src/test/results/clientnegative/right_side_join.q.out new file mode 100644 index 0000000..ad4fb72 --- /dev/null +++ b/ql/src/test/results/clientnegative/right_side_join.q.out @@ -0,0 +1 @@ +FAILED: SemanticException Invalid token on the right side of the join: TOK_LEFTOUTERJOIN; please rewrite your query; for example, put the nested join on the left side, or nest joins differently