github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sqlbase/errors.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 sqlbase 12 13 import ( 14 "github.com/cockroachdb/cockroach/pkg/roachpb" 15 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 16 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 17 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 18 "github.com/cockroachdb/errors" 19 ) 20 21 const ( 22 txnAbortedMsg = "current transaction is aborted, commands ignored " + 23 "until end of transaction block" 24 txnCommittedMsg = "current transaction is committed, commands ignored " + 25 "until end of transaction block" 26 ) 27 28 // NewTransactionAbortedError creates an error for trying to run a command in 29 // the context of transaction that's in the aborted state. Any statement other 30 // than ROLLBACK TO SAVEPOINT will return this error. 31 func NewTransactionAbortedError(customMsg string) error { 32 if customMsg != "" { 33 return pgerror.Newf( 34 pgcode.InFailedSQLTransaction, "%s: %s", customMsg, txnAbortedMsg) 35 } 36 return pgerror.New(pgcode.InFailedSQLTransaction, txnAbortedMsg) 37 } 38 39 // NewTransactionCommittedError creates an error that signals that the SQL txn 40 // is in the COMMIT_WAIT state and that only a COMMIT statement will be accepted. 41 func NewTransactionCommittedError() error { 42 return pgerror.New(pgcode.InvalidTransactionState, txnCommittedMsg) 43 } 44 45 // NewNonNullViolationError creates an error for a violation of a non-NULL constraint. 46 func NewNonNullViolationError(columnName string) error { 47 return pgerror.Newf(pgcode.NotNullViolation, "null value in column %q violates not-null constraint", columnName) 48 } 49 50 // NewInvalidSchemaDefinitionError creates an error for an invalid schema 51 // definition such as a schema definition that doesn't parse. 52 func NewInvalidSchemaDefinitionError(err error) error { 53 return pgerror.WithCandidateCode(err, pgcode.InvalidSchemaDefinition) 54 } 55 56 // NewUnsupportedSchemaUsageError creates an error for an invalid 57 // schema use, e.g. mydb.someschema.tbl. 58 func NewUnsupportedSchemaUsageError(name string) error { 59 return pgerror.Newf(pgcode.InvalidSchemaName, 60 "unsupported schema specification: %q", name) 61 } 62 63 // NewCCLRequiredError creates an error for when a CCL feature is used in an OSS 64 // binary. 65 func NewCCLRequiredError(err error) error { 66 return pgerror.WithCandidateCode(err, pgcode.CCLRequired) 67 } 68 69 // IsCCLRequiredError returns whether the error is a CCLRequired error. 70 func IsCCLRequiredError(err error) bool { 71 return errHasCode(err, pgcode.CCLRequired) 72 } 73 74 // NewUndefinedDatabaseError creates an error that represents a missing database. 75 func NewUndefinedDatabaseError(name string) error { 76 // Postgres will return an UndefinedTable error on queries that go to a "relation" 77 // that does not exist (a query to a non-existent table or database), but will 78 // return an InvalidCatalogName error when connecting to a database that does 79 // not exist. We've chosen to return this code for all cases where the error cause 80 // is a missing database. 81 return pgerror.Newf( 82 pgcode.InvalidCatalogName, "database %q does not exist", name) 83 } 84 85 // NewInvalidWildcardError creates an error that represents the result of expanding 86 // a table wildcard over an invalid database or schema prefix. 87 func NewInvalidWildcardError(name string) error { 88 return pgerror.Newf( 89 pgcode.InvalidCatalogName, 90 "%q does not match any valid database or schema", name) 91 } 92 93 // NewUndefinedObjectError returns the correct undefined object error based on 94 // the kind of object that was requested. 95 func NewUndefinedObjectError(name tree.NodeFormatter, kind tree.DesiredObjectKind) error { 96 switch kind { 97 case tree.TableObject: 98 return NewUndefinedRelationError(name) 99 case tree.TypeObject: 100 return NewUndefinedTypeError(name) 101 default: 102 return errors.AssertionFailedf("unknown object kind %d", kind) 103 } 104 } 105 106 // NewUndefinedTypeError creates an error that represents a missing type. 107 func NewUndefinedTypeError(name tree.NodeFormatter) error { 108 return pgerror.Newf(pgcode.UndefinedObject, "type %q does not exist", tree.ErrString(name)) 109 } 110 111 // NewUndefinedRelationError creates an error that represents a missing database table or view. 112 func NewUndefinedRelationError(name tree.NodeFormatter) error { 113 return pgerror.Newf(pgcode.UndefinedTable, 114 "relation %q does not exist", tree.ErrString(name)) 115 } 116 117 // NewUndefinedColumnError creates an error that represents a missing database column. 118 func NewUndefinedColumnError(name string) error { 119 return pgerror.Newf(pgcode.UndefinedColumn, "column %q does not exist", name) 120 } 121 122 // NewColumnAlreadyExistsError creates an error for a preexisting column. 123 func NewColumnAlreadyExistsError(name, relation string) error { 124 return pgerror.Newf(pgcode.DuplicateColumn, "column %q of relation %q already exists", name, relation) 125 } 126 127 // NewDatabaseAlreadyExistsError creates an error for a preexisting database. 128 func NewDatabaseAlreadyExistsError(name string) error { 129 return pgerror.Newf(pgcode.DuplicateDatabase, "database %q already exists", name) 130 } 131 132 // NewRelationAlreadyExistsError creates an error for a preexisting relation. 133 func NewRelationAlreadyExistsError(name string) error { 134 return pgerror.Newf(pgcode.DuplicateRelation, "relation %q already exists", name) 135 } 136 137 // NewTypeAlreadyExistsError creates an error for a preexisting type. 138 func NewTypeAlreadyExistsError(name string) error { 139 return pgerror.Newf(pgcode.DuplicateObject, "type %q already exists", name) 140 } 141 142 // IsRelationAlreadyExistsError checks whether this is an error for a preexisting relation. 143 func IsRelationAlreadyExistsError(err error) bool { 144 return errHasCode(err, pgcode.DuplicateRelation) 145 } 146 147 // NewWrongObjectTypeError creates a wrong object type error. 148 func NewWrongObjectTypeError(name tree.NodeFormatter, desiredObjType string) error { 149 return pgerror.Newf(pgcode.WrongObjectType, "%q is not a %s", 150 tree.ErrString(name), desiredObjType) 151 } 152 153 // NewSyntaxErrorf creates a syntax error. 154 func NewSyntaxErrorf(format string, args ...interface{}) error { 155 return pgerror.Newf(pgcode.Syntax, format, args...) 156 } 157 158 // NewDependentObjectErrorf creates a dependent object error. 159 func NewDependentObjectErrorf(format string, args ...interface{}) error { 160 return pgerror.Newf(pgcode.DependentObjectsStillExist, format, args...) 161 } 162 163 // NewRangeUnavailableError creates an unavailable range error. 164 func NewRangeUnavailableError( 165 rangeID roachpb.RangeID, origErr error, nodeIDs ...roachpb.NodeID, 166 ) error { 167 // TODO(knz): This could should really use errors.Wrap or 168 // errors.WithSecondaryError. 169 return pgerror.Newf(pgcode.RangeUnavailable, 170 "key range id:%d is unavailable; missing nodes: %s. Original error: %v", 171 rangeID, nodeIDs, origErr) 172 } 173 174 // NewWindowInAggError creates an error for the case when a window function is 175 // nested within an aggregate function. 176 func NewWindowInAggError() error { 177 return pgerror.New(pgcode.Grouping, 178 "window functions are not allowed in aggregate") 179 } 180 181 // NewAggInAggError creates an error for the case when an aggregate function is 182 // contained within another aggregate function. 183 func NewAggInAggError() error { 184 return pgerror.New(pgcode.Grouping, "aggregate function calls cannot be nested") 185 } 186 187 // QueryCanceledError is an error representing query cancellation. 188 var QueryCanceledError = pgerror.New( 189 pgcode.QueryCanceled, "query execution canceled") 190 191 // QueryTimeoutError is an error representing a query timeout. 192 var QueryTimeoutError = pgerror.New( 193 pgcode.QueryCanceled, "query execution canceled due to statement timeout") 194 195 // IsOutOfMemoryError checks whether this is an out of memory error. 196 func IsOutOfMemoryError(err error) bool { 197 return errHasCode(err, pgcode.OutOfMemory) 198 } 199 200 // IsUndefinedColumnError checks whether this is an undefined column error. 201 func IsUndefinedColumnError(err error) bool { 202 return errHasCode(err, pgcode.UndefinedColumn) 203 } 204 205 // IsUndefinedRelationError checks whether this is an undefined relation error. 206 func IsUndefinedRelationError(err error) bool { 207 return errHasCode(err, pgcode.UndefinedTable) 208 } 209 210 func errHasCode(err error, code ...string) bool { 211 pgCode := pgerror.GetPGCode(err) 212 for _, c := range code { 213 if pgCode == c { 214 return true 215 } 216 } 217 return false 218 }