Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support CastTimeAsDuration in TiFlash #5548

Merged
merged 23 commits into from
Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a62cfb0
fix typo:change \'<\' to \'>\'
AntiTopQuark Aug 6, 2022
9bf24a3
feat: support CastTimeAsDuration in TiFlash
AntiTopQuark Aug 6, 2022
e6765ac
fix typo: add \'tidb_\' prefix
AntiTopQuark Aug 6, 2022
f4d61aa
add integration-test for cast time as duration
AntiTopQuark Aug 6, 2022
d92f9b9
fix typo: delete unused '-'
AntiTopQuark Aug 6, 2022
b964b23
test: update unittest and integration_test
AntiTopQuark Aug 6, 2022
e1a17ae
test: update integration_test
AntiTopQuark Aug 6, 2022
c6f2fbb
format: format code
AntiTopQuark Aug 6, 2022
edbac27
Merge branch 'master' into master
AntiTopQuark Aug 8, 2022
085c704
feat: support castTimeAsDuration func
AntiTopQuark Aug 9, 2022
ccc41e1
update: support CastTimeAsDuration func
AntiTopQuark Aug 10, 2022
1850afc
update test: support CastTimeAsDuration func
AntiTopQuark Aug 10, 2022
bd312d1
update unittest: format code
AntiTopQuark Aug 10, 2022
9fda534
Merge branch 'master' into master
AntiTopQuark Aug 10, 2022
d8946c4
Merge branch 'master' into master
AntiTopQuark Aug 10, 2022
977ef42
Merge branch 'master' into master
AntiTopQuark Aug 11, 2022
d7aa49b
Merge branch 'master' into master
AntiTopQuark Aug 11, 2022
2a713a1
Merge branch 'master' into master
AntiTopQuark Aug 11, 2022
fcd5834
Merge branch 'master' into master
AntiTopQuark Aug 12, 2022
6757ef8
use ColumnConst to optimize castTimeAsDuration
AntiTopQuark Aug 12, 2022
003009a
Merge branch 'master' into master
AntiTopQuark Aug 15, 2022
35b37a0
Merge branch 'master' into master
ti-chi-bot Aug 15, 2022
a4cb0ca
Merge branch 'master' into master
ti-chi-bot Aug 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dbms/src/Flash/Coprocessor/DAGUtils.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ const std::unordered_map<tipb::ScalarFuncSig, String> scalar_func_map({
{tipb::ScalarFuncSig::CastTimeAsString, "tidb_cast"},
{tipb::ScalarFuncSig::CastTimeAsDecimal, "tidb_cast"},
{tipb::ScalarFuncSig::CastTimeAsTime, "tidb_cast"},
//{tipb::ScalarFuncSig::CastTimeAsDuration, "cast"},
{tipb::ScalarFuncSig::CastTimeAsDuration, "tidb_cast"},
//{tipb::ScalarFuncSig::CastTimeAsJson, "cast"},

//{tipb::ScalarFuncSig::CastDurationAsInt, "cast"},
Expand Down
45 changes: 44 additions & 1 deletion dbms/src/Functions/FunctionsTiDBConversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <Columns/ColumnTuple.h>
#include <Columns/ColumnsCommon.h>
#include <Common/FieldVisitors.h>
#include <Common/MyDuration.h>
#include <Common/MyTime.h>
#include <DataTypes/DataTypeArray.h>
#include <DataTypes/DataTypeDate.h>
Expand Down Expand Up @@ -1558,7 +1559,7 @@ struct TiDBConvertToTime
}
};

