diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 177cd4ebba7d2..86db2daa270ec 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -7617,14 +7617,11 @@ func checkIgnorePlacementDDL(ctx sessionctx.Context) bool { // AddResourceGroup implements the DDL interface, creates a resource group. func (d *ddl) AddResourceGroup(ctx sessionctx.Context, stmt *ast.CreateResourceGroupStmt) (err error) { - groupInfo := &model.ResourceGroupInfo{ResourceGroupSettings: &model.ResourceGroupSettings{}} groupName := stmt.ResourceGroupName - groupInfo.Name = groupName - for _, opt := range stmt.ResourceGroupOptionList { - err := SetDirectResourceGroupUnit(groupInfo.ResourceGroupSettings, opt.Tp, opt.StrValue, opt.UintValue, opt.BoolValue) - if err != nil { - return err - } + groupInfo := &model.ResourceGroupInfo{Name: groupName, ResourceGroupSettings: &model.ResourceGroupSettings{}} + groupInfo, err = buildResourceGroup(groupInfo, stmt.ResourceGroupOptionList) + if err != nil { + return err } if _, ok := d.GetInfoSchemaWithInterceptor(ctx).ResourceGroupByName(groupName); ok { @@ -7713,6 +7710,7 @@ func buildResourceGroup(oldGroup *model.ResourceGroupInfo, options []*ast.Resour return nil, err } } + groupInfo.ResourceGroupSettings.Adjust() return groupInfo, nil } diff --git a/ddl/resource_group_test.go b/ddl/resource_group_test.go index fcc547ec42f8d..162a3ac233a05 100644 --- a/ddl/resource_group_test.go +++ b/ddl/resource_group_test.go @@ -87,7 +87,7 @@ func TestResourceGroupBasic(t *testing.T) { re.Equal(uint64(2000), g.RURate) re.Equal(int64(-1), g.BurstLimit) - tk.MustQuery("select * from information_schema.resource_groups where name = 'x'").Check(testkit.Rows("x 2000 0 YES")) + tk.MustQuery("select * from information_schema.resource_groups where name = 'x'").Check(testkit.Rows("x 2000 YES")) tk.MustExec("drop resource group x") g = testResourceGroupNameFromIS(t, tk.Session(), "x") @@ -104,7 +104,7 @@ func TestResourceGroupBasic(t *testing.T) { require.Equal(t, "y", groupInfo.Name.L) require.Equal(t, groupID, groupInfo.ID) require.Equal(t, uint64(4000), groupInfo.RURate) - require.Equal(t, int64(0), groupInfo.BurstLimit) + require.Equal(t, int64(4000), groupInfo.BurstLimit) } g = testResourceGroupNameFromIS(t, tk.Session(), "y") checkFunc(g) @@ -126,25 +126,29 @@ func TestResourceGroupBasic(t *testing.T) { tk.MustContainErrMsg("create resource group x ru_per_sec=1000 ru_per_sec=200, ru_per_sec=300", "Dupliated options specified") tk.MustGetErrCode("create resource group x burstable, burstable", mysql.ErrParse) tk.MustContainErrMsg("create resource group x burstable, burstable", "Dupliated options specified") + tk.MustGetErrCode("create resource group x ru_per_sec=1000, burstable, burstable", mysql.ErrParse) + tk.MustContainErrMsg("create resource group x ru_per_sec=1000, burstable, burstable", "Dupliated options specified") + tk.MustGetErrCode("create resource group x burstable, ru_per_sec=1000, burstable", mysql.ErrParse) + tk.MustContainErrMsg("create resource group x burstable, ru_per_sec=1000, burstable", "Dupliated options specified") groups, err := infosync.ListResourceGroups(context.TODO()) require.Equal(t, 0, len(groups)) require.NoError(t, err) // Check information schema table information_schema.resource_groups tk.MustExec("create resource group x RU_PER_SEC=1000") - tk.MustQuery("select * from information_schema.resource_groups where name = 'x'").Check(testkit.Rows("x 1000 0 NO")) + tk.MustQuery("select * from information_schema.resource_groups where name = 'x'").Check(testkit.Rows("x 1000 NO")) tk.MustExec("alter resource group x RU_PER_SEC=2000 BURSTABLE") - tk.MustQuery("select * from information_schema.resource_groups where name = 'x'").Check(testkit.Rows("x 2000 0 YES")) + tk.MustQuery("select * from information_schema.resource_groups where name = 'x'").Check(testkit.Rows("x 2000 YES")) tk.MustExec("alter resource group x BURSTABLE RU_PER_SEC=3000") - tk.MustQuery("select * from information_schema.resource_groups where name = 'x'").Check(testkit.Rows("x 3000 0 YES")) + tk.MustQuery("select * from information_schema.resource_groups where name = 'x'").Check(testkit.Rows("x 3000 YES")) tk.MustQuery("show create resource group x").Check(testkit.Rows("x CREATE RESOURCE GROUP `x` RU_PER_SEC=3000 BURSTABLE")) tk.MustExec("create resource group y BURSTABLE RU_PER_SEC=2000") - tk.MustQuery("select * from information_schema.resource_groups where name = 'y'").Check(testkit.Rows("y 2000 0 YES")) + tk.MustQuery("select * from information_schema.resource_groups where name = 'y'").Check(testkit.Rows("y 2000 YES")) tk.MustQuery("show create resource group y").Check(testkit.Rows("y CREATE RESOURCE GROUP `y` RU_PER_SEC=2000 BURSTABLE")) tk.MustExec("alter resource group y RU_PER_SEC=4000 BURSTABLE") - tk.MustQuery("select * from information_schema.resource_groups where name = 'y'").Check(testkit.Rows("y 4000 0 YES")) + tk.MustQuery("select * from information_schema.resource_groups where name = 'y'").Check(testkit.Rows("y 4000 YES")) tk.MustQuery("show create resource group y").Check(testkit.Rows("y CREATE RESOURCE GROUP `y` RU_PER_SEC=4000 BURSTABLE")) tk.MustQuery("select count(*) from information_schema.resource_groups").Check(testkit.Rows("2")) diff --git a/executor/infoschema_reader.go b/executor/infoschema_reader.go index a016d5a459df1..d3e94d5b77353 100644 --- a/executor/infoschema_reader.go +++ b/executor/infoschema_reader.go @@ -3406,7 +3406,6 @@ func (e *memtableRetriever) setDataFromResourceGroups() error { row := types.MakeDatums( group.Name, group.RUSettings.RU.Settings.FillRate, - uint64(group.RUSettings.RU.Tokens), burstable, ) rows = append(rows, row) @@ -3416,7 +3415,6 @@ func (e *memtableRetriever) setDataFromResourceGroups() error { group.Name, nil, nil, - nil, ) rows = append(rows, row) } diff --git a/infoschema/tables.go b/infoschema/tables.go index 3cbf9ee1b464f..7a2631b4abe13 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -1595,7 +1595,6 @@ var tableMemoryUsageOpsHistoryCols = []columnInfo{ var tableResourceGroupsCols = []columnInfo{ {name: "NAME", tp: mysql.TypeVarchar, size: resourcegroup.MaxGroupNameLength, flag: mysql.NotNullFlag}, {name: "RU_PER_SEC", tp: mysql.TypeLonglong, size: 21}, - {name: "RU_TOKENS", tp: mysql.TypeLonglong, size: 21}, {name: "BURSTABLE", tp: mysql.TypeVarchar, size: 3}, } diff --git a/parser/model/model.go b/parser/model/model.go index d530bea00ac9c..25afd90b4a47c 100644 --- a/parser/model/model.go +++ b/parser/model/model.go @@ -1875,6 +1875,14 @@ func (p *ResourceGroupSettings) String() string { return sb.String() } +// Adjust adjusts the resource group settings. +func (p *ResourceGroupSettings) Adjust() { + // Curretly we only support ru_per_sec sytanx, so BurstLimit(capicity) is always same as ru_per_sec. + if p.BurstLimit == 0 { + p.BurstLimit = int64(p.RURate) + } +} + // Clone clones the resource group settings. func (p *ResourceGroupSettings) Clone() *ResourceGroupSettings { cloned := *p diff --git a/parser/parser.go b/parser/parser.go index 816226256ecf0..303aa5b3158de 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -11970,19 +11970,21 @@ yynewstate: } case 10: { - parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.ResourceGroupOption), yyS[yypt-0].item.(*ast.ResourceGroupOption)) - if yyS[yypt-1].item.([]*ast.ResourceGroupOption)[0].Tp == yyS[yypt-0].item.(*ast.ResourceGroupOption).Tp { + if yyS[yypt-1].item.([]*ast.ResourceGroupOption)[0].Tp == yyS[yypt-0].item.(*ast.ResourceGroupOption).Tp || + (len(yyS[yypt-1].item.([]*ast.ResourceGroupOption)) > 1 && yyS[yypt-1].item.([]*ast.ResourceGroupOption)[1].Tp == yyS[yypt-0].item.(*ast.ResourceGroupOption).Tp) { yylex.AppendError(yylex.Errorf("Dupliated options specified")) return 1 } + parser.yyVAL.item = append(yyS[yypt-1].item.([]*ast.ResourceGroupOption), yyS[yypt-0].item.(*ast.ResourceGroupOption)) } case 11: { - parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.ResourceGroupOption), yyS[yypt-0].item.(*ast.ResourceGroupOption)) - if yyS[yypt-2].item.([]*ast.ResourceGroupOption)[0].Tp == yyS[yypt-0].item.(*ast.ResourceGroupOption).Tp { + if yyS[yypt-2].item.([]*ast.ResourceGroupOption)[0].Tp == yyS[yypt-0].item.(*ast.ResourceGroupOption).Tp || + (len(yyS[yypt-2].item.([]*ast.ResourceGroupOption)) > 1 && yyS[yypt-2].item.([]*ast.ResourceGroupOption)[1].Tp == yyS[yypt-0].item.(*ast.ResourceGroupOption).Tp) { yylex.AppendError(yylex.Errorf("Dupliated options specified")) return 1 } + parser.yyVAL.item = append(yyS[yypt-2].item.([]*ast.ResourceGroupOption), yyS[yypt-0].item.(*ast.ResourceGroupOption)) } case 12: { diff --git a/parser/parser.y b/parser/parser.y index 31c32ca7f4d34..83d91e8803349 100644 --- a/parser/parser.y +++ b/parser/parser.y @@ -1599,19 +1599,21 @@ ResourceGroupOptionList: } | ResourceGroupOptionList DirectResourceGroupOption { - $$ = append($1.([]*ast.ResourceGroupOption), $2.(*ast.ResourceGroupOption)) - if $1.([]*ast.ResourceGroupOption)[0].Tp == $2.(*ast.ResourceGroupOption).Tp { + if $1.([]*ast.ResourceGroupOption)[0].Tp == $2.(*ast.ResourceGroupOption).Tp || + (len($1.([]*ast.ResourceGroupOption)) > 1 && $1.([]*ast.ResourceGroupOption)[1].Tp == $2.(*ast.ResourceGroupOption).Tp) { yylex.AppendError(yylex.Errorf("Dupliated options specified")) return 1 } + $$ = append($1.([]*ast.ResourceGroupOption), $2.(*ast.ResourceGroupOption)) } | ResourceGroupOptionList ',' DirectResourceGroupOption { + if $1.([]*ast.ResourceGroupOption)[0].Tp == $3.(*ast.ResourceGroupOption).Tp || + (len($1.([]*ast.ResourceGroupOption)) > 1 && $1.([]*ast.ResourceGroupOption)[1].Tp == $3.(*ast.ResourceGroupOption).Tp) { + yylex.AppendError(yylex.Errorf("Dupliated options specified")) + return 1 + } $$ = append($1.([]*ast.ResourceGroupOption), $3.(*ast.ResourceGroupOption)) - if $1.([]*ast.ResourceGroupOption)[0].Tp == $3.(*ast.ResourceGroupOption).Tp { - yylex.AppendError(yylex.Errorf("Dupliated options specified")) - return 1 - } } DirectResourceGroupOption: