github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/create_role.go (about) 1 // Copyright 2021 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package plan 16 17 import ( 18 "fmt" 19 "strings" 20 21 "github.com/dolthub/go-mysql-server/sql/types" 22 23 "github.com/dolthub/go-mysql-server/sql" 24 ) 25 26 // CreateRole represents the statement CREATE ROLE. 27 type CreateRole struct { 28 IfNotExists bool 29 Roles []UserName 30 MySQLDb sql.Database 31 } 32 33 // NewCreateRole returns a new CreateRole node. 34 func NewCreateRole(ifNotExists bool, roles []UserName) *CreateRole { 35 return &CreateRole{ 36 IfNotExists: ifNotExists, 37 Roles: roles, 38 MySQLDb: sql.UnresolvedDatabase("mysql"), 39 } 40 } 41 42 var _ sql.Node = (*CreateRole)(nil) 43 var _ sql.CollationCoercible = (*CreateRole)(nil) 44 45 // Schema implements the interface sql.Node. 46 func (n *CreateRole) Schema() sql.Schema { 47 return types.OkResultSchema 48 } 49 50 // String implements the interface sql.Node. 51 func (n *CreateRole) String() string { 52 roles := make([]string, len(n.Roles)) 53 for i, role := range n.Roles { 54 roles[i] = role.String("") 55 } 56 ifNotExists := "" 57 if n.IfNotExists { 58 ifNotExists = "IfNotExists: " 59 } 60 return fmt.Sprintf("CreateRole(%s%s)", ifNotExists, strings.Join(roles, ", ")) 61 } 62 63 // Database implements the interface sql.Databaser. 64 func (n *CreateRole) Database() sql.Database { 65 return n.MySQLDb 66 } 67 68 // WithDatabase implements the interface sql.Databaser. 69 func (n *CreateRole) WithDatabase(db sql.Database) (sql.Node, error) { 70 nn := *n 71 nn.MySQLDb = db 72 return &nn, nil 73 } 74 75 // Resolved implements the interface sql.Node. 76 func (n *CreateRole) Resolved() bool { 77 _, ok := n.MySQLDb.(sql.UnresolvedDatabase) 78 return !ok 79 } 80 81 func (n *CreateRole) IsReadOnly() bool { 82 return false 83 } 84 85 // Children implements the interface sql.Node. 86 func (n *CreateRole) Children() []sql.Node { 87 return nil 88 } 89 90 // WithChildren implements the interface sql.Node. 91 func (n *CreateRole) WithChildren(children ...sql.Node) (sql.Node, error) { 92 if len(children) != 0 { 93 return nil, sql.ErrInvalidChildrenNumber.New(n, len(children), 0) 94 } 95 return n, nil 96 } 97 98 // CheckPrivileges implements the interface sql.Node. 99 func (n *CreateRole) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool { 100 // Both CREATE ROLE and CREATE USER are valid privileges, so we use an OR 101 subject := sql.PrivilegeCheckSubject{} 102 return opChecker.UserHasPrivileges(ctx, sql.NewPrivilegedOperation(subject, sql.PrivilegeType_CreateRole)) || 103 opChecker.UserHasPrivileges(ctx, sql.NewPrivilegedOperation(subject, sql.PrivilegeType_CreateUser)) 104 } 105 106 // CollationCoercibility implements the interface sql.CollationCoercible. 107 func (*CreateRole) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 108 return sql.Collation_binary, 7 109 }