This is an automated email from the ASF dual-hosted git repository. kgyrtkirk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push: new 17f7208 HIVE-25734: Wrongly-typed constant in case expression leads to incorrect empty result (#2815) ( Alessandro Solimando reviewed by Zoltan Haindrich) 17f7208 is described below commit 17f72087bd0fc8b5d306e01277052cdcc87c8556 Author: Alessandro Solimando <alessandro.solima...@gmail.com> AuthorDate: Tue Nov 30 09:54:33 2021 +0100 HIVE-25734: Wrongly-typed constant in case expression leads to incorrect empty result (#2815) ( Alessandro Solimando reviewed by Zoltan Haindrich) --- .../rules/HivePointLookupOptimizerRule.java | 35 +++- .../calcite/translator/RexNodeConverter.java | 14 +- .../rules/TestHivePointLookupOptimizerRule.java | 165 +++++++++++++++++- .../calcite/translator/TestRexNodeConverter.java | 186 +++++++++++++++++++++ .../clientpositive/cbo_case_when_wrong_type.q | 10 ++ .../llap/cbo_case_when_wrong_type.q.out | 84 ++++++++++ .../perf/tpcds30tb/tez/query39.q.out | 8 +- 7 files changed, 484 insertions(+), 18 deletions(-) diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePointLookupOptimizerRule.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePointLookupOptimizerRule.java index bf69d3a..da6e9e7 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePointLookupOptimizerRule.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePointLookupOptimizerRule.java @@ -29,6 +29,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.plan.RelOptRuleCall; @@ -387,12 +388,12 @@ public abstract class HivePointLookupOptimizerRule extends RelOptRule { } private static boolean isColumnExpr(RexNode node) { - return !node.getType().isStruct() && HiveCalciteUtil.getInputRefs(node).size() > 0 + return !node.getType().isStruct() && !HiveCalciteUtil.getInputRefs(node).isEmpty() && HiveCalciteUtil.isDeterministic(node); } private static boolean isConstExpr(RexNode node) { - return !node.getType().isStruct() && HiveCalciteUtil.getInputRefs(node).size() == 0 + return !node.getType().isStruct() && HiveCalciteUtil.getInputRefs(node).isEmpty() && HiveCalciteUtil.isDeterministic(node); } @@ -508,7 +509,7 @@ public abstract class HivePointLookupOptimizerRule extends RelOptRule { for (Entry<Set<RexNodeRef>, Collection<ConstraintGroup>> sa : assignmentGroups.asMap().entrySet()) { // skip opaque - if (sa.getKey().size() == 0) { + if (sa.getKey().isEmpty()) { continue; } // not enough equalities should not be handled @@ -593,6 +594,7 @@ public abstract class HivePointLookupOptimizerRule extends RelOptRule { // into a null value. final Multimap<RexNode,RexNode> inLHSExprToRHSNullableExprs = LinkedHashMultimap.create(); final List<RexNode> operands = new ArrayList<>(RexUtil.flattenAnd(call.getOperands())); + for (int i = 0; i < operands.size(); i++) { RexNode operand = operands.get(i); if (operand.getKind() == SqlKind.IN) { @@ -614,7 +616,11 @@ public abstract class HivePointLookupOptimizerRule extends RelOptRule { inLHSExprToRHSNullableExprs.put(ref, constNode); } } - inLHSExprToRHSExprs.get(ref).retainAll(expressions); + Collection<RexNode> knownConstants = inLHSExprToRHSExprs.get(ref); + if (!shareSameType(knownConstants, expressions)) { + return call; + } + knownConstants.retainAll(expressions); } else { for (int j = 1; j < inCall.getOperands().size(); j++) { RexNode constNode = inCall.getOperands().get(j); @@ -639,7 +645,12 @@ public abstract class HivePointLookupOptimizerRule extends RelOptRule { inLHSExprToRHSNullableExprs.put(c.exprNode, c.constNode); } if (inLHSExprToRHSExprs.containsKey(c.exprNode)) { - inLHSExprToRHSExprs.get(c.exprNode).retainAll(Collections.singleton(c.constNode)); + Collection<RexNode> knownConstants = inLHSExprToRHSExprs.get(c.exprNode); + Collection<RexNode> nextConstant = Collections.singleton(c.constNode); + if (!shareSameType(knownConstants, nextConstant)) { + return call; + } + knownConstants.retainAll(nextConstant); } else { inLHSExprToRHSExprs.put(c.exprNode, c.constNode); } @@ -655,6 +666,20 @@ public abstract class HivePointLookupOptimizerRule extends RelOptRule { return RexUtil.composeConjunction(rexBuilder, newOperands, false); } + /** + * Check if the type of nodes in the two collections is homogeneous within the collections + * and identical between them. + * @param nodes1 the first collection of nodes + * @param nodes2 the second collection of nodes + * @return true if nodes in both collections is unique and identical, false otherwise + */ + private static boolean shareSameType(Collection<RexNode> nodes1, Collection<RexNode> nodes2) { + return Stream.of(nodes1, nodes2).flatMap(Collection::stream) + .map(n -> n.getType().getSqlTypeName()) + .distinct() + .count() == 1; + } + private static RexNode handleOR(RexBuilder rexBuilder, RexCall call) { // IN clauses need to be combined by keeping all elements final List<RexNode> operands = new ArrayList<>(RexUtil.flattenOr(call.getOperands())); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/RexNodeConverter.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/RexNodeConverter.java index 9aa1d59..6835289 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/RexNodeConverter.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/RexNodeConverter.java @@ -150,7 +150,7 @@ public class RexNodeConverter { ExprNodeDesc tmpExprNode; RexNode tmpRN; - List<RexNode> childRexNodeLst = new ArrayList<RexNode>(); + List<RexNode> childRexNodeLst = new ArrayList<>(); Builder<RelDataType> argTypeBldr = ImmutableList.<RelDataType> builder(); // TODO: 1) Expand to other functions as needed 2) What about types other than primitive. @@ -164,7 +164,7 @@ public class RexNodeConverter { boolean isCompare = !isNumeric && tgtUdf instanceof GenericUDFBaseCompare; boolean isWhenCase = tgtUdf instanceof GenericUDFWhen || tgtUdf instanceof GenericUDFCase; boolean isTransformableTimeStamp = func.getGenericUDF() instanceof GenericUDFUnixTimeStamp && - func.getChildren().size() != 0; + !func.getChildren().isEmpty(); boolean isBetween = !isNumeric && tgtUdf instanceof GenericUDFBetween; boolean isIN = !isNumeric && tgtUdf instanceof GenericUDFIn; boolean isAllPrimitive = true; @@ -367,9 +367,15 @@ public class RexNodeConverter { for (int i = 1; i < length; i++) { if (i % 2 == 1) { // We rewrite it + RexNode node = childRexNodeLst.get(i); + if (node.isA(SqlKind.LITERAL) && !node.getType().equals(firstPred.getType())) { + // this effectively changes the type of the literal to that of the predicate + // to which it is anyway going to be compared with + // ex: CASE WHEN =($0:SMALLINT, 1:INTEGER) ... => CASE WHEN =($0:SMALLINT, 1:SMALLINT) + node = rexBuilder.makeCast(firstPred.getType(), node); + } newChildRexNodeLst.add( - rexBuilder.makeCall( - SqlStdOperatorTable.EQUALS, firstPred, childRexNodeLst.get(i))); + rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, firstPred, node)); } else { newChildRexNodeLst.add(childRexNodeLst.get(i)); } diff --git a/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/TestHivePointLookupOptimizerRule.java b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/TestHivePointLookupOptimizerRule.java index 09f83ca..67ba437 100644 --- a/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/TestHivePointLookupOptimizerRule.java +++ b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/TestHivePointLookupOptimizerRule.java @@ -66,6 +66,7 @@ public class TestHivePointLookupOptimizerRule { public int f1; public int f2; public int f3; + public double f4; } @Before @@ -97,7 +98,7 @@ public class TestHivePointLookupOptimizerRule { return builder.call(SqlStdOperatorTable.AND, args); } - public RexNode eq(String field, int value) { + public RexNode eq(String field, Number value) { return builder.call(SqlStdOperatorTable.EQUALS, builder.field(field), builder.literal(value)); } @@ -132,6 +133,162 @@ public class TestHivePointLookupOptimizerRule { } @Test + public void testInExprsMergedSingleOverlap() { + + // @formatter:off + final RelNode basePlan = builder + .scan("t") + .filter( + and( + or( + eq("f1",1), + eq("f1",2) + ), + or( + eq("f1",1), + eq("f1",3) + ) + ) + ) + .build(); + // @formatter:on + + planner.setRoot(basePlan); + RelNode optimizedRelNode = planner.findBestExp(); + + HiveFilter filter = (HiveFilter) optimizedRelNode; + RexNode condition = filter.getCondition(); + assertEquals("=($0, 1)", condition.toString()); + } + + @Test + public void testInExprsAndEqualsMerged() { + + // @formatter:off + final RelNode basePlan = builder + .scan("t") + .filter( + and( + or( + eq("f1",1), + eq("f1",2) + ), + or( + eq("f1",1), + eq("f1",3) + ), + eq("f1",1) + ) + ) + .build(); + // @formatter:on + + planner.setRoot(basePlan); + RelNode optimizedRelNode = planner.findBestExp(); + + HiveFilter filter = (HiveFilter) optimizedRelNode; + RexNode condition = filter.getCondition(); + assertEquals("=($0, 1)", condition.toString()); + } + + @Test + public void testInExprsMergedMultipleOverlap() { + + // @formatter:off + final RelNode basePlan = builder + .scan("t") + .filter( + and( + or( + eq("f1",1), + eq("f1",2), + eq("f1",4), + eq("f1",3) + ), + or( + eq("f1",5), + eq("f1",1), + eq("f1",2), + eq("f1",3) + ) + ) + ) + .build(); + // @formatter:on + + planner.setRoot(basePlan); + RelNode optimizedRelNode = planner.findBestExp(); + + HiveFilter filter = (HiveFilter) optimizedRelNode; + RexNode condition = filter.getCondition(); + assertEquals("IN($0, 1, 2, 3)", condition.toString()); + } + + @Test + public void testCaseWithConstantsOfDifferentType() { + + // @formatter:off + final RelNode basePlan = builder + .scan("t") + .filter( + and( + or( + eq("f1",1), + eq("f1",2) + ), + eq("f1", 1.0), + or( + eq("f4",3.0), + eq("f4",4.1) + ) + ) + ) + .build(); + // @formatter:on + + planner.setRoot(basePlan); + RelNode optimizedRelNode = planner.findBestExp(); + + HiveFilter filter = (HiveFilter) optimizedRelNode; + RexNode condition = filter.getCondition(); + // ideally the result would be AND(=($0, 1), IN($3, 3.0E0:DOUBLE, 4.1E0:DOUBLE)), but we + // don't try to compare constants of different type for the same column, even if comparable + assertEquals("AND(IN($0, 1, 2), =($0, 1.0E0:DOUBLE), IN($3, 3.0E0:DOUBLE, 4.1E0:DOUBLE))", + condition.toString()); + } + + @Test + public void testCaseInAndEqualsWithConstantsOfDifferentType() { + + // @formatter:off + final RelNode basePlan = builder + .scan("t") + .filter( + and( + or( + eq("f1",1), + eq("f1",2) + ), + eq("f1",1), + or( + eq("f4",3.0), + eq("f4",4.1) + ), + eq("f4",4.1) + ) + ) + .build(); + // @formatter:on + + planner.setRoot(basePlan); + RelNode optimizedRelNode = planner.findBestExp(); + + HiveFilter filter = (HiveFilter) optimizedRelNode; + RexNode condition = filter.getCondition(); + assertEquals("AND(=($0, 1), =($3, 4.1E0:DOUBLE))", condition.toString()); + } + + @Test public void testSimpleStructCase() { // @formatter:off @@ -203,11 +360,8 @@ public class TestHivePointLookupOptimizerRule { or(eq("f2",3),eq("f2",4)), or(eq("f3",3),eq("f3",4)) ) - - ) )) - .build(); // @formatter:on @@ -217,7 +371,8 @@ public class TestHivePointLookupOptimizerRule { HiveFilter filter = (HiveFilter) optimizedRelNode; RexNode condition = filter.getCondition(); System.out.println(condition); - assertEquals("AND(IN($0, 1, 2), OR(AND(IN($1, 1, 2), IN($2, 1, 2)), AND(IN($1, 3, 4), IN($2, 3, 4))))", + assertEquals("AND(IN($0, 1, 2), OR(AND(IN($1, 1, 2), IN($2, 1, 2)), " + + "AND(IN($1, 3, 4), IN($2, 3, 4))))", condition.toString()); } diff --git a/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/translator/TestRexNodeConverter.java b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/translator/TestRexNodeConverter.java new file mode 100644 index 0000000..341097b --- /dev/null +++ b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/translator/TestRexNodeConverter.java @@ -0,0 +1,186 @@ +/* + * 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.optimizer.calcite.translator; + +import com.google.common.collect.ImmutableList; +import org.apache.calcite.jdbc.JavaTypeFactoryImpl; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelOptPlanner; +import org.apache.calcite.plan.RelOptSchema; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.logical.LogicalTableScan; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rex.RexBuilder; +import org.apache.calcite.rex.RexNode; +import org.apache.calcite.sql.fun.SqlStdOperatorTable; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.tools.RelBuilder; +import org.apache.hadoop.hive.conf.HiveConf; +import org.apache.hadoop.hive.ql.optimizer.calcite.HiveRelFactories; +import org.apache.hadoop.hive.ql.optimizer.calcite.HiveTypeSystemImpl; +import org.apache.hadoop.hive.ql.optimizer.calcite.RelOptHiveTable; +import org.apache.hadoop.hive.ql.parse.CalcitePlanner; +import org.apache.hadoop.hive.ql.parse.SemanticException; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.Collections; +import java.util.List; + +import static org.mockito.Mockito.doReturn; + +@RunWith(MockitoJUnitRunner.class) +public class TestRexNodeConverter { + + private static final String CASE_FUNC_TEST = "case"; + private static final RexBuilder REX_BUILDER = new RexBuilder( + new JavaTypeFactoryImpl(new HiveTypeSystemImpl())); + private static final RelDataTypeFactory TYPE_FACTORY = REX_BUILDER.getTypeFactory(); + + private static RelDataType smallIntegerType; + private static RelDataType integerType; + @SuppressWarnings("FieldCanBeLocal") + private static RelDataType nullableSmallIntegerType; + + private static RexNode varChar34; + private static RexNode varChar35; + private static RexNode varCharNull; + + private static RelOptCluster relOptCluster; + private static RelBuilder relBuilder; + private static RelDataType tableType; + + @Mock + private RelOptSchema schemaMock; + @Mock + private RelOptHiveTable tableMock; + + private LogicalTableScan tableScan; + + @BeforeClass + public static void beforeClass() { + smallIntegerType = TYPE_FACTORY.createSqlType(SqlTypeName.SMALLINT); + integerType = TYPE_FACTORY.createSqlType(SqlTypeName.INTEGER); + nullableSmallIntegerType = TYPE_FACTORY.createTypeWithNullability(smallIntegerType, true); + + RelDataType varcharType = TYPE_FACTORY.createSqlType(SqlTypeName.VARCHAR, 20); + varChar34 = REX_BUILDER.makeLiteral("34", varcharType, true); + varChar35 = REX_BUILDER.makeLiteral("35", varcharType, true); + varCharNull = REX_BUILDER.makeLiteral(null, varcharType, true); + + tableType = TYPE_FACTORY.createStructType( + ImmutableList.of(smallIntegerType, nullableSmallIntegerType), + ImmutableList.of("f1", "f2") + ); + + RelOptPlanner planner = CalcitePlanner.createPlanner(new HiveConf()); + relOptCluster = RelOptCluster.create(planner, REX_BUILDER); + } + + @Before + public void before() { + doReturn(tableType).when(tableMock).getRowType(); + tableScan = LogicalTableScan.create(relOptCluster, tableMock, Collections.emptyList()); + relBuilder = HiveRelFactories.HIVE_BUILDER.create(relOptCluster, schemaMock); + } + + @Test public void testRewriteCaseChildren() throws SemanticException { + RelNode scan = relBuilder.push(tableScan).build(); + RexNode inputRef = REX_BUILDER.makeInputRef(scan, 0); + + List<RexNode> childrenNodeList = ImmutableList.of( + inputRef, + REX_BUILDER.makeLiteral(1, integerType, true), + varChar34, + REX_BUILDER.makeLiteral(6, integerType, true), + varChar35); + + List<RexNode> expected = ImmutableList.of( + REX_BUILDER.makeCall(SqlStdOperatorTable.EQUALS, + inputRef, REX_BUILDER.makeLiteral(1, smallIntegerType, true)), + varChar34, + REX_BUILDER.makeCall(SqlStdOperatorTable.EQUALS, + inputRef, REX_BUILDER.makeLiteral(6, smallIntegerType, true)), + varChar35, + varCharNull); + + List<RexNode> computed = RexNodeConverter.rewriteCaseChildren( + CASE_FUNC_TEST, childrenNodeList, REX_BUILDER); + + Assert.assertEquals(expected, computed); + } + + @Test public void testRewriteCaseChildrenNullChild() throws SemanticException { + RelNode scan = relBuilder.push(tableScan).build(); + RexNode inputRef = REX_BUILDER.makeInputRef(scan, 0); + + List<RexNode> childrenNodeList = ImmutableList.of( + inputRef, + REX_BUILDER.makeLiteral(1, integerType, true), + varChar34, + REX_BUILDER.makeLiteral(null, integerType, true), + varChar35); + + List<RexNode> expected = ImmutableList.of( + REX_BUILDER.makeCall(SqlStdOperatorTable.EQUALS, + inputRef, REX_BUILDER.makeLiteral(1, smallIntegerType, true)), + varChar34, + REX_BUILDER.makeCall(SqlStdOperatorTable.EQUALS, + inputRef, REX_BUILDER.makeLiteral(null, smallIntegerType, true)), + varChar35, + varCharNull); + + List<RexNode> computed = RexNodeConverter.rewriteCaseChildren( + CASE_FUNC_TEST, childrenNodeList, REX_BUILDER); + + Assert.assertEquals(expected, computed); + } + + @Test public void testRewriteCaseChildrenNullChildAndNullableType() throws SemanticException { + RelNode scan = relBuilder.push(tableScan).build(); + RexNode inputRef = REX_BUILDER.makeInputRef(scan, 1); + + List<RexNode> childrenNodeList = ImmutableList.of( + inputRef, + REX_BUILDER.makeLiteral(1, integerType, true), + varChar34, + REX_BUILDER.makeLiteral(null, integerType, true), + varChar35); + + List<RexNode> expected = ImmutableList.of( + REX_BUILDER.makeCall(SqlStdOperatorTable.EQUALS, + inputRef, REX_BUILDER.makeLiteral(1, smallIntegerType, true)), + varChar34, + REX_BUILDER.makeCall(SqlStdOperatorTable.EQUALS, + inputRef, REX_BUILDER.makeLiteral(null, smallIntegerType, true)), + varChar35, + varCharNull); + + List<RexNode> computed = RexNodeConverter.rewriteCaseChildren( + CASE_FUNC_TEST, childrenNodeList, REX_BUILDER); + + Assert.assertEquals(expected, computed); + } +} diff --git a/ql/src/test/queries/clientpositive/cbo_case_when_wrong_type.q b/ql/src/test/queries/clientpositive/cbo_case_when_wrong_type.q new file mode 100644 index 0000000..d559cdb --- /dev/null +++ b/ql/src/test/queries/clientpositive/cbo_case_when_wrong_type.q @@ -0,0 +1,10 @@ +create table t (a smallint, b string); +insert into t values (1, 'a'); +insert into t values (2, 'aa'); +insert into t values (6, 'aaaaaa'); + +select 1 from t where a in (1,2,3) and case a when 1 then true when 2 then true end; +explain cbo select 1 from t where a in (1,2,3) and case a when 1 then true when 2 then true end; + +select 1 from t where a in (1,2,3) and case when a = 1 then true when a = 2 then true end; +explain cbo select 1 from t where a in (1,2,3) and case when a = 1 then true when a = 2 then true end; \ No newline at end of file diff --git a/ql/src/test/results/clientpositive/llap/cbo_case_when_wrong_type.q.out b/ql/src/test/results/clientpositive/llap/cbo_case_when_wrong_type.q.out new file mode 100644 index 0000000..dd48583 --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/cbo_case_when_wrong_type.q.out @@ -0,0 +1,84 @@ +PREHOOK: query: create table t (a smallint, b string) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@t +POSTHOOK: query: create table t (a smallint, b string) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@t +PREHOOK: query: insert into t values (1, 'a') +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +PREHOOK: Output: default@t +POSTHOOK: query: insert into t values (1, 'a') +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +POSTHOOK: Output: default@t +POSTHOOK: Lineage: t.a SCRIPT [] +POSTHOOK: Lineage: t.b SCRIPT [] +PREHOOK: query: insert into t values (2, 'aa') +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +PREHOOK: Output: default@t +POSTHOOK: query: insert into t values (2, 'aa') +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +POSTHOOK: Output: default@t +POSTHOOK: Lineage: t.a SCRIPT [] +POSTHOOK: Lineage: t.b SCRIPT [] +PREHOOK: query: insert into t values (6, 'aaaaaa') +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +PREHOOK: Output: default@t +POSTHOOK: query: insert into t values (6, 'aaaaaa') +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +POSTHOOK: Output: default@t +POSTHOOK: Lineage: t.a SCRIPT [] +POSTHOOK: Lineage: t.b SCRIPT [] +PREHOOK: query: select 1 from t where a in (1,2,3) and case a when 1 then true when 2 then true end +PREHOOK: type: QUERY +PREHOOK: Input: default@t +#### A masked pattern was here #### +POSTHOOK: query: select 1 from t where a in (1,2,3) and case a when 1 then true when 2 then true end +POSTHOOK: type: QUERY +POSTHOOK: Input: default@t +#### A masked pattern was here #### +1 +1 +PREHOOK: query: explain cbo select 1 from t where a in (1,2,3) and case a when 1 then true when 2 then true end +PREHOOK: type: QUERY +PREHOOK: Input: default@t +#### A masked pattern was here #### +POSTHOOK: query: explain cbo select 1 from t where a in (1,2,3) and case a when 1 then true when 2 then true end +POSTHOOK: type: QUERY +POSTHOOK: Input: default@t +#### A masked pattern was here #### +CBO PLAN: +HiveProject($f0=[1]) + HiveFilter(condition=[IN($0, 1:SMALLINT, 2:SMALLINT)]) + HiveTableScan(table=[[default, t]], table:alias=[t]) + +PREHOOK: query: select 1 from t where a in (1,2,3) and case when a = 1 then true when a = 2 then true end +PREHOOK: type: QUERY +PREHOOK: Input: default@t +#### A masked pattern was here #### +POSTHOOK: query: select 1 from t where a in (1,2,3) and case when a = 1 then true when a = 2 then true end +POSTHOOK: type: QUERY +POSTHOOK: Input: default@t +#### A masked pattern was here #### +1 +1 +PREHOOK: query: explain cbo select 1 from t where a in (1,2,3) and case when a = 1 then true when a = 2 then true end +PREHOOK: type: QUERY +PREHOOK: Input: default@t +#### A masked pattern was here #### +POSTHOOK: query: explain cbo select 1 from t where a in (1,2,3) and case when a = 1 then true when a = 2 then true end +POSTHOOK: type: QUERY +POSTHOOK: Input: default@t +#### A masked pattern was here #### +CBO PLAN: +HiveProject($f0=[1]) + HiveFilter(condition=[IN($0, 1:SMALLINT, 2:SMALLINT)]) + HiveTableScan(table=[[default, t]], table:alias=[t]) + diff --git a/ql/src/test/results/clientpositive/perf/tpcds30tb/tez/query39.q.out b/ql/src/test/results/clientpositive/perf/tpcds30tb/tez/query39.q.out index c633923..0b0e893 100644 --- a/ql/src/test/results/clientpositive/perf/tpcds30tb/tez/query39.q.out +++ b/ql/src/test/results/clientpositive/perf/tpcds30tb/tez/query39.q.out @@ -214,10 +214,10 @@ STAGE PLANS: outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5 Statistics: Num rows: 7918 Data size: 380064 Basic stats: COMPLETE Column stats: COMPLETE Filter Operator - predicate: CASE WHEN (((UDFToDouble(_col2) / _col3) = 0)) THEN (false) ELSE (((power(((_col4 - ((_col5 * _col5) / _col3)) / CASE WHEN ((_col3 = 1L)) THEN (null) ELSE ((_col3 - 1)) END), 0.5) / (UDFToDouble(_col2) / _col3)) > 1.0D)) END (type: boolean) + predicate: CASE WHEN (((UDFToDouble(_col2) / _col3) = 0.0D)) THEN (false) ELSE (((power(((_col4 - ((_col5 * _col5) / _col3)) / CASE WHEN ((_col3 = 1L)) THEN (null) ELSE ((_col3 - 1)) END), 0.5) / (UDFToDouble(_col2) / _col3)) > 1.0D)) END (type: boolean) Statistics: Num rows: 3959 Data size: 190032 Basic stats: COMPLETE Column stats: COMPLETE Select Operator - expressions: _col0 (type: bigint), _col1 (type: bigint), (UDFToDouble(_col2) / _col3) (type: double), CASE WHEN (((UDFToDouble(_col2) / _col3) = 0)) THEN (null) ELSE ((power(((_col4 - ((_col5 * _col5) / _col3)) / CASE WHEN ((_col3 = 1L)) THEN (null) ELSE ((_col3 - 1)) END), 0.5) / (UDFToDouble(_col2) / _col3))) END (type: double) + expressions: _col0 (type: bigint), _col1 (type: bigint), (UDFToDouble(_col2) / _col3) (type: double), CASE WHEN (((UDFToDouble(_col2) / _col3) = 0.0D)) THEN (null) ELSE ((power(((_col4 - ((_col5 * _col5) / _col3)) / CASE WHEN ((_col3 = 1L)) THEN (null) ELSE ((_col3 - 1)) END), 0.5) / (UDFToDouble(_col2) / _col3))) END (type: double) outputColumnNames: _col0, _col1, _col2, _col3 Statistics: Num rows: 3959 Data size: 126688 Basic stats: COMPLETE Column stats: COMPLETE Map Join Operator @@ -263,10 +263,10 @@ STAGE PLANS: outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5 Statistics: Num rows: 7918 Data size: 380064 Basic stats: COMPLETE Column stats: COMPLETE Filter Operator - predicate: CASE WHEN (((UDFToDouble(_col2) / _col3) = 0)) THEN (false) ELSE (((power(((_col4 - ((_col5 * _col5) / _col3)) / CASE WHEN ((_col3 = 1L)) THEN (null) ELSE ((_col3 - 1)) END), 0.5) / (UDFToDouble(_col2) / _col3)) > 1.0D)) END (type: boolean) + predicate: CASE WHEN (((UDFToDouble(_col2) / _col3) = 0.0D)) THEN (false) ELSE (((power(((_col4 - ((_col5 * _col5) / _col3)) / CASE WHEN ((_col3 = 1L)) THEN (null) ELSE ((_col3 - 1)) END), 0.5) / (UDFToDouble(_col2) / _col3)) > 1.0D)) END (type: boolean) Statistics: Num rows: 3959 Data size: 190032 Basic stats: COMPLETE Column stats: COMPLETE Select Operator - expressions: _col0 (type: bigint), _col1 (type: bigint), (UDFToDouble(_col2) / _col3) (type: double), CASE WHEN (((UDFToDouble(_col2) / _col3) = 0)) THEN (null) ELSE ((power(((_col4 - ((_col5 * _col5) / _col3)) / CASE WHEN ((_col3 = 1L)) THEN (null) ELSE ((_col3 - 1)) END), 0.5) / (UDFToDouble(_col2) / _col3))) END (type: double) + expressions: _col0 (type: bigint), _col1 (type: bigint), (UDFToDouble(_col2) / _col3) (type: double), CASE WHEN (((UDFToDouble(_col2) / _col3) = 0.0D)) THEN (null) ELSE ((power(((_col4 - ((_col5 * _col5) / _col3)) / CASE WHEN ((_col3 = 1L)) THEN (null) ELSE ((_col3 - 1)) END), 0.5) / (UDFToDouble(_col2) / _col3))) END (type: double) outputColumnNames: _col0, _col1, _col2, _col3 Statistics: Num rows: 3959 Data size: 126688 Basic stats: COMPLETE Column stats: COMPLETE Reduce Output Operator