diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java index 489af4b331cb3d..2468606406557e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionOptimization.java @@ -25,6 +25,7 @@ import org.apache.doris.nereids.rules.expression.rules.DistinctPredicatesRule; import org.apache.doris.nereids.rules.expression.rules.ExtractCommonFactorRule; import org.apache.doris.nereids.rules.expression.rules.LikeToEqualRewrite; +import org.apache.doris.nereids.rules.expression.rules.LogToLn; import org.apache.doris.nereids.rules.expression.rules.NullSafeEqualToEqual; import org.apache.doris.nereids.rules.expression.rules.SimplifyComparisonPredicate; import org.apache.doris.nereids.rules.expression.rules.SimplifyConflictCompound; @@ -61,7 +62,8 @@ public class ExpressionOptimization extends ExpressionRewrite { TopnToMax.INSTANCE, NullSafeEqualToEqual.INSTANCE, LikeToEqualRewrite.INSTANCE, - BetweenToEqual.INSTANCE + BetweenToEqual.INSTANCE, + LogToLn.INSTANCE ) ); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java index baa5ebfe078da4..67f515dcce9f93 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/ExpressionRuleType.java @@ -34,6 +34,7 @@ public enum ExpressionRuleType { EXTRACT_COMMON_FACTOR, FOLD_CONSTANT_ON_BE, FOLD_CONSTANT_ON_FE, + LOG_TO_LN, IN_PREDICATE_DEDUP, IN_PREDICATE_EXTRACT_NON_CONSTANT, IN_PREDICATE_TO_EQUAL_TO, diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/LogToLn.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/LogToLn.java new file mode 100644 index 00000000000000..577e16c88df2d1 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/LogToLn.java @@ -0,0 +1,56 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.rules.expression.rules; + +import org.apache.doris.nereids.rules.expression.ExpressionPatternMatcher; +import org.apache.doris.nereids.rules.expression.ExpressionPatternRuleFactory; +import org.apache.doris.nereids.rules.expression.ExpressionRuleType; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Ln; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Log; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** + * 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. + */ +public class LogToLn implements ExpressionPatternRuleFactory { + + public static final LogToLn INSTANCE = new LogToLn(); + + @Override + public List> buildRules() { + return ImmutableList.of( + matchesType(Log.class).then(LogToLn::rewrite) + .toRule(ExpressionRuleType.LOG_TO_LN) + ); + } + + /** rewrite */ + public static Expression rewrite(Log log) { + if (log.arity() == 1) { + return new Ln(log.child(0)); + } else { + return log; + } + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Log.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Log.java index d8f23e21e05ed9..559bc7a0dbb7c6 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Log.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Log.java @@ -37,9 +37,17 @@ public class Log extends ScalarFunction implements BinaryExpression, ExplicitlyCastableSignature, AlwaysNullable { public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE), FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE, DoubleType.INSTANCE) ); + /** + * constructor with 1 arguments. + */ + public Log(Expression arg0) { + super("log", arg0); + } + /** * constructor with 2 arguments. */ @@ -52,8 +60,13 @@ public Log(Expression arg0, Expression arg1) { */ @Override public Log withChildren(List children) { - Preconditions.checkArgument(children.size() == 2); - return new Log(children.get(0), children.get(1)); + Preconditions.checkArgument(children.size() == 1 || children.size() == 2, + "Log function should have 1 or 2 children, but got: %s", children.size()); + if (children.size() == 1) { + return new Log(children.get(0)); + } else { + return new Log(children.get(0), children.get(1)); + } } @Override diff --git a/regression-test/data/query_p0/sql_functions/math_functions/test_math_unary_always_nullable.out b/regression-test/data/query_p0/sql_functions/math_functions/test_math_unary_always_nullable.out index ae2203c03d8fb0..bb6cff5ec9303d 100644 --- a/regression-test/data/query_p0/sql_functions/math_functions/test_math_unary_always_nullable.out +++ b/regression-test/data/query_p0/sql_functions/math_functions/test_math_unary_always_nullable.out @@ -149,3 +149,17 @@ 7 \N true 8 \N true +-- !dlog_tbl_1 -- +1 0.09531017980432493 0.09531017980432493 1.0986122886681098 1.0986122886681098 +2 \N \N 1.0986122886681098 1.0986122886681098 +3 \N \N 1.0986122886681098 1.0986122886681098 +4 \N \N 1.0986122886681098 1.0986122886681098 +5 \N \N 1.0986122886681098 1.0986122886681098 +6 \N \N 1.0986122886681098 1.0986122886681098 +7 \N \N 1.0986122886681098 1.0986122886681098 +8 \N \N 1.0986122886681098 1.0986122886681098 +9 0.1823215567939546 0.1823215567939546 1.0986122886681098 1.0986122886681098 +10 0.7884573603642703 0.7884573603642703 1.0986122886681098 1.0986122886681098 +11 1.2237754316221157 1.2237754316221157 1.0986122886681098 1.0986122886681098 +12 1.7227665977411035 1.7227665977411035 1.0986122886681098 1.0986122886681098 + diff --git a/regression-test/suites/query_p0/sql_functions/math_functions/test_math_unary_always_nullable.groovy b/regression-test/suites/query_p0/sql_functions/math_functions/test_math_unary_always_nullable.groovy index 64b9ddc01ef795..a4ebd6647faf3e 100644 --- a/regression-test/suites/query_p0/sql_functions/math_functions/test_math_unary_always_nullable.groovy +++ b/regression-test/suites/query_p0/sql_functions/math_functions/test_math_unary_always_nullable.groovy @@ -110,4 +110,13 @@ suite("test_math_unary_alway_nullable") { select rowid, dsqrt(val), dsqrt(val) is null from test_math_unary_alway_nullable order by rowid; """ + sql """ + insert into test_math_unary_alway_nullable values + (9, 1.2), (10, 2.2), (11, 3.4), (12, 5.6) + """ + + qt_dlog_tbl_1 """ + select rowid, log(val), ln(val), log(3), ln(3) from test_math_unary_alway_nullable order by rowid; + """ + }