Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: bind user to some resource group #39561

Merged
merged 21 commits into from
Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3304176
*: add support to create/alter user with resource group option (#26)
BornChanger Nov 17, 2022
ad41e83
*: pass user's resource group name to sessionVars.ResourceGroupName (…
BornChanger Nov 17, 2022
f367d60
*: add new case
BornChanger Dec 1, 2022
57943db
*: rebase and add unit test case
BornChanger Dec 6, 2022
fb2d66f
*: reformat the json column to address review comment
BornChanger Dec 6, 2022
a86dd8c
*: refactor the new syntax
BornChanger Dec 6, 2022
5565066
executor: fix compiler warning
BornChanger Dec 6, 2022
7cef273
Update executor/simple.go
BornChanger Dec 7, 2022
e9ae4c9
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
4b4afc4
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
a4562a1
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
8353889
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
d74f2ba
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
f9d2799
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
3f19d4f
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
1ea6455
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
fc4a9c9
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
fedbf1a
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
1f0e7a3
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
36b57d4
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
3ee0500
Merge branch 'master' into bind_resource_group
ti-chi-bot Dec 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 22 additions & 7 deletions executor/simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -946,14 +946,23 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm
passwdlockinfo.passwordExpired = "Y"
}

var userAttributes any = nil
var userAttributes []string

if s.CommentOrAttributeOption != nil {
if s.CommentOrAttributeOption.Type == ast.UserCommentType {
userAttributes = fmt.Sprintf("{\"metadata\": {\"comment\": \"%s\"}}", s.CommentOrAttributeOption.Value)
userAttributes = append(userAttributes, fmt.Sprintf("\"metadata\": {\"comment\": \"%s\"}", s.CommentOrAttributeOption.Value))
} else if s.CommentOrAttributeOption.Type == ast.UserAttributeType {
userAttributes = fmt.Sprintf("{\"metadata\": %s}", s.CommentOrAttributeOption.Value)
userAttributes = append(userAttributes, fmt.Sprintf("\"metadata\": %s", s.CommentOrAttributeOption.Value))
}
}
resourceGroupName := "default"
if s.ResourceGroupNameOption != nil {
if s.ResourceGroupNameOption.Type == ast.UserResourceGroupName {
resourceGroupName = s.ResourceGroupNameOption.Value
}
}
userAttributes = append(userAttributes, fmt.Sprintf("\"resource_group\": \"%s\"", resourceGroupName))
userAttributesStr := fmt.Sprintf("{%s}", strings.Join(userAttributes, ","))

tokenIssuer := ""
for _, authTokenOption := range s.AuthTokenOrTLSOptions {
Expand Down Expand Up @@ -1043,7 +1052,7 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm
}

hostName := strings.ToLower(spec.User.Hostname)
sqlexec.MustFormatSQL(sql, valueTemplate, hostName, spec.User.Username, pwd, authPlugin, userAttributes, passwdlockinfo.lockAccount, recordTokenIssuer, passwdlockinfo.passwordExpired, passwdlockinfo.passwordLifetime)
sqlexec.MustFormatSQL(sql, valueTemplate, hostName, spec.User.Username, pwd, authPlugin, userAttributesStr, passwdlockinfo.lockAccount, recordTokenIssuer, passwdlockinfo.passwordExpired, passwdlockinfo.passwordLifetime)
// add Password_reuse_time value.
if passwdlockinfo.passwordReuseInterval != notSpecified {
sqlexec.MustFormatSQL(sql, `, %?`, passwdlockinfo.passwordReuseInterval)
Expand Down Expand Up @@ -1583,13 +1592,19 @@ func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt)
fields = append(fields, alterField{"password_lifetime=%?", passwdlockinfo.passwordLifetime})
}

var newAttributes []string
if s.CommentOrAttributeOption != nil {
newAttributesStr := ""
if s.CommentOrAttributeOption.Type == ast.UserCommentType {
newAttributesStr = fmt.Sprintf(`{"metadata": {"comment": "%s"}}`, s.CommentOrAttributeOption.Value)
newAttributes = append(newAttributes, fmt.Sprintf(`"metadata": {"comment": "%s"}`, s.CommentOrAttributeOption.Value))
} else {
newAttributesStr = fmt.Sprintf(`{"metadata": %s}`, s.CommentOrAttributeOption.Value)
newAttributes = append(newAttributes, fmt.Sprintf(`"metadata": %s`, s.CommentOrAttributeOption.Value))
}
}
if s.ResourceGroupNameOption != nil && s.ResourceGroupNameOption.Type == ast.UserResourceGroupName {
newAttributes = append(newAttributes, fmt.Sprintf(`"resource_group": "%s"`, s.ResourceGroupNameOption.Value))
}
if len(newAttributes) > 0 {
newAttributesStr := fmt.Sprintf("{%s}", strings.Join(newAttributes, ","))
fields = append(fields, alterField{"user_attributes=json_merge_patch(coalesce(user_attributes, '{}'), %?)", newAttributesStr})
}

