diff --git a/expression/function_traits.go b/expression/function_traits.go index c16beb0c749fa..ef9c58a3e4380 100644 --- a/expression/function_traits.go +++ b/expression/function_traits.go @@ -41,6 +41,8 @@ var UnCacheableFunctions = map[string]struct{}{ ast.TimeLiteral: {}, ast.DateLiteral: {}, ast.TimestampLiteral: {}, + ast.AesEncrypt: {}, // affected by @@block_encryption_mode + ast.AesDecrypt: {}, } // unFoldableFunctions stores functions which can not be folded duration constant folding stage. diff --git a/planner/core/plan_cache_param.go b/planner/core/plan_cache_param.go index a997bb8f7b83d..9f4bfbc721397 100644 --- a/planner/core/plan_cache_param.go +++ b/planner/core/plan_cache_param.go @@ -43,7 +43,7 @@ var ( paramCtxPool = sync.Pool{New: func() interface{} { buf := new(strings.Builder) buf.Reset() - restoreCtx := format.NewRestoreCtx(format.RestoreForNonPrepPlanCache, buf) + restoreCtx := format.NewRestoreCtx(format.RestoreForNonPrepPlanCache|format.RestoreStringWithoutCharset, buf) return restoreCtx }} ) @@ -55,10 +55,10 @@ type paramReplacer struct { func (pr *paramReplacer) Enter(in ast.Node) (out ast.Node, skipChildren bool) { switch n := in.(type) { - case *ast.SelectField, *ast.GroupByClause, *ast.Limit: + case *ast.SelectField, *ast.GroupByClause, *ast.Limit, *ast.OrderByClause: // Skip replacing values in these case: // 1. SelectField: to keep the output field names be corresponding to these values. - // 2. GroupByClause: to avoid breaking the full_group_by check. + // 2. GroupByClause, OrderByClause: to avoid breaking the full_group_by check. // 3. Limit: to generate different plans for queries with different limit values. return in, true case *driver.ValueExpr: diff --git a/planner/core/plan_cache_test.go b/planner/core/plan_cache_test.go index 885584849c906..7b1b58cf5bb36 100644 --- a/planner/core/plan_cache_test.go +++ b/planner/core/plan_cache_test.go @@ -1469,11 +1469,11 @@ func TestNonPreparedPlanCacheGroupBy(t *testing.T) { tk.MustExec(`select sum(b) from t group by a+1`) tk.MustExec(`select sum(b) from t group by a+1`) - tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1")) + tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0")) tk.MustExec(`select sum(b) from t group by a+2`) tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0")) tk.MustExec(`select sum(b) from t group by a+2`) - tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1")) + tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0")) } func TestNonPreparedPlanCacheFieldNames(t *testing.T) { @@ -1850,7 +1850,7 @@ func TestNonPreparedPlanCacheJoin(t *testing.T) { } } -func TestNonPreparedPlanCacheAgg(t *testing.T) { +func TestNonPreparedPlanCacheAggSort(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") @@ -1862,13 +1862,17 @@ func TestNonPreparedPlanCacheAgg(t *testing.T) { "select count(*) from t", "select max(b) from t group by a", "select count(*), a from t group by a, b", - "select sum(b) from t group by a+1", - "select count(*) from t group by a+b", + "select a from t order by a", + "select a, b, a+b from t order by a, b", } unsupported := []string{ + "select sum(b) from t group by a+1", + "select count(*) from t group by a+b", "select a, b, count(*) from t group by 1", // group by position "select a, b, count(*) from t group by 1, a", // group by position "select a, b, count(*) from t group by a having b < 1", // not support having-clause + "select a from t order by a+1", + "select a, b, a+b from t order by a + b", } for _, sql := range supported { @@ -1894,13 +1898,13 @@ func TestNonPreparedPlanCacheOrder(t *testing.T) { "select a from t order by a", "select a from t order by a asc", "select a from t order by a desc", - "select a from t order by a+1,b-2", - "select a from t order by a desc, b+2", "select a from t order by a,b desc", } unsupported := []string{ "select a from t order by 1", // order by position "select a from t order by a, 1", + "select a from t order by a+1,b-2", + "select a from t order by a desc, b+2", } for _, sql := range supported { diff --git a/planner/core/plan_cacheable_checker.go b/planner/core/plan_cacheable_checker.go index 4b467dcd942d4..82111688cbecf 100644 --- a/planner/core/plan_cacheable_checker.go +++ b/planner/core/plan_cacheable_checker.go @@ -435,18 +435,18 @@ func (checker *nonPreparedPlanCacheableChecker) Enter(in ast.Node) (out ast.Node return in, !checker.cacheable case *ast.GroupByClause: for _, item := range node.Items { - if _, isPos := item.Expr.(*ast.PositionExpr); isPos { + if _, isCol := item.Expr.(*ast.ColumnNameExpr); !isCol { checker.cacheable = false - checker.reason = "query has group by position" + checker.reason = "only support group by {columns}'" return in, !checker.cacheable } } return in, !checker.cacheable case *ast.OrderByClause: for _, item := range node.Items { - if _, isPos := item.Expr.(*ast.PositionExpr); isPos { + if _, isCol := item.Expr.(*ast.ColumnNameExpr); !isCol { checker.cacheable = false - checker.reason = "query has order by position" + checker.reason = "only support order by {columns}'" return in, !checker.cacheable } }