From a3b33db888808495d631a623a1c71c25fba3954d Mon Sep 17 00:00:00 2001 From: Volodymyr Vysotskyi Date: Thu, 1 Nov 2018 18:31:16 +0200 Subject: [PATCH] DRILL-4456: Add Hive translate UDF closes #1527 --- .../exec/expr/fn/HiveFunctionRegistry.java | 45 ++++++++++++------- .../exec/fn/hive/TestInbuiltHiveUDFs.java | 13 ++++++ 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/contrib/storage-hive/core/src/main/java/org/apache/drill/exec/expr/fn/HiveFunctionRegistry.java b/contrib/storage-hive/core/src/main/java/org/apache/drill/exec/expr/fn/HiveFunctionRegistry.java index cb00ede9bf0..0ec97785372 100644 --- a/contrib/storage-hive/core/src/main/java/org/apache/drill/exec/expr/fn/HiveFunctionRegistry.java +++ b/contrib/storage-hive/core/src/main/java/org/apache/drill/exec/expr/fn/HiveFunctionRegistry.java @@ -20,9 +20,12 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Stream; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.sql.SqlOperatorBinding; +import org.apache.calcite.sql.fun.OracleSqlOperatorTable; +import org.apache.calcite.sql.fun.SqlStdOperatorTable; import org.apache.calcite.sql.type.SqlReturnTypeInference; import org.apache.calcite.sql.type.SqlTypeName; import org.apache.drill.common.config.DrillConfig; @@ -38,6 +41,7 @@ import org.apache.drill.exec.planner.sql.HiveUDFOperator; import org.apache.drill.exec.planner.sql.HiveUDFOperatorWithoutInference; import org.apache.drill.exec.planner.sql.TypeInferenceUtils; +import org.apache.drill.shaded.guava.com.google.common.collect.ImmutableMap; import org.apache.hadoop.hive.ql.exec.Description; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.hive.ql.udf.UDFType; @@ -48,8 +52,18 @@ import org.apache.drill.shaded.guava.com.google.common.collect.ArrayListMultimap; import org.apache.drill.shaded.guava.com.google.common.collect.Sets; -public class HiveFunctionRegistry implements PluggableFunctionRegistry{ - static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(HiveFunctionRegistry.class); +public class HiveFunctionRegistry implements PluggableFunctionRegistry { + private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(HiveFunctionRegistry.class); + + /** + * Map for renaming UDFs. Keys of the map represent UDF names which should be replaced + * and its values represent target UDF names. + */ + private static final Map FUNCTION_REPLACE_MAP = ImmutableMap. builder() + // renames Hive's TRANSLATE UDF to TRANSLATE3 due to CALCITE-1115 + .put(SqlStdOperatorTable.TRANSLATE.getName().toLowerCase(), + OracleSqlOperatorTable.TRANSLATE3.getName().toLowerCase()) + .build(); private ArrayListMultimap> methodsGenericUDF = ArrayListMultimap.create(); private ArrayListMultimap> methodsUDF = ArrayListMultimap.create(); @@ -102,27 +116,28 @@ public void register(DrillOperatorTable operatorTable) { } } - private void register(Class clazz, ArrayListMultimap> methods) { + private void register(Class clazz, ArrayListMultimap> methods) { Description desc = clazz.getAnnotation(Description.class); - String[] names; + Stream namesStream; if (desc != null) { - names = desc.name().split(","); - for (int i=0; i name.replace('.', '_')); } + // Checks specified array of function names whether they should be replaced + // using FUNCTION_REPLACE_MAP map. + namesStream.map(String::toLowerCase) + .map(functionName -> FUNCTION_REPLACE_MAP.getOrDefault(functionName, functionName)) + .forEach(name -> methods.put(name, clazz)); + UDFType type = clazz.getAnnotation(UDFType.class); if (type != null && !type.deterministic()) { nonDeterministicUDFs.add(clazz); } - - - for(int i=0; i