Expand Down
10 changes: 6 additions & 4 deletions executor/simple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ func TestUserAttributes(t *testing.T) {
_, err := rootTK.Exec(`CREATE USER testuser2 ATTRIBUTE '{"name": "Tom", age: 19}'`)
rootTK.MustExec(`CREATE USER testuser2`)
require.Error(t, err)
rootTK.MustQuery(`SELECT user_attributes FROM mysql.user WHERE user = 'testuser'`).Check(testkit.Rows(`{"metadata": {"comment": "1234"}}`))
rootTK.MustQuery(`SELECT user_attributes FROM mysql.user WHERE user = 'testuser1'`).Check(testkit.Rows(`{"metadata": {"age": 19, "name": "Tom"}}`))
rootTK.MustQuery(`SELECT user_attributes FROM mysql.user WHERE user = 'testuser2'`).Check(testkit.Rows(`<nil>`))
rootTK.MustQuery(`SELECT user_attributes FROM mysql.user WHERE user = 'testuser'`).Check(testkit.Rows(`{"metadata": {"comment": "1234"}, "resource_group": "default"}`))
rootTK.MustQuery(`SELECT user_attributes FROM mysql.user WHERE user = 'testuser1'`).Check(testkit.Rows(`{"metadata": {"age": 19, "name": "Tom"}, "resource_group": "default"}`))
rootTK.MustQuery(`SELECT user_attributes FROM mysql.user WHERE user = 'testuser2'`).Check(testkit.Rows(`{"resource_group": "default"}`))
rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser'`).Check(testkit.Rows(`{"comment": "1234"}`))
rootTK.MustQueryWithContext(ctx, `SELECT attribute FROM information_schema.user_attributes WHERE user = 'testuser1'`).Check(testkit.Rows(`{"age": 19, "name": "Tom"}`))
rootTK.MustQueryWithContext(ctx, `SELECT attribute->>"$.age" AS age, attribute->>"$.name" AS name FROM information_schema.user_attributes WHERE user = 'testuser1'`).Check(testkit.Rows(`19 Tom`))
Expand Down Expand Up @@ -127,7 +127,9 @@ func TestUserAttributes(t *testing.T) {
// https://github.com/pingcap/tidb/issues/39207
rootTK.MustExec("create user usr1@'%' identified by 'passord'")
rootTK.MustExec("alter user usr1 comment 'comment1'")
rootTK.MustQuery("select user_attributes from mysql.user where user = 'usr1'").Check(testkit.Rows(`{"metadata": {"comment": "comment1"}}`))
rootTK.MustQuery("select user_attributes from mysql.user where user = 'usr1'").Check(testkit.Rows(`{"metadata": {"comment": "comment1"}, "resource_group": "default"}`))
rootTK.MustExec("alter user usr1 resource group 'rg1'")
rootTK.MustQuery("select user_attributes from mysql.user where user = 'usr1'").Check(testkit.Rows(`{"metadata": {"comment": "comment1"}, "resource_group": "rg1"}`))
}

func TestValidatePassword(t *testing.T) {
Expand Down
29 changes: 29 additions & 0 deletions parser/ast/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,8 @@ const (

UserCommentType
UserAttributeType

UserResourceGroupName
)

type PasswordOrLockOption struct {
Expand Down Expand Up @@ -1573,6 +1575,19 @@ func (c *CommentOrAttributeOption) Restore(ctx *format.RestoreCtx) error {
return nil
}

type ResourceGroupNameOption struct {
Type int
Value string
}

func (c *ResourceGroupNameOption) Restore(ctx *format.RestoreCtx) error {
if c.Type == UserResourceGroupName {
ctx.WriteKeyWord(" RESOURCE GROUP ")
ctx.WriteString(c.Value)
}
return nil
}

// CreateUserStmt creates user account.
// See https://dev.mysql.com/doc/refman/8.0/en/create-user.html
type CreateUserStmt struct {
Expand All @@ -1585,6 +1600,7 @@ type CreateUserStmt struct {
ResourceOptions []*ResourceOption
PasswordOrLockOptions []*PasswordOrLockOption
CommentOrAttributeOption *CommentOrAttributeOption
ResourceGroupNameOption *ResourceGroupNameOption
}

// Restore implements Node interface.
Expand Down Expand Up @@ -1643,6 +1659,12 @@ func (n *CreateUserStmt) Restore(ctx *format.RestoreCtx) error {
}
}

if n.ResourceGroupNameOption != nil {
if err := n.ResourceGroupNameOption.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore CreateUserStmt.ResourceGroupNameOption")
}
}

return nil
}

Expand Down Expand Up @@ -1679,6 +1701,7 @@ type AlterUserStmt struct {
ResourceOptions []*ResourceOption
PasswordOrLockOptions []*PasswordOrLockOption
CommentOrAttributeOption *CommentOrAttributeOption
ResourceGroupNameOption *ResourceGroupNameOption
}

// Restore implements Node interface.
Expand Down Expand Up @@ -1740,6 +1763,12 @@ func (n *AlterUserStmt) Restore(ctx *format.RestoreCtx) error {
}
}

if n.ResourceGroupNameOption != nil {
if err := n.ResourceGroupNameOption.Restore(ctx); err != nil {
return errors.Annotatef(err, "An error occurred while restore AlterUserStmt.ResourceGroupNameOption")
}
}

return nil
}

Expand Down