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