diff --git a/cmd/explaintest/r/generated_columns.result b/cmd/explaintest/r/generated_columns.result index a937079129e11..59311e829ad41 100644 --- a/cmd/explaintest/r/generated_columns.result +++ b/cmd/explaintest/r/generated_columns.result @@ -151,6 +151,7 @@ PARTITION p3 VALUES LESS THAN (4), PARTITION p4 VALUES LESS THAN (5), PARTITION p5 VALUES LESS THAN (6), PARTITION max VALUES LESS THAN MAXVALUE); +analyze table sgc3; EXPLAIN format = 'brief' SELECT * FROM sgc3 WHERE a <= 1; id estRows task access object operator info TableReader 3323.33 root partition:p0,p1 data:Selection diff --git a/cmd/explaintest/r/select.result b/cmd/explaintest/r/select.result index a31c03782bbfb..9577b28e47c35 100644 --- a/cmd/explaintest/r/select.result +++ b/cmd/explaintest/r/select.result @@ -381,19 +381,20 @@ PartitionUnion_8 20000.00 root └─TableReader_12 10000.00 root data:TableFullScan_11 └─TableFullScan_11 10000.00 cop[tikv] table:th, partition:p2 keep order:false, stats:pseudo set @@session.tidb_partition_prune_mode = 'dynamic'; +analyze table th; desc select * from th where a=-2; id estRows task access object operator info -TableReader_7 10.00 root partition:p2 data:Selection_6 -└─Selection_6 10.00 cop[tikv] eq(test.th.a, -2) - └─TableFullScan_5 10000.00 cop[tikv] table:th keep order:false, stats:pseudo +TableReader_7 1.00 root partition:p2 data:Selection_6 +└─Selection_6 1.00 cop[tikv] eq(test.th.a, -2) + └─TableFullScan_5 17.00 cop[tikv] table:th keep order:false desc select * from th; id estRows task access object operator info -TableReader_5 10000.00 root partition:all data:TableFullScan_4 -└─TableFullScan_4 10000.00 cop[tikv] table:th keep order:false, stats:pseudo +TableReader_5 17.00 root partition:all data:TableFullScan_4 +└─TableFullScan_4 17.00 cop[tikv] table:th keep order:false desc select * from th partition (p2,p1); id estRows task access object operator info -TableReader_5 10000.00 root partition:p1,p2 data:TableFullScan_4 -└─TableFullScan_4 10000.00 cop[tikv] table:th keep order:false, stats:pseudo +TableReader_5 17.00 root partition:p1,p2 data:TableFullScan_4 +└─TableFullScan_4 17.00 cop[tikv] table:th keep order:false set @@session.tidb_partition_prune_mode = DEFAULT; drop table if exists t; create table t(a int, b int); diff --git a/cmd/explaintest/t/generated_columns.test b/cmd/explaintest/t/generated_columns.test index c007f8ff42e66..48570e8ccbffb 100644 --- a/cmd/explaintest/t/generated_columns.test +++ b/cmd/explaintest/t/generated_columns.test @@ -107,6 +107,8 @@ PARTITION p4 VALUES LESS THAN (5), PARTITION p5 VALUES LESS THAN (6), PARTITION max VALUES LESS THAN MAXVALUE); +analyze table sgc3; + EXPLAIN format = 'brief' SELECT * FROM sgc3 WHERE a <= 1; EXPLAIN format = 'brief' SELECT * FROM sgc3 WHERE a < 7; diff --git a/cmd/explaintest/t/select.test b/cmd/explaintest/t/select.test index dbb505bb250f0..907066ffff4f4 100644 --- a/cmd/explaintest/t/select.test +++ b/cmd/explaintest/t/select.test @@ -190,6 +190,7 @@ desc select * from th where a=-2; desc select * from th; desc select * from th partition (p2,p1); set @@session.tidb_partition_prune_mode = 'dynamic'; +analyze table th; desc select * from th where a=-2; desc select * from th; desc select * from th partition (p2,p1); diff --git a/ddl/db_partition_test.go b/ddl/db_partition_test.go index 609006d7d380d..ee831e739479c 100644 --- a/ddl/db_partition_test.go +++ b/ddl/db_partition_test.go @@ -656,6 +656,8 @@ create table log_message_1 ( } func TestPartitionRangeColumnsCollate(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("create schema PartitionRangeColumnsCollate") @@ -3569,6 +3571,9 @@ func TestPartitionListWithTimeType(t *testing.T) { } func TestPartitionListWithNewCollation(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") + store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") diff --git a/executor/analyzetest/analyze_test.go b/executor/analyzetest/analyze_test.go index f544cbd0983cb..b9bfc153fa33c 100644 --- a/executor/analyzetest/analyze_test.go +++ b/executor/analyzetest/analyze_test.go @@ -2833,6 +2833,8 @@ PARTITION BY RANGE ( a ) ( } func TestAnalyzePartitionStaticToDynamic(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) originalVal := tk.MustQuery("select @@tidb_persist_analyze_options").Rows()[0][0].(string) @@ -2901,7 +2903,7 @@ PARTITION BY RANGE ( a ) ( tk.MustQuery("select * from t where a > 1 and b > 1 and c > 1 and d > 1") require.NoError(t, h.LoadNeededHistograms()) tbl := h.GetTableStats(tableInfo) - require.Equal(t, 0, len(tbl.Columns)) + require.Equal(t, 4, len(tbl.Columns)) // ignore both p0's 3 buckets, persisted-partition-options' 1 bucket, just use table-level 2 buckets tk.MustExec("analyze table t partition p0") diff --git a/executor/builder.go b/executor/builder.go index 19bbe09493cb3..0cda7ef3f55a0 100644 --- a/executor/builder.go +++ b/executor/builder.go @@ -3300,7 +3300,7 @@ func (b *executorBuilder) buildTableReader(v *plannercore.PhysicalTableReader) E sctx := b.ctx.GetSessionVars().StmtCtx sctx.TableIDs = append(sctx.TableIDs, ts.Table.ID) - if !b.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if !b.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return ret } // When isPartition is set, it means the union rewriting is done, so a partition reader is preferred. @@ -3504,7 +3504,7 @@ func buildNoRangeIndexReader(b *executorBuilder, v *plannercore.PhysicalIndexRea e.feedback = statistics.NewQueryFeedback(0, nil, 0, is.Desc) } else { tblID := e.physicalTableID - if b.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if b.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { tblID = e.table.Meta().ID } e.feedback = statistics.NewQueryFeedback(tblID, is.Hist, int64(is.StatsCount()), is.Desc) @@ -3547,7 +3547,7 @@ func (b *executorBuilder) buildIndexReader(v *plannercore.PhysicalIndexReader) E sctx := b.ctx.GetSessionVars().StmtCtx sctx.IndexNames = append(sctx.IndexNames, is.Table.Name.O+":"+is.Index.Name.O) - if !b.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if !b.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return ret } // When isPartition is set, it means the union rewriting is done, so a partition reader is preferred. @@ -3723,7 +3723,7 @@ func (b *executorBuilder) buildIndexLookUpReader(v *plannercore.PhysicalIndexLoo sctx.IndexNames = append(sctx.IndexNames, is.Table.Name.O+":"+is.Index.Name.O) sctx.TableIDs = append(sctx.TableIDs, ts.Table.ID) - if !b.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if !b.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return ret } @@ -3860,7 +3860,7 @@ func (b *executorBuilder) buildIndexMergeReader(v *plannercore.PhysicalIndexMerg sctx.TableIDs = append(sctx.TableIDs, ts.Table.ID) executorCounterIndexMergeReaderExecutor.Inc() - if !b.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if !b.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return ret } @@ -3978,7 +3978,7 @@ func (builder *dataReaderBuilder) buildTableReaderForIndexJoin(ctx context.Conte return nil, err } tbInfo := e.table.Meta() - if tbInfo.GetPartitionInfo() == nil || !builder.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if tbInfo.GetPartitionInfo() == nil || !builder.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { if v.IsCommonHandle { kvRanges, err := buildKvRangesForIndexJoin(e.ctx, getPhysicalTableID(e.table), -1, lookUpContents, indexRanges, keyOff2IdxOff, cwc, memTracker, interruptSignal) if err != nil { @@ -4226,7 +4226,7 @@ func (builder *dataReaderBuilder) buildIndexReaderForIndexJoin(ctx context.Conte return nil, err } tbInfo := e.table.Meta() - if tbInfo.GetPartitionInfo() == nil || !builder.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if tbInfo.GetPartitionInfo() == nil || !builder.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { kvRanges, err := buildKvRangesForIndexJoin(e.ctx, e.physicalTableID, e.index.ID, lookUpContents, indexRanges, keyOff2IdxOff, cwc, memoryTracker, interruptSignal) if err != nil { return nil, err @@ -4273,7 +4273,7 @@ func (builder *dataReaderBuilder) buildIndexLookUpReaderForIndexJoin(ctx context } tbInfo := e.table.Meta() - if tbInfo.GetPartitionInfo() == nil || !builder.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if tbInfo.GetPartitionInfo() == nil || !builder.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { e.kvRanges, err = buildKvRangesForIndexJoin(e.ctx, getPhysicalTableID(e.table), e.index.ID, lookUpContents, indexRanges, keyOff2IdxOff, cwc, memTracker, interruptSignal) if err != nil { return nil, err @@ -4859,7 +4859,7 @@ func getPhysicalTableID(t table.Table) int64 { } func getFeedbackStatsTableID(ctx sessionctx.Context, t table.Table) int64 { - if p, ok := t.(table.PhysicalTable); ok && !ctx.GetSessionVars().UseDynamicPartitionPrune() { + if p, ok := t.(table.PhysicalTable); ok && !ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return p.GetPhysicalID() } return t.Meta().ID diff --git a/executor/distsql_test.go b/executor/distsql_test.go index a0fc642a020d7..1f895a6703420 100644 --- a/executor/distsql_test.go +++ b/executor/distsql_test.go @@ -291,6 +291,8 @@ func TestPushLimitDownIndexLookUpReader(t *testing.T) { } func TestPartitionTableIndexLookUpReader(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/executor/executor.go b/executor/executor.go index e3ac232ba0d53..73238ee3cdcb1 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -1926,6 +1926,13 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) { sc.OptimizerCETrace = nil sc.StatsLoadStatus = make(map[model.TableItemID]string) sc.IsSyncStatsFailed = false + // Firstly we assume that UseDynamicPruneMode can be enabled according session variable, then we will check other conditions + // in PlanBuilder.buildDataSource + if ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() { + sc.UseDynamicPruneMode = true + } else { + sc.UseDynamicPruneMode = false + } sc.SysdateIsNow = ctx.GetSessionVars().SysdateIsNow diff --git a/executor/executor_issue_test.go b/executor/executor_issue_test.go index 8e8b4d28f0fa3..febdbd6031823 100644 --- a/executor/executor_issue_test.go +++ b/executor/executor_issue_test.go @@ -583,6 +583,8 @@ func TestFix31537(t *testing.T) { } func TestIssue30382(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") diff --git a/executor/index_lookup_join_test.go b/executor/index_lookup_join_test.go index dfd9f04a69140..24168058353ec 100644 --- a/executor/index_lookup_join_test.go +++ b/executor/index_lookup_join_test.go @@ -21,6 +21,7 @@ import ( "strings" "testing" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/testkit" "github.com/stretchr/testify/require" ) @@ -391,6 +392,8 @@ func TestIssue24547(t *testing.T) { } func TestIssue27138(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/executor/partition_table_test.go b/executor/partition_table_test.go index ce553e7b29f11..72fbf75c377bf 100644 --- a/executor/partition_table_test.go +++ b/executor/partition_table_test.go @@ -21,6 +21,7 @@ import ( "testing" "time" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/infoschema" @@ -33,6 +34,8 @@ import ( ) func TestFourReader(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -529,6 +532,8 @@ func TestView(t *testing.T) { } func TestDirectReadingwithIndexJoin(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -641,6 +646,8 @@ func TestDirectReadingwithIndexJoin(t *testing.T) { } func TestDynamicPruningUnderIndexJoin(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -943,6 +950,8 @@ func TestGlobalStatsAndSQLBinding(t *testing.T) { } func TestPartitionTableWithDifferentJoin(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -1731,6 +1740,8 @@ func TestDynamicPruneModeWithExpression(t *testing.T) { } func TestAddDropPartitions(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -1764,6 +1775,8 @@ func TestAddDropPartitions(t *testing.T) { } func TestMPPQueryExplainInfo(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -1793,6 +1806,8 @@ func TestMPPQueryExplainInfo(t *testing.T) { } func TestPartitionPruningInTransaction(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -2026,6 +2041,8 @@ func TestSubqueries(t *testing.T) { } func TestSplitRegion(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -2062,6 +2079,9 @@ func TestSplitRegion(t *testing.T) { } func TestParallelApply(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") + store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -2569,6 +2589,8 @@ func TestDirectReadingWithAgg(t *testing.T) { } func TestDynamicModeByDefault(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -2764,6 +2786,8 @@ func TestIssue25309(t *testing.T) { } func TestGlobalIndexScan(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -2784,6 +2808,8 @@ partition p2 values less than (10))`) } func TestGlobalIndexDoubleRead(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/executor/show_stats.go b/executor/show_stats.go index 597c6923ccc6f..058b3ed7c62da 100644 --- a/executor/show_stats.go +++ b/executor/show_stats.go @@ -108,7 +108,7 @@ func (e *ShowExec) fetchShowStatsMeta() error { for _, db := range dbs { for _, tbl := range db.Tables { pi := tbl.GetPartitionInfo() - if pi == nil || e.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if pi == nil || e.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() { partitionName := "" if pi != nil { partitionName = "global" @@ -150,7 +150,7 @@ func (e *ShowExec) fetchShowStatsHistogram() error { for _, db := range dbs { for _, tbl := range db.Tables { pi := tbl.GetPartitionInfo() - if pi == nil || e.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if pi == nil || e.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() { partitionName := "" if pi != nil { partitionName = "global" @@ -224,7 +224,7 @@ func (e *ShowExec) fetchShowStatsBuckets() error { for _, db := range dbs { for _, tbl := range db.Tables { pi := tbl.GetPartitionInfo() - if pi == nil || e.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if pi == nil || e.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() { partitionName := "" if pi != nil { partitionName = "global" @@ -283,7 +283,7 @@ func (e *ShowExec) fetchShowStatsTopN() error { for _, db := range dbs { for _, tbl := range db.Tables { pi := tbl.GetPartitionInfo() - if pi == nil || e.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if pi == nil || e.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() { partitionName := "" if pi != nil { partitionName = "global" @@ -415,7 +415,7 @@ func (e *ShowExec) fetchShowStatsHealthy() { for _, db := range dbs { for _, tbl := range db.Tables { pi := tbl.GetPartitionInfo() - if pi == nil || e.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if pi == nil || e.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() { partitionName := "" if pi != nil { partitionName = "global" diff --git a/executor/tiflashtest/tiflash_test.go b/executor/tiflashtest/tiflash_test.go index 5725ca22df4e2..d18dc2c87132c 100644 --- a/executor/tiflashtest/tiflash_test.go +++ b/executor/tiflashtest/tiflash_test.go @@ -457,6 +457,8 @@ func TestTiFlashPartitionTableReader(t *testing.T) { } func TestPartitionTable(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t, withMockTiFlash(2)) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") diff --git a/executor/write_test.go b/executor/write_test.go index 0c28d521c61a1..a5ef9da73ce00 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -21,6 +21,7 @@ import ( "strconv" "testing" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/kv" @@ -3237,6 +3238,8 @@ func TestWriteListPartitionTable1(t *testing.T) { // TestWriteListPartitionTable2 test for write list partition when the partition expression is complicated and contain generated column. func TestWriteListPartitionTable2(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") @@ -3359,6 +3362,8 @@ func TestWriteListPartitionTable2(t *testing.T) { } func TestWriteListColumnsPartitionTable1(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") @@ -4200,6 +4205,8 @@ func TestUpdate(t *testing.T) { } func TestListColumnsPartitionWithGlobalIndex(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") diff --git a/planner/cascades/integration_test.go b/planner/cascades/integration_test.go index e3a7b750373ec..ebb80b192a383 100644 --- a/planner/cascades/integration_test.go +++ b/planner/cascades/integration_test.go @@ -18,6 +18,7 @@ import ( "fmt" "testing" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/planner/cascades" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/testkit" @@ -375,6 +376,8 @@ func TestTopN(t *testing.T) { } func TestCascadePlannerHashedPartTable(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/planner/core/access_object.go b/planner/core/access_object.go index 81296c39c9223..c57f7edc06b90 100644 --- a/planner/core/access_object.go +++ b/planner/core/access_object.go @@ -352,7 +352,7 @@ func (p *BatchPointGetPlan) AccessObject() AccessObject { func getDynamicAccessPartition(sctx sessionctx.Context, tblInfo *model.TableInfo, partitionInfo *PartitionInfo, asName string) (res *DynamicPartitionAccessObject) { pi := tblInfo.GetPartitionInfo() - if pi == nil || !sctx.GetSessionVars().UseDynamicPartitionPrune() { + if pi == nil || !sctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return nil } @@ -392,7 +392,7 @@ func getDynamicAccessPartition(sctx sessionctx.Context, tblInfo *model.TableInfo } func (p *PhysicalTableReader) accessObject(sctx sessionctx.Context) AccessObject { - if !sctx.GetSessionVars().UseDynamicPartitionPrune() { + if !sctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return DynamicPartitionAccessObjects(nil) } if len(p.PartitionInfos) == 0 { @@ -444,7 +444,7 @@ func (p *PhysicalTableReader) accessObject(sctx sessionctx.Context) AccessObject } func (p *PhysicalIndexReader) accessObject(sctx sessionctx.Context) AccessObject { - if !sctx.GetSessionVars().UseDynamicPartitionPrune() { + if !sctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return DynamicPartitionAccessObjects(nil) } is := p.IndexPlans[0].(*PhysicalIndexScan) @@ -460,7 +460,7 @@ func (p *PhysicalIndexReader) accessObject(sctx sessionctx.Context) AccessObject } func (p *PhysicalIndexLookUpReader) accessObject(sctx sessionctx.Context) AccessObject { - if !sctx.GetSessionVars().UseDynamicPartitionPrune() { + if !sctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return DynamicPartitionAccessObjects(nil) } ts := p.TablePlans[0].(*PhysicalTableScan) @@ -476,7 +476,7 @@ func (p *PhysicalIndexLookUpReader) accessObject(sctx sessionctx.Context) Access } func (p *PhysicalIndexMergeReader) accessObject(sctx sessionctx.Context) AccessObject { - if !sctx.GetSessionVars().UseDynamicPartitionPrune() { + if !sctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return DynamicPartitionAccessObjects(nil) } ts := p.TablePlans[0].(*PhysicalTableScan) diff --git a/planner/core/cbo_test.go b/planner/core/cbo_test.go index d8d46c04d2aaa..31ba6bfeb3e07 100644 --- a/planner/core/cbo_test.go +++ b/planner/core/cbo_test.go @@ -23,6 +23,7 @@ import ( "strings" "testing" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/parser/model" @@ -819,6 +820,8 @@ func TestLimitIndexEstimation(t *testing.T) { } func TestBatchPointGetTablePartition(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) testKit := testkit.NewTestKit(t, store) testKit.MustExec("use test") diff --git a/planner/core/collect_column_stats_usage_test.go b/planner/core/collect_column_stats_usage_test.go index d494235bc66fc..38d246ff8bfd7 100644 --- a/planner/core/collect_column_stats_usage_test.go +++ b/planner/core/collect_column_stats_usage_test.go @@ -20,6 +20,7 @@ import ( "sort" "testing" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/util/hint" @@ -272,6 +273,8 @@ func TestCollectPredicateColumns(t *testing.T) { } func TestCollectHistNeededColumns(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") tests := []struct { pruneMode string sql string diff --git a/planner/core/explain.go b/planner/core/explain.go index d056eebc37d60..62ece42048433 100644 --- a/planner/core/explain.go +++ b/planner/core/explain.go @@ -214,7 +214,7 @@ func (p *PhysicalTableScan) OperatorInfo(normalized bool) string { if p.stats.StatsVersion == statistics.PseudoVersion && !normalized { buffer.WriteString(", stats:pseudo") } - if p.StoreType == kv.TiFlash && p.Table.GetPartitionInfo() != nil && p.IsMPPOrBatchCop && p.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if p.StoreType == kv.TiFlash && p.Table.GetPartitionInfo() != nil && p.IsMPPOrBatchCop && p.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { buffer.WriteString(", PartitionTableScan:true") } return buffer.String() diff --git a/planner/core/find_best_task.go b/planner/core/find_best_task.go index f538e3fe62c8e..5a9b524373593 100644 --- a/planner/core/find_best_task.go +++ b/planner/core/find_best_task.go @@ -936,7 +936,7 @@ func (ds *DataSource) findBestTask(prop *property.PhysicalProperty, planCounter var hashPartColName *ast.ColumnName if tblInfo := ds.table.Meta(); canConvertPointGet && tblInfo.GetPartitionInfo() != nil { // We do not build [batch] point get for dynamic table partitions now. This can be optimized. - if ds.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if ds.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { canConvertPointGet = false } if canConvertPointGet && len(path.Ranges) > 1 { diff --git a/planner/core/integration_partition_test.go b/planner/core/integration_partition_test.go index e8c53739d2819..353fc379be794 100644 --- a/planner/core/integration_partition_test.go +++ b/planner/core/integration_partition_test.go @@ -21,6 +21,7 @@ import ( "strings" "testing" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/parser/auth" "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/session" @@ -61,6 +62,9 @@ func TestListPartitionPushDown(t *testing.T) { } func TestListColVariousTypes(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") + store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -102,6 +106,9 @@ func TestListColVariousTypes(t *testing.T) { } func TestListPartitionPruning(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") + store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index 075972aa23a01..1b91cc8106c7e 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -1452,6 +1452,8 @@ func TestPartitionTableStats(t *testing.T) { } func TestPartitionPruningForInExpr(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -1477,6 +1479,8 @@ func TestPartitionPruningForInExpr(t *testing.T) { } func TestPartitionPruningWithDateType(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -3375,6 +3379,8 @@ func TestExplainAnalyzeDML2(t *testing.T) { } func TestPartitionExplain(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") @@ -3549,6 +3555,8 @@ func TestPartitionUnionWithPPruningColumn(t *testing.T) { } func TestIssue20139(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) @@ -6519,6 +6527,9 @@ func TestIssue32632(t *testing.T) { } func TestTiFlashPartitionTableScan(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") + store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") @@ -7131,6 +7142,58 @@ func TestCastTimeAsDurationToTiFlash(t *testing.T) { tk.MustQuery("explain select cast(a as time), cast(b as time) from t;").CheckAt([]int{0, 2, 4}, rows) } +func TestPartitionTableFallBackStatic(t *testing.T) { + store, _ := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set @@tidb_partition_prune_mode='static'") + tk.MustExec("CREATE TABLE t (a int) PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (6),PARTITION p1 VALUES LESS THAN (11));") + tk.MustExec("insert into t values (1),(2),(3),(4),(7),(8),(9),(10)") + tk.MustExec("analyze table t") + + // use static plan in static mode + rows := [][]interface{}{ + {"PartitionUnion", "", ""}, + {"├─TableReader", "", "data:TableFullScan"}, + {"│ └─TableFullScan", "table:t, partition:p0", "keep order:false"}, + {"└─TableReader", "", "data:TableFullScan"}, + {" └─TableFullScan", "table:t, partition:p1", "keep order:false"}, + } + tk.MustQuery("explain format='brief' select * from t").CheckAt([]int{0, 3, 4}, rows) + + tk.MustExec("CREATE TABLE t2 (a int) PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (6),PARTITION p1 VALUES LESS THAN (11));") + tk.MustExec("insert into t2 values (1),(2),(3),(4),(7),(8),(9),(10)") + tk.MustExec("analyze table t2") + tk.MustExec("set @@tidb_partition_prune_mode='dynamic'") + + // use static plan in dynamic mode due to having not global stats + tk.MustQuery("explain format='brief' select * from t").CheckAt([]int{0, 3, 4}, rows) + tk.MustExec("analyze table t") + + // use dynamic plan in dynamic mode with global stats + rows = [][]interface{}{ + {"TableReader", "partition:all", "data:TableFullScan"}, + {"└─TableFullScan", "table:t", "keep order:false"}, + } + tk.MustQuery("explain format='brief' select * from t").CheckAt([]int{0, 3, 4}, rows) + + rows = [][]interface{}{ + {"Union", "", ""}, + {"├─PartitionUnion", "", ""}, + {"│ ├─TableReader", "", "data:TableFullScan"}, + {"│ │ └─TableFullScan", "table:t, partition:p0", "keep order:false"}, + {"│ └─TableReader", "", "data:TableFullScan"}, + {"│ └─TableFullScan", "table:t, partition:p1", "keep order:false"}, + {"└─PartitionUnion", "", ""}, + {" ├─TableReader", "", "data:TableFullScan"}, + {" │ └─TableFullScan", "table:t2, partition:p0", "keep order:false"}, + {" └─TableReader", "", "data:TableFullScan"}, + {" └─TableFullScan", "table:t2, partition:p1", "keep order:false"}, + } + // use static plan in dynamic mode due to t2 has no global stats + tk.MustQuery("explain format='brief' select * from t union all select * from t2;").CheckAt([]int{0, 3, 4}, rows) +} + func TestEnableTiFlashReadForWriteStmt(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index e57d951959054..b632d352956bf 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -26,6 +26,7 @@ import ( "unicode" "github.com/pingcap/errors" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/expression/aggregation" @@ -4157,7 +4158,7 @@ func getStatsTable(ctx sessionctx.Context, tblInfo *model.TableInfo, pid int64) } var statsTbl *statistics.Table - if pid == tblInfo.ID || ctx.GetSessionVars().UseDynamicPartitionPrune() { + if pid == tblInfo.ID || ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { statsTbl = statsHandle.GetTableStats(tblInfo, handle.WithTableStatsByQuery()) } else { statsTbl = statsHandle.GetPartitionStats(tblInfo, pid, handle.WithTableStatsByQuery()) @@ -4374,9 +4375,24 @@ func (b *PlanBuilder) buildDataSource(ctx context.Context, tn *ast.TableName, as } if tableInfo.GetPartitionInfo() != nil { - // Use the new partition implementation, clean up the code here when it's full implemented. - if !b.ctx.GetSessionVars().UseDynamicPartitionPrune() { + h := domain.GetDomain(b.ctx).StatsHandle() + tblStats := h.GetTableStats(tableInfo) + isDynamicEnabled := b.ctx.GetSessionVars().IsDynamicPartitionPruneEnabled() + globalStatsReady := tblStats.IsInitialized() + // If dynamic partition prune isn't enabled or global stats is not ready, we won't enable dynamic prune mode in query + usePartitionProcessor := !isDynamicEnabled || !globalStatsReady + + failpoint.Inject("forceDynamicPrune", func(val failpoint.Value) { + if val.(bool) { + if isDynamicEnabled { + usePartitionProcessor = false + } + } + }) + + if usePartitionProcessor { b.optFlag = b.optFlag | flagPartitionProcessor + b.ctx.GetSessionVars().StmtCtx.UseDynamicPruneMode = false } pt := tbl.(table.PartitionedTable) diff --git a/planner/core/partition_pruner_test.go b/planner/core/partition_pruner_test.go index d3db641a8efd9..fffef54373bd8 100644 --- a/planner/core/partition_pruner_test.go +++ b/planner/core/partition_pruner_test.go @@ -21,6 +21,7 @@ import ( "strings" "testing" + "github.com/pingcap/failpoint" plannercore "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/testkit" @@ -29,6 +30,8 @@ import ( ) func TestHashPartitionPruner(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("create database test_partition") @@ -250,6 +253,8 @@ func TestRangeColumnPartitionPruningForInString(t *testing.T) { } func TestListPartitionPruner(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("drop database if exists test_partition;") @@ -321,6 +326,8 @@ func TestListPartitionPruner(t *testing.T) { } func TestListColumnsPartitionPruner(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("set @@session.tidb_enable_list_partition = ON") @@ -532,6 +539,8 @@ func TestListColumnsPartitionPrunerRandom(t *testing.T) { } func TestIssue22635(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("USE test;") diff --git a/planner/core/physical_plan_test.go b/planner/core/physical_plan_test.go index 61a2f5dd87e11..d4cf5a5a10430 100644 --- a/planner/core/physical_plan_test.go +++ b/planner/core/physical_plan_test.go @@ -21,6 +21,7 @@ import ( "strings" "testing" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/infoschema" @@ -1259,6 +1260,8 @@ func doTestPushdownDistinct(t *testing.T, vars, input []string, output []struct } func TestGroupConcatOrderby(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") var ( input []string output []struct { @@ -2066,6 +2069,9 @@ func TestHJBuildAndProbeHint4StaticPartitionTable(t *testing.T) { } func TestHJBuildAndProbeHint4DynamicPartitionTable(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") + var ( input []string output []struct { diff --git a/planner/core/plan_to_pb.go b/planner/core/plan_to_pb.go index 0bd07a4415f20..59194e5b37286 100644 --- a/planner/core/plan_to_pb.go +++ b/planner/core/plan_to_pb.go @@ -185,7 +185,7 @@ func (p *PhysicalLimit) ToPB(ctx sessionctx.Context, storeType kv.StoreType) (*t // ToPB implements PhysicalPlan ToPB interface. func (p *PhysicalTableScan) ToPB(ctx sessionctx.Context, storeType kv.StoreType) (*tipb.Executor, error) { - if storeType == kv.TiFlash && p.Table.GetPartitionInfo() != nil && p.IsMPPOrBatchCop && p.ctx.GetSessionVars().UseDynamicPartitionPrune() { + if storeType == kv.TiFlash && p.Table.GetPartitionInfo() != nil && p.IsMPPOrBatchCop && p.ctx.GetSessionVars().StmtCtx.UseDynamicPartitionPrune() { return p.partitionTableScanToPBForFlash(ctx) } tsExec := tables.BuildTableScanFromInfos(p.Table, p.Columns) diff --git a/planner/core/point_get_plan_test.go b/planner/core/point_get_plan_test.go index 71804ae0fc00e..3a92d25719c09 100644 --- a/planner/core/point_get_plan_test.go +++ b/planner/core/point_get_plan_test.go @@ -21,6 +21,7 @@ import ( "testing" "time" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/planner" @@ -653,6 +654,8 @@ func TestBatchPointGetPartition(t *testing.T) { } func TestBatchPointGetPartitionForAccessObject(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/planner/core/rule_join_reorder_test.go b/planner/core/rule_join_reorder_test.go index a981495807d3d..a0c136d8d4a2f 100644 --- a/planner/core/rule_join_reorder_test.go +++ b/planner/core/rule_join_reorder_test.go @@ -17,6 +17,7 @@ package core_test import ( "testing" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/parser/model" plannercore "github.com/pingcap/tidb/planner/core" @@ -233,6 +234,8 @@ func TestJoinOrderHint4StaticPartitionTable(t *testing.T) { } func TestJoinOrderHint4DynamicPartitionTable(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/sessionctx/stmtctx/stmtctx.go b/sessionctx/stmtctx/stmtctx.go index 18945a9e5fb81..7506cc85d9424 100644 --- a/sessionctx/stmtctx/stmtctx.go +++ b/sessionctx/stmtctx/stmtctx.go @@ -317,6 +317,8 @@ type StatementContext struct { StatsLoadStatus map[model.TableItemID]string // IsSyncStatsFailed indicates whether any failure happened during sync stats IsSyncStatsFailed bool + // UseDynamicPruneMode indicates whether use UseDynamicPruneMode in query stmt + UseDynamicPruneMode bool // ColRefFromPlan mark the column ref used by assignment in update statement. ColRefFromUpdatePlan []int64 } @@ -984,6 +986,11 @@ func (sc *StatementContext) GetLockWaitStartTime() time.Time { return time.Unix(0, startTime) } +// UseDynamicPartitionPrune indicates whether dynamic partition is used during the query +func (sc *StatementContext) UseDynamicPartitionPrune() bool { + return sc.UseDynamicPruneMode +} + // CopTasksDetails collects some useful information of cop-tasks during execution. type CopTasksDetails struct { NumCopTasks int diff --git a/sessionctx/variable/session.go b/sessionctx/variable/session.go index 192ed495a873c..41cd46dbfe166 100644 --- a/sessionctx/variable/session.go +++ b/sessionctx/variable/session.go @@ -1332,8 +1332,10 @@ func (s *SessionVars) CheckAndGetTxnScope() string { return kv.GlobalTxnScope } -// UseDynamicPartitionPrune indicates whether use new dynamic partition prune. -func (s *SessionVars) UseDynamicPartitionPrune() bool { +// IsDynamicPartitionPruneEnabled indicates whether dynamic partition prune enabled +// Note that: IsDynamicPartitionPruneEnabled only indicates whether dynamic partition prune mode is enabled according to +// session variable, it isn't guaranteed to be used during query due to other conditions checking. +func (s *SessionVars) IsDynamicPartitionPruneEnabled() bool { return PartitionPruneMode(s.PartitionPruneMode.Load()) == Dynamic } diff --git a/statistics/handle/handle_test.go b/statistics/handle/handle_test.go index 95a663949dd6d..5e61f0f75bd83 100644 --- a/statistics/handle/handle_test.go +++ b/statistics/handle/handle_test.go @@ -2121,6 +2121,9 @@ func TestAnalyzeWithDynamicPartitionPruneMode(t *testing.T) { } func TestPartitionPruneModeSessionVariable(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") + store := testkit.CreateMockStore(t) tk1 := testkit.NewTestKit(t, store) tk1.MustExec("use test") diff --git a/statistics/integration_test.go b/statistics/integration_test.go index 5abba85ff9193..c4e4d315c7dbe 100644 --- a/statistics/integration_test.go +++ b/statistics/integration_test.go @@ -300,6 +300,8 @@ func TestExpBackoffEstimation(t *testing.T) { } func TestGlobalStats(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") diff --git a/table/tables/partition_test.go b/table/tables/partition_test.go index b05cf8f5037bd..aed5ef219ad87 100644 --- a/table/tables/partition_test.go +++ b/table/tables/partition_test.go @@ -18,6 +18,7 @@ import ( "context" "testing" + "github.com/pingcap/failpoint" mysql "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" @@ -393,6 +394,8 @@ func TestLocatePartitionSingleColumn(t *testing.T) { } func TestLocatePartition(t *testing.T) { + failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`) + defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune") store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test")