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 enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
61 				  IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE,
62                                   IGNORE_EXCEPT_NON_UNIQUE};
63 
64 /* Flag bits for unique_table() */
65 #define CHECK_DUP_ALLOW_DIFFERENT_ALIAS 1
66 #define CHECK_DUP_FOR_CREATE 2
67 #define CHECK_DUP_SKIP_TEMP_TABLE 4
68 
69 uint get_table_def_key(const TABLE_LIST *table_list, const char **key);
70 TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
71                    uint lock_flags);
72 
73 /* mysql_lock_tables() and open_table() flags bits */
74 #define MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK      0x0001
75 #define MYSQL_OPEN_IGNORE_FLUSH                 0x0002
76 /* MYSQL_OPEN_TEMPORARY_ONLY (0x0004) is not used anymore. */
77 #define MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY      0x0008
78 #define MYSQL_LOCK_LOG_TABLE                    0x0010
79 /**
80   Do not try to acquire a metadata lock on the table: we
81   already have one.
82 */
83 #define MYSQL_OPEN_HAS_MDL_LOCK                 0x0020
84 /**
85   If in locked tables mode, ignore the locked tables and get
86   a new instance of the table.
87 */
88 #define MYSQL_OPEN_GET_NEW_TABLE                0x0040
89 /* 0x0080 used to be MYSQL_OPEN_SKIP_TEMPORARY */
90 /** Fail instead of waiting when conficting metadata lock is discovered. */
91 #define MYSQL_OPEN_FAIL_ON_MDL_CONFLICT         0x0100
92 /** Open tables using MDL_SHARED lock instead of one specified in parser. */
93 #define MYSQL_OPEN_FORCE_SHARED_MDL             0x0200
94 /**
95   Open tables using MDL_SHARED_HIGH_PRIO lock instead of one specified
96   in parser.
97 */
98 #define MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL   0x0400
99 /**
100   When opening or locking the table, use the maximum timeout
101   (LONG_TIMEOUT = 1 year) rather than the user-supplied timeout value.
102 */
103 #define MYSQL_LOCK_IGNORE_TIMEOUT               0x0800
104 /**
105   When acquiring "strong" (SNW, SNRW, X) metadata locks on tables to
106   be open do not acquire global and schema-scope IX locks.
107 */
108 #define MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK         0x1000
109 #define MYSQL_LOCK_NOT_TEMPORARY		0x2000
110 #define MYSQL_LOCK_USE_MALLOC                   0x4000
111 /**
112   Only check THD::killed if waits happen (e.g. wait on MDL, wait on
113   table flush, wait on thr_lock.c locks) while opening and locking table.
114 */
115 #define MYSQL_OPEN_IGNORE_KILLED                0x8000
116 /**
117    Don't try to  auto-repair table
118 */
119 #define MYSQL_OPEN_IGNORE_REPAIR                0x10000
120 
121 /** Please refer to the internals manual. */
122 #define MYSQL_OPEN_REOPEN  (MYSQL_OPEN_IGNORE_FLUSH |\
123                             MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK |\
124                             MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |\
125                             MYSQL_LOCK_IGNORE_TIMEOUT |\
126                             MYSQL_OPEN_GET_NEW_TABLE |\
127                             MYSQL_OPEN_HAS_MDL_LOCK)
128 
129 bool is_locked_view(THD *thd, TABLE_LIST *t);
130 bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx);
131 
132 bool get_key_map_from_key_list(key_map *map, TABLE *table,
133                                List<String> *index_list);
134 TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name);
135 TABLE *find_write_locked_table(TABLE *list, const char *db,
136                                const char *table_name);
137 thr_lock_type read_lock_type_for_table(THD *thd,
138                                        Query_tables_list *prelocking_ctx,
139                                        TABLE_LIST *table_list,
140                                        bool routine_modifies_data);
141 
142 my_bool mysql_rm_tmp_tables(void);
143 void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
144                              const MDL_savepoint &start_of_statement_svp);
145 bool table_already_fk_prelocked(TABLE_LIST *tl, LEX_CSTRING *db,
146                                 LEX_CSTRING *table, thr_lock_type lock_type);
147 TABLE_LIST *find_table_in_list(TABLE_LIST *table,
148                                TABLE_LIST *TABLE_LIST::*link,
149                                const LEX_CSTRING *db_name,
150                                const LEX_CSTRING *table_name);
151 void close_thread_tables(THD *thd);
152 void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *);
153 void switch_defaults_to_nullable_trigger_fields(TABLE *table);
154 bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
155                                           List<Item> &fields,
156                                           List<Item> &values,
157                                           bool ignore_errors,
158                                           enum trg_event_type event);
159 bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
160                                           Field **field,
161                                           List<Item> &values,
162                                           bool ignore_errors,
163                                           enum trg_event_type event);
164 bool insert_fields(THD *thd, Name_resolution_context *context,
165 		   const char *db_name, const char *table_name,
166                    List_iterator<Item> *it, bool any_privileges,
167                    uint *hidden_bit_fields);
168 void make_leaves_list(THD *thd, List<TABLE_LIST> &list, TABLE_LIST *tables,
169                       bool full_table_list, TABLE_LIST *boundary);
170 int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
171 	       List<Item> *sum_func_list, uint wild_num, uint * hidden_bit_fields);
172 bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
173                   List<Item> &item, enum_column_usage column_usage,
174                   List<Item> *sum_func_list, List<Item> *pre_fix,
175                   bool allow_sum_func);
176 void unfix_fields(List<Item> &items);
177 bool fill_record(THD * thd, TABLE *table_arg, List<Item> &fields,
178                  List<Item> &values, bool ignore_errors, bool update);
179 bool fill_record(THD *thd, TABLE *table, Field **field, List<Item> &values,
180                  bool ignore_errors, bool use_value);
181 
182 Field *
183 find_field_in_tables(THD *thd, Item_ident *item,
184                      TABLE_LIST *first_table, TABLE_LIST *last_table,
185                      Item **ref, find_item_error_report_type report_error,
186                      bool check_privileges, bool register_tree_change);
187 Field *
188 find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
189                         const char *name, size_t length,
190                         const char *item_name, const char *db_name,
191                         const char *table_name, Item **ref,
192                         bool check_privileges, bool allow_rowid,
193                         uint *cached_field_index_ptr,
194                         bool register_tree_change, TABLE_LIST **actual_table);
195 Field *
196 find_field_in_table(THD *thd, TABLE *table, const char *name, size_t length,
197                     bool allow_rowid, uint *cached_field_index_ptr);
198 Field *
199 find_field_in_table_sef(TABLE *table, const char *name);
200 Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
201                           find_item_error_report_type report_error,
202                           enum_resolution_type *resolution, uint limit= 0);
203 bool setup_tables(THD *thd, Name_resolution_context *context,
204                   List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
205                   List<TABLE_LIST> &leaves, bool select_insert,
206                   bool full_table_list);
207 bool setup_tables_and_check_access(THD *thd,
208                                    Name_resolution_context *context,
209                                    List<TABLE_LIST> *from_clause,
210                                    TABLE_LIST *tables,
211                                    List<TABLE_LIST> &leaves,
212                                    bool select_insert,
213                                    ulong want_access_first,
214                                    ulong want_access,
215                                    bool full_table_list);
216 bool wait_while_table_is_used(THD *thd, TABLE *table,
217                               enum ha_extra_function function);
218 
219 void drop_open_table(THD *thd, TABLE *table, const LEX_CSTRING *db_name,
220                      const LEX_CSTRING *table_name);
221 void update_non_unique_table_error(TABLE_LIST *update,
222                                    const char *operation,
223                                    TABLE_LIST *duplicate);
224 int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
225 		COND **conds);
226 void wrap_ident(THD *thd, Item **conds);
227 int setup_ftfuncs(SELECT_LEX* select);
228 void cleanup_ftfuncs(SELECT_LEX *select_lex);
229 int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
230 bool lock_table_names(THD *thd, const DDL_options_st &options,
231                       TABLE_LIST *table_list,
232                       TABLE_LIST *table_list_end, ulong lock_wait_timeout,
233                       uint flags);
234 static inline bool
lock_table_names(THD * thd,TABLE_LIST * table_list,TABLE_LIST * table_list_end,ulong lock_wait_timeout,uint flags)235 lock_table_names(THD *thd, TABLE_LIST *table_list,
236                  TABLE_LIST *table_list_end, ulong lock_wait_timeout,
237                  uint flags)
238 {
239   return lock_table_names(thd, thd->lex->create_info, table_list,
240                           table_list_end, lock_wait_timeout, flags);
241 }
242 bool open_tables(THD *thd, const DDL_options_st &options,
243                  TABLE_LIST **tables, uint *counter,
244                  uint flags, Prelocking_strategy *prelocking_strategy);
245 
246 static inline bool
open_tables(THD * thd,TABLE_LIST ** tables,uint * counter,uint flags,Prelocking_strategy * prelocking_strategy)247 open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags,
248             Prelocking_strategy *prelocking_strategy)
249 {
250   return open_tables(thd, thd->lex->create_info, tables, counter, flags,
251                      prelocking_strategy);
252 }
253 /* open_and_lock_tables with optional derived handling */
254 bool open_and_lock_tables(THD *thd, const DDL_options_st &options,
255                           TABLE_LIST *tables,
256                           bool derived, uint flags,
257                           Prelocking_strategy *prelocking_strategy);
258 static inline bool
open_and_lock_tables(THD * thd,TABLE_LIST * tables,bool derived,uint flags,Prelocking_strategy * prelocking_strategy)259 open_and_lock_tables(THD *thd, TABLE_LIST *tables,
260                      bool derived, uint flags,
261                      Prelocking_strategy *prelocking_strategy)
262 {
263   return open_and_lock_tables(thd, thd->lex->create_info,
264                               tables, derived, flags, prelocking_strategy);
265 }
266 /* simple open_and_lock_tables without derived handling for single table */
267 TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
268                                 thr_lock_type lock_type, uint flags,
269                                 Prelocking_strategy *prelocking_strategy);
270 bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags,
271                                     uint dt_phases);
272 bool open_tables_only_view_structure(THD *thd, TABLE_LIST *tables,
273                                      bool can_deadlock);
274 bool open_and_lock_internal_tables(TABLE *table, bool lock);
275 bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
276 int decide_logging_format(THD *thd, TABLE_LIST *tables);
277 void close_thread_table(THD *thd, TABLE **table_ptr);
278 TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
279                          uint check_flag);
280 bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b);
281 
282 class Open_tables_backup;
283 /* Functions to work with system tables. */
284 bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
285                                  Open_tables_backup *backup);
286 void close_system_tables(THD *thd, Open_tables_backup *backup);
287 void close_mysql_tables(THD *thd);
288 TABLE *open_system_table_for_update(THD *thd, TABLE_LIST *one_table);
289 TABLE *open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup);
290 void close_log_table(THD *thd, Open_tables_backup *backup);
291 
292 TABLE *open_performance_schema_table(THD *thd, TABLE_LIST *one_table,
293                                      Open_tables_state *backup);
294 void close_performance_schema_table(THD *thd, Open_tables_state *backup);
295 
296 bool close_cached_tables(THD *thd, TABLE_LIST *tables,
297                          bool wait_for_refresh, ulong timeout);
298 bool close_cached_connection_tables(THD *thd, LEX_CSTRING *connect_string);
299 void close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
300                                ha_extra_function extra,
301                                TABLE *skip_table);
302 OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild);
303 bool tdc_open_view(THD *thd, TABLE_LIST *table_list, uint flags);
304 
305 TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
306                                   const char *table_name,
307                                   int *p_error);
308 void mark_tmp_table_for_reuse(TABLE *table);
309 
310 int dynamic_column_error_message(enum_dyncol_func_result rc);
311 
312 /* open_and_lock_tables with optional derived handling */
313 int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived);
314 
315 extern "C" int simple_raw_key_cmp(void* arg, const void* key1,
316                                   const void* key2);
317 extern "C" int count_distinct_walk(void *elem, element_count count, void *arg);
318 int simple_str_key_cmp(void* arg, uchar* key1, uchar* key2);
319 
320 extern Item **not_found_item;
321 extern Field *not_found_field;
322 extern Field *view_ref_found;
323 
324 /**
325   clean/setup table fields and map.
326 
327   @param table        TABLE structure pointer (which should be setup)
328   @param table_list   TABLE_LIST structure pointer (owner of TABLE)
329   @param tablenr     table number
330 */
331 
332 
setup_table_map(TABLE * table,TABLE_LIST * table_list,uint tablenr)333 inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
334 {
335   table->used_fields= 0;
336   table_list->reset_const_table();
337   table->null_row= 0;
338   table->status= STATUS_NO_RECORD;
339   table->maybe_null= table_list->outer_join;
340   TABLE_LIST *embedding= table_list->embedding;
341   while (!table->maybe_null && embedding)
342   {
343     table->maybe_null= embedding->outer_join;
344     embedding= embedding->embedding;
345   }
346   table->tablenr= tablenr;
347   table->map= (table_map) 1 << tablenr;
348   table->force_index= table_list->force_index;
349   table->force_index_order= table->force_index_group= 0;
350   table->covering_keys= table->s->keys_for_keyread;
351   TABLE_LIST *orig= table_list->select_lex ?
352     table_list->select_lex->master_unit()->derived : 0;
353   if (!orig || !orig->is_merged_derived())
354   {
355     /* Tables merged from derived were set up already.*/
356     table->covering_keys= table->s->keys_for_keyread;
357   }
358 }
359 
find_table_in_global_list(TABLE_LIST * table,LEX_CSTRING * db_name,LEX_CSTRING * table_name)360 inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table,
361                                              LEX_CSTRING *db_name,
362                                              LEX_CSTRING *table_name)
363 {
364   return find_table_in_list(table, &TABLE_LIST::next_global,
365                             db_name, table_name);
366 }
367 
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)368 inline bool setup_fields_with_no_wrap(THD *thd, Ref_ptr_array ref_pointer_array,
369                                       List<Item> &item,
370                                       enum_column_usage column_usage,
371                                       List<Item> *sum_func_list,
372                                       bool allow_sum_func)
373 {
374   bool res;
375   thd->lex->select_lex.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   thd->lex->select_lex.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()564   void set_has_protection_against_grl()
565   {
566     m_has_protection_against_grl= TRUE;
567   }
568 
has_protection_against_grl()569   bool has_protection_against_grl() const
570   {
571     return m_has_protection_against_grl;
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   bool 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