You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

error.go 15KB

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