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