From e22e185a6d497c7b4b2826eca4bdd5ce7735673b Mon Sep 17 00:00:00 2001 From: Haibin Xie Date: Mon, 23 Sep 2019 14:46:21 +0800 Subject: [PATCH 1/2] planner/core: fix resolve rule for group by expression --- planner/core/logical_plan_builder.go | 13 +++++++++++-- planner/core/prepare_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index 517746047d580..457542bf157bc 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -1437,16 +1437,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 607afd2a85f3d..cbe3449710b42 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;").Check(testkit.Rows("3", "2")) + + 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")) +} From 72db9ed64d40632097fd6cacf6fecd57e024c2cc Mon Sep 17 00:00:00 2001 From: Haibin Xie Date: Mon, 23 Sep 2019 15:09:22 +0800 Subject: [PATCH 2/2] fix test --- planner/core/prepare_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planner/core/prepare_test.go b/planner/core/prepare_test.go index cbe3449710b42..829ec099fface 100644 --- a/planner/core/prepare_test.go +++ b/planner/core/prepare_test.go @@ -361,7 +361,7 @@ func (s *testPrepareSuite) TestPrepareForGroupByItems(c *C) { 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;").Check(testkit.Rows("3", "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;")