From 3e488acbc5b210ee369f5b41d64419bf333a133c Mon Sep 17 00:00:00 2001 From: ti-srebot <66930949+ti-srebot@users.noreply.github.com> Date: Fri, 18 Jun 2021 19:57:21 +0800 Subject: [PATCH] expression: push unix_timestamp, concat to TiFlash (#2059) (#2085) --- dbms/src/Common/MyTime.cpp | 20 -- dbms/src/Common/MyTime.h | 19 ++ dbms/src/Flash/Coprocessor/DAGUtils.cpp | 6 +- dbms/src/Functions/FunctionsConversion.cpp | 120 ++++++++++++ dbms/src/Functions/FunctionsConversion.h | 64 +++---- dbms/src/Functions/FunctionsString.cpp | 60 ++++++ dbms/src/Functions/IFunction.h | 2 +- tests/fullstack-test/expr/concat.test | 76 ++++++++ tests/fullstack-test/expr/unixTimeStamp.test | 185 +++++++++++++++++++ 9 files changed, 495 insertions(+), 57 deletions(-) create mode 100644 tests/fullstack-test/expr/concat.test create mode 100644 tests/fullstack-test/expr/unixTimeStamp.test diff --git a/dbms/src/Common/MyTime.cpp b/dbms/src/Common/MyTime.cpp index 70f8089ef31..1436ad08342 100644 --- a/dbms/src/Common/MyTime.cpp +++ b/dbms/src/Common/MyTime.cpp @@ -797,26 +797,6 @@ String MyDateTime::toString(int fsp) const inline bool isZeroDate(UInt64 time) { return time == 0; } -inline bool supportedByDateLUT(const MyDateTime & my_time) { return my_time.year >= 1970; } - -/// DateLUT only support time from year 1970, in some corner cases, the input date may be -/// 1969-12-31, need extra logical to handle it -inline time_t getEpochSecond(const MyDateTime & my_time, const DateLUTImpl & time_zone) -{ - if likely (supportedByDateLUT(my_time)) - return time_zone.makeDateTime(my_time.year, my_time.month, my_time.day, my_time.hour, my_time.minute, my_time.second); - if likely (my_time.year == 1969 && my_time.month == 12 && my_time.day == 31) - { - /// - 3600 * 24 + my_time.hour * 3600 + my_time.minute * 60 + my_time.second is UTC based, need to adjust - /// the epoch according to the input time_zone - return -3600 * 24 + my_time.hour * 3600 + my_time.minute * 60 + my_time.second - time_zone.getOffsetAtStartEpoch(); - } - else - { - throw Exception("Unsupported timestamp value , TiFlash only support timestamp after 1970-01-01 00:00:00 UTC)"); - } -} - void convertTimeZone(UInt64 from_time, UInt64 & to_time, const DateLUTImpl & time_zone_from, const DateLUTImpl & time_zone_to) { if (isZeroDate(from_time)) diff --git a/dbms/src/Common/MyTime.h b/dbms/src/Common/MyTime.h index e337013f45f..3e80ae58460 100644 --- a/dbms/src/Common/MyTime.h +++ b/dbms/src/Common/MyTime.h @@ -163,6 +163,25 @@ int calcDayNum(int year, int month, int day); size_t maxFormattedDateTimeStringLength(const String & format); +inline bool supportedByDateLUT(const MyDateTime & my_time) { return my_time.year >= 1970; } + +/// DateLUT only support time from year 1970, in some corner cases, the input date may be +/// 1969-12-31, need extra logical to handle it +inline time_t getEpochSecond(const MyDateTime & my_time, const DateLUTImpl & time_zone) +{ + if likely (supportedByDateLUT(my_time)) + return time_zone.makeDateTime(my_time.year, my_time.month, my_time.day, my_time.hour, my_time.minute, my_time.second); + if likely (my_time.year == 1969 && my_time.month == 12 && my_time.day == 31) + { + /// - 3600 * 24 + my_time.hour * 3600 + my_time.minute * 60 + my_time.second is UTC based, need to adjust + /// the epoch according to the input time_zone + return -3600 * 24 + my_time.hour * 3600 + my_time.minute * 60 + my_time.second - time_zone.getOffsetAtStartEpoch(); + } + else + { + throw Exception("Unsupported timestamp value , TiFlash only support timestamp after 1970-01-01 00:00:00 UTC)"); + } +} bool isPunctuation(char c); diff --git a/dbms/src/Flash/Coprocessor/DAGUtils.cpp b/dbms/src/Flash/Coprocessor/DAGUtils.cpp index de77a704d54..37a057f4d05 100644 --- a/dbms/src/Flash/Coprocessor/DAGUtils.cpp +++ b/dbms/src/Flash/Coprocessor/DAGUtils.cpp @@ -888,8 +888,7 @@ std::unordered_map scalar_func_map({ //{tipb::ScalarFuncSig::SubDateAndString, "cast"}, //{tipb::ScalarFuncSig::UnixTimestampCurrent, "cast"}, - //{tipb::ScalarFuncSig::UnixTimestampInt, "cast"}, - //{tipb::ScalarFuncSig::UnixTimestampDec, "cast"}, + {tipb::ScalarFuncSig::UnixTimestampInt, "tidbUnixTimeStampInt"}, {tipb::ScalarFuncSig::UnixTimestampDec, "tidbUnixTimeStampDec"}, //{tipb::ScalarFuncSig::ConvertTz, "cast"}, //{tipb::ScalarFuncSig::MakeDate, "cast"}, @@ -941,8 +940,7 @@ std::unordered_map scalar_func_map({ //{tipb::ScalarFuncSig::Bin, "cast"}, //{tipb::ScalarFuncSig::ASCII, "cast"}, //{tipb::ScalarFuncSig::Char, "cast"}, - {tipb::ScalarFuncSig::CharLengthUTF8, "lengthUTF8"}, - //{tipb::ScalarFuncSig::Concat, "cast"}, + {tipb::ScalarFuncSig::CharLengthUTF8, "lengthUTF8"}, {tipb::ScalarFuncSig::Concat, "tidbConcat"}, //{tipb::ScalarFuncSig::ConcatWS, "cast"}, //{tipb::ScalarFuncSig::Convert, "cast"}, //{tipb::ScalarFuncSig::Elt, "cast"}, diff --git a/dbms/src/Functions/FunctionsConversion.cpp b/dbms/src/Functions/FunctionsConversion.cpp index 69d18595f76..91107ac158a 100644 --- a/dbms/src/Functions/FunctionsConversion.cpp +++ b/dbms/src/Functions/FunctionsConversion.cpp @@ -27,6 +27,124 @@ void throwExceptionForIncompletelyParsedValue( } +struct NameTiDBUnixTimeStampInt { static constexpr auto name = "tidbUnixTimeStampInt"; }; +struct NameTiDBUnixTimeStampDec { static constexpr auto name = "tidbUnixTimeStampDec"; }; + +template +class FunctionTiDBUnixTimeStamp : public IFunction +{ +public: + static constexpr auto name = Name::name; + static FunctionPtr create(const Context & context) { return std::make_shared(context); }; + explicit FunctionTiDBUnixTimeStamp(const Context & context) : timezone_(context.getTimezoneInfo()){}; + + String getName() const override + { + return name; + } + + size_t getNumberOfArguments() const override { return 1; } + + bool useDefaultImplementationForConstants() const override { return true; } + + DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override + { + if (!arguments[0].type->isMyDateOrMyDateTime()) + throw Exception("The argument of function " + getName() + " must be date or datetime type", ErrorCodes::ILLEGAL_COLUMN); + + if constexpr (std::is_same_v) + return std::make_shared(); + + int fsp = 0; + if (checkDataType(arguments[0].type.get())) + { + auto & datetimeType = dynamic_cast(*arguments[0].type); + fsp = datetimeType.getFraction(); + } + return std::make_shared(12+fsp, fsp); + } + + void executeImpl(Block & block, const ColumnNumbers & arguments, const size_t result) override + { + const auto & col_with_type_and_name = block.getByPosition(arguments[0]); + + const auto * col_from = checkAndGetColumn(col_with_type_and_name.column.get()); + const ColumnUInt64::Container & vec_from = col_from->getData(); + size_t size = vec_from.size(); + + if constexpr (std::is_same_v) + { + auto col_to = ColumnUInt64::create(); + auto & vec_to = col_to->getData(); + vec_to.resize(size); + + for (size_t i = 0; i < size; i++) + { + UInt64 ret = 0; + if (getUnixTimeStampHelper(vec_from[i], ret)) + vec_to[i] = ret; + else + vec_to[i] = 0; + } + + block.getByPosition(result).column = std::move(col_to); + } + else /* if constexpr (std::is_same_v) */ + { + // Todo: speed up by `prepare`. + int fsp = 0, multiplier = 1, divider = 1'000'000; + if (checkDataType(col_with_type_and_name.type.get())) + { + auto & datetimeType = dynamic_cast(*col_with_type_and_name.type); + fsp = datetimeType.getFraction(); + } + multiplier = getScaleMultiplier(fsp); + divider = 1'000'000 / multiplier; + + auto col_to = ColumnDecimal::create(0, fsp); + auto & vec_to = col_to->getData(); + vec_to.resize(size); + + for (size_t i = 0; i < size; i++) + { + UInt64 ret = 0; + if (getUnixTimeStampHelper(vec_from[i], ret)) + { + MyDateTime datetime(vec_from[i]); + vec_to[i] = ret * multiplier + datetime.micro_second / divider; + } + else + vec_to[i] = 0; + } + + block.getByPosition(result).column = std::move(col_to); + } + } + +private: + const TimezoneInfo & timezone_; + + bool getUnixTimeStampHelper(UInt64 packed, UInt64 & ret) + { + static const auto lut_utc = DateLUT::instance("UTC"); + + if (timezone_.is_name_based) + convertTimeZone(packed, ret, *timezone_.timezone, lut_utc); + else + convertTimeZoneByOffset(packed, ret, -timezone_.timezone_offset, lut_utc); + + try + { + ret = getEpochSecond(ret, lut_utc); + } + catch (...) + { + return false; + } + return true; + } +}; + void registerFunctionsConversion(FunctionFactory & factory) { factory.registerFunction(); @@ -91,6 +209,8 @@ void registerFunctionsConversion(FunctionFactory & factory) factory.registerFunction(); factory.registerFunction(); + factory.registerFunction>(); + factory.registerFunction>(); factory.registerFunction>(); factory.registerFunction>(); } diff --git a/dbms/src/Functions/FunctionsConversion.h b/dbms/src/Functions/FunctionsConversion.h index 8a0c88c9ffb..7c445b33c24 100644 --- a/dbms/src/Functions/FunctionsConversion.h +++ b/dbms/src/Functions/FunctionsConversion.h @@ -1,44 +1,45 @@ #pragma once -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include #include -#include -#include -#include -#include #include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include + +#include +#include +#include +#include namespace DB @@ -1750,7 +1751,6 @@ class FunctionStrToDate : public IFunction } }; - /// Monotonicity. struct PositiveMonotonicity diff --git a/dbms/src/Functions/FunctionsString.cpp b/dbms/src/Functions/FunctionsString.cpp index e913c22c882..5915a6f184a 100644 --- a/dbms/src/Functions/FunctionsString.cpp +++ b/dbms/src/Functions/FunctionsString.cpp @@ -931,6 +931,65 @@ class ConcatImpl : public IFunction } }; +/** TiDB Function CONCAT(str1,str2,...) + * Returns the string that results from concatenating the arguments. May have one or more arguments. + * CONCAT() returns NULL if any argument is NULL. +*/ +class FunctionTiDBConcat : public IFunction +{ +private: + const Context & context; + + struct NameTiDBConcat + { + static constexpr auto name = "tidbConcat"; + }; + +public: + static constexpr auto name = NameTiDBConcat::name; + FunctionTiDBConcat(const Context & context) : context(context) {} + static FunctionPtr create(const Context & context) + { + return std::make_shared(context); + } + + String getName() const override{ return name; } + + bool isVariadic() const override{ return true; } + size_t getNumberOfArguments() const override{ return 0; } + + bool useDefaultImplementationForNulls() const override { return true; } + + DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override + { + if (arguments.size() < 1) + throw Exception("Number of arguments for function " + getName() + " doesn't match: passed " + toString(arguments.size()) + + ", should be at least 1.", + ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); + + for (const auto arg_idx : ext::range(0, arguments.size())) + { + const auto & arg = arguments[arg_idx].get(); + if (!arg->isStringOrFixedString()) + throw Exception{ + "Illegal type " + arg->getName() + " of argument " + std::to_string(arg_idx + 1) + " of function " + getName(), + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; + } + + return std::make_shared(); + } + + void executeImpl(Block & block, const ColumnNumbers & arguments, const size_t result) override + { + if (arguments.size() == 1) + { + const IColumn * c0 = block.getByPosition(arguments[0]).column.get(); + block.getByPosition(result).column = c0->cloneResized(c0->size()); + } + else + return ConcatImpl(context).executeImpl(block, arguments, result); + } +}; class FunctionSubstring : public IFunction { @@ -2753,6 +2812,7 @@ void registerFunctionsString(FunctionFactory & factory) factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); + factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); diff --git a/dbms/src/Functions/IFunction.h b/dbms/src/Functions/IFunction.h index 963d048545d..4f140d956a6 100644 --- a/dbms/src/Functions/IFunction.h +++ b/dbms/src/Functions/IFunction.h @@ -253,7 +253,7 @@ class IFunction : public std::enable_shared_from_this, /// TODO: make const void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override = 0; - /// Override this functions to change default implementation behavior. See details in IMyFunction. + /// Override this functions to change default implementation behavior. See details in IPreparedFunction. bool useDefaultImplementationForNulls() const override { return true; } bool useDefaultImplementationForConstants() const override { return false; } ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {}; } diff --git a/tests/fullstack-test/expr/concat.test b/tests/fullstack-test/expr/concat.test new file mode 100644 index 00000000000..33d9fe897e0 --- /dev/null +++ b/tests/fullstack-test/expr/concat.test @@ -0,0 +1,76 @@ +mysql> drop table if exists test.t +mysql> create table test.t(a char(5), b char(5)) +mysql> alter table test.t set tiflash replica 1 +mysql> insert into test.t values(null, 'y') +mysql> insert into test.t values('x', null) +func> wait_table test t +mysql> select concat(a, b), count(*) from test.t group by 1; ++-----------------+----------+ +| concat(a, b) | count(*) | ++-----------------+----------+ +| NULL | 2 | ++-----------------+----------+ + +mysql> drop table if exists test.t +mysql> create table test.t(a int, b char(10), c varchar(10)); +mysql> alter table test.t set tiflash replica 1 +func> wait_table test t + +mysql> insert into test.t values(1, '次', '测test试'); +mysql> insert into test.t values(114, 'null', '112'); +mysql> insert into test.t values(null, '114', '614'); +mysql> insert into test.t values(360, null, '-0-'); +mysql> insert into test.t values(360, 124, null); +mysql> insert into test.t values(null, null, null); +mysql> analyze table test.t; + +#mysql> select concat(a, b, c), count(*) from test.t group by 1; +#+-----------------+----------+ +#| concat(a, b, c) | count(*) | +#+-----------------+----------+ +#| NULL | 4 | +#| 114null112 | 1 | +#| 1次测test试 | 1 | +#+-----------------+----------+ + + +mysql> select count(*) from test.t where concat(a, b, c) is null group by concat(a, b, c); ++----------+ +| count(*) | ++-----------+ +| 4 | ++----------+ + +mysql> select count(*) from test.t where concat(a, b, c)='114null112' group by concat(a, b, c); ++----------+ +| count(*) | ++-----------+ +| 1 | ++----------+ + +mysql> select count(*) from test.t where concat(a, b, c)='1次测test试' group by concat(a, b, c); ++----------+ +| count(*) | ++-----------+ +| 1 | ++----------+ + +mysql> select concat(a, NULL), count(*) from test.t group by 1; ++-----------------+----------+ +| concat(a, NULL) | count(*) | ++-----------------+----------+ +| NULL | 6 | ++-----------------+----------+ + +mysql> select concat(b), count(*) from test.t group by 1; ++-----------+----------+ +| concat(b) | count(*) | ++-----------+----------+ +| null | 1 | +| 124 | 1 | +| NULL | 2 | +| 114 | 1 | +| 次 | 1 | ++-----------+----------+ + +mysql> drop table test.t; diff --git a/tests/fullstack-test/expr/unixTimeStamp.test b/tests/fullstack-test/expr/unixTimeStamp.test new file mode 100644 index 00000000000..058095be3bd --- /dev/null +++ b/tests/fullstack-test/expr/unixTimeStamp.test @@ -0,0 +1,185 @@ +mysql> drop table if exists test.t +mysql> create table test.t(a date, b datetime, c timestamp(3), d timestamp(6)); +mysql> alter table test.t set tiflash replica 1; +func> wait_table test t + +mysql> insert into test.t values ('2021-05-23 11:45:14', '2021-05-23 11:45:14', '2021-05-23 11:45:14', '2021-05-23 11:45:14'); +mysql> insert into test.t values ('2021-05-23 11:45:14.192', '2021-05-23 11:45:14.192', '2021-05-23 11:45:14.192', '2021-05-23 11:45:14.192'); +mysql> insert into test.t values ('2021-05-23 11:45:14.191981', '2021-05-23 11:45:14.191981', '2021-05-23 11:45:14.191981', '2021-05-23 11:45:14.191981'); +mysql> analyze table test.t; + +mysql> set @@session.tidb_isolation_read_engines = "tikv"; select count(*), unix_timestamp(a),unix_timestamp(b),unix_timestamp(c),unix_timestamp(d) from test.t group by unix_timestamp(a),unix_timestamp(b),unix_timestamp(c),unix_timestamp(d); ++----------+-------------------+-------------------+-------------------+-------------------+ +| count(*) | unix_timestamp(a) | unix_timestamp(b) | unix_timestamp(c) | unix_timestamp(d) | ++----------+-------------------+-------------------+-------------------+-------------------+ +| 1 | 1621728000 | 1621770314 | 1621770314.192 | 1621770314.192000 | +| 1 | 1621728000 | 1621770314 | 1621770314.192 | 1621770314.191981 | +| 1 | 1621728000 | 1621770314 | 1621770314.000 | 1621770314.000000 | ++----------+-------------------+-------------------+-------------------+-------------------+ + +mysql> set @@session.tidb_isolation_read_engines = "tiflash"; select count(*), unix_timestamp(a),unix_timestamp(b),unix_timestamp(c),unix_timestamp(d) from test.t group by unix_timestamp(a),unix_timestamp(b),unix_timestamp(c),unix_timestamp(d); ++----------+-------------------+-------------------+-------------------+-------------------+ +| count(*) | unix_timestamp(a) | unix_timestamp(b) | unix_timestamp(c) | unix_timestamp(d) | ++----------+-------------------+-------------------+-------------------+-------------------+ +| 1 | 1621728000 | 1621770314 | 1621770314.192 | 1621770314.192000 | +| 1 | 1621728000 | 1621770314 | 1621770314.192 | 1621770314.191981 | +| 1 | 1621728000 | 1621770314 | 1621770314.000 | 1621770314.000000 | ++----------+-------------------+-------------------+-------------------+-------------------+ + +mysql> set time_zone = '+1:00'; set @@session.tidb_isolation_read_engines = "tikv"; select count(*), unix_timestamp(a),unix_timestamp(b),unix_timestamp(c),unix_timestamp(d) from test.t group by unix_timestamp(a),unix_timestamp(b),unix_timestamp(c),unix_timestamp(d); ++----------+-------------------+-------------------+-------------------+-------------------+ +| count(*) | unix_timestamp(a) | unix_timestamp(b) | unix_timestamp(c) | unix_timestamp(d) | ++----------+-------------------+-------------------+-------------------+-------------------+ +| 1 | 1621724400 | 1621766714 | 1621770314.192 | 1621770314.191981 | +| 1 | 1621724400 | 1621766714 | 1621770314.000 | 1621770314.000000 | +| 1 | 1621724400 | 1621766714 | 1621770314.192 | 1621770314.192000 | ++----------+-------------------+-------------------+-------------------+-------------------+ + +mysql> set time_zone = '+1:00'; set @@session.tidb_isolation_read_engines = "tiflash"; select count(*), unix_timestamp(a),unix_timestamp(b),unix_timestamp(c),unix_timestamp(d) from test.t group by unix_timestamp(a),unix_timestamp(b),unix_timestamp(c),unix_timestamp(d); ++----------+-------------------+-------------------+-------------------+-------------------+ +| count(*) | unix_timestamp(a) | unix_timestamp(b) | unix_timestamp(c) | unix_timestamp(d) | ++----------+-------------------+-------------------+-------------------+-------------------+ +| 1 | 1621724400 | 1621766714 | 1621770314.192 | 1621770314.191981 | +| 1 | 1621724400 | 1621766714 | 1621770314.000 | 1621770314.000000 | +| 1 | 1621724400 | 1621766714 | 1621770314.192 | 1621770314.192000 | ++----------+-------------------+-------------------+-------------------+-------------------+ + +# date +mysql> set time_zone = '+0:00'; set @@session.tidb_isolation_read_engines = "tikv"; select a, unix_timestamp(a) from test.t where unix_timestamp(a)='1621728000'; ++------------+-------------------+ +| a | unix_timestamp(a) | ++------------+-------------------+ +| 2021-05-23 | 1621728000 | +| 2021-05-23 | 1621728000 | +| 2021-05-23 | 1621728000 | ++------------+-------------------+ +mysql> set time_zone = '+0:00'; set @@session.tidb_isolation_read_engines = "tiflash"; select a, unix_timestamp(a) from test.t where unix_timestamp(a)='1621728000'; ++------------+-------------------+ +| a | unix_timestamp(a) | ++------------+-------------------+ +| 2021-05-23 | 1621728000 | +| 2021-05-23 | 1621728000 | +| 2021-05-23 | 1621728000 | ++------------+-------------------+ + +mysql> set time_zone = '+1:00'; set @@session.tidb_isolation_read_engines = "tikv"; select a, unix_timestamp(a) from test.t where unix_timestamp(a)='1621724400'; ++------------+-------------------+ +| a | unix_timestamp(a) | ++------------+-------------------+ +| 2021-05-23 | 1621724400 | +| 2021-05-23 | 1621724400 | +| 2021-05-23 | 1621724400 | ++------------+-------------------+ +mysql> set time_zone = '+1:00'; set @@session.tidb_isolation_read_engines = "tiflash"; select a, unix_timestamp(a) from test.t where unix_timestamp(a)='1621724400'; ++------------+-------------------+ +| a | unix_timestamp(a) | ++------------+-------------------+ +| 2021-05-23 | 1621724400 | +| 2021-05-23 | 1621724400 | +| 2021-05-23 | 1621724400 | ++------------+-------------------+ + +# datetime +mysql> set time_zone = '+0:00'; set @@session.tidb_isolation_read_engines = "tikv"; select b, unix_timestamp(b) from test.t where unix_timestamp(b)='1621770314'; ++---------------------+-------------------+ +| b | unix_timestamp(b) | ++---------------------+-------------------+ +| 2021-05-23 11:45:14 | 1621770314 | +| 2021-05-23 11:45:14 | 1621770314 | +| 2021-05-23 11:45:14 | 1621770314 | ++---------------------+-------------------+ +mysql> set time_zone = '+0:00'; set @@session.tidb_isolation_read_engines = "tiflash"; select b, unix_timestamp(b) from test.t where unix_timestamp(b)='1621770314'; ++---------------------+-------------------+ +| b | unix_timestamp(b) | ++---------------------+-------------------+ +| 2021-05-23 11:45:14 | 1621770314 | +| 2021-05-23 11:45:14 | 1621770314 | +| 2021-05-23 11:45:14 | 1621770314 | ++---------------------+-------------------+ + +mysql> set time_zone = '+1:00'; set @@session.tidb_isolation_read_engines = "tikv"; select b, unix_timestamp(b) from test.t where unix_timestamp(b)='1621766714'; ++---------------------+-------------------+ +| b | unix_timestamp(b) | ++---------------------+-------------------+ +| 2021-05-23 11:45:14 | 1621766714 | +| 2021-05-23 11:45:14 | 1621766714 | +| 2021-05-23 11:45:14 | 1621766714 | ++---------------------+-------------------+ +mysql> set time_zone = '+1:00'; set @@session.tidb_isolation_read_engines = "tiflash"; select b, unix_timestamp(b) from test.t where unix_timestamp(b)='1621766714'; ++---------------------+-------------------+ +| b | unix_timestamp(b) | ++---------------------+-------------------+ +| 2021-05-23 11:45:14 | 1621766714 | +| 2021-05-23 11:45:14 | 1621766714 | +| 2021-05-23 11:45:14 | 1621766714 | ++---------------------+-------------------+ + +# timestamp(3) +mysql> set time_zone = '+0:00'; set @@session.tidb_isolation_read_engines = "tikv"; select c, unix_timestamp(c) from test.t where unix_timestamp(c)='1621770314.192'; ++-------------------------+-------------------+ +| c | unix_timestamp(c) | ++-------------------------+-------------------+ +| 2021-05-23 11:45:14.192 | 1621770314.192 | +| 2021-05-23 11:45:14.192 | 1621770314.192 | ++-------------------------+-------------------+ +mysql> set time_zone = '+0:00'; set @@session.tidb_isolation_read_engines = "tiflash"; select c, unix_timestamp(c) from test.t where unix_timestamp(c)='1621770314.192'; ++-------------------------+-------------------+ +| c | unix_timestamp(c) | ++-------------------------+-------------------+ +| 2021-05-23 11:45:14.192 | 1621770314.192 | +| 2021-05-23 11:45:14.192 | 1621770314.192 | ++-------------------------+-------------------+ +mysql> set time_zone = '+1:00'; set @@session.tidb_isolation_read_engines = "tikv"; select c, unix_timestamp(c) from test.t where unix_timestamp(c)='1621770314.192'; ++-------------------------+-------------------+ +| c | unix_timestamp(c) | ++-------------------------+-------------------+ +| 2021-05-23 12:45:14.192 | 1621770314.192 | +| 2021-05-23 12:45:14.192 | 1621770314.192 | ++-------------------------+-------------------+ +mysql> set time_zone = '+1:00'; set @@session.tidb_isolation_read_engines = "tiflash"; select c, unix_timestamp(c) from test.t where unix_timestamp(c)='1621770314.192'; ++-------------------------+-------------------+ +| c | unix_timestamp(c) | ++-------------------------+-------------------+ +| 2021-05-23 12:45:14.192 | 1621770314.192 | +| 2021-05-23 12:45:14.192 | 1621770314.192 | ++-------------------------+-------------------+ + +# timestamp(6) +mysql> set @@session.tidb_isolation_read_engines = "tikv"; select d, unix_timestamp(d) from test.t where unix_timestamp(d)='1621770314.191981'; ++----------------------------+-------------------+ +| d | unix_timestamp(d) | ++----------------------------+-------------------+ +| 2021-05-23 11:45:14.191981 | 1621770314.191981 | ++----------------------------+-------------------+ +mysql> set @@session.tidb_isolation_read_engines = "tiflash";select d, unix_timestamp(d) from test.t where unix_timestamp(d)='1621770314.191981'; ++----------------------------+-------------------+ +| d | unix_timestamp(d) | ++----------------------------+-------------------+ +| 2021-05-23 11:45:14.191981 | 1621770314.191981 | ++----------------------------+-------------------+ + +mysql> set @@session.tidb_isolation_read_engines = "tikv"; select d, unix_timestamp(d) from test.t where unix_timestamp(d)=1621770314.192000; ++----------------------------+-------------------+ +| d | unix_timestamp(d) | ++----------------------------+-------------------+ +| 2021-05-23 11:45:14.192000 | 1621770314.192000 | ++----------------------------+-------------------+ +mysql> set @@session.tidb_isolation_read_engines = "tiflash";select d, unix_timestamp(d) from test.t where unix_timestamp(d)=1621770314.192000; ++----------------------------+-------------------+ +| d | unix_timestamp(d) | ++----------------------------+-------------------+ +| 2021-05-23 11:45:14.192000 | 1621770314.192000 | ++----------------------------+-------------------+ + +mysql> set @@session.tidb_isolation_read_engines = "tikv"; select d, unix_timestamp(d) from test.t where unix_timestamp(d)=1621770314; ++----------------------------+-------------------+ +| d | unix_timestamp(d) | ++----------------------------+-------------------+ +| 2021-05-23 11:45:14.000000 | 1621770314.000000 | ++----------------------------+-------------------+ +mysql> set @@session.tidb_isolation_read_engines = "tiflash";select d, unix_timestamp(d) from test.t where unix_timestamp(d)=1621770314; ++----------------------------+-------------------+ +| d | unix_timestamp(d) | ++----------------------------+-------------------+ +| 2021-05-23 11:45:14.000000 | 1621770314.000000 | ++----------------------------+-------------------+