source: code/trunk/vendor/github.com/lib/pq/error.go@ 822

Last change on this file since 822 was 822, checked in by yakumo.izuru, 22 months ago

Prefer immortal.run over runit and rc.d, use vendored modules
for convenience.

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 15.5 KB
Line 
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 "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
356func 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.
401func (err *Error) Fatal() bool {
402 return err.Severity == Efatal
403}
404
405// SQLState returns the SQLState of the error.
406func (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.
412func (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
452func (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.
458type PGError interface {
459 Error() string
460 Fatal() bool
461 Get(k byte) (v string)
462}
463
464func 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.
469func fmterrorf(s string, args ...interface{}) error {
470 return fmt.Errorf("pq: %s", fmt.Sprintf(s, args...))
471}
472
473func 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
486func (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}
Note: See TracBrowser for help on using the repository browser.