1 /* Copyright (c) 2005, 2021, Oracle and/or its affiliates.
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, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #ifndef SQL_ERROR_H
24 #define SQL_ERROR_H
25 
26 #include "sql_list.h"
27 #include "sql_string.h"                        /* String */
28 #include "sql_plist.h" /* I_P_List */
29 #include "mysql_com.h" /* MYSQL_ERRMSG_SIZE */
30 
31 class THD;
32 class my_decimal;
33 typedef struct st_mysql_lex_string LEX_STRING;
34 
35 ///////////////////////////////////////////////////////////////////////////
36 
37 /**
38   Representation of a SQL condition.
39   A SQL condition can be a completion condition (note, warning),
40   or an exception condition (error, not found).
41 */
42 class Sql_condition : public Sql_alloc
43 {
44 public:
45   /**
46     Enumeration value describing the severity of the condition.
47   */
48   enum enum_severity_level
49   { SL_NOTE, SL_WARNING, SL_ERROR, SEVERITY_END};
50 
51   /**
52     Get the MESSAGE_TEXT of this condition.
53     @return the message text.
54   */
message_text()55   const char* message_text() const
56   { return m_message_text.ptr(); }
57 
58   /**
59     Get the MESSAGE_OCTET_LENGTH of this condition.
60     @return the length in bytes of the message text.
61   */
message_octet_length()62   size_t message_octet_length() const
63   { return m_message_text.length(); }
64 
65   /**
66     Get the RETURNED_SQLSTATE of this condition.
67     @return the sql state.
68   */
returned_sqlstate()69   const char* returned_sqlstate() const
70   { return m_returned_sqlstate; }
71 
72   /**
73     Get the MYSQL_ERRNO of this condition.
74     @return the sql error number condition item.
75   */
mysql_errno()76   uint mysql_errno() const
77   { return m_mysql_errno; }
78 
79   /**
80     Get the severity level of this condition.
81     @return the severity level condition item.
82   */
severity()83   Sql_condition::enum_severity_level severity() const
84   { return m_severity_level; }
85 
86 private:
87   /*
88     The interface of Sql_condition is mostly private, by design,
89     so that only the following code:
90     - various raise_error() or raise_warning() methods in class THD,
91     - the implementation of SIGNAL / RESIGNAL / GET DIAGNOSTICS
92     - catch / re-throw of SQL conditions in stored procedures (sp_rcontext)
93     is allowed to create / modify a SQL condition.
94     Enforcing this policy prevents confusion, since the only public
95     interface available to the rest of the server implementation
96     is the interface offered by the THD methods (THD::raise_error()),
97     which should be used.
98   */
99   friend class THD;
100   friend class Diagnostics_area;
101   friend class Sql_cmd_common_signal;
102   friend class Sql_cmd_signal;
103   friend class Sql_cmd_resignal;
104   friend class sp_rcontext;
105   friend class Condition_information_item;
106 
107   /**
108     Constructor.
109 
110     @param mem_root Memory root to use for the condition items
111                     of this condition.
112   */
113   Sql_condition(MEM_ROOT *mem_root);
114 
115   /**
116     Constructor.
117 
118     @param mem_root          Memory root to use for the condition items
119                              of this condition.
120     @param mysql_errno       MYSQL_ERRNO
121     @param returned_sqlstate RETURNED_SQLSTATE
122     @param severity          Severity level - error, warning or note.
123     @param message_Text      MESSAGE_TEXT
124   */
125   Sql_condition(MEM_ROOT *mem_root,
126                 uint mysql_errno,
127                 const char* returned_sqlstate,
128                 Sql_condition::enum_severity_level severity,
129                 const char *message_text);
130 
131   /** Destructor. */
~Sql_condition()132   ~Sql_condition()
133   {}
134 
135   /**
136     Copy optional condition items attributes.
137     @param cond the condition to copy.
138   */
139   void copy_opt_attributes(const Sql_condition *cond);
140 
141   /**
142     Set the condition message test.
143     @param message_text  Message text, expressed in the character set derived
144                          from the server --language option
145   */
146   void set_message_text(const char* message_text);
147 
148   /** Set the RETURNED_SQLSTATE of this condition. */
set_returned_sqlstate(const char * sqlstate)149   void set_returned_sqlstate(const char* sqlstate)
150   {
151     memcpy(m_returned_sqlstate, sqlstate, SQLSTATE_LENGTH);
152     m_returned_sqlstate[SQLSTATE_LENGTH]= '\0';
153   }
154 
155   /** Set the CLASS_ORIGIN and SUBCLASS_ORIGIN of this condition. */
156   void set_class_origins();
157 
158 private:
159   /** SQL CLASS_ORIGIN condition item. */
160   String m_class_origin;
161 
162   /** SQL SUBCLASS_ORIGIN condition item. */
163   String m_subclass_origin;
164 
165   /** SQL CONSTRAINT_CATALOG condition item. */
166   String m_constraint_catalog;
167 
168   /** SQL CONSTRAINT_SCHEMA condition item. */
169   String m_constraint_schema;
170 
171   /** SQL CONSTRAINT_NAME condition item. */
172   String m_constraint_name;
173 
174   /** SQL CATALOG_NAME condition item. */
175   String m_catalog_name;
176 
177   /** SQL SCHEMA_NAME condition item. */
178   String m_schema_name;
179 
180   /** SQL TABLE_NAME condition item. */
181   String m_table_name;
182 
183   /** SQL COLUMN_NAME condition item. */
184   String m_column_name;
185 
186   /** SQL CURSOR_NAME condition item. */
187   String m_cursor_name;
188 
189   /** Message text, expressed in the character set implied by --language. */
190   String m_message_text;
191 
192   /** MySQL extension, MYSQL_ERRNO condition item. */
193   uint m_mysql_errno;
194 
195   /**
196     SQL RETURNED_SQLSTATE condition item.
197     This member is always NUL terminated.
198   */
199   char m_returned_sqlstate[SQLSTATE_LENGTH+1];
200 
201   /** Severity (error, warning, note) of this condition. */
202   Sql_condition::enum_severity_level m_severity_level;
203 
204   /** Pointers for participating in the list of conditions. */
205   Sql_condition *m_next_condition;
206   Sql_condition **m_prev_condition;
207 
208   /** Memory root to use to hold condition item values. */
209   MEM_ROOT *m_mem_root;
210 };
211 
212 ///////////////////////////////////////////////////////////////////////////
213 
214 size_t err_conv(char *buff, size_t to_length, const char *from,
215                 size_t from_length, const CHARSET_INFO *from_cs);
216 
217 class ErrConvString
218 {
219   char err_buffer[MYSQL_ERRMSG_SIZE];
220   size_t buf_length;
221 public:
ErrConvString(String * str)222   explicit ErrConvString(String *str)
223   {
224     buf_length= err_conv(err_buffer, sizeof(err_buffer), str->ptr(),
225                          str->length(), str->charset());
226   }
227 
ErrConvString(const char * str,const CHARSET_INFO * cs)228   ErrConvString(const char *str, const CHARSET_INFO* cs)
229   {
230     buf_length= err_conv(err_buffer, sizeof(err_buffer), str, strlen(str), cs);
231   }
232 
ErrConvString(const char * str,size_t length)233   ErrConvString(const char *str, size_t length)
234   {
235     buf_length= err_conv(err_buffer, sizeof(err_buffer), str, length,
236                          &my_charset_latin1);
237   }
238 
ErrConvString(const char * str,size_t length,const CHARSET_INFO * cs)239   ErrConvString(const char *str, size_t length, const CHARSET_INFO* cs)
240   {
241     buf_length= err_conv(err_buffer, sizeof(err_buffer), str, length, cs);
242   }
243 
ErrConvString(longlong nr)244   ErrConvString(longlong nr)
245   {
246     buf_length= my_snprintf(err_buffer, sizeof(err_buffer), "%lld", nr);
247   }
248 
ErrConvString(longlong nr,bool unsigned_flag)249   ErrConvString(longlong nr, bool unsigned_flag)
250   {
251     buf_length= longlong10_to_str(nr, err_buffer, unsigned_flag ? 10 : -10) -
252                 err_buffer;
253   }
254 
255   ErrConvString(double nr);
256   ErrConvString(const my_decimal *nr);
257   ErrConvString(const struct st_mysql_time *ltime, uint dec);
258 
~ErrConvString()259   ~ErrConvString() { };
ptr()260   char *ptr() { return err_buffer; }
length()261   size_t length() const { return buf_length; }
262 };
263 
264 ///////////////////////////////////////////////////////////////////////////
265 
266 /**
267   Stores status of the currently executed statement.
268   Cleared at the beginning of the statement, and then
269   can hold either OK, ERROR, or EOF status.
270   Can not be assigned twice per statement.
271 */
272 class Diagnostics_area
273 {
274   /** The type of the counted and doubly linked list of conditions. */
275   typedef I_P_List<Sql_condition,
276                    I_P_List_adapter<Sql_condition,
277                                     &Sql_condition::m_next_condition,
278                                     &Sql_condition::m_prev_condition>,
279                    I_P_List_counter,
280                    I_P_List_fast_push_back<Sql_condition> >
281           Sql_condition_list;
282 
283 public:
284   /** Const iterator used to iterate through the condition list. */
285   typedef Sql_condition_list::Const_Iterator Sql_condition_iterator;
286 
287   enum enum_diagnostics_status
288   {
289     /** The area is cleared at start of a statement. */
290     DA_EMPTY= 0,
291     /** Set whenever one calls my_ok(). */
292     DA_OK,
293     /** Set whenever one calls my_eof(). */
294     DA_EOF,
295     /** Set whenever one calls my_error() or my_message(). */
296     DA_ERROR,
297     /** Set in case of a custom response, such as one from COM_STMT_PREPARE. */
298     DA_DISABLED
299   };
300 
301   Diagnostics_area(bool allow_unlimited_conditions);
302   ~Diagnostics_area();
303 
set_overwrite_status(bool can_overwrite_status)304   void set_overwrite_status(bool can_overwrite_status)
305   { m_can_overwrite_status= can_overwrite_status; }
306 
is_sent()307   bool is_sent() const { return m_is_sent; }
308 
set_is_sent(bool is_sent)309   void set_is_sent(bool is_sent) { m_is_sent= is_sent; }
310 
311   /**
312     Set OK status -- ends commands that do not return a
313     result set, e.g. INSERT/UPDATE/DELETE.
314 
315     @param affected_rows  The number of rows affected by the last statement.
316                           @sa Diagnostics_area::m_affected_rows.
317     @param last_insert_id The value to be returned by LAST_INSERT_ID().
318                           @sa Diagnostics_area::m_last_insert_id.
319     @param message_text   The OK-message text.
320   */
321   void set_ok_status(ulonglong affected_rows,
322                      ulonglong last_insert_id,
323                      const char *message_text);
324 
325   /**
326     Set EOF status.
327 
328     @param thd  Thread context.
329   */
330   void set_eof_status(THD *thd);
331 
332   /**
333     Set ERROR status in the Diagnostics Area. This function should be used to
334     report fatal errors (such as out-of-memory errors) when no further
335     processing is possible.
336 
337     @param mysql_errno      SQL-condition error number
338   */
339   void set_error_status(uint mysql_errno);
340 
341   /**
342     Set ERROR status in the Diagnostics Area.
343 
344     @param mysql_errno        SQL-condition error number
345     @param message_text       SQL-condition message
346     @param returned_sqlstate  SQL-condition state
347   */
348   void set_error_status(uint mysql_errno,
349                         const char *message_text,
350                         const char *returned_sqlstate);
351 
352   /**
353     Mark the Diagnostics Area as 'DISABLED'.
354 
355     This is used in rare cases when the COM_ command at hand sends a response
356     in a custom format. One example is the query cache, another is
357     COM_STMT_PREPARE.
358   */
disable_status()359   void disable_status()
360   {
361     assert(m_status == DA_EMPTY);
362     m_status= DA_DISABLED;
363   }
364 
365   /**
366     Clear this Diagnostics Area.
367 
368     Normally called at the end of a statement.
369   */
370   void reset_diagnostics_area();
371 
is_set()372   bool is_set() const { return m_status != DA_EMPTY; }
373 
is_error()374   bool is_error() const { return m_status == DA_ERROR; }
375 
is_eof()376   bool is_eof() const { return m_status == DA_EOF; }
377 
is_ok()378   bool is_ok() const { return m_status == DA_OK; }
379 
is_disabled()380   bool is_disabled() const { return m_status == DA_DISABLED; }
381 
status()382   enum_diagnostics_status status() const { return m_status; }
383 
message_text()384   const char *message_text() const
385   {
386     assert(m_status == DA_ERROR || m_status == DA_OK);
387     return m_message_text;
388   }
389 
mysql_errno()390   uint mysql_errno() const
391   {
392     assert(m_status == DA_ERROR);
393     return m_mysql_errno;
394   }
395 
returned_sqlstate()396   const char* returned_sqlstate() const
397   {
398     assert(m_status == DA_ERROR);
399     return m_returned_sqlstate;
400   }
401 
affected_rows()402   ulonglong affected_rows() const
403   {
404     assert(m_status == DA_OK);
405     return m_affected_rows;
406   }
407 
last_insert_id()408   ulonglong last_insert_id() const
409   {
410     assert(m_status == DA_OK);
411     return m_last_insert_id;
412   }
413 
last_statement_cond_count()414   uint last_statement_cond_count() const
415   {
416     assert(m_status == DA_OK || m_status == DA_EOF);
417     return m_last_statement_cond_count;
418   }
419 
420   /** Return the number of conditions raised by the current statement. */
current_statement_cond_count()421   ulong current_statement_cond_count() const
422   { return m_current_statement_cond_count; }
423 
424   /**
425     Reset between two COM_ commands. Conditions are preserved
426     between commands, but m_current_statement_cond_count indicates
427     the number of conditions of this particular statement only.
428   */
reset_statement_cond_count()429   void reset_statement_cond_count()
430   { m_current_statement_cond_count= 0; }
431 
432   /**
433     Checks if the condition list contains SQL-condition with the given message.
434 
435     @param message_text    Message text
436     @param message_length  Length of message_text
437 
438     @return true if the condition list contains an SQL-condition with the given
439     message text.
440   */
441   bool has_sql_condition(const char *message_text, size_t message_length) const;
442 
443   /**
444     Checks if the condition list contains SQL-condition with the given error
445     code.
446 
447     @param sql_errno    Error code
448 
449     @return true if the condition list contains an SQL-condition with the given
450     error code.
451   */
452   bool has_sql_condition(uint sql_errno) const;
453 
454   /**
455     Reset the current condition information stored in the Diagnostics Area.
456     Clear all conditions, the number of conditions, reset current row counter
457     to point to the first row.
458   */
459   void reset_condition_info(THD *thd);
460 
461   /** Return the current counter value. */
current_row_for_condition()462   ulong current_row_for_condition() const
463   { return m_current_row_for_condition; }
464 
465   /** Increment the current row counter to point at the next row. */
inc_current_row_for_condition()466   void inc_current_row_for_condition()
467   { m_current_row_for_condition++; }
468 
469   /** Reset the current row counter. Start counting from the first row. */
reset_current_row_for_condition()470   void reset_current_row_for_condition()
471   { m_current_row_for_condition= 1; }
472 
473   /**
474     The number of errors, or number of rows returned by SHOW ERRORS,
475     also the value of session variable @@error_count.
476   */
477   ulong error_count(THD *thd) const;
478 
479   /**
480     Used for @@warning_count system variable, which prints
481     the number of rows returned by SHOW WARNINGS.
482  */
483   ulong warn_count(THD *thd) const;
484 
485   /**
486     The number of conditions (errors, warnings and notes) in the list.
487   */
cond_count()488   uint cond_count() const
489   { return m_conditions_list.elements(); }
490 
sql_conditions()491   Sql_condition_iterator sql_conditions() const
492   { return m_conditions_list; }
493 
494   const char * get_first_condition_message();
495 
496   /** Make sure there is room for the given number of conditions. */
497   void reserve_number_of_conditions(THD *thd, uint count);
498 
499   /**
500     Add a new SQL-condition to the current list and increment the respective
501     counters.
502 
503     @param thd                Thread context.
504     @param mysql_errno        SQL-condition error number.
505     @param returned_sqlstate  SQL-condition state.
506     @param severity           SQL-condition severity.
507     @param message_text       SQL-condition message.
508 
509     @return a pointer to the added SQL-condition.
510   */
511   Sql_condition *push_warning(THD *thd,
512                               uint mysql_errno,
513                               const char* returned_sqlstate,
514                               Sql_condition::enum_severity_level severity,
515                               const char* message_text);
516 
517   /**
518     Mark current SQL-conditions so that we can later know which
519     SQL-conditions have been added.
520   */
521   void mark_preexisting_sql_conditions();
522 
523   /**
524     Copy SQL-conditions that have been added since
525     mark_preexisting_sql_conditions() was called.
526 
527     @param thd    Thread context.
528     @param src_da Diagnostics Area to copy from.
529   */
530   void copy_new_sql_conditions(THD *thd, const Diagnostics_area *src_da);
531 
532   /**
533     Copy all SQL-conditions from src_da to this DA.
534 
535     @param thd    Thread context.
536     @param src_da Diagnostics Area to copy from.
537   */
538   void copy_sql_conditions_from_da(THD *thd, const Diagnostics_area *src_da);
539 
540   /**
541     Copy Sql_conditions that are not SL_ERROR from the source
542     Diagnostics Area to the current Diagnostics Area.
543 
544     @param thd    Thread context.
545     @param src_da Diagnostics Area to copy from.
546   */
547   void copy_non_errors_from_da(THD *thd, const Diagnostics_area *src_da);
548 
549   /**
550     @return SQL-condition, which corresponds to the error state in
551     Diagnostics Area.
552   */
553   Sql_condition *error_condition() const;
554 
555 private:
556   /**
557     Add a new SQL-condition to the current list and increment the respective
558     counters.
559 
560     @param thd            Thread context.
561     @param sql_condition  SQL-condition to copy values from.
562 
563     @return a pointer to the added SQL-condition.
564   */
565   Sql_condition *push_warning(THD *thd, const Sql_condition *sql_condition);
566 
567   /**
568     Push the given Diagnostics Area on top of the stack.
569     "This" will then become the stacked Diagnostics Area.
570     Conditions present in the new stacked Diagnostics Area
571     will be copied to the new top Diagnostics Area.
572 
573     @note This function will not set THD::m_stmt_da.
574           Use THD::push_diagnostics_area() instead.
575 
576     @param thd  Thread context
577     @param da   Diagnostics Area to be come the top of
578                 the Diagnostics Area stack.
579     @param copy_conditions
580                 Copy the conditions from the new second Diagnostics Area
581                 to the new first Diagnostics Area, as per SQL standard.
582   */
583   void push_diagnostics_area(THD *thd, Diagnostics_area *da,
584                              bool copy_conditions);
585 
586   /**
587     Pop "this" off the Diagnostics Area stack.
588 
589     @note This function will not set THD::m_stmt_da.
590           Use THD::pop_diagnostics_area() instead.
591 
592     @returns The new top of the Diagnostics Area stack.
593   */
594   Diagnostics_area *pop_diagnostics_area();
595 
596   /**
597     Returns the Diagnostics Area below the current diagnostics
598     area on the stack.
599   */
stacked_da()600   const Diagnostics_area *stacked_da() const
601   { return m_stacked_da; }
602 
603 private:
604   /** Pointer to the Diagnostics Area below on the stack. */
605   Diagnostics_area *m_stacked_da;
606 
607   /** A memory root to allocate conditions */
608   MEM_ROOT m_condition_root;
609 
610   /** List of conditions of all severities. */
611   Sql_condition_list m_conditions_list;
612 
613   /** List of conditions present in DA at handler activation. */
614   List<const Sql_condition> m_preexisting_sql_conditions;
615 
616   /** True if status information is sent to the client. */
617   bool m_is_sent;
618 
619   /** Set to make set_error_status after set_{ok,eof}_status possible. */
620   bool m_can_overwrite_status;
621 
622   /** Indicates if push_warning() allows unlimited number of conditions. */
623   bool m_allow_unlimited_conditions;
624 
625   enum_diagnostics_status m_status;
626 
627 private:
628   /*
629     This section contains basic attributes of Sql_condition to store
630     information about error (SQL-condition of error severity) or OK-message.
631     The attributes are inlined here (instead of using Sql_condition) to be able
632     to store the information in case of out-of-memory error.
633   */
634 
635   /**
636     Message buffer. It is used only when DA is in OK or ERROR status.
637     If DA status is ERROR, it's the MESSAGE_TEXT attribute of SQL-condition.
638     If DA status is OK, it's the OK-message to be sent.
639   */
640   char m_message_text[MYSQL_ERRMSG_SIZE];
641 
642   /**
643     SQL RETURNED_SQLSTATE condition item.
644     This member is always NUL terminated.
645   */
646   char m_returned_sqlstate[SQLSTATE_LENGTH+1];
647 
648   /**
649     SQL error number. One of ER_ codes from share/errmsg.txt.
650     Set by set_error_status.
651   */
652   uint m_mysql_errno;
653 
654   /**
655     The number of rows affected by the last statement. This is
656     semantically close to thd->row_count_func, but has a different
657     life cycle. thd->row_count_func stores the value returned by
658     function ROW_COUNT() and is cleared only by statements that
659     update its value, such as INSERT, UPDATE, DELETE and few others.
660     This member is cleared at the beginning of the next statement.
661 
662     We could possibly merge the two, but life cycle of thd->row_count_func
663     can not be changed.
664   */
665   ulonglong m_affected_rows;
666 
667   /**
668     Similarly to the previous member, this is a replacement of
669     thd->first_successful_insert_id_in_prev_stmt, which is used
670     to implement LAST_INSERT_ID().
671   */
672   ulonglong m_last_insert_id;
673 
674   /**
675     Number of conditions of this last statement. May differ from
676     the number of conditions returned by SHOW WARNINGS e.g. in case
677     the statement doesn't clear the conditions, and doesn't generate
678     them.
679   */
680   uint m_last_statement_cond_count;
681 
682   /**
683     The number of conditions of the current statement. m_conditions_list
684     life cycle differs from statement life cycle -- it may span
685     multiple statements. In that case we get
686     m_current_statement_cond_count 0, whereas m_conditions_list is not empty.
687   */
688   uint m_current_statement_cond_count;
689 
690   /** A break down of the number of conditions per severity (level). */
691   uint m_current_statement_cond_count_by_sl[(uint) Sql_condition::SEVERITY_END];
692 
693   /**
694     Row counter, to print in errors and warnings. Not increased in
695     create_sort_index(); may differ from examined_row_count.
696   */
697   ulong m_current_row_for_condition;
698 
699   /** Save @@error_count before pre-clearing the DA. */
700   ulong m_saved_error_count;
701 
702   /** Save @@warning_count before pre-clearing the DA. */
703   ulong m_saved_warn_count;
704 
705   friend class THD;
706 };
707 
708 ///////////////////////////////////////////////////////////////////////////
709 
710 
711 void push_warning(THD *thd, Sql_condition::enum_severity_level severity,
712                   uint code, const char *message_text);
713 
714 /*
715   Note that this MY_ATTRIBUTE check cannot detect number/type mismatch
716   since the format string is not known at compile time.
717   It can however detect if push_warning_printf() is used without any
718   printf arguments. In such cases, use push_warning() instead.
719 */
720 void push_warning_printf(THD *thd, Sql_condition::enum_severity_level severity,
721                          uint code, const char *format, ...)
722                          MY_ATTRIBUTE((format(printf, 4, 5)));
723 
724 /**
725   Generates a warning that a feature is deprecated.
726 
727   Using it as
728     push_deprecated_warn(thd, "BAD", "'GOOD'");
729   Will result in a warning:
730     "The syntax 'BAD' is deprecated and will be removed in a
731      future release. Please use 'GOOD' instead"
732 
733   @param thd         Thread context. If NULL, warning is written
734                      to the error log, otherwise the warning is
735                      sent to the client.
736   @param old_syntax
737   @param new_syntax
738 */
739 void push_deprecated_warn(THD *thd, const char *old_syntax,
740                           const char *new_syntax);
741 
742 /**
743   Generates a warning that a feature is deprecated.
744 
745   Using it as
746     push_deprecated_warn_no_replacement(thd, "old");
747   Will result in a warning:
748     "The syntax 'old' is deprecated and will be removed in a
749      future release.
750 
751   @param thd         Thread context. If NULL, warning is written
752                      to the error log, otherwise the warning is
753                      sent to the client.
754   @param old_syntax
755 */
756 void push_deprecated_warn_no_replacement(THD *thd, const char *old_syntax);
757 
758 bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
759 
760 size_t convert_error_message(char *to, size_t to_length,
761                              const CHARSET_INFO *to_cs,
762                              const char *from, size_t from_length,
763                              const CHARSET_INFO *from_cs, uint *errors);
764 
765 extern const LEX_STRING warning_level_names[];
766 
767 bool is_sqlstate_valid(const LEX_STRING *sqlstate);
768 
769 
770 /**
771   Checks if the specified SQL-state-string defines COMPLETION condition.
772   This function assumes that the given string contains a valid SQL-state.
773 
774   @param s the condition SQLSTATE.
775 
776   @retval true if the given string defines COMPLETION condition.
777   @retval false otherwise.
778 */
is_sqlstate_completion(const char * s)779 inline bool is_sqlstate_completion(const char *s)
780 { return s[0] == '0' && s[1] == '0'; }
781 
782 
783 /**
784   Checks if the specified SQL-state-string defines WARNING condition.
785   This function assumes that the given string contains a valid SQL-state.
786 
787   @param s the condition SQLSTATE.
788 
789   @retval true if the given string defines WARNING condition.
790   @retval false otherwise.
791 */
is_sqlstate_warning(const char * s)792 inline bool is_sqlstate_warning(const char *s)
793 { return s[0] == '0' && s[1] == '1'; }
794 
795 
796 /**
797   Checks if the specified SQL-state-string defines NOT FOUND condition.
798   This function assumes that the given string contains a valid SQL-state.
799 
800   @param s the condition SQLSTATE.
801 
802   @retval true if the given string defines NOT FOUND condition.
803   @retval false otherwise.
804 */
is_sqlstate_not_found(const char * s)805 inline bool is_sqlstate_not_found(const char *s)
806 { return s[0] == '0' && s[1] == '2'; }
807 
808 
809 /**
810   Checks if the specified SQL-state-string defines EXCEPTION condition.
811   This function assumes that the given string contains a valid SQL-state.
812 
813   @param s the condition SQLSTATE.
814 
815   @retval true if the given string defines EXCEPTION condition.
816   @retval false otherwise.
817 */
is_sqlstate_exception(const char * s)818 inline bool is_sqlstate_exception(const char *s)
819 { return s[0] != '0' || s[1] > '2'; }
820 
821 
822 #endif // SQL_ERROR_H
823