diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/QBJoinTree.java ql/src/java/org/apache/hadoop/hive/ql/parse/QBJoinTree.java index 9c8cac1..90abbe3 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/QBJoinTree.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/QBJoinTree.java @@ -111,7 +111,11 @@ public String getLeftAlias() { * String */ public void setLeftAlias(String leftAlias) { - this.leftAlias = leftAlias; + if ( this.leftAlias != null && !this.leftAlias.equals(leftAlias) ) { + this.leftAlias = null; + } else { + this.leftAlias = leftAlias; + } } public String[] getRightAliases() { diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java index cf0c895..8c3dc0c 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -1379,7 +1379,7 @@ private boolean isPresent(String[] list, String elem) { } @SuppressWarnings("nls") - private void parseJoinCondPopulateAlias(QBJoinTree joinTree, ASTNode condn, + void parseJoinCondPopulateAlias(QBJoinTree joinTree, ASTNode condn, ArrayList leftAliases, ArrayList rightAliases, ArrayList fields) throws SemanticException { // String[] allAliases = joinTree.getAllAliases(); @@ -1501,6 +1501,160 @@ private void populateAliases(List leftAliases, } } + /* + * refactored out of the Equality case of parseJoinCondition + * so that this can be recursively called on its left tree in the case when + * only left sources are referenced in a Predicate + */ + void applyEqualityPredicateToQBJoinTree(QBJoinTree joinTree, + JoinType type, + List leftSrc, + ASTNode joinCond, + ASTNode leftCondn, + ASTNode rightCondn, + List leftCondAl1, + List leftCondAl2, + List rightCondAl1, + List rightCondAl2) throws SemanticException { + if (leftCondAl1.size() != 0) { + if ((rightCondAl1.size() != 0) + || ((rightCondAl1.size() == 0) && (rightCondAl2.size() == 0))) { + if (type.equals(JoinType.LEFTOUTER) || + type.equals(JoinType.FULLOUTER)) { + if (conf.getBoolVar(HiveConf.ConfVars.HIVEOUTERJOINSUPPORTSFILTERS)) { + joinTree.getFilters().get(0).add(joinCond); + } else { + LOG.warn(ErrorMsg.OUTERJOIN_USES_FILTERS); + joinTree.getFiltersForPushing().get(0).add(joinCond); + } + } else { + /* + * If the rhs references table sources and this QBJoinTree has a leftTree; + * hand it to the leftTree and let it recursively handle it. + * There are 3 cases of passing a condition down: + * 1. The leftSide && rightSide don't contains references to the leftTree's rightAlias + * => pass the lists down as is. + * 2. The leftSide contains refs to the leftTree's rightAlias, the rightSide doesn't + * => switch the leftCondAl1 and leftConAl2 lists and pass down. + * 3. The rightSide contains refs to the leftTree's rightAlias, the leftSide doesn't + * => switch the rightCondAl1 and rightConAl2 lists and pass down. + * 4. In case both contain references to the leftTree's rightAlias + * => we cannot push the condition down. + * 5. If either contain references to both left & right + * => we cannot push forward. + */ + if (rightCondAl1.size() != 0) { + QBJoinTree leftTree = joinTree.getJoinSrc(); + List leftTreeLeftSrc = new ArrayList(); + if (leftTree != null) { + String leftTreeRightSource = leftTree.getRightAliases() != null && + leftTree.getRightAliases().length > 0 ? + leftTree.getRightAliases()[0] : null; + + boolean leftHasRightReference = false; + for (String r : leftCondAl1) { + if (r.equals(leftTreeRightSource)) { + leftHasRightReference = true; + break; + } + } + boolean rightHasRightReference = false; + for (String r : rightCondAl1) { + if (r.equals(leftTreeRightSource)) { + rightHasRightReference = true; + break; + } + } + + boolean pushedDown = false; + if ( !leftHasRightReference && !rightHasRightReference ) { + applyEqualityPredicateToQBJoinTree(leftTree, type, leftTreeLeftSrc, + joinCond, leftCondn, rightCondn, + leftCondAl1, leftCondAl2, + rightCondAl1, rightCondAl2); + pushedDown = true; + } else if ( !leftHasRightReference && rightHasRightReference && rightCondAl1.size() == 1 ) { + applyEqualityPredicateToQBJoinTree(leftTree, type, leftTreeLeftSrc, + joinCond, leftCondn, rightCondn, + leftCondAl1, leftCondAl2, + rightCondAl2, rightCondAl1); + pushedDown = true; + } else if (leftHasRightReference && !rightHasRightReference && leftCondAl1.size() == 1 ) { + applyEqualityPredicateToQBJoinTree(leftTree, type, leftTreeLeftSrc, + joinCond, leftCondn, rightCondn, + leftCondAl2, leftCondAl1, + rightCondAl1, rightCondAl2); + pushedDown = true; + } + + if (leftTreeLeftSrc.size() == 1) { + leftTree.setLeftAlias(leftTreeLeftSrc.get(0)); + } + if ( pushedDown) { + return; + } + } // leftTree != null + } + joinTree.getFiltersForPushing().get(0).add(joinCond); + } + } else if (rightCondAl2.size() != 0) { + populateAliases(leftCondAl1, leftCondAl2, leftCondn, joinTree, + leftSrc); + populateAliases(rightCondAl1, rightCondAl2, rightCondn, joinTree, + leftSrc); + boolean nullsafe = joinCond.getToken().getType() == HiveParser.EQUAL_NS; + joinTree.getNullSafes().add(nullsafe); + } + } else if (leftCondAl2.size() != 0) { + if ((rightCondAl2.size() != 0) + || ((rightCondAl1.size() == 0) && (rightCondAl2.size() == 0))) { + if (type.equals(JoinType.RIGHTOUTER) + || type.equals(JoinType.FULLOUTER)) { + if (conf.getBoolVar(HiveConf.ConfVars.HIVEOUTERJOINSUPPORTSFILTERS)) { + joinTree.getFilters().get(1).add(joinCond); + } else { + LOG.warn(ErrorMsg.OUTERJOIN_USES_FILTERS); + joinTree.getFiltersForPushing().get(1).add(joinCond); + } + } else { + joinTree.getFiltersForPushing().get(1).add(joinCond); + } + } else if (rightCondAl1.size() != 0) { + populateAliases(leftCondAl1, leftCondAl2, leftCondn, joinTree, + leftSrc); + populateAliases(rightCondAl1, rightCondAl2, rightCondn, joinTree, + leftSrc); + boolean nullsafe = joinCond.getToken().getType() == HiveParser.EQUAL_NS; + joinTree.getNullSafes().add(nullsafe); + } + } else if (rightCondAl1.size() != 0) { + if (type.equals(JoinType.LEFTOUTER) + || type.equals(JoinType.FULLOUTER)) { + if (conf.getBoolVar(HiveConf.ConfVars.HIVEOUTERJOINSUPPORTSFILTERS)) { + joinTree.getFilters().get(0).add(joinCond); + } else { + LOG.warn(ErrorMsg.OUTERJOIN_USES_FILTERS); + joinTree.getFiltersForPushing().get(0).add(joinCond); + } + } else { + joinTree.getFiltersForPushing().get(0).add(joinCond); + } + } else { + if (type.equals(JoinType.RIGHTOUTER) + || type.equals(JoinType.FULLOUTER)) { + if (conf.getBoolVar(HiveConf.ConfVars.HIVEOUTERJOINSUPPORTSFILTERS)) { + joinTree.getFilters().get(1).add(joinCond); + } else { + LOG.warn(ErrorMsg.OUTERJOIN_USES_FILTERS); + joinTree.getFiltersForPushing().get(1).add(joinCond); + } + } else { + joinTree.getFiltersForPushing().get(1).add(joinCond); + } + } + + } + private void parseJoinCondition(QBJoinTree joinTree, ASTNode joinCond, List leftSrc) throws SemanticException { if (joinCond == null) { @@ -1581,75 +1735,10 @@ private void parseJoinCondition(QBJoinTree joinTree, ASTNode joinCond, .getMsg(joinCond)); } - if (leftCondAl1.size() != 0) { - if ((rightCondAl1.size() != 0) - || ((rightCondAl1.size() == 0) && (rightCondAl2.size() == 0))) { - if (type.equals(JoinType.LEFTOUTER) || - type.equals(JoinType.FULLOUTER)) { - if (conf.getBoolVar(HiveConf.ConfVars.HIVEOUTERJOINSUPPORTSFILTERS)) { - joinTree.getFilters().get(0).add(joinCond); - } else { - LOG.warn(ErrorMsg.OUTERJOIN_USES_FILTERS); - joinTree.getFiltersForPushing().get(0).add(joinCond); - } - } else { - joinTree.getFiltersForPushing().get(0).add(joinCond); - } - } else if (rightCondAl2.size() != 0) { - populateAliases(leftCondAl1, leftCondAl2, leftCondn, joinTree, - leftSrc); - populateAliases(rightCondAl1, rightCondAl2, rightCondn, joinTree, - leftSrc); - boolean nullsafe = joinCond.getToken().getType() == HiveParser.EQUAL_NS; - joinTree.getNullSafes().add(nullsafe); - } - } else if (leftCondAl2.size() != 0) { - if ((rightCondAl2.size() != 0) - || ((rightCondAl1.size() == 0) && (rightCondAl2.size() == 0))) { - if (type.equals(JoinType.RIGHTOUTER) - || type.equals(JoinType.FULLOUTER)) { - if (conf.getBoolVar(HiveConf.ConfVars.HIVEOUTERJOINSUPPORTSFILTERS)) { - joinTree.getFilters().get(1).add(joinCond); - } else { - LOG.warn(ErrorMsg.OUTERJOIN_USES_FILTERS); - joinTree.getFiltersForPushing().get(1).add(joinCond); - } - } else { - joinTree.getFiltersForPushing().get(1).add(joinCond); - } - } else if (rightCondAl1.size() != 0) { - populateAliases(leftCondAl1, leftCondAl2, leftCondn, joinTree, - leftSrc); - populateAliases(rightCondAl1, rightCondAl2, rightCondn, joinTree, - leftSrc); - boolean nullsafe = joinCond.getToken().getType() == HiveParser.EQUAL_NS; - joinTree.getNullSafes().add(nullsafe); - } - } else if (rightCondAl1.size() != 0) { - if (type.equals(JoinType.LEFTOUTER) - || type.equals(JoinType.FULLOUTER)) { - if (conf.getBoolVar(HiveConf.ConfVars.HIVEOUTERJOINSUPPORTSFILTERS)) { - joinTree.getFilters().get(0).add(joinCond); - } else { - LOG.warn(ErrorMsg.OUTERJOIN_USES_FILTERS); - joinTree.getFiltersForPushing().get(0).add(joinCond); - } - } else { - joinTree.getFiltersForPushing().get(0).add(joinCond); - } - } else { - if (type.equals(JoinType.RIGHTOUTER) - || type.equals(JoinType.FULLOUTER)) { - if (conf.getBoolVar(HiveConf.ConfVars.HIVEOUTERJOINSUPPORTSFILTERS)) { - joinTree.getFilters().get(1).add(joinCond); - } else { - LOG.warn(ErrorMsg.OUTERJOIN_USES_FILTERS); - joinTree.getFiltersForPushing().get(1).add(joinCond); - } - } else { - joinTree.getFiltersForPushing().get(1).add(joinCond); - } - } + applyEqualityPredicateToQBJoinTree(joinTree, type, leftSrc, + joinCond, leftCondn, rightCondn, + leftCondAl1, leftCondAl2, + rightCondAl1, rightCondAl2); break; @@ -6839,7 +6928,7 @@ private void parseStreamTables(QBJoinTree joinTree, QB qb) { /** * Merges node to target */ - private void mergeJoins(QB qb, QBJoinTree node, QBJoinTree target, int pos) { + private void mergeJoins(QB qb, QBJoinTree node, QBJoinTree target, int pos, int[] tgtToNodeExprMap) { String[] nodeRightAliases = node.getRightAliases(); String[] trgtRightAliases = target.getRightAliases(); String[] rightAliases = new String[nodeRightAliases.length @@ -6868,7 +6957,12 @@ private void mergeJoins(QB qb, QBJoinTree node, QBJoinTree target, int pos) { ArrayList> expr = target.getExpressions(); for (int i = 0; i < nodeRightAliases.length; i++) { - expr.add(node.getExpressions().get(i + 1)); + List nodeConds = node.getExpressions().get(i + 1); + ArrayList reordereNodeConds = new ArrayList(); + for(int k=0; k < tgtToNodeExprMap.length; k++) { + reordereNodeConds.add(nodeConds.get(k)); + } + expr.add(reordereNodeConds); } ArrayList nns = node.getNullSafes(); @@ -6985,11 +7079,11 @@ private void mergeJoins(QB qb, QBJoinTree node, QBJoinTree target, int pos) { } } - private int findMergePos(QBJoinTree node, QBJoinTree target) { + private ObjectPair findMergePos(QBJoinTree node, QBJoinTree target) { int res = -1; String leftAlias = node.getLeftAlias(); if (leftAlias == null) { - return -1; + return new ObjectPair(-1, null); } ArrayList nodeCondn = node.getExpressions().get(0); @@ -7008,18 +7102,41 @@ private int findMergePos(QBJoinTree node, QBJoinTree target) { } } - if ((targetCondn == null) || (nodeCondn.size() != targetCondn.size())) { - return -1; + if ( targetCondn == null ) { + return new ObjectPair(-1, null); + } + + /* + * The order of the join condition expressions don't matter. + * A merge can happen: + * - if every target condition is present in some position of the node condition list. + * - there is no node condition, which is not equal to any target condition. + */ + + int[] tgtToNodeExprMap = new int[targetCondn.size()]; + boolean[] nodeFiltersMapped = new boolean[nodeCondn.size()]; + int i, j; + for(i=0; i mergeDetails = findMergePos(node, target); + int pos = mergeDetails.getFirst(); if (pos >= 0) { // for outer joins, it should not exceed 16 aliases (short type) if (!node.getNoOuterJoin() || !target.getNoOuterJoin()) { @@ -7063,7 +7181,7 @@ private void mergeJoinTree(QB qb) { continue; } } - mergeJoins(qb, node, target, pos); + mergeJoins(qb, node, target, pos, mergeDetails.getSecond()); trees.set(j, null); continue; // continue merging with next alias } diff --git ql/src/test/org/apache/hadoop/hive/ql/parse/TestQBJoinTreeApplyPredicate.java ql/src/test/org/apache/hadoop/hive/ql/parse/TestQBJoinTreeApplyPredicate.java new file mode 100644 index 0000000..9e77949 --- /dev/null +++ ql/src/test/org/apache/hadoop/hive/ql/parse/TestQBJoinTreeApplyPredicate.java @@ -0,0 +1,217 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hive.ql.parse; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.Assert; + +import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.ql.session.SessionState; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class TestQBJoinTreeApplyPredicate { + + static HiveConf conf; + + SemanticAnalyzer sA; + + @BeforeClass + public static void initialize() { + conf = new HiveConf(SemanticAnalyzer.class); + SessionState.start(conf); + } + + @Before + public void setup() throws SemanticException { + sA = new SemanticAnalyzer(conf); + } + + static ASTNode constructIdentifier(String nm) { + return (ASTNode) ParseDriver.adaptor.create(HiveParser.Identifier, nm); + } + + static ASTNode constructTabRef(String tblNm) { + ASTNode table = (ASTNode) + ParseDriver.adaptor.create(HiveParser.TOK_TABLE_OR_COL, "TOK_TABLE_OR_COL"); + ASTNode id = constructIdentifier(tblNm); + table.addChild(id); + return table; + } + + static ASTNode constructColRef(String tblNm, String colNm) { + ASTNode table = constructTabRef(tblNm); + ASTNode col = constructIdentifier(colNm); + ASTNode dot = (ASTNode) ParseDriver.adaptor.create(HiveParser.DOT, "."); + dot.addChild(table); + dot.addChild(col); + return dot; + } + + static ASTNode constructEqualityCond(String lTbl, String lCol, String rTbl, String rCol) { + ASTNode lRef = constructColRef(lTbl, lCol); + ASTNode rRef = constructColRef(rTbl, rCol); + ASTNode eq = (ASTNode) ParseDriver.adaptor.create(HiveParser.EQUAL, "="); + eq.addChild(lRef); + eq.addChild(rRef); + return eq; + } + + QBJoinTree createJoinTree(JoinType type, + String leftAlias, + QBJoinTree leftTree, + String rightAlias) { + QBJoinTree jT = new QBJoinTree(); + JoinCond[] condn = new JoinCond[1]; + condn[0] = new JoinCond(0, 1, type); + if ( leftTree == null ) { + jT.setLeftAlias(leftAlias); + String[] leftAliases = new String[1]; + leftAliases[0] = leftAlias; + jT.setLeftAliases(leftAliases); + } else { + jT.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]; + jT.setLeftAliases(leftAliases); + } + String[] rightAliases = new String[1]; + rightAliases[0] = rightAlias; + jT.setRightAliases(rightAliases); + String[] children = new String[2]; + children[0] = leftAlias; + children[1] = rightAlias; + jT.setBaseSrc(children); + ArrayList> expressions = new ArrayList>(); + expressions.add(new ArrayList()); + expressions.add(new ArrayList()); + jT.setExpressions(expressions); + + ArrayList nullsafes = new ArrayList(); + jT.setNullSafes(nullsafes); + + ArrayList> filters = new ArrayList>(); + filters.add(new ArrayList()); + filters.add(new ArrayList()); + jT.setFilters(filters); + jT.setFilterMap(new int[2][]); + + ArrayList> filtersForPushing = + new ArrayList>(); + filtersForPushing.add(new ArrayList()); + filtersForPushing.add(new ArrayList()); + jT.setFiltersForPushing(filtersForPushing); + + return jT; + } + + ASTNode applyEqPredicate(QBJoinTree jT, + String lTbl, String lCol, + String rTbl, String rCol) throws SemanticException { + ASTNode joinCond = constructEqualityCond(lTbl, lCol, rTbl, rCol); + + ASTNode leftCondn = (ASTNode) joinCond.getChild(0); + ASTNode rightCondn = (ASTNode) joinCond.getChild(1); + + List leftSrc = new ArrayList(); + ArrayList leftCondAl1 = new ArrayList(); + ArrayList leftCondAl2 = new ArrayList(); + ArrayList rightCondAl1 = new ArrayList(); + ArrayList rightCondAl2 = new ArrayList(); + + sA.parseJoinCondPopulateAlias(jT, leftCondn, leftCondAl1, leftCondAl2, null); + sA.parseJoinCondPopulateAlias(jT, rightCondn, rightCondAl1, rightCondAl2, null); + + sA.applyEqualityPredicateToQBJoinTree(jT, JoinType.INNER, leftSrc, joinCond, + leftCondn, + rightCondn, + leftCondAl1, leftCondAl2, rightCondAl1, rightCondAl2); + return joinCond; + } + + @Test + public void testSimpleCondn() throws SemanticException { + QBJoinTree jT = createJoinTree(JoinType.INNER, "a", null, "b"); + ASTNode joinCond = applyEqPredicate(jT, "a", "x", "b", "y"); + Assert.assertEquals(jT.getExpressions().get(0).get(0), joinCond.getChild(0)); + Assert.assertEquals(jT.getExpressions().get(1).get(0), joinCond.getChild(1)); + } + + @Test + public void test3WayJoin() throws SemanticException { + QBJoinTree jT1 = createJoinTree(JoinType.INNER, "a", null, "b"); + QBJoinTree jT = createJoinTree(JoinType.INNER, "b", jT1, "c"); + ASTNode joinCond1 = applyEqPredicate(jT, "a", "x", "b", "y"); + ASTNode joinCond2 = applyEqPredicate(jT, "b", "y", "c", "z"); + Assert.assertEquals(jT1.getExpressions().get(0).get(0), joinCond1.getChild(0)); + Assert.assertEquals(jT1.getExpressions().get(1).get(0), joinCond1.getChild(1)); + Assert.assertEquals(jT.getExpressions().get(0).get(0), joinCond2.getChild(0)); + Assert.assertEquals(jT.getExpressions().get(1).get(0), joinCond2.getChild(1)); + } + + @Test + public void test3WayJoinSwitched() throws SemanticException { + QBJoinTree jT1 = createJoinTree(JoinType.INNER, "a", null, "b"); + QBJoinTree jT = createJoinTree(JoinType.INNER, "b", jT1, "c"); + ASTNode joinCond1 = applyEqPredicate(jT, "b", "y", "a", "x"); + ASTNode joinCond2 = applyEqPredicate(jT, "b", "y", "c", "z"); + Assert.assertEquals(jT1.getExpressions().get(0).get(0), joinCond1.getChild(1)); + Assert.assertEquals(jT1.getExpressions().get(1).get(0), joinCond1.getChild(0)); + Assert.assertEquals(jT.getExpressions().get(0).get(0), joinCond2.getChild(0)); + Assert.assertEquals(jT.getExpressions().get(1).get(0), joinCond2.getChild(1)); + } + + @Test + public void test4WayJoin() throws SemanticException { + QBJoinTree jT1 = createJoinTree(JoinType.INNER, "a", null, "b"); + QBJoinTree jT2 = createJoinTree(JoinType.INNER, "b", jT1, "c"); + QBJoinTree jT = createJoinTree(JoinType.INNER, "c", jT2, "d"); + ASTNode joinCond1 = applyEqPredicate(jT, "a", "x", "b", "y"); + ASTNode joinCond2 = applyEqPredicate(jT, "b", "y", "c", "z"); + ASTNode joinCond3 = applyEqPredicate(jT, "a", "x", "c", "z"); + Assert.assertEquals(jT1.getExpressions().get(0).get(0), joinCond1.getChild(0)); + Assert.assertEquals(jT1.getExpressions().get(1).get(0), joinCond1.getChild(1)); + Assert.assertEquals(jT2.getExpressions().get(0).get(0), joinCond2.getChild(0)); + Assert.assertEquals(jT2.getExpressions().get(1).get(0), joinCond2.getChild(1)); + Assert.assertEquals(jT2.getExpressions().get(0).get(1), joinCond3.getChild(0)); + Assert.assertEquals(jT2.getExpressions().get(1).get(1), joinCond3.getChild(1)); + } + + @Test + public void test4WayJoinSwitched() throws SemanticException { + QBJoinTree jT1 = createJoinTree(JoinType.INNER, "a", null, "b"); + QBJoinTree jT2 = createJoinTree(JoinType.INNER, "b", jT1, "c"); + QBJoinTree jT = createJoinTree(JoinType.INNER, "c", jT2, "d"); + ASTNode joinCond1 = applyEqPredicate(jT, "b", "y", "a", "x"); + ASTNode joinCond2 = applyEqPredicate(jT, "b", "y", "c", "z"); + ASTNode joinCond3 = applyEqPredicate(jT, "c", "z", "a", "x"); + Assert.assertEquals(jT1.getExpressions().get(0).get(0), joinCond1.getChild(1)); + Assert.assertEquals(jT1.getExpressions().get(1).get(0), joinCond1.getChild(0)); + Assert.assertEquals(jT2.getExpressions().get(0).get(0), joinCond2.getChild(0)); + Assert.assertEquals(jT2.getExpressions().get(1).get(0), joinCond2.getChild(1)); + Assert.assertEquals(jT2.getExpressions().get(0).get(1), joinCond3.getChild(1)); + Assert.assertEquals(jT2.getExpressions().get(1).get(1), joinCond3.getChild(0)); + } +} \ No newline at end of file diff --git ql/src/test/queries/clientpositive/join_cond_pushdown_1.q ql/src/test/queries/clientpositive/join_cond_pushdown_1.q new file mode 100644 index 0000000..c426ec9 --- /dev/null +++ ql/src/test/queries/clientpositive/join_cond_pushdown_1.q @@ -0,0 +1,30 @@ +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; + + + +explain select * +from part p1 join part p2 join part p3 on p1.p_name = p2.p_name and p2.p_name = p3.p_name; + +explain select * +from part p1 join part p2 join part p3 on p2.p_name = p1.p_name and p3.p_name = p2.p_name; + +explain select * +from part p1 join part p2 join part p3 on p2.p_partkey + p1.p_partkey = p1.p_partkey and p3.p_name = p2.p_name; + +explain select * +from part p1 join part p2 join part p3 on p2.p_partkey = 1 and p3.p_name = p2.p_name; diff --git ql/src/test/queries/clientpositive/join_cond_pushdown_2.q ql/src/test/queries/clientpositive/join_cond_pushdown_2.q new file mode 100644 index 0000000..e154431 --- /dev/null +++ ql/src/test/queries/clientpositive/join_cond_pushdown_2.q @@ -0,0 +1,24 @@ +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; + + +explain select * +from part p1 join part p2 join part p3 on p1.p_name = p2.p_name join part p4 on p2.p_name = p3.p_name and p1.p_name = p4.p_name; + +explain select * +from part p1 join part p2 join part p3 on p2.p_name = p1.p_name join part p4 on p2.p_name = p3.p_name and p1.p_partkey = p4.p_partkey + and p1.p_partkey = p2.p_partkey; diff --git ql/src/test/results/clientpositive/auto_sortmerge_join_12.q.out ql/src/test/results/clientpositive/auto_sortmerge_join_12.q.out index 865627b..63be98e 100644 --- ql/src/test/results/clientpositive/auto_sortmerge_join_12.q.out +++ ql/src/test/results/clientpositive/auto_sortmerge_join_12.q.out @@ -280,8 +280,8 @@ STAGE PLANS: HashTable Sink Operator condition expressions: 0 - 1 {key} - 2 {key} + 1 + 2 handleSkewJoin: false keys: 0 [Column[key]] @@ -295,8 +295,8 @@ STAGE PLANS: HashTable Sink Operator condition expressions: 0 - 1 {key} - 2 {key} + 1 + 2 handleSkewJoin: false keys: 0 [Column[key]] @@ -330,44 +330,38 @@ STAGE PLANS: Inner Join 1 to 2 condition expressions: 0 - 1 {key} - 2 {key} + 1 + 2 handleSkewJoin: false keys: 0 [Column[key]] 1 [Column[key]] 2 [Column[key]] - outputColumnNames: _col5, _col10 Position of Big Table: 2 - Filter Operator - isSamplingPred: false - predicate: - expr: (_col10 = _col5) - type: boolean - Map Join Operator - condition map: - Inner Join 0 to 1 - condition expressions: - 0 - 1 - handleSkewJoin: false - keys: - 0 [] - 1 [] - Position of Big Table: 0 - Select Operator - Group By Operator - aggregations: - expr: count() - bucketGroup: false - mode: hash - outputColumnNames: _col0 - Reduce Output Operator - sort order: - tag: -1 - value expressions: - expr: _col0 - type: bigint + Map Join Operator + condition map: + Inner Join 0 to 1 + condition expressions: + 0 + 1 + handleSkewJoin: false + keys: + 0 [] + 1 [] + Position of Big Table: 0 + Select Operator + Group By Operator + aggregations: + expr: count() + bucketGroup: false + mode: hash + outputColumnNames: _col0 + Reduce Output Operator + sort order: + tag: -1 + value expressions: + expr: _col0 + type: bigint Local Work: Map Reduce Local Work Path -> Alias: diff --git ql/src/test/results/clientpositive/join_cond_pushdown_1.q.out ql/src/test/results/clientpositive/join_cond_pushdown_1.q.out new file mode 100644 index 0000000..e20c36b --- /dev/null +++ ql/src/test/results/clientpositive/join_cond_pushdown_1.q.out @@ -0,0 +1,919 @@ +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 +PREHOOK: query: explain select * +from part p1 join part p2 join part p3 on p1.p_name = p2.p_name and p2.p_name = p3.p_name +PREHOOK: type: QUERY +POSTHOOK: query: explain select * +from part p1 join part p2 join part p3 on p1.p_name = p2.p_name and p2.p_name = p3.p_name +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_JOIN (TOK_TABREF (TOK_TABNAME part) p1) (TOK_TABREF (TOK_TABNAME part) p2)) (TOK_TABREF (TOK_TABNAME part) p3) (and (= (. (TOK_TABLE_OR_COL p1) p_name) (. (TOK_TABLE_OR_COL p2) p_name)) (= (. (TOK_TABLE_OR_COL p2) p_name) (. (TOK_TABLE_OR_COL p3) p_name))))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)))) + +STAGE DEPENDENCIES: + Stage-1 is a root stage + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-1 + Map Reduce + Alias -> Map Operator Tree: + p1 + TableScan + alias: p1 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 0 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + p2 + TableScan + alias: p2 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 1 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + p3 + TableScan + alias: p3 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 2 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + Reduce Operator Tree: + Join Operator + condition map: + Inner Join 0 to 1 + Inner Join 1 to 2 + condition expressions: + 0 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + 1 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + 2 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + handleSkewJoin: false + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col22, _col23, _col24, _col25, _col26, _col27, _col28, _col29, _col30 + Select Operator + expressions: + expr: _col0 + type: int + expr: _col1 + type: string + expr: _col2 + type: string + expr: _col3 + type: string + expr: _col4 + type: string + expr: _col5 + type: int + expr: _col6 + type: string + expr: _col7 + type: double + expr: _col8 + type: string + expr: _col11 + type: int + expr: _col12 + type: string + expr: _col13 + type: string + expr: _col14 + type: string + expr: _col15 + type: string + expr: _col16 + type: int + expr: _col17 + type: string + expr: _col18 + type: double + expr: _col19 + type: string + expr: _col22 + type: int + expr: _col23 + type: string + expr: _col24 + type: string + expr: _col25 + type: string + expr: _col26 + type: string + expr: _col27 + type: int + expr: _col28 + type: string + expr: _col29 + type: double + expr: _col30 + type: string + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col9, _col10, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col20, _col21, _col22, _col23, _col24, _col25, _col26 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.TextInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat + serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe + + Stage: Stage-0 + Fetch Operator + limit: -1 + + +PREHOOK: query: explain select * +from part p1 join part p2 join part p3 on p2.p_name = p1.p_name and p3.p_name = p2.p_name +PREHOOK: type: QUERY +POSTHOOK: query: explain select * +from part p1 join part p2 join part p3 on p2.p_name = p1.p_name and p3.p_name = p2.p_name +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_JOIN (TOK_TABREF (TOK_TABNAME part) p1) (TOK_TABREF (TOK_TABNAME part) p2)) (TOK_TABREF (TOK_TABNAME part) p3) (and (= (. (TOK_TABLE_OR_COL p2) p_name) (. (TOK_TABLE_OR_COL p1) p_name)) (= (. (TOK_TABLE_OR_COL p3) p_name) (. (TOK_TABLE_OR_COL p2) p_name))))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)))) + +STAGE DEPENDENCIES: + Stage-1 is a root stage + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-1 + Map Reduce + Alias -> Map Operator Tree: + p1 + TableScan + alias: p1 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 0 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + p2 + TableScan + alias: p2 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 1 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + p3 + TableScan + alias: p3 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 2 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + Reduce Operator Tree: + Join Operator + condition map: + Inner Join 0 to 1 + Inner Join 1 to 2 + condition expressions: + 0 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + 1 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + 2 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + handleSkewJoin: false + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col22, _col23, _col24, _col25, _col26, _col27, _col28, _col29, _col30 + Select Operator + expressions: + expr: _col0 + type: int + expr: _col1 + type: string + expr: _col2 + type: string + expr: _col3 + type: string + expr: _col4 + type: string + expr: _col5 + type: int + expr: _col6 + type: string + expr: _col7 + type: double + expr: _col8 + type: string + expr: _col11 + type: int + expr: _col12 + type: string + expr: _col13 + type: string + expr: _col14 + type: string + expr: _col15 + type: string + expr: _col16 + type: int + expr: _col17 + type: string + expr: _col18 + type: double + expr: _col19 + type: string + expr: _col22 + type: int + expr: _col23 + type: string + expr: _col24 + type: string + expr: _col25 + type: string + expr: _col26 + type: string + expr: _col27 + type: int + expr: _col28 + type: string + expr: _col29 + type: double + expr: _col30 + type: string + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col9, _col10, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col20, _col21, _col22, _col23, _col24, _col25, _col26 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.TextInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat + serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe + + Stage: Stage-0 + Fetch Operator + limit: -1 + + +PREHOOK: query: explain select * +from part p1 join part p2 join part p3 on p2.p_partkey + p1.p_partkey = p1.p_partkey and p3.p_name = p2.p_name +PREHOOK: type: QUERY +POSTHOOK: query: explain select * +from part p1 join part p2 join part p3 on p2.p_partkey + p1.p_partkey = p1.p_partkey and p3.p_name = p2.p_name +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_JOIN (TOK_TABREF (TOK_TABNAME part) p1) (TOK_TABREF (TOK_TABNAME part) p2)) (TOK_TABREF (TOK_TABNAME part) p3) (and (= (+ (. (TOK_TABLE_OR_COL p2) p_partkey) (. (TOK_TABLE_OR_COL p1) p_partkey)) (. (TOK_TABLE_OR_COL p1) p_partkey)) (= (. (TOK_TABLE_OR_COL p3) p_name) (. (TOK_TABLE_OR_COL p2) p_name))))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)))) + +STAGE DEPENDENCIES: + Stage-2 is a root stage + Stage-1 depends on stages: Stage-2 + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-2 + Map Reduce + Alias -> Map Operator Tree: + p1 + TableScan + alias: p1 + Reduce Output Operator + sort order: + tag: 0 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + p2 + TableScan + alias: p2 + Reduce Output Operator + sort order: + tag: 1 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + Reduce Operator Tree: + Join Operator + condition map: + Inner Join 0 to 1 + condition expressions: + 0 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + 1 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + handleSkewJoin: false + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19 + Filter Operator + predicate: + expr: ((_col11 + _col0) = _col0) + type: boolean + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.SequenceFileInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat + serde: org.apache.hadoop.hive.serde2.lazybinary.LazyBinarySerDe + + Stage: Stage-1 + Map Reduce + Alias -> Map Operator Tree: + $INTNAME + TableScan + Reduce Output Operator + key expressions: + expr: _col12 + type: string + sort order: + + Map-reduce partition columns: + expr: _col12 + type: string + tag: 0 + value expressions: + expr: _col11 + type: int + expr: _col12 + type: string + expr: _col13 + type: string + expr: _col14 + type: string + expr: _col15 + type: string + expr: _col16 + type: int + expr: _col17 + type: string + expr: _col18 + type: double + expr: _col19 + type: string + expr: _col0 + type: int + expr: _col1 + type: string + expr: _col2 + type: string + expr: _col3 + type: string + expr: _col4 + type: string + expr: _col5 + type: int + expr: _col6 + type: string + expr: _col7 + type: double + expr: _col8 + type: string + p3 + TableScan + alias: p3 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 1 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + Reduce Operator Tree: + Join Operator + condition map: + Inner Join 0 to 1 + condition expressions: + 0 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} {VALUE._col11} {VALUE._col12} {VALUE._col13} {VALUE._col14} {VALUE._col15} {VALUE._col16} {VALUE._col17} {VALUE._col18} {VALUE._col19} + 1 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + handleSkewJoin: false + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col22, _col23, _col24, _col25, _col26, _col27, _col28, _col29, _col30 + Select Operator + expressions: + expr: _col11 + type: int + expr: _col12 + type: string + expr: _col13 + type: string + expr: _col14 + type: string + expr: _col15 + type: string + expr: _col16 + type: int + expr: _col17 + type: string + expr: _col18 + type: double + expr: _col19 + type: string + expr: _col0 + type: int + expr: _col1 + type: string + expr: _col2 + type: string + expr: _col3 + type: string + expr: _col4 + type: string + expr: _col5 + type: int + expr: _col6 + type: string + expr: _col7 + type: double + expr: _col8 + type: string + expr: _col22 + type: int + expr: _col23 + type: string + expr: _col24 + type: string + expr: _col25 + type: string + expr: _col26 + type: string + expr: _col27 + type: int + expr: _col28 + type: string + expr: _col29 + type: double + expr: _col30 + type: string + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col9, _col10, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col20, _col21, _col22, _col23, _col24, _col25, _col26 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.TextInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat + serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe + + Stage: Stage-0 + Fetch Operator + limit: -1 + + +PREHOOK: query: explain select * +from part p1 join part p2 join part p3 on p2.p_partkey = 1 and p3.p_name = p2.p_name +PREHOOK: type: QUERY +POSTHOOK: query: explain select * +from part p1 join part p2 join part p3 on p2.p_partkey = 1 and p3.p_name = p2.p_name +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_JOIN (TOK_TABREF (TOK_TABNAME part) p1) (TOK_TABREF (TOK_TABNAME part) p2)) (TOK_TABREF (TOK_TABNAME part) p3) (and (= (. (TOK_TABLE_OR_COL p2) p_partkey) 1) (= (. (TOK_TABLE_OR_COL p3) p_name) (. (TOK_TABLE_OR_COL p2) p_name))))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)))) + +STAGE DEPENDENCIES: + Stage-2 is a root stage + Stage-1 depends on stages: Stage-2 + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-2 + Map Reduce + Alias -> Map Operator Tree: + p1 + TableScan + alias: p1 + Reduce Output Operator + sort order: + tag: 0 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + p2 + TableScan + alias: p2 + Filter Operator + predicate: + expr: (p_partkey = 1) + type: boolean + Reduce Output Operator + sort order: + tag: 1 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + Reduce Operator Tree: + Join Operator + condition map: + Inner Join 0 to 1 + condition expressions: + 0 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + 1 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + handleSkewJoin: false + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.SequenceFileInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat + serde: org.apache.hadoop.hive.serde2.lazybinary.LazyBinarySerDe + + Stage: Stage-1 + Map Reduce + Alias -> Map Operator Tree: + $INTNAME + TableScan + Reduce Output Operator + key expressions: + expr: _col12 + type: string + sort order: + + Map-reduce partition columns: + expr: _col12 + type: string + tag: 0 + value expressions: + expr: _col11 + type: int + expr: _col12 + type: string + expr: _col13 + type: string + expr: _col14 + type: string + expr: _col15 + type: string + expr: _col16 + type: int + expr: _col17 + type: string + expr: _col18 + type: double + expr: _col19 + type: string + expr: _col0 + type: int + expr: _col1 + type: string + expr: _col2 + type: string + expr: _col3 + type: string + expr: _col4 + type: string + expr: _col5 + type: int + expr: _col6 + type: string + expr: _col7 + type: double + expr: _col8 + type: string + p3 + TableScan + alias: p3 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 1 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + Reduce Operator Tree: + Join Operator + condition map: + Inner Join 0 to 1 + condition expressions: + 0 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} {VALUE._col11} {VALUE._col12} {VALUE._col13} {VALUE._col14} {VALUE._col15} {VALUE._col16} {VALUE._col17} {VALUE._col18} {VALUE._col19} + 1 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + handleSkewJoin: false + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col22, _col23, _col24, _col25, _col26, _col27, _col28, _col29, _col30 + Select Operator + expressions: + expr: _col11 + type: int + expr: _col12 + type: string + expr: _col13 + type: string + expr: _col14 + type: string + expr: _col15 + type: string + expr: _col16 + type: int + expr: _col17 + type: string + expr: _col18 + type: double + expr: _col19 + type: string + expr: _col0 + type: int + expr: _col1 + type: string + expr: _col2 + type: string + expr: _col3 + type: string + expr: _col4 + type: string + expr: _col5 + type: int + expr: _col6 + type: string + expr: _col7 + type: double + expr: _col8 + type: string + expr: _col22 + type: int + expr: _col23 + type: string + expr: _col24 + type: string + expr: _col25 + type: string + expr: _col26 + type: string + expr: _col27 + type: int + expr: _col28 + type: string + expr: _col29 + type: double + expr: _col30 + type: string + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col9, _col10, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col20, _col21, _col22, _col23, _col24, _col25, _col26 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.TextInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat + serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe + + Stage: Stage-0 + Fetch Operator + limit: -1 + + diff --git ql/src/test/results/clientpositive/join_cond_pushdown_2.q.out ql/src/test/results/clientpositive/join_cond_pushdown_2.q.out new file mode 100644 index 0000000..c66444c --- /dev/null +++ ql/src/test/results/clientpositive/join_cond_pushdown_2.q.out @@ -0,0 +1,683 @@ +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 +PREHOOK: query: explain select * +from part p1 join part p2 join part p3 on p1.p_name = p2.p_name join part p4 on p2.p_name = p3.p_name and p1.p_name = p4.p_name +PREHOOK: type: QUERY +POSTHOOK: query: explain select * +from part p1 join part p2 join part p3 on p1.p_name = p2.p_name join part p4 on p2.p_name = p3.p_name and p1.p_name = p4.p_name +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_JOIN (TOK_JOIN (TOK_TABREF (TOK_TABNAME part) p1) (TOK_TABREF (TOK_TABNAME part) p2)) (TOK_TABREF (TOK_TABNAME part) p3) (= (. (TOK_TABLE_OR_COL p1) p_name) (. (TOK_TABLE_OR_COL p2) p_name))) (TOK_TABREF (TOK_TABNAME part) p4) (and (= (. (TOK_TABLE_OR_COL p2) p_name) (. (TOK_TABLE_OR_COL p3) p_name)) (= (. (TOK_TABLE_OR_COL p1) p_name) (. (TOK_TABLE_OR_COL p4) p_name))))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)))) + +STAGE DEPENDENCIES: + Stage-1 is a root stage + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-1 + Map Reduce + Alias -> Map Operator Tree: + p1 + TableScan + alias: p1 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 0 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + p2 + TableScan + alias: p2 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 1 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + p3 + TableScan + alias: p3 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 2 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + p4 + TableScan + alias: p4 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 3 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + Reduce Operator Tree: + Join Operator + condition map: + Inner Join 0 to 1 + Inner Join 1 to 2 + Inner Join 0 to 3 + condition expressions: + 0 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + 1 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + 2 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + 3 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + handleSkewJoin: false + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col22, _col23, _col24, _col25, _col26, _col27, _col28, _col29, _col30, _col33, _col34, _col35, _col36, _col37, _col38, _col39, _col40, _col41 + Select Operator + expressions: + expr: _col0 + type: int + expr: _col1 + type: string + expr: _col2 + type: string + expr: _col3 + type: string + expr: _col4 + type: string + expr: _col5 + type: int + expr: _col6 + type: string + expr: _col7 + type: double + expr: _col8 + type: string + expr: _col11 + type: int + expr: _col12 + type: string + expr: _col13 + type: string + expr: _col14 + type: string + expr: _col15 + type: string + expr: _col16 + type: int + expr: _col17 + type: string + expr: _col18 + type: double + expr: _col19 + type: string + expr: _col22 + type: int + expr: _col23 + type: string + expr: _col24 + type: string + expr: _col25 + type: string + expr: _col26 + type: string + expr: _col27 + type: int + expr: _col28 + type: string + expr: _col29 + type: double + expr: _col30 + type: string + expr: _col33 + type: int + expr: _col34 + type: string + expr: _col35 + type: string + expr: _col36 + type: string + expr: _col37 + type: string + expr: _col38 + type: int + expr: _col39 + type: string + expr: _col40 + type: double + expr: _col41 + type: string + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col9, _col10, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col20, _col21, _col22, _col23, _col24, _col25, _col26, _col27, _col28, _col29, _col30, _col31, _col32, _col33, _col34, _col35 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.TextInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat + serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe + + Stage: Stage-0 + Fetch Operator + limit: -1 + + +PREHOOK: query: explain select * +from part p1 join part p2 join part p3 on p2.p_name = p1.p_name join part p4 on p2.p_name = p3.p_name and p1.p_partkey = p4.p_partkey + and p1.p_partkey = p2.p_partkey +PREHOOK: type: QUERY +POSTHOOK: query: explain select * +from part p1 join part p2 join part p3 on p2.p_name = p1.p_name join part p4 on p2.p_name = p3.p_name and p1.p_partkey = p4.p_partkey + and p1.p_partkey = p2.p_partkey +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_JOIN (TOK_JOIN (TOK_TABREF (TOK_TABNAME part) p1) (TOK_TABREF (TOK_TABNAME part) p2)) (TOK_TABREF (TOK_TABNAME part) p3) (= (. (TOK_TABLE_OR_COL p2) p_name) (. (TOK_TABLE_OR_COL p1) p_name))) (TOK_TABREF (TOK_TABNAME part) p4) (and (and (= (. (TOK_TABLE_OR_COL p2) p_name) (. (TOK_TABLE_OR_COL p3) p_name)) (= (. (TOK_TABLE_OR_COL p1) p_partkey) (. (TOK_TABLE_OR_COL p4) p_partkey))) (= (. (TOK_TABLE_OR_COL p1) p_partkey) (. (TOK_TABLE_OR_COL p2) p_partkey))))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)))) + +STAGE DEPENDENCIES: + Stage-3 is a root stage + Stage-2 depends on stages: Stage-3 + Stage-1 depends on stages: Stage-2 + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-3 + Map Reduce + Alias -> Map Operator Tree: + p1 + TableScan + alias: p1 + Reduce Output Operator + key expressions: + expr: p_name + type: string + expr: p_partkey + type: int + sort order: ++ + Map-reduce partition columns: + expr: p_name + type: string + expr: p_partkey + type: int + tag: 0 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + p2 + TableScan + alias: p2 + Reduce Output Operator + key expressions: + expr: p_name + type: string + expr: p_partkey + type: int + sort order: ++ + Map-reduce partition columns: + expr: p_name + type: string + expr: p_partkey + type: int + tag: 1 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + Reduce Operator Tree: + Join Operator + condition map: + Inner Join 0 to 1 + condition expressions: + 0 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + 1 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + handleSkewJoin: false + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.SequenceFileInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat + serde: org.apache.hadoop.hive.serde2.lazybinary.LazyBinarySerDe + + Stage: Stage-2 + Map Reduce + Alias -> Map Operator Tree: + $INTNAME + TableScan + Reduce Output Operator + key expressions: + expr: _col12 + type: string + sort order: + + Map-reduce partition columns: + expr: _col12 + type: string + tag: 0 + value expressions: + expr: _col11 + type: int + expr: _col12 + type: string + expr: _col13 + type: string + expr: _col14 + type: string + expr: _col15 + type: string + expr: _col16 + type: int + expr: _col17 + type: string + expr: _col18 + type: double + expr: _col19 + type: string + expr: _col0 + type: int + expr: _col1 + type: string + expr: _col2 + type: string + expr: _col3 + type: string + expr: _col4 + type: string + expr: _col5 + type: int + expr: _col6 + type: string + expr: _col7 + type: double + expr: _col8 + type: string + p3 + TableScan + alias: p3 + Reduce Output Operator + key expressions: + expr: p_name + type: string + sort order: + + Map-reduce partition columns: + expr: p_name + type: string + tag: 1 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + Reduce Operator Tree: + Join Operator + condition map: + Inner Join 0 to 1 + condition expressions: + 0 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} {VALUE._col11} {VALUE._col12} {VALUE._col13} {VALUE._col14} {VALUE._col15} {VALUE._col16} {VALUE._col17} {VALUE._col18} {VALUE._col19} + 1 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + handleSkewJoin: false + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col22, _col23, _col24, _col25, _col26, _col27, _col28, _col29, _col30 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.SequenceFileInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat + serde: org.apache.hadoop.hive.serde2.lazybinary.LazyBinarySerDe + + Stage: Stage-1 + Map Reduce + Alias -> Map Operator Tree: + $INTNAME + TableScan + Reduce Output Operator + key expressions: + expr: _col11 + type: int + sort order: + + Map-reduce partition columns: + expr: _col11 + type: int + tag: 0 + value expressions: + expr: _col22 + type: int + expr: _col23 + type: string + expr: _col24 + type: string + expr: _col25 + type: string + expr: _col26 + type: string + expr: _col27 + type: int + expr: _col28 + type: string + expr: _col29 + type: double + expr: _col30 + type: string + expr: _col0 + type: int + expr: _col1 + type: string + expr: _col2 + type: string + expr: _col3 + type: string + expr: _col4 + type: string + expr: _col5 + type: int + expr: _col6 + type: string + expr: _col7 + type: double + expr: _col8 + type: string + expr: _col11 + type: int + expr: _col12 + type: string + expr: _col13 + type: string + expr: _col14 + type: string + expr: _col15 + type: string + expr: _col16 + type: int + expr: _col17 + type: string + expr: _col18 + type: double + expr: _col19 + type: string + p4 + TableScan + alias: p4 + Reduce Output Operator + key expressions: + expr: p_partkey + type: int + sort order: + + Map-reduce partition columns: + expr: p_partkey + type: int + tag: 1 + value expressions: + expr: p_partkey + type: int + expr: p_name + type: string + expr: p_mfgr + type: string + expr: p_brand + type: string + expr: p_type + type: string + expr: p_size + type: int + expr: p_container + type: string + expr: p_retailprice + type: double + expr: p_comment + type: string + Reduce Operator Tree: + Join Operator + condition map: + Inner Join 0 to 1 + condition expressions: + 0 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} {VALUE._col11} {VALUE._col12} {VALUE._col13} {VALUE._col14} {VALUE._col15} {VALUE._col16} {VALUE._col17} {VALUE._col18} {VALUE._col19} {VALUE._col22} {VALUE._col23} {VALUE._col24} {VALUE._col25} {VALUE._col26} {VALUE._col27} {VALUE._col28} {VALUE._col29} {VALUE._col30} + 1 {VALUE._col0} {VALUE._col1} {VALUE._col2} {VALUE._col3} {VALUE._col4} {VALUE._col5} {VALUE._col6} {VALUE._col7} {VALUE._col8} + handleSkewJoin: false + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col22, _col23, _col24, _col25, _col26, _col27, _col28, _col29, _col30, _col33, _col34, _col35, _col36, _col37, _col38, _col39, _col40, _col41 + Select Operator + expressions: + expr: _col22 + type: int + expr: _col23 + type: string + expr: _col24 + type: string + expr: _col25 + type: string + expr: _col26 + type: string + expr: _col27 + type: int + expr: _col28 + type: string + expr: _col29 + type: double + expr: _col30 + type: string + expr: _col11 + type: int + expr: _col12 + type: string + expr: _col13 + type: string + expr: _col14 + type: string + expr: _col15 + type: string + expr: _col16 + type: int + expr: _col17 + type: string + expr: _col18 + type: double + expr: _col19 + type: string + expr: _col0 + type: int + expr: _col1 + type: string + expr: _col2 + type: string + expr: _col3 + type: string + expr: _col4 + type: string + expr: _col5 + type: int + expr: _col6 + type: string + expr: _col7 + type: double + expr: _col8 + type: string + expr: _col33 + type: int + expr: _col34 + type: string + expr: _col35 + type: string + expr: _col36 + type: string + expr: _col37 + type: string + expr: _col38 + type: int + expr: _col39 + type: string + expr: _col40 + type: double + expr: _col41 + type: string + outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7, _col8, _col9, _col10, _col11, _col12, _col13, _col14, _col15, _col16, _col17, _col18, _col19, _col20, _col21, _col22, _col23, _col24, _col25, _col26, _col27, _col28, _col29, _col30, _col31, _col32, _col33, _col34, _col35 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.TextInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat + serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe + + Stage: Stage-0 + Fetch Operator + limit: -1 + +