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  }