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 428ba38..58ee605 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 @@ -8493,12 +8493,15 @@ private void mergeJoinTree(QB qb) { if (tree.getJoinSrc() == null) { return; } + // make array with QBJoinTree : outer most(0) --> inner most(n) List trees = new ArrayList(); for (;tree != null; tree = tree.getJoinSrc()) { trees.add(tree); } + // merging from 'target'(inner) to 'node'(outer) + boolean mergedQBJTree = false; for (int i = trees.size() - 1; i >= 0; i--) { QBJoinTree target = trees.get(i); if (target == null) { @@ -8528,6 +8531,7 @@ private void mergeJoinTree(QB qb) { } mergeJoins(qb, node, target, pos, mergeDetails.getSecond()); trees.set(j, null); + mergedQBJTree = true; continue; // continue merging with next alias } /* @@ -8540,6 +8544,27 @@ private void mergeJoinTree(QB qb) { } } } + + // Now that we reordered QBJoinTrees, update leftaliases of all + // QBJoinTree from innermost to outer + if ((trees.size() > 1) && mergedQBJTree) { + QBJoinTree curQBJTree = null; + QBJoinTree prevQBJTree = null; + for (int i = trees.size() - 1; i >= 0; i--) { + curQBJTree = trees.get(i); + if (curQBJTree != null) { + if (prevQBJTree != null) { + ArrayList newCurLeftAliases = new ArrayList(); + newCurLeftAliases.addAll(Arrays.asList(prevQBJTree.getLeftAliases())); + newCurLeftAliases.addAll(Arrays.asList(prevQBJTree.getRightAliases())); + curQBJTree + .setLeftAliases(newCurLeftAliases.toArray(new String[newCurLeftAliases.size()])); + } + prevQBJTree = curQBJTree; + } + } + } + // reconstruct join tree QBJoinTree current = null; for (int i = 0; i < trees.size(); i++) {