Skip to content

Commit

Permalink
Merge branch 'master' into qualified_table_column_in_test
Browse files Browse the repository at this point in the history
  • Loading branch information
ywqzzy authored Aug 16, 2022
2 parents f6bd9ef + 577aada commit ebe80cd
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 7 deletions.
2 changes: 1 addition & 1 deletion dbms/src/DataStreams/IProfilingBlockInputStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class IProfilingBlockInputStream : public IBlockInputStream

Block read() override final;

Block read(FilterPtr & res_filter, bool return_filter) override final;
Block read(FilterPtr & res_filter, bool return_filter) override;

/** The default implementation calls readPrefixImpl() on itself, and then readPrefix() recursively for all children.
* There are cases when you do not want `readPrefix` of children to be called synchronously, in this function,
Expand Down
9 changes: 8 additions & 1 deletion dbms/src/DataStreams/SharedQueryBlockInputStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ class SharedQueryBlockInputStream : public IProfilingBlockInputStream
}

protected:
Block readImpl() override
/// The BlockStreamProfileInfo of SharedQuery is useless,
/// and it will trigger tsan UT fail because of data race.
/// So overriding method `read` here.
Block read(FilterPtr &, bool) override
{
std::unique_lock lock(mutex);

Expand All @@ -134,6 +137,10 @@ class SharedQueryBlockInputStream : public IProfilingBlockInputStream

return block;
}
Block readImpl() override
{
throw Exception("Unsupport");
}

void fetchBlocks()
{
Expand Down
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
38 changes: 37 additions & 1 deletion dbms/src/Functions/FunctionsTiDBConversion.h
100644 → 100755
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 @@ -1549,7 +1550,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 @@ -1601,6 +1602,41 @@ struct TiDBConvertToDuration
block.getByPosition(result).column = std::move(to_col);
}
}
else if constexpr (std::is_same_v<FromDataType, DataTypeMyDate>)
{
// cast date as duration
const auto & to_type = checkAndGetDataType<DataTypeMyDuration>(removeNullable(block.getByPosition(result).type).get());
block.getByPosition(result).column = to_type->createColumnConst(size, toField(0)); // The DATE type is used for values with a date part but no time part. The value of Duration is always zero.
}
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 & from_type = checkAndGetDataType<DataTypeMyDateTime>(block.getByPosition(arguments[0]).type.get());
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
113 changes: 112 additions & 1 deletion dbms/src/Functions/tests/gtest_tidb_conversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1313,7 +1313,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 @@ -1766,5 +1766,116 @@ 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, 111100);
MyDateTime datetime_frac2(2021, 10, 26, 11, 11, 11, 123500);
MyDateTime datetime_frac3(2021, 10, 26, 11, 11, 11, 999900);

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 + 11) * 1000000000L + 999900000L})
.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 + 11) * 1000000000L + 999900000L})
.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())}));


// Test Const
ColumnWithTypeAndName input_const(createConstColumn<DataTypeMyDateTime::FieldType>(1, datetime_frac2.toPackedUInt()).column, datetime_type_ptr, "input_const");
ColumnWithTypeAndName output1_const(createConstColumn<DataTypeMyDuration::FieldType>(1, (11 * 3600 + 11 * 60 + 11) * 1000000000L + 123500000L).column, to_type_1, "output1_const");
ColumnWithTypeAndName output2_const(createConstColumn<DataTypeMyDuration::FieldType>(1, (11 * 3600 + 11 * 60 + 11) * 1000000000L + 123500000L).column, to_type_2, "output2_const");
ColumnWithTypeAndName output3_const(createConstColumn<DataTypeMyDuration::FieldType>(1, (11 * 3600 + 11 * 60 + 11) * 1000000000L + 120000000L).column, to_type_3, "output3_const");

ASSERT_COLUMN_EQ(output1_const, executeFunction(func_name, {input_const, createCastTypeConstColumn(to_type_1->getName())}));
ASSERT_COLUMN_EQ(output2_const, executeFunction(func_name, {input_const, createCastTypeConstColumn(to_type_2->getName())}));
ASSERT_COLUMN_EQ(output3_const, executeFunction(func_name, {input_const, createCastTypeConstColumn(to_type_3->getName())}));

// Test Nullable
ColumnWithTypeAndName input_nullable(
createColumn<Nullable<DataTypeMyDateTime::FieldType>>({datetime_frac1.toPackedUInt(),
{},
datetime_frac2.toPackedUInt(),
{},
datetime_frac3.toPackedUInt()})
.column,
makeNullable(datetime_type_ptr),
"input_nullable");
ColumnWithTypeAndName output1_nullable(
createColumn<Nullable<DataTypeMyDuration::FieldType>>({(11 * 3600 + 11 * 60 + 11) * 1000000000L + 111100000L,
{},
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 123500000L,
{},
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 999900000L})
.column,
makeNullable(to_type_1),
"output1_output");
ColumnWithTypeAndName output2_nullable(
createColumn<Nullable<DataTypeMyDuration::FieldType>>({(11 * 3600 + 11 * 60 + 11) * 1000000000L + 111100000L,
{},
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 123500000L,
{},
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 999900000L})
.column,
makeNullable(to_type_2),
"output2_output");
ColumnWithTypeAndName output3_nullable(
createColumn<Nullable<DataTypeMyDuration::FieldType>>({(11 * 3600 + 11 * 60 + 11) * 1000000000L + 110000000L,
{},
(11 * 3600 + 11 * 60 + 11) * 1000000000L + 120000000L,
{},
(11 * 3600 + 11 * 60 + 12) * 1000000000L + 000000000L})
.column,
makeNullable(to_type_3),
"output3_output");

ASSERT_COLUMN_EQ(output1_nullable, executeFunction(func_name, {input_nullable, createCastTypeConstColumn(makeNullable(to_type_1)->getName())}));
ASSERT_COLUMN_EQ(output2_nullable, executeFunction(func_name, {input_nullable, createCastTypeConstColumn(makeNullable(to_type_2)->getName())}));
ASSERT_COLUMN_EQ(output3_nullable, executeFunction(func_name, {input_nullable, createCastTypeConstColumn(makeNullable(to_type_3)->getName())}));
}
CATCH

} // namespace
} // namespace DB::tests
95 changes: 95 additions & 0 deletions tests/fullstack-test/expr/cast_as_duration.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# 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> insert into test.t values(null,null);

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 |
| NULL |
+----------------------------+
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 |
| NULL |
+----------------------------+
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 |
| NULL |
+----------------------------+
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 |
| NULL |
+----------------------------+
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 |
| NULL |
+----------------------------+
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 |
| NULL |
+----------------------------+
mysql> drop table if exists test.t;
1 change: 0 additions & 1 deletion tests/sanitize/tsan.suppression
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
race:dbms/src/Common/TiFlashMetrics.h
race:dbms/src/DataStreams/BlockStreamProfileInfo.h

0 comments on commit ebe80cd

Please sign in to comment.