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