This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 78c2799ba07 [fix](Nereids) alias function should use unbound slot as
place holder (#43597)
78c2799ba07 is described below
commit 78c2799ba07c6dddcd586fa8f8e7eddbb2570c1d
Author: morrySnow <[email protected]>
AuthorDate: Tue Nov 12 16:36:05 2024 +0800
[fix](Nereids) alias function should use unbound slot as place holder
(#43597)
Related PR: #18257
Problem Summary:
when construct alias function for Nereids, should use unbound slot as
placeholder.
Currently, we use SlotReference, then we could replace it by wrong
parameter,
because SlotReference use ExprId as Unique Identifier.
For example, if placeholder's ExprId is 1, then all slots that ExprId
equals one
will be replaced by input parameter.
### Release note
Fix the issus that wrong result when using alias function.
---
.../trees/expressions/functions/udf/AliasUdf.java | 30 +---------------------
.../expressions/functions/udf/AliasUdfBuilder.java | 14 +++++-----
.../nereids_p0/javaudf/test_alias_function.groovy | 16 ++++++------
3 files changed, 16 insertions(+), 44 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdf.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdf.java
index 7b97335e77c..c8b7a3c721a 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdf.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdf.java
@@ -21,23 +21,18 @@ import org.apache.doris.catalog.AliasFunction;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.analyzer.UnboundFunction;
-import org.apache.doris.nereids.analyzer.UnboundSlot;
import org.apache.doris.nereids.parser.NereidsParser;
import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.SlotReference;
import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.ScalarFunction;
-import
org.apache.doris.nereids.trees.expressions.visitor.DefaultExpressionRewriter;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.types.NullType;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
import java.util.Arrays;
import java.util.List;
-import java.util.Map;
import java.util.stream.Collectors;
/**
@@ -88,20 +83,10 @@ public class AliasUdf extends ScalarFunction implements
ExplicitlyCastableSignat
String functionSql = function.getOriginFunction().toSql();
Expression parsedFunction = new
NereidsParser().parseExpression(functionSql);
- Map<String, SlotReference> replaceMap = Maps.newHashMap();
- for (int i = 0; i < function.getNumArgs(); ++i) {
- replaceMap.put(function.getParameters().get(i),
- new SlotReference(
- function.getParameters().get(i),
- DataType.fromCatalogType(function.getArgs()[i])));
- }
-
- Expression slotBoundFunction =
VirtualSlotReplacer.INSTANCE.replace(parsedFunction, replaceMap);
-
AliasUdf aliasUdf = new AliasUdf(
function.functionName(),
Arrays.stream(function.getArgs()).map(DataType::fromCatalogType).collect(Collectors.toList()),
- ((UnboundFunction) slotBoundFunction),
+ ((UnboundFunction) parsedFunction),
function.getParameters());
AliasUdfBuilder builder = new AliasUdfBuilder(aliasUdf);
@@ -123,17 +108,4 @@ public class AliasUdf extends ScalarFunction implements
ExplicitlyCastableSignat
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitAliasUdf(this, context);
}
-
- private static class VirtualSlotReplacer extends
DefaultExpressionRewriter<Map<String, SlotReference>> {
- public static final VirtualSlotReplacer INSTANCE = new
VirtualSlotReplacer();
-
- public Expression replace(Expression expression, Map<String,
SlotReference> context) {
- return expression.accept(this, context);
- }
-
- @Override
- public Expression visitUnboundSlot(UnboundSlot slot, Map<String,
SlotReference> context) {
- return context.get(slot.getName());
- }
- }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdfBuilder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdfBuilder.java
index 2bb832524e9..58c5abcdd26 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdfBuilder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/udf/AliasUdfBuilder.java
@@ -21,10 +21,10 @@ import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.common.Pair;
import org.apache.doris.common.util.ReflectionUtils;
import org.apache.doris.nereids.analyzer.Scope;
+import org.apache.doris.nereids.analyzer.UnboundSlot;
import org.apache.doris.nereids.rules.analysis.ExpressionAnalyzer;
import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext;
import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.util.TypeCoercionUtils;
@@ -90,14 +90,14 @@ public class AliasUdfBuilder extends UdfBuilder {
// replace the placeholder slot to the input expressions.
// adjust input, parameter and replaceMap to be corresponding.
- Map<String, SlotReference> slots = Maps.newLinkedHashMap();
+ Map<String, UnboundSlot> slots = Maps.newLinkedHashMap();
aliasUdf.getUnboundFunction().foreachUp(child -> {
- if (child instanceof SlotReference) {
- slots.put(((SlotReference) child).getName(), (SlotReference)
child);
+ if (child instanceof UnboundSlot) {
+ slots.put(((UnboundSlot) child).getName(), (UnboundSlot)
child);
}
});
- Map<SlotReference, Expression> paramSlotToRealInput =
Maps.newHashMap();
+ Map<UnboundSlot, Expression> paramSlotToRealInput = Maps.newHashMap();
for (int i = 0; i < inputs.size(); ++i) {
String parameter = aliasUdf.getParameters().get(i);
Preconditions.checkArgument(slots.containsKey(parameter));
@@ -107,8 +107,8 @@ public class AliasUdfBuilder extends UdfBuilder {
ExpressionAnalyzer udfAnalyzer = new ExpressionAnalyzer(
null, new Scope(ImmutableList.of()), null, false, false) {
@Override
- public Expression visitSlotReference(SlotReference slotReference,
ExpressionRewriteContext context) {
- return paramSlotToRealInput.get(slotReference);
+ public Expression visitUnboundSlot(UnboundSlot unboundSlot,
ExpressionRewriteContext context) {
+ return paramSlotToRealInput.get(unboundSlot);
}
};
diff --git
a/regression-test/suites/nereids_p0/javaudf/test_alias_function.groovy
b/regression-test/suites/nereids_p0/javaudf/test_alias_function.groovy
index 579724a0139..c7c138e9934 100644
--- a/regression-test/suites/nereids_p0/javaudf/test_alias_function.groovy
+++ b/regression-test/suites/nereids_p0/javaudf/test_alias_function.groovy
@@ -33,7 +33,7 @@ suite("nereids_test_alias_function") {
CREATE ALIAS FUNCTION f2(DATETIMEV2(3), INT) with PARAMETER (datetime1,
int1) as
DATE_FORMAT(HOURS_ADD(
date_trunc(datetime1, 'day'),
- add(multiply(floor(divide(HOUR(datetime1), divide(24, int1))), 1),
1)), '%Y%m%d:%H')
+ add(multiply(floor(divide(day(datetime1), divide(24, int1))), 1),
1)), '%Y%m%d:%H')
'''
sql '''
CREATE ALIAS FUNCTION f3(INT) with PARAMETER (int1) as
@@ -50,11 +50,11 @@ suite("nereids_test_alias_function") {
}
test {
sql 'select f2(f1(\'2023-05-20\', 2), 3)'
- result([['20230518:01']])
+ result([['20230518:03']])
}
test {
sql 'select f3(4)'
- result([['20230518:01']])
+ result([['20230518:04']])
}
test {
sql 'select cast(f1(\'2023-06-01\', k1) as string) from test order by
k1'
@@ -67,17 +67,17 @@ suite("nereids_test_alias_function") {
test {
sql 'select f2(f1(\'2023-05-20\', k1), 4) from test order by k1'
result([
- ['20230519:01'],
- ['20230518:01'],
- ['20230517:01']
+ ['20230519:04'],
+ ['20230518:04'],
+ ['20230517:03']
])
}
test {
sql 'select f3(k1) from test order by k1'
result([
['20230518:01'],
- ['20230518:01'],
- ['20230518:01']
+ ['20230518:02'],
+ ['20230518:03']
])
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]