diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java index ca0416b..43ff57e 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/TypeCheckProcFactory.java @@ -63,9 +63,12 @@ import org.apache.hadoop.hive.ql.udf.SettableUDF; import org.apache.hadoop.hive.ql.udf.generic.GenericUDF; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFBaseCompare; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDFNvl; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPAnd; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPEqual; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNot; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPOr; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDFWhen; import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.hadoop.hive.serde2.objectinspector.ConstantObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; @@ -1057,6 +1060,17 @@ protected ExprNodeDesc getXpathOrFuncExprNodeDesc(ASTNode expr, } desc = ExprNodeGenericFuncDesc.newInstance(genericUDF, funcText, childrenList); + } else if (ctx.isFoldExpr() && canConvertIntoNvl(genericUDF, children)) { + // Rewrite CASE into NVL + List childrenList = new ArrayList(2); + childrenList.add(children.get(0)); + childrenList.add(new ExprNodeConstantDesc(false)); + desc = ExprNodeGenericFuncDesc.newInstance(new GenericUDFNvl(), children); + if (Boolean.FALSE.equals(((ExprNodeConstantDesc) children.get(1)).getValue())) { + List exprs = new ArrayList<>(); + exprs.add(desc); + desc = ExprNodeGenericFuncDesc.newInstance(new GenericUDFOPNot(), exprs); + } } else { desc = ExprNodeGenericFuncDesc.newInstance(genericUDF, funcText, children); @@ -1085,6 +1099,21 @@ protected ExprNodeDesc getXpathOrFuncExprNodeDesc(ASTNode expr, return desc; } + private boolean canConvertIntoNvl(GenericUDF genericUDF, ArrayList children) { + if (genericUDF instanceof GenericUDFWhen && children.size() == 3 && + children.get(1) instanceof ExprNodeConstantDesc && + children.get(2) instanceof ExprNodeConstantDesc) { + ExprNodeConstantDesc constThen = (ExprNodeConstantDesc) children.get(1); + ExprNodeConstantDesc constElse = (ExprNodeConstantDesc) children.get(2); + Object thenVal = constThen.getValue(); + Object elseVal = constElse.getValue(); + if (thenVal instanceof Boolean && elseVal instanceof Boolean) { + return true; + } + } + return false; + } + /** * Returns true if des is a descendant of ans (ancestor) */