From 977b7cbe41cc2c54c500bf2dad38c2150e13a2bb Mon Sep 17 00:00:00 2001 From: spongedc Date: Sat, 2 Jun 2018 17:12:49 +0800 Subject: [PATCH 1/7] plan: when 'only_full_group_by' is set in sql_mode, raise error for nonaggregated column in query without GROUP BY --- executor/aggregate_test.go | 9 +++ plan/errors.go | 117 ++++++++++++++++++----------------- plan/logical_plan_builder.go | 60 +++++++++++++++++- 3 files changed, 126 insertions(+), 60 deletions(-) diff --git a/executor/aggregate_test.go b/executor/aggregate_test.go index 194af8c498628..98db26caa8aed 100644 --- a/executor/aggregate_test.go +++ b/executor/aggregate_test.go @@ -425,6 +425,12 @@ func (s *testSuite) TestOnlyFullGroupBy(c *C) { c.Assert(terror.ErrorEqual(err, plan.ErrFieldNotInGroupBy), IsTrue) _, err = tk.Exec("select -b from t group by c") c.Assert(terror.ErrorEqual(err, plan.ErrFieldNotInGroupBy), IsTrue) + _, err = tk.Exec("select a, max(b) from t") + c.Assert(terror.ErrorEqual(err, plan.ErrMixOfGroupFuncAndFields), IsTrue) + _, err = tk.Exec("select sum(a)+b from t") + c.Assert(terror.ErrorEqual(err, plan.ErrMixOfGroupFuncAndFields), IsTrue) + _, err = tk.Exec("select count(b), c from t") + c.Assert(terror.ErrorEqual(err, plan.ErrMixOfGroupFuncAndFields), IsTrue) // test compatible with sql_mode = ONLY_FULL_GROUP_BY tk.MustQuery("select a from t group by a,b,c") tk.MustQuery("select b from t group by b") @@ -444,6 +450,9 @@ func (s *testSuite) TestOnlyFullGroupBy(c *C) { tk.MustQuery("select b like '%a' from t group by b") tk.MustQuery("select c REGEXP '1.*' from t group by c") tk.MustQuery("select -b from t group by b") + tk.MustQuery("select max(a+b) from t") + tk.MustQuery("select avg(a)+1 from t") + _, err = tk.Exec("select count(c), 5 from t") // test functinal depend on primary key tk.MustQuery("select * from t group by a") // test functional depend on unique not null columns diff --git a/plan/errors.go b/plan/errors.go index e9854681be11d..a906870f6fd70 100644 --- a/plan/errors.go +++ b/plan/errors.go @@ -26,25 +26,26 @@ const ( codeWrongParamCount = 5 codeSchemaChanged = 6 - codeWrongUsage = mysql.ErrWrongUsage - codeAmbiguous = mysql.ErrNonUniq - codeUnknownColumn = mysql.ErrBadField - codeUnknownTable = mysql.ErrUnknownTable - codeWrongArguments = mysql.ErrWrongArguments - codeBadGeneratedColumn = mysql.ErrBadGeneratedColumn - codeFieldNotInGroupBy = mysql.ErrFieldNotInGroupBy - codeBadTable = mysql.ErrBadTable - codeKeyDoesNotExist = mysql.ErrKeyDoesNotExist - codeOperandColumns = mysql.ErrOperandColumns - codeInvalidWildCard = mysql.ErrParse - codeInvalidGroupFuncUse = mysql.ErrInvalidGroupFuncUse - codeIllegalReference = mysql.ErrIllegalReference - codeNoDB = mysql.ErrNoDB - codeUnknownExplainFormat = mysql.ErrUnknownExplainFormat - codeWrongGroupField = mysql.ErrWrongGroupField - codeDupFieldName = mysql.ErrDupFieldName - codeNonUpdatableTable = mysql.ErrNonUpdatableTable - codeInternal = mysql.ErrInternal + codeWrongUsage = mysql.ErrWrongUsage + codeAmbiguous = mysql.ErrNonUniq + codeUnknownColumn = mysql.ErrBadField + codeUnknownTable = mysql.ErrUnknownTable + codeWrongArguments = mysql.ErrWrongArguments + codeBadGeneratedColumn = mysql.ErrBadGeneratedColumn + codeFieldNotInGroupBy = mysql.ErrFieldNotInGroupBy + codeBadTable = mysql.ErrBadTable + codeKeyDoesNotExist = mysql.ErrKeyDoesNotExist + codeOperandColumns = mysql.ErrOperandColumns + codeInvalidWildCard = mysql.ErrParse + codeInvalidGroupFuncUse = mysql.ErrInvalidGroupFuncUse + codeIllegalReference = mysql.ErrIllegalReference + codeNoDB = mysql.ErrNoDB + codeUnknownExplainFormat = mysql.ErrUnknownExplainFormat + codeWrongGroupField = mysql.ErrWrongGroupField + codeDupFieldName = mysql.ErrDupFieldName + codeNonUpdatableTable = mysql.ErrNonUpdatableTable + codeInternal = mysql.ErrInternal + codeMixOfGroupFuncAndFields = mysql.ErrMixOfGroupFuncAndFields ) // error definitions. @@ -56,48 +57,50 @@ var ( ErrWrongParamCount = terror.ClassOptimizer.New(codeWrongParamCount, "Wrong parameter count") ErrSchemaChanged = terror.ClassOptimizer.New(codeSchemaChanged, "Schema has changed") - ErrWrongUsage = terror.ClassOptimizer.New(codeWrongUsage, mysql.MySQLErrName[mysql.ErrWrongUsage]) - ErrAmbiguous = terror.ClassOptimizer.New(codeAmbiguous, mysql.MySQLErrName[mysql.ErrNonUniq]) - ErrUnknownColumn = terror.ClassOptimizer.New(codeUnknownColumn, mysql.MySQLErrName[mysql.ErrBadField]) - ErrUnknownTable = terror.ClassOptimizer.New(codeUnknownTable, mysql.MySQLErrName[mysql.ErrUnknownTable]) - ErrWrongArguments = terror.ClassOptimizer.New(codeWrongArguments, mysql.MySQLErrName[mysql.ErrWrongArguments]) - ErrBadGeneratedColumn = terror.ClassOptimizer.New(codeBadGeneratedColumn, mysql.MySQLErrName[mysql.ErrBadGeneratedColumn]) - ErrFieldNotInGroupBy = terror.ClassOptimizer.New(codeFieldNotInGroupBy, mysql.MySQLErrName[mysql.ErrFieldNotInGroupBy]) - ErrBadTable = terror.ClassOptimizer.New(codeBadTable, mysql.MySQLErrName[mysql.ErrBadTable]) - ErrKeyDoesNotExist = terror.ClassOptimizer.New(codeKeyDoesNotExist, mysql.MySQLErrName[mysql.ErrKeyDoesNotExist]) - ErrOperandColumns = terror.ClassOptimizer.New(codeOperandColumns, mysql.MySQLErrName[mysql.ErrOperandColumns]) - ErrInvalidWildCard = terror.ClassOptimizer.New(codeInvalidWildCard, "Wildcard fields without any table name appears in wrong place") - ErrInvalidGroupFuncUse = terror.ClassOptimizer.New(codeInvalidGroupFuncUse, mysql.MySQLErrName[mysql.ErrInvalidGroupFuncUse]) - ErrIllegalReference = terror.ClassOptimizer.New(codeIllegalReference, mysql.MySQLErrName[mysql.ErrIllegalReference]) - ErrNoDB = terror.ClassOptimizer.New(codeNoDB, mysql.MySQLErrName[mysql.ErrNoDB]) - ErrUnknownExplainFormat = terror.ClassOptimizer.New(codeUnknownExplainFormat, mysql.MySQLErrName[mysql.ErrUnknownExplainFormat]) - ErrWrongGroupField = terror.ClassOptimizer.New(codeWrongGroupField, mysql.MySQLErrName[mysql.ErrWrongGroupField]) - ErrDupFieldName = terror.ClassOptimizer.New(codeDupFieldName, mysql.MySQLErrName[mysql.ErrDupFieldName]) - ErrNonUpdatableTable = terror.ClassOptimizer.New(codeNonUpdatableTable, mysql.MySQLErrName[mysql.ErrNonUpdatableTable]) - ErrInternal = terror.ClassOptimizer.New(codeInternal, mysql.MySQLErrName[mysql.ErrInternal]) + ErrWrongUsage = terror.ClassOptimizer.New(codeWrongUsage, mysql.MySQLErrName[mysql.ErrWrongUsage]) + ErrAmbiguous = terror.ClassOptimizer.New(codeAmbiguous, mysql.MySQLErrName[mysql.ErrNonUniq]) + ErrUnknownColumn = terror.ClassOptimizer.New(codeUnknownColumn, mysql.MySQLErrName[mysql.ErrBadField]) + ErrUnknownTable = terror.ClassOptimizer.New(codeUnknownTable, mysql.MySQLErrName[mysql.ErrUnknownTable]) + ErrWrongArguments = terror.ClassOptimizer.New(codeWrongArguments, mysql.MySQLErrName[mysql.ErrWrongArguments]) + ErrBadGeneratedColumn = terror.ClassOptimizer.New(codeBadGeneratedColumn, mysql.MySQLErrName[mysql.ErrBadGeneratedColumn]) + ErrFieldNotInGroupBy = terror.ClassOptimizer.New(codeFieldNotInGroupBy, mysql.MySQLErrName[mysql.ErrFieldNotInGroupBy]) + ErrBadTable = terror.ClassOptimizer.New(codeBadTable, mysql.MySQLErrName[mysql.ErrBadTable]) + ErrKeyDoesNotExist = terror.ClassOptimizer.New(codeKeyDoesNotExist, mysql.MySQLErrName[mysql.ErrKeyDoesNotExist]) + ErrOperandColumns = terror.ClassOptimizer.New(codeOperandColumns, mysql.MySQLErrName[mysql.ErrOperandColumns]) + ErrInvalidWildCard = terror.ClassOptimizer.New(codeInvalidWildCard, "Wildcard fields without any table name appears in wrong place") + ErrInvalidGroupFuncUse = terror.ClassOptimizer.New(codeInvalidGroupFuncUse, mysql.MySQLErrName[mysql.ErrInvalidGroupFuncUse]) + ErrIllegalReference = terror.ClassOptimizer.New(codeIllegalReference, mysql.MySQLErrName[mysql.ErrIllegalReference]) + ErrNoDB = terror.ClassOptimizer.New(codeNoDB, mysql.MySQLErrName[mysql.ErrNoDB]) + ErrUnknownExplainFormat = terror.ClassOptimizer.New(codeUnknownExplainFormat, mysql.MySQLErrName[mysql.ErrUnknownExplainFormat]) + ErrWrongGroupField = terror.ClassOptimizer.New(codeWrongGroupField, mysql.MySQLErrName[mysql.ErrWrongGroupField]) + ErrDupFieldName = terror.ClassOptimizer.New(codeDupFieldName, mysql.MySQLErrName[mysql.ErrDupFieldName]) + ErrNonUpdatableTable = terror.ClassOptimizer.New(codeNonUpdatableTable, mysql.MySQLErrName[mysql.ErrNonUpdatableTable]) + ErrInternal = terror.ClassOptimizer.New(codeInternal, mysql.MySQLErrName[mysql.ErrInternal]) + ErrMixOfGroupFuncAndFields = terror.ClassOptimizer.New(codeMixOfGroupFuncAndFields, "In aggregated query without GROUP BY, expression #%d of SELECT list contains nonaggregated column '%s'; this is incompatible with sql_mode=only_full_group_by") ) func init() { mysqlErrCodeMap := map[terror.ErrCode]uint16{ - codeWrongUsage: mysql.ErrWrongUsage, - codeAmbiguous: mysql.ErrNonUniq, - codeUnknownColumn: mysql.ErrBadField, - codeUnknownTable: mysql.ErrBadTable, - codeWrongArguments: mysql.ErrWrongArguments, - codeBadGeneratedColumn: mysql.ErrBadGeneratedColumn, - codeFieldNotInGroupBy: mysql.ErrFieldNotInGroupBy, - codeBadTable: mysql.ErrBadTable, - codeKeyDoesNotExist: mysql.ErrKeyDoesNotExist, - codeOperandColumns: mysql.ErrOperandColumns, - codeInvalidWildCard: mysql.ErrParse, - codeInvalidGroupFuncUse: mysql.ErrInvalidGroupFuncUse, - codeIllegalReference: mysql.ErrIllegalReference, - codeNoDB: mysql.ErrNoDB, - codeUnknownExplainFormat: mysql.ErrUnknownExplainFormat, - codeWrongGroupField: mysql.ErrWrongGroupField, - codeDupFieldName: mysql.ErrDupFieldName, - codeNonUpdatableTable: mysql.ErrUnknownTable, - codeInternal: mysql.ErrInternal, + codeWrongUsage: mysql.ErrWrongUsage, + codeAmbiguous: mysql.ErrNonUniq, + codeUnknownColumn: mysql.ErrBadField, + codeUnknownTable: mysql.ErrBadTable, + codeWrongArguments: mysql.ErrWrongArguments, + codeBadGeneratedColumn: mysql.ErrBadGeneratedColumn, + codeFieldNotInGroupBy: mysql.ErrFieldNotInGroupBy, + codeBadTable: mysql.ErrBadTable, + codeKeyDoesNotExist: mysql.ErrKeyDoesNotExist, + codeOperandColumns: mysql.ErrOperandColumns, + codeInvalidWildCard: mysql.ErrParse, + codeInvalidGroupFuncUse: mysql.ErrInvalidGroupFuncUse, + codeIllegalReference: mysql.ErrIllegalReference, + codeNoDB: mysql.ErrNoDB, + codeUnknownExplainFormat: mysql.ErrUnknownExplainFormat, + codeWrongGroupField: mysql.ErrWrongGroupField, + codeDupFieldName: mysql.ErrDupFieldName, + codeNonUpdatableTable: mysql.ErrUnknownTable, + codeInternal: mysql.ErrInternal, + codeMixOfGroupFuncAndFields: mysql.ErrMixOfGroupFuncAndFields, } terror.ErrClassToMySQLCodes[terror.ClassOptimizer] = mysqlErrCodeMap } diff --git a/plan/logical_plan_builder.go b/plan/logical_plan_builder.go index 608aaea952a21..6fd8ebfb0e438 100644 --- a/plan/logical_plan_builder.go +++ b/plan/logical_plan_builder.go @@ -1286,6 +1286,14 @@ func checkExprInGroupBy(p LogicalPlan, expr ast.ExprNode, offset int, loc string } func (b *planBuilder) checkOnlyFullGroupBy(p LogicalPlan, fields []*ast.SelectField, orderBy *ast.OrderByClause, gby *ast.GroupByClause, from ast.ResultSetNode, where ast.ExprNode) { + if gby != nil { + b.checkOnlyFullGroupByWithGroupClause(p, fields, orderBy, gby, from, where) + return + } + b.checkOnlyFullGroupByWithOutGroupClause(p, fields) +} + +func (b *planBuilder) checkOnlyFullGroupByWithGroupClause(p LogicalPlan, fields []*ast.SelectField, orderBy *ast.OrderByClause, gby *ast.GroupByClause, from ast.ResultSetNode, where ast.ExprNode) { gbyCols := make(map[*expression.Column]struct{}, len(fields)) gbyExprs := make([]ast.ExprNode, 0, len(fields)) schema := p.Schema() @@ -1342,6 +1350,51 @@ func (b *planBuilder) checkOnlyFullGroupBy(p LogicalPlan, fields []*ast.SelectFi } } +func (b *planBuilder) checkOnlyFullGroupByWithOutGroupClause(p LogicalPlan, fields []*ast.SelectField) { + resolver := colResolverForOnlyFullGroupBy{} + //for idx, field := range fields { + for idx, field := range fields { + resolver.exprIdx = idx + field.Accept(&resolver) + if err := resolver.Check(); err != nil { + b.err = err + return + } + } +} + +type colResolverForOnlyFullGroupBy struct { + firstNonAggCol *ast.ColumnName + exprIdx int + firstNonAggColIdex int + hasAggFunc bool +} + +func (c *colResolverForOnlyFullGroupBy) Enter(node ast.Node) (ast.Node, bool) { + switch node.(type) { + case *ast.AggregateFuncExpr: + c.hasAggFunc = true + return node, true + case *ast.ColumnNameExpr: + if c.firstNonAggCol == nil { + c.firstNonAggCol, c.firstNonAggColIdex = node.(*ast.ColumnNameExpr).Name, c.exprIdx + } + return node, true + } + return node, false +} + +func (c *colResolverForOnlyFullGroupBy) Leave(node ast.Node) (ast.Node, bool) { + return node, true +} + +func (c *colResolverForOnlyFullGroupBy) Check() error { + if c.hasAggFunc && c.firstNonAggCol != nil { + return ErrMixOfGroupFuncAndFields.GenByArgs(c.firstNonAggColIdex+1, c.firstNonAggCol.Name.O) + } + return nil +} + type colResolver struct { p LogicalPlan cols map[*expression.Column]struct{} @@ -1512,10 +1565,11 @@ func (b *planBuilder) buildSelect(sel *ast.SelectStmt) LogicalPlan { if b.err != nil { return nil } - if b.ctx.GetSessionVars().SQLMode.HasOnlyFullGroupBy() { - b.checkOnlyFullGroupBy(p, sel.Fields.Fields, sel.OrderBy, sel.GroupBy, sel.From.TableRefs, sel.Where) - } } + if b.ctx.GetSessionVars().SQLMode.HasOnlyFullGroupBy() && sel.From != nil { + b.checkOnlyFullGroupBy(p, sel.Fields.Fields, sel.OrderBy, sel.GroupBy, sel.From.TableRefs, sel.Where) + } + // We must resolve having and order by clause before build projection, // because when the query is "select a+1 as b from t having sum(b) < 0", we must replace sum(b) to sum(a+1), // which only can be done before building projection and extracting Agg functions. From d13d11ec31ecc4febf96a992e7cf17c0cec146db Mon Sep 17 00:00:00 2001 From: spongedc Date: Sat, 2 Jun 2018 22:16:09 +0800 Subject: [PATCH 2/7] add more tests --- executor/aggregate_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/executor/aggregate_test.go b/executor/aggregate_test.go index 98db26caa8aed..31123c865d7fb 100644 --- a/executor/aggregate_test.go +++ b/executor/aggregate_test.go @@ -431,6 +431,8 @@ func (s *testSuite) TestOnlyFullGroupBy(c *C) { c.Assert(terror.ErrorEqual(err, plan.ErrMixOfGroupFuncAndFields), IsTrue) _, err = tk.Exec("select count(b), c from t") c.Assert(terror.ErrorEqual(err, plan.ErrMixOfGroupFuncAndFields), IsTrue) + _, err = tk.Exec("select distinct a, b, count(a) from t") + c.Assert(terror.ErrorEqual(err, plan.ErrMixOfGroupFuncAndFields), IsTrue) // test compatible with sql_mode = ONLY_FULL_GROUP_BY tk.MustQuery("select a from t group by a,b,c") tk.MustQuery("select b from t group by b") From a0c7e949a2c3a6bff8a079740501423faf4a89f7 Mon Sep 17 00:00:00 2001 From: spongedc Date: Tue, 5 Jun 2018 07:41:06 +0800 Subject: [PATCH 3/7] code refine --- plan/logical_plan_builder.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plan/logical_plan_builder.go b/plan/logical_plan_builder.go index 6fd8ebfb0e438..ec0112436b564 100644 --- a/plan/logical_plan_builder.go +++ b/plan/logical_plan_builder.go @@ -1352,7 +1352,6 @@ func (b *planBuilder) checkOnlyFullGroupByWithGroupClause(p LogicalPlan, fields func (b *planBuilder) checkOnlyFullGroupByWithOutGroupClause(p LogicalPlan, fields []*ast.SelectField) { resolver := colResolverForOnlyFullGroupBy{} - //for idx, field := range fields { for idx, field := range fields { resolver.exprIdx = idx field.Accept(&resolver) @@ -1363,10 +1362,12 @@ func (b *planBuilder) checkOnlyFullGroupByWithOutGroupClause(p LogicalPlan, fiel } } +// colResolverForOnlyFullGroupBy visits Expr tree to find out if an Expr tree is an aggregation function. +// If so, find out the first column name that not in an aggregation function. type colResolverForOnlyFullGroupBy struct { firstNonAggCol *ast.ColumnName exprIdx int - firstNonAggColIdex int + firstNonAggColIdx int hasAggFunc bool } @@ -1377,7 +1378,7 @@ func (c *colResolverForOnlyFullGroupBy) Enter(node ast.Node) (ast.Node, bool) { return node, true case *ast.ColumnNameExpr: if c.firstNonAggCol == nil { - c.firstNonAggCol, c.firstNonAggColIdex = node.(*ast.ColumnNameExpr).Name, c.exprIdx + c.firstNonAggCol, c.firstNonAggColIdx = node.(*ast.ColumnNameExpr).Name, c.exprIdx } return node, true } @@ -1390,7 +1391,7 @@ func (c *colResolverForOnlyFullGroupBy) Leave(node ast.Node) (ast.Node, bool) { func (c *colResolverForOnlyFullGroupBy) Check() error { if c.hasAggFunc && c.firstNonAggCol != nil { - return ErrMixOfGroupFuncAndFields.GenByArgs(c.firstNonAggColIdex+1, c.firstNonAggCol.Name.O) + return ErrMixOfGroupFuncAndFields.GenByArgs(c.firstNonAggColIdx+1, c.firstNonAggCol.Name.O) } return nil } From f96eebaf07c23f6de53d85e18b029866827a7c95 Mon Sep 17 00:00:00 2001 From: spongedc Date: Tue, 5 Jun 2018 10:43:31 +0800 Subject: [PATCH 4/7] Refine code format --- plan/logical_plan_builder.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plan/logical_plan_builder.go b/plan/logical_plan_builder.go index ec0112436b564..f39e5dde5c404 100644 --- a/plan/logical_plan_builder.go +++ b/plan/logical_plan_builder.go @@ -1365,10 +1365,10 @@ func (b *planBuilder) checkOnlyFullGroupByWithOutGroupClause(p LogicalPlan, fiel // colResolverForOnlyFullGroupBy visits Expr tree to find out if an Expr tree is an aggregation function. // If so, find out the first column name that not in an aggregation function. type colResolverForOnlyFullGroupBy struct { - firstNonAggCol *ast.ColumnName - exprIdx int + firstNonAggCol *ast.ColumnName + exprIdx int firstNonAggColIdx int - hasAggFunc bool + hasAggFunc bool } func (c *colResolverForOnlyFullGroupBy) Enter(node ast.Node) (ast.Node, bool) { From e0d9b9c82caf241b04c397148ab144dd80f770f6 Mon Sep 17 00:00:00 2001 From: spongedc Date: Fri, 8 Jun 2018 14:36:24 +0800 Subject: [PATCH 5/7] code refine --- plan/logical_plan_builder.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plan/logical_plan_builder.go b/plan/logical_plan_builder.go index 1dc16d401e2e9..1db44c5f23a37 100644 --- a/plan/logical_plan_builder.go +++ b/plan/logical_plan_builder.go @@ -1408,7 +1408,7 @@ func (b *planBuilder) checkOnlyFullGroupByWithOutGroupClause(p LogicalPlan, fiel resolver.exprIdx = idx field.Accept(&resolver) if err := resolver.Check(); err != nil { - b.err = err + b.err = errors.Trace(err) return } } @@ -1424,13 +1424,13 @@ type colResolverForOnlyFullGroupBy struct { } func (c *colResolverForOnlyFullGroupBy) Enter(node ast.Node) (ast.Node, bool) { - switch node.(type) { + switch t := node.(type) { case *ast.AggregateFuncExpr: c.hasAggFunc = true return node, true case *ast.ColumnNameExpr: if c.firstNonAggCol == nil { - c.firstNonAggCol, c.firstNonAggColIdx = node.(*ast.ColumnNameExpr).Name, c.exprIdx + c.firstNonAggCol, c.firstNonAggColIdx = t.Name, c.exprIdx } return node, true } From 8b4e13d758ccc1032c6d2dd0135c0d560e495f95 Mon Sep 17 00:00:00 2001 From: spongedc Date: Fri, 8 Jun 2018 14:58:45 +0800 Subject: [PATCH 6/7] fix merge error --- plan/errors.go | 129 +++++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 63 deletions(-) diff --git a/plan/errors.go b/plan/errors.go index ca85752657ab6..086e11e7f1434 100644 --- a/plan/errors.go +++ b/plan/errors.go @@ -26,27 +26,28 @@ const ( codeWrongParamCount = 5 codeSchemaChanged = 6 - codeWrongUsage = mysql.ErrWrongUsage - codeAmbiguous = mysql.ErrNonUniq - codeUnknownColumn = mysql.ErrBadField - codeUnknownTable = mysql.ErrUnknownTable - codeWrongArguments = mysql.ErrWrongArguments - codeBadGeneratedColumn = mysql.ErrBadGeneratedColumn - codeFieldNotInGroupBy = mysql.ErrFieldNotInGroupBy - codeBadTable = mysql.ErrBadTable - codeKeyDoesNotExist = mysql.ErrKeyDoesNotExist - codeOperandColumns = mysql.ErrOperandColumns - codeInvalidWildCard = mysql.ErrParse - codeInvalidGroupFuncUse = mysql.ErrInvalidGroupFuncUse - codeIllegalReference = mysql.ErrIllegalReference - codeNoDB = mysql.ErrNoDB - codeUnknownExplainFormat = mysql.ErrUnknownExplainFormat - codeWrongGroupField = mysql.ErrWrongGroupField - codeDupFieldName = mysql.ErrDupFieldName - codeNonUpdatableTable = mysql.ErrNonUpdatableTable - codeInternal = mysql.ErrInternal - codeMixOfGroupFuncAndFields = mysql.ErrMixOfGroupFuncAndFields - codeNonUniqTable = mysql.ErrNonuniqTable + codeWrongUsage = mysql.ErrWrongUsage + codeAmbiguous = mysql.ErrNonUniq + codeUnknownColumn = mysql.ErrBadField + codeUnknownTable = mysql.ErrUnknownTable + codeWrongArguments = mysql.ErrWrongArguments + codeBadGeneratedColumn = mysql.ErrBadGeneratedColumn + codeFieldNotInGroupBy = mysql.ErrFieldNotInGroupBy + codeBadTable = mysql.ErrBadTable + codeKeyDoesNotExist = mysql.ErrKeyDoesNotExist + codeOperandColumns = mysql.ErrOperandColumns + codeInvalidWildCard = mysql.ErrParse + codeInvalidGroupFuncUse = mysql.ErrInvalidGroupFuncUse + codeIllegalReference = mysql.ErrIllegalReference + codeNoDB = mysql.ErrNoDB + codeUnknownExplainFormat = mysql.ErrUnknownExplainFormat + codeWrongGroupField = mysql.ErrWrongGroupField + codeDupFieldName = mysql.ErrDupFieldName + codeNonUpdatableTable = mysql.ErrNonUpdatableTable + codeInternal = mysql.ErrInternal + codeMixOfGroupFuncAndFields = mysql.ErrMixOfGroupFuncAndFields + codeNonUniqTable = mysql.ErrNonuniqTable + codeWrongNumberOfColumnsInSelect = mysql.ErrWrongNumberOfColumnsInSelect ) // error definitions. @@ -58,52 +59,54 @@ var ( ErrWrongParamCount = terror.ClassOptimizer.New(codeWrongParamCount, "Wrong parameter count") ErrSchemaChanged = terror.ClassOptimizer.New(codeSchemaChanged, "Schema has changed") - ErrWrongUsage = terror.ClassOptimizer.New(codeWrongUsage, mysql.MySQLErrName[mysql.ErrWrongUsage]) - ErrAmbiguous = terror.ClassOptimizer.New(codeAmbiguous, mysql.MySQLErrName[mysql.ErrNonUniq]) - ErrUnknownColumn = terror.ClassOptimizer.New(codeUnknownColumn, mysql.MySQLErrName[mysql.ErrBadField]) - ErrUnknownTable = terror.ClassOptimizer.New(codeUnknownTable, mysql.MySQLErrName[mysql.ErrUnknownTable]) - ErrWrongArguments = terror.ClassOptimizer.New(codeWrongArguments, mysql.MySQLErrName[mysql.ErrWrongArguments]) - ErrBadGeneratedColumn = terror.ClassOptimizer.New(codeBadGeneratedColumn, mysql.MySQLErrName[mysql.ErrBadGeneratedColumn]) - ErrFieldNotInGroupBy = terror.ClassOptimizer.New(codeFieldNotInGroupBy, mysql.MySQLErrName[mysql.ErrFieldNotInGroupBy]) - ErrBadTable = terror.ClassOptimizer.New(codeBadTable, mysql.MySQLErrName[mysql.ErrBadTable]) - ErrKeyDoesNotExist = terror.ClassOptimizer.New(codeKeyDoesNotExist, mysql.MySQLErrName[mysql.ErrKeyDoesNotExist]) - ErrOperandColumns = terror.ClassOptimizer.New(codeOperandColumns, mysql.MySQLErrName[mysql.ErrOperandColumns]) - ErrInvalidWildCard = terror.ClassOptimizer.New(codeInvalidWildCard, "Wildcard fields without any table name appears in wrong place") - ErrInvalidGroupFuncUse = terror.ClassOptimizer.New(codeInvalidGroupFuncUse, mysql.MySQLErrName[mysql.ErrInvalidGroupFuncUse]) - ErrIllegalReference = terror.ClassOptimizer.New(codeIllegalReference, mysql.MySQLErrName[mysql.ErrIllegalReference]) - ErrNoDB = terror.ClassOptimizer.New(codeNoDB, mysql.MySQLErrName[mysql.ErrNoDB]) - ErrUnknownExplainFormat = terror.ClassOptimizer.New(codeUnknownExplainFormat, mysql.MySQLErrName[mysql.ErrUnknownExplainFormat]) - ErrWrongGroupField = terror.ClassOptimizer.New(codeWrongGroupField, mysql.MySQLErrName[mysql.ErrWrongGroupField]) - ErrDupFieldName = terror.ClassOptimizer.New(codeDupFieldName, mysql.MySQLErrName[mysql.ErrDupFieldName]) - ErrNonUpdatableTable = terror.ClassOptimizer.New(codeNonUpdatableTable, mysql.MySQLErrName[mysql.ErrNonUpdatableTable]) - ErrInternal = terror.ClassOptimizer.New(codeInternal, mysql.MySQLErrName[mysql.ErrInternal]) - ErrMixOfGroupFuncAndFields = terror.ClassOptimizer.New(codeMixOfGroupFuncAndFields, "In aggregated query without GROUP BY, expression #%d of SELECT list contains nonaggregated column '%s'; this is incompatible with sql_mode=only_full_group_by") - ErrNonUniqTable = terror.ClassOptimizer.New(codeNonUniqTable, mysql.MySQLErrName[mysql.ErrNonuniqTable]) + ErrWrongUsage = terror.ClassOptimizer.New(codeWrongUsage, mysql.MySQLErrName[mysql.ErrWrongUsage]) + ErrAmbiguous = terror.ClassOptimizer.New(codeAmbiguous, mysql.MySQLErrName[mysql.ErrNonUniq]) + ErrUnknownColumn = terror.ClassOptimizer.New(codeUnknownColumn, mysql.MySQLErrName[mysql.ErrBadField]) + ErrUnknownTable = terror.ClassOptimizer.New(codeUnknownTable, mysql.MySQLErrName[mysql.ErrUnknownTable]) + ErrWrongArguments = terror.ClassOptimizer.New(codeWrongArguments, mysql.MySQLErrName[mysql.ErrWrongArguments]) + ErrWrongNumberOfColumnsInSelect = terror.ClassOptimizer.New(codeWrongNumberOfColumnsInSelect, mysql.MySQLErrName[mysql.ErrWrongNumberOfColumnsInSelect]) + ErrBadGeneratedColumn = terror.ClassOptimizer.New(codeBadGeneratedColumn, mysql.MySQLErrName[mysql.ErrBadGeneratedColumn]) + ErrFieldNotInGroupBy = terror.ClassOptimizer.New(codeFieldNotInGroupBy, mysql.MySQLErrName[mysql.ErrFieldNotInGroupBy]) + ErrBadTable = terror.ClassOptimizer.New(codeBadTable, mysql.MySQLErrName[mysql.ErrBadTable]) + ErrKeyDoesNotExist = terror.ClassOptimizer.New(codeKeyDoesNotExist, mysql.MySQLErrName[mysql.ErrKeyDoesNotExist]) + ErrOperandColumns = terror.ClassOptimizer.New(codeOperandColumns, mysql.MySQLErrName[mysql.ErrOperandColumns]) + ErrInvalidWildCard = terror.ClassOptimizer.New(codeInvalidWildCard, "Wildcard fields without any table name appears in wrong place") + ErrInvalidGroupFuncUse = terror.ClassOptimizer.New(codeInvalidGroupFuncUse, mysql.MySQLErrName[mysql.ErrInvalidGroupFuncUse]) + ErrIllegalReference = terror.ClassOptimizer.New(codeIllegalReference, mysql.MySQLErrName[mysql.ErrIllegalReference]) + ErrNoDB = terror.ClassOptimizer.New(codeNoDB, mysql.MySQLErrName[mysql.ErrNoDB]) + ErrUnknownExplainFormat = terror.ClassOptimizer.New(codeUnknownExplainFormat, mysql.MySQLErrName[mysql.ErrUnknownExplainFormat]) + ErrWrongGroupField = terror.ClassOptimizer.New(codeWrongGroupField, mysql.MySQLErrName[mysql.ErrWrongGroupField]) + ErrDupFieldName = terror.ClassOptimizer.New(codeDupFieldName, mysql.MySQLErrName[mysql.ErrDupFieldName]) + ErrNonUpdatableTable = terror.ClassOptimizer.New(codeNonUpdatableTable, mysql.MySQLErrName[mysql.ErrNonUpdatableTable]) + ErrInternal = terror.ClassOptimizer.New(codeInternal, mysql.MySQLErrName[mysql.ErrInternal]) + ErrMixOfGroupFuncAndFields = terror.ClassOptimizer.New(codeMixOfGroupFuncAndFields, "In aggregated query without GROUP BY, expression #%d of SELECT list contains nonaggregated column '%s'; this is incompatible with sql_mode=only_full_group_by") + ErrNonUniqTable = terror.ClassOptimizer.New(codeNonUniqTable, mysql.MySQLErrName[mysql.ErrNonuniqTable]) ) func init() { mysqlErrCodeMap := map[terror.ErrCode]uint16{ - codeWrongUsage: mysql.ErrWrongUsage, - codeAmbiguous: mysql.ErrNonUniq, - codeUnknownColumn: mysql.ErrBadField, - codeUnknownTable: mysql.ErrBadTable, - codeWrongArguments: mysql.ErrWrongArguments, - codeBadGeneratedColumn: mysql.ErrBadGeneratedColumn, - codeFieldNotInGroupBy: mysql.ErrFieldNotInGroupBy, - codeBadTable: mysql.ErrBadTable, - codeKeyDoesNotExist: mysql.ErrKeyDoesNotExist, - codeOperandColumns: mysql.ErrOperandColumns, - codeInvalidWildCard: mysql.ErrParse, - codeInvalidGroupFuncUse: mysql.ErrInvalidGroupFuncUse, - codeIllegalReference: mysql.ErrIllegalReference, - codeNoDB: mysql.ErrNoDB, - codeUnknownExplainFormat: mysql.ErrUnknownExplainFormat, - codeWrongGroupField: mysql.ErrWrongGroupField, - codeDupFieldName: mysql.ErrDupFieldName, - codeNonUpdatableTable: mysql.ErrUnknownTable, - codeInternal: mysql.ErrInternal, - codeMixOfGroupFuncAndFields: mysql.ErrMixOfGroupFuncAndFields, - codeNonUniqTable: mysql.ErrNonuniqTable, + codeWrongUsage: mysql.ErrWrongUsage, + codeAmbiguous: mysql.ErrNonUniq, + codeUnknownColumn: mysql.ErrBadField, + codeUnknownTable: mysql.ErrBadTable, + codeWrongArguments: mysql.ErrWrongArguments, + codeBadGeneratedColumn: mysql.ErrBadGeneratedColumn, + codeFieldNotInGroupBy: mysql.ErrFieldNotInGroupBy, + codeBadTable: mysql.ErrBadTable, + codeKeyDoesNotExist: mysql.ErrKeyDoesNotExist, + codeOperandColumns: mysql.ErrOperandColumns, + codeInvalidWildCard: mysql.ErrParse, + codeInvalidGroupFuncUse: mysql.ErrInvalidGroupFuncUse, + codeIllegalReference: mysql.ErrIllegalReference, + codeNoDB: mysql.ErrNoDB, + codeUnknownExplainFormat: mysql.ErrUnknownExplainFormat, + codeWrongGroupField: mysql.ErrWrongGroupField, + codeDupFieldName: mysql.ErrDupFieldName, + codeNonUpdatableTable: mysql.ErrUnknownTable, + codeInternal: mysql.ErrInternal, + codeMixOfGroupFuncAndFields: mysql.ErrMixOfGroupFuncAndFields, + codeNonUniqTable: mysql.ErrNonuniqTable, + codeWrongNumberOfColumnsInSelect: mysql.ErrWrongNumberOfColumnsInSelect, } terror.ErrClassToMySQLCodes[terror.ClassOptimizer] = mysqlErrCodeMap } From b5589a436c2e3d9499c57c666ca150c6d52f967b Mon Sep 17 00:00:00 2001 From: "duchuan.dc" Date: Wed, 13 Jun 2018 15:09:21 +0800 Subject: [PATCH 7/7] refine tests --- executor/aggregate_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executor/aggregate_test.go b/executor/aggregate_test.go index 31123c865d7fb..1aeff3d1dda83 100644 --- a/executor/aggregate_test.go +++ b/executor/aggregate_test.go @@ -454,7 +454,7 @@ func (s *testSuite) TestOnlyFullGroupBy(c *C) { tk.MustQuery("select -b from t group by b") tk.MustQuery("select max(a+b) from t") tk.MustQuery("select avg(a)+1 from t") - _, err = tk.Exec("select count(c), 5 from t") + tk.MustQuery("select count(c), 5 from t") // test functinal depend on primary key tk.MustQuery("select * from t group by a") // test functional depend on unique not null columns