diff --git a/planner/core/common_plans.go b/planner/core/common_plans.go index 2f874bdbe2214..55ab4b98edf54 100644 --- a/planner/core/common_plans.go +++ b/planner/core/common_plans.go @@ -588,6 +588,10 @@ REBUILD: if containTableDual(p) && varsNum > 0 { stmtCtx.SkipPlanCache = true } + // plan has shuffle operator will not be cached. + if !stmtCtx.SkipPlanCache && containShuffleOperator(p) { + stmtCtx.SkipPlanCache = true + } if prepared.UseCache && !stmtCtx.SkipPlanCache && !ignorePlanCache { // rebuild key to exclude kv.TiFlash when stmt is not read only if _, isolationReadContainTiFlash := sessVars.IsolationReadEngines[kv.TiFlash]; isolationReadContainTiFlash && !IsReadOnly(stmt, sessVars) { @@ -637,6 +641,25 @@ func containTableDual(p Plan) bool { return childContainTableDual } +func containShuffleOperator(p Plan) bool { + if _, isShuffle := p.(*PhysicalShuffle); isShuffle { + return true + } + if _, isShuffleRecv := p.(*PhysicalShuffleReceiverStub); isShuffleRecv { + return true + } + physicalPlan, ok := p.(PhysicalPlan) + if !ok { + return false + } + for _, child := range physicalPlan.Children() { + if containShuffleOperator(child) { + return true + } + } + return false +} + // tryCachePointPlan will try to cache point execution plan, there may be some // short paths for these executions, currently "point select" and "point update" func (e *Execute) tryCachePointPlan(ctx context.Context, sctx sessionctx.Context, diff --git a/planner/core/prepare_test.go b/planner/core/prepare_test.go index 71dd3cde99752..66c6b14c0aa54 100644 --- a/planner/core/prepare_test.go +++ b/planner/core/prepare_test.go @@ -2945,3 +2945,29 @@ func TestIssue37901(t *testing.T) { tk.MustExec(`execute st1 using @t`) tk.MustQuery(`select count(*) from t4`).Check(testkit.Rows("2")) } + +func TestIssue38335(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`CREATE TABLE PK_LP9463 ( + COL1 mediumint NOT NULL DEFAULT '77' COMMENT 'NUMERIC PK', + COL2 varchar(20) COLLATE utf8mb4_bin DEFAULT NULL, + COL4 datetime DEFAULT NULL, + COL3 bigint DEFAULT NULL, + COL5 float DEFAULT NULL, + PRIMARY KEY (COL1))`) + tk.MustExec(` +INSERT INTO PK_LP9463 VALUES (-7415279,'笚綷想摻癫梒偆荈湩窐曋繾鏫蘌憬稁渣½隨苆','1001-11-02 05:11:33',-3745331437675076296,-3.21618e38), +(-7153863,'鯷氤衡椻闍饑堀鱟垩啵緬氂哨笂序鉲秼摀巽茊','6800-06-20 23:39:12',-7871155140266310321,-3.04829e38), +(77,'娥藨潰眤徕菗柢礥蕶浠嶲憅榩椻鍙鑜堋ᛀ暵氎','4473-09-13 01:18:59',4076508026242316746,-1.9525e38), +(16614,'阖旕雐盬皪豧篣哙舄糗悄蟊鯴瞶珧赺潴嶽簤彉','2745-12-29 00:29:06',-4242415439257105874,2.71063e37)`) + tk.MustExec(`prepare stmt from 'SELECT *, rank() OVER (PARTITION BY col2 ORDER BY COL1) FROM PK_LP9463 WHERE col1 != ? AND col1 < ?'`) + tk.MustExec(`set @a=-8414766051197, @b=-8388608`) + tk.MustExec(`execute stmt using @a,@b`) + tk.MustExec(`set @a=16614, @b=16614`) + rows := tk.MustQuery(`execute stmt using @a,@b`).Sort() + tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0")) + tk.MustQuery(`SELECT *, rank() OVER (PARTITION BY col2 ORDER BY COL1) FROM PK_LP9463 WHERE col1 != 16614 and col1 < 16614`).Sort().Check(rows.Rows()) +}