/// cast duration as duration
/// cast time/duration as duration
/// TODO: support more types convert to duration
template <typename FromDataType, typename ToDataType, bool return_nullable>
struct TiDBConvertToDuration
Expand Down Expand Up @@ -1610,6 +1611,48 @@ struct TiDBConvertToDuration
block.getByPosition(result).column = std::move(to_col);
}
}
else if constexpr (std::is_same_v<FromDataType, DataTypeMyDate>)
{
// cast date as duration
auto to_col = ColumnVector<Int64>::create();
auto & vec_to = to_col->getData();
vec_to.resize(size);
for (size_t i = 0; i < size; ++i)
{
vec_to[i] = 0; // The DATE type is used for values with a date part but no time part. The value of Duration is always zero.
}
block.getByPosition(result).column = std::move(to_col);
}
else if constexpr (std::is_same_v<FromDataType, DataTypeMyDateTime>)
{
// cast time as duration
const auto * col_from = checkAndGetColumn<ColumnUInt64>(block.getByPosition(arguments[0]).column.get());
const ColumnUInt64::Container & from_vec = col_from->getData();
const auto & col_with_type_and_name = block.getByPosition(arguments[0]);
const auto & from_type = static_cast<const DataTypeMyDateTime &>(*col_with_type_and_name.type);
int from_fsp = from_type.getFraction();

auto to_col = ColumnVector<Int64>::create();
auto & vec_to = to_col->getData();
vec_to.resize(size);
const auto & to_type = checkAndGetDataType<DataTypeMyDuration>(removeNullable(block.getByPosition(result).type).get());
int to_fsp = to_type->getFsp();

for (size_t i = 0; i < size; ++i)
{
MyDateTime datetime(from_vec[i]);
MyDuration duration(1 /*neg*/, datetime.hour, datetime.minute, datetime.second, datetime.micro_second, from_fsp);
if (to_fsp < from_fsp)
{
vec_to[i] = round(duration.nanoSecond(), (6 - to_fsp) + 3);
}
else
{
vec_to[i] = duration.nanoSecond();
}
}
block.getByPosition(result).column = std::move(to_col);
}
else
{
throw Exception(
Expand Down
60 changes: 59 additions & 1 deletion dbms/src/Functions/tests/gtest_tidb_conversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1296,7 +1296,7 @@ try
const auto from_type = std::make_shared<DataTypeMyDuration>(3);
const auto to_type_1 = std::make_shared<DataTypeMyDuration>(5); // from_fsp < to_fsp
const auto to_type_2 = std::make_shared<DataTypeMyDuration>(3); // from_fsp == to_fsp
const auto to_type_3 = std::make_shared<DataTypeMyDuration>(2); // from_fsp < to_fsp
const auto to_type_3 = std::make_shared<DataTypeMyDuration>(2); // from_fsp > to_fsp

ColumnWithTypeAndName input(
createColumn<DataTypeMyDuration::FieldType>({(20 * 3600 + 20 * 60 + 20) * 1000000000L + 555000000L,
Expand Down Expand Up @@ -1749,5 +1749,63 @@ try
}
CATCH

TEST_F(TestTidbConversion, castTimeAsDuration)
try
{
const auto to_type_1 = std::make_shared<DataTypeMyDuration>(5); // from_fsp < to_fsp
const auto to_type_2 = std::make_shared<DataTypeMyDuration>(4); // from_fsp == to_fsp
const auto to_type_3 = std::make_shared<DataTypeMyDuration>(2); // from_fsp > to_fsp
// cast datetime to duration
const auto datetime_type_ptr = std::make_shared<DataTypeMyDateTime>(4);
MyDateTime date(2021, 10, 26, 0, 0, 0, 0);
MyDateTime datetime(2021, 10, 26, 11, 11, 11, 0);
MyDateTime datetime_frac1(2021, 10, 26, 11, 11, 11, 111111);
MyDateTime datetime_frac2(2021, 10, 26, 11, 11, 11, 123456);
MyDateTime datetime_frac3(2021, 10, 26, 11, 11, 11, 999999);

auto col_datetime = ColumnUInt64::create();
col_datetime->insert(Field(date.toPackedUInt()));
col_datetime->insert(Field(datetime.toPackedUInt()));
col_datetime->insert(Field(datetime_frac1.toPackedUInt()));
col_datetime->insert(Field(datetime_frac2.toPackedUInt()));
col_datetime->insert(Field(datetime_frac3.toPackedUInt()));

auto ctn_datetime = ColumnWithTypeAndName(std::move(col_datetime), datetime_type_ptr, "datetime");
ColumnWithTypeAndName datetime_output1(
createColumn<DataTypeMyDuration::FieldType>({(0 * 3600 + 0 * 60 + 0) * 1000000000L + 000000000L,
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 000000000L,
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 111100000L,
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 123500000L,
(11 * 3600 + 11 * 60 + 12) * 1000000000L + 00000000L})
.column,
to_type_1,
"datetime_output1");
ColumnWithTypeAndName datetime_output2(
createColumn<DataTypeMyDuration::FieldType>({(0 * 3600 + 0 * 60 + 0) * 1000000000L + 000000000L,
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 000000000L,
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 111100000L,
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 123500000L,
(11 * 3600 + 11 * 60 + 12) * 1000000000L + 000000000L})
.column,
to_type_2,
"datetime_output2");

ColumnWithTypeAndName datetime_output3(
createColumn<DataTypeMyDuration::FieldType>({(0 * 3600 + 0 * 60 + 0) * 1000000000L + 000000000L,
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 000000000L,
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 110000000L,
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 120000000L,
(11 * 3600 + 11 * 60 + 12) * 1000000000L + 000000000L})
.column,
to_type_3,
"datetime_output3");


// ASSERT_COLUMN_EQ(datetime_output1, executeFunction(func_name, {ctn_datetime, createCastTypeConstColumn(to_type_1->getName())}));
// ASSERT_COLUMN_EQ(datetime_output2, executeFunction(func_name, {ctn_datetime, createCastTypeConstColumn(to_type_2->getName())}));
ASSERT_COLUMN_EQ(datetime_output3, executeFunction(func_name, {ctn_datetime, createCastTypeConstColumn(to_type_3->getName())}));
}
CATCH

} // namespace
} // namespace DB::tests
88 changes: 88 additions & 0 deletions tests/fullstack-test/expr/cast_as_duration.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Copyright 2022 PingCAP, Ltd.
#
# Licensed 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.


mysql> drop table if exists test.t;
mysql> create table test.t(c1 date, c2 datetime(4));
mysql> insert into test.t values('2022-01-01','2022-09-20 11:11:11.0000');
mysql> insert into test.t values('2022-01-01','2022-09-20 11:11:11.1111');
mysql> insert into test.t values('2022-01-01','2022-09-20 11:11:11.1234');
mysql> insert into test.t values('2022-01-01','2022-09-20 11:11:11.1255');
mysql> insert into test.t values('2022-01-01','2022-09-20 11:11:11.9999');

mysql> alter table test.t set tiflash replica 1;

func> wait_table test t

mysql> set @@tidb_isolation_read_engines='tiflash'; set @@tidb_enforce_mpp = 1; select cast(test.t.c1 as time(2)) from test.t;
+----------------------------+
| cast(test.t.c1 as time(2)) |
+----------------------------+
| 00:00:00.00 |
| 00:00:00.00 |
| 00:00:00.00 |
| 00:00:00.00 |
| 00:00:00.00 |
+----------------------------+
mysql> set @@tidb_isolation_read_engines='tiflash'; set @@tidb_enforce_mpp = 1; select cast(test.t.c1 as time(4)) from test.t;
+----------------------------+
| cast(test.t.c1 as time(4)) |
+----------------------------+
| 00:00:00.0000 |
| 00:00:00.0000 |
| 00:00:00.0000 |
| 00:00:00.0000 |
| 00:00:00.0000 |
+----------------------------+
mysql> set @@tidb_isolation_read_engines='tiflash'; set @@tidb_enforce_mpp = 1; select cast(test.t.c1 as time(5)) from test.t;
+----------------------------+
| cast(test.t.c1 as time(5)) |
+----------------------------+
| 00:00:00.00000 |
| 00:00:00.00000 |
| 00:00:00.00000 |
| 00:00:00.00000 |
| 00:00:00.00000 |
+----------------------------+
mysql> set @@tidb_isolation_read_engines='tiflash'; set @@tidb_enforce_mpp = 1; select cast(test.t.c2 as time(2)) from test.t;
+----------------------------+
| cast(test.t.c2 as time(2)) |
+----------------------------+
| 11:11:11.00 |
| 11:11:11.11 |
| 11:11:11.12 |
| 11:11:11.13 |
| 11:11:12.00 |
+----------------------------+
mysql> set @@tidb_isolation_read_engines='tiflash'; set @@tidb_enforce_mpp = 1; select cast(test.t.c2 as time(4)) from test.t;
+----------------------------+
| cast(test.t.c2 as time(4)) |
+----------------------------+
| 11:11:11.0000 |
| 11:11:11.1111 |
| 11:11:11.1234 |
| 11:11:11.1255 |
| 11:11:11.9999 |
+----------------------------+
mysql> set @@tidb_isolation_read_engines='tiflash'; set @@tidb_enforce_mpp = 1; select cast(test.t.c2 as time(5)) from test.t;
+----------------------------+
| cast(test.t.c2 as time(5)) |
+----------------------------+
| 11:11:11.00000 |
| 11:11:11.11110 |
| 11:11:11.12340 |
| 11:11:11.12550 |
| 11:11:11.99990 |
+----------------------------+
mysql> drop table if exists test.t;