github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/create_sequence.go (about) 1 // Copyright 2015 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 16 "github.com/cockroachdb/cockroach/pkg/keys" 17 "github.com/cockroachdb/cockroach/pkg/kv" 18 "github.com/cockroachdb/cockroach/pkg/server/telemetry" 19 "github.com/cockroachdb/cockroach/pkg/sql/catalog/catalogkv" 20 "github.com/cockroachdb/cockroach/pkg/sql/privilege" 21 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 22 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 23 "github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry" 24 "github.com/cockroachdb/cockroach/pkg/sql/types" 25 "github.com/cockroachdb/cockroach/pkg/util/hlc" 26 ) 27 28 type createSequenceNode struct { 29 n *tree.CreateSequence 30 dbDesc *sqlbase.DatabaseDescriptor 31 } 32 33 func (p *planner) CreateSequence(ctx context.Context, n *tree.CreateSequence) (planNode, error) { 34 un := n.Name.ToUnresolvedObjectName() 35 dbDesc, prefix, err := p.ResolveUncachedDatabase(ctx, un) 36 if err != nil { 37 return nil, err 38 } 39 n.Name.ObjectNamePrefix = prefix 40 41 if err := p.CheckPrivilege(ctx, dbDesc, privilege.CREATE); err != nil { 42 return nil, err 43 } 44 45 return &createSequenceNode{ 46 n: n, 47 dbDesc: dbDesc, 48 }, nil 49 } 50 51 // ReadingOwnWrites implements the planNodeReadingOwnWrites interface. 52 // This is because CREATE SEQUENCE performs multiple KV operations on descriptors 53 // and expects to see its own writes. 54 func (n *createSequenceNode) ReadingOwnWrites() {} 55 56 func (n *createSequenceNode) startExec(params runParams) error { 57 telemetry.Inc(sqltelemetry.SchemaChangeCreateCounter("sequence")) 58 isTemporary := n.n.Temporary 59 60 _, schemaID, err := getTableCreateParams(params, n.dbDesc.ID, isTemporary, n.n.Name.Table()) 61 if err != nil { 62 if sqlbase.IsRelationAlreadyExistsError(err) && n.n.IfNotExists { 63 return nil 64 } 65 return err 66 } 67 68 return doCreateSequence( 69 params, n.n.String(), n.dbDesc, schemaID, &n.n.Name, isTemporary, n.n.Options, 70 tree.AsStringWithFQNames(n.n, params.Ann()), 71 ) 72 } 73 74 // doCreateSequence performs the creation of a sequence in KV. The 75 // context argument is a string to use in the event log. 76 func doCreateSequence( 77 params runParams, 78 context string, 79 dbDesc *DatabaseDescriptor, 80 schemaID sqlbase.ID, 81 name *TableName, 82 isTemporary bool, 83 opts tree.SequenceOptions, 84 jobDesc string, 85 ) error { 86 id, err := catalogkv.GenerateUniqueDescID(params.ctx, params.p.ExecCfg().DB, params.p.ExecCfg().Codec) 87 if err != nil { 88 return err 89 } 90 91 // Inherit permissions from the database descriptor. 92 privs := dbDesc.GetPrivileges() 93 94 if isTemporary { 95 telemetry.Inc(sqltelemetry.CreateTempSequenceCounter) 96 } 97 98 desc, err := MakeSequenceTableDesc( 99 name.Table(), 100 opts, 101 dbDesc.ID, 102 schemaID, 103 id, 104 params.creationTimeForNewTableDescriptor(), 105 privs, 106 isTemporary, 107 ¶ms, 108 ) 109 if err != nil { 110 return err 111 } 112 113 // makeSequenceTableDesc already validates the table. No call to 114 // desc.ValidateTable() needed here. 115 116 key := sqlbase.MakeObjectNameKey( 117 params.ctx, 118 params.ExecCfg().Settings, 119 dbDesc.ID, 120 schemaID, 121 name.Table(), 122 ).Key(params.ExecCfg().Codec) 123 if err = params.p.createDescriptorWithID( 124 params.ctx, key, id, &desc, params.EvalContext().Settings, jobDesc, 125 ); err != nil { 126 return err 127 } 128 129 // Initialize the sequence value. 130 seqValueKey := params.ExecCfg().Codec.SequenceKey(uint32(id)) 131 b := &kv.Batch{} 132 b.Inc(seqValueKey, desc.SequenceOpts.Start-desc.SequenceOpts.Increment) 133 if err := params.p.txn.Run(params.ctx, b); err != nil { 134 return err 135 } 136 137 if err := desc.Validate(params.ctx, params.p.txn, params.ExecCfg().Codec); err != nil { 138 return err 139 } 140 141 // Log Create Sequence event. This is an auditable log event and is 142 // recorded in the same transaction as the table descriptor update. 143 return MakeEventLogger(params.extendedEvalCtx.ExecCfg).InsertEventRecord( 144 params.ctx, 145 params.p.txn, 146 EventLogCreateSequence, 147 int32(desc.ID), 148 int32(params.extendedEvalCtx.NodeID.SQLInstanceID()), 149 struct { 150 SequenceName string 151 Statement string 152 User string 153 }{name.FQString(), context, params.SessionData().User}, 154 ) 155 } 156 157 func (*createSequenceNode) Next(runParams) (bool, error) { return false, nil } 158 func (*createSequenceNode) Values() tree.Datums { return tree.Datums{} } 159 func (*createSequenceNode) Close(context.Context) {} 160 161 // MakeSequenceTableDesc creates a sequence descriptor. 162 func MakeSequenceTableDesc( 163 sequenceName string, 164 sequenceOptions tree.SequenceOptions, 165 parentID sqlbase.ID, 166 schemaID sqlbase.ID, 167 id sqlbase.ID, 168 creationTime hlc.Timestamp, 169 privileges *sqlbase.PrivilegeDescriptor, 170 isTemporary bool, 171 params *runParams, 172 ) (sqlbase.MutableTableDescriptor, error) { 173 desc := InitTableDescriptor( 174 id, 175 parentID, 176 schemaID, 177 sequenceName, 178 creationTime, 179 privileges, 180 isTemporary, 181 ) 182 183 // Mimic a table with one column, "value". 184 desc.Columns = []sqlbase.ColumnDescriptor{ 185 { 186 ID: sqlbase.SequenceColumnID, 187 Name: sqlbase.SequenceColumnName, 188 Type: types.Int, 189 }, 190 } 191 desc.PrimaryIndex = sqlbase.IndexDescriptor{ 192 ID: keys.SequenceIndexID, 193 Name: sqlbase.PrimaryKeyIndexName, 194 ColumnIDs: []sqlbase.ColumnID{sqlbase.SequenceColumnID}, 195 ColumnNames: []string{sqlbase.SequenceColumnName}, 196 ColumnDirections: []sqlbase.IndexDescriptor_Direction{sqlbase.IndexDescriptor_ASC}, 197 } 198 desc.Families = []sqlbase.ColumnFamilyDescriptor{ 199 { 200 ID: keys.SequenceColumnFamilyID, 201 ColumnIDs: []sqlbase.ColumnID{sqlbase.SequenceColumnID}, 202 ColumnNames: []string{sqlbase.SequenceColumnName}, 203 Name: "primary", 204 DefaultColumnID: sqlbase.SequenceColumnID, 205 }, 206 } 207 208 // Fill in options, starting with defaults then overriding. 209 opts := &sqlbase.TableDescriptor_SequenceOpts{ 210 Increment: 1, 211 } 212 err := assignSequenceOptions(opts, sequenceOptions, true /* setDefaults */, params, id) 213 if err != nil { 214 return desc, err 215 } 216 desc.SequenceOpts = opts 217 218 // A sequence doesn't have dependencies and thus can be made public 219 // immediately. 220 desc.State = sqlbase.TableDescriptor_PUBLIC 221 222 return desc, desc.ValidateTable() 223 }