diff --git ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/ASTConverter.java ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/ASTConverter.java index de7e2f8..e7de4f7 100644 --- ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/ASTConverter.java +++ ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/ASTConverter.java @@ -53,6 +53,7 @@ import org.apache.calcite.sql.type.SqlTypeName; import org.apache.calcite.util.ImmutableBitSet; import org.apache.hadoop.hive.metastore.api.FieldSchema; +import org.apache.hadoop.hive.ql.exec.Description; import org.apache.hadoop.hive.ql.metadata.VirtualColumn; import org.apache.hadoop.hive.ql.optimizer.calcite.CalciteSemanticException; import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveGroupingID; @@ -62,6 +63,8 @@ import org.apache.hadoop.hive.ql.parse.ASTNode; import org.apache.hadoop.hive.ql.parse.HiveParser; import org.apache.hadoop.hive.ql.parse.ParseDriver; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDFNvl; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNot; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -581,6 +584,31 @@ public ASTNode visitCall(RexCall call) { astNodeLst.add(astBldr.node()); } + // Rewrite CASE into NVL if possible + if (op.kind == SqlKind.CASE && call.getOperands().size() == 3) { + if (call.getOperands().get(1).isAlwaysTrue() && + call.getOperands().get(2).isAlwaysFalse()) { + ASTNode node = (ASTNode) ParseDriver.adaptor.create(HiveParser.TOK_FUNCTION, "TOK_FUNCTION"); + ParseDriver.adaptor.addChild(node, ParseDriver.adaptor.create(HiveParser.Identifier, + GenericUDFNvl.class.getAnnotation(Description.class).name())); + ParseDriver.adaptor.addChild(node, call.getOperands().get(0).accept(this)); + ParseDriver.adaptor.addChild(node, call.getOperands().get(2).accept(this)); + return node; + } else if (call.getOperands().get(1).isAlwaysFalse() && + call.getOperands().get(2).isAlwaysTrue()) { + ASTNode node = (ASTNode) ParseDriver.adaptor.create(HiveParser.TOK_FUNCTION, "TOK_FUNCTION"); + ParseDriver.adaptor.addChild(node, ParseDriver.adaptor.create(HiveParser.Identifier, + GenericUDFOPNot.class.getAnnotation(Description.class).name())); + ASTNode nodeChild = (ASTNode) ParseDriver.adaptor.create(HiveParser.TOK_FUNCTION, "TOK_FUNCTION"); + ParseDriver.adaptor.addChild(nodeChild, ParseDriver.adaptor.create(HiveParser.Identifier, + GenericUDFNvl.class.getAnnotation(Description.class).name())); + ParseDriver.adaptor.addChild(nodeChild, call.getOperands().get(0).accept(this)); + ParseDriver.adaptor.addChild(nodeChild, call.getOperands().get(1).accept(this)); + ParseDriver.adaptor.addChild(node, nodeChild); + return node; + } + } + for (RexNode operand : call.operands) { astNodeLst.add(operand.accept(this)); }