diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConstantPropagateProcFactory.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConstantPropagateProcFactory.java index b7a067a..b1d2ba4 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConstantPropagateProcFactory.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConstantPropagateProcFactory.java @@ -188,6 +188,14 @@ private static ExprNodeConstantDesc typeCast(ExprNodeDesc desc, TypeInfo ti) { return new ExprNodeConstantDesc(ti, convObj); } + public static ExprNodeDesc foldExpr(ExprNodeGenericFuncDesc funcDesc) { + + GenericUDF udf = funcDesc.getGenericUDF(); + if (!isDeterministicUdf(udf)) { + return funcDesc; + } + return evaluateFunction(funcDesc.getGenericUDF(),funcDesc.getChildren(), funcDesc.getChildren()); + } /** * Fold input expression desc. * @@ -279,7 +287,7 @@ private static boolean isDeterministicUdf(GenericUDF udf) { (UDF) Class.forName(bridge.getUdfClassName(), true, Utilities.getSessionSpecifiedClassLoader()) .newInstance(); files = udfInternal.getRequiredFiles(); - jars = udf.getRequiredJars(); + jars = udfInternal.getRequiredJars(); } catch (Exception e) { LOG.error("The UDF implementation class '" + udfClassName + "' is not present in the class path"); @@ -471,6 +479,16 @@ private static ExprNodeDesc evaluateFunction(GenericUDF udf, List // FIXME: add null support. return null; + } else if (desc instanceof ExprNodeGenericFuncDesc) { + ExprNodeDesc evaluatedFn = foldExpr((ExprNodeGenericFuncDesc)desc); + if (null == evaluatedFn || !(evaluatedFn instanceof ExprNodeConstantDesc)) { + return null; + } + ExprNodeConstantDesc constant = (ExprNodeConstantDesc) evaluatedFn; + Object writableValue = PrimitiveObjectInspectorFactory.getPrimitiveJavaObjectInspector( + (PrimitiveTypeInfo) constant.getTypeInfo()).getPrimitiveWritableObject(constant.getValue()); + arguments[i] = new DeferredJavaObject(writableValue); + argois[i] = ObjectInspectorUtils.getConstantObjectInspector(constant.getWritableObjectInspector(), writableValue); } else { return null; } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/pcr/PcrOpProcFactory.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/pcr/PcrOpProcFactory.java index c2d49f6..8955cbd 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/pcr/PcrOpProcFactory.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/pcr/PcrOpProcFactory.java @@ -31,10 +31,13 @@ import org.apache.hadoop.hive.ql.lib.NodeProcessorCtx; import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.metadata.Partition; +import org.apache.hadoop.hive.ql.optimizer.ConstantPropagateProcFactory; import org.apache.hadoop.hive.ql.parse.ParseContext; import org.apache.hadoop.hive.ql.parse.PrunedPartitionList; import org.apache.hadoop.hive.ql.parse.SemanticException; +import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeDesc; +import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc; import org.apache.hadoop.hive.ql.plan.OperatorDesc; /** @@ -133,7 +136,15 @@ public Object process(Node nd, Stack stack, NodeProcessorCtx procCtx, if (wrapper.state == PcrExprProcFactory.WalkState.TRUE) { owc.getOpToRemove().add(new PcrOpWalkerCtx.OpToDeleteInfo(pop, fop)); - } else if (wrapper.state != PcrExprProcFactory.WalkState.FALSE) { + } else if (wrapper.state == PcrExprProcFactory.WalkState.CONSTANT && wrapper.outExpr instanceof ExprNodeGenericFuncDesc) { + ExprNodeDesc desc = ConstantPropagateProcFactory.foldExpr((ExprNodeGenericFuncDesc)wrapper.outExpr); + if (desc != null && desc instanceof ExprNodeConstantDesc && Boolean.TRUE.equals(((ExprNodeConstantDesc)desc).getValue())) { + owc.getOpToRemove().add(new PcrOpWalkerCtx.OpToDeleteInfo(pop, fop)); + } else { + fop.getConf().setPredicate(wrapper.outExpr); + } + } + else if (wrapper.state != PcrExprProcFactory.WalkState.FALSE) { fop.getConf().setPredicate(wrapper.outExpr); } else { LOG.warn("Filter passes no row"); diff --git a/ql/src/test/queries/clientpositive/pcr.q b/ql/src/test/queries/clientpositive/pcr.q index 3be0ff2..a2ffda3 100644 --- a/ql/src/test/queries/clientpositive/pcr.q +++ b/ql/src/test/queries/clientpositive/pcr.q @@ -138,4 +138,6 @@ insert overwrite table foo_field partition (ds=7) select strct from ab where str select s,ds from foo_field where ((ds + s.a) > 0) order by ds,s; drop table foo_field; - +explain select key,value from srcpart where cast(hr as double) = cast(11 as double); +explain select key,value from srcpart where hr = cast(11 as double); +explain select key,value from srcpart where cast(hr as double) = 11 ; diff --git a/ql/src/test/results/clientpositive/pcr.q.out b/ql/src/test/results/clientpositive/pcr.q.out index 9d3b283..568417a 100644 --- a/ql/src/test/results/clientpositive/pcr.q.out +++ b/ql/src/test/results/clientpositive/pcr.q.out @@ -6067,3 +6067,66 @@ POSTHOOK: query: drop table foo_field POSTHOOK: type: DROPTABLE POSTHOOK: Input: default@foo_field POSTHOOK: Output: default@foo_field +PREHOOK: query: explain select key,value from srcpart where cast(hr as double) = cast(11 as double) +PREHOOK: type: QUERY +POSTHOOK: query: explain select key,value from srcpart where cast(hr as double) = cast(11 as double) +POSTHOOK: type: QUERY +STAGE DEPENDENCIES: + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-0 + Fetch Operator + limit: -1 + Processor Tree: + TableScan + alias: srcpart + Statistics: Num rows: 1000 Data size: 10624 Basic stats: COMPLETE Column stats: NONE + Select Operator + expressions: key (type: string), value (type: string) + outputColumnNames: _col0, _col1 + Statistics: Num rows: 1000 Data size: 10624 Basic stats: COMPLETE Column stats: NONE + ListSink + +PREHOOK: query: explain select key,value from srcpart where hr = cast(11 as double) +PREHOOK: type: QUERY +POSTHOOK: query: explain select key,value from srcpart where hr = cast(11 as double) +POSTHOOK: type: QUERY +STAGE DEPENDENCIES: + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-0 + Fetch Operator + limit: -1 + Processor Tree: + TableScan + alias: srcpart + Statistics: Num rows: 1000 Data size: 10624 Basic stats: COMPLETE Column stats: NONE + Select Operator + expressions: key (type: string), value (type: string) + outputColumnNames: _col0, _col1 + Statistics: Num rows: 1000 Data size: 10624 Basic stats: COMPLETE Column stats: NONE + ListSink + +PREHOOK: query: explain select key,value from srcpart where cast(hr as double) = 11 +PREHOOK: type: QUERY +POSTHOOK: query: explain select key,value from srcpart where cast(hr as double) = 11 +POSTHOOK: type: QUERY +STAGE DEPENDENCIES: + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-0 + Fetch Operator + limit: -1 + Processor Tree: + TableScan + alias: srcpart + Statistics: Num rows: 1000 Data size: 10624 Basic stats: COMPLETE Column stats: NONE + Select Operator + expressions: key (type: string), value (type: string) + outputColumnNames: _col0, _col1 + Statistics: Num rows: 1000 Data size: 10624 Basic stats: COMPLETE Column stats: NONE + ListSink + diff --git a/ql/src/test/results/compiler/plan/input_part1.q.xml b/ql/src/test/results/compiler/plan/input_part1.q.xml index 0bca511..3640102 100644 --- a/ql/src/test/results/compiler/plan/input_part1.q.xml +++ b/ql/src/test/results/compiler/plan/input_part1.q.xml @@ -352,6 +352,9 @@ _col3 + + ds + @@ -363,6 +366,9 @@ _col2 + + hr + diff --git a/ql/src/test/results/compiler/plan/sample1.q.xml b/ql/src/test/results/compiler/plan/sample1.q.xml index a5017cb..0ab3b87 100644 --- a/ql/src/test/results/compiler/plan/sample1.q.xml +++ b/ql/src/test/results/compiler/plan/sample1.q.xml @@ -352,6 +352,9 @@ _col3 + + hr + @@ -363,6 +366,9 @@ _col2 + + ds +