...

Source file src/github.com/lib/pq/error.go

Documentation: github.com/lib/pq

     1  package pq
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"fmt"
     6  	"io"
     7  	"net"
     8  	"runtime"
     9  )
    10  
    11  // Error severities
    12  const (
    13  	Efatal   = "FATAL"
    14  	Epanic   = "PANIC"
    15  	Ewarning = "WARNING"
    16  	Enotice  = "NOTICE"
    17  	Edebug   = "DEBUG"
    18  	Einfo    = "INFO"
    19  	Elog     = "LOG"
    20  )
    21  
    22  // Error represents an error communicating with the server.
    23  //
    24  // See http://www.postgresql.org/docs/current/static/protocol-error-fields.html for details of the fields
    25  type Error struct {
    26  	Severity         string
    27  	Code             ErrorCode
    28  	Message          string
    29  	Detail           string
    30  	Hint             string
    31  	Position         string
    32  	InternalPosition string
    33  	InternalQuery    string
    34  	Where            string
    35  	Schema           string
    36  	Table            string
    37  	Column           string
    38  	DataTypeName     string
    39  	Constraint       string
    40  	File             string
    41  	Line             string
    42  	Routine          string
    43  }
    44  
    45  // ErrorCode is a five-character error code.
    46  type ErrorCode string
    47  
    48  // Name returns a more human friendly rendering of the error code, namely the
    49  // "condition name".
    50  //
    51  // See http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html for
    52  // details.
    53  func (ec ErrorCode) Name() string {
    54  	return errorCodeNames[ec]
    55  }
    56  
    57  // ErrorClass is only the class part of an error code.
    58  type ErrorClass string
    59  
    60  // Name returns the condition name of an error class.  It is equivalent to the
    61  // condition name of the "standard" error code (i.e. the one having the last
    62  // three characters "000").
    63  func (ec ErrorClass) Name() string {
    64  	return errorCodeNames[ErrorCode(ec+"000")]
    65  }
    66  
    67  // Class returns the error class, e.g. "28".
    68  //
    69  // See http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html for
    70  // details.
    71  func (ec ErrorCode) Class() ErrorClass {
    72  	return ErrorClass(ec[0:2])
    73  }
    74  
    75  // errorCodeNames is a mapping between the five-character error codes and the
    76  // human readable "condition names". It is derived from the list at
    77  // http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html
    78  var errorCodeNames = map[ErrorCode]string{
    79  	// Class 00 - Successful Completion
    80  	"00000": "successful_completion",
    81  	// Class 01 - Warning
    82  	"01000": "warning",
    83  	"0100C": "dynamic_result_sets_returned",
    84  	"01008": "implicit_zero_bit_padding",
    85  	"01003": "null_value_eliminated_in_set_function",
    86  	"01007": "privilege_not_granted",
    87  	"01006": "privilege_not_revoked",
    88  	"01004": "string_data_right_truncation",
    89  	"01P01": "deprecated_feature",
    90  	// Class 02 - No Data (this is also a warning class per the SQL standard)
    91  	"02000": "no_data",
    92  	"02001": "no_additional_dynamic_result_sets_returned",
    93  	// Class 03 - SQL Statement Not Yet Complete
    94  	"03000": "sql_statement_not_yet_complete",
    95  	// Class 08 - Connection Exception
    96  	"08000": "connection_exception",
    97  	"08003": "connection_does_not_exist",
    98  	"08006": "connection_failure",
    99  	"08001": "sqlclient_unable_to_establish_sqlconnection",
   100  	"08004": "sqlserver_rejected_establishment_of_sqlconnection",
   101  	"08007": "transaction_resolution_unknown",
   102  	"08P01": "protocol_violation",
   103  	// Class 09 - Triggered Action Exception
   104  	"09000": "triggered_action_exception",
   105  	// Class 0A - Feature Not Supported
   106  	"0A000": "feature_not_supported",
   107  	// Class 0B - Invalid Transaction Initiation
   108  	"0B000": "invalid_transaction_initiation",
   109  	// Class 0F - Locator Exception
   110  	"0F000": "locator_exception",
   111  	"0F001": "invalid_locator_specification",
   112  	// Class 0L - Invalid Grantor
   113  	"0L000": "invalid_grantor",
   114  	"0LP01": "invalid_grant_operation",
   115  	// Class 0P - Invalid Role Specification
   116  	"0P000": "invalid_role_specification",
   117  	// Class 0Z - Diagnostics Exception
   118  	"0Z000": "diagnostics_exception",
   119  	"0Z002": "stacked_diagnostics_accessed_without_active_handler",
   120  	// Class 20 - Case Not Found
   121  	"20000": "case_not_found",
   122  	// Class 21 - Cardinality Violation
   123  	"21000": "cardinality_violation",
   124  	// Class 22 - Data Exception
   125  	"22000": "data_exception",
   126  	"2202E": "array_subscript_error",
   127  	"22021": "character_not_in_repertoire",
   128  	"22008": "datetime_field_overflow",
   129  	"22012": "division_by_zero",
   130  	"22005": "error_in_assignment",
   131  	"2200B": "escape_character_conflict",
   132  	"22022": "indicator_overflow",
   133  	"22015": "interval_field_overflow",
   134  	"2201E": "invalid_argument_for_logarithm",
   135  	"22014": "invalid_argument_for_ntile_function",
   136  	"22016": "invalid_argument_for_nth_value_function",
   137  	"2201F": "invalid_argument_for_power_function",
   138  	"2201G": "invalid_argument_for_width_bucket_function",
   139  	"22018": "invalid_character_value_for_cast",
   140  	"22007": "invalid_datetime_format",
   141  	"22019": "invalid_escape_character",
   142  	"2200D": "invalid_escape_octet",
   143  	"22025": "invalid_escape_sequence",
   144  	"22P06": "nonstandard_use_of_escape_character",
   145  	"22010": "invalid_indicator_parameter_value",
   146  	"22023": "invalid_parameter_value",
   147  	"2201B": "invalid_regular_expression",
   148  	"2201W": "invalid_row_count_in_limit_clause",
   149  	"2201X": "invalid_row_count_in_result_offset_clause",
   150  	"22009": "invalid_time_zone_displacement_value",
   151  	"2200C": "invalid_use_of_escape_character",
   152  	"2200G": "most_specific_type_mismatch",
   153  	"22004": "null_value_not_allowed",
   154  	"22002": "null_value_no_indicator_parameter",
   155  	"22003": "numeric_value_out_of_range",
   156  	"2200H": "sequence_generator_limit_exceeded",
   157  	"22026": "string_data_length_mismatch",
   158  	"22001": "string_data_right_truncation",
   159  	"22011": "substring_error",
   160  	"22027": "trim_error",
   161  	"22024": "unterminated_c_string",
   162  	"2200F": "zero_length_character_string",
   163  	"22P01": "floating_point_exception",
   164  	"22P02": "invalid_text_representation",
   165  	"22P03": "invalid_binary_representation",
   166  	"22P04": "bad_copy_file_format",
   167  	"22P05": "untranslatable_character",
   168  	"2200L": "not_an_xml_document",
   169  	"2200M": "invalid_xml_document",
   170  	"2200N": "invalid_xml_content",
   171  	"2200S": "invalid_xml_comment",
   172  	"2200T": "invalid_xml_processing_instruction",
   173  	// Class 23 - Integrity Constraint Violation
   174  	"23000": "integrity_constraint_violation",
   175  	"23001": "restrict_violation",
   176  	"23502": "not_null_violation",
   177  	"23503": "foreign_key_violation",
   178  	"23505": "unique_violation",
   179  	"23514": "check_violation",
   180  	"23P01": "exclusion_violation",
   181  	// Class 24 - Invalid Cursor State
   182  	"24000": "invalid_cursor_state",
   183  	// Class 25 - Invalid Transaction State
   184  	"25000": "invalid_transaction_state",
   185  	"25001": "active_sql_transaction",
   186  	"25002": "branch_transaction_already_active",
   187  	"25008": "held_cursor_requires_same_isolation_level",
   188  	"25003": "inappropriate_access_mode_for_branch_transaction",
   189  	"25004": "inappropriate_isolation_level_for_branch_transaction",
   190  	"25005": "no_active_sql_transaction_for_branch_transaction",
   191  	"25006": "read_only_sql_transaction",
   192  	"25007": "schema_and_data_statement_mixing_not_supported",
   193  	"25P01": "no_active_sql_transaction",
   194  	"25P02": "in_failed_sql_transaction",
   195  	// Class 26 - Invalid SQL Statement Name
   196  	"26000": "invalid_sql_statement_name",
   197  	// Class 27 - Triggered Data Change Violation
   198  	"27000": "triggered_data_change_violation",
   199  	// Class 28 - Invalid Authorization Specification
   200  	"28000": "invalid_authorization_specification",
   201  	"28P01": "invalid_password",
   202  	// Class 2B - Dependent Privilege Descriptors Still Exist
   203  	"2B000": "dependent_privilege_descriptors_still_exist",
   204  	"2BP01": "dependent_objects_still_exist",
   205  	// Class 2D - Invalid Transaction Termination
   206  	"2D000": "invalid_transaction_termination",
   207  	// Class 2F - SQL Routine Exception
   208  	"2F000": "sql_routine_exception",
   209  	"2F005": "function_executed_no_return_statement",
   210  	"2F002": "modifying_sql_data_not_permitted",
   211  	"2F003": "prohibited_sql_statement_attempted",
   212  	"2F004": "reading_sql_data_not_permitted",
   213  	// Class 34 - Invalid Cursor Name
   214  	"34000": "invalid_cursor_name",
   215  	// Class 38 - External Routine Exception
   216  	"38000": "external_routine_exception",
   217  	"38001": "containing_sql_not_permitted",
   218  	"38002": "modifying_sql_data_not_permitted",
   219  	"38003": "prohibited_sql_statement_attempted",
   220  	"38004": "reading_sql_data_not_permitted",
   221  	// Class 39 - External Routine Invocation Exception
   222  	"39000": "external_routine_invocation_exception",
   223  	"39001": "invalid_sqlstate_returned",
   224  	"39004": "null_value_not_allowed",
   225  	"39P01": "trigger_protocol_violated",
   226  	"39P02": "srf_protocol_violated",
   227  	// Class 3B - Savepoint Exception
   228  	"3B000": "savepoint_exception",
   229  	"3B001": "invalid_savepoint_specification",
   230  	// Class 3D - Invalid Catalog Name
   231  	"3D000": "invalid_catalog_name",
   232  	// Class 3F - Invalid Schema Name
   233  	"3F000": "invalid_schema_name",
   234  	// Class 40 - Transaction Rollback
   235  	"40000": "transaction_rollback",
   236  	"40002": "transaction_integrity_constraint_violation",
   237  	"40001": "serialization_failure",
   238  	"40003": "statement_completion_unknown",
   239  	"40P01": "deadlock_detected",
   240  	// Class 42 - Syntax Error or Access Rule Violation
   241  	"42000": "syntax_error_or_access_rule_violation",
   242  	"42601": "syntax_error",
   243  	"42501": "insufficient_privilege",
   244  	"42846": "cannot_coerce",
   245  	"42803": "grouping_error",
   246  	"42P20": "windowing_error",
   247  	"42P19": "invalid_recursion",
   248  	"42830": "invalid_foreign_key",
   249  	"42602": "invalid_name",
   250  	"42622": "name_too_long",
   251  	"42939": "reserved_name",
   252  	"42804": "datatype_mismatch",
   253  	"42P18": "indeterminate_datatype",
   254  	"42P21": "collation_mismatch",
   255  	"42P22": "indeterminate_collation",
   256  	"42809": "wrong_object_type",
   257  	"42703": "undefined_column",
   258  	"42883": "undefined_function",
   259  	"42P01": "undefined_table",
   260  	"42P02": "undefined_parameter",
   261  	"42704": "undefined_object",
   262  	"42701": "duplicate_column",
   263  	"42P03": "duplicate_cursor",
   264  	"42P04": "duplicate_database",
   265  	"42723": "duplicate_function",
   266  	"42P05": "duplicate_prepared_statement",
   267  	"42P06": "duplicate_schema",
   268  	"42P07": "duplicate_table",
   269  	"42712": "duplicate_alias",
   270  	"42710": "duplicate_object",
   271  	"42702": "ambiguous_column",
   272  	"42725": "ambiguous_function",
   273  	"42P08": "ambiguous_parameter",
   274  	"42P09": "ambiguous_alias",
   275  	"42P10": "invalid_column_reference",
   276  	"42611": "invalid_column_definition",
   277  	"42P11": "invalid_cursor_definition",
   278  	"42P12": "invalid_database_definition",
   279  	"42P13": "invalid_function_definition",
   280  	"42P14": "invalid_prepared_statement_definition",
   281  	"42P15": "invalid_schema_definition",
   282  	"42P16": "invalid_table_definition",
   283  	"42P17": "invalid_object_definition",
   284  	// Class 44 - WITH CHECK OPTION Violation
   285  	"44000": "with_check_option_violation",
   286  	// Class 53 - Insufficient Resources
   287  	"53000": "insufficient_resources",
   288  	"53100": "disk_full",
   289  	"53200": "out_of_memory",
   290  	"53300": "too_many_connections",
   291  	"53400": "configuration_limit_exceeded",
   292  	// Class 54 - Program Limit Exceeded
   293  	"54000": "program_limit_exceeded",
   294  	"54001": "statement_too_complex",
   295  	"54011": "too_many_columns",
   296  	"54023": "too_many_arguments",
   297  	// Class 55 - Object Not In Prerequisite State
   298  	"55000": "object_not_in_prerequisite_state",
   299  	"55006": "object_in_use",
   300  	"55P02": "cant_change_runtime_param",
   301  	"55P03": "lock_not_available",
   302  	// Class 57 - Operator Intervention
   303  	"57000": "operator_intervention",
   304  	"57014": "query_canceled",
   305  	"57P01": "admin_shutdown",
   306  	"57P02": "crash_shutdown",
   307  	"57P03": "cannot_connect_now",
   308  	"57P04": "database_dropped",
   309  	// Class 58 - System Error (errors external to PostgreSQL itself)
   310  	"58000": "system_error",
   311  	"58030": "io_error",
   312  	"58P01": "undefined_file",
   313  	"58P02": "duplicate_file",
   314  	// Class F0 - Configuration File Error
   315  	"F0000": "config_file_error",
   316  	"F0001": "lock_file_exists",
   317  	// Class HV - Foreign Data Wrapper Error (SQL/MED)
   318  	"HV000": "fdw_error",
   319  	"HV005": "fdw_column_name_not_found",
   320  	"HV002": "fdw_dynamic_parameter_value_needed",
   321  	"HV010": "fdw_function_sequence_error",
   322  	"HV021": "fdw_inconsistent_descriptor_information",
   323  	"HV024": "fdw_invalid_attribute_value",
   324  	"HV007": "fdw_invalid_column_name",
   325  	"HV008": "fdw_invalid_column_number",
   326  	"HV004": "fdw_invalid_data_type",
   327  	"HV006": "fdw_invalid_data_type_descriptors",
   328  	"HV091": "fdw_invalid_descriptor_field_identifier",
   329  	"HV00B": "fdw_invalid_handle",
   330  	"HV00C": "fdw_invalid_option_index",
   331  	"HV00D": "fdw_invalid_option_name",
   332  	"HV090": "fdw_invalid_string_length_or_buffer_length",
   333  	"HV00A": "fdw_invalid_string_format",
   334  	"HV009": "fdw_invalid_use_of_null_pointer",
   335  	"HV014": "fdw_too_many_handles",
   336  	"HV001": "fdw_out_of_memory",
   337  	"HV00P": "fdw_no_schemas",
   338  	"HV00J": "fdw_option_name_not_found",
   339  	"HV00K": "fdw_reply_handle",
   340  	"HV00Q": "fdw_schema_not_found",
   341  	"HV00R": "fdw_table_not_found",
   342  	"HV00L": "fdw_unable_to_create_execution",
   343  	"HV00M": "fdw_unable_to_create_reply",
   344  	"HV00N": "fdw_unable_to_establish_connection",
   345  	// Class P0 - PL/pgSQL Error
   346  	"P0000": "plpgsql_error",
   347  	"P0001": "raise_exception",
   348  	"P0002": "no_data_found",
   349  	"P0003": "too_many_rows",
   350  	// Class XX - Internal Error
   351  	"XX000": "internal_error",
   352  	"XX001": "data_corrupted",
   353  	"XX002": "index_corrupted",
   354  }
   355  
   356  func parseError(r *readBuf) *Error {
   357  	err := new(Error)
   358  	for t := r.byte(); t != 0; t = r.byte() {
   359  		msg := r.string()
   360  		switch t {
   361  		case 'S':
   362  			err.Severity = msg
   363  		case 'C':
   364  			err.Code = ErrorCode(msg)
   365  		case 'M':
   366  			err.Message = msg
   367  		case 'D':
   368  			err.Detail = msg
   369  		case 'H':
   370  			err.Hint = msg
   371  		case 'P':
   372  			err.Position = msg
   373  		case 'p':
   374  			err.InternalPosition = msg
   375  		case 'q':
   376  			err.InternalQuery = msg
   377  		case 'W':
   378  			err.Where = msg
   379  		case 's':
   380  			err.Schema = msg
   381  		case 't':
   382  			err.Table = msg
   383  		case 'c':
   384  			err.Column = msg
   385  		case 'd':
   386  			err.DataTypeName = msg
   387  		case 'n':
   388  			err.Constraint = msg
   389  		case 'F':
   390  			err.File = msg
   391  		case 'L':
   392  			err.Line = msg
   393  		case 'R':
   394  			err.Routine = msg
   395  		}
   396  	}
   397  	return err
   398  }
   399  
   400  // Fatal returns true if the Error Severity is fatal.
   401  func (err *Error) Fatal() bool {
   402  	return err.Severity == Efatal
   403  }
   404  
   405  // SQLState returns the SQLState of the error.
   406  func (err *Error) SQLState() string {
   407  	return string(err.Code)
   408  }
   409  
   410  // Get implements the legacy PGError interface. New code should use the fields
   411  // of the Error struct directly.
   412  func (err *Error) Get(k byte) (v string) {
   413  	switch k {
   414  	case 'S':
   415  		return err.Severity
   416  	case 'C':
   417  		return string(err.Code)
   418  	case 'M':
   419  		return err.Message
   420  	case 'D':
   421  		return err.Detail
   422  	case 'H':
   423  		return err.Hint
   424  	case 'P':
   425  		return err.Position
   426  	case 'p':
   427  		return err.InternalPosition
   428  	case 'q':
   429  		return err.InternalQuery
   430  	case 'W':
   431  		return err.Where
   432  	case 's':
   433  		return err.Schema
   434  	case 't':
   435  		return err.Table
   436  	case 'c':
   437  		return err.Column
   438  	case 'd':
   439  		return err.DataTypeName
   440  	case 'n':
   441  		return err.Constraint
   442  	case 'F':
   443  		return err.File
   444  	case 'L':
   445  		return err.Line
   446  	case 'R':
   447  		return err.Routine
   448  	}
   449  	return ""
   450  }
   451  
   452  func (err *Error) Error() string {
   453  	return "pq: " + err.Message
   454  }
   455  
   456  // PGError is an interface used by previous versions of pq. It is provided
   457  // only to support legacy code. New code should use the Error type.
   458  type PGError interface {
   459  	Error() string
   460  	Fatal() bool
   461  	Get(k byte) (v string)
   462  }
   463  
   464  func errorf(s string, args ...interface{}) {
   465  	panic(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...)))
   466  }
   467  
   468  // TODO(ainar-g) Rename to errorf after removing panics.
   469  func fmterrorf(s string, args ...interface{}) error {
   470  	return fmt.Errorf("pq: %s", fmt.Sprintf(s, args...))
   471  }
   472  
   473  func errRecoverNoErrBadConn(err *error) {
   474  	e := recover()
   475  	if e == nil {
   476  		// Do nothing
   477  		return
   478  	}
   479  	var ok bool
   480  	*err, ok = e.(error)
   481  	if !ok {
   482  		*err = fmt.Errorf("pq: unexpected error: %#v", e)
   483  	}
   484  }
   485  
   486  func (cn *conn) errRecover(err *error) {
   487  	e := recover()
   488  	switch v := e.(type) {
   489  	case nil:
   490  		// Do nothing
   491  	case runtime.Error:
   492  		cn.err.set(driver.ErrBadConn)
   493  		panic(v)
   494  	case *Error:
   495  		if v.Fatal() {
   496  			*err = driver.ErrBadConn
   497  		} else {
   498  			*err = v
   499  		}
   500  	case *net.OpError:
   501  		cn.err.set(driver.ErrBadConn)
   502  		*err = v
   503  	case *safeRetryError:
   504  		cn.err.set(driver.ErrBadConn)
   505  		*err = driver.ErrBadConn
   506  	case error:
   507  		if v == io.EOF || v.Error() == "remote error: handshake failure" {
   508  			*err = driver.ErrBadConn
   509  		} else {
   510  			*err = v
   511  		}
   512  
   513  	default:
   514  		cn.err.set(driver.ErrBadConn)
   515  		panic(fmt.Sprintf("unknown error: %#v", e))
   516  	}
   517  
   518  	// Any time we return ErrBadConn, we need to remember it since *Tx doesn't
   519  	// mark the connection bad in database/sql.
   520  	if *err == driver.ErrBadConn {
   521  		cn.err.set(driver.ErrBadConn)
   522  	}
   523  }
   524  

View as plain text