MySQL  8.0.18
Source Code Documentation
error_handler.h
Go to the documentation of this file.
1 /* Copyright (c) 2015, 2019, 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, 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 ERROR_HANDLER_INCLUDED
24 #define ERROR_HANDLER_INCLUDED
25 
26 #include <string>
27 
28 #include <stddef.h>
29 #include <sys/types.h>
30 
31 #include "mysqld_error.h" // ER_*
32 #include "sql/sql_error.h" // Sql_condition
33 
34 class Create_field;
35 class Field;
36 class String;
37 class THD;
38 struct TABLE_LIST;
39 class handler;
40 
41 /**
42  This class represents the interface for internal error handlers.
43  Internal error handlers are exception handlers used by the server
44  implementation.
45 */
47  protected:
49 
52  }
53 
55 
56  public:
57  /**
58  Handle a sql condition.
59  This method can be implemented by a subclass to achieve any of the
60  following:
61  - mask a warning/error internally, prevent exposing it to the user,
62  - mask a warning/error and throw another one instead.
63  When this method returns true, the sql condition is considered
64  'handled', and will not be propagated to upper layers.
65  It is the responsibility of the code installing an internal handler
66  to then check for trapped conditions, and implement logic to recover
67  from the anticipated conditions trapped during runtime.
68 
69  This mechanism is similar to C++ try/throw/catch:
70  - 'try' correspond to <code>THD::push_internal_handler()</code>,
71  - 'throw' correspond to <code>my_error()</code>,
72  which invokes <code>my_message_sql()</code>,
73  - 'catch' correspond to checking how/if an internal handler was invoked,
74  before removing it from the exception stack with
75  <code>THD::pop_internal_handler()</code>.
76 
77  @param thd the calling thread
78  @param sql_errno the error number for the condition raised.
79  @param sqlstate the SQLSTATE for the condition raised.
80  @param level the severity level for the condition raised.
81  @param msg the error message for the condition raised.
82  @return true if the condition is handled
83  */
84  virtual bool handle_condition(THD *thd, uint sql_errno, const char *sqlstate,
86  const char *msg) = 0;
87 
88  private:
90  friend class THD;
91 };
92 
93 /**
94  Implements the trivial error handler which cancels all error states
95  and prevents an SQLSTATE to be set.
96 */
97 
99  public:
100  virtual bool handle_condition(THD *, uint, const char *,
102  const char *) {
103  /* Ignore error */
104  return true;
105  }
106 };
107 
108 /**
109  Implements the error handler for SET_VAR hint.
110  For Sys_var_hint::update_vars handler accepts first warning or error.
111  Subsequent error are ignored to avoid message duplication.
112  For Sys_var_hint::restore_vars all warnings and errors are ignored
113  since valid value is restored.
114 */
115 
117  public:
118  Set_var_error_handler(bool ignore_warn_arg)
120  ignore_warn(ignore_warn_arg),
122 
123  virtual bool handle_condition(THD *, uint, const char *,
125  const char *) {
126  if (*level == Sql_condition::SL_ERROR) (*level) = Sql_condition::SL_WARNING;
127 
128  if (ignore_subsequent_messages) return true;
130 
131  return ignore_warn;
132  }
133 
135 
136  private:
139 };
140 
141 /**
142  This class is an internal error handler implementation for
143  DROP TABLE statements. The thing is that there may be warnings during
144  execution of these statements, which should not be exposed to the user.
145  This class is intended to silence such warnings.
146 */
147 
149  public:
150  virtual bool handle_condition(THD *thd, uint sql_errno, const char *sqlstate,
152  const char *msg);
153 };
154 
155 /**
156  Internal error handler to process an error from MDL_context::upgrade_lock()
157  and mysql_lock_tables(). Used by implementations of HANDLER READ and
158  LOCK TABLES LOCAL.
159 */
160 
162  : public Internal_error_handler {
163  public:
164  virtual bool handle_condition(THD *, uint sql_errno, const char *,
166  const char *) {
167  if (sql_errno == ER_LOCK_ABORTED || sql_errno == ER_LOCK_DEADLOCK)
168  m_need_reopen = true;
169 
170  return m_need_reopen;
171  }
172 
173  bool need_reopen() const { return m_need_reopen; }
174  void init() { m_need_reopen = false; }
175 
176  private:
178 };
179 
180 /**
181  An Internal_error_handler that suppresses errors regarding views'
182  underlying tables that occur during privilege checking. It hides errors which
183  show view underlying table information.
184  This happens in the cases when
185 
186  - A view's underlying table (e.g. referenced in its SELECT list) does not
187  exist or columns of underlying table are altered. There should not be an
188  error as no attempt was made to access it per se.
189 
190  - Access is denied for some table, column, function or stored procedure
191  such as mentioned above. This error gets raised automatically, since we
192  can't untangle its access checking from that of the view itself.
193 
194  There are currently two mechanisms at work that handle errors for views
195  based on an Internal_error_handler. This one and another one is
196  Show_create_error_handler. The latter handles errors encountered during
197  execution of SHOW CREATE VIEW, while this mechanism using this method is
198  handles SELECT from views. The two methods should not clash.
199 
200 */
203 
204  public:
205  View_error_handler(TABLE_LIST *top_view) : m_top_view(top_view) {}
206  virtual bool handle_condition(THD *thd, uint sql_errno, const char *,
208  const char *message);
209 };
210 
211 /**
212  This internal handler is used to trap ER_NO_SUCH_TABLE.
213 */
214 
216  public:
218 
219  virtual bool handle_condition(THD *, uint sql_errno, const char *,
221  const char *) {
222  if (sql_errno == ER_NO_SUCH_TABLE) {
224  return true;
225  }
226 
228  return false;
229  }
230 
231  /**
232  Returns true if one or more ER_NO_SUCH_TABLE errors have been
233  trapped and no other errors have been seen. false otherwise.
234  */
235  bool safely_trapped_errors() const {
236  /*
237  If m_unhandled_errors != 0, something else, unanticipated, happened,
238  so the error is not trapped but returned to the caller.
239  Multiple ER_NO_SUCH_TABLE can be raised in case of views.
240  */
241  return ((m_handled_errors > 0) && (m_unhandled_errors == 0));
242  }
243 
244  private:
247 };
248 
249 /**
250  This internal handler implements downgrade from SL_ERROR to SL_WARNING
251  for statements which support IGNORE.
252 */
253 
255  public:
256  virtual bool handle_condition(THD *thd, uint sql_errno, const char *sqlstate,
258  const char *msg);
259 };
260 
261 /**
262  This internal handler implements upgrade from SL_WARNING to SL_ERROR
263  for the error codes affected by STRICT mode. Currently STRICT mode does
264  not affect SELECT statements.
265 */
266 
268  public:
272  };
273 
276 
278  : m_set_select_behavior(param) {}
279 
280  virtual bool handle_condition(THD *thd, uint sql_errno, const char *sqlstate,
282  const char *msg);
283 
284  private:
285  /*
286  For SELECT and SET statement, we do not always give error in STRICT mode.
287  For triggers, Strict_error_handler is pushed in the beginning of statement.
288  If a SELECT or SET is executed from the Trigger, it should not always give
289  error. We use this flag to choose when to give error and when warning.
290  */
292 };
293 
294 /**
295  The purpose of this error handler is to print out more user friendly error
296  messages when an error regarding a functional index happens. Since functional
297  indexes are implemented as hidden generated columns with an auto-generated
298  name, we would end up printing errors like "Out of range value for column
299  '912ec803b2ce49e4a541068d495ab570' at row 0". With this error handler, we
300  end up printing something like "Out of range value for functional index
301  'functional_index_2' at row 0" instead.
302 
303  The handler keeps track of the previous error handler that was in use, and
304  calls that error handler to get the correct severity among other things.
305 */
307  public:
308  Functional_index_error_handler(const Field *field, THD *thd);
309 
311  const std::string &functional_index_name,
312  THD *thd);
313 
314  Functional_index_error_handler(const std::string &functional_index_name,
315  THD *thd);
316 
317  bool handle_condition(THD *thd, uint sql_errno, const char *,
319  const char *message) override;
320 
322 
323  void force_error_code(int error_code) { m_force_error_code = error_code; }
324 
325  private:
330 };
331 
332 //////////////////////////////////////////////////////////////////////////
333 
334 /**
335  After retrieving the tablespace name, the tablespace name is validated.
336  If the name is invalid, it is ignored. The function used to validate
337  the name, 'validate_tablespace_name()', emits errors. In the context of
338  retrieving tablespace names, the errors must be ignored. This error handler
339  makes sure this is done.
340 */
341 
343  public:
344  bool handle_condition(THD *, uint sql_errno, const char *,
345  Sql_condition::enum_severity_level *, const char *) {
346  return (sql_errno == ER_WRONG_TABLESPACE_NAME ||
347  sql_errno == ER_TOO_LONG_IDENT);
348  }
349 };
350 
351 /*
352  Disable ER_TOO_LONG_KEY for creation of system tables.
353  TODO: This is a Workaround due to bug#20629014.
354  Remove this internal error handler when the bug is fixed.
355 */
357  public:
358  virtual bool handle_condition(THD *, uint sql_errno, const char *,
360  const char *) {
361  return (sql_errno == ER_TOO_LONG_KEY);
362  }
363 };
364 
365 /**
366  Error handler class to convert ER_LOCK_DEADLOCK error to
367  ER_WARN_I_S_SKIPPED_TABLE/TABLESPACE error.
368 
369  Handler is pushed for opening a table or acquiring a MDL lock on
370  tables for INFORMATION_SCHEMA views (system views) operations.
371 */
373  public:
374  Info_schema_error_handler(THD *thd, const String *schema_name,
375  const String *table_name);
376 
377  Info_schema_error_handler(THD *thd, const String *tablespace_name);
378 
379  virtual bool handle_condition(THD *, uint sql_errno, const char *,
381  const char *);
382 
383  bool is_error_handled() const { return m_error_handled; }
384 
385  private:
387 
388  // Schema name
390 
391  // Table name
393 
394  // Tablespace name
396 
399 
400  // Flag to indicate whether deadlock error is handled by the handler or not.
401  bool m_error_handled = false;
402 };
403 
404 /**
405  An Internal_error_handler that converts errors related to foreign key
406  constraint checks 'ER_NO_REFERENCED_ROW_2' and 'ER_ROW_IS_REFERENCED_2'
407  to ER_NO_REFERENCED_ROW and ER_ROW_IS_REFERENCED based on privilege checks.
408  This prevents from revealing parent and child tables information respectively
409  when the foreign key constraint check fails and user does not have privileges
410  to access those tables.
411 */
415 
416  public:
417  Foreign_key_error_handler(THD *thd, handler *table_handler)
418  : m_table_handler(table_handler), m_thd(thd) {}
419  virtual bool handle_condition(THD *, uint sql_errno, const char *,
421  const char *message);
422 };
423 
424 #endif // ERROR_HANDLER_INCLUDED
Set_var_error_handler(bool ignore_warn_arg)
Definition: error_handler.h:118
TABLE_LIST * m_top_view
Definition: error_handler.h:202
bool ignore_subsequent_messages
Definition: error_handler.h:138
THD * m_thd
Definition: error_handler.h:414
Internal_error_handler * prev_internal_handler() const
Definition: error_handler.h:50
int m_handled_errors
Definition: error_handler.h:245
Mdl_object_type
Definition: error_handler.h:397
virtual ~Internal_error_handler()
Definition: error_handler.h:54
Internal error handler to process an error from MDL_context::upgrade_lock() and mysql_lock_tables().
Definition: error_handler.h:161
virtual bool handle_condition(THD *, uint sql_errno, const char *, Sql_condition::enum_severity_level *, const char *)
Handle a sql condition.
Definition: error_handler.cc:469
Info_schema_error_handler(THD *thd, const String *schema_name, const String *table_name)
Following are implementation of error handler to convert ER_LOCK_DEADLOCK error when executing I_S...
Definition: error_handler.cc:455
const String * m_table_name
Definition: error_handler.h:392
bool m_need_reopen
Definition: error_handler.h:177
Definition: field.h:700
virtual bool handle_condition(THD *, uint, const char *, Sql_condition::enum_severity_level *level, const char *)
Handle a sql condition.
Definition: error_handler.h:123
std::string m_functional_index_name
Definition: error_handler.h:326
Functional_index_error_handler(const Field *field, THD *thd)
Definition: error_handler.cc:230
const String * m_tablespace_name
Definition: error_handler.h:395
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4009
Definition: error_handler.h:356
Foreign_key_error_handler(THD *thd, handler *table_handler)
Definition: error_handler.h:417
Using this class is fraught with peril, and you need to be very careful when doing so...
Definition: sql_string.h:161
enum_set_select_behavior m_set_select_behavior
Definition: error_handler.h:291
THD * m_thd
Definition: error_handler.h:327
bool handle_condition(THD *, uint sql_errno, const char *, Sql_condition::enum_severity_level *, const char *)
Handle a sql condition.
Definition: error_handler.h:344
bool ignore_warn
Definition: error_handler.h:137
bool safely_trapped_errors() const
Returns true if one or more ER_NO_SUCH_TABLE errors have been trapped and no other errors have been s...
Definition: error_handler.h:235
virtual bool handle_condition(THD *thd, uint sql_errno, const char *sqlstate, Sql_condition::enum_severity_level *level, const char *msg)
Implementation of Drop_table_error_handler::handle_condition().
Definition: error_handler.cc:56
Definition: sql_error.h:58
virtual bool handle_condition(THD *, uint sql_errno, const char *, Sql_condition::enum_severity_level *level, const char *message)
Handle a sql condition.
Definition: error_handler.cc:488
This class is an internal error handler implementation for DROP TABLE statements. ...
Definition: error_handler.h:148
~Functional_index_error_handler() override
Definition: error_handler.cc:274
bool is_error_handled() const
Definition: error_handler.h:383
This internal handler implements upgrade from SL_WARNING to SL_ERROR for the error codes affected by ...
Definition: error_handler.h:267
Error handler class to convert ER_LOCK_DEADLOCK error to ER_WARN_I_S_SKIPPED_TABLE/TABLESPACE error...
Definition: error_handler.h:372
virtual bool handle_condition(THD *thd, uint sql_errno, const char *sqlstate, Sql_condition::enum_severity_level *level, const char *msg)=0
Handle a sql condition.
No_such_table_error_handler()
Definition: error_handler.h:217
virtual bool handle_condition(THD *, uint, const char *, Sql_condition::enum_severity_level *, const char *)
Handle a sql condition.
Definition: error_handler.h:100
virtual bool handle_condition(THD *thd, uint sql_errno, const char *sqlstate, Sql_condition::enum_severity_level *level, const char *msg)
Implementation of STRICT mode.
Definition: error_handler.cc:155
bool m_can_deadlock
Definition: error_handler.h:386
unsigned int uint
Definition: uca-dump.cc:29
enum_set_select_behavior
Definition: error_handler.h:269
bool handle_condition(THD *thd, uint sql_errno, const char *, Sql_condition::enum_severity_level *level, const char *message) override
Handle a sql condition.
Definition: error_handler.cc:320
An Internal_error_handler that converts errors related to foreign key constraint checks &#39;ER_NO_REFERE...
Definition: error_handler.h:412
char msg[1024]
Definition: test_sql_9_sessions.cc:281
int m_force_error_code
Definition: error_handler.h:329
bool m_pop_error_handler
Definition: error_handler.h:328
bool need_reopen() const
Definition: error_handler.h:173
int m_unhandled_errors
Definition: error_handler.h:246
virtual bool handle_condition(THD *, uint sql_errno, const char *, Sql_condition::enum_severity_level *, const char *)
Handle a sql condition.
Definition: error_handler.h:219
const String * m_schema_name
Definition: error_handler.h:389
Mdl_object_type m_object_type
Definition: error_handler.h:398
Definition: sql_error.h:58
View_error_handler(TABLE_LIST *top_view)
Definition: error_handler.h:205
This class represents the interface for internal error handlers.
Definition: error_handler.h:46
virtual bool handle_condition(THD *, uint sql_errno, const char *, Sql_condition::enum_severity_level *, const char *)
Handle a sql condition.
Definition: error_handler.h:164
void reset_state()
Definition: error_handler.h:134
Create_field is a description a field/column that may or may not exists in a table.
Definition: create_field.h:50
virtual bool handle_condition(THD *thd, uint sql_errno, const char *, Sql_condition::enum_severity_level *level, const char *message)
Handle a sql condition.
Definition: error_handler.cc:116
virtual bool handle_condition(THD *thd, uint sql_errno, const char *sqlstate, Sql_condition::enum_severity_level *level, const char *msg)
This handler is used for the statements which support IGNORE keyword.
Definition: error_handler.cc:72
void force_error_code(int error_code)
Definition: error_handler.h:323
This internal handler is used to trap ER_NO_SUCH_TABLE.
Definition: error_handler.h:215
An Internal_error_handler that suppresses errors regarding views&#39; underlying tables that occur during...
Definition: error_handler.h:201
This internal handler implements downgrade from SL_ERROR to SL_WARNING for statements which support I...
Definition: error_handler.h:254
#define NULL
Definition: types.h:55
Implements the error handler for SET_VAR hint.
Definition: error_handler.h:116
Internal_error_handler * m_prev_internal_handler
Definition: error_handler.h:89
void init()
Definition: error_handler.h:174
enum_severity_level
Enumeration value describing the severity of the condition.
Definition: sql_error.h:58
Internal_error_handler()
Definition: error_handler.h:48
Definition: table.h:2468
virtual bool handle_condition(THD *, uint sql_errno, const char *, Sql_condition::enum_severity_level *, const char *)
Handle a sql condition.
Definition: error_handler.h:358
After retrieving the tablespace name, the tablespace name is validated.
Definition: error_handler.h:342
Strict_error_handler()
Definition: error_handler.h:274
Implements the trivial error handler which cancels all error states and prevents an SQLSTATE to be se...
Definition: error_handler.h:98
#define false
Definition: config_static.h:43
bool m_error_handled
Definition: error_handler.h:401
The purpose of this error handler is to print out more user friendly error messages when an error reg...
Definition: error_handler.h:306
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:778
Strict_error_handler(enum_set_select_behavior param)
Definition: error_handler.h:277
handler * m_table_handler
Definition: error_handler.h:413
const char * table_name
Definition: rules_table_service.cc:55