PageRenderTime 73ms CodeModel.GetById 14ms app.highlight 43ms RepoModel.GetById 11ms app.codeStats 0ms

/Godeps/_workspace/src/github.com/lib/pq/error.go

https://github.com/mmcgrana/pgpin
Go | 487 lines | 401 code | 17 blank | 69 comment | 13 complexity | fdfcc6fd6dabc5e45b866620201aa83f MD5 | raw file
  1package pq
  2
  3import (
  4	"database/sql/driver"
  5	"fmt"
  6	"io"
  7	"net"
  8	"runtime"
  9)
 10
 11// Error severities
 12const (
 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
 25type 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.
 46type 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.
 53func (ec ErrorCode) Name() string {
 54	return errorCodeNames[ec]
 55}
 56
 57// ErrorClass is only the class part of an error code.
 58type 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").
 63func (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.
 71func (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
 78var 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	"22026": "string_data_length_mismatch",
157	"22001": "string_data_right_truncation",
158	"22011": "substring_error",
159	"22027": "trim_error",
160	"22024": "unterminated_c_string",
161	"2200F": "zero_length_character_string",
162	"22P01": "floating_point_exception",
163	"22P02": "invalid_text_representation",
164	"22P03": "invalid_binary_representation",
165	"22P04": "bad_copy_file_format",
166	"22P05": "untranslatable_character",
167	"2200L": "not_an_xml_document",
168	"2200M": "invalid_xml_document",
169	"2200N": "invalid_xml_content",
170	"2200S": "invalid_xml_comment",
171	"2200T": "invalid_xml_processing_instruction",
172	// Class 23 - Integrity Constraint Violation
173	"23000": "integrity_constraint_violation",
174	"23001": "restrict_violation",
175	"23502": "not_null_violation",
176	"23503": "foreign_key_violation",
177	"23505": "unique_violation",
178	"23514": "check_violation",
179	"23P01": "exclusion_violation",
180	// Class 24 - Invalid Cursor State
181	"24000": "invalid_cursor_state",
182	// Class 25 - Invalid Transaction State
183	"25000": "invalid_transaction_state",
184	"25001": "active_sql_transaction",
185	"25002": "branch_transaction_already_active",
186	"25008": "held_cursor_requires_same_isolation_level",
187	"25003": "inappropriate_access_mode_for_branch_transaction",
188	"25004": "inappropriate_isolation_level_for_branch_transaction",
189	"25005": "no_active_sql_transaction_for_branch_transaction",
190	"25006": "read_only_sql_transaction",
191	"25007": "schema_and_data_statement_mixing_not_supported",
192	"25P01": "no_active_sql_transaction",
193	"25P02": "in_failed_sql_transaction",
194	// Class 26 - Invalid SQL Statement Name
195	"26000": "invalid_sql_statement_name",
196	// Class 27 - Triggered Data Change Violation
197	"27000": "triggered_data_change_violation",
198	// Class 28 - Invalid Authorization Specification
199	"28000": "invalid_authorization_specification",
200	"28P01": "invalid_password",
201	// Class 2B - Dependent Privilege Descriptors Still Exist
202	"2B000": "dependent_privilege_descriptors_still_exist",
203	"2BP01": "dependent_objects_still_exist",
204	// Class 2D - Invalid Transaction Termination
205	"2D000": "invalid_transaction_termination",
206	// Class 2F - SQL Routine Exception
207	"2F000": "sql_routine_exception",
208	"2F005": "function_executed_no_return_statement",
209	"2F002": "modifying_sql_data_not_permitted",
210	"2F003": "prohibited_sql_statement_attempted",
211	"2F004": "reading_sql_data_not_permitted",
212	// Class 34 - Invalid Cursor Name
213	"34000": "invalid_cursor_name",
214	// Class 38 - External Routine Exception
215	"38000": "external_routine_exception",
216	"38001": "containing_sql_not_permitted",
217	"38002": "modifying_sql_data_not_permitted",
218	"38003": "prohibited_sql_statement_attempted",
219	"38004": "reading_sql_data_not_permitted",
220	// Class 39 - External Routine Invocation Exception
221	"39000": "external_routine_invocation_exception",
222	"39001": "invalid_sqlstate_returned",
223	"39004": "null_value_not_allowed",
224	"39P01": "trigger_protocol_violated",
225	"39P02": "srf_protocol_violated",
226	// Class 3B - Savepoint Exception
227	"3B000": "savepoint_exception",
228	"3B001": "invalid_savepoint_specification",
229	// Class 3D - Invalid Catalog Name
230	"3D000": "invalid_catalog_name",
231	// Class 3F - Invalid Schema Name
232	"3F000": "invalid_schema_name",
233	// Class 40 - Transaction Rollback
234	"40000": "transaction_rollback",
235	"40002": "transaction_integrity_constraint_violation",
236	"40001": "serialization_failure",
237	"40003": "statement_completion_unknown",
238	"40P01": "deadlock_detected",
239	// Class 42 - Syntax Error or Access Rule Violation
240	"42000": "syntax_error_or_access_rule_violation",
241	"42601": "syntax_error",
242	"42501": "insufficient_privilege",
243	"42846": "cannot_coerce",
244	"42803": "grouping_error",
245	"42P20": "windowing_error",
246	"42P19": "invalid_recursion",
247	"42830": "invalid_foreign_key",
248	"42602": "invalid_name",
249	"42622": "name_too_long",
250	"42939": "reserved_name",
251	"42804": "datatype_mismatch",
252	"42P18": "indeterminate_datatype",
253	"42P21": "collation_mismatch",
254	"42P22": "indeterminate_collation",
255	"42809": "wrong_object_type",
256	"42703": "undefined_column",
257	"42883": "undefined_function",
258	"42P01": "undefined_table",
259	"42P02": "undefined_parameter",
260	"42704": "undefined_object",
261	"42701": "duplicate_column",
262	"42P03": "duplicate_cursor",
263	"42P04": "duplicate_database",
264	"42723": "duplicate_function",
265	"42P05": "duplicate_prepared_statement",
266	"42P06": "duplicate_schema",
267	"42P07": "duplicate_table",
268	"42712": "duplicate_alias",
269	"42710": "duplicate_object",
270	"42702": "ambiguous_column",
271	"42725": "ambiguous_function",
272	"42P08": "ambiguous_parameter",
273	"42P09": "ambiguous_alias",
274	"42P10": "invalid_column_reference",
275	"42611": "invalid_column_definition",
276	"42P11": "invalid_cursor_definition",
277	"42P12": "invalid_database_definition",
278	"42P13": "invalid_function_definition",
279	"42P14": "invalid_prepared_statement_definition",
280	"42P15": "invalid_schema_definition",
281	"42P16": "invalid_table_definition",
282	"42P17": "invalid_object_definition",
283	// Class 44 - WITH CHECK OPTION Violation
284	"44000": "with_check_option_violation",
285	// Class 53 - Insufficient Resources
286	"53000": "insufficient_resources",
287	"53100": "disk_full",
288	"53200": "out_of_memory",
289	"53300": "too_many_connections",
290	"53400": "configuration_limit_exceeded",
291	// Class 54 - Program Limit Exceeded
292	"54000": "program_limit_exceeded",
293	"54001": "statement_too_complex",
294	"54011": "too_many_columns",
295	"54023": "too_many_arguments",
296	// Class 55 - Object Not In Prerequisite State
297	"55000": "object_not_in_prerequisite_state",
298	"55006": "object_in_use",
299	"55P02": "cant_change_runtime_param",
300	"55P03": "lock_not_available",
301	// Class 57 - Operator Intervention
302	"57000": "operator_intervention",
303	"57014": "query_canceled",
304	"57P01": "admin_shutdown",
305	"57P02": "crash_shutdown",
306	"57P03": "cannot_connect_now",
307	"57P04": "database_dropped",
308	// Class 58 - System Error (errors external to PostgreSQL itself)
309	"58000": "system_error",
310	"58030": "io_error",
311	"58P01": "undefined_file",
312	"58P02": "duplicate_file",
313	// Class F0 - Configuration File Error
314	"F0000": "config_file_error",
315	"F0001": "lock_file_exists",
316	// Class HV - Foreign Data Wrapper Error (SQL/MED)
317	"HV000": "fdw_error",
318	"HV005": "fdw_column_name_not_found",
319	"HV002": "fdw_dynamic_parameter_value_needed",
320	"HV010": "fdw_function_sequence_error",
321	"HV021": "fdw_inconsistent_descriptor_information",
322	"HV024": "fdw_invalid_attribute_value",
323	"HV007": "fdw_invalid_column_name",
324	"HV008": "fdw_invalid_column_number",
325	"HV004": "fdw_invalid_data_type",
326	"HV006": "fdw_invalid_data_type_descriptors",
327	"HV091": "fdw_invalid_descriptor_field_identifier",
328	"HV00B": "fdw_invalid_handle",
329	"HV00C": "fdw_invalid_option_index",
330	"HV00D": "fdw_invalid_option_name",
331	"HV090": "fdw_invalid_string_length_or_buffer_length",
332	"HV00A": "fdw_invalid_string_format",
333	"HV009": "fdw_invalid_use_of_null_pointer",
334	"HV014": "fdw_too_many_handles",
335	"HV001": "fdw_out_of_memory",
336	"HV00P": "fdw_no_schemas",
337	"HV00J": "fdw_option_name_not_found",
338	"HV00K": "fdw_reply_handle",
339	"HV00Q": "fdw_schema_not_found",
340	"HV00R": "fdw_table_not_found",
341	"HV00L": "fdw_unable_to_create_execution",
342	"HV00M": "fdw_unable_to_create_reply",
343	"HV00N": "fdw_unable_to_establish_connection",
344	// Class P0 - PL/pgSQL Error
345	"P0000": "plpgsql_error",
346	"P0001": "raise_exception",
347	"P0002": "no_data_found",
348	"P0003": "too_many_rows",
349	// Class XX - Internal Error
350	"XX000": "internal_error",
351	"XX001": "data_corrupted",
352	"XX002": "index_corrupted",
353}
354
355func parseError(r *readBuf) *Error {
356	err := new(Error)
357	for t := r.byte(); t != 0; t = r.byte() {
358		msg := r.string()
359		switch t {
360		case 'S':
361			err.Severity = msg
362		case 'C':
363			err.Code = ErrorCode(msg)
364		case 'M':
365			err.Message = msg
366		case 'D':
367			err.Detail = msg
368		case 'H':
369			err.Hint = msg
370		case 'P':
371			err.Position = msg
372		case 'p':
373			err.InternalPosition = msg
374		case 'q':
375			err.InternalQuery = msg
376		case 'W':
377			err.Where = msg
378		case 's':
379			err.Schema = msg
380		case 't':
381			err.Table = msg
382		case 'c':
383			err.Column = msg
384		case 'd':
385			err.DataTypeName = msg
386		case 'n':
387			err.Constraint = msg
388		case 'F':
389			err.File = msg
390		case 'L':
391			err.Line = msg
392		case 'R':
393			err.Routine = msg
394		}
395	}
396	return err
397}
398
399// Fatal returns true if the Error Severity is fatal.
400func (err *Error) Fatal() bool {
401	return err.Severity == Efatal
402}
403
404// Get implements the legacy PGError interface. New code should use the fields
405// of the Error struct directly.
406func (err *Error) Get(k byte) (v string) {
407	switch k {
408	case 'S':
409		return err.Severity
410	case 'C':
411		return string(err.Code)
412	case 'M':
413		return err.Message
414	case 'D':
415		return err.Detail
416	case 'H':
417		return err.Hint
418	case 'P':
419		return err.Position
420	case 'p':
421		return err.InternalPosition
422	case 'q':
423		return err.InternalQuery
424	case 'W':
425		return err.Where
426	case 's':
427		return err.Schema
428	case 't':
429		return err.Table
430	case 'c':
431		return err.Column
432	case 'd':
433		return err.DataTypeName
434	case 'n':
435		return err.Constraint
436	case 'F':
437		return err.File
438	case 'L':
439		return err.Line
440	case 'R':
441		return err.Routine
442	}
443	return ""
444}
445
446func (err Error) Error() string {
447	return "pq: " + err.Message
448}
449
450// PGError is an interface used by previous versions of pq. It is provided
451// only to support legacy code. New code should use the Error type.
452type PGError interface {
453	Error() string
454	Fatal() bool
455	Get(k byte) (v string)
456}
457
458func errorf(s string, args ...interface{}) {
459	panic(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...)))
460}
461
462func errRecover(err *error) {
463	e := recover()
464	switch v := e.(type) {
465	case nil:
466		// Do nothing
467	case runtime.Error:
468		panic(v)
469	case *Error:
470		if v.Fatal() {
471			*err = driver.ErrBadConn
472		} else {
473			*err = v
474		}
475	case *net.OpError:
476		*err = driver.ErrBadConn
477	case error:
478		if v == io.EOF || v.(error).Error() == "remote error: handshake failure" {
479			*err = driver.ErrBadConn
480		} else {
481			*err = v
482		}
483
484	default:
485		panic(fmt.Sprintf("unknown error: %#v", e))
486	}
487}