github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sem/tree/txn.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 tree 12 13 import ( 14 "fmt" 15 "strings" 16 17 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 18 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 19 ) 20 21 // IsolationLevel holds the isolation level for a transaction. 22 type IsolationLevel int 23 24 // IsolationLevel values 25 const ( 26 UnspecifiedIsolation IsolationLevel = iota 27 SerializableIsolation 28 ) 29 30 var isolationLevelNames = [...]string{ 31 UnspecifiedIsolation: "UNSPECIFIED", 32 SerializableIsolation: "SERIALIZABLE", 33 } 34 35 // IsolationLevelMap is a map from string isolation level name to isolation 36 // level, in the lowercase format that set isolation_level supports. 37 var IsolationLevelMap = map[string]IsolationLevel{ 38 "serializable": SerializableIsolation, 39 } 40 41 func (i IsolationLevel) String() string { 42 if i < 0 || i > IsolationLevel(len(isolationLevelNames)-1) { 43 return fmt.Sprintf("IsolationLevel(%d)", i) 44 } 45 return isolationLevelNames[i] 46 } 47 48 // UserPriority holds the user priority for a transaction. 49 type UserPriority int 50 51 // UserPriority values 52 const ( 53 UnspecifiedUserPriority UserPriority = iota 54 Low 55 Normal 56 High 57 ) 58 59 var userPriorityNames = [...]string{ 60 UnspecifiedUserPriority: "UNSPECIFIED", 61 Low: "LOW", 62 Normal: "NORMAL", 63 High: "HIGH", 64 } 65 66 func (up UserPriority) String() string { 67 if up < 0 || up > UserPriority(len(userPriorityNames)-1) { 68 return fmt.Sprintf("UserPriority(%d)", up) 69 } 70 return userPriorityNames[up] 71 } 72 73 // UserPriorityFromString converts a string into a UserPriority. 74 func UserPriorityFromString(val string) (_ UserPriority, ok bool) { 75 switch strings.ToUpper(val) { 76 case "LOW": 77 return Low, true 78 case "NORMAL": 79 return Normal, true 80 case "HIGH": 81 return High, true 82 default: 83 return 0, false 84 } 85 } 86 87 // ReadWriteMode holds the read write mode for a transaction. 88 type ReadWriteMode int 89 90 // ReadWriteMode values 91 const ( 92 UnspecifiedReadWriteMode ReadWriteMode = iota 93 ReadOnly 94 ReadWrite 95 ) 96 97 var readWriteModeNames = [...]string{ 98 UnspecifiedReadWriteMode: "UNSPECIFIED", 99 ReadOnly: "ONLY", 100 ReadWrite: "WRITE", 101 } 102 103 func (ro ReadWriteMode) String() string { 104 if ro < 0 || ro > ReadWriteMode(len(readWriteModeNames)-1) { 105 return fmt.Sprintf("ReadWriteMode(%d)", ro) 106 } 107 return readWriteModeNames[ro] 108 } 109 110 // TransactionModes holds the transaction modes for a transaction. 111 type TransactionModes struct { 112 Isolation IsolationLevel 113 UserPriority UserPriority 114 ReadWriteMode ReadWriteMode 115 AsOf AsOfClause 116 } 117 118 // Format implements the NodeFormatter interface. 119 func (node *TransactionModes) Format(ctx *FmtCtx) { 120 var sep string 121 if node.Isolation != UnspecifiedIsolation { 122 ctx.Printf(" ISOLATION LEVEL %s", node.Isolation) 123 sep = "," 124 } 125 if node.UserPriority != UnspecifiedUserPriority { 126 ctx.Printf("%s PRIORITY %s", sep, node.UserPriority) 127 sep = "," 128 } 129 if node.ReadWriteMode != UnspecifiedReadWriteMode { 130 ctx.Printf("%s READ %s", sep, node.ReadWriteMode) 131 } 132 if node.AsOf.Expr != nil { 133 ctx.WriteString(sep) 134 ctx.WriteString(" ") 135 node.AsOf.Format(ctx) 136 } 137 } 138 139 var ( 140 errIsolationLevelSpecifiedMultipleTimes = pgerror.New(pgcode.Syntax, "isolation level specified multiple times") 141 errUserPrioritySpecifiedMultipleTimes = pgerror.New(pgcode.Syntax, "user priority specified multiple times") 142 errReadModeSpecifiedMultipleTimes = pgerror.New(pgcode.Syntax, "read mode specified multiple times") 143 errAsOfSpecifiedMultipleTimes = pgerror.New(pgcode.Syntax, "AS OF SYSTEM TIME specified multiple times") 144 145 // ErrAsOfSpecifiedWithReadWrite is returned when a statement attempts to set 146 // a historical query to READ WRITE which conflicts with its implied READ ONLY 147 // mode. 148 ErrAsOfSpecifiedWithReadWrite = pgerror.New(pgcode.Syntax, "AS OF SYSTEM TIME specified with READ WRITE mode") 149 ) 150 151 // Merge groups two sets of transaction modes together. 152 // Used in the parser. 153 func (node *TransactionModes) Merge(other TransactionModes) error { 154 if other.Isolation != UnspecifiedIsolation { 155 if node.Isolation != UnspecifiedIsolation { 156 return errIsolationLevelSpecifiedMultipleTimes 157 } 158 node.Isolation = other.Isolation 159 } 160 if other.UserPriority != UnspecifiedUserPriority { 161 if node.UserPriority != UnspecifiedUserPriority { 162 return errUserPrioritySpecifiedMultipleTimes 163 } 164 node.UserPriority = other.UserPriority 165 } 166 if other.AsOf.Expr != nil { 167 if node.AsOf.Expr != nil { 168 return errAsOfSpecifiedMultipleTimes 169 } 170 node.AsOf.Expr = other.AsOf.Expr 171 } 172 if other.ReadWriteMode != UnspecifiedReadWriteMode { 173 if node.ReadWriteMode != UnspecifiedReadWriteMode { 174 return errReadModeSpecifiedMultipleTimes 175 } 176 node.ReadWriteMode = other.ReadWriteMode 177 } 178 if node.ReadWriteMode != UnspecifiedReadWriteMode && 179 node.ReadWriteMode != ReadOnly && 180 node.AsOf.Expr != nil { 181 return ErrAsOfSpecifiedWithReadWrite 182 } 183 return nil 184 } 185 186 // BeginTransaction represents a BEGIN statement 187 type BeginTransaction struct { 188 Modes TransactionModes 189 } 190 191 // Format implements the NodeFormatter interface. 192 func (node *BeginTransaction) Format(ctx *FmtCtx) { 193 ctx.WriteString("BEGIN TRANSACTION") 194 node.Modes.Format(ctx) 195 } 196 197 // CommitTransaction represents a COMMIT statement. 198 type CommitTransaction struct{} 199 200 // Format implements the NodeFormatter interface. 201 func (node *CommitTransaction) Format(ctx *FmtCtx) { 202 ctx.WriteString("COMMIT TRANSACTION") 203 } 204 205 // RollbackTransaction represents a ROLLBACK statement. 206 type RollbackTransaction struct{} 207 208 // Format implements the NodeFormatter interface. 209 func (node *RollbackTransaction) Format(ctx *FmtCtx) { 210 ctx.WriteString("ROLLBACK TRANSACTION") 211 } 212 213 // Savepoint represents a SAVEPOINT <name> statement. 214 type Savepoint struct { 215 Name Name 216 } 217 218 // Format implements the NodeFormatter interface. 219 func (node *Savepoint) Format(ctx *FmtCtx) { 220 ctx.WriteString("SAVEPOINT ") 221 node.Name.Format(ctx) 222 } 223 224 // ReleaseSavepoint represents a RELEASE SAVEPOINT <name> statement. 225 type ReleaseSavepoint struct { 226 Savepoint Name 227 } 228 229 // Format implements the NodeFormatter interface. 230 func (node *ReleaseSavepoint) Format(ctx *FmtCtx) { 231 ctx.WriteString("RELEASE SAVEPOINT ") 232 node.Savepoint.Format(ctx) 233 } 234 235 // RollbackToSavepoint represents a ROLLBACK TO SAVEPOINT <name> statement. 236 type RollbackToSavepoint struct { 237 Savepoint Name 238 } 239 240 // Format implements the NodeFormatter interface. 241 func (node *RollbackToSavepoint) Format(ctx *FmtCtx) { 242 ctx.WriteString("ROLLBACK TRANSACTION TO SAVEPOINT ") 243 node.Savepoint.Format(ctx) 244 }