github.com/dolthub/go-mysql-server@v0.18.0/sql/plan/ddl_procedure.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 "time" 20 21 "github.com/dolthub/go-mysql-server/sql" 22 ) 23 24 type CreateProcedure struct { 25 *Procedure 26 ddlNode 27 BodyString string 28 } 29 30 var _ sql.Node = (*CreateProcedure)(nil) 31 var _ sql.Databaser = (*CreateProcedure)(nil) 32 var _ sql.DebugStringer = (*CreateProcedure)(nil) 33 var _ sql.CollationCoercible = (*CreateProcedure)(nil) 34 35 // NewCreateProcedure returns a *CreateProcedure node. 36 func NewCreateProcedure( 37 db sql.Database, 38 name, 39 definer string, 40 params []ProcedureParam, 41 createdAt, modifiedAt time.Time, 42 securityContext ProcedureSecurityContext, 43 characteristics []Characteristic, 44 body sql.Node, 45 comment, createString, bodyString string, 46 ) *CreateProcedure { 47 procedure := NewProcedure( 48 name, 49 definer, 50 params, 51 securityContext, 52 comment, 53 characteristics, 54 createString, 55 body, 56 createdAt, 57 modifiedAt) 58 return &CreateProcedure{ 59 Procedure: procedure, 60 BodyString: bodyString, 61 ddlNode: ddlNode{db}, 62 } 63 } 64 65 // Database implements the sql.Databaser interface. 66 func (c *CreateProcedure) Database() sql.Database { 67 return c.Db 68 } 69 70 // WithDatabase implements the sql.Databaser interface. 71 func (c *CreateProcedure) WithDatabase(database sql.Database) (sql.Node, error) { 72 cp := *c 73 cp.Db = database 74 return &cp, nil 75 } 76 77 // Resolved implements the sql.Node interface. 78 func (c *CreateProcedure) Resolved() bool { 79 return c.ddlNode.Resolved() && c.Procedure.Resolved() 80 } 81 82 func (c *CreateProcedure) IsReadOnly() bool { 83 return false 84 } 85 86 // Schema implements the sql.Node interface. 87 func (c *CreateProcedure) Schema() sql.Schema { 88 return nil 89 } 90 91 // Children implements the sql.Node interface. 92 func (c *CreateProcedure) Children() []sql.Node { 93 return []sql.Node{c.Procedure} 94 } 95 96 // WithChildren implements the sql.Node interface. 97 func (c *CreateProcedure) WithChildren(children ...sql.Node) (sql.Node, error) { 98 if len(children) != 1 { 99 return nil, sql.ErrInvalidChildrenNumber.New(c, len(children), 1) 100 } 101 procedure, ok := children[0].(*Procedure) 102 if !ok { 103 return nil, fmt.Errorf("expected `*Procedure` but got `%T`", children[0]) 104 } 105 106 nc := *c 107 nc.Procedure = procedure 108 return &nc, nil 109 } 110 111 // CheckPrivileges implements the interface sql.Node. 112 func (c *CreateProcedure) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool { 113 subject := sql.PrivilegeCheckSubject{ 114 Database: c.Db.Name(), 115 } 116 117 return opChecker.UserHasPrivileges(ctx, sql.NewPrivilegedOperation(subject, sql.PrivilegeType_CreateRoutine)) 118 } 119 120 // CollationCoercibility implements the interface sql.CollationCoercible. 121 func (*CreateProcedure) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) { 122 return sql.Collation_binary, 7 123 } 124 125 // String implements the sql.Node interface. 126 func (c *CreateProcedure) String() string { 127 definer := "" 128 if c.Definer != "" { 129 definer = fmt.Sprintf(" DEFINER = %s", c.Definer) 130 } 131 params := "" 132 for i, param := range c.Params { 133 if i > 0 { 134 params += ", " 135 } 136 params += param.String() 137 } 138 comment := "" 139 if c.Comment != "" { 140 comment = fmt.Sprintf(" COMMENT '%s'", c.Comment) 141 } 142 characteristics := "" 143 for _, characteristic := range c.Characteristics { 144 characteristics += fmt.Sprintf(" %s", characteristic.String()) 145 } 146 return fmt.Sprintf("CREATE%s PROCEDURE %s (%s) %s%s%s %s", 147 definer, c.Name, params, c.SecurityContext.String(), comment, characteristics, c.Procedure.String()) 148 } 149 150 // DebugString implements the sql.DebugStringer interface. 151 func (c *CreateProcedure) DebugString() string { 152 definer := "" 153 if c.Definer != "" { 154 definer = fmt.Sprintf(" DEFINER = %s", c.Definer) 155 } 156 params := "" 157 for i, param := range c.Params { 158 if i > 0 { 159 params += ", " 160 } 161 params += param.String() 162 } 163 comment := "" 164 if c.Comment != "" { 165 comment = fmt.Sprintf(" COMMENT '%s'", c.Comment) 166 } 167 characteristics := "" 168 for _, characteristic := range c.Characteristics { 169 characteristics += fmt.Sprintf(" %s", characteristic.String()) 170 } 171 return fmt.Sprintf("CREATE%s PROCEDURE %s (%s) %s%s%s %s", 172 definer, c.Name, params, c.SecurityContext.String(), comment, characteristics, sql.DebugString(c.Procedure)) 173 }