# Copyright (C) 2020 The Psycopg Team
-from typing import Any, Optional, Sequence, Type
+from typing import Any, Callable, Dict, Optional, Sequence, Type
from psycopg3.pq.proto import PGresult
from psycopg3.pq.enums import DiagnosticField
return None
-def class_for_state(sqlstate: bytes) -> Type[Error]:
- # TODO: stub
- return DatabaseError
+def lookup(sqlstate: str) -> Type[Error]:
+ return _sqlcodes[sqlstate]
def error_from_result(result: PGresult, encoding: str = "utf-8") -> Error:
from psycopg3 import pq
state = result.error_field(DiagnosticField.SQLSTATE) or b""
- cls = class_for_state(state)
+ cls = _class_for_state(state.decode("ascii"))
return cls(pq.error_message(result), pgresult=result, encoding=encoding)
+
+
+def _class_for_state(sqlstate: str) -> Type[Error]:
+ try:
+ return lookup(sqlstate)
+ except KeyError:
+ return get_base_exception(sqlstate)
+
+
+def get_base_exception(sqlstate: str) -> Type[Error]:
+ exc = _base_exc_map.get(sqlstate[:2])
+ if exc is not None:
+ return exc
+
+ exc = _base_exc_map.get(sqlstate[0])
+ if exc is not None:
+ return exc
+
+ return DatabaseError
+
+
+_base_exc_map = {
+ "0A": NotSupportedError, # Feature Not Supported
+ "20": ProgrammingError, # Case Not Foud
+ "21": ProgrammingError, # Cardinality Violation
+ "22": DataError, # Data Exception
+ "23": IntegrityError, # Integrity Constraint Violation
+ "24": InternalError, # Invalid Cursor State
+ "25": InternalError, # Invalid Transaction State
+ "26": ProgrammingError, # Invalid SQL Statement Name *
+ "27": OperationalError, # Triggered Data Change Violation
+ "28": OperationalError, # Invalid Authorization Specification
+ "2B": InternalError, # Dependent Privilege Descriptors Still Exist
+ "2D": InternalError, # Invalid Transaction Termination
+ "2F": OperationalError, # SQL Routine Exception *
+ "34": ProgrammingError, # Invalid Cursor Name *
+ "38": OperationalError, # External Routine Exception *
+ "39": OperationalError, # External Routine Invocation Exception *
+ "3B": OperationalError, # Savepoint Exception *
+ "3D": ProgrammingError, # Invalid Catalog Name
+ "3F": ProgrammingError, # Invalid Schema Name
+ "40": OperationalError, # Transaction Rollback
+ "42": ProgrammingError, # Syntax Error or Access Rule Violation
+ "44": ProgrammingError, # WITH CHECK OPTION Violation
+ "53": OperationalError, # Insufficient Resources
+ "54": OperationalError, # Program Limit Exceeded
+ "55": OperationalError, # Object Not In Prerequisite State
+ "57": OperationalError, # Operator Intervention
+ "58": OperationalError, # System Error (errors external to PostgreSQL itself)
+ "F": OperationalError, # Configuration File Error
+ "H": OperationalError, # Foreign Data Wrapper Error (SQL/MED)
+ "P": ProgrammingError, # PL/pgSQL Error
+ "X": InternalError, # Internal Error
+}
+
+
+def sqlcode(code: str) -> Callable[[Type[Error]], Type[Error]]:
+ """
+ Decorator to associate an exception class to a sqlstate.
+ """
+
+ def sqlcode_(cls: Type[Error]) -> Type[Error]:
+ _sqlcodes[code] = cls
+ return cls
+
+ return sqlcode_
+
+
+_sqlcodes: Dict[str, Type[Error]] = {}
+
+
+# Classes generated by toosls/update_errors.py
+# autogenerated: start
+
+# Class 02 - No Data (this is also a warning class per the SQL standard)
+
+
+@sqlcode("02000")
+class NoData(DatabaseError):
+ pass
+
+
+@sqlcode("02001")
+class NoAdditionalDynamicResultSetsReturned(DatabaseError):
+ pass
+
+
+# Class 03 - SQL Statement Not Yet Complete
+
+
+@sqlcode("03000")
+class SqlStatementNotYetComplete(DatabaseError):
+ pass
+
+
+# Class 08 - Connection Exception
+
+
+@sqlcode("08000")
+class ConnectionException(DatabaseError):
+ pass
+
+
+@sqlcode("08001")
+class SqlclientUnableToEstablishSqlconnection(DatabaseError):
+ pass
+
+
+@sqlcode("08003")
+class ConnectionDoesNotExist(DatabaseError):
+ pass
+
+
+@sqlcode("08004")
+class SqlserverRejectedEstablishmentOfSqlconnection(DatabaseError):
+ pass
+
+
+@sqlcode("08006")
+class ConnectionFailure(DatabaseError):
+ pass
+
+
+@sqlcode("08007")
+class TransactionResolutionUnknown(DatabaseError):
+ pass
+
+
+@sqlcode("08P01")
+class ProtocolViolation(DatabaseError):
+ pass
+
+
+# Class 09 - Triggered Action Exception
+
+
+@sqlcode("09000")
+class TriggeredActionException(DatabaseError):
+ pass
+
+
+# Class 0A - Feature Not Supported
+
+
+@sqlcode("0A000")
+class FeatureNotSupported(NotSupportedError):
+ pass
+
+
+# Class 0B - Invalid Transaction Initiation
+
+
+@sqlcode("0B000")
+class InvalidTransactionInitiation(DatabaseError):
+ pass
+
+
+# Class 0F - Locator Exception
+
+
+@sqlcode("0F000")
+class LocatorException(DatabaseError):
+ pass
+
+
+@sqlcode("0F001")
+class InvalidLocatorSpecification(DatabaseError):
+ pass
+
+
+# Class 0L - Invalid Grantor
+
+
+@sqlcode("0L000")
+class InvalidGrantor(DatabaseError):
+ pass
+
+
+@sqlcode("0LP01")
+class InvalidGrantOperation(DatabaseError):
+ pass
+
+
+# Class 0P - Invalid Role Specification
+
+
+@sqlcode("0P000")
+class InvalidRoleSpecification(DatabaseError):
+ pass
+
+
+# Class 0Z - Diagnostics Exception
+
+
+@sqlcode("0Z000")
+class DiagnosticsException(DatabaseError):
+ pass
+
+
+@sqlcode("0Z002")
+class StackedDiagnosticsAccessedWithoutActiveHandler(DatabaseError):
+ pass
+
+
+# Class 20 - Case Not Found
+
+
+@sqlcode("20000")
+class CaseNotFound(ProgrammingError):
+ pass
+
+
+# Class 21 - Cardinality Violation
+
+
+@sqlcode("21000")
+class CardinalityViolation(ProgrammingError):
+ pass
+
+
+# Class 22 - Data Exception
+
+
+@sqlcode("22000")
+class DataException(DataError):
+ pass
+
+
+@sqlcode("22001")
+class StringDataRightTruncation(DataError):
+ pass
+
+
+@sqlcode("22002")
+class NullValueNoIndicatorParameter(DataError):
+ pass
+
+
+@sqlcode("22003")
+class NumericValueOutOfRange(DataError):
+ pass
+
+
+@sqlcode("22004")
+class NullValueNotAllowed(DataError):
+ pass
+
+
+@sqlcode("22005")
+class ErrorInAssignment(DataError):
+ pass
+
+
+@sqlcode("22007")
+class InvalidDatetimeFormat(DataError):
+ pass
+
+
+@sqlcode("22008")
+class DatetimeFieldOverflow(DataError):
+ pass
+
+
+@sqlcode("22009")
+class InvalidTimeZoneDisplacementValue(DataError):
+ pass
+
+
+@sqlcode("2200B")
+class EscapeCharacterConflict(DataError):
+ pass
+
+
+@sqlcode("2200C")
+class InvalidUseOfEscapeCharacter(DataError):
+ pass
+
+
+@sqlcode("2200D")
+class InvalidEscapeOctet(DataError):
+ pass
+
+
+@sqlcode("2200F")
+class ZeroLengthCharacterString(DataError):
+ pass
+
+
+@sqlcode("2200G")
+class MostSpecificTypeMismatch(DataError):
+ pass
+
+
+@sqlcode("2200H")
+class SequenceGeneratorLimitExceeded(DataError):
+ pass
+
+
+@sqlcode("2200L")
+class NotAnXmlDocument(DataError):
+ pass
+
+
+@sqlcode("2200M")
+class InvalidXmlDocument(DataError):
+ pass
+
+
+@sqlcode("2200N")
+class InvalidXmlContent(DataError):
+ pass
+
+
+@sqlcode("2200S")
+class InvalidXmlComment(DataError):
+ pass
+
+
+@sqlcode("2200T")
+class InvalidXmlProcessingInstruction(DataError):
+ pass
+
+
+@sqlcode("22010")
+class InvalidIndicatorParameterValue(DataError):
+ pass
+
+
+@sqlcode("22011")
+class SubstringError(DataError):
+ pass
+
+
+@sqlcode("22012")
+class DivisionByZero(DataError):
+ pass
+
+
+@sqlcode("22013")
+class InvalidPrecedingOrFollowingSize(DataError):
+ pass
+
+
+@sqlcode("22014")
+class InvalidArgumentForNtileFunction(DataError):
+ pass
+
+
+@sqlcode("22015")
+class IntervalFieldOverflow(DataError):
+ pass
+
+
+@sqlcode("22016")
+class InvalidArgumentForNthValueFunction(DataError):
+ pass
+
+
+@sqlcode("22018")
+class InvalidCharacterValueForCast(DataError):
+ pass
+
+
+@sqlcode("22019")
+class InvalidEscapeCharacter(DataError):
+ pass
+
+
+@sqlcode("2201B")
+class InvalidRegularExpression(DataError):
+ pass
+
+
+@sqlcode("2201E")
+class InvalidArgumentForLogarithm(DataError):
+ pass
+
+
+@sqlcode("2201F")
+class InvalidArgumentForPowerFunction(DataError):
+ pass
+
+
+@sqlcode("2201G")
+class InvalidArgumentForWidthBucketFunction(DataError):
+ pass
+
+
+@sqlcode("2201W")
+class InvalidRowCountInLimitClause(DataError):
+ pass
+
+
+@sqlcode("2201X")
+class InvalidRowCountInResultOffsetClause(DataError):
+ pass
+
+
+@sqlcode("22021")
+class CharacterNotInRepertoire(DataError):
+ pass
+
+
+@sqlcode("22022")
+class IndicatorOverflow(DataError):
+ pass
+
+
+@sqlcode("22023")
+class InvalidParameterValue(DataError):
+ pass
+
+
+@sqlcode("22024")
+class UnterminatedCString(DataError):
+ pass
+
+
+@sqlcode("22025")
+class InvalidEscapeSequence(DataError):
+ pass
+
+
+@sqlcode("22026")
+class StringDataLengthMismatch(DataError):
+ pass
+
+
+@sqlcode("22027")
+class TrimError(DataError):
+ pass
+
+
+@sqlcode("2202E")
+class ArraySubscriptError(DataError):
+ pass
+
+
+@sqlcode("2202G")
+class InvalidTablesampleRepeat(DataError):
+ pass
+
+
+@sqlcode("2202H")
+class InvalidTablesampleArgument(DataError):
+ pass
+
+
+@sqlcode("22030")
+class DuplicateJsonObjectKeyValue(DataError):
+ pass
+
+
+@sqlcode("22032")
+class InvalidJsonText(DataError):
+ pass
+
+
+@sqlcode("22033")
+class InvalidSqlJsonSubscript(DataError):
+ pass
+
+
+@sqlcode("22034")
+class MoreThanOneSqlJsonItem(DataError):
+ pass
+
+
+@sqlcode("22035")
+class NoSqlJsonItem(DataError):
+ pass
+
+
+@sqlcode("22036")
+class NonNumericSqlJsonItem(DataError):
+ pass
+
+
+@sqlcode("22037")
+class NonUniqueKeysInAJsonObject(DataError):
+ pass
+
+
+@sqlcode("22038")
+class SingletonSqlJsonItemRequired(DataError):
+ pass
+
+
+@sqlcode("22039")
+class SqlJsonArrayNotFound(DataError):
+ pass
+
+
+@sqlcode("2203A")
+class SqlJsonMemberNotFound(DataError):
+ pass
+
+
+@sqlcode("2203B")
+class SqlJsonNumberNotFound(DataError):
+ pass
+
+
+@sqlcode("2203C")
+class SqlJsonObjectNotFound(DataError):
+ pass
+
+
+@sqlcode("2203D")
+class TooManyJsonArrayElements(DataError):
+ pass
+
+
+@sqlcode("2203E")
+class TooManyJsonObjectMembers(DataError):
+ pass
+
+
+@sqlcode("2203F")
+class SqlJsonScalarRequired(DataError):
+ pass
+
+
+@sqlcode("22P01")
+class FloatingPointException(DataError):
+ pass
+
+
+@sqlcode("22P02")
+class InvalidTextRepresentation(DataError):
+ pass
+
+
+@sqlcode("22P03")
+class InvalidBinaryRepresentation(DataError):
+ pass
+
+
+@sqlcode("22P04")
+class BadCopyFileFormat(DataError):
+ pass
+
+
+@sqlcode("22P05")
+class UntranslatableCharacter(DataError):
+ pass
+
+
+@sqlcode("22P06")
+class NonstandardUseOfEscapeCharacter(DataError):
+ pass
+
+
+# Class 23 - Integrity Constraint Violation
+
+
+@sqlcode("23000")
+class IntegrityConstraintViolation(IntegrityError):
+ pass
+
+
+@sqlcode("23001")
+class RestrictViolation(IntegrityError):
+ pass
+
+
+@sqlcode("23502")
+class NotNullViolation(IntegrityError):
+ pass
+
+
+@sqlcode("23503")
+class ForeignKeyViolation(IntegrityError):
+ pass
+
+
+@sqlcode("23505")
+class UniqueViolation(IntegrityError):
+ pass
+
+
+@sqlcode("23514")
+class CheckViolation(IntegrityError):
+ pass
+
+
+@sqlcode("23P01")
+class ExclusionViolation(IntegrityError):
+ pass
+
+
+# Class 24 - Invalid Cursor State
+
+
+@sqlcode("24000")
+class InvalidCursorState(InternalError):
+ pass
+
+
+# Class 25 - Invalid Transaction State
+
+
+@sqlcode("25000")
+class InvalidTransactionState(InternalError):
+ pass
+
+
+@sqlcode("25001")
+class ActiveSqlTransaction(InternalError):
+ pass
+
+
+@sqlcode("25002")
+class BranchTransactionAlreadyActive(InternalError):
+ pass
+
+
+@sqlcode("25003")
+class InappropriateAccessModeForBranchTransaction(InternalError):
+ pass
+
+
+@sqlcode("25004")
+class InappropriateIsolationLevelForBranchTransaction(InternalError):
+ pass
+
+
+@sqlcode("25005")
+class NoActiveSqlTransactionForBranchTransaction(InternalError):
+ pass
+
+
+@sqlcode("25006")
+class ReadOnlySqlTransaction(InternalError):
+ pass
+
+
+@sqlcode("25007")
+class SchemaAndDataStatementMixingNotSupported(InternalError):
+ pass
+
+
+@sqlcode("25008")
+class HeldCursorRequiresSameIsolationLevel(InternalError):
+ pass
+
+
+@sqlcode("25P01")
+class NoActiveSqlTransaction(InternalError):
+ pass
+
+
+@sqlcode("25P02")
+class InFailedSqlTransaction(InternalError):
+ pass
+
+
+@sqlcode("25P03")
+class IdleInTransactionSessionTimeout(InternalError):
+ pass
+
+
+# Class 26 - Invalid SQL Statement Name
+
+
+@sqlcode("26000")
+class InvalidSqlStatementName(ProgrammingError):
+ pass
+
+
+# Class 27 - Triggered Data Change Violation
+
+
+@sqlcode("27000")
+class TriggeredDataChangeViolation(OperationalError):
+ pass
+
+
+# Class 28 - Invalid Authorization Specification
+
+
+@sqlcode("28000")
+class InvalidAuthorizationSpecification(OperationalError):
+ pass
+
+
+@sqlcode("28P01")
+class InvalidPassword(OperationalError):
+ pass
+
+
+# Class 2B - Dependent Privilege Descriptors Still Exist
+
+
+@sqlcode("2B000")
+class DependentPrivilegeDescriptorsStillExist(InternalError):
+ pass
+
+
+@sqlcode("2BP01")
+class DependentObjectsStillExist(InternalError):
+ pass
+
+
+# Class 2D - Invalid Transaction Termination
+
+
+@sqlcode("2D000")
+class InvalidTransactionTermination(InternalError):
+ pass
+
+
+# Class 2F - SQL Routine Exception
+
+
+@sqlcode("2F000")
+class SqlRoutineException(OperationalError):
+ pass
+
+
+@sqlcode("2F002")
+class ModifyingSqlDataNotPermitted(OperationalError):
+ pass
+
+
+@sqlcode("2F003")
+class ProhibitedSqlStatementAttempted(OperationalError):
+ pass
+
+
+@sqlcode("2F004")
+class ReadingSqlDataNotPermitted(OperationalError):
+ pass
+
+
+@sqlcode("2F005")
+class FunctionExecutedNoReturnStatement(OperationalError):
+ pass
+
+
+# Class 34 - Invalid Cursor Name
+
+
+@sqlcode("34000")
+class InvalidCursorName(ProgrammingError):
+ pass
+
+
+# Class 38 - External Routine Exception
+
+
+@sqlcode("38000")
+class ExternalRoutineException(OperationalError):
+ pass
+
+
+@sqlcode("38001")
+class ContainingSqlNotPermitted(OperationalError):
+ pass
+
+
+@sqlcode("38002")
+class ModifyingSqlDataNotPermittedExt(OperationalError):
+ pass
+
+
+@sqlcode("38003")
+class ProhibitedSqlStatementAttemptedExt(OperationalError):
+ pass
+
+
+@sqlcode("38004")
+class ReadingSqlDataNotPermittedExt(OperationalError):
+ pass
+
+
+# Class 39 - External Routine Invocation Exception
+
+
+@sqlcode("39000")
+class ExternalRoutineInvocationException(OperationalError):
+ pass
+
+
+@sqlcode("39001")
+class InvalidSqlstateReturned(OperationalError):
+ pass
+
+
+@sqlcode("39004")
+class NullValueNotAllowedExt(OperationalError):
+ pass
+
+
+@sqlcode("39P01")
+class TriggerProtocolViolated(OperationalError):
+ pass
+
+
+@sqlcode("39P02")
+class SrfProtocolViolated(OperationalError):
+ pass
+
+
+@sqlcode("39P03")
+class EventTriggerProtocolViolated(OperationalError):
+ pass
+
+
+# Class 3B - Savepoint Exception
+
+
+@sqlcode("3B000")
+class SavepointException(OperationalError):
+ pass
+
+
+@sqlcode("3B001")
+class InvalidSavepointSpecification(OperationalError):
+ pass
+
+
+# Class 3D - Invalid Catalog Name
+
+
+@sqlcode("3D000")
+class InvalidCatalogName(ProgrammingError):
+ pass
+
+
+# Class 3F - Invalid Schema Name
+
+
+@sqlcode("3F000")
+class InvalidSchemaName(ProgrammingError):
+ pass
+
+
+# Class 40 - Transaction Rollback
+
+
+@sqlcode("40000")
+class TransactionRollback(OperationalError):
+ pass
+
+
+@sqlcode("40001")
+class SerializationFailure(OperationalError):
+ pass
+
+
+@sqlcode("40002")
+class TransactionIntegrityConstraintViolation(OperationalError):
+ pass
+
+
+@sqlcode("40003")
+class StatementCompletionUnknown(OperationalError):
+ pass
+
+
+@sqlcode("40P01")
+class DeadlockDetected(OperationalError):
+ pass
+
+
+# Class 42 - Syntax Error or Access Rule Violation
+
+
+@sqlcode("42000")
+class SyntaxErrorOrAccessRuleViolation(ProgrammingError):
+ pass
+
+
+@sqlcode("42501")
+class InsufficientPrivilege(ProgrammingError):
+ pass
+
+
+@sqlcode("42601")
+class SyntaxError(ProgrammingError):
+ pass
+
+
+@sqlcode("42602")
+class InvalidName(ProgrammingError):
+ pass
+
+
+@sqlcode("42611")
+class InvalidColumnDefinition(ProgrammingError):
+ pass
+
+
+@sqlcode("42622")
+class NameTooLong(ProgrammingError):
+ pass
+
+
+@sqlcode("42701")
+class DuplicateColumn(ProgrammingError):
+ pass
+
+
+@sqlcode("42702")
+class AmbiguousColumn(ProgrammingError):
+ pass
+
+
+@sqlcode("42703")
+class UndefinedColumn(ProgrammingError):
+ pass
+
+
+@sqlcode("42704")
+class UndefinedObject(ProgrammingError):
+ pass
+
+
+@sqlcode("42710")
+class DuplicateObject(ProgrammingError):
+ pass
+
+
+@sqlcode("42712")
+class DuplicateAlias(ProgrammingError):
+ pass
+
+
+@sqlcode("42723")
+class DuplicateFunction(ProgrammingError):
+ pass
+
+
+@sqlcode("42725")
+class AmbiguousFunction(ProgrammingError):
+ pass
+
+
+@sqlcode("42803")
+class GroupingError(ProgrammingError):
+ pass
+
+
+@sqlcode("42804")
+class DatatypeMismatch(ProgrammingError):
+ pass
+
+
+@sqlcode("42809")
+class WrongObjectType(ProgrammingError):
+ pass
+
+
+@sqlcode("42830")
+class InvalidForeignKey(ProgrammingError):
+ pass
+
+
+@sqlcode("42846")
+class CannotCoerce(ProgrammingError):
+ pass
+
+
+@sqlcode("42883")
+class UndefinedFunction(ProgrammingError):
+ pass
+
+
+@sqlcode("428C9")
+class GeneratedAlways(ProgrammingError):
+ pass
+
+
+@sqlcode("42939")
+class ReservedName(ProgrammingError):
+ pass
+
+
+@sqlcode("42P01")
+class UndefinedTable(ProgrammingError):
+ pass
+
+
+@sqlcode("42P02")
+class UndefinedParameter(ProgrammingError):
+ pass
+
+
+@sqlcode("42P03")
+class DuplicateCursor(ProgrammingError):
+ pass
+
+
+@sqlcode("42P04")
+class DuplicateDatabase(ProgrammingError):
+ pass
+
+
+@sqlcode("42P05")
+class DuplicatePreparedStatement(ProgrammingError):
+ pass
+
+
+@sqlcode("42P06")
+class DuplicateSchema(ProgrammingError):
+ pass
+
+
+@sqlcode("42P07")
+class DuplicateTable(ProgrammingError):
+ pass
+
+
+@sqlcode("42P08")
+class AmbiguousParameter(ProgrammingError):
+ pass
+
+
+@sqlcode("42P09")
+class AmbiguousAlias(ProgrammingError):
+ pass
+
+
+@sqlcode("42P10")
+class InvalidColumnReference(ProgrammingError):
+ pass
+
+
+@sqlcode("42P11")
+class InvalidCursorDefinition(ProgrammingError):
+ pass
+
+
+@sqlcode("42P12")
+class InvalidDatabaseDefinition(ProgrammingError):
+ pass
+
+
+@sqlcode("42P13")
+class InvalidFunctionDefinition(ProgrammingError):
+ pass
+
+
+@sqlcode("42P14")
+class InvalidPreparedStatementDefinition(ProgrammingError):
+ pass
+
+
+@sqlcode("42P15")
+class InvalidSchemaDefinition(ProgrammingError):
+ pass
+
+
+@sqlcode("42P16")
+class InvalidTableDefinition(ProgrammingError):
+ pass
+
+
+@sqlcode("42P17")
+class InvalidObjectDefinition(ProgrammingError):
+ pass
+
+
+@sqlcode("42P18")
+class IndeterminateDatatype(ProgrammingError):
+ pass
+
+
+@sqlcode("42P19")
+class InvalidRecursion(ProgrammingError):
+ pass
+
+
+@sqlcode("42P20")
+class WindowingError(ProgrammingError):
+ pass
+
+
+@sqlcode("42P21")
+class CollationMismatch(ProgrammingError):
+ pass
+
+
+@sqlcode("42P22")
+class IndeterminateCollation(ProgrammingError):
+ pass
+
+
+# Class 44 - WITH CHECK OPTION Violation
+
+
+@sqlcode("44000")
+class WithCheckOptionViolation(ProgrammingError):
+ pass
+
+
+# Class 53 - Insufficient Resources
+
+
+@sqlcode("53000")
+class InsufficientResources(OperationalError):
+ pass
+
+
+@sqlcode("53100")
+class DiskFull(OperationalError):
+ pass
+
+
+@sqlcode("53200")
+class OutOfMemory(OperationalError):
+ pass
+
+
+@sqlcode("53300")
+class TooManyConnections(OperationalError):
+ pass
+
+
+@sqlcode("53400")
+class ConfigurationLimitExceeded(OperationalError):
+ pass
+
+
+# Class 54 - Program Limit Exceeded
+
+
+@sqlcode("54000")
+class ProgramLimitExceeded(OperationalError):
+ pass
+
+
+@sqlcode("54001")
+class StatementTooComplex(OperationalError):
+ pass
+
+
+@sqlcode("54011")
+class TooManyColumns(OperationalError):
+ pass
+
+
+@sqlcode("54023")
+class TooManyArguments(OperationalError):
+ pass
+
+
+# Class 55 - Object Not In Prerequisite State
+
+
+@sqlcode("55000")
+class ObjectNotInPrerequisiteState(OperationalError):
+ pass
+
+
+@sqlcode("55006")
+class ObjectInUse(OperationalError):
+ pass
+
+
+@sqlcode("55P02")
+class CantChangeRuntimeParam(OperationalError):
+ pass
+
+
+@sqlcode("55P03")
+class LockNotAvailable(OperationalError):
+ pass
+
+
+@sqlcode("55P04")
+class UnsafeNewEnumValueUsage(OperationalError):
+ pass
+
+
+# Class 57 - Operator Intervention
+
+
+@sqlcode("57000")
+class OperatorIntervention(OperationalError):
+ pass
+
+
+@sqlcode("57014")
+class QueryCanceled(OperationalError):
+ pass
+
+
+@sqlcode("57P01")
+class AdminShutdown(OperationalError):
+ pass
+
+
+@sqlcode("57P02")
+class CrashShutdown(OperationalError):
+ pass
+
+
+@sqlcode("57P03")
+class CannotConnectNow(OperationalError):
+ pass
+
+
+@sqlcode("57P04")
+class DatabaseDropped(OperationalError):
+ pass
+
+
+# Class 58 - System Error (errors external to PostgreSQL itself)
+
+
+@sqlcode("58000")
+class SystemError(OperationalError):
+ pass
+
+
+@sqlcode("58030")
+class IoError(OperationalError):
+ pass
+
+
+@sqlcode("58P01")
+class UndefinedFile(OperationalError):
+ pass
+
+
+@sqlcode("58P02")
+class DuplicateFile(OperationalError):
+ pass
+
+
+# Class 72 - Snapshot Failure
+
+
+@sqlcode("72000")
+class SnapshotTooOld(DatabaseError):
+ pass
+
+
+# Class F0 - Configuration File Error
+
+
+@sqlcode("F0000")
+class ConfigFileError(OperationalError):
+ pass
+
+
+@sqlcode("F0001")
+class LockFileExists(OperationalError):
+ pass
+
+
+# Class HV - Foreign Data Wrapper Error (SQL/MED)
+
+
+@sqlcode("HV000")
+class FdwError(OperationalError):
+ pass
+
+
+@sqlcode("HV001")
+class FdwOutOfMemory(OperationalError):
+ pass
+
+
+@sqlcode("HV002")
+class FdwDynamicParameterValueNeeded(OperationalError):
+ pass
+
+
+@sqlcode("HV004")
+class FdwInvalidDataType(OperationalError):
+ pass
+
+
+@sqlcode("HV005")
+class FdwColumnNameNotFound(OperationalError):
+ pass
+
+
+@sqlcode("HV006")
+class FdwInvalidDataTypeDescriptors(OperationalError):
+ pass
+
+
+@sqlcode("HV007")
+class FdwInvalidColumnName(OperationalError):
+ pass
+
+
+@sqlcode("HV008")
+class FdwInvalidColumnNumber(OperationalError):
+ pass
+
+
+@sqlcode("HV009")
+class FdwInvalidUseOfNullPointer(OperationalError):
+ pass
+
+
+@sqlcode("HV00A")
+class FdwInvalidStringFormat(OperationalError):
+ pass
+
+
+@sqlcode("HV00B")
+class FdwInvalidHandle(OperationalError):
+ pass
+
+
+@sqlcode("HV00C")
+class FdwInvalidOptionIndex(OperationalError):
+ pass
+
+
+@sqlcode("HV00D")
+class FdwInvalidOptionName(OperationalError):
+ pass
+
+
+@sqlcode("HV00J")
+class FdwOptionNameNotFound(OperationalError):
+ pass
+
+
+@sqlcode("HV00K")
+class FdwReplyHandle(OperationalError):
+ pass
+
+
+@sqlcode("HV00L")
+class FdwUnableToCreateExecution(OperationalError):
+ pass
+
+
+@sqlcode("HV00M")
+class FdwUnableToCreateReply(OperationalError):
+ pass
+
+
+@sqlcode("HV00N")
+class FdwUnableToEstablishConnection(OperationalError):
+ pass
+
+
+@sqlcode("HV00P")
+class FdwNoSchemas(OperationalError):
+ pass
+
+
+@sqlcode("HV00Q")
+class FdwSchemaNotFound(OperationalError):
+ pass
+
+
+@sqlcode("HV00R")
+class FdwTableNotFound(OperationalError):
+ pass
+
+
+@sqlcode("HV010")
+class FdwFunctionSequenceError(OperationalError):
+ pass
+
+
+@sqlcode("HV014")
+class FdwTooManyHandles(OperationalError):
+ pass
+
+
+@sqlcode("HV021")
+class FdwInconsistentDescriptorInformation(OperationalError):
+ pass
+
+
+@sqlcode("HV024")
+class FdwInvalidAttributeValue(OperationalError):
+ pass
+
+
+@sqlcode("HV090")
+class FdwInvalidStringLengthOrBufferLength(OperationalError):
+ pass
+
+
+@sqlcode("HV091")
+class FdwInvalidDescriptorFieldIdentifier(OperationalError):
+ pass
+
+
+# Class P0 - PL/pgSQL Error
+
+
+@sqlcode("P0000")
+class PlpgsqlError(ProgrammingError):
+ pass
+
+
+@sqlcode("P0001")
+class RaiseException(ProgrammingError):
+ pass
+
+
+@sqlcode("P0002")
+class NoDataFound(ProgrammingError):
+ pass
+
+
+@sqlcode("P0003")
+class TooManyRows(ProgrammingError):
+ pass
+
+
+@sqlcode("P0004")
+class AssertFailure(ProgrammingError):
+ pass
+
+
+# Class XX - Internal Error
+
+
+@sqlcode("XX000")
+class InternalError_(InternalError):
+ pass
+
+
+@sqlcode("XX001")
+class DataCorrupted(InternalError):
+ pass
+
+
+@sqlcode("XX002")
+class IndexCorrupted(InternalError):
+ pass
+
+
+# autogenerated: end
--- /dev/null
+#!/usr/bin/env python
+"""Generate per-sqlstate errors from PostgreSQL source code.
+
+The script can be run at a new PostgreSQL release to refresh the module.
+"""
+
+# Copyright (C) 2020 The Psycopg Team
+
+
+import os
+import re
+import sys
+from urllib.request import urlopen
+from collections import defaultdict
+
+from psycopg3.errors import get_base_exception
+
+
+def main():
+
+ fn = os.path.dirname(__file__) + "/../psycopg3/errors.py"
+
+ with open(fn, "r") as f:
+ lines = f.read().splitlines()
+
+ istart, iend = [
+ i
+ for i, line in enumerate(lines)
+ if re.match(r"\s*#\s*autogenerated:\s+(start|end)", line)
+ ]
+
+ classes, errors = fetch_errors(["9.5", "9.6", "10", "11", "12"])
+ lines[istart + 1 : iend] = generate_module_data(classes, errors)
+
+ with open(fn, "w") as f:
+ for line in lines:
+ f.write(line + "\n")
+
+
+def parse_errors_txt(url):
+ classes = {}
+ errors = defaultdict(dict)
+
+ page = urlopen(url)
+ for line in page.read().decode("ascii").splitlines():
+ # Strip comments and skip blanks
+ line = line.split("#")[0].strip()
+ if not line:
+ continue
+
+ # Parse a section
+ m = re.match(r"Section: (Class (..) - .+)", line)
+ if m:
+ label, class_ = m.groups()
+ classes[class_] = label
+ continue
+
+ # Parse an error
+ m = re.match(
+ r"(.....)\s+(?:E|W|S)\s+ERRCODE_(\S+)(?:\s+(\S+))?$", line
+ )
+ if m:
+ errcode, macro, spec = m.groups()
+ # skip errcodes without specs as they are not publically visible
+ if not spec:
+ continue
+ errlabel = spec.upper()
+ errors[class_][errcode] = errlabel
+ continue
+
+ # We don't expect anything else
+ raise ValueError("unexpected line:\n%s" % line)
+
+ return classes, errors
+
+
+errors_txt_url = (
+ "http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;"
+ "f=src/backend/utils/errcodes.txt;hb=%s"
+)
+
+
+def fetch_errors(versions):
+ classes = {}
+ errors = defaultdict(dict)
+
+ for version in versions:
+ print(version, file=sys.stderr)
+ tver = tuple(map(int, version.split()[0].split(".")))
+ tag = "%s%s_STABLE" % (
+ (tver[0] >= 10 and "REL_" or "REL"),
+ version.replace(".", "_"),
+ )
+ c1, e1 = parse_errors_txt(errors_txt_url % tag)
+ classes.update(c1)
+
+ for c, cerrs in e1.items():
+ errors[c].update(cerrs)
+
+ return classes, errors
+
+
+def generate_module_data(classes, errors):
+ tmpl = """
+@sqlcode(%(errcode)r)
+class %(cls)s(%(base)s):
+ pass
+"""
+ specific = {
+ "38002": "ModifyingSqlDataNotPermittedExt",
+ "38003": "ProhibitedSqlStatementAttemptedExt",
+ "38004": "ReadingSqlDataNotPermittedExt",
+ "39004": "NullValueNotAllowedExt",
+ "XX000": "InternalError_",
+ }
+
+ seen = set(
+ """
+ Error Warning InterfaceError DataError DatabaseError ProgrammingError
+ IntegrityError InternalError NotSupportedError OperationalError
+ """.split()
+ )
+
+ for clscode, clslabel in sorted(classes.items()):
+ if clscode in ("00", "01"):
+ # success and warning - never raised
+ continue
+
+ yield f"\n# {clslabel}"
+
+ for errcode, errlabel in sorted(errors[clscode].items()):
+ if errcode in specific:
+ clsname = specific[errcode]
+ else:
+ clsname = errlabel.title().replace("_", "")
+ if clsname in seen:
+ raise Exception("class already existing: %s" % clsname)
+ seen.add(clsname)
+
+ base = get_base_exception(errcode)
+
+ yield tmpl % {
+ "cls": clsname,
+ "errcode": errcode,
+ "base": base.__name__,
+ }
+
+
+if __name__ == "__main__":
+ sys.exit(main())