MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_error.h
1 /* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #ifndef SQL_ERROR_H
17 #define SQL_ERROR_H
18 
19 #include "sql_list.h"
20 #include "m_string.h" /* LEX_STRING */
21 #include "sql_string.h" /* String */
22 #include "sql_plist.h" /* I_P_List */
23 #include "mysql_com.h" /* MYSQL_ERRMSG_SIZE */
24 
25 class THD;
26 class my_decimal;
27 
29 
35 class Sql_condition : public Sql_alloc
36 {
37 public:
38  /*
39  Enumeration value describing the severity of the error.
40 
41  Note that these enumeration values must correspond to the indices
42  of the sql_print_message_handlers array.
43  */
44  enum enum_warning_level
45  { WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END};
46 
51  const char* get_message_text() const;
52 
57  int get_message_octet_length() const;
58 
63  const char* get_sqlstate() const
64  { return m_returned_sqlstate; }
65 
70  uint get_sql_errno() const
71  { return m_sql_errno; }
72 
77  Sql_condition::enum_warning_level get_level() const
78  { return m_level; }
79 
80 private:
81  /*
82  The interface of Sql_condition is mostly private, by design,
83  so that only the following code:
84  - various raise_error() or raise_warning() methods in class THD,
85  - the implementation of SIGNAL / RESIGNAL / GET DIAGNOSTICS
86  - catch / re-throw of SQL conditions in stored procedures (sp_rcontext)
87  is allowed to create / modify a SQL condition.
88  Enforcing this policy prevents confusion, since the only public
89  interface available to the rest of the server implementation
90  is the interface offered by the THD methods (THD::raise_error()),
91  which should be used.
92  */
93  friend class THD;
94  friend class Warning_info;
95  friend class Sql_cmd_common_signal;
96  friend class Sql_cmd_signal;
97  friend class Sql_cmd_resignal;
98  friend class sp_rcontext;
99  friend class Condition_information_item;
100 
106  Sql_condition();
107 
113  void init(MEM_ROOT *mem_root);
114 
120  Sql_condition(MEM_ROOT *mem_root);
121 
123  ~Sql_condition()
124  {}
125 
130  void copy_opt_attributes(const Sql_condition *cond);
131 
140  void set(uint sql_errno, const char* sqlstate,
141  Sql_condition::enum_warning_level level,
142  const char* msg);
143 
149  void set_builtin_message_text(const char* str);
150 
152  void set_sqlstate(const char* sqlstate);
153 
155  void set_class_origins();
156 
160  void clear();
161 
162 private:
164  String m_class_origin;
165 
167  String m_subclass_origin;
168 
170  String m_constraint_catalog;
171 
173  String m_constraint_schema;
174 
176  String m_constraint_name;
177 
179  String m_catalog_name;
180 
182  String m_schema_name;
183 
185  String m_table_name;
186 
188  String m_column_name;
189 
191  String m_cursor_name;
192 
194  String m_message_text;
195 
197  uint m_sql_errno;
198 
203  char m_returned_sqlstate[SQLSTATE_LENGTH+1];
204 
206  Sql_condition::enum_warning_level m_level;
207 
209  Sql_condition *next_in_wi;
210  Sql_condition **prev_in_wi;
211 
213  MEM_ROOT *m_mem_root;
214 };
215 
217 
222 {
224  typedef I_P_List<Sql_condition,
226  &Sql_condition::next_in_wi,
227  &Sql_condition::prev_in_wi>,
231 
233  MEM_ROOT m_warn_root;
234 
236  Sql_condition_list m_warn_list;
237 
239  uint m_warn_count[(uint) Sql_condition::WARN_LEVEL_END];
240 
247  uint m_current_statement_warn_count;
248 
249  /*
250  Row counter, to print in errors and warnings. Not increased in
251  create_sort_index(); may differ from examined_row_count.
252  */
253  ulong m_current_row_for_warning;
254 
256  ulonglong m_warn_id;
257 
272  const Sql_condition *m_error_condition;
273 
275  bool m_allow_unlimited_warnings;
276 
278  bool m_read_only;
279 
281  Warning_info *m_next_in_da;
282  Warning_info **m_prev_in_da;
283 
284  List<Sql_condition> m_marked_sql_conditions;
285 
286 public:
287  Warning_info(ulonglong warn_id_arg, bool allow_unlimited_warnings);
288  ~Warning_info();
289 
290 private:
291  Warning_info(const Warning_info &rhs); /* Not implemented */
292  Warning_info& operator=(const Warning_info &rhs); /* Not implemented */
293 
303  bool has_sql_condition(const char *message_str, ulong message_length) const;
304 
312  void clear(ulonglong new_id);
313 
326  void opt_clear(ulonglong query_id)
327  {
328  if (query_id != m_warn_id)
329  clear(query_id);
330  }
331 
341  void append_warning_info(THD *thd, const Warning_info *source);
342 
348  void reset_for_next_command()
349  { m_current_statement_warn_count= 0; }
350 
355  void mark_sql_conditions_for_removal();
356 
361  void unmark_sql_conditions_from_removal()
362  { m_marked_sql_conditions.empty(); }
363 
368  void remove_marked_sql_conditions();
369 
380  bool is_marked_for_removal(const Sql_condition *cond) const;
381 
386  void mark_condition_for_removal(Sql_condition *cond)
387  { m_marked_sql_conditions.push_back(cond, &m_warn_root); }
388 
393  ulong warn_count() const
394  {
395  /*
396  This may be higher than warn_list.elements() if we have
397  had more warnings than thd->variables.max_error_count.
398  */
399  return (m_warn_count[(uint) Sql_condition::WARN_LEVEL_NOTE] +
400  m_warn_count[(uint) Sql_condition::WARN_LEVEL_ERROR] +
401  m_warn_count[(uint) Sql_condition::WARN_LEVEL_WARN]);
402  }
403 
408  ulong error_count() const
409  { return m_warn_count[(uint) Sql_condition::WARN_LEVEL_ERROR]; }
410 
414  uint cond_count() const
415  {
416  return m_warn_list.elements();
417  }
418 
420  ulonglong id() const { return m_warn_id; }
421 
423  void id(ulonglong id) { m_warn_id= id; }
424 
426  bool is_empty() const { return m_warn_list.is_empty(); }
427 
429  void inc_current_row_for_warning() { m_current_row_for_warning++; }
430 
432  void reset_current_row_for_warning() { m_current_row_for_warning= 1; }
433 
435  ulong current_row_for_warning() const { return m_current_row_for_warning; }
436 
438  ulong current_statement_warn_count() const
439  { return m_current_statement_warn_count; }
440 
442  void reserve_space(THD *thd, uint count);
443 
456  Sql_condition *push_warning(THD *thd,
457  uint sql_errno,
458  const char* sqlstate,
459  Sql_condition::enum_warning_level level,
460  const char* msg);
461 
471  Sql_condition *push_warning(THD *thd, const Sql_condition *sql_condition);
472 
484  void set_read_only(bool read_only)
485  { m_read_only= read_only; }
486 
491  bool is_read_only() const
492  { return m_read_only; }
493 
500  const Sql_condition *get_error_condition() const
501  { return m_error_condition; }
502 
508  void set_error_condition(const Sql_condition *error_condition)
509  { m_error_condition= error_condition; }
510 
517  void clear_error_condition()
518  { m_error_condition= NULL; }
519 
520  // for:
521  // - m_next_in_da / m_prev_in_da
522  // - is_marked_for_removal()
523  friend class Diagnostics_area;
524 };
525 
526 uint err_conv(char *buff, size_t to_length, const char *from,
527  size_t from_length, const CHARSET_INFO *from_cs);
528 
530 {
531  char err_buffer[MYSQL_ERRMSG_SIZE];
532  size_t buf_length;
533 public:
534  ErrConvString(String *str)
535  {
536  buf_length= err_conv(err_buffer, sizeof(err_buffer), str->ptr(),
537  str->length(), str->charset());
538  }
539 
540  ErrConvString(const char *str, const CHARSET_INFO* cs)
541  {
542  buf_length= err_conv(err_buffer, sizeof(err_buffer), str, strlen(str), cs);
543  }
544 
545  ErrConvString(const char *str, uint length)
546  {
547  buf_length= err_conv(err_buffer, sizeof(err_buffer), str, length,
548  &my_charset_latin1);
549  }
550 
551  ErrConvString(const char *str, uint length, const CHARSET_INFO* cs)
552  {
553  buf_length= err_conv(err_buffer, sizeof(err_buffer), str, length, cs);
554  }
555 
556  ErrConvString(longlong nr)
557  {
558  buf_length= my_snprintf(err_buffer, sizeof(err_buffer), "%lld", nr);
559  }
560 
561  ErrConvString(longlong nr, bool unsigned_flag)
562  {
563  buf_length= longlong10_to_str(nr, err_buffer, unsigned_flag ? 10 : -10) -
564  err_buffer;
565  }
566 
567  ErrConvString(double nr);
568  ErrConvString(const my_decimal *nr);
569  ErrConvString(const struct st_mysql_time *ltime, uint dec);
570 
571  ~ErrConvString() { };
572  char *ptr() { return err_buffer; }
573  size_t length() const { return buf_length; }
574 };
575 
577 
585 {
586 private:
588  typedef I_P_List<Warning_info,
590  &Warning_info::m_next_in_da,
591  &Warning_info::m_prev_in_da>,
595 
596 public:
600 
602  {
613  };
614 
615  void set_overwrite_status(bool can_overwrite_status)
616  { m_can_overwrite_status= can_overwrite_status; }
617 
618  bool is_sent() const { return m_is_sent; }
619 
620  void set_is_sent(bool is_sent) { m_is_sent= is_sent; }
621 
622  void set_ok_status(ulonglong affected_rows,
623  ulonglong last_insert_id,
624  const char *message);
625 
626  void set_eof_status(THD *thd);
627 
628  void set_error_status(uint sql_errno);
629 
630  void set_error_status(uint sql_errno,
631  const char *message,
632  const char *sqlstate,
633  const Sql_condition *error_condition);
634 
635  void disable_status();
636 
637  void reset_diagnostics_area();
638 
639  bool is_set() const { return m_status != DA_EMPTY; }
640 
641  bool is_error() const { return m_status == DA_ERROR; }
642 
643  bool is_eof() const { return m_status == DA_EOF; }
644 
645  bool is_ok() const { return m_status == DA_OK; }
646 
647  bool is_disabled() const { return m_status == DA_DISABLED; }
648 
649  enum_diagnostics_status status() const { return m_status; }
650 
651  const char *message() const
652  { DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK); return m_message; }
653 
654  uint sql_errno() const
655  { DBUG_ASSERT(m_status == DA_ERROR); return m_sql_errno; }
656 
657  const char* get_sqlstate() const
658  { DBUG_ASSERT(m_status == DA_ERROR); return m_sqlstate; }
659 
660  ulonglong affected_rows() const
661  { DBUG_ASSERT(m_status == DA_OK); return m_affected_rows; }
662 
663  ulonglong last_insert_id() const
664  { DBUG_ASSERT(m_status == DA_OK); return m_last_insert_id; }
665 
666  uint statement_warn_count() const
667  {
668  DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF);
669  return m_statement_warn_count;
670  }
671 
673  Diagnostics_area(ulonglong warning_info_id, bool allow_unlimited_warnings);
674 
675  void push_warning_info(Warning_info *wi)
676  { m_wi_stack.push_front(wi); }
677 
678  void pop_warning_info()
679  {
680  DBUG_ASSERT(m_wi_stack.elements() > 0);
681  m_wi_stack.remove(m_wi_stack.front());
682  }
683 
684  void set_warning_info_id(ulonglong id)
685  { get_warning_info()->id(id); }
686 
687  ulonglong warning_info_id() const
688  { return get_warning_info()->id(); }
689 
700  bool warning_info_changed(const Warning_info *wi) const
701  { return get_warning_info()->id() != wi->id(); }
702 
703  bool is_warning_info_empty() const
704  { return get_warning_info()->is_empty(); }
705 
706  ulong current_statement_warn_count() const
707  { return get_warning_info()->current_statement_warn_count(); }
708 
709  bool has_sql_condition(const char *message_str, ulong message_length) const
710  { return get_warning_info()->has_sql_condition(message_str, message_length); }
711 
712  void reset_for_next_command()
713  { get_warning_info()->reset_for_next_command(); }
714 
715  void clear_warning_info(ulonglong id)
716  { get_warning_info()->clear(id); }
717 
718  void opt_clear_warning_info(ulonglong query_id)
719  { get_warning_info()->opt_clear(query_id); }
720 
721  ulong current_row_for_warning() const
722  { return get_warning_info()->current_row_for_warning(); }
723 
724  void inc_current_row_for_warning()
725  { get_warning_info()->inc_current_row_for_warning(); }
726 
727  void reset_current_row_for_warning()
728  { get_warning_info()->reset_current_row_for_warning(); }
729 
730  bool is_warning_info_read_only() const
731  { return get_warning_info()->is_read_only(); }
732 
733  void set_warning_info_read_only(bool read_only)
734  { get_warning_info()->set_read_only(read_only); }
735 
736  ulong error_count() const
737  { return get_warning_info()->error_count(); }
738 
739  ulong warn_count() const
740  { return get_warning_info()->warn_count(); }
741 
742  uint cond_count() const
743  { return get_warning_info()->cond_count(); }
744 
745  Sql_condition_iterator sql_conditions() const
746  { return get_warning_info()->m_warn_list; }
747 
748  void reserve_space(THD *thd, uint count)
749  { get_warning_info()->reserve_space(thd, count); }
750 
751  Sql_condition *push_warning(THD *thd, const Sql_condition *sql_condition)
752  { return get_warning_info()->push_warning(thd, sql_condition); }
753 
754  Sql_condition *push_warning(THD *thd,
755  uint sql_errno,
756  const char* sqlstate,
757  Sql_condition::enum_warning_level level,
758  const char* msg)
759  {
760  return get_warning_info()->push_warning(thd,
761  sql_errno, sqlstate, level, msg);
762  }
763 
764  void mark_sql_conditions_for_removal()
765  { get_warning_info()->mark_sql_conditions_for_removal(); }
766 
767  void unmark_sql_conditions_from_removal()
768  { get_warning_info()->unmark_sql_conditions_from_removal(); }
769 
770  void remove_marked_sql_conditions()
771  { get_warning_info()->remove_marked_sql_conditions(); }
772 
773  const Sql_condition *get_error_condition() const
774  { return get_warning_info()->get_error_condition(); }
775 
776  void copy_sql_conditions_to_wi(THD *thd, Warning_info *dst_wi) const
777  { dst_wi->append_warning_info(thd, get_warning_info()); }
778 
779  void copy_sql_conditions_from_wi(THD *thd, const Warning_info *src_wi)
780  { get_warning_info()->append_warning_info(thd, src_wi); }
781 
782  void copy_non_errors_from_wi(THD *thd, const Warning_info *src_wi);
783 
784 private:
785  Warning_info *get_warning_info() { return m_wi_stack.front(); }
786 
787  const Warning_info *get_warning_info() const { return m_wi_stack.front(); }
788 
789 private:
791  bool m_is_sent;
792 
794  bool m_can_overwrite_status;
795 
797  char m_message[MYSQL_ERRMSG_SIZE];
798 
803  uint m_sql_errno;
804 
805  char m_sqlstate[SQLSTATE_LENGTH+1];
806 
818  ulonglong m_affected_rows;
819 
825  ulonglong m_last_insert_id;
826 
833  uint m_statement_warn_count;
834 
835  enum_diagnostics_status m_status;
836 
837  Warning_info m_main_wi;
838 
839  Warning_info_list m_wi_stack;
840 };
841 
843 
844 
845 void push_warning(THD *thd, Sql_condition::enum_warning_level level,
846  uint code, const char *msg);
847 
848 void push_warning_printf(THD *thd, Sql_condition::enum_warning_level level,
849  uint code, const char *format, ...);
850 
851 bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
852 
853 uint32 convert_error_message(char *to, uint32 to_length,
854  const CHARSET_INFO *to_cs,
855  const char *from, uint32 from_length,
856  const CHARSET_INFO *from_cs, uint *errors);
857 
858 extern const LEX_STRING warning_level_names[];
859 
860 bool is_sqlstate_valid(const LEX_STRING *sqlstate);
861 
862 
872 inline bool is_sqlstate_completion(const char *s)
873 { return s[0] == '0' && s[1] == '0'; }
874 
875 
885 inline bool is_sqlstate_warning(const char *s)
886 { return s[0] == '0' && s[1] == '1'; }
887 
888 
898 inline bool is_sqlstate_not_found(const char *s)
899 { return s[0] == '0' && s[1] == '2'; }
900 
901 
911 inline bool is_sqlstate_exception(const char *s)
912 { return s[0] != '0' || s[1] > '2'; }
913 
914 
915 #endif // SQL_ERROR_H