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 b53c42636e [Fix](Nereids) fold constant result is wrong on functions 
relative to timezone (#19863)
b53c42636e is described below

commit b53c42636ecb1522c64066ddd293e986df0f395e
Author: mch_ucchi <41606806+sohardforan...@users.noreply.github.com>
AuthorDate: Wed May 31 15:52:40 2023 +0800

    [Fix](Nereids) fold constant result is wrong on functions relative to 
timezone (#19863)
---
 .../expression/rules/FoldConstantRuleOnFE.java     |  4 --
 .../nereids/trees/expressions/Expression.java      |  5 +++
 .../trees/expressions/ExpressionEvaluator.java     |  2 +-
 .../doris/nereids/trees/expressions/Foldable.java  | 24 +++++++++++
 .../functions/executable/DateTimeAcquire.java      | 39 ++++++++++++------
 .../executable/DateTimeExtractAndTransform.java    | 25 ++----------
 .../expressions/functions/scalar/CurrentDate.java  |  3 +-
 .../expressions/functions/scalar/CurrentTime.java  |  3 +-
 .../org/apache/doris/nereids/util/DateUtils.java   |  9 +++++
 .../nereids_p0/datatype/test_date_acquire.groovy   | 46 ++++++++++++++++++++++
 10 files changed, 121 insertions(+), 39 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
index 2451b72be5..7c60c8df79 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnFE.java
@@ -328,10 +328,6 @@ public class FoldConstantRuleOnFE extends 
AbstractExpressionRewriteRule {
     @Override
     public Expression visitBoundFunction(BoundFunction boundFunction, 
ExpressionRewriteContext context) {
         boundFunction = rewriteChildren(boundFunction, context);
-        //functions, like current_date, do not have arg
-        if (boundFunction.getArguments().isEmpty()) {
-            return boundFunction;
-        }
         Optional<Expression> checkedExpr = preProcess(boundFunction);
         if (checkedExpr.isPresent()) {
             return checkedExpr.get();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
index 0d2772d768..e58795e112 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
@@ -20,6 +20,7 @@ package org.apache.doris.nereids.trees.expressions;
 import org.apache.doris.nereids.analyzer.Unbound;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.trees.AbstractTreeNode;
+import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
 import org.apache.doris.nereids.trees.expressions.functions.ExpressionTrait;
 import org.apache.doris.nereids.trees.expressions.literal.Literal;
 import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
@@ -139,6 +140,10 @@ public abstract class Expression extends 
AbstractTreeNode<Expression> implements
      */
     public boolean isConstant() {
         if (this instanceof LeafExpression) {
+            if (this instanceof BoundFunction) {
+                BoundFunction function = ((BoundFunction) this);
+                return function instanceof Foldable;
+            }
             return this instanceof Literal;
         } else {
             return children().stream().allMatch(Expression::isConstant);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java
index 80eb82f3a0..b6b2441c99 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ExpressionEvaluator.java
@@ -137,11 +137,11 @@ public enum ExpressionEvaluator {
         ImmutableMultimap.Builder<String, FunctionInvoker> mapBuilder =
                 new ImmutableMultimap.Builder<String, FunctionInvoker>();
         List<Class> classes = ImmutableList.of(
+                DateTimeAcquire.class,
                 DateTimeExtractAndTransform.class,
                 ExecutableFunctions.class,
                 DateLiteral.class,
                 DateTimeArithmetic.class,
-                DateTimeAcquire.class,
                 NumericArithmetic.class
         );
         for (Class cls : classes) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Foldable.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Foldable.java
new file mode 100644
index 0000000000..fae923dd86
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Foldable.java
@@ -0,0 +1,24 @@
+// 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.trees.expressions;
+
+/**
+ * specifically for bound function can be folded to constant.
+ */
+public interface Foldable {
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeAcquire.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeAcquire.java
index 8670ea1858..e5dca783fd 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeAcquire.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeAcquire.java
@@ -23,9 +23,10 @@ import 
org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
 import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
+import org.apache.doris.nereids.util.DateUtils;
 
 import java.time.LocalDateTime;
-import java.util.TimeZone;
+import java.time.ZoneId;
 
 /**
  * executable functions:
@@ -37,12 +38,12 @@ public class DateTimeAcquire {
      */
     @ExecFunction(name = "now", argTypes = {}, returnType = "DATETIME")
     public static Expression now() {
-        return DateTimeLiteral.fromJavaDateType(LocalDateTime.now());
+        return 
DateTimeLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
     }
 
     @ExecFunction(name = "now", argTypes = {"INT"}, returnType = "DATETIMEV2")
     public static Expression now(IntegerLiteral precision) {
-        return DateTimeV2Literal.fromJavaDateType(LocalDateTime.now(),
+        return 
DateTimeV2Literal.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()),
                 precision.getValue());
     }
 
@@ -51,12 +52,12 @@ public class DateTimeAcquire {
      */
     @ExecFunction(name = "current_timestamp", argTypes = {}, returnType = 
"DATETIME")
     public static Expression currentTimestamp() {
-        return DateTimeLiteral.fromJavaDateType(LocalDateTime.now());
+        return 
DateTimeLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
     }
 
     @ExecFunction(name = "current_timestamp", argTypes = {"INT"}, returnType = 
"DATETIMEV2")
     public static Expression currentTimestamp(IntegerLiteral precision) {
-        return DateTimeV2Literal.fromJavaDateType(LocalDateTime.now(), 
precision.getValue());
+        return 
DateTimeV2Literal.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()), 
precision.getValue());
     }
 
     /**
@@ -64,12 +65,12 @@ public class DateTimeAcquire {
      */
     @ExecFunction(name = "localtime", argTypes = {}, returnType = "DATETIME")
     public static Expression localTime() {
-        return 
DateTimeLiteral.fromJavaDateType(LocalDateTime.now(TimeZone.getDefault().toZoneId()));
+        return 
DateTimeLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
     }
 
     @ExecFunction(name = "localtimestamp", argTypes = {}, returnType = 
"DATETIME")
     public static Expression localTimestamp() {
-        return 
DateTimeV2Literal.fromJavaDateType(LocalDateTime.now(TimeZone.getDefault().toZoneId()));
+        return 
DateTimeV2Literal.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
     }
 
     /**
@@ -77,12 +78,12 @@ public class DateTimeAcquire {
      */
     @ExecFunction(name = "curdate", argTypes = {}, returnType = "DATE")
     public static Expression curDate() {
-        return DateLiteral.fromJavaDateType(LocalDateTime.now());
+        return 
DateLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
     }
 
     @ExecFunction(name = "current_date", argTypes = {}, returnType = "DATE")
     public static Expression currentDate() {
-        return DateLiteral.fromJavaDateType(LocalDateTime.now());
+        return 
DateLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
     }
 
     /**
@@ -90,11 +91,27 @@ public class DateTimeAcquire {
      */
     @ExecFunction(name = "curtime", argTypes = {}, returnType = "DATETIME")
     public static Expression curTime() {
-        return DateTimeLiteral.fromJavaDateType(LocalDateTime.now());
+        return 
DateTimeLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
     }
 
     @ExecFunction(name = "current_time", argTypes = {}, returnType = 
"DATETIME")
     public static Expression currentTime() {
-        return DateTimeLiteral.fromJavaDateType(LocalDateTime.now());
+        return 
DateTimeLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
+    }
+
+    /**
+     * date transformation function: unix_timestamp
+     */
+    @ExecFunction(name = "unix_timestamp", argTypes = {}, returnType = "INT")
+    public static Expression unixTimestamp() {
+        return new IntegerLiteral((int) (System.currentTimeMillis() / 1000L));
+    }
+
+    /**
+     * date transformation function: utc_timestamp
+     */
+    @ExecFunction(name = "utc_timestamp", argTypes = {}, returnType = "INT")
+    public static Expression utcTimestamp() {
+        return 
DateTimeLiteral.fromJavaDateType(LocalDateTime.now(ZoneId.of("UTC+0")));
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
index 66dd20d6c3..b0a61832b6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
@@ -448,20 +448,12 @@ public class DateTimeExtractAndTransform {
                 .plusSeconds(second.getValue())
                 .atZone(ZoneId.of("UTC+0"))
                 .toOffsetDateTime()
-                .atZoneSameInstant(ZoneId.systemDefault());
+                .atZoneSameInstant(DateUtils.getTimeZone());
         return dateFormat(new DateTimeLiteral(dateTime.getYear(), 
dateTime.getMonthValue(),
                         dateTime.getDayOfMonth(), dateTime.getHour(), 
dateTime.getMinute(), dateTime.getSecond()),
                 format);
     }
 
-    /**
-     * date transformation function: unix_timestamp
-     */
-    @ExecFunction(name = "unix_timestamp", argTypes = {}, returnType = "INT")
-    public static Expression unixTimestamp() {
-        return new IntegerLiteral(getTimestamp(LocalDateTime.now()));
-    }
-
     /**
      * date transformation function: unix_timestamp
      */
@@ -509,18 +501,9 @@ public class DateTimeExtractAndTransform {
         }
         return ((int) Duration.between(
                 specialLowerBound,
-                dateTime
-                .atZone(ZoneId.systemDefault())
-                .toOffsetDateTime().atZoneSameInstant(ZoneId.of("UTC+0"))
-                .toLocalDateTime()).getSeconds());
-    }
-
-    /**
-     * date transformation function: utc_timestamp
-     */
-    @ExecFunction(name = "utc_timestamp", argTypes = {}, returnType = "INT")
-    public static Expression utcTimestamp() {
-        return DateTimeLiteral.fromJavaDateType(LocalDateTime.now());
+                dateTime.atZone(DateUtils.getTimeZone())
+                        
.toOffsetDateTime().atZoneSameInstant(ZoneId.of("UTC+0"))
+                        .toLocalDateTime()).getSeconds());
     }
 
     /**
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentDate.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentDate.java
index bca7ffd05c..d4bcfbee77 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentDate.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentDate.java
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.trees.expressions.functions.scalar;
 
 import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Foldable;
 import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic;
@@ -33,7 +34,7 @@ import java.util.List;
  * ScalarFunction 'current_date'. This class is generated by GenerateFunction.
  */
 public class CurrentDate extends ScalarFunction
-        implements LeafExpression, ExplicitlyCastableSignature, 
Nondeterministic, AlwaysNotNullable {
+        implements LeafExpression, ExplicitlyCastableSignature, 
Nondeterministic, AlwaysNotNullable, Foldable {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(DateType.INSTANCE).args()
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentTime.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentTime.java
index 2e09c36d85..9bf190879b 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentTime.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentTime.java
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.trees.expressions.functions.scalar;
 
 import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Foldable;
 import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
 import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic;
@@ -33,7 +34,7 @@ import java.util.List;
  * ScalarFunction 'current_time'. This class is generated by GenerateFunction.
  */
 public class CurrentTime extends ScalarFunction
-        implements LeafExpression, ExplicitlyCastableSignature, 
Nondeterministic, AlwaysNotNullable {
+        implements LeafExpression, ExplicitlyCastableSignature, 
Nondeterministic, AlwaysNotNullable, Foldable {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
             FunctionSignature.ret(TimeType.INSTANCE).args()
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java
index 8014bbd199..cb65a9bca6 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/DateUtils.java
@@ -18,8 +18,10 @@
 package org.apache.doris.nereids.util;
 
 import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.qe.ConnectContext;
 
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.TextStyle;
@@ -163,4 +165,11 @@ public class DateUtils {
     public static int getOrDefault(final TemporalAccessor accessor, final 
ChronoField field) {
         return accessor.isSupported(field) ? accessor.get(field) : /*default 
value*/ 0;
     }
+
+    public static ZoneId getTimeZone() {
+        if (ConnectContext.get() == null || 
ConnectContext.get().getSessionVariable() == null) {
+            return ZoneId.systemDefault();
+        }
+        return 
ZoneId.of(ConnectContext.get().getSessionVariable().getTimeZone());
+    }
 }
diff --git 
a/regression-test/suites/nereids_p0/datatype/test_date_acquire.groovy 
b/regression-test/suites/nereids_p0/datatype/test_date_acquire.groovy
new file mode 100644
index 0000000000..f78752a33f
--- /dev/null
+++ b/regression-test/suites/nereids_p0/datatype/test_date_acquire.groovy
@@ -0,0 +1,46 @@
+// 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.
+
+suite("test_date_acquire") {
+    sql 'set enable_nereids_planner=true'
+    sql 'set enable_fallback_to_original_planner=false'
+
+    String res = sql 'explain select now(), now(3), curdate(), current_date(), 
curtime(), current_time(), current_timestamp(), current_timestamp(3)'
+    res = res.split('VUNION')[1]
+    assertFalse(res.contains("()") || res.contains("(3)"))
+
+    sql "set enable_fold_constant_by_be=true"
+
+    test {
+        sql "select from_unixtime(1553152255), unix_timestamp('2007-11-30 
10:30%3A19', '%Y-%m-%d %H:%i%%3A%s')"
+        result([['2019-03-21 15:10:55', 1196389819]])
+    }
+
+    sql "set time_zone='+00:00'"
+
+    test {
+        sql "select from_unixtime(1553152255), unix_timestamp('2007-11-30 
10:30%3A19', '%Y-%m-%d %H:%i%%3A%s')"
+        result([['2019-03-21 07:10:55', 1196418619]])
+    }
+
+    sql "set time_zone='+04:00'"
+
+    test {
+        sql "select from_unixtime(1553152255), unix_timestamp('2007-11-30 
10:30%3A19', '%Y-%m-%d %H:%i%%3A%s')"
+        result([['2019-03-21 11:10:55', 1196404219]])
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to