Skip to content

Commit 3b9bf2a

Browse files
committed
[feature](Nereids): Convert log(x) to ln(x) (apache#52862)
Problem Summary: * In MySQL, LOG(col, e) is equivalent to LN(col), where e is Euler’s number (~2.71828). * Currently, MySQL also supports LOG(col) as a shorthand for LOG(col, e) (i.e., natural logarithm). * This conversion replaces LOG(col) with LN(col) when only a single argument is provided. doc: apache/doris-website#2605
1 parent d499904 commit 3b9bf2a

File tree

5 files changed

+98
-4
lines changed

5 files changed

+98
-4
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.doris.nereids.rules.expression.rules.DistinctPredicatesRule;
2525
import org.apache.doris.nereids.rules.expression.rules.ExtractCommonFactorRule;
2626
import org.apache.doris.nereids.rules.expression.rules.LikeToEqualRewrite;
27+
import org.apache.doris.nereids.rules.expression.rules.LogToLn;
2728
import org.apache.doris.nereids.rules.expression.rules.NullSafeEqualToEqual;
2829
import org.apache.doris.nereids.rules.expression.rules.OrToIn;
2930
import org.apache.doris.nereids.rules.expression.rules.SimplifyComparisonPredicate;
@@ -55,7 +56,8 @@ public class ExpressionOptimization extends ExpressionRewrite {
5556
TopnToMax.INSTANCE,
5657
NullSafeEqualToEqual.INSTANCE,
5758
LikeToEqualRewrite.INSTANCE,
58-
BetweenToEqual.INSTANCE
59+
BetweenToEqual.INSTANCE,
60+
LogToLn.INSTANCE
5961
)
6062
);
6163
private static final ExpressionRuleExecutor EXECUTOR = new ExpressionRuleExecutor(OPTIMIZE_REWRITE_RULES);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.doris.nereids.rules.expression.rules;
19+
20+
import org.apache.doris.nereids.rules.expression.ExpressionPatternMatcher;
21+
import org.apache.doris.nereids.rules.expression.ExpressionPatternRuleFactory;
22+
import org.apache.doris.nereids.rules.expression.ExpressionRuleType;
23+
import org.apache.doris.nereids.trees.expressions.Expression;
24+
import org.apache.doris.nereids.trees.expressions.functions.scalar.Ln;
25+
import org.apache.doris.nereids.trees.expressions.functions.scalar.Log;
26+
27+
import com.google.common.collect.ImmutableList;
28+
29+
import java.util.List;
30+
31+
/**
32+
* In MySQL, LOG(col, e) is equivalent to LN(col), where e is Euler’s number (~2.71828).
33+
* Currently, MySQL also supports LOG(col) as a shorthand for LOG(col, e) (i.e., natural logarithm).
34+
* This conversion replaces LOG(col) with LN(col) when only a single argument is provided.
35+
*/
36+
public class LogToLn implements ExpressionPatternRuleFactory {
37+
38+
public static final LogToLn INSTANCE = new LogToLn();
39+
40+
@Override
41+
public List<ExpressionPatternMatcher<? extends Expression>> buildRules() {
42+
return ImmutableList.of(
43+
matchesType(Log.class).then(LogToLn::rewrite)
44+
.toRule(ExpressionRuleType.LOG_TO_LN)
45+
);
46+
}
47+
48+
/** rewrite */
49+
public static Expression rewrite(Log log) {
50+
if (log.arity() == 1) {
51+
return new Ln(log.child(0));
52+
} else {
53+
return log;
54+
}
55+
}
56+
}

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Log.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,17 @@ public class Log extends ScalarFunction
3737
implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNullable {
3838

3939
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
40+
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE),
4041
FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, DoubleType.INSTANCE)
4142
);
4243

44+
/**
45+
* constructor with 1 arguments.
46+
*/
47+
public Log(Expression arg0) {
48+
super("log", arg0);
49+
}
50+
4351
/**
4452
* constructor with 2 arguments.
4553
*/
@@ -52,8 +60,13 @@ public Log(Expression arg0, Expression arg1) {
5260
*/
5361
@Override
5462
public Log withChildren(List<Expression> children) {
55-
Preconditions.checkArgument(children.size() == 2);
56-
return new Log(children.get(0), children.get(1));
63+
Preconditions.checkArgument(children.size() == 1 || children.size() == 2,
64+
"Log function should have 1 or 2 children, but got: %s", children.size());
65+
if (children.size() == 1) {
66+
return new Log(children.get(0));
67+
} else {
68+
return new Log(children.get(0), children.get(1));
69+
}
5770
}
5871

5972
@Override

regression-test/data/query_p0/sql_functions/math_functions/test_math_unary_always_nullable.out

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,17 @@
9393
7 \N true
9494
8 \N true
9595

96+
-- !dlog_tbl_1 --
97+
1 0.09531017980432493 0.09531017980432493 1.0986122886681098 1.0986122886681098
98+
2 \N \N 1.0986122886681098 1.0986122886681098
99+
3 \N \N 1.0986122886681098 1.0986122886681098
100+
4 \N \N 1.0986122886681098 1.0986122886681098
101+
5 \N \N 1.0986122886681098 1.0986122886681098
102+
6 \N \N 1.0986122886681098 1.0986122886681098
103+
7 \N \N 1.0986122886681098 1.0986122886681098
104+
8 \N \N 1.0986122886681098 1.0986122886681098
105+
9 0.1823215567939546 0.1823215567939546 1.0986122886681098 1.0986122886681098
106+
10 0.7884573603642703 0.7884573603642703 1.0986122886681098 1.0986122886681098
107+
11 1.2237754316221157 1.2237754316221157 1.0986122886681098 1.0986122886681098
108+
12 1.7227665977411035 1.7227665977411035 1.0986122886681098 1.0986122886681098
109+

regression-test/suites/query_p0/sql_functions/math_functions/test_math_unary_always_nullable.groovy

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,13 @@ suite("test_math_unary_alway_nullable") {
8282
select rowid, dsqrt(val), dsqrt(val) is null from test_math_unary_alway_nullable order by rowid;
8383
"""
8484

85-
}
85+
sql """
86+
insert into test_math_unary_alway_nullable values
87+
(9, 1.2), (10, 2.2), (11, 3.4), (12, 5.6)
88+
"""
89+
90+
qt_dlog_tbl_1 """
91+
select rowid, log(val), ln(val), log(3), ln(3) from test_math_unary_alway_nullable order by rowid;
92+
"""
93+
94+
}

0 commit comments

Comments
 (0)