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

expression: implement castTimeAsDuration function pushdown #37036

Merged
merged 12 commits into from
Aug 15, 2022
5 changes: 5 additions & 0 deletions expression/expr_to_pb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,11 @@ func TestExprPushDownToFlash(t *testing.T) {
require.NoError(t, err)
exprs = append(exprs, function)

// CastTimeAsDuration
function, err = NewFunction(mock.NewContext(), ast.Cast, types.NewFieldType(mysql.TypeDatetime), durationColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// Substring2ArgsUTF8
function, err = NewFunction(mock.NewContext(), ast.Substr, types.NewFieldType(mysql.TypeString), stringColumn, intColumn)
require.NoError(t, err)
Expand Down
2 changes: 2 additions & 0 deletions expression/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,8 @@ func scalarExprSupportedByFlash(function *ScalarFunction) bool {
tipb.ScalarFuncSig_CastStringAsTime /*, tipb.ScalarFuncSig_CastDurationAsTime, tipb.ScalarFuncSig_CastJsonAsTime*/ :
// ban the function of casting year type as time type pushing down to tiflash because of https://github.com/pingcap/tidb/issues/26215
return function.GetArgs()[0].GetType().GetType() != mysql.TypeYear
case tipb.ScalarFuncSig_CastTimeAsDuration:
return retType.GetType() == mysql.TypeDuration
}
case ast.DateAdd, ast.AddDate:
switch function.Function.PbCode() {
Expand Down
37 changes: 37 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7092,3 +7092,40 @@ func TestEltPushDownToTiFlash(t *testing.T) {
}
tk.MustQuery("explain select elt(a, b) from t;").CheckAt([]int{0, 2, 4}, rows)
}

func TestCastTimeAsDurationToTiFlash(t *testing.T) {
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a date, b datetime(4))")
tk.MustExec("insert into t values('2021-10-26', '2021-10-26')")
tk.MustExec("insert into t values('2021-10-26', '2021-10-26 11:11:11')")
tk.MustExec("insert into t values('2021-10-26', '2021-10-26 11:11:11.111111')")
tk.MustExec("insert into t values('2021-10-26', '2021-10-26 11:11:11.123456')")
tk.MustExec("insert into t values('2021-10-26', '2021-10-26 11:11:11.999999')")

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.
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", "root", "data:ExchangeSender_8"},
{"└─ExchangeSender_8", "mpp[tiflash]", "ExchangeType: PassThrough"},
{" └─Projection_4", "mpp[tiflash]", " cast(test.t.a, time BINARY)->Column#4, cast(test.t.b, time BINARY)->Column#5"},
{" └─TableFullScan_7", "mpp[tiflash]", "keep order:false, stats:pseudo"},
}
tk.MustQuery("explain select cast(a as time), cast(b as time) from t;").CheckAt([]int{0, 2, 4}, rows)
}