github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/create_database.go (about) 1 // Copyright 2017 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package sql 12 13 import ( 14 "context" 15 "strings" 16 17 "github.com/cockroachdb/cockroach/pkg/server/telemetry" 18 "github.com/cockroachdb/cockroach/pkg/sql/catalog/descs" 19 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 20 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 21 "github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry" 22 "github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented" 23 ) 24 25 type createDatabaseNode struct { 26 n *tree.CreateDatabase 27 } 28 29 // CreateDatabase creates a database. 30 // Privileges: superuser. 31 // Notes: postgres requires superuser or "CREATEDB". 32 // mysql uses the mysqladmin command. 33 func (p *planner) CreateDatabase(ctx context.Context, n *tree.CreateDatabase) (planNode, error) { 34 if n.Name == "" { 35 return nil, errEmptyDatabaseName 36 } 37 38 if tmpl := n.Template; tmpl != "" { 39 // See https://www.postgresql.org/docs/current/static/manage-ag-templatedbs.html 40 if !strings.EqualFold(tmpl, "template0") { 41 return nil, unimplemented.NewWithIssuef(10151, 42 "unsupported template: %s", tmpl) 43 } 44 } 45 46 if enc := n.Encoding; enc != "" { 47 // We only support UTF8 (and aliases for UTF8). 48 if !(strings.EqualFold(enc, "UTF8") || 49 strings.EqualFold(enc, "UTF-8") || 50 strings.EqualFold(enc, "UNICODE")) { 51 return nil, unimplemented.NewWithIssueDetailf(35882, "create.db.encoding", 52 "unsupported encoding: %s", enc) 53 } 54 } 55 56 if col := n.Collate; col != "" { 57 // We only support C and C.UTF-8. 58 if col != "C" && col != "C.UTF-8" { 59 return nil, unimplemented.NewWithIssueDetailf(16618, "create.db.collation", 60 "unsupported collation: %s", col) 61 } 62 } 63 64 if ctype := n.CType; ctype != "" { 65 // We only support C and C.UTF-8. 66 if ctype != "C" && ctype != "C.UTF-8" { 67 return nil, unimplemented.NewWithIssueDetailf(35882, "create.db.classification", 68 "unsupported character classification: %s", ctype) 69 } 70 } 71 72 if err := p.RequireAdminRole(ctx, "CREATE DATABASE"); err != nil { 73 return nil, err 74 } 75 76 return &createDatabaseNode{n: n}, nil 77 } 78 79 func (n *createDatabaseNode) startExec(params runParams) error { 80 telemetry.Inc(sqltelemetry.SchemaChangeCreateCounter("database")) 81 desc := sqlbase.MakeDatabaseDesc(n.n) 82 83 created, err := params.p.createDatabase( 84 params.ctx, &desc, n.n.IfNotExists, tree.AsStringWithFQNames(n.n, params.Ann())) 85 if err != nil { 86 return err 87 } 88 if created { 89 // Log Create Database event. This is an auditable log event and is 90 // recorded in the same transaction as the table descriptor update. 91 if err := MakeEventLogger(params.extendedEvalCtx.ExecCfg).InsertEventRecord( 92 params.ctx, 93 params.p.txn, 94 EventLogCreateDatabase, 95 int32(desc.ID), 96 int32(params.extendedEvalCtx.NodeID.SQLInstanceID()), 97 struct { 98 DatabaseName string 99 Statement string 100 User string 101 }{n.n.Name.String(), n.n.String(), params.SessionData().User}, 102 ); err != nil { 103 return err 104 } 105 params.extendedEvalCtx.Descs.AddUncommittedDatabase( 106 desc.Name, desc.ID, descs.DBCreated) 107 } 108 return nil 109 } 110 111 func (*createDatabaseNode) Next(runParams) (bool, error) { return false, nil } 112 func (*createDatabaseNode) Values() tree.Datums { return tree.Datums{} } 113 func (*createDatabaseNode) Close(context.Context) {}