1 /* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
2    Copyright (c) 2011, 2018, MariaDB
3 
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; version 2 of the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1335  USA */
17 
18 #ifndef SQL_BASE_INCLUDED
19 #define SQL_BASE_INCLUDED
20 
21 #include "sql_class.h"                          /* enum_column_usage */
22 #include "sql_trigger.h"                        /* trg_event_type */
23 #include "mysqld.h"                             /* key_map */
24 #include "table_cache.h"
25 
26 class Item_ident;
27 struct Name_resolution_context;
28 class Open_table_context;
29 class Open_tables_state;
30 class Prelocking_strategy;
31 struct TABLE_LIST;
32 class THD;
33 struct handlerton;
34 struct TABLE;
35 
36 typedef class st_select_lex SELECT_LEX;
37 
38 typedef struct st_lock_param_type ALTER_PARTITION_PARAM_TYPE;
39 
40 /*
41   This enumeration type is used only by the function find_item_in_list
42   to return the info on how an item has been resolved against a list
43   of possibly aliased items.
44   The item can be resolved:
45    - against an alias name of the list's element (RESOLVED_AGAINST_ALIAS)
46    - against non-aliased field name of the list  (RESOLVED_WITH_NO_ALIAS)
47    - against an aliased field name of the list   (RESOLVED_BEHIND_ALIAS)
48    - ignoring the alias name in cases when SQL requires to ignore aliases
49      (e.g. when the resolved field reference contains a table name or
50      when the resolved item is an expression)   (RESOLVED_IGNORING_ALIAS)
51 */
52 enum enum_resolution_type {
53   NOT_RESOLVED=0,
54   RESOLVED_IGNORING_ALIAS,
55   RESOLVED_BEHIND_ALIAS,
56   RESOLVED_WITH_NO_ALIAS,
57   RESOLVED_AGAINST_ALIAS
58 };
59 
60 /* Argument to flush_tables() of what to flush */
61 enum flush_tables_type {
62   FLUSH_ALL,
63   FLUSH_NON_TRANS_TABLES,
64   FLUSH_SYS_TABLES
65 };
66 
67 enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
68 				  IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE,
69                                   IGNORE_EXCEPT_NON_UNIQUE};
70 
71 /* Flag bits for unique_table() */
72 #define CHECK_DUP_ALLOW_DIFFERENT_ALIAS 1
73 #define CHECK_DUP_FOR_CREATE 2
74 #define CHECK_DUP_SKIP_TEMP_TABLE 4
75 
76 uint get_table_def_key(const TABLE_LIST *table_list, const char **key);
77 TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
78                    uint lock_flags);
79 
80 /* mysql_lock_tables() and open_table() flags bits */
81 #define MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK      0x0001
82 #define MYSQL_OPEN_IGNORE_FLUSH                 0x0002
83 /* MYSQL_OPEN_TEMPORARY_ONLY (0x0004) is not used anymore. */
84 #define MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY      0x0008
85 #define MYSQL_LOCK_LOG_TABLE                    0x0010
86 /**
87   Do not try to acquire a metadata lock on the table: we
88   already have one.
89 */
90 #define MYSQL_OPEN_HAS_MDL_LOCK                 0x0020
91 /**
92   If in locked tables mode, ignore the locked tables and get
93   a new instance of the table.
94 */
95 #define MYSQL_OPEN_GET_NEW_TABLE                0x0040
96 /* 0x0080 used to be MYSQL_OPEN_SKIP_TEMPORARY */
97 /** Fail instead of waiting when conficting metadata lock is discovered. */
98 #define MYSQL_OPEN_FAIL_ON_MDL_CONFLICT         0x0100
99 /** Open tables using MDL_SHARED lock instead of one specified in parser. */
100 #define MYSQL_OPEN_FORCE_SHARED_MDL             0x0200
101 /**
102   Open tables using MDL_SHARED_HIGH_PRIO lock instead of one specified
103   in parser.
104 */
105 #define MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL   0x0400
106 /**
107   When opening or locking the table, use the maximum timeout
108   (LONG_TIMEOUT = 1 year) rather than the user-supplied timeout value.
109 */
110 #define MYSQL_LOCK_IGNORE_TIMEOUT               0x0800
111 /**
112   When acquiring "strong" (SNW, SNRW, X) metadata locks on tables to
113   be open do not acquire global and schema-scope IX locks.
114 */
115 #define MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK         0x1000
116 #define MYSQL_LOCK_NOT_TEMPORARY		0x2000
117 #define MYSQL_LOCK_USE_MALLOC                   0x4000
118 /**
119   Only check THD::killed if waits happen (e.g. wait on MDL, wait on
120   table flush, wait on thr_lock.c locks) while opening and locking table.
121 */
122 #define MYSQL_OPEN_IGNORE_KILLED                0x8000
123 /**
124    Don't try to  auto-repair table
125 */
126 #define MYSQL_OPEN_IGNORE_REPAIR                0x10000
127 
128 /** Please refer to the internals manual. */
129 #define MYSQL_OPEN_REOPEN  (MYSQL_OPEN_IGNORE_FLUSH |\
130                             MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK |\
131                             MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |\
132                             MYSQL_LOCK_IGNORE_TIMEOUT |\
133                             MYSQL_OPEN_GET_NEW_TABLE |\
134                             MYSQL_OPEN_HAS_MDL_LOCK)
135 
136 bool is_locked_view(THD *thd, TABLE_LIST *t);
137 bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx);
138 
139 bool get_key_map_from_key_list(key_map *map, TABLE *table,
140                                List<String> *index_list);
141 TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name);
142 TABLE *find_write_locked_table(TABLE *list, const char *db,
143                                const char *table_name);
144 thr_lock_type read_lock_type_for_table(THD *thd,
145                                        Query_tables_list *prelocking_ctx,
146                                        TABLE_LIST *table_list,
147                                        bool routine_modifies_data);
148 
149 my_bool mysql_rm_tmp_tables(void);
150 void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
151                              const MDL_savepoint &start_of_statement_svp);
152 bool table_already_fk_prelocked(TABLE_LIST *tl, LEX_CSTRING *db,
153                                 LEX_CSTRING *table, thr_lock_type lock_type);
154 TABLE_LIST *find_table_in_list(TABLE_LIST *table,
155                                TABLE_LIST *TABLE_LIST::*link,
156                                const LEX_CSTRING *db_name,
157                                const LEX_CSTRING *table_name);
158 void close_thread_tables(THD *thd);
159 void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *);
160 void switch_defaults_to_nullable_trigger_fields(TABLE *table);
161 bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
162                                           List<Item> &fields,
163                                           List<Item> &values,
164                                           bool ignore_errors,
165                                           enum trg_event_type event);
166 bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
167                                           Field **field,
168                                           List<Item> &values,
169                                           bool ignore_errors,
170                                           enum trg_event_type event);
171 bool insert_fields(THD *thd, Name_resolution_context *context,
172 		   const char *db_name, const char *table_name,
173                    List_iterator<Item> *it, bool any_privileges,
174                    uint *hidden_bit_fields);
175 void make_leaves_list(THD *thd, List<TABLE_LIST> &list, TABLE_LIST *tables,
176                       bool full_table_list, TABLE_LIST *boundary);
177 int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
178 	       List<Item> *sum_func_list, uint wild_num, uint * hidden_bit_fields);
179 bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
180                   List<Item> &item, enum_column_usage column_usage,
181                   List<Item> *sum_func_list, List<Item> *pre_fix,
182                   bool allow_sum_func);
183 void unfix_fields(List<Item> &items);
184 bool fill_record(THD * thd, TABLE *table_arg, List<Item> &fields,
185                  List<Item> &values, bool ignore_errors, bool update);
186 bool fill_record(THD *thd, TABLE *table, Field **field, List<Item> &values,
187                  bool ignore_errors, bool use_value);
188 
189 Field *
190 find_field_in_tables(THD *thd, Item_ident *item,
191                      TABLE_LIST *first_table, TABLE_LIST *last_table,
192                      Item **ref, find_item_error_report_type report_error,
193                      bool check_privileges, bool register_tree_change);
194 Field *
195 find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
196                         const char *name, size_t length,
197                         const char *item_name, const char *db_name,
198                         const char *table_name, Item **ref,
199                         bool check_privileges, bool allow_rowid,
200                         uint *cached_field_index_ptr,
201                         bool register_tree_change, TABLE_LIST **actual_table);
202 Field *
203 find_field_in_table(THD *thd, TABLE *table, const char *name, size_t length,
204                     bool allow_rowid, uint *cached_field_index_ptr);
205 Field *
206 find_field_in_table_sef(TABLE *table, const char *name);
207 Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
208                           find_item_error_report_type report_error,
209                           enum_resolution_type *resolution, uint limit= 0);
210 bool setup_tables(THD *thd, Name_resolution_context *context,
211                   List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
212                   List<TABLE_LIST> &leaves, bool select_insert,
213                   bool full_table_list);
214 bool setup_tables_and_check_access(THD *thd,
215                                    Name_resolution_context *context,
216                                    List<TABLE_LIST> *from_clause,
217                                    TABLE_LIST *tables,
218                                    List<TABLE_LIST> &leaves,
219                                    bool select_insert,
220                                    ulong want_access_first,
221                                    ulong want_access,
222                                    bool full_table_list);
223 bool wait_while_table_is_used(THD *thd, TABLE *table,
224                               enum ha_extra_function function);
225 
226 void drop_open_table(THD *thd, TABLE *table, const LEX_CSTRING *db_name,
227                      const LEX_CSTRING *table_name);
228 void update_non_unique_table_error(TABLE_LIST *update,
229                                    const char *operation,
230                                    TABLE_LIST *duplicate);
231 int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
232 		COND **conds);
233 void wrap_ident(THD *thd, Item **conds);
234 int setup_ftfuncs(SELECT_LEX* select);
235 void cleanup_ftfuncs(SELECT_LEX *select_lex);
236 int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
237 bool lock_table_names(THD *thd, const DDL_options_st &options,
238                       TABLE_LIST *table_list,
239                       TABLE_LIST *table_list_end, ulong lock_wait_timeout,
240                       uint flags);
241 static inline bool
lock_table_names(THD * thd,TABLE_LIST * table_list,TABLE_LIST * table_list_end,ulong lock_wait_timeout,uint flags)242 lock_table_names(THD *thd, TABLE_LIST *table_list,
243                  TABLE_LIST *table_list_end, ulong lock_wait_timeout,
244                  uint flags)
245 {
246   return lock_table_names(thd, thd->lex->create_info, table_list,
247                           table_list_end, lock_wait_timeout, flags);
248 }
249 bool open_tables(THD *thd, const DDL_options_st &options,
250                  TABLE_LIST **tables, uint *counter,
251                  uint flags, Prelocking_strategy *prelocking_strategy);
252 
253 static inline bool
open_tables(THD * thd,TABLE_LIST ** tables,uint * counter,uint flags,Prelocking_strategy * prelocking_strategy)254 open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags,
255             Prelocking_strategy *prelocking_strategy)
256 {
257   return open_tables(thd, thd->lex->create_info, tables, counter, flags,
258                      prelocking_strategy);
259 }
260 /* open_and_lock_tables with optional derived handling */
261 bool open_and_lock_tables(THD *thd, const DDL_options_st &options,
262                           TABLE_LIST *tables,
263                           bool derived, uint flags,
264                           Prelocking_strategy *prelocking_strategy);
265 static inline bool
open_and_lock_tables(THD * thd,TABLE_LIST * tables,bool derived,uint flags,Prelocking_strategy * prelocking_strategy)266 open_and_lock_tables(THD *thd, TABLE_LIST *tables,
267                      bool derived, uint flags,
268                      Prelocking_strategy *prelocking_strategy)
269 {
270   return open_and_lock_tables(thd, thd->lex->create_info,
271                               tables, derived, flags, prelocking_strategy);
272 }
273 /* simple open_and_lock_tables without derived handling for single table */
274 TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
275                                 thr_lock_type lock_type, uint flags,
276                                 Prelocking_strategy *prelocking_strategy);
277 bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags,
278                                     uint dt_phases);
279 bool open_tables_only_view_structure(THD *thd, TABLE_LIST *tables,
280                                      bool can_deadlock);
281 bool open_and_lock_internal_tables(TABLE *table, bool lock);
282 bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
283 int decide_logging_format(THD *thd, TABLE_LIST *tables);
284 void close_thread_table(THD *thd, TABLE **table_ptr);
285 TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
286                          uint check_flag);
287 bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b);
288 
289 class Open_tables_backup;
290 /* Functions to work with system tables. */
291 bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
292                                  Open_tables_backup *backup);
293 void close_system_tables(THD *thd, Open_tables_backup *backup);
294 void close_mysql_tables(THD *thd);
295 TABLE *open_system_table_for_update(THD *thd, TABLE_LIST *one_table);
296 TABLE *open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup);
297 void close_log_table(THD *thd, Open_tables_backup *backup);
298 
299 bool close_cached_tables(THD *thd, TABLE_LIST *tables,
300                          bool wait_for_refresh, ulong timeout);
301 void purge_tables(bool purge_flag);
302 bool flush_tables(THD *thd, flush_tables_type flag);
303 bool close_cached_connection_tables(THD *thd, LEX_CSTRING *connect_string);
304 void close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
305                                ha_extra_function extra,
306                                TABLE *skip_table);
307 OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild);
308 bool tdc_open_view(THD *thd, TABLE_LIST *table_list, uint flags);
309 
310 TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
311                                   const char *table_name,
312                                   int *p_error);
313 void mark_tmp_table_for_reuse(TABLE *table);
314 
315 int dynamic_column_error_message(enum_dyncol_func_result rc);
316 
317 /* open_and_lock_tables with optional derived handling */
318 int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived);
319 
320 extern "C" int simple_raw_key_cmp(void* arg, const void* key1,
321                                   const void* key2);
322 extern "C" int count_distinct_walk(void *elem, element_count count, void *arg);
323 int simple_str_key_cmp(void* arg, uchar* key1, uchar* key2);
324 
325 extern Item **not_found_item;
326 extern Field *not_found_field;
327 extern Field *view_ref_found;
328 
329 /**
330   clean/setup table fields and map.
331 
332   @param table        TABLE structure pointer (which should be setup)
333   @param table_list   TABLE_LIST structure pointer (owner of TABLE)
334   @param tablenr     table number
335 */
336 
337 
setup_table_map(TABLE * table,TABLE_LIST * table_list,uint tablenr)338 inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
339 {
340   table->used_fields= 0;
341   table_list->reset_const_table();
342   table->null_row= 0;
343   table->status= STATUS_NO_RECORD;
344   table->maybe_null= table_list->outer_join;
345   TABLE_LIST *embedding= table_list->embedding;
346   while (!table->maybe_null && embedding)
347   {
348     table->maybe_null= embedding->outer_join;
349     embedding= embedding->embedding;
350   }
351   table->tablenr= tablenr;
352   table->map= (table_map) 1 << tablenr;
353   table->force_index= table_list->force_index;
354   table->force_index_order= table->force_index_group= 0;
355   table->covering_keys= table->s->keys_for_keyread;
356 }
357 
find_table_in_global_list(TABLE_LIST * table,LEX_CSTRING * db_name,LEX_CSTRING * table_name)358 inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table,
359                                              LEX_CSTRING *db_name,
360                                              LEX_CSTRING *table_name)
361 {
362   return find_table_in_list(table, &TABLE_LIST::next_global,
363                             db_name, table_name);
364 }
365 
setup_fields_with_no_wrap(THD * thd,Ref_ptr_array ref_pointer_array,List<Item> & item,enum_column_usage column_usage,List<Item> * sum_func_list,bool allow_sum_func)366 inline bool setup_fields_with_no_wrap(THD *thd, Ref_ptr_array ref_pointer_array,
367                                       List<Item> &item,
368                                       enum_column_usage column_usage,
369                                       List<Item> *sum_func_list,
370                                       bool allow_sum_func)
371 {
372   bool res;
373   SELECT_LEX *first= thd->lex->first_select_lex();
374   DBUG_ASSERT(thd->lex->current_select == first);
375   first->no_wrap_view_item= TRUE;
376   res= setup_fields(thd, ref_pointer_array, item, column_usage,
377                     sum_func_list, NULL,  allow_sum_func);
378   first->no_wrap_view_item= FALSE;
379   return res;
380 }
381 
382 /**
383   An abstract class for a strategy specifying how the prelocking
384   algorithm should extend the prelocking set while processing
385   already existing elements in the set.
386 */
387 
388 class Prelocking_strategy
389 {
390 public:
~Prelocking_strategy()391   virtual ~Prelocking_strategy() { }
392 
reset(THD * thd)393   virtual void reset(THD *thd) { };
394   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
395                               Sroutine_hash_entry *rt, sp_head *sp,
396                               bool *need_prelocking) = 0;
397   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
398                             TABLE_LIST *table_list, bool *need_prelocking) = 0;
399   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
400                            TABLE_LIST *table_list, bool *need_prelocking)= 0;
handle_end(THD * thd)401   virtual bool handle_end(THD *thd) { return 0; };
402 };
403 
404 
405 /**
406   A Strategy for prelocking algorithm suitable for DML statements.
407 
408   Ensures that all tables used by all statement's SF/SP/triggers and
409   required for foreign key checks are prelocked and SF/SPs used are
410   cached.
411 */
412 
413 class DML_prelocking_strategy : public Prelocking_strategy
414 {
415 public:
416   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
417                               Sroutine_hash_entry *rt, sp_head *sp,
418                               bool *need_prelocking);
419   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
420                             TABLE_LIST *table_list, bool *need_prelocking);
421   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
422                            TABLE_LIST *table_list, bool *need_prelocking);
423 };
424 
425 
426 /**
427   A strategy for prelocking algorithm to be used for LOCK TABLES
428   statement.
429 */
430 
431 class Lock_tables_prelocking_strategy : public DML_prelocking_strategy
432 {
433   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
434                             TABLE_LIST *table_list, bool *need_prelocking);
435 };
436 
437 
438 /**
439   Strategy for prelocking algorithm to be used for ALTER TABLE statements.
440 
441   Unlike DML or LOCK TABLES strategy, it doesn't
442   prelock triggers, views or stored routines, since they are not
443   used during ALTER.
444 */
445 
446 class Alter_table_prelocking_strategy : public Prelocking_strategy
447 {
448 public:
449   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
450                               Sroutine_hash_entry *rt, sp_head *sp,
451                               bool *need_prelocking);
452   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
453                             TABLE_LIST *table_list, bool *need_prelocking);
454   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
455                            TABLE_LIST *table_list, bool *need_prelocking);
456 };
457 
458 
459 inline bool
open_tables(THD * thd,const DDL_options_st & options,TABLE_LIST ** tables,uint * counter,uint flags)460 open_tables(THD *thd, const DDL_options_st &options,
461             TABLE_LIST **tables, uint *counter, uint flags)
462 {
463   DML_prelocking_strategy prelocking_strategy;
464 
465   return open_tables(thd, options, tables, counter, flags,
466                      &prelocking_strategy);
467 }
468 inline bool
open_tables(THD * thd,TABLE_LIST ** tables,uint * counter,uint flags)469 open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags)
470 {
471   DML_prelocking_strategy prelocking_strategy;
472 
473   return open_tables(thd, thd->lex->create_info, tables, counter, flags,
474                      &prelocking_strategy);
475 }
476 
open_n_lock_single_table(THD * thd,TABLE_LIST * table_l,thr_lock_type lock_type,uint flags)477 inline TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
478                                        thr_lock_type lock_type, uint flags)
479 {
480   DML_prelocking_strategy prelocking_strategy;
481 
482   return open_n_lock_single_table(thd, table_l, lock_type, flags,
483                                   &prelocking_strategy);
484 }
485 
486 
487 /* open_and_lock_tables with derived handling */
open_and_lock_tables(THD * thd,const DDL_options_st & options,TABLE_LIST * tables,bool derived,uint flags)488 inline bool open_and_lock_tables(THD *thd,
489                                  const DDL_options_st &options,
490                                  TABLE_LIST *tables,
491                                  bool derived, uint flags)
492 {
493   DML_prelocking_strategy prelocking_strategy;
494 
495   return open_and_lock_tables(thd, options, tables, derived, flags,
496                               &prelocking_strategy);
497 }
open_and_lock_tables(THD * thd,TABLE_LIST * tables,bool derived,uint flags)498 inline bool open_and_lock_tables(THD *thd, TABLE_LIST *tables,
499                                   bool derived, uint flags)
500 {
501   DML_prelocking_strategy prelocking_strategy;
502 
503   return open_and_lock_tables(thd, thd->lex->create_info,
504                               tables, derived, flags,
505                               &prelocking_strategy);
506 }
507 
508 
509 bool restart_trans_for_tables(THD *thd, TABLE_LIST *table);
510 
511 bool extend_table_list(THD *thd, TABLE_LIST *tables,
512                        Prelocking_strategy *prelocking_strategy,
513                        bool has_prelocking_list);
514 
515 void promote_select_describe_flag_if_needed(LEX *lex);
516 
517 /**
518   A context of open_tables() function, used to recover
519   from a failed open_table() or open_routine() attempt.
520 */
521 
522 class Open_table_context
523 {
524 public:
525   enum enum_open_table_action
526   {
527     OT_NO_ACTION= 0,
528     OT_BACKOFF_AND_RETRY,
529     OT_REOPEN_TABLES,
530     OT_DISCOVER,
531     OT_REPAIR
532   };
533   Open_table_context(THD *thd, uint flags);
534 
535   bool recover_from_failed_open();
536   bool request_backoff_action(enum_open_table_action action_arg,
537                               TABLE_LIST *table);
538 
can_recover_from_failed_open()539   bool can_recover_from_failed_open() const
540   { return m_action != OT_NO_ACTION; }
541 
542   /**
543     When doing a back-off, we close all tables acquired by this
544     statement.  Return an MDL savepoint taken at the beginning of
545     the statement, so that we can rollback to it before waiting on
546     locks.
547   */
start_of_statement_svp()548   const MDL_savepoint &start_of_statement_svp() const
549   {
550     return m_start_of_statement_svp;
551   }
552 
get_timeout()553   inline ulong get_timeout() const
554   {
555     return m_timeout;
556   }
557 
get_flags()558   uint get_flags() const { return m_flags; }
559 
560   /**
561     Set flag indicating that we have already acquired metadata lock
562     protecting this statement against GRL while opening tables.
563   */
set_has_protection_against_grl(enum_mdl_type mdl_type)564   void set_has_protection_against_grl(enum_mdl_type mdl_type)
565   {
566     m_has_protection_against_grl|= MDL_BIT(mdl_type);
567   }
568 
has_protection_against_grl(enum_mdl_type mdl_type)569   bool has_protection_against_grl(enum_mdl_type mdl_type) const
570   {
571     return (bool) (m_has_protection_against_grl & MDL_BIT(mdl_type));
572   }
573 
574 private:
575   /* THD for which tables are opened. */
576   THD *m_thd;
577   /**
578     For OT_DISCOVER and OT_REPAIR actions, the table list element for
579     the table which definition should be re-discovered or which
580     should be repaired.
581   */
582   TABLE_LIST *m_failed_table;
583   MDL_savepoint m_start_of_statement_svp;
584   /**
585     Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system
586     tables or to the "lock_wait_timeout" system variable for regular tables.
587   */
588   ulong m_timeout;
589   /* open_table() flags. */
590   uint m_flags;
591   /** Back off action. */
592   enum enum_open_table_action m_action;
593   /**
594     Whether we had any locks when this context was created.
595     If we did, they are from the previous statement of a transaction,
596     and we can't safely do back-off (and release them).
597   */
598   bool m_has_locks;
599   /**
600     Indicates that in the process of opening tables we have acquired
601     protection against global read lock.
602   */
603   mdl_bitmap_t m_has_protection_against_grl;
604 };
605 
606 
607 /**
608   Check if a TABLE_LIST instance represents a pre-opened temporary table.
609 */
610 
is_temporary_table(TABLE_LIST * tl)611 inline bool is_temporary_table(TABLE_LIST *tl)
612 {
613   if (tl->view || tl->schema_table)
614     return FALSE;
615 
616   if (!tl->table)
617     return FALSE;
618 
619   /*
620     NOTE: 'table->s' might be NULL for specially constructed TABLE
621     instances. See SHOW TRIGGERS for example.
622   */
623 
624   if (!tl->table->s)
625     return FALSE;
626 
627   return tl->table->s->tmp_table != NO_TMP_TABLE;
628 }
629 
630 
631 /**
632   This internal handler is used to trap ER_NO_SUCH_TABLE.
633 */
634 
635 class No_such_table_error_handler : public Internal_error_handler
636 {
637 public:
No_such_table_error_handler()638   No_such_table_error_handler()
639     : m_handled_errors(0), m_unhandled_errors(0)
640   {}
641 
642   bool handle_condition(THD *thd,
643                         uint sql_errno,
644                         const char* sqlstate,
645                         Sql_condition::enum_warning_level *level,
646                         const char* msg,
647                         Sql_condition ** cond_hdl);
648 
649   /**
650     Returns TRUE if one or more ER_NO_SUCH_TABLE errors have been
651     trapped and no other errors have been seen. FALSE otherwise.
652   */
653   bool safely_trapped_errors();
654 
655 private:
656   int m_handled_errors;
657   int m_unhandled_errors;
658 };
659 
660 
661 #endif /* SQL_BASE_INCLUDED */
662