diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index 968ea44c6fdcb..01dae7b01422d 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -1454,16 +1454,25 @@ type gbyResolver struct { err error inExpr bool isParam bool + + exprDepth int // exprDepth is the depth of current expression in expression tree. } func (g *gbyResolver) Enter(inNode ast.Node) (ast.Node, bool) { + g.exprDepth++ switch n := inNode.(type) { case *ast.SubqueryExpr, *ast.CompareSubqueryExpr, *ast.ExistsSubqueryExpr: return inNode, true case *driver.ParamMarkerExpr: - newNode := expression.ConstructPositionExpr(n) g.isParam = true - return newNode, true + if g.exprDepth == 1 { + _, isNull, isExpectedType := getUintFromNode(g.ctx, n) + // For constant uint expression in top level, it should be treated as position expression. + if !isNull && isExpectedType { + return expression.ConstructPositionExpr(n), true + } + } + return n, true case *driver.ValueExpr, *ast.ColumnNameExpr, *ast.ParenthesesExpr, *ast.ColumnName: default: g.inExpr = true diff --git a/planner/core/prepare_test.go b/planner/core/prepare_test.go index 984f41537e726..f468661bb005a 100644 --- a/planner/core/prepare_test.go +++ b/planner/core/prepare_test.go @@ -345,3 +345,28 @@ func (s *testPrepareSuite) TestPrepareWithWindowFunction(c *C) { tk.MustExec("set @a=0, @b=1;") tk.MustQuery("execute stmt2 using @a, @b").Check(testkit.Rows("0", "0")) } + +func (s *testPrepareSuite) TestPrepareForGroupByItems(c *C) { + defer testleak.AfterTest(c)() + store, dom, err := newStoreWithBootstrap() + c.Assert(err, IsNil) + tk := testkit.NewTestKit(c, store) + defer func() { + dom.Close() + store.Close() + }() + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(id int, v int)") + tk.MustExec("insert into t(id, v) values(1, 2),(1, 2),(2, 3);") + tk.MustExec("prepare s1 from 'select max(v) from t group by floor(id/?)';") + tk.MustExec("set @a=2;") + tk.MustQuery("execute s1 using @a;").Sort().Check(testkit.Rows("2", "3")) + + tk.MustExec("prepare s1 from 'select max(v) from t group by ?';") + tk.MustExec("set @a=2;") + err = tk.ExecToErr("execute s1 using @a;") + c.Assert(err.Error(), Equals, "Unknown column '2' in 'group statement'") + tk.MustExec("set @a=2.0;") + tk.MustQuery("execute s1 using @a;").Check(testkit.Rows("3")) +}