diff --git a/expression/expr_to_pb_test.go b/expression/expr_to_pb_test.go index 4baf924a1b4ff..7a6459fb1a091 100644 --- a/expression/expr_to_pb_test.go +++ b/expression/expr_to_pb_test.go @@ -522,6 +522,7 @@ func TestExprPushDownToFlash(t *testing.T) { int32Column := genColumn(mysql.TypeLong, 8) float32Column := genColumn(mysql.TypeFloat, 9) enumColumn := genColumn(mysql.TypeEnum, 10) + durationColumn := genColumn(mysql.TypeDuration, 11) function, err := NewFunction(mock.NewContext(), ast.JSONLength, types.NewFieldType(mysql.TypeLonglong), jsonColumn) require.NoError(t, err) @@ -1125,6 +1126,11 @@ func TestExprPushDownToFlash(t *testing.T) { require.NoError(t, err) exprs = append(exprs, function) + // TimeToSec + function, err = NewFunction(mock.NewContext(), ast.TimeToSec, types.NewFieldType(mysql.TypeDuration), durationColumn) + require.NoError(t, err) + exprs = append(exprs, function) + pushed, remained = PushDownExprs(sc, exprs, client, kv.TiFlash) require.Len(t, pushed, len(exprs)) require.Len(t, remained, 0) diff --git a/expression/expression.go b/expression/expression.go index 9965ce0a7cecc..0709acae46a57 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -1059,7 +1059,8 @@ func scalarExprSupportedByFlash(function *ScalarFunction) bool { ast.InetNtoa, ast.InetAton, ast.Inet6Ntoa, ast.Inet6Aton, ast.Coalesce, ast.ASCII, ast.Length, ast.Trim, ast.Position, ast.Format, ast.LTrim, ast.RTrim, ast.Lpad, ast.Rpad, ast.Regexp, - ast.Hour, ast.Minute, ast.Second, ast.MicroSecond: + ast.Hour, ast.Minute, ast.Second, ast.MicroSecond, + ast.TimeToSec: switch function.Function.PbCode() { case tipb.ScalarFuncSig_InDuration, tipb.ScalarFuncSig_CoalesceDuration, diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index 63e9d118507a3..a55acf9f5d89f 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -2726,6 +2726,41 @@ func TestIssue18984(t *testing.T) { "3 3 3 2 4 3 5")) } +func TestTimeToSecPushDownToTiFlash(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a time(4))") + tk.MustExec("insert into t values('700:10:10.123456')") + tk.MustExec("insert into t values('20:20:20')") + tk.MustExec("set @@tidb_allow_mpp=1; set @@tidb_enforce_mpp=1") + tk.MustExec("set @@tidb_isolation_read_engines = 'tiflash'") + + // Create virtual tiflash replica info. + dom := domain.GetDomain(tk.Session()) + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + require.True(t, exists) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + + rows := [][]interface{}{ + {"TableReader_9", "10000.00", "root", " data:ExchangeSender_8"}, + {"└─ExchangeSender_8", "10000.00", "mpp[tiflash]", " ExchangeType: PassThrough"}, + {" └─Projection_4", "10000.00", "mpp[tiflash]", " time_to_sec(test.t.a)->Column#3"}, + {" └─TableFullScan_7", "10000.00", "mpp[tiflash]", "table:t", "keep order:false, stats:pseudo"}, + } + tk.MustQuery("explain select time_to_sec(a) from t;").Check(rows) +} + func TestBitColumnPushDown(t *testing.T) { store, clean := testkit.CreateMockStore(t) defer clean()