You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by ya...@apache.org on 2022/12/23 11:05:14 UTC

[doris] branch master updated: [bugfix](from_unixtime) fix timezone not work for from_unixtime (#15298)

This is an automated email from the ASF dual-hosted git repository.

yangzhg 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 a98636a970 [bugfix](from_unixtime) fix timezone not work for from_unixtime (#15298)
a98636a970 is described below

commit a98636a97083932a39045994c7b612d029ce0be7
Author: Zhengguo Yang <ya...@gmail.com>
AuthorDate: Fri Dec 23 19:05:09 2022 +0800

    [bugfix](from_unixtime) fix timezone not work for from_unixtime (#15298)
    
    * [bugfix](from_unixtime) fix timezone not work for from_unixtime
---
 be/src/gutil/casts.h                               |   7 +-
 be/src/gutil/charmap.h                             |   5 -
 be/src/gutil/gscoped_ptr.h                         |  12 +-
 be/src/gutil/once.h                                |   5 +-
 be/src/gutil/strings/stringpiece.h                 |   5 -
 be/src/gutil/type_traits.h                         | 468 ---------------------
 be/src/http/action/tablet_migration_action.cpp     |   2 +-
 be/src/runtime/memory/mem_tracker_limiter.cpp      |  14 +-
 be/src/util/thread.cpp                             |   2 +-
 .../function_utils.h => src/util/type_traits.h}    |  40 +-
 be/src/vec/functions/date_time_transforms.h        |  29 +-
 .../function_date_or_datetime_to_string.h          |   2 +-
 .../function_datetime_string_to_string.cpp         |   7 +-
 .../functions/function_datetime_string_to_string.h |  38 +-
 be/test/exprs/timestamp_functions_test.cpp         |  25 +-
 be/test/testutil/function_utils.cpp                |  22 +-
 be/test/testutil/function_utils.h                  |   1 -
 .../data/datatype_p0/date/test_from_unixtime.out   |   7 +
 .../datatype_p0/date/test_from_unixtime.groovy     |  34 +-
 19 files changed, 99 insertions(+), 626 deletions(-)

diff --git a/be/src/gutil/casts.h b/be/src/gutil/casts.h
index 71a147cfaf..8e2a1a5cad 100644
--- a/be/src/gutil/casts.h
+++ b/be/src/gutil/casts.h
@@ -14,9 +14,10 @@
 #include <limits.h> // for enumeration casts and tests
 #include <string.h> // for memcpy
 
+#include <type_traits>
+
 #include "gutil/macros.h"
 #include "gutil/template_util.h"
-#include "gutil/type_traits.h"
 
 // Use implicit_cast as a safe version of static_cast or const_cast
 // for implicit conversions. For example:
@@ -89,8 +90,8 @@ inline To down_cast(From* f) {        // so we only accept pointers
 // compiler will just bind From to const T.
 template <typename To, typename From>
 inline To down_cast(From& f) {
-    COMPILE_ASSERT(base::is_reference<To>::value, target_type_not_a_reference);
-    typedef typename base::remove_reference<To>::type* ToAsPointer;
+    COMPILE_ASSERT(std::is_reference<To>::value, target_type_not_a_reference);
+    using ToAsPointer = typename std::remove_reference<To>::type*;
     if (false) {
         // Compile-time check that To inherits from From. See above for details.
         ::implicit_cast<From*, ToAsPointer>(NULL);
diff --git a/be/src/gutil/charmap.h b/be/src/gutil/charmap.h
index 213d44f726..797abcce5c 100644
--- a/be/src/gutil/charmap.h
+++ b/be/src/gutil/charmap.h
@@ -17,10 +17,6 @@
 
 #include <string.h>
 
-#include "gutil/basictypes.h"
-#include "gutil/integral_types.h"
-#include "gutil/type_traits.h"
-
 class Charmap {
 public:
     // Initializes with given uint32 values.  For instance, the first
@@ -73,4 +69,3 @@ protected:
         }
     }
 };
-DECLARE_POD(Charmap);
diff --git a/be/src/gutil/gscoped_ptr.h b/be/src/gutil/gscoped_ptr.h
index d1d88d1da7..01305b9294 100644
--- a/be/src/gutil/gscoped_ptr.h
+++ b/be/src/gutil/gscoped_ptr.h
@@ -102,11 +102,11 @@
 #include <stdlib.h>
 
 #include <algorithm> // For std::swap().
+#include <type_traits>
 
 #include "gutil/basictypes.h"
 #include "gutil/move.h"
 #include "gutil/template_util.h"
-#include "gutil/type_traits.h"
 
 namespace doris {
 
@@ -137,7 +137,7 @@ struct DefaultDeleter {
         // cannot convert to T*.
         enum { T_must_be_complete = sizeof(T) };
         enum { U_must_be_complete = sizeof(U) };
-        COMPILE_ASSERT((base::is_convertible<U*, T*>::value),
+        COMPILE_ASSERT((std::is_convertible<U*, T*>::value),
                        U_ptr_must_implicitly_convert_to_T_ptr);
     }
     inline void operator()(T* ptr) const {
@@ -186,8 +186,8 @@ namespace internal {
 template <typename T>
 struct IsNotRefCounted {
     enum {
-        value = !base::is_convertible<T*, doris::subtle::RefCountedBase*>::value &&
-                !base::is_convertible<T*, doris::subtle::RefCountedThreadSafeBase*>::value
+        value = !std::is_convertible<T*, doris::subtle::RefCountedBase*>::value &&
+                !std::is_convertible<T*, doris::subtle::RefCountedThreadSafeBase*>::value
     };
 };
 
@@ -345,7 +345,7 @@ public:
     // implementation of gscoped_ptr.
     template <typename U, typename V>
     gscoped_ptr(gscoped_ptr<U, V> other) : impl_(&other.impl_) {
-        COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array);
+        COMPILE_ASSERT(!std::is_array<U>::value, U_cannot_be_an_array);
     }
 
     // Constructor.  Move constructor for C++03 move emulation of this type.
@@ -363,7 +363,7 @@ public:
     // gscoped_ptr.
     template <typename U, typename V>
     gscoped_ptr& operator=(gscoped_ptr<U, V> rhs) {
-        COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array);
+        COMPILE_ASSERT(!std::is_array<U>::value, U_cannot_be_an_array);
         impl_.TakeState(&rhs.impl_);
         return *this;
     }
diff --git a/be/src/gutil/once.h b/be/src/gutil/once.h
index fcc6b19373..5688668cb4 100644
--- a/be/src/gutil/once.h
+++ b/be/src/gutil/once.h
@@ -28,7 +28,6 @@
 #include "gutil/integral_types.h"
 #include "gutil/macros.h"
 #include "gutil/port.h"
-#include "gutil/type_traits.h"
 
 // The following enum values are not for use by clients
 enum {
@@ -64,7 +63,7 @@ inline void GoogleOnceInitArg(GoogleOnceType* state, void (*func_with_arg)(T*),
     Atomic32 s = Acquire_Load(&state->state);
     if (PREDICT_FALSE(s != GOOGLE_ONCE_INTERNAL_DONE)) {
         // Deal with const T as well as non-const T.
-        typedef typename base::remove_const<T>::type mutable_T;
+        using mutable_T = typename std::remove_const<T>::type;
         GoogleOnceInternalInit(&state->state, 0, reinterpret_cast<void (*)(void*)>(func_with_arg),
                                const_cast<mutable_T*>(arg));
     }
@@ -102,7 +101,7 @@ public:
         Atomic32 s = Acquire_Load(&this->state_);
         if (PREDICT_FALSE(s != GOOGLE_ONCE_INTERNAL_DONE)) {
             // Deal with const T as well as non-const T.
-            typedef typename base::remove_const<T>::type mutable_T;
+            using mutable_T = typename std::remove_const<T>::type;
             GoogleOnceInternalInit(&this->state_, 0,
                                    reinterpret_cast<void (*)(void*)>(func_with_arg),
                                    const_cast<mutable_T*>(arg));
diff --git a/be/src/gutil/strings/stringpiece.h b/be/src/gutil/strings/stringpiece.h
index 99ef3b6fde..143eb8d3e3 100644
--- a/be/src/gutil/strings/stringpiece.h
+++ b/be/src/gutil/strings/stringpiece.h
@@ -124,7 +124,6 @@
 #include "gutil/integral_types.h"
 #include "gutil/port.h"
 #include "gutil/strings/fastmem.h"
-#include "gutil/type_traits.h"
 
 class StringPiece {
 private:
@@ -288,10 +287,6 @@ public:
     StringPiece substr(size_type pos, size_type n = npos) const;
 };
 
-#ifndef SWIG
-DECLARE_POD(StringPiece); // So vector<StringPiece> becomes really fast
-#endif
-
 // This large function is defined inline so that in a fairly common case where
 // one of the arguments is a literal, the compiler can elide a lot of the
 // following comparisons.
diff --git a/be/src/gutil/type_traits.h b/be/src/gutil/type_traits.h
deleted file mode 100644
index 3841c622bf..0000000000
--- a/be/src/gutil/type_traits.h
+++ /dev/null
@@ -1,468 +0,0 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ----
-//
-// This code is compiled directly on many platforms, including client
-// platforms like Windows, Mac, and embedded systems.  Before making
-// any changes here, make sure that you're not breaking any platforms.
-//
-// Define a small subset of tr1 type traits. The traits we define are:
-//   enable_if
-//   is_integral
-//   is_floating_point
-//   is_pointer
-//   is_array
-//   is_enum
-//   is_reference
-//   is_pod
-//   has_trivial_constructor
-//   has_trivial_copy
-//   has_trivial_assign
-//   has_trivial_destructor
-//   remove_const
-//   remove_volatile
-//   remove_cv
-//   remove_reference
-//   add_reference
-//   remove_pointer
-//   is_same
-//   is_convertible
-// We can add more type traits as required.
-
-#ifndef BASE_TYPE_TRAITS_H_
-#define BASE_TYPE_TRAITS_H_
-
-#include <utility>
-using std::make_pair;
-using std::pair; // For pair
-
-#include "gutil/template_util.h" // For true_type and false_type
-
-namespace base {
-
-template <bool cond, class T>
-struct enable_if;
-template <class T>
-struct is_integral;
-template <class T>
-struct is_floating_point;
-template <class T>
-struct is_pointer;
-template <class T>
-struct is_array;
-// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least)
-#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
-// is_enum uses is_convertible, which is not available on MSVC.
-template <class T>
-struct is_enum;
-#endif
-template <class T>
-struct is_reference;
-template <class T>
-struct is_pod;
-template <class T>
-struct has_trivial_constructor;
-template <class T>
-struct has_trivial_copy;
-template <class T>
-struct has_trivial_assign;
-template <class T>
-struct has_trivial_destructor;
-template <class T>
-struct remove_const;
-template <class T>
-struct remove_volatile;
-template <class T>
-struct remove_cv;
-template <class T>
-struct remove_reference;
-template <class T>
-struct add_reference;
-template <class T>
-struct remove_pointer;
-template <class T, class U>
-struct is_same;
-#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
-template <class From, class To>
-struct is_convertible;
-#endif
-
-// enable_if, equivalent semantics to c++11 std::enable_if, specifically:
-//   "If B is true, the member typedef type shall equal T; otherwise, there
-//    shall be no member typedef type."
-// Specified by 20.9.7.6 [Other transformations]
-template <bool cond, class T = void>
-struct enable_if {
-    typedef T type;
-};
-template <class T>
-struct enable_if<false, T> {};
-
-// is_integral is false except for the built-in integer types. A
-// cv-qualified type is integral if and only if the underlying type is.
-template <class T>
-struct is_integral : false_type {};
-template <>
-struct is_integral<bool> : true_type {};
-template <>
-struct is_integral<char> : true_type {};
-template <>
-struct is_integral<unsigned char> : true_type {};
-template <>
-struct is_integral<signed char> : true_type {};
-#if defined(_MSC_VER)
-// wchar_t is not by default a distinct type from unsigned short in
-// Microsoft C.
-// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
-template <>
-struct is_integral<__wchar_t> : true_type {};
-#else
-template <>
-struct is_integral<wchar_t> : true_type {};
-#endif
-#if defined(__APPLE__)
-template <>
-struct is_integral<int64_t> : true_type {};
-template <>
-struct is_integral<uint64_t> : true_type {};
-#endif
-template <>
-struct is_integral<short> : true_type {};
-template <>
-struct is_integral<unsigned short> : true_type {};
-template <>
-struct is_integral<int> : true_type {};
-template <>
-struct is_integral<unsigned int> : true_type {};
-template <>
-struct is_integral<long> : true_type {};
-template <>
-struct is_integral<unsigned long> : true_type {};
-#if defined(HAVE_LONG_LONG) && !defined(__APPLE__)
-template <>
-struct is_integral<long long> : true_type {};
-template <>
-struct is_integral<unsigned long long> : true_type {};
-#endif
-template <class T>
-struct is_integral<const T> : is_integral<T> {};
-template <class T>
-struct is_integral<volatile T> : is_integral<T> {};
-template <class T>
-struct is_integral<const volatile T> : is_integral<T> {};
-
-// is_floating_point is false except for the built-in floating-point types.
-// A cv-qualified type is integral if and only if the underlying type is.
-template <class T>
-struct is_floating_point : false_type {};
-template <>
-struct is_floating_point<float> : true_type {};
-template <>
-struct is_floating_point<double> : true_type {};
-template <>
-struct is_floating_point<long double> : true_type {};
-template <class T>
-struct is_floating_point<const T> : is_floating_point<T> {};
-template <class T>
-struct is_floating_point<volatile T> : is_floating_point<T> {};
-template <class T>
-struct is_floating_point<const volatile T> : is_floating_point<T> {};
-
-// is_pointer is false except for pointer types. A cv-qualified type (e.g.
-// "int* const", as opposed to "int const*") is cv-qualified if and only if
-// the underlying type is.
-template <class T>
-struct is_pointer : false_type {};
-template <class T>
-struct is_pointer<T*> : true_type {};
-template <class T>
-struct is_pointer<const T> : is_pointer<T> {};
-template <class T>
-struct is_pointer<volatile T> : is_pointer<T> {};
-template <class T>
-struct is_pointer<const volatile T> : is_pointer<T> {};
-
-template <class>
-struct is_array : public false_type {};
-template <class T, size_t n>
-struct is_array<T[n]> : public true_type {};
-template <class T>
-struct is_array<T[]> : public true_type {};
-
-#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
-
-namespace internal {
-
-template <class T>
-struct is_class_or_union {
-    template <class U>
-    static small_ tester(void (U::*)());
-    template <class U>
-    static big_ tester(...);
-    static const bool value = sizeof(tester<T>(0)) == sizeof(small_);
-};
-
-// is_convertible chokes if the first argument is an array. That's why
-// we use add_reference here.
-template <bool NotUnum, class T>
-struct is_enum_impl : is_convertible<typename add_reference<T>::type, int> {};
-
-template <class T>
-struct is_enum_impl<true, T> : false_type {};
-
-} // namespace internal
-
-// Specified by TR1 [4.5.1] primary type categories.
-
-// Implementation note:
-//
-// Each type is either void, integral, floating point, array, pointer,
-// reference, member object pointer, member function pointer, enum,
-// union or class. Out of these, only integral, floating point, reference,
-// class and enum types are potentially convertible to int. Therefore,
-// if a type is not a reference, integral, floating point or class and
-// is convertible to int, it's a enum. Adding cv-qualification to a type
-// does not change whether it's an enum.
-//
-// Is-convertible-to-int check is done only if all other checks pass,
-// because it can't be used with some types (e.g. void or classes with
-// inaccessible conversion operators).
-template <class T>
-struct is_enum
-        : internal::is_enum_impl<is_same<T, void>::value || is_integral<T>::value ||
-                                         is_floating_point<T>::value || is_reference<T>::value ||
-                                         internal::is_class_or_union<T>::value,
-                                 T> {};
-
-template <class T>
-struct is_enum<const T> : is_enum<T> {};
-template <class T>
-struct is_enum<volatile T> : is_enum<T> {};
-template <class T>
-struct is_enum<const volatile T> : is_enum<T> {};
-
-#endif
-
-// is_reference is false except for reference types.
-template <typename T>
-struct is_reference : false_type {};
-template <typename T>
-struct is_reference<T&> : true_type {};
-
-// We can't get is_pod right without compiler help, so fail conservatively.
-// We will assume it's false except for arithmetic types, enumerations,
-// pointers and cv-qualified versions thereof. Note that std::pair<T,U>
-// is not a POD even if T and U are PODs.
-template <class T>
-struct is_pod : integral_constant<bool, (is_integral<T>::value || is_floating_point<T>::value ||
-#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
-                                         // is_enum is not available on MSVC.
-                                         is_enum<T>::value ||
-#endif
-                                         is_pointer<T>::value)> {
-};
-template <class T>
-struct is_pod<const T> : is_pod<T> {};
-template <class T>
-struct is_pod<volatile T> : is_pod<T> {};
-template <class T>
-struct is_pod<const volatile T> : is_pod<T> {};
-
-// We can't get has_trivial_constructor right without compiler help, so
-// fail conservatively. We will assume it's false except for: (1) types
-// for which is_pod is true. (2) std::pair of types with trivial
-// constructors. (3) array of a type with a trivial constructor.
-// (4) const versions thereof.
-template <class T>
-struct has_trivial_constructor : is_pod<T> {};
-template <class T, class U>
-struct has_trivial_constructor<std::pair<T, U>>
-        : integral_constant<bool, (has_trivial_constructor<T>::value &&
-                                   has_trivial_constructor<U>::value)> {};
-template <class A, int N>
-struct has_trivial_constructor<A[N]> : has_trivial_constructor<A> {};
-template <class T>
-struct has_trivial_constructor<const T> : has_trivial_constructor<T> {};
-
-// We can't get has_trivial_copy right without compiler help, so fail
-// conservatively. We will assume it's false except for: (1) types
-// for which is_pod is true. (2) std::pair of types with trivial copy
-// constructors. (3) array of a type with a trivial copy constructor.
-// (4) const versions thereof.
-template <class T>
-struct has_trivial_copy : is_pod<T> {};
-template <class T, class U>
-struct has_trivial_copy<std::pair<T, U>>
-        : integral_constant<bool, (has_trivial_copy<T>::value && has_trivial_copy<U>::value)> {};
-template <class A, int N>
-struct has_trivial_copy<A[N]> : has_trivial_copy<A> {};
-template <class T>
-struct has_trivial_copy<const T> : has_trivial_copy<T> {};
-
-// We can't get has_trivial_assign right without compiler help, so fail
-// conservatively. We will assume it's false except for: (1) types
-// for which is_pod is true. (2) std::pair of types with trivial copy
-// constructors. (3) array of a type with a trivial assign constructor.
-template <class T>
-struct has_trivial_assign : is_pod<T> {};
-template <class T, class U>
-struct has_trivial_assign<std::pair<T, U>>
-        : integral_constant<bool, (has_trivial_assign<T>::value && has_trivial_assign<U>::value)> {
-};
-template <class A, int N>
-struct has_trivial_assign<A[N]> : has_trivial_assign<A> {};
-
-// We can't get has_trivial_destructor right without compiler help, so
-// fail conservatively. We will assume it's false except for: (1) types
-// for which is_pod is true. (2) std::pair of types with trivial
-// destructors. (3) array of a type with a trivial destructor.
-// (4) const versions thereof.
-template <class T>
-struct has_trivial_destructor : is_pod<T> {};
-template <class T, class U>
-struct has_trivial_destructor<std::pair<T, U>>
-        : integral_constant<bool, (has_trivial_destructor<T>::value &&
-                                   has_trivial_destructor<U>::value)> {};
-template <class A, int N>
-struct has_trivial_destructor<A[N]> : has_trivial_destructor<A> {};
-template <class T>
-struct has_trivial_destructor<const T> : has_trivial_destructor<T> {};
-
-// Specified by TR1 [4.7.1]
-template <typename T>
-struct remove_const {
-    typedef T type;
-};
-template <typename T>
-struct remove_const<T const> {
-    typedef T type;
-};
-template <typename T>
-struct remove_volatile {
-    typedef T type;
-};
-template <typename T>
-struct remove_volatile<T volatile> {
-    typedef T type;
-};
-template <typename T>
-struct remove_cv {
-    typedef typename remove_const<typename remove_volatile<T>::type>::type type;
-};
-
-// Specified by TR1 [4.7.2] Reference modifications.
-template <typename T>
-struct remove_reference {
-    typedef T type;
-};
-template <typename T>
-struct remove_reference<T&> {
-    typedef T type;
-};
-
-template <typename T>
-struct add_reference {
-    typedef T& type;
-};
-template <typename T>
-struct add_reference<T&> {
-    typedef T& type;
-};
-
-// Specified by TR1 [4.7.4] Pointer modifications.
-template <typename T>
-struct remove_pointer {
-    typedef T type;
-};
-template <typename T>
-struct remove_pointer<T*> {
-    typedef T type;
-};
-template <typename T>
-struct remove_pointer<T* const> {
-    typedef T type;
-};
-template <typename T>
-struct remove_pointer<T* volatile> {
-    typedef T type;
-};
-template <typename T>
-struct remove_pointer<T* const volatile> {
-    typedef T type;
-};
-
-// Specified by TR1 [4.6] Relationships between types
-template <typename T, typename U>
-struct is_same : public false_type {};
-template <typename T>
-struct is_same<T, T> : public true_type {};
-
-// Specified by TR1 [4.6] Relationships between types
-#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
-namespace internal {
-
-// This class is an implementation detail for is_convertible, and you
-// don't need to know how it works to use is_convertible. For those
-// who care: we declare two different functions, one whose argument is
-// of type To and one with a variadic argument list. We give them
-// return types of different size, so we can use sizeof to trick the
-// compiler into telling us which function it would have chosen if we
-// had called it with an argument of type From.  See Alexandrescu's
-// _Modern C++ Design_ for more details on this sort of trick.
-
-template <typename From, typename To>
-struct ConvertHelper {
-    static small_ Test(To);
-    static big_ Test(...);
-    static From Create();
-};
-} // namespace internal
-
-// Inherits from true_type if From is convertible to To, false_type otherwise.
-template <typename From, typename To>
-struct is_convertible
-        : integral_constant<bool, sizeof(internal::ConvertHelper<From, To>::Test(
-                                          internal::ConvertHelper<From, To>::Create())) ==
-                                          sizeof(small_)> {};
-#endif
-
-} // namespace base
-
-// Right now these macros are no-ops, and mostly just document the fact
-// these types are PODs, for human use.  They may be made more contentful
-// later.  The typedef is just to make it legal to put a semicolon after
-// these macros.
-#define DECLARE_POD(TypeName) typedef int Dummy_Type_For_DECLARE_POD ATTRIBUTE_UNUSED
-#define DECLARE_NESTED_POD(TypeName) DECLARE_POD(TypeName)
-#define PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(TemplateName) \
-    typedef int Dummy_Type_For_PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT ATTRIBUTE_UNUSED
-#define ENFORCE_POD(TypeName) typedef int Dummy_Type_For_ENFORCE_POD ATTRIBUTE_UNUSED
-
-#endif // BASE_TYPE_TRAITS_H_
diff --git a/be/src/http/action/tablet_migration_action.cpp b/be/src/http/action/tablet_migration_action.cpp
index c4dafdede7..6cb05d13a0 100644
--- a/be/src/http/action/tablet_migration_action.cpp
+++ b/be/src/http/action/tablet_migration_action.cpp
@@ -88,7 +88,7 @@ void TabletMigrationAction::handle(HttpRequest* req) {
                                 _migration_tasks.erase(it_task);
                             }
                             std::pair<MigrationTask, Status> finished_task =
-                                    make_pair(current_task, result_status);
+                                    std::make_pair(current_task, result_status);
                             if (_finished_migration_tasks.size() >=
                                 config::finished_migration_tasks_size) {
                                 _finished_migration_tasks.pop_front();
diff --git a/be/src/runtime/memory/mem_tracker_limiter.cpp b/be/src/runtime/memory/mem_tracker_limiter.cpp
index 2c8d112245..07e8b79b10 100644
--- a/be/src/runtime/memory/mem_tracker_limiter.cpp
+++ b/be/src/runtime/memory/mem_tracker_limiter.cpp
@@ -287,17 +287,17 @@ int64_t MemTrackerLimiter::free_top_memory_query(int64_t min_free_mem) {
                                         std::greater<std::pair<int64_t, std::string>>>
                             min_pq_null;
                     std::swap(min_pq, min_pq_null);
-                    min_pq.push(
-                            pair<int64_t, std::string>(tracker->consumption(), tracker->label()));
+                    min_pq.push(std::pair<int64_t, std::string>(tracker->consumption(),
+                                                                tracker->label()));
                     return cancel_top_query(min_pq);
                 } else if (tracker->consumption() + prepare_free_mem < min_free_mem) {
-                    min_pq.push(
-                            pair<int64_t, std::string>(tracker->consumption(), tracker->label()));
+                    min_pq.push(std::pair<int64_t, std::string>(tracker->consumption(),
+                                                                tracker->label()));
                     prepare_free_mem += tracker->consumption();
                 } else if (tracker->consumption() > min_pq.top().first) {
                     // No need to modify prepare_free_mem, prepare_free_mem will always be greater than min_free_mem.
-                    min_pq.push(
-                            pair<int64_t, std::string>(tracker->consumption(), tracker->label()));
+                    min_pq.push(std::pair<int64_t, std::string>(tracker->consumption(),
+                                                                tracker->label()));
                     min_pq.pop();
                 }
             }
@@ -322,7 +322,7 @@ int64_t MemTrackerLimiter::free_top_overcommit_query(int64_t min_free_mem) {
                 if (overcommit_ratio == 0) { // Small query does not cancel
                     continue;
                 }
-                min_pq.push(pair<int64_t, std::string>(overcommit_ratio, tracker->label()));
+                min_pq.push(std::pair<int64_t, std::string>(overcommit_ratio, tracker->label()));
                 query_consumption[tracker->label()] = tracker->consumption();
             }
         }
diff --git a/be/src/util/thread.cpp b/be/src/util/thread.cpp
index c9cc9ba63f..ae58b575ac 100644
--- a/be/src/util/thread.cpp
+++ b/be/src/util/thread.cpp
@@ -240,7 +240,7 @@ void ThreadMgr::display_thread_callback(const WebPageHandler::ArgumentMap& args,
         }
     } else {
         // List all thread groups and the number of threads running in each.
-        std::vector<pair<string, uint64_t>> thread_categories_info;
+        std::vector<std::pair<string, uint64_t>> thread_categories_info;
         uint64_t running;
         {
             std::unique_lock<std::mutex> l(_lock);
diff --git a/be/test/testutil/function_utils.h b/be/src/util/type_traits.h
similarity index 57%
copy from be/test/testutil/function_utils.h
copy to be/src/util/type_traits.h
index 9c759f7b23..dafa20f2d0 100644
--- a/be/test/testutil/function_utils.h
+++ b/be/src/util/type_traits.h
@@ -15,32 +15,26 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#include <memory>
-#include <vector>
+#pragma once
 
-#include "udf/udf.h"
-#include "udf/udf_internal.h"
+#include <complex>
+#include <type_traits>
 
 namespace doris {
 
-class MemPool;
-class RuntimeState;
-
-class FunctionUtils {
-public:
-    FunctionUtils();
-    FunctionUtils(RuntimeState* state);
-    FunctionUtils(const doris_udf::FunctionContext::TypeDesc& return_type,
-                  const std::vector<doris_udf::FunctionContext::TypeDesc>& arg_types,
-                  int varargs_buffer_size);
-    ~FunctionUtils();
-
-    doris_udf::FunctionContext* get_fn_ctx() { return _fn_ctx; }
-
-private:
-    RuntimeState* _state = nullptr;
-    MemPool* _memory_pool = nullptr;
-    doris_udf::FunctionContext* _fn_ctx = nullptr;
-};
+template <class T, template <class...> class Primary>
+struct is_specialization_of : std::false_type {};
+
+template <template <class...> class Primary, class... Args>
+struct is_specialization_of<Primary<Args...>, Primary> : std::true_type {};
+
+template <class T, template <class...> class Primary>
+inline constexpr bool is_specialization_of_v = is_specialization_of<T, Primary>::value;
+
+template <class T>
+using is_complex = is_specialization_of<T, std::complex>;
+
+template <class T>
+inline constexpr bool is_complex_v = is_specialization_of_v<T, std::complex>;
 
 } // namespace doris
diff --git a/be/src/vec/functions/date_time_transforms.h b/be/src/vec/functions/date_time_transforms.h
index 44588c76ea..d07d258dd3 100644
--- a/be/src/vec/functions/date_time_transforms.h
+++ b/be/src/vec/functions/date_time_transforms.h
@@ -21,7 +21,10 @@
 #pragma once
 
 #include "common/status.h"
+#include "runtime/runtime_state.h"
+#include "udf/udf_internal.h"
 #include "util/binary_cast.hpp"
+#include "util/type_traits.h"
 #include "vec/columns/column_nullable.h"
 #include "vec/columns/column_string.h"
 #include "vec/columns/column_vector.h"
@@ -209,10 +212,7 @@ struct FromUnixTimeImpl {
     static constexpr auto name = "from_unixtime";
 
     static inline auto execute(FromType val, StringRef format, ColumnString::Chars& res_data,
-                               size_t& offset) {
-        // TODO: use default time zone, slowly and incorrect, just for test use
-        static cctz::time_zone time_zone = cctz::fixed_time_zone(cctz::seconds(8 * 60 * 60));
-
+                               size_t& offset, const cctz::time_zone& time_zone) {
         DateType dt;
         if (format.size > 128 || val < 0 || val > INT_MAX || !dt.from_unixtime(val, time_zone)) {
             return std::pair {offset, true};
@@ -232,7 +232,8 @@ struct FromUnixTimeImpl {
 
 template <typename Transform>
 struct TransformerToStringOneArgument {
-    static void vector(const PaddedPODArray<typename Transform::OpArgType>& ts,
+    static void vector(FunctionContext* context,
+                       const PaddedPODArray<typename Transform::OpArgType>& ts,
                        ColumnString::Chars& res_data, ColumnString::Offsets& res_offsets,
                        NullMap& null_map) {
         const auto len = ts.size();
@@ -254,7 +255,8 @@ struct TransformerToStringOneArgument {
 
 template <typename Transform>
 struct TransformerToStringTwoArgument {
-    static void vector_constant(const PaddedPODArray<typename Transform::FromType>& ts,
+    static void vector_constant(FunctionContext* context,
+                                const PaddedPODArray<typename Transform::FromType>& ts,
                                 const std::string& format, ColumnString::Chars& res_data,
                                 ColumnString::Offsets& res_offsets,
                                 PaddedPODArray<UInt8>& null_map) {
@@ -266,9 +268,16 @@ struct TransformerToStringTwoArgument {
         size_t offset = 0;
         for (int i = 0; i < len; ++i) {
             const auto& t = ts[i];
-            const auto [new_offset, is_null] = Transform::execute(
-                    t, StringRef(format.c_str(), format.size()), res_data, offset);
-
+            size_t new_offset;
+            bool is_null;
+            if constexpr (is_specialization_of_v<Transform, FromUnixTimeImpl>) {
+                std::tie(new_offset, is_null) =
+                        Transform::execute(t, StringRef(format.c_str(), format.size()), res_data,
+                                           offset, context->impl()->state()->timezone_obj());
+            } else {
+                std::tie(new_offset, is_null) = Transform::execute(
+                        t, StringRef(format.c_str(), format.size()), res_data, offset);
+            }
             res_offsets[i] = new_offset;
             null_map[i] = is_null;
         }
@@ -335,4 +344,4 @@ struct DateTimeTransformImpl {
     }
 };
 
-} // namespace doris::vectorized
\ No newline at end of file
+} // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_date_or_datetime_to_string.h b/be/src/vec/functions/function_date_or_datetime_to_string.h
index f540fbe229..c4f07e05b8 100644
--- a/be/src/vec/functions/function_date_or_datetime_to_string.h
+++ b/be/src/vec/functions/function_date_or_datetime_to_string.h
@@ -62,7 +62,7 @@ public:
         // Support all input of datetime is valind to make sure not null return
         if (sources) {
             TransformerToStringOneArgument<Transform>::vector(
-                    sources->get_data(), col_res->get_chars(), col_res->get_offsets(),
+                    context, sources->get_data(), col_res->get_chars(), col_res->get_offsets(),
                     null_map->get_data());
             block.replace_by_position(
                     result, ColumnNullable::create(std::move(col_res), std::move(null_map)));
diff --git a/be/src/vec/functions/function_datetime_string_to_string.cpp b/be/src/vec/functions/function_datetime_string_to_string.cpp
index a871ac224b..70c82306db 100644
--- a/be/src/vec/functions/function_datetime_string_to_string.cpp
+++ b/be/src/vec/functions/function_datetime_string_to_string.cpp
@@ -28,16 +28,11 @@ using FunctionDateTimeV2DateFormat =
         FunctionDateTimeStringToString<DateFormatImpl<DateV2Value<DateTimeV2ValueType>, UInt64>>;
 using FunctionFromUnixTime = FunctionDateTimeStringToString<FromUnixTimeImpl<VecDateTimeValue>>;
 
-FunctionBuilderPtr createFromUnixTimeFunction() {
-    return std::make_shared<FromUnixTimeFunctionBuilder>();
-}
-
 void register_function_date_time_string_to_string(SimpleFunctionFactory& factory) {
     factory.register_function<FunctionDateFormat>();
     factory.register_function<FunctionDateFormatV2>();
     factory.register_function<FunctionFromUnixTime>();
     factory.register_function<FunctionDateTimeV2DateFormat>();
-    factory.register_function("from_unixtime", &createFromUnixTimeFunction);
 }
 
-} // namespace doris::vectorized
\ No newline at end of file
+} // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_datetime_string_to_string.h b/be/src/vec/functions/function_datetime_string_to_string.h
index 7e9e84268b..3e14c38ef4 100644
--- a/be/src/vec/functions/function_datetime_string_to_string.h
+++ b/be/src/vec/functions/function_datetime_string_to_string.h
@@ -75,8 +75,9 @@ public:
                 if (const auto* delta_const_column =
                             typeid_cast<const ColumnConst*>(&source_col1)) {
                     TransformerToStringTwoArgument<Transform>::vector_constant(
-                            sources->get_data(), delta_const_column->get_field().get<String>(),
-                            col_res->get_chars(), col_res->get_offsets(), vec_null_map_to);
+                            context, sources->get_data(),
+                            delta_const_column->get_field().get<String>(), col_res->get_chars(),
+                            col_res->get_offsets(), vec_null_map_to);
                 } else {
                     return Status::InternalError(
                             "Illegal column {} is not const {}",
@@ -84,7 +85,7 @@ public:
                 }
             } else {
                 TransformerToStringTwoArgument<Transform>::vector_constant(
-                        sources->get_data(), "%Y-%m-%d %H:%i:%s", col_res->get_chars(),
+                        context, sources->get_data(), "%Y-%m-%d %H:%i:%s", col_res->get_chars(),
                         col_res->get_offsets(), vec_null_map_to);
             }
 
@@ -105,35 +106,4 @@ public:
     }
 };
 
-class FromUnixTimeFunctionBuilder : public FunctionBuilderImpl {
-public:
-    explicit FromUnixTimeFunctionBuilder() = default;
-
-    String get_name() const override { return "from_unixtime"; }
-    bool is_variadic() const override { return true; }
-    size_t get_number_of_arguments() const override { return 0; }
-
-    ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
-
-protected:
-    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
-        return make_nullable(std::make_shared<DataTypeString>());
-    }
-    DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override {
-        return make_nullable(std::make_shared<DataTypeString>());
-    }
-
-    bool use_default_implementation_for_nulls() const override { return false; }
-
-    FunctionBasePtr build_impl(const ColumnsWithTypeAndName& arguments,
-                               const DataTypePtr& return_type) const override {
-        DataTypes data_types(arguments.size());
-        for (size_t i = 0; i < arguments.size(); ++i) data_types[i] = arguments[i].type;
-        // TODO: we still use VecDateTimeValue to convert unix timestamp to string
-        auto function =
-                FunctionDateTimeStringToString<FromUnixTimeImpl<VecDateTimeValue>>::create();
-        return std::make_shared<DefaultFunction>(function, data_types, return_type);
-    }
-};
-
 } // namespace doris::vectorized
diff --git a/be/test/exprs/timestamp_functions_test.cpp b/be/test/exprs/timestamp_functions_test.cpp
index 19577c3bd2..5193ef71e5 100644
--- a/be/test/exprs/timestamp_functions_test.cpp
+++ b/be/test/exprs/timestamp_functions_test.cpp
@@ -20,7 +20,6 @@
 #include <gtest/gtest.h>
 
 #include "runtime/exec_env.h"
-#include "runtime/runtime_state.h"
 #include "runtime/test_env.h"
 #include "testutil/function_utils.h"
 #include "udf/udf.h"
@@ -40,23 +39,13 @@ class TimestampFunctionsTest : public testing::Test {
 public:
     TimestampFunctionsTest() {}
 
-    void SetUp() {
-        TQueryGlobals globals;
-        globals.__set_now_string("2019-08-06 01:38:57");
-        globals.__set_timestamp_ms(1565080737805);
-        globals.__set_time_zone("America/Los_Angeles");
-        state = new RuntimeState(globals);
-        utils = new FunctionUtils(state);
+    void SetUp() override {
+        utils = new FunctionUtils();
         ctx = utils->get_fn_ctx();
     }
 
-    void TearDown() {
-        delete state;
-        delete utils;
-    }
+    void TearDown() override { delete utils; }
 
-private:
-    RuntimeState* state = nullptr;
     FunctionUtils* utils = nullptr;
     FunctionContext* ctx = nullptr;
 };
@@ -341,7 +330,7 @@ TEST_F(TimestampFunctionsTest, now) {
 }
 
 TEST_F(TimestampFunctionsTest, from_unix) {
-    IntVal unixtimestamp(1565080737);
+    IntVal unixtimestamp(1565026737);
     StringVal sval = TimestampFunctions::from_unix(ctx, unixtimestamp);
     EXPECT_EQ("2019-08-06 01:38:57", std::string((char*)sval.ptr, sval.len));
 
@@ -354,9 +343,9 @@ TEST_F(TimestampFunctionsTest, to_unix) {
     DateTimeVal dt_val;
     dt_val.packed_time = 1847544683002068992;
     dt_val.type = TIME_DATETIME;
-    EXPECT_EQ(1565080737, TimestampFunctions::to_unix(ctx).val);
-    EXPECT_EQ(1565080737, TimestampFunctions::to_unix(ctx, dt_val).val);
-    EXPECT_EQ(1565080737, TimestampFunctions::to_unix(ctx, StringVal("2019-08-06 01:38:57"),
+    EXPECT_EQ(1565026737, TimestampFunctions::to_unix(ctx).val);
+    EXPECT_EQ(1565026737, TimestampFunctions::to_unix(ctx, dt_val).val);
+    EXPECT_EQ(1565026737, TimestampFunctions::to_unix(ctx, StringVal("2019-08-06 01:38:57"),
                                                       "%Y-%m-%d %H:%i:%S")
                                   .val);
 
diff --git a/be/test/testutil/function_utils.cpp b/be/test/testutil/function_utils.cpp
index 28aaeb2455..eb2c50fa80 100644
--- a/be/test/testutil/function_utils.cpp
+++ b/be/test/testutil/function_utils.cpp
@@ -20,19 +20,17 @@
 #include <vector>
 
 #include "runtime/mem_pool.h"
+#include "runtime/runtime_state.h"
 #include "udf/udf_internal.h"
 
 namespace doris {
 
 FunctionUtils::FunctionUtils() {
-    doris_udf::FunctionContext::TypeDesc return_type;
-    std::vector<doris_udf::FunctionContext::TypeDesc> arg_types;
-    _memory_pool = new MemPool();
-    _fn_ctx = FunctionContextImpl::create_context(_state, _memory_pool, return_type, arg_types, 0,
-                                                  false);
-}
-FunctionUtils::FunctionUtils(RuntimeState* state) {
-    _state = state;
+    TQueryGlobals globals;
+    globals.__set_now_string("2019-08-06 01:38:57");
+    globals.__set_timestamp_ms(1565026737805);
+    globals.__set_time_zone("Asia/Shanghai");
+    _state = new RuntimeState(globals);
     doris_udf::FunctionContext::TypeDesc return_type;
     std::vector<doris_udf::FunctionContext::TypeDesc> arg_types;
     _memory_pool = new MemPool();
@@ -43,6 +41,11 @@ FunctionUtils::FunctionUtils(RuntimeState* state) {
 FunctionUtils::FunctionUtils(const doris_udf::FunctionContext::TypeDesc& return_type,
                              const std::vector<doris_udf::FunctionContext::TypeDesc>& arg_types,
                              int varargs_buffer_size) {
+    TQueryGlobals globals;
+    globals.__set_now_string("2019-08-06 01:38:57");
+    globals.__set_timestamp_ms(1565026737805);
+    globals.__set_time_zone("Asia/Shanghai");
+    _state = new RuntimeState(globals);
     _memory_pool = new MemPool();
     _fn_ctx = FunctionContextImpl::create_context(_state, _memory_pool, return_type, arg_types,
                                                   varargs_buffer_size, false);
@@ -52,6 +55,9 @@ FunctionUtils::~FunctionUtils() {
     _fn_ctx->impl()->close();
     delete _fn_ctx;
     delete _memory_pool;
+    if (_state) {
+        delete _state;
+    }
 }
 
 } // namespace doris
diff --git a/be/test/testutil/function_utils.h b/be/test/testutil/function_utils.h
index 9c759f7b23..c13a532060 100644
--- a/be/test/testutil/function_utils.h
+++ b/be/test/testutil/function_utils.h
@@ -29,7 +29,6 @@ class RuntimeState;
 class FunctionUtils {
 public:
     FunctionUtils();
-    FunctionUtils(RuntimeState* state);
     FunctionUtils(const doris_udf::FunctionContext::TypeDesc& return_type,
                   const std::vector<doris_udf::FunctionContext::TypeDesc>& arg_types,
                   int varargs_buffer_size);
diff --git a/regression-test/data/datatype_p0/date/test_from_unixtime.out b/regression-test/data/datatype_p0/date/test_from_unixtime.out
new file mode 100644
index 0000000000..c202e0aeea
--- /dev/null
+++ b/regression-test/data/datatype_p0/date/test_from_unixtime.out
@@ -0,0 +1,7 @@
+-- This file is automatically generated. You should know what you did if you want to edit this
+-- !sql1 --
+2019-03-21 15:10:55
+
+-- !sql2 --
+2019-03-21 07:10:55
+
diff --git a/be/test/testutil/function_utils.h b/regression-test/suites/datatype_p0/date/test_from_unixtime.groovy
similarity index 54%
copy from be/test/testutil/function_utils.h
copy to regression-test/suites/datatype_p0/date/test_from_unixtime.groovy
index 9c759f7b23..8798749b1b 100644
--- a/be/test/testutil/function_utils.h
+++ b/regression-test/suites/datatype_p0/date/test_from_unixtime.groovy
@@ -1,3 +1,4 @@
+
 // 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
@@ -15,32 +16,13 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#include <memory>
-#include <vector>
-
-#include "udf/udf.h"
-#include "udf/udf_internal.h"
-
-namespace doris {
-
-class MemPool;
-class RuntimeState;
-
-class FunctionUtils {
-public:
-    FunctionUtils();
-    FunctionUtils(RuntimeState* state);
-    FunctionUtils(const doris_udf::FunctionContext::TypeDesc& return_type,
-                  const std::vector<doris_udf::FunctionContext::TypeDesc>& arg_types,
-                  int varargs_buffer_size);
-    ~FunctionUtils();
+suite("test_from_unixtime") {
+    sql "set enable_vectorized_engine=true"
+    sql "set enable_fold_constant_by_be=true"
 
-    doris_udf::FunctionContext* get_fn_ctx() { return _fn_ctx; }
+    qt_sql1 "select from_unixtime(1553152255)"
 
-private:
-    RuntimeState* _state = nullptr;
-    MemPool* _memory_pool = nullptr;
-    doris_udf::FunctionContext* _fn_ctx = nullptr;
-};
+    sql "set time_zone='+00:00'"
 
-} // namespace doris
+    qt_sql2 "select from_unixtime(1553152255)"
+}


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