Skip to content

Commit

Permalink
Push down ADDDATE(), DATE_ADD() on String, Real types (pingcap#2454)
Browse files Browse the repository at this point in the history
  • Loading branch information
mengxin9014 authored and JaySon-Huang committed Aug 5, 2021
1 parent e69ce97 commit 09d0aa0
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 2 deletions.
7 changes: 7 additions & 0 deletions dbms/src/Flash/Coprocessor/DAGExpressionAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,13 @@ static String buildDateAddOrSubFunction(DAGExpressionAnalyzer * analyzer, const
arg_names.push_back(delta_column);
delta_column = analyzer->applyFunction("toInt64OrNull", arg_names, actions, nullptr);
}
else if (!delta_column_type->isInteger())
{
// convert to integer
Names arg_names;
arg_names.push_back(delta_column);
delta_column = analyzer->applyFunction("round", arg_names, actions, nullptr);
}
Names argument_names;
argument_names.push_back(date_column);
argument_names.push_back(delta_column);
Expand Down
2 changes: 1 addition & 1 deletion dbms/src/Flash/Coprocessor/DAGUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ std::unordered_map<tipb::ScalarFuncSig, String> scalar_func_map({
//{tipb::ScalarFuncSig::SubDateDurationInt, "cast"},
//{tipb::ScalarFuncSig::SubDateDatetimeReal, "cast"},
//{tipb::ScalarFuncSig::SubDateDatetimeDecimal, "cast"},
//{tipb::ScalarFuncSig::AddDateStringReal, "cast"},
{tipb::ScalarFuncSig::AddDateStringReal, "date_add"},
//{tipb::ScalarFuncSig::AddDateIntReal, "cast"},
//{tipb::ScalarFuncSig::AddDateIntDecimal, "cast"},
//{tipb::ScalarFuncSig::AddDateDatetimeReal, "cast"},
Expand Down
2 changes: 1 addition & 1 deletion dbms/src/Functions/FunctionsDateTime.h
Original file line number Diff line number Diff line change
Expand Up @@ -1169,7 +1169,7 @@ struct DateTimeAddIntervalImpl
const IColumn & delta_column = *block.getByPosition(arguments[1]).column;

if (const auto * delta_const_column = typeid_cast<const ColumnConst *>(&delta_column))
Op::vector_constant(sources->getData(), col_to->getData(), delta_const_column->getField().get<Int64>(), time_zone);
Op::vector_constant(sources->getData(), col_to->getData(), delta_const_column->getInt(0), time_zone);
else
Op::vector_vector(sources->getData(), col_to->getData(), delta_column, time_zone);

Expand Down
161 changes: 161 additions & 0 deletions tests/fullstack-test/expr/adddate_string_real.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
mysql> drop table if exists test.t
mysql> create table if not exists test.t(col_date date, col_string char(10), col_real double, unit char(10))

mysql> insert into test.t values('2006-10-11', '2006-10-10', 1.2, 'DAY'),('2019-03-27', '2019-03-26', 1.6, 'DAY'),('2006-10-09', '2006-10-10', -1.2, 'DAY'),('2019-03-25', '2019-03-26', -1.6, 'DAY');
mysql> insert into test.t values('2000-03-01', '2000-02-28', 1.2, 'DAYLEAP'),('2000-03-01', '2000-02-28', 1.6, 'DAYLEAP'),('2000-03-01', '2000-03-02', -1.2, 'DAYLEAP'),('2000-03-01', '2000-03-02', -1.6, 'DAYLEAP');
mysql> insert into test.t values('2006-10-17', '2006-10-10', 1.2, 'WEEK'),('2019-04-02', '2019-03-26', 1.6, 'WEEK'),('2006-10-03', '2006-10-10', -1.2, 'WEEK'),('2019-03-19', '2019-03-26', -1.6, 'WEEK');
mysql> insert into test.t values('2006-11-10', '2006-10-10', 1.2, 'MONTH'),('2019-04-26', '2019-03-26', 1.6, 'MONTH'),('2006-09-10', '2006-10-10', -1.2, 'MONTH'),('2019-02-26', '2019-03-26', -1.6, 'MONTH');
mysql> insert into test.t values('2007-10-10', '2006-10-10', 1.2, 'YEAR'),('2020-03-26', '2019-03-26', 1.6, 'YEAR'),('2005-10-10', '2006-10-10', -1.2, 'YEAR'),('2018-03-26', '2019-03-26', -1.6, 'YEAR');
mysql> insert into test.t values('2006-10-11', '2006-10-10', 1.2, 'HOUR'),('2019-03-27', '2019-03-26', 1.6, 'HOUR'),('2006-10-09', '2006-10-10', -1.2, 'HOUR'),('2019-03-25', '2019-03-26', -1.6, 'HOUR');
mysql> insert into test.t values('2006-10-11', '2006-10-10', 1.2, 'MINUTE'),('2019-03-27', '2019-03-26', 1.6, 'MINUTE'),('2006-10-09', '2006-10-10', -1.2, 'MINUTE'),('2019-03-25', '2019-03-26', -1.6, 'MINUTE');

mysql> alter table test.t set tiflash replica 1

func> wait_table test t

mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date > ADDDATE(col_string, col_real) and unit = 'DAYLEAP'
+------------+------------+----------+---------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+---------+
| 2000-03-01 | 2000-02-28 | 1.2 | DAYLEAP |
| 2000-03-01 | 2000-03-02 | -1.6 | DAYLEAP |
+------------+------------+----------+---------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date = ADDDATE(col_string, col_real) and unit = 'DAYLEAP'
+------------+------------+----------+---------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+---------+
| 2000-03-01 | 2000-02-28 | 1.6 | DAYLEAP |
| 2000-03-01 | 2000-03-02 | -1.2 | DAYLEAP |
+------------+------------+----------+---------+

mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date < ADDDATE(col_string, col_real) and unit = 'DAY'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2019-03-27 | 2019-03-26 | 1.6 | DAY |
+------------+------------+----------+------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date = ADDDATE(col_string, col_real) and unit = 'DAY'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2006-10-11 | 2006-10-10 | 1.2 | DAY |
| 2006-10-09 | 2006-10-10 | -1.2 | DAY |
+------------+------------+----------+------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date > ADDDATE(col_string, col_real) and unit = 'DAY'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2019-03-25 | 2019-03-26 | -1.6 | DAY |
+------------+------------+----------+------+

mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date < DATE_ADD(col_string, INTERVAL col_real DAY) and unit = 'DAY'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2019-03-27 | 2019-03-26 | 1.6 | DAY |
+------------+------------+----------+------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date = DATE_ADD(col_string, INTERVAL col_real DAY) and unit = 'DAY'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2006-10-11 | 2006-10-10 | 1.2 | DAY |
| 2006-10-09 | 2006-10-10 | -1.2 | DAY |
+------------+------------+----------+------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date > DATE_ADD(col_string, INTERVAL col_real DAY) and unit = 'DAY'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2019-03-25 | 2019-03-26 | -1.6 | DAY |
+------------+------------+----------+------+

mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date < DATE_ADD(col_string, INTERVAL col_real week) and unit = 'WEEK'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2019-04-02 | 2019-03-26 | 1.6 | WEEK |
+------------+------------+----------+------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date = DATE_ADD(col_string, INTERVAL col_real week) and unit = 'WEEK'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2006-10-17 | 2006-10-10 | 1.2 | WEEK |
| 2006-10-03 | 2006-10-10 | -1.2 | WEEK |
+------------+------------+----------+------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date > DATE_ADD(col_string, INTERVAL col_real week) and unit = 'WEEK'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2019-03-19 | 2019-03-26 | -1.6 | WEEK |
+------------+------------+----------+------+

mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date < DATE_ADD(col_string, INTERVAL col_real month) and unit = 'MONTH'
+------------+------------+----------+-------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+-------+
| 2019-04-26 | 2019-03-26 | 1.6 | MONTH |
+------------+------------+----------+-------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date = DATE_ADD(col_string, INTERVAL col_real month) and unit = 'MONTH'
+------------+------------+----------+-------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+-------+
| 2006-11-10 | 2006-10-10 | 1.2 | MONTH |
| 2006-09-10 | 2006-10-10 | -1.2 | MONTH |
+------------+------------+----------+-------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date > DATE_ADD(col_string, INTERVAL col_real month) and unit = 'MONTH'
+------------+------------+----------+-------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+-------+
| 2019-02-26 | 2019-03-26 | -1.6 | MONTH |
+------------+------------+----------+-------+

mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date < DATE_ADD(col_string, INTERVAL col_real year) and unit = 'YEAR'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2020-03-26 | 2019-03-26 | 1.6 | YEAR |
+------------+------------+----------+------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date = DATE_ADD(col_string, INTERVAL col_real year) and unit = 'YEAR'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2007-10-10 | 2006-10-10 | 1.2 | YEAR |
| 2005-10-10 | 2006-10-10 | -1.2 | YEAR |
+------------+------------+----------+------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date > DATE_ADD(col_string, INTERVAL col_real year) and unit = 'YEAR'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2018-03-26 | 2019-03-26 | -1.6 | YEAR |
+------------+------------+----------+------+

mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date = DATE_ADD(col_string, INTERVAL cast(23.6 as double) hour) and unit = 'HOUR'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2006-10-11 | 2006-10-10 | 1.2 | HOUR |
| 2019-03-27 | 2019-03-26 | 1.6 | HOUR |
+------------+------------+----------+------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date = DATE_ADD(col_string, INTERVAL cast(-23.6 as double) hour) and unit = 'HOUR'
+------------+------------+----------+------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+------+
| 2006-10-09 | 2006-10-10 | -1.2 | HOUR |
| 2019-03-25 | 2019-03-26 | -1.6 | HOUR |
+------------+------------+----------+------+

mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date = DATE_ADD(col_string, INTERVAL cast(1439.6 as double) minute) and unit = 'MINUTE'
+------------+------------+----------+--------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+--------+
| 2006-10-11 | 2006-10-10 | 1.2 | MINUTE |
| 2019-03-27 | 2019-03-26 | 1.6 | MINUTE |
+------------+------------+----------+--------+
mysql> set @@tidb_isolation_read_engines='tiflash'; select * from test.t where col_date = DATE_ADD(col_string, INTERVAL cast(-1439.6 as double) minute) and unit = 'MINUTE'
+------------+------------+----------+--------+
| col_date | col_string | col_real | unit |
+------------+------------+----------+--------+
| 2006-10-09 | 2006-10-10 | -1.2 | MINUTE |
| 2019-03-25 | 2019-03-26 | -1.6 | MINUTE |
+------------+------------+----------+--------+

mysql> drop table if exists test.t

0 comments on commit 09d0aa0

Please sign in to comment.