From 6b179e997b4616f289ff832e89a5e98c57184422 Mon Sep 17 00:00:00 2001 From: Pranav Bhole Date: Wed, 4 Oct 2023 17:49:08 -0700 Subject: [PATCH] adding AliasExprMacro --- .../druid/math/expr/BuiltInExprMacros.java | 64 +++++++++++++++---- .../druid/math/expr/ExprMacroTable.java | 27 ++++---- .../apache/druid/math/expr/NamedFunction.java | 9 --- ...ComplexDecodeBase64OperatorConversion.java | 6 +- .../DecodeBase64UTFOperatorConversion.java | 2 +- .../calcite/planner/DruidOperatorTable.java | 2 +- 6 files changed, 70 insertions(+), 40 deletions(-) diff --git a/processing/src/main/java/org/apache/druid/math/expr/BuiltInExprMacros.java b/processing/src/main/java/org/apache/druid/math/expr/BuiltInExprMacros.java index 1a61408aab571..2dbecda34fde4 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/BuiltInExprMacros.java +++ b/processing/src/main/java/org/apache/druid/math/expr/BuiltInExprMacros.java @@ -25,26 +25,32 @@ import javax.annotation.Nullable; import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; public class BuiltInExprMacros { + public static final String COMPLEX_DECODE_BASE64_NAME = "complex_decode_base64"; + public static final String COMPLEX_DECODE_BASE64_ALIAS_NAME = "decode_base64_complex"; + public static final String STRING_DECODE_BASE64_NAME = "decode_base64_utf8"; + public static class ComplexDecodeBase64ExprMacro implements ExprMacroTable.ExprMacro { - public static final String NAME = "complex_decode_base64"; - public static final String ALIAS_NAME = "decode_base64_complex"; + private final String NAME; - @Override - public String name() + public ComplexDecodeBase64ExprMacro(final String name) { - return NAME; + this.NAME = name; } + /** + * use name() in closure scope to allow Alias macro to override it with alias. + * + * @return String + */ @Override - public Optional alias() + public String name() { - return Optional.of(ALIAS_NAME); + return NAME; } @Override @@ -60,7 +66,7 @@ final class ComplexDecodeBase64Expression extends ExprMacroTable.BaseScalarMacro public ComplexDecodeBase64Expression(List args) { - super(NAME, args); + super(name(), args); validationHelperCheckArgumentCount(args, 2); final Expr arg0 = args.get(0); @@ -156,8 +162,12 @@ public Object getLiteralValue() public static class StringDecodeBase64UTFExprMacro implements ExprMacroTable.ExprMacro { + private final String NAME; - public static final String NAME = "decode_base64_utf8"; + public StringDecodeBase64UTFExprMacro(final String name) + { + this.NAME = name; + } @Override public Expr apply(List args) @@ -166,6 +176,11 @@ public Expr apply(List args) return new StringDecodeBase64UTFExpression(args.get(0)); } + /** + * use name() in closure scope to allow Alias macro to override it with alias. + * + * @return String + */ @Override public String name() { @@ -176,7 +191,7 @@ final class StringDecodeBase64UTFExpression extends ExprMacroTable.BaseScalarUni { public StringDecodeBase64UTFExpression(Expr arg) { - super(NAME, arg); + super(name(), arg); } @Override @@ -222,4 +237,31 @@ public Object getLiteralValue() } } } + + /*** + * Alias Expression macro create an alias and deligates operations to same base macro + */ + public static class AliasExprMacro implements ExprMacroTable.ExprMacro + { + private final ExprMacroTable.ExprMacro exprMacro; + private final String alias; + + public AliasExprMacro(final ExprMacroTable.ExprMacro baseExprMacro, final String alias) + { + this.exprMacro = baseExprMacro; + this.alias = alias; + } + + @Override + public Expr apply(List args) + { + return exprMacro.apply(args); + } + + @Override + public String name() + { + return alias; + } + } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/ExprMacroTable.java b/processing/src/main/java/org/apache/druid/math/expr/ExprMacroTable.java index e75213045789e..1b80c1b6cd423 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/ExprMacroTable.java +++ b/processing/src/main/java/org/apache/druid/math/expr/ExprMacroTable.java @@ -33,6 +33,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; /** * Mechanism by which Druid expressions can define new functions for the Druid expression language. When @@ -42,9 +43,15 @@ */ public class ExprMacroTable { + private static final BuiltInExprMacros.ComplexDecodeBase64ExprMacro COMPLEX_DECODE_BASE_64_EXPR_MACRO = new BuiltInExprMacros.ComplexDecodeBase64ExprMacro( + BuiltInExprMacros.COMPLEX_DECODE_BASE64_NAME); private static final List BUILT_IN = ImmutableList.of( - new BuiltInExprMacros.ComplexDecodeBase64ExprMacro(), - new BuiltInExprMacros.StringDecodeBase64UTFExprMacro() + COMPLEX_DECODE_BASE_64_EXPR_MACRO, + new BuiltInExprMacros.AliasExprMacro( + COMPLEX_DECODE_BASE_64_EXPR_MACRO, + BuiltInExprMacros.COMPLEX_DECODE_BASE64_ALIAS_NAME + ), + new BuiltInExprMacros.StringDecodeBase64UTFExprMacro(BuiltInExprMacros.STRING_DECODE_BASE64_NAME) ); private static final ExprMacroTable NIL = new ExprMacroTable(Collections.emptyList()); @@ -52,19 +59,9 @@ public class ExprMacroTable public ExprMacroTable(final List macros) { - this.macroMap = Maps.newHashMapWithExpectedSize(BUILT_IN.size() + 1 + macros.size()); - BUILT_IN.forEach(m -> { - macroMap.put(StringUtils.toLowerCase(m.name()), m); - if (m.alias().isPresent()) { - macroMap.put(StringUtils.toLowerCase(m.alias().get()), m); - } - }); - for (ExprMacro macro : macros) { - macroMap.put(StringUtils.toLowerCase(macro.name()), macro); - if (macro.alias().isPresent()) { - macroMap.put(StringUtils.toLowerCase(macro.alias().get()), macro); - } - } + this.macroMap = Maps.newHashMapWithExpectedSize(BUILT_IN.size() + macros.size()); + macroMap.putAll(BUILT_IN.stream().collect(Collectors.toMap(m -> StringUtils.toLowerCase(m.name()), m -> m))); + macroMap.putAll(macros.stream().collect(Collectors.toMap(m -> StringUtils.toLowerCase(m.name()), m -> m))); } public static ExprMacroTable nil() diff --git a/processing/src/main/java/org/apache/druid/math/expr/NamedFunction.java b/processing/src/main/java/org/apache/druid/math/expr/NamedFunction.java index 839a166db9fbf..574535ac68480 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/NamedFunction.java +++ b/processing/src/main/java/org/apache/druid/math/expr/NamedFunction.java @@ -23,7 +23,6 @@ import java.util.Arrays; import java.util.List; -import java.util.Optional; /** * Common stuff for "named" functions of "functional" expressions, such as {@link FunctionExpr}, @@ -39,14 +38,6 @@ public interface NamedFunction */ String name(); - /** - * Alias of the function - */ - default Optional alias() - { - return Optional.empty(); - } - /** * Helper method for creating a {@link ExpressionValidationException} with the specified reason */ diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ComplexDecodeBase64OperatorConversion.java b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ComplexDecodeBase64OperatorConversion.java index 94b90ed9af8d8..635415da27642 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ComplexDecodeBase64OperatorConversion.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ComplexDecodeBase64OperatorConversion.java @@ -51,10 +51,10 @@ public class ComplexDecodeBase64OperatorConversion implements SqlOperatorConvers }; private static final SqlFunction SQL_FUNCTION = OperatorConversions - .operatorBuilder(StringUtils.toUpperCase(BuiltInExprMacros.ComplexDecodeBase64ExprMacro.NAME)) + .operatorBuilder(StringUtils.toUpperCase(BuiltInExprMacros.COMPLEX_DECODE_BASE64_NAME)) .operandTypeChecker( OperandTypes.sequence( - "'" + StringUtils.toUpperCase(BuiltInExprMacros.ComplexDecodeBase64ExprMacro.NAME) + "(typeName, base64)'", + "'" + StringUtils.toUpperCase(BuiltInExprMacros.COMPLEX_DECODE_BASE64_NAME) + "(typeName, base64)'", OperandTypes.and(OperandTypes.family(SqlTypeFamily.STRING), OperandTypes.LITERAL), OperandTypes.ANY ) @@ -86,7 +86,7 @@ public DruidExpression toDruidExpression( String arg0 = druidExpressions.get(0).getExpression(); return DruidExpression.ofExpression( ColumnType.ofComplex(arg0.substring(1, arg0.length() - 1)), - DruidExpression.functionCall(BuiltInExprMacros.ComplexDecodeBase64ExprMacro.NAME), + DruidExpression.functionCall(BuiltInExprMacros.COMPLEX_DECODE_BASE64_NAME), druidExpressions ); } diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/DecodeBase64UTFOperatorConversion.java b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/DecodeBase64UTFOperatorConversion.java index f0a0bf40a8cfe..210d5d44a3000 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/DecodeBase64UTFOperatorConversion.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/DecodeBase64UTFOperatorConversion.java @@ -33,7 +33,7 @@ public class DecodeBase64UTFOperatorConversion extends DirectOperatorConversion { private static final SqlFunction SQL_FUNCTION = OperatorConversions - .operatorBuilder(StringUtils.toUpperCase(BuiltInExprMacros.StringDecodeBase64UTFExprMacro.NAME)) + .operatorBuilder(StringUtils.toUpperCase(BuiltInExprMacros.STRING_DECODE_BASE64_NAME)) .operandTypes(SqlTypeFamily.CHARACTER) .returnTypeNullable(SqlTypeName.VARCHAR) .functionCategory(SqlFunctionCategory.STRING) diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidOperatorTable.java b/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidOperatorTable.java index e09e404465482..85c58365171af 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidOperatorTable.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidOperatorTable.java @@ -236,7 +236,7 @@ public class DruidOperatorTable implements SqlOperatorTable .add(COMPLEX_DECODE_OPERATOR_CONVERSIONS) .add(new AliasedOperatorConversion( COMPLEX_DECODE_OPERATOR_CONVERSIONS, - BuiltInExprMacros.ComplexDecodeBase64ExprMacro.ALIAS_NAME + BuiltInExprMacros.COMPLEX_DECODE_BASE64_ALIAS_NAME )) .add(new DecodeBase64UTFOperatorConversion()) .build();