From ca24807b3894646c9e8b6bb41bd84bfa7f0cfe7f Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Tue, 14 Feb 2023 11:49:36 +0800 Subject: [PATCH 01/10] add more checks when pushing TopN down --- planner/core/integration_test.go | 10 ++++++ planner/core/task.go | 60 ++++++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index f6cce8454e945..03cdc6ebe25b0 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -8431,3 +8431,13 @@ func TestIssue40285(t *testing.T) { tk.MustExec("CREATE TABLE t(col1 enum('p5', '9a33x') NOT NULL DEFAULT 'p5',col2 tinyblob DEFAULT NULL) ENGINE = InnoDB DEFAULT CHARSET = latin1 COLLATE = latin1_bin;") tk.MustQuery("(select last_value(col1) over () as r0 from t) union all (select col2 as r0 from t);") } + +// https://github.com/pingcap/tidb/issues/41355 +func TestIssue41355(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1; CREATE TABLE `t1` (`c1` varchar(100) DEFAULT NULL, `c2` varchar(100) GENERATED ALWAYS AS (lower(`c1`)) VIRTUAL);") + tk.MustExec("insert into t1(c1) values('a'), ('e'), ('b'), ('c'), ('d'), ('e'), ('x'), ('y'), ('a'), ('b');") + tk.MustQuery("select * from t1 order by c2 limit 2;").Check(testkit.Rows("a a", "a a")) +} diff --git a/planner/core/task.go b/planner/core/task.go index 553bc64b9a6b9..a29d469fc7442 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -895,15 +895,6 @@ func (p *PhysicalLimit) sinkIntoIndexLookUp(t task) bool { return true } -// canPushDown checks if this topN can be pushed down. If each of the expression can be converted to pb, it can be pushed. -func (p *PhysicalTopN) canPushDown(storeTp kv.StoreType) bool { - exprs := make([]expression.Expression, 0, len(p.ByItems)) - for _, item := range p.ByItems { - exprs = append(exprs, item.Expr) - } - return expression.CanExprsPushDown(p.ctx.GetSessionVars().StmtCtx, exprs, p.ctx.GetClient(), storeTp) -} - func (p *PhysicalSort) attach2Task(tasks ...task) task { t := tasks[0].copy() t = attachPlan2Task(p, t) @@ -955,6 +946,53 @@ func (p *PhysicalTopN) canPushToIndexPlan(indexPlan PhysicalPlan, byItemCols []* return true } +// canExpressionConvertedToPB checks whether each of the the expression in TopN can be converted to pb. +func (p *PhysicalTopN) canExpressionConvertedToPB(storeTp kv.StoreType) bool { + exprs := make([]expression.Expression, 0, len(p.ByItems)) + for _, item := range p.ByItems { + exprs = append(exprs, item.Expr) + } + return expression.CanExprsPushDown(p.ctx.GetSessionVars().StmtCtx, exprs, p.ctx.GetClient(), storeTp) +} + +// containVirtualColumn checks whether TopN.ByItems contains virtual generated columns. +func (p *PhysicalTopN) containVirtualColumn(copTask *copTask) bool { + tCols := copTask.tablePlan.Schema().Columns + for _, by := range p.ByItems { + cols := expression.ExtractColumns(by.Expr) + for _, col := range cols { + if col.VirtualExpr != nil { + for _, tCol := range tCols { + // A column with ID > 0 indicates that the column can be resolved by data source. + if tCol.ID > 0 && tCol.ID == col.ID && tCol.VirtualExpr != nil { + return true + } + } + } + } + } + return false +} + +// canPushDownToTiKV checks whether this topN can be pushed down to TiKV. +func (p *PhysicalTopN) canPushDownToTiKV(copTask *copTask) bool { + if !p.canExpressionConvertedToPB(kv.TiKV) { + return false + } + if len(copTask.rootTaskConds) != 0 { + return false + } + if p.containVirtualColumn(copTask) { + return false + } + return true +} + +// canPushDownToTiFlash checks whether this topN can be pushed down to TiFlash. +func (p *PhysicalTopN) canPushDownToTiFlash() bool { + return !p.canExpressionConvertedToPB(kv.TiFlash) +} + func (p *PhysicalTopN) attach2Task(tasks ...task) task { t := tasks[0].copy() cols := make([]*expression.Column, 0, len(p.ByItems)) @@ -962,7 +1000,7 @@ func (p *PhysicalTopN) attach2Task(tasks ...task) task { cols = append(cols, expression.ExtractColumns(item.Expr)...) } needPushDown := len(cols) > 0 - if copTask, ok := t.(*copTask); ok && needPushDown && p.canPushDown(copTask.getStoreType()) && len(copTask.rootTaskConds) == 0 { + if copTask, ok := t.(*copTask); ok && needPushDown && p.canPushDownToTiKV(copTask) { newTask, changed := p.pushTopNDownToDynamicPartition(copTask) if changed { return newTask @@ -978,7 +1016,7 @@ func (p *PhysicalTopN) attach2Task(tasks ...task) task { pushedDownTopN = p.getPushedDownTopN(copTask.tablePlan) copTask.tablePlan = pushedDownTopN } - } else if mppTask, ok := t.(*mppTask); ok && needPushDown && p.canPushDown(kv.TiFlash) { + } else if mppTask, ok := t.(*mppTask); ok && needPushDown && p.canPushDownToTiFlash() { pushedDownTopN := p.getPushedDownTopN(mppTask.p) mppTask.p = pushedDownTopN } From 855cdf5d7e80b56760a5af0704461eb8635b0e75 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Tue, 14 Feb 2023 18:31:41 +0800 Subject: [PATCH 02/10] fix --- planner/core/task.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planner/core/task.go b/planner/core/task.go index a29d469fc7442..3f68e90c9585d 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -990,7 +990,7 @@ func (p *PhysicalTopN) canPushDownToTiKV(copTask *copTask) bool { // canPushDownToTiFlash checks whether this topN can be pushed down to TiFlash. func (p *PhysicalTopN) canPushDownToTiFlash() bool { - return !p.canExpressionConvertedToPB(kv.TiFlash) + return p.canExpressionConvertedToPB(kv.TiFlash) } func (p *PhysicalTopN) attach2Task(tasks ...task) task { From c46454fe5e0a7e6449ae2f62ba560dfc1753b18d Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Wed, 15 Feb 2023 17:12:49 +0800 Subject: [PATCH 03/10] for tiflash --- planner/core/integration_test.go | 30 ++++++++++++++++++++++++++++-- planner/core/task.go | 17 +++++++++++------ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index e2c85f9ffe441..bed907fd45008 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -8453,11 +8453,37 @@ func TestIssue41273(t *testing.T) { require.False(t, tk.HasPlanForLastExecution("IndexMerge")) } +// https://github.com/pingcap/tidb/issues/41355 func TestIssue41355(t *testing.T) { - store := testkit.CreateMockStore(t) + store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") - tk.MustExec("drop table if exists t1; CREATE TABLE `t1` (`c1` varchar(100) DEFAULT NULL, `c2` varchar(100) GENERATED ALWAYS AS (lower(`c1`)) VIRTUAL);") + tk.MustExec("drop table if exists t1") + tk.MustExec("CREATE TABLE `t1` (`c1` varchar(100) DEFAULT NULL, `c2` varchar(100) GENERATED ALWAYS AS (lower(`c1`)) VIRTUAL);") tk.MustExec("insert into t1(c1) values('a'), ('e'), ('b'), ('c'), ('d'), ('e'), ('x'), ('y'), ('a'), ('b');") + + // tikv + tk.MustExec("set @@tidb_isolation_read_engines = 'tikv'") tk.MustQuery("select * from t1 order by c2 limit 2;").Check(testkit.Rows("a a", "a a")) + + // tiflash + tk.MustExec("set @@tidb_allow_mpp=1; set @@tidb_enforce_mpp=1") + tk.MustExec("set @@tidb_isolation_read_engines = 'tiflash'") + is := dom.InfoSchema() + db, exists := is.SchemaByName(model.NewCIStr("test")) + require.True(t, exists) + for _, tblInfo := range db.Tables { + if tblInfo.Name.L == "t1" { + tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ + Count: 1, + Available: true, + } + } + } + rows := [][]interface{}{ + {"TopN_7", "root", "test.t1.c2, offset:0, count:2"}, + {"└─TableReader_15", "root", "data:TableFullScan_14"}, + {" └─TableFullScan_14", "cop[tiflash]", "keep order:false, stats:pseudo"}, + } + tk.MustQuery("explain select * from t1 order by c2 limit 2;").CheckAt([]int{0, 2, 4}, rows) } diff --git a/planner/core/task.go b/planner/core/task.go index 3f68e90c9585d..c4859f59f2991 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -956,8 +956,7 @@ func (p *PhysicalTopN) canExpressionConvertedToPB(storeTp kv.StoreType) bool { } // containVirtualColumn checks whether TopN.ByItems contains virtual generated columns. -func (p *PhysicalTopN) containVirtualColumn(copTask *copTask) bool { - tCols := copTask.tablePlan.Schema().Columns +func (p *PhysicalTopN) containVirtualColumn(tCols []*expression.Column) bool { for _, by := range p.ByItems { cols := expression.ExtractColumns(by.Expr) for _, col := range cols { @@ -982,15 +981,21 @@ func (p *PhysicalTopN) canPushDownToTiKV(copTask *copTask) bool { if len(copTask.rootTaskConds) != 0 { return false } - if p.containVirtualColumn(copTask) { + if p.containVirtualColumn(copTask.plan().Schema().Columns) { return false } return true } // canPushDownToTiFlash checks whether this topN can be pushed down to TiFlash. -func (p *PhysicalTopN) canPushDownToTiFlash() bool { - return p.canExpressionConvertedToPB(kv.TiFlash) +func (p *PhysicalTopN) canPushDownToTiFlash(mppTask *mppTask) bool { + if !p.canExpressionConvertedToPB(kv.TiFlash) { + return false + } + if p.containVirtualColumn(mppTask.plan().Schema().Columns) { + return false + } + return true } func (p *PhysicalTopN) attach2Task(tasks ...task) task { @@ -1016,7 +1021,7 @@ func (p *PhysicalTopN) attach2Task(tasks ...task) task { pushedDownTopN = p.getPushedDownTopN(copTask.tablePlan) copTask.tablePlan = pushedDownTopN } - } else if mppTask, ok := t.(*mppTask); ok && needPushDown && p.canPushDownToTiFlash() { + } else if mppTask, ok := t.(*mppTask); ok && needPushDown && p.canPushDownToTiFlash(mppTask) { pushedDownTopN := p.getPushedDownTopN(mppTask.p) mppTask.p = pushedDownTopN } From 3c030a3f610b0ab32349bb3e57eeb6f7aa8a73b8 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Wed, 15 Feb 2023 17:30:03 +0800 Subject: [PATCH 04/10] remove useless check --- planner/core/task.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planner/core/task.go b/planner/core/task.go index c4859f59f2991..7e5d3c324f373 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -963,7 +963,7 @@ func (p *PhysicalTopN) containVirtualColumn(tCols []*expression.Column) bool { if col.VirtualExpr != nil { for _, tCol := range tCols { // A column with ID > 0 indicates that the column can be resolved by data source. - if tCol.ID > 0 && tCol.ID == col.ID && tCol.VirtualExpr != nil { + if tCol.ID > 0 && tCol.ID == col.ID { return true } } From e57faf936776016a236627e7887c92dd71201e0c Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Wed, 15 Feb 2023 17:42:38 +0800 Subject: [PATCH 05/10] remove useless check --- planner/core/task.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/planner/core/task.go b/planner/core/task.go index 7e5d3c324f373..e134ea13ce346 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -960,12 +960,10 @@ func (p *PhysicalTopN) containVirtualColumn(tCols []*expression.Column) bool { for _, by := range p.ByItems { cols := expression.ExtractColumns(by.Expr) for _, col := range cols { - if col.VirtualExpr != nil { - for _, tCol := range tCols { - // A column with ID > 0 indicates that the column can be resolved by data source. - if tCol.ID > 0 && tCol.ID == col.ID { - return true - } + for _, tCol := range tCols { + // A column with ID > 0 indicates that the column can be resolved by data source. + if tCol.ID > 0 && tCol.ID == col.ID && tCol.VirtualExpr != nil { + return true } } } From 350e4245c18dc46bfac1e8fd6b7768214accd847 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Wed, 15 Feb 2023 19:43:48 +0800 Subject: [PATCH 06/10] simplify --- expression/expr_to_pb.go | 4 ++++ planner/core/task.go | 31 +++---------------------------- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/expression/expr_to_pb.go b/expression/expr_to_pb.go index a9a29868b9283..99c4c2332cb06 100644 --- a/expression/expr_to_pb.go +++ b/expression/expr_to_pb.go @@ -183,6 +183,10 @@ func FieldTypeFromPB(ft *tipb.FieldType) *types.FieldType { } func (pc PbConverter) columnToPBExpr(column *Column) *tipb.Expr { + // virtual generated column, can not support for now. + if column.VirtualExpr != nil { + return nil + } if !pc.client.IsRequestTypeSupported(kv.ReqTypeSelect, int64(tipb.ExprType_ColumnRef)) { return nil } diff --git a/planner/core/task.go b/planner/core/task.go index e134ea13ce346..1e1211824a9c5 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -955,22 +955,6 @@ func (p *PhysicalTopN) canExpressionConvertedToPB(storeTp kv.StoreType) bool { return expression.CanExprsPushDown(p.ctx.GetSessionVars().StmtCtx, exprs, p.ctx.GetClient(), storeTp) } -// containVirtualColumn checks whether TopN.ByItems contains virtual generated columns. -func (p *PhysicalTopN) containVirtualColumn(tCols []*expression.Column) bool { - for _, by := range p.ByItems { - cols := expression.ExtractColumns(by.Expr) - for _, col := range cols { - for _, tCol := range tCols { - // A column with ID > 0 indicates that the column can be resolved by data source. - if tCol.ID > 0 && tCol.ID == col.ID && tCol.VirtualExpr != nil { - return true - } - } - } - } - return false -} - // canPushDownToTiKV checks whether this topN can be pushed down to TiKV. func (p *PhysicalTopN) canPushDownToTiKV(copTask *copTask) bool { if !p.canExpressionConvertedToPB(kv.TiKV) { @@ -979,21 +963,12 @@ func (p *PhysicalTopN) canPushDownToTiKV(copTask *copTask) bool { if len(copTask.rootTaskConds) != 0 { return false } - if p.containVirtualColumn(copTask.plan().Schema().Columns) { - return false - } return true } // canPushDownToTiFlash checks whether this topN can be pushed down to TiFlash. -func (p *PhysicalTopN) canPushDownToTiFlash(mppTask *mppTask) bool { - if !p.canExpressionConvertedToPB(kv.TiFlash) { - return false - } - if p.containVirtualColumn(mppTask.plan().Schema().Columns) { - return false - } - return true +func (p *PhysicalTopN) canPushDownToTiFlash() bool { + return p.canExpressionConvertedToPB(kv.TiFlash) } func (p *PhysicalTopN) attach2Task(tasks ...task) task { @@ -1019,7 +994,7 @@ func (p *PhysicalTopN) attach2Task(tasks ...task) task { pushedDownTopN = p.getPushedDownTopN(copTask.tablePlan) copTask.tablePlan = pushedDownTopN } - } else if mppTask, ok := t.(*mppTask); ok && needPushDown && p.canPushDownToTiFlash(mppTask) { + } else if mppTask, ok := t.(*mppTask); ok && needPushDown && p.canPushDownToTiFlash() { pushedDownTopN := p.getPushedDownTopN(mppTask.p) mppTask.p = pushedDownTopN } From f60473edf72bccf9a5dd16bd6e32d1b3df21b1bf Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Wed, 15 Feb 2023 19:59:35 +0800 Subject: [PATCH 07/10] fix --- expression/expr_to_pb.go | 4 ---- planner/core/task.go | 31 ++++++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/expression/expr_to_pb.go b/expression/expr_to_pb.go index 99c4c2332cb06..a9a29868b9283 100644 --- a/expression/expr_to_pb.go +++ b/expression/expr_to_pb.go @@ -183,10 +183,6 @@ func FieldTypeFromPB(ft *tipb.FieldType) *types.FieldType { } func (pc PbConverter) columnToPBExpr(column *Column) *tipb.Expr { - // virtual generated column, can not support for now. - if column.VirtualExpr != nil { - return nil - } if !pc.client.IsRequestTypeSupported(kv.ReqTypeSelect, int64(tipb.ExprType_ColumnRef)) { return nil } diff --git a/planner/core/task.go b/planner/core/task.go index 1e1211824a9c5..e134ea13ce346 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -955,6 +955,22 @@ func (p *PhysicalTopN) canExpressionConvertedToPB(storeTp kv.StoreType) bool { return expression.CanExprsPushDown(p.ctx.GetSessionVars().StmtCtx, exprs, p.ctx.GetClient(), storeTp) } +// containVirtualColumn checks whether TopN.ByItems contains virtual generated columns. +func (p *PhysicalTopN) containVirtualColumn(tCols []*expression.Column) bool { + for _, by := range p.ByItems { + cols := expression.ExtractColumns(by.Expr) + for _, col := range cols { + for _, tCol := range tCols { + // A column with ID > 0 indicates that the column can be resolved by data source. + if tCol.ID > 0 && tCol.ID == col.ID && tCol.VirtualExpr != nil { + return true + } + } + } + } + return false +} + // canPushDownToTiKV checks whether this topN can be pushed down to TiKV. func (p *PhysicalTopN) canPushDownToTiKV(copTask *copTask) bool { if !p.canExpressionConvertedToPB(kv.TiKV) { @@ -963,12 +979,21 @@ func (p *PhysicalTopN) canPushDownToTiKV(copTask *copTask) bool { if len(copTask.rootTaskConds) != 0 { return false } + if p.containVirtualColumn(copTask.plan().Schema().Columns) { + return false + } return true } // canPushDownToTiFlash checks whether this topN can be pushed down to TiFlash. -func (p *PhysicalTopN) canPushDownToTiFlash() bool { - return p.canExpressionConvertedToPB(kv.TiFlash) +func (p *PhysicalTopN) canPushDownToTiFlash(mppTask *mppTask) bool { + if !p.canExpressionConvertedToPB(kv.TiFlash) { + return false + } + if p.containVirtualColumn(mppTask.plan().Schema().Columns) { + return false + } + return true } func (p *PhysicalTopN) attach2Task(tasks ...task) task { @@ -994,7 +1019,7 @@ func (p *PhysicalTopN) attach2Task(tasks ...task) task { pushedDownTopN = p.getPushedDownTopN(copTask.tablePlan) copTask.tablePlan = pushedDownTopN } - } else if mppTask, ok := t.(*mppTask); ok && needPushDown && p.canPushDownToTiFlash() { + } else if mppTask, ok := t.(*mppTask); ok && needPushDown && p.canPushDownToTiFlash(mppTask) { pushedDownTopN := p.getPushedDownTopN(mppTask.p) mppTask.p = pushedDownTopN } From cc0f6f24069c71a1d80f6bd3a11680862c740071 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Wed, 15 Feb 2023 20:59:43 +0800 Subject: [PATCH 08/10] add more tests --- planner/core/integration_test.go | 70 ++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index bed907fd45008..3e899a3d584b7 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -8454,36 +8454,80 @@ func TestIssue41273(t *testing.T) { } // https://github.com/pingcap/tidb/issues/41355 -func TestIssue41355(t *testing.T) { +// Virtually generated columns push down is not supported now. +// This test covers: TopN, Projection, Selection. +func TestVirtualExprPushDown(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t1") - tk.MustExec("CREATE TABLE `t1` (`c1` varchar(100) DEFAULT NULL, `c2` varchar(100) GENERATED ALWAYS AS (lower(`c1`)) VIRTUAL);") - tk.MustExec("insert into t1(c1) values('a'), ('e'), ('b'), ('c'), ('d'), ('e'), ('x'), ('y'), ('a'), ('b');") - - // tikv + tk.MustExec("use test;") + tk.MustExec("drop table if exists t;") + tk.MustExec("CREATE TABLE t (c1 int DEFAULT 0, c2 int GENERATED ALWAYS AS (abs(c1)) VIRTUAL);") + tk.MustExec("insert into t(c1) values(1), (-1), (2), (-2), (99), (-99);") tk.MustExec("set @@tidb_isolation_read_engines = 'tikv'") - tk.MustQuery("select * from t1 order by c2 limit 2;").Check(testkit.Rows("a a", "a a")) - // tiflash + // TopN to tikv. + rows := [][]interface{}{ + {"TopN_7", "root", "test.t.c2, offset:0, count:2"}, + {"└─TableReader_13", "root", "data:TableFullScan_12"}, + {" └─TableFullScan_12", "cop[tikv]", "keep order:false, stats:pseudo"}, + } + tk.MustQuery("explain select * from t order by c2 limit 2;").CheckAt([]int{0, 2, 4}, rows) + + // Projection to tikv. + rows = [][]interface{}{ + {"Projection_3", "root", "plus(test.t.c1, test.t.c2)->Column#4"}, + {"└─TableReader_5", "root", "data:TableFullScan_4"}, + {" └─TableFullScan_4", "cop[tikv]", "keep order:false, stats:pseudo"}, + } + tk.MustExec("set session tidb_opt_projection_push_down='ON';") + tk.MustQuery("explain select c1 + c2 from t;").CheckAt([]int{0, 2, 4}, rows) + tk.MustExec("set session tidb_opt_projection_push_down='OFF';") + + // Selection to tikv. + rows = [][]interface{}{ + {"Selection_7", "root", "gt(test.t.c2, 1)"}, + {"└─TableReader_6", "root", "data:TableFullScan_5"}, + {" └─TableFullScan_5", "cop[tikv]", "keep order:false, stats:pseudo"}, + } + tk.MustQuery("explain select * from t where c2 > 1;").CheckAt([]int{0, 2, 4}, rows) + tk.MustExec("set @@tidb_allow_mpp=1; set @@tidb_enforce_mpp=1") tk.MustExec("set @@tidb_isolation_read_engines = 'tiflash'") is := dom.InfoSchema() db, exists := is.SchemaByName(model.NewCIStr("test")) require.True(t, exists) for _, tblInfo := range db.Tables { - if tblInfo.Name.L == "t1" { + if tblInfo.Name.L == "t" { tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{ Count: 1, Available: true, } } } - rows := [][]interface{}{ - {"TopN_7", "root", "test.t1.c2, offset:0, count:2"}, + + // TopN to tiflash. + rows = [][]interface{}{ + {"TopN_7", "root", "test.t.c2, offset:0, count:2"}, {"└─TableReader_15", "root", "data:TableFullScan_14"}, {" └─TableFullScan_14", "cop[tiflash]", "keep order:false, stats:pseudo"}, } - tk.MustQuery("explain select * from t1 order by c2 limit 2;").CheckAt([]int{0, 2, 4}, rows) + tk.MustQuery("explain select * from t order by c2 limit 2;").CheckAt([]int{0, 2, 4}, rows) + + // Projection to tiflash. + rows = [][]interface{}{ + {"Projection_3", "root", "plus(test.t.c1, test.t.c2)->Column#4"}, + {"└─TableReader_6", "root", "data:TableFullScan_5"}, + {" └─TableFullScan_5", "cop[tiflash]", "keep order:false, stats:pseudo"}, + } + tk.MustExec("set session tidb_opt_projection_push_down='ON';") + tk.MustQuery("explain select c1 + c2 from t;").CheckAt([]int{0, 2, 4}, rows) + tk.MustExec("set session tidb_opt_projection_push_down='OFF';") + + // Selection to tiflash. + rows = [][]interface{}{ + {"Selection_8", "root", "gt(test.t.c2, 1)"}, + {"└─TableReader_7", "root", "data:TableFullScan_6"}, + {" └─TableFullScan_6", "cop[tiflash]", "keep order:false, stats:pseudo"}, + } + tk.MustQuery("explain select * from t where c2 > 1;").CheckAt([]int{0, 2, 4}, rows) } From 38202bf5313dc9332ec00f88949df425fc9abe8e Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Wed, 15 Feb 2023 21:03:18 +0800 Subject: [PATCH 09/10] update --- planner/core/integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index 3e899a3d584b7..8e76f6e9331ce 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -8454,7 +8454,7 @@ func TestIssue41273(t *testing.T) { } // https://github.com/pingcap/tidb/issues/41355 -// Virtually generated columns push down is not supported now. +// The "virtual generated columns" push down is not supported now. // This test covers: TopN, Projection, Selection. func TestVirtualExprPushDown(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) From 7d454ab352a1f50ec3457b01e1a54afeec068631 Mon Sep 17 00:00:00 2001 From: Dousir9 <736191200@qq.com> Date: Wed, 15 Feb 2023 21:04:14 +0800 Subject: [PATCH 10/10] update --- planner/core/integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index 8e76f6e9331ce..b163c94795a56 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -8454,7 +8454,7 @@ func TestIssue41273(t *testing.T) { } // https://github.com/pingcap/tidb/issues/41355 -// The "virtual generated columns" push down is not supported now. +// The "virtual generated column" push down is not supported now. // This test covers: TopN, Projection, Selection. func TestVirtualExprPushDown(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t)