diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java index 08e1136..942fb35 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java @@ -1739,13 +1739,13 @@ public static boolean isOpCast(ExprNodeDesc desc) { if (!(desc instanceof ExprNodeGenericFuncDesc)) { return false; } - GenericUDF genericUDF = ((ExprNodeGenericFuncDesc)desc).getGenericUDF(); - Class udfClass; - if (genericUDF instanceof GenericUDFBridge) { - udfClass = ((GenericUDFBridge)genericUDF).getUdfClass(); - } else { - udfClass = genericUDF.getClass(); - } + return isOpCast(((ExprNodeGenericFuncDesc)desc).getGenericUDF()); + } + + public static boolean isOpCast(GenericUDF genericUDF) { + Class udfClass = (genericUDF instanceof GenericUDFBridge) ? + ((GenericUDFBridge)genericUDF).getUdfClass() : genericUDF.getClass(); + return udfClass == UDFToBoolean.class || udfClass == UDFToByte.class || udfClass == UDFToDouble.class || udfClass == UDFToFloat.class || udfClass == UDFToInteger.class || udfClass == UDFToLong.class || 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 9ca194a..b9b832e 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 @@ -164,6 +164,10 @@ private static ExprNodeConstantDesc typeCast(ExprNodeDesc desc, TypeInfo ti) { } LOG.debug("Casting " + desc + " to type " + ti); ExprNodeConstantDesc c = (ExprNodeConstantDesc) desc; + if (null != c.getFoldedFromVal() && priti.getTypeName().equals(serdeConstants.STRING_TYPE_NAME)) { + // avoid double casting to preserve original string representation of constant. + return new ExprNodeConstantDesc(c.getFoldedFromVal()); + } ObjectInspector origOI = TypeInfoUtils.getStandardJavaObjectInspectorFromTypeInfo(desc.getTypeInfo()); ObjectInspector oi = @@ -538,7 +542,12 @@ private static ExprNodeDesc evaluateFunction(GenericUDF udf, List LOG.error("Unable to evaluate " + udf + ". Return value unrecoginizable."); return null; } - return new ExprNodeConstantDesc(o); + String constStr = null; + if(arguments.length == 1 && FunctionRegistry.isOpCast(udf)) { + // remember original string representation of constant. + constStr = arguments[0].get().toString(); + } + return new ExprNodeConstantDesc(o).setFoldedFromVal(constStr); } catch (HiveException e) { LOG.error("Evaluation function " + udf.getClass() + " failed in Constant Propagatation Optimizer."); diff --git a/ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeConstantDesc.java b/ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeConstantDesc.java index 8a41577..b15df0f 100755 --- a/ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeConstantDesc.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeConstantDesc.java @@ -40,6 +40,17 @@ // If this constant was created while doing constant folding, foldedFromCol holds the name of // original column from which it was folded. private transient String foldedFromCol; + // string representation of folding constant. + private transient String foldedFromVal; + + public ExprNodeConstantDesc setFoldedFromVal(String foldedFromVal) { + this.foldedFromVal = foldedFromVal; + return this; + } + + public String getFoldedFromVal() { + return foldedFromVal; + } public String getFoldedFromCol() { return foldedFromCol; diff --git a/ql/src/test/queries/clientpositive/constprog_type.q b/ql/src/test/queries/clientpositive/constprog_type.q index 93249ad..4907652 100644 --- a/ql/src/test/queries/clientpositive/constprog_type.q +++ b/ql/src/test/queries/clientpositive/constprog_type.q @@ -12,3 +12,5 @@ SELECT cast('2013-11-17' as date), cast(cast('1.3041352164485E9' as double) as t FROM src tablesample (1 rows); SELECT * FROM dest1; + +SELECT key, value FROM src WHERE key = cast(86 as double); diff --git a/ql/src/test/results/clientpositive/constprog_type.q.out b/ql/src/test/results/clientpositive/constprog_type.q.out index 1764184..08b0ae3 100644 --- a/ql/src/test/results/clientpositive/constprog_type.q.out +++ b/ql/src/test/results/clientpositive/constprog_type.q.out @@ -122,3 +122,12 @@ POSTHOOK: type: QUERY POSTHOOK: Input: default@dest1 #### A masked pattern was here #### 2013-11-17 2011-04-29 20:46:56.4485 +PREHOOK: query: SELECT key, value FROM src WHERE key = cast(86 as double) +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: SELECT key, value FROM src WHERE key = cast(86 as double) +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +86 val_86