1 /* Copyright (c) 2010, 2018, 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_BASE_INCLUDED
17 #define SQL_BASE_INCLUDED
18 
19 #include "unireg.h"                    // REQUIRED: for other includes
20 #include "sql_trigger.h"                        /* trg_event_type */
21 #include "sql_class.h"                          /* enum_mark_columns */
22 #include "mysqld.h"                             /* key_map */
23 
24 class Item_ident;
25 struct Name_resolution_context;
26 class Open_table_context;
27 class Open_tables_state;
28 class Prelocking_strategy;
29 struct TABLE_LIST;
30 class THD;
31 struct handlerton;
32 struct TABLE;
33 
34 typedef class st_select_lex SELECT_LEX;
35 
36 typedef struct st_lock_param_type ALTER_PARTITION_PARAM_TYPE;
37 
38 /*
39   This enumeration type is used only by the function find_item_in_list
40   to return the info on how an item has been resolved against a list
41   of possibly aliased items.
42   The item can be resolved:
43    - against an alias name of the list's element (RESOLVED_AGAINST_ALIAS)
44    - against non-aliased field name of the list  (RESOLVED_WITH_NO_ALIAS)
45    - against an aliased field name of the list   (RESOLVED_BEHIND_ALIAS)
46    - ignoring the alias name in cases when SQL requires to ignore aliases
47      (e.g. when the resolved field reference contains a table name or
48      when the resolved item is an expression)   (RESOLVED_IGNORING_ALIAS)
49 */
50 enum enum_resolution_type {
51   NOT_RESOLVED=0,
52   RESOLVED_IGNORING_ALIAS,
53   RESOLVED_BEHIND_ALIAS,
54   RESOLVED_WITH_NO_ALIAS,
55   RESOLVED_AGAINST_ALIAS
56 };
57 
58 enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
59 				  IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE,
60                                   IGNORE_EXCEPT_NON_UNIQUE};
61 
62 enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
63                                  TDC_RT_REMOVE_UNUSED};
64 
65 /* bits for last argument to remove_table_from_cache() */
66 #define RTFC_NO_FLAG                0x0000
67 #define RTFC_OWNED_BY_THD_FLAG      0x0001
68 #define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002
69 #define RTFC_CHECK_KILLED_FLAG      0x0004
70 
71 bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
72 extern mysql_mutex_t LOCK_open;
73 bool table_cache_init(void);
74 void table_cache_free(void);
75 bool table_def_init(void);
76 void table_def_free(void);
77 void table_def_start_shutdown(void);
78 void assign_new_table_id(TABLE_SHARE *share);
79 uint cached_open_tables(void);
80 uint cached_table_definitions(void);
81 uint create_table_def_key(THD *thd, char *key,
82                           const TABLE_LIST *table_list,
83                           bool tmp_table);
84 
85 /**
86   Create a table cache key for non-temporary table.
87 
88   @param key         Buffer for key (must be at least NAME_LEN*2+2 bytes).
89   @param db          Database name.
90   @param table_name  Table name.
91 
92   @return Length of key.
93 
94   @sa create_table_def_key(thd, char *, table_list, bool)
95 */
96 
97 inline uint
create_table_def_key(char * key,const char * db,const char * table_name)98 create_table_def_key(char *key, const char *db, const char *table_name)
99 {
100   /*
101     In theory caller should ensure that both db and table_name are
102     not longer than NAME_LEN bytes. In practice we play safe to avoid
103     buffer overruns.
104   */
105   return (uint)(strmake(strmake(key, db, NAME_LEN) + 1, table_name,
106                         NAME_LEN) - key + 1);
107 }
108 
109 TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
110                              uint key_length, uint db_flags, int *error,
111                              my_hash_value_type hash_value);
112 void release_table_share(TABLE_SHARE *share);
113 TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name);
114 
115 TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
116                    uint lock_flags);
117 
118 /* mysql_lock_tables() and open_table() flags bits */
119 #define MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK      0x0001
120 #define MYSQL_OPEN_IGNORE_FLUSH                 0x0002
121 #define MYSQL_OPEN_TEMPORARY_ONLY               0x0004
122 #define MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY      0x0008
123 #define MYSQL_LOCK_LOG_TABLE                    0x0010
124 /**
125   Do not try to acquire a metadata lock on the table: we
126   already have one.
127 */
128 #define MYSQL_OPEN_HAS_MDL_LOCK                 0x0020
129 /**
130   If in locked tables mode, ignore the locked tables and get
131   a new instance of the table.
132 */
133 #define MYSQL_OPEN_GET_NEW_TABLE                0x0040
134 /** Don't look up the table in the list of temporary tables. */
135 #define MYSQL_OPEN_SKIP_TEMPORARY               0x0080
136 /** Fail instead of waiting when conficting metadata lock is discovered. */
137 #define MYSQL_OPEN_FAIL_ON_MDL_CONFLICT         0x0100
138 /** Open tables using MDL_SHARED lock instead of one specified in parser. */
139 #define MYSQL_OPEN_FORCE_SHARED_MDL             0x0200
140 /**
141   Open tables using MDL_SHARED_HIGH_PRIO lock instead of one specified
142   in parser.
143 */
144 #define MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL   0x0400
145 /**
146   When opening or locking the table, use the maximum timeout
147   (LONG_TIMEOUT = 1 year) rather than the user-supplied timeout value.
148 */
149 #define MYSQL_LOCK_IGNORE_TIMEOUT               0x0800
150 /**
151   When acquiring "strong" (SNW, SNRW, X) metadata locks on tables to
152   be open do not acquire global and schema-scope IX locks.
153 */
154 #define MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK         0x1000
155 
156 /** Please refer to the internals manual. */
157 #define MYSQL_OPEN_REOPEN  (MYSQL_OPEN_IGNORE_FLUSH |\
158                             MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK |\
159                             MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |\
160                             MYSQL_LOCK_IGNORE_TIMEOUT |\
161                             MYSQL_OPEN_GET_NEW_TABLE |\
162                             MYSQL_OPEN_SKIP_TEMPORARY |\
163                             MYSQL_OPEN_HAS_MDL_LOCK)
164 
165 bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
166                 Open_table_context *ot_ctx);
167 bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias,
168                   uint db_stat, uint prgflag,
169                   uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc,
170                   MEM_ROOT *mem_root);
171 
172 bool get_key_map_from_key_list(key_map *map, TABLE *table,
173                                List<String> *index_list);
174 TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
175 			   const char *table_name,
176                            bool add_to_temporary_tables_list);
177 TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name);
178 TABLE *find_write_locked_table(TABLE *list, const char *db,
179                                const char *table_name);
180 thr_lock_type read_lock_type_for_table(THD *thd,
181                                        Query_tables_list *prelocking_ctx,
182                                        TABLE_LIST *table_list);
183 
184 my_bool mysql_rm_tmp_tables(void);
185 bool rm_temporary_table(handlerton *base, const char *path);
186 void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
187                              const MDL_savepoint &start_of_statement_svp);
188 TABLE_LIST *find_table_in_list(TABLE_LIST *table,
189                                TABLE_LIST *TABLE_LIST::*link,
190                                const char *db_name,
191                                const char *table_name);
192 TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name);
193 TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
194 TABLE *find_temporary_table(THD *thd, const char *table_key,
195                             uint table_key_length);
196 void close_thread_tables(THD *thd);
197 bool fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
198                                           List<Item> &values,
199                                           bool ignore_errors,
200                                           Table_triggers_list *triggers,
201                                           enum trg_event_type event);
202 bool fill_record_n_invoke_before_triggers(THD *thd, Field **field,
203                                           List<Item> &values,
204                                           bool ignore_errors,
205                                           Table_triggers_list *triggers,
206                                           enum trg_event_type event);
207 bool insert_fields(THD *thd, Name_resolution_context *context,
208 		   const char *db_name, const char *table_name,
209                    List_iterator<Item> *it, bool any_privileges);
210 int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
211 	       List<Item> *sum_func_list, uint wild_num);
212 bool setup_fields(THD *thd, Item** ref_pointer_array,
213                   List<Item> &item, enum_mark_columns mark_used_columns,
214                   List<Item> *sum_func_list, bool allow_sum_func);
215 bool fill_record(THD *thd, Field **field, List<Item> &values,
216                  bool ignore_errors);
217 
218 Field *
219 find_field_in_tables(THD *thd, Item_ident *item,
220                      TABLE_LIST *first_table, TABLE_LIST *last_table,
221                      Item **ref, find_item_error_report_type report_error,
222                      bool check_privileges, bool register_tree_change);
223 Field *
224 find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
225                         const char *name, uint length,
226                         const char *item_name, const char *db_name,
227                         const char *table_name, Item **ref,
228                         bool check_privileges, bool allow_rowid,
229                         uint *cached_field_index_ptr,
230                         bool register_tree_change, TABLE_LIST **actual_table);
231 Field *
232 find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
233                     bool allow_rowid, uint *cached_field_index_ptr);
234 Field *
235 find_field_in_table_sef(TABLE *table, const char *name);
236 Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
237                           find_item_error_report_type report_error,
238                           enum_resolution_type *resolution);
239 bool setup_tables(THD *thd, Name_resolution_context *context,
240                   List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
241                   TABLE_LIST **leaves, bool select_insert);
242 bool setup_tables_and_check_access(THD *thd,
243                                    Name_resolution_context *context,
244                                    List<TABLE_LIST> *from_clause,
245                                    TABLE_LIST *tables,
246                                    TABLE_LIST **leaves,
247                                    bool select_insert,
248                                    ulong want_access_first,
249                                    ulong want_access);
250 bool wait_while_table_is_used(THD *thd, TABLE *table,
251                               enum ha_extra_function function);
252 
253 void drop_open_table(THD *thd, TABLE *table, const char *db_name,
254                      const char *table_name);
255 void update_non_unique_table_error(TABLE_LIST *update,
256                                    const char *operation,
257                                    TABLE_LIST *duplicate);
258 int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
259 		COND **conds);
260 int setup_ftfuncs(SELECT_LEX* select);
261 int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
262 bool lock_table_names(THD *thd, TABLE_LIST *table_list,
263                       TABLE_LIST *table_list_end, ulong lock_wait_timeout,
264                       uint flags);
265 bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags,
266                  Prelocking_strategy *prelocking_strategy);
267 /* open_and_lock_tables with optional derived handling */
268 bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
269                           bool derived, uint flags,
270                           Prelocking_strategy *prelocking_strategy);
271 /* simple open_and_lock_tables without derived handling for single table */
272 TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
273                                 thr_lock_type lock_type, uint flags,
274                                 Prelocking_strategy *prelocking_strategy);
275 bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
276 bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
277 int decide_logging_format(THD *thd, TABLE_LIST *tables);
278 void free_io_cache(TABLE *entry);
279 void intern_close_table(TABLE *entry);
280 bool close_thread_table(THD *thd, TABLE **table_ptr);
281 bool close_temporary_tables(THD *thd);
282 TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
283                          bool check_alias);
284 int drop_temporary_table(THD *thd, TABLE_LIST *table_list, bool *is_trans);
285 void close_temporary_table(THD *thd, TABLE *table, bool free_share,
286                            bool delete_table);
287 void close_temporary(TABLE *table, bool free_share, bool delete_table);
288 bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
289 			    const char *table_name);
290 bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
291 
292 /* Functions to work with system tables. */
293 bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
294                                  Open_tables_backup *backup);
295 void close_system_tables(THD *thd, Open_tables_backup *backup);
296 void close_mysql_tables(THD *thd);
297 TABLE *open_system_table_for_update(THD *thd, TABLE_LIST *one_table);
298 TABLE *open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup);
299 void close_log_table(THD *thd, Open_tables_backup *backup);
300 
301 TABLE *open_performance_schema_table(THD *thd, TABLE_LIST *one_table,
302                                      Open_tables_state *backup);
303 void close_performance_schema_table(THD *thd, Open_tables_state *backup);
304 
305 bool close_cached_tables(THD *thd, TABLE_LIST *tables,
306                          bool wait_for_refresh, ulong timeout);
307 bool close_cached_connection_tables(THD *thd, LEX_STRING *connect_string);
308 void close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
309                                bool remove_from_locked_tables,
310                                TABLE *skip_table);
311 OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild);
312 void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
313                       const char *db, const char *table_name,
314                       bool has_lock);
315 bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias,
316                    char *cache_key, uint cache_key_length,
317                    MEM_ROOT *mem_root, uint flags);
318 void tdc_flush_unused_tables();
319 TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
320                                   const char *table_name,
321                                   bool no_error);
322 void mark_tmp_table_for_reuse(TABLE *table);
323 bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
324 
325 extern TABLE *unused_tables;
326 extern Item **not_found_item;
327 extern Field *not_found_field;
328 extern Field *view_ref_found;
329 extern HASH table_def_cache;
330 
331 /**
332   clean/setup table fields and map.
333 
334   @param table        TABLE structure pointer (which should be setup)
335   @param table_list   TABLE_LIST structure pointer (owner of TABLE)
336   @param tablenr     table number
337 */
338 
339 
setup_table_map(TABLE * table,TABLE_LIST * table_list,uint tablenr)340 inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
341 {
342   table->used_fields= 0;
343   table->const_table= 0;
344   table->null_row= 0;
345   table->status= STATUS_NO_RECORD;
346   table->maybe_null= table_list->outer_join;
347   TABLE_LIST *embedding= table_list->embedding;
348   while (!table->maybe_null && embedding)
349   {
350     table->maybe_null= embedding->outer_join;
351     embedding= embedding->embedding;
352   }
353   table->tablenr= tablenr;
354   table->map= (table_map) 1 << tablenr;
355   table->force_index= table_list->force_index;
356   table->force_index_order= table->force_index_group= 0;
357   table->covering_keys= table->s->keys_for_keyread;
358   table->merge_keys.clear_all();
359 }
360 
find_table_in_global_list(TABLE_LIST * table,const char * db_name,const char * table_name)361 inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table,
362                                              const char *db_name,
363                                              const char *table_name)
364 {
365   return find_table_in_list(table, &TABLE_LIST::next_global,
366                             db_name, table_name);
367 }
368 
find_table_in_local_list(TABLE_LIST * table,const char * db_name,const char * table_name)369 inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table,
370                                             const char *db_name,
371                                             const char *table_name)
372 {
373   return find_table_in_list(table, &TABLE_LIST::next_local,
374                             db_name, table_name);
375 }
376 
377 
setup_fields_with_no_wrap(THD * thd,Item ** ref_pointer_array,List<Item> & item,enum_mark_columns mark_used_columns,List<Item> * sum_func_list,bool allow_sum_func)378 inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array,
379                                       List<Item> &item,
380                                       enum_mark_columns mark_used_columns,
381                                       List<Item> *sum_func_list,
382                                       bool allow_sum_func)
383 {
384   bool res;
385   thd->lex->select_lex.no_wrap_view_item= TRUE;
386   res= setup_fields(thd, ref_pointer_array, item, mark_used_columns,
387                     sum_func_list, allow_sum_func);
388   thd->lex->select_lex.no_wrap_view_item= FALSE;
389   return res;
390 }
391 
392 /**
393   An abstract class for a strategy specifying how the prelocking
394   algorithm should extend the prelocking set while processing
395   already existing elements in the set.
396 */
397 
398 class Prelocking_strategy
399 {
400 public:
~Prelocking_strategy()401   virtual ~Prelocking_strategy() { }
402 
403   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
404                               Sroutine_hash_entry *rt, sp_head *sp,
405                               bool *need_prelocking) = 0;
406   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
407                             TABLE_LIST *table_list, bool *need_prelocking) = 0;
408   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
409                            TABLE_LIST *table_list, bool *need_prelocking)= 0;
410 };
411 
412 
413 /**
414   A Strategy for prelocking algorithm suitable for DML statements.
415 
416   Ensures that all tables used by all statement's SF/SP/triggers and
417   required for foreign key checks are prelocked and SF/SPs used are
418   cached.
419 */
420 
421 class DML_prelocking_strategy : public Prelocking_strategy
422 {
423 public:
424   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
425                               Sroutine_hash_entry *rt, sp_head *sp,
426                               bool *need_prelocking);
427   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
428                             TABLE_LIST *table_list, bool *need_prelocking);
429   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
430                            TABLE_LIST *table_list, bool *need_prelocking);
431 };
432 
433 
434 /**
435   A strategy for prelocking algorithm to be used for LOCK TABLES
436   statement.
437 */
438 
439 class Lock_tables_prelocking_strategy : public DML_prelocking_strategy
440 {
441   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
442                             TABLE_LIST *table_list, bool *need_prelocking);
443 };
444 
445 
446 /**
447   Strategy for prelocking algorithm to be used for ALTER TABLE statements.
448 
449   Unlike DML or LOCK TABLES strategy, it doesn't
450   prelock triggers, views or stored routines, since they are not
451   used during ALTER.
452 */
453 
454 class Alter_table_prelocking_strategy : public Prelocking_strategy
455 {
456 public:
457 
Alter_table_prelocking_strategy(Alter_info * alter_info)458   Alter_table_prelocking_strategy(Alter_info *alter_info)
459     : m_alter_info(alter_info)
460   {}
461 
462   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
463                               Sroutine_hash_entry *rt, sp_head *sp,
464                               bool *need_prelocking);
465   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
466                             TABLE_LIST *table_list, bool *need_prelocking);
467   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
468                            TABLE_LIST *table_list, bool *need_prelocking);
469 
470 private:
471   Alter_info *m_alter_info;
472 };
473 
474 
475 inline bool
open_tables(THD * thd,TABLE_LIST ** tables,uint * counter,uint flags)476 open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags)
477 {
478   DML_prelocking_strategy prelocking_strategy;
479 
480   return open_tables(thd, tables, counter, flags, &prelocking_strategy);
481 }
482 
483 
open_n_lock_single_table(THD * thd,TABLE_LIST * table_l,thr_lock_type lock_type,uint flags)484 inline TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
485                                        thr_lock_type lock_type, uint flags)
486 {
487   DML_prelocking_strategy prelocking_strategy;
488 
489   return open_n_lock_single_table(thd, table_l, lock_type, flags,
490                                   &prelocking_strategy);
491 }
492 
493 
494 /* open_and_lock_tables with derived handling */
open_and_lock_tables(THD * thd,TABLE_LIST * tables,bool derived,uint flags)495 inline bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
496                                  bool derived, uint flags)
497 {
498   DML_prelocking_strategy prelocking_strategy;
499 
500   return open_and_lock_tables(thd, tables, derived, flags,
501                               &prelocking_strategy);
502 }
503 
504 
505 /**
506   A context of open_tables() function, used to recover
507   from a failed open_table() or open_routine() attempt.
508 */
509 
510 class Open_table_context
511 {
512 public:
513   enum enum_open_table_action
514   {
515     OT_NO_ACTION= 0,
516     OT_BACKOFF_AND_RETRY,
517     OT_REOPEN_TABLES,
518     OT_DISCOVER,
519     OT_REPAIR
520   };
521   Open_table_context(THD *thd, uint flags);
522 
523   bool recover_from_failed_open();
524   bool request_backoff_action(enum_open_table_action action_arg,
525                               TABLE_LIST *table);
526 
can_recover_from_failed_open()527   bool can_recover_from_failed_open() const
528   { return m_action != OT_NO_ACTION; }
529 
530   /**
531     When doing a back-off, we close all tables acquired by this
532     statement.  Return an MDL savepoint taken at the beginning of
533     the statement, so that we can rollback to it before waiting on
534     locks.
535   */
start_of_statement_svp()536   const MDL_savepoint &start_of_statement_svp() const
537   {
538     return m_start_of_statement_svp;
539   }
540 
get_timeout()541   inline ulong get_timeout() const
542   {
543     return m_timeout;
544   }
545 
get_flags()546   uint get_flags() const { return m_flags; }
547 
548   /**
549     Set flag indicating that we have already acquired metadata lock
550     protecting this statement against GRL while opening tables.
551   */
set_has_protection_against_grl()552   void set_has_protection_against_grl()
553   {
554     m_has_protection_against_grl= TRUE;
555   }
556 
has_protection_against_grl()557   bool has_protection_against_grl() const
558   {
559     return m_has_protection_against_grl;
560   }
561 
562 private:
563   /* THD for which tables are opened. */
564   THD *m_thd;
565   /**
566     For OT_DISCOVER and OT_REPAIR actions, the table list element for
567     the table which definition should be re-discovered or which
568     should be repaired.
569   */
570   TABLE_LIST *m_failed_table;
571   MDL_savepoint m_start_of_statement_svp;
572   /**
573     Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system
574     tables or to the "lock_wait_timeout" system variable for regular tables.
575   */
576   ulong m_timeout;
577   /* open_table() flags. */
578   uint m_flags;
579   /** Back off action. */
580   enum enum_open_table_action m_action;
581   /**
582     Whether we had any locks when this context was created.
583     If we did, they are from the previous statement of a transaction,
584     and we can't safely do back-off (and release them).
585   */
586   bool m_has_locks;
587   /**
588     Indicates that in the process of opening tables we have acquired
589     protection against global read lock.
590   */
591   bool m_has_protection_against_grl;
592 };
593 
594 
595 /**
596   This internal handler is used to trap ER_NO_SUCH_TABLE.
597 */
598 
599 class No_such_table_error_handler : public Internal_error_handler
600 {
601 public:
No_such_table_error_handler()602   No_such_table_error_handler()
603     : m_handled_errors(0), m_unhandled_errors(0)
604   {}
605 
606   bool handle_condition(THD *thd,
607                         uint sql_errno,
608                         const char* sqlstate,
609                         MYSQL_ERROR::enum_warning_level level,
610                         const char* msg,
611                         MYSQL_ERROR ** cond_hdl);
612 
613   /**
614     Returns TRUE if one or more ER_NO_SUCH_TABLE errors have been
615     trapped and no other errors have been seen. FALSE otherwise.
616   */
617   bool safely_trapped_errors();
618 
619 private:
620   int m_handled_errors;
621   int m_unhandled_errors;
622 };
623 
624 
625 #endif /* SQL_BASE_INCLUDED */
626