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.

508 lines
15 KiB

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