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  }