1 /* Copyright (c) 2010, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
22 
23 #ifndef SQL_BASE_INCLUDED
24 #define SQL_BASE_INCLUDED
25 
26 #include "sql_class.h"                          /* enum_mark_columns */
27 
28 class COPY_INFO;
29 class Item_ident;
30 struct Name_resolution_context;
31 class Open_table_context;
32 class Open_tables_state;
33 class Prelocking_strategy;
34 struct TABLE_LIST;
35 class THD;
36 struct handlerton;
37 struct TABLE;
38 class Table_trigger_dispatcher;
39 
40 typedef class st_select_lex SELECT_LEX;
41 
42 typedef struct st_lock_param_type ALTER_PARTITION_PARAM_TYPE;
43 
44 #define TEMP_PREFIX	"MY"
45 
46 	/* Defines for use with openfrm, openprt and openfrd */
47 
48 #define READ_ALL		1	/* openfrm: Read all parameters */
49 #define EXTRA_RECORD		8	/* Reservera plats f|r extra record */
50 #define DELAYED_OPEN	        4096    /* Open table later */
51 #define OPEN_VIEW		8196    /* Allow open on view */
52 #define OPEN_VIEW_NO_PARSE     16384    /* Open frm only if it's a view,
53                                            but do not parse view itself */
54 /**
55   This flag is used in function get_all_tables() which fills
56   I_S tables with data which are retrieved from frm files and storage engine
57   The flag means that we need to open FRM file only to get necessary data.
58 */
59 #define OPEN_FRM_FILE_ONLY     32768
60 /**
61   This flag is used in function get_all_tables() which fills
62   I_S tables with data which are retrieved from frm files and storage engine
63   The flag means that we need to process tables only to get necessary data.
64   Views are not processed.
65 */
66 #define OPEN_TABLE_ONLY        OPEN_FRM_FILE_ONLY*2
67 /**
68   This flag is used in function get_all_tables() which fills
69   I_S tables with data which are retrieved from frm files and storage engine
70   The flag means that we need to process views only to get necessary data.
71   Tables are not processed.
72 */
73 #define OPEN_VIEW_ONLY         OPEN_TABLE_ONLY*2
74 /**
75   This flag is used in function get_all_tables() which fills
76   I_S tables with data which are retrieved from frm files and storage engine.
77   The flag means that we need to open a view.
78 */
79 #define OPEN_VIEW_FULL         OPEN_VIEW_ONLY*2
80 /**
81   This flag is used in function get_all_tables() which fills
82   I_S tables with data which are retrieved from frm files and storage engine.
83   The flag means that I_S table uses optimization algorithm.
84 */
85 #define OPTIMIZE_I_S_TABLE     OPEN_VIEW_FULL*2
86 /**
87   The flag means that we need to process trigger files only.
88 */
89 #define OPEN_TRIGGER_ONLY      OPTIMIZE_I_S_TABLE*2
90 /**
91   This flag is used to instruct tdc_open_view() to check metadata version.
92 */
93 #define CHECK_METADATA_VERSION OPEN_TRIGGER_ONLY*2
94 
95 
96 /*
97   This enumeration type is used only by the function find_item_in_list
98   to return the info on how an item has been resolved against a list
99   of possibly aliased items.
100   The item can be resolved:
101    - against an alias name of the list's element (RESOLVED_AGAINST_ALIAS)
102    - against non-aliased field name of the list  (RESOLVED_WITH_NO_ALIAS)
103    - against an aliased field name of the list   (RESOLVED_BEHIND_ALIAS)
104    - ignoring the alias name in cases when SQL requires to ignore aliases
105      (e.g. when the resolved field reference contains a table name or
106      when the resolved item is an expression)   (RESOLVED_IGNORING_ALIAS)
107 */
108 enum enum_resolution_type {
109   NOT_RESOLVED=0,
110   RESOLVED_IGNORING_ALIAS,
111   RESOLVED_BEHIND_ALIAS,
112   RESOLVED_WITH_NO_ALIAS,
113   RESOLVED_AGAINST_ALIAS
114 };
115 
116 enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
117 				  IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE,
118                                   IGNORE_EXCEPT_NON_UNIQUE};
119 
120 enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
121                                  TDC_RT_REMOVE_UNUSED,
122                                  TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE};
123 
124 /* bits for last argument to remove_table_from_cache() */
125 #define RTFC_NO_FLAG                0x0000
126 #define RTFC_OWNED_BY_THD_FLAG      0x0001
127 #define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002
128 #define RTFC_CHECK_KILLED_FLAG      0x0004
129 
130 bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
131 extern mysql_mutex_t LOCK_open;
132 bool table_cache_init(void);
133 void table_cache_free(void);
134 bool table_def_init(void);
135 void table_def_free(void);
136 void table_def_start_shutdown(void);
137 void assign_new_table_id(TABLE_SHARE *share);
138 uint cached_table_definitions(void);
139 size_t get_table_def_key(const TABLE_LIST *table_list, const char **key);
140 TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list,
141                              const char *key, size_t key_length,
142                              uint db_flags, int *error,
143                              my_hash_value_type hash_value);
144 void release_table_share(TABLE_SHARE *share);
145 TABLE_SHARE *get_cached_table_share(THD *thd, const char *db,
146                                     const char *table_name);
147 
148 TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
149                    uint lock_flags);
150 
151 /* mysql_lock_tables() and open_table() flags bits */
152 #define MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK      0x0001
153 #define MYSQL_OPEN_IGNORE_FLUSH                 0x0002
154 /* MYSQL_OPEN_TEMPORARY_ONLY (0x0004) is not used anymore. */
155 #define MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY      0x0008
156 #define MYSQL_LOCK_LOG_TABLE                    0x0010
157 /**
158   Do not try to acquire a metadata lock on the table: we
159   already have one.
160 */
161 #define MYSQL_OPEN_HAS_MDL_LOCK                 0x0020
162 /**
163   If in locked tables mode, ignore the locked tables and get
164   a new instance of the table.
165 */
166 #define MYSQL_OPEN_GET_NEW_TABLE                0x0040
167 /* 0x0080 used to be MYSQL_OPEN_SKIP_TEMPORARY */
168 /** Fail instead of waiting when conficting metadata lock is discovered. */
169 #define MYSQL_OPEN_FAIL_ON_MDL_CONFLICT         0x0100
170 /** Open tables using MDL_SHARED lock instead of one specified in parser. */
171 #define MYSQL_OPEN_FORCE_SHARED_MDL             0x0200
172 /**
173   Open tables using MDL_SHARED_HIGH_PRIO lock instead of one specified
174   in parser.
175 */
176 #define MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL   0x0400
177 /**
178   When opening or locking the table, use the maximum timeout
179   (LONG_TIMEOUT = 1 year) rather than the user-supplied timeout value.
180 */
181 #define MYSQL_LOCK_IGNORE_TIMEOUT               0x0800
182 /**
183   When acquiring "strong" (SNW, SNRW, X) metadata locks on tables to
184   be open do not acquire global, tablespace-scope and schema-scope IX locks.
185 */
186 #define MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK         0x1000
187 /**
188   When opening or locking a replication table through an internal
189   operation rather than explicitly through an user thread.
190 */
191 #define MYSQL_LOCK_RPL_INFO_TABLE               0x2000
192 /**
193   Only check THD::killed if waits happen (e.g. wait on MDL, wait on
194   table flush, wait on thr_lock.c locks) while opening and locking table.
195 */
196 #define MYSQL_OPEN_IGNORE_KILLED                0x4000
197 
198 /** Please refer to the internals manual. */
199 #define MYSQL_OPEN_REOPEN  (MYSQL_OPEN_IGNORE_FLUSH |\
200                             MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK |\
201                             MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY |\
202                             MYSQL_LOCK_IGNORE_TIMEOUT |\
203                             MYSQL_OPEN_IGNORE_KILLED |\
204                             MYSQL_OPEN_GET_NEW_TABLE |\
205                             MYSQL_OPEN_HAS_MDL_LOCK)
206 
207 bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx);
208 
209 bool get_key_map_from_key_list(key_map *map, TABLE *table,
210                                List<String> *index_list);
211 TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
212 			   const char *table_name,
213                            bool add_to_temporary_tables_list,
214                            bool open_in_engine);
215 TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name);
216 thr_lock_type read_lock_type_for_table(THD *thd,
217                                        Query_tables_list *prelocking_ctx,
218                                        TABLE_LIST *table_list,
219                                        bool routine_modifies_data);
220 
221 my_bool mysql_rm_tmp_tables(void);
222 bool rm_temporary_table(handlerton *base, const char *path);
223 void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
224                              const MDL_savepoint &start_of_statement_svp);
225 TABLE_LIST *find_table_in_list(TABLE_LIST *table,
226                                TABLE_LIST *TABLE_LIST::*link,
227                                const char *db_name,
228                                const char *table_name);
229 TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name);
230 TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
231 TABLE *find_temporary_table(THD *thd, const char *table_key,
232                             size_t table_key_length);
233 void close_thread_tables(THD *thd);
234 bool fill_record_n_invoke_before_triggers(THD *thd, COPY_INFO *optype_info,
235                                           List<Item> &fields,
236                                           List<Item> &values,
237                                           TABLE *table,
238                                           enum enum_trigger_event_type event,
239                                           int num_fields);
240 bool fill_record_n_invoke_before_triggers(THD *thd, Field **field,
241                                           List<Item> &values,
242                                           TABLE *table,
243                                           enum enum_trigger_event_type event,
244                                           int num_fields);
245 bool insert_fields(THD *thd, Name_resolution_context *context,
246 		   const char *db_name, const char *table_name,
247                    List_iterator<Item> *it, bool any_privileges);
248 bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
249                   List<Item> &item, ulong privilege,
250                   List<Item> *sum_func_list,
251                   bool allow_sum_func, bool column_update);
252 bool fill_record(THD *thd, TABLE *table, List<Item> &fields, List<Item> &values,
253                  MY_BITMAP *bitmap, MY_BITMAP *insert_into_fields_bitmap);
254 bool fill_record(THD *thd, TABLE *table, Field **field, List<Item> &values,
255                  MY_BITMAP *bitmap, MY_BITMAP *insert_into_fields_bitmap);
256 
257 bool check_record(THD *thd, Field **ptr);
258 
259 Field *
260 find_field_in_tables(THD *thd, Item_ident *item,
261                      TABLE_LIST *first_table, TABLE_LIST *last_table,
262                      Item **ref, find_item_error_report_type report_error,
263                      ulong want_privilege, bool register_tree_change);
264 Field *
265 find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
266                         const char *name, size_t length,
267                         const char *item_name, const char *db_name,
268                         const char *table_name, Item **ref,
269                         ulong want_privilege, bool allow_rowid,
270                         uint *cached_field_index_ptr,
271                         bool register_tree_change, TABLE_LIST **actual_table);
272 Field *
273 find_field_in_table(THD *thd, TABLE *table, const char *name, size_t length,
274                     bool allow_rowid, uint *cached_field_index_ptr);
275 Field *
276 find_field_in_table_sef(TABLE *table, const char *name);
277 Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
278                           find_item_error_report_type report_error,
279                           enum_resolution_type *resolution);
280 bool setup_natural_join_row_types(THD *thd,
281                                   List<TABLE_LIST> *from_clause,
282                                   Name_resolution_context *context);
283 bool wait_while_table_is_used(THD *thd, TABLE *table,
284                               enum ha_extra_function function);
285 
286 void drop_open_table(THD *thd, TABLE *table, const char *db_name,
287                      const char *table_name);
288 void update_non_unique_table_error(TABLE_LIST *update,
289                                    const char *operation,
290                                    TABLE_LIST *duplicate);
291 int setup_ftfuncs(SELECT_LEX* select);
292 bool init_ftfuncs(THD *thd, SELECT_LEX* select);
293 int run_before_dml_hook(THD *thd);
294 bool lock_table_names(THD *thd, TABLE_LIST *table_list,
295                       TABLE_LIST *table_list_end, ulong lock_wait_timeout,
296                       uint flags);
297 bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags,
298                  Prelocking_strategy *prelocking_strategy);
299 /* open_and_lock_tables */
300 bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, uint flags,
301                           Prelocking_strategy *prelocking_strategy);
302 /* simple open_and_lock_tables for single table */
303 TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
304                                 thr_lock_type lock_type, uint flags,
305                                 Prelocking_strategy *prelocking_strategy);
306 bool open_tables_for_query(THD *thd, TABLE_LIST *tables, uint flags);
307 bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
308 void free_io_cache(TABLE *entry);
309 void intern_close_table(TABLE *entry);
310 void close_thread_table(THD *thd, TABLE **table_ptr);
311 bool close_temporary_tables(THD *thd);
312 TABLE_LIST *unique_table(THD *thd, const TABLE_LIST *table,
313                          TABLE_LIST *table_list, bool check_alias);
314 int drop_temporary_table(THD *thd, TABLE_LIST *table_list, bool *is_trans);
315 void close_temporary_table(THD *thd, TABLE *table, bool free_share,
316                            bool delete_table);
317 void close_temporary(TABLE *table, bool free_share, bool delete_table);
318 bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
319 			    const char *table_name);
320 bool open_temporary_tables(THD *thd, TABLE_LIST *tl_list);
321 bool open_temporary_table(THD *thd, TABLE_LIST *tl);
322 bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
323 bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b);
324 bool is_order_deterministic(List<TABLE_LIST>* join_list,
325                             Item *cond, ORDER* order);
326 bool is_order_deterministic(TABLE_LIST *table,
327                             Item *cond, ORDER* order);
328 
329 /* Functions to work with system tables. */
330 bool open_nontrans_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
331                                  Open_tables_backup *backup);
332 bool open_trans_system_tables_for_read(THD *thd, TABLE_LIST *table_list);
333 void close_nontrans_system_tables(THD *thd, Open_tables_backup *backup);
334 void close_trans_system_tables(THD *thd);
335 void close_mysql_tables(THD *thd);
336 TABLE *open_system_table_for_update(THD *thd, TABLE_LIST *one_table);
337 TABLE *open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup);
338 void close_log_table(THD *thd, Open_tables_backup *backup);
339 
340 TABLE *open_performance_schema_table(THD *thd, TABLE_LIST *one_table,
341                                      Open_tables_state *backup);
342 void close_performance_schema_table(THD *thd, Open_tables_state *backup);
343 
344 bool close_cached_tables(THD *thd, TABLE_LIST *tables,
345                          bool wait_for_refresh, ulong timeout);
346 void close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
347                                bool remove_from_locked_tables,
348                                TABLE *skip_table);
349 OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild);
350 void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
351                       const char *db, const char *table_name,
352                       bool has_lock);
353 bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias,
354                    const char *cache_key, size_t cache_key_length, uint flags);
355 void tdc_flush_unused_tables();
356 TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
357                                   const char *table_name,
358                                   bool no_error);
359 void mark_tmp_table_for_reuse(TABLE *table);
360 bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
361 bool add_view_place_holder(THD *thd, TABLE_LIST *table_list);
362 
363 extern Item **not_found_item;
364 extern Field *not_found_field;
365 extern Field *view_ref_found;
366 extern HASH table_def_cache;
367 
368 /**
369   clean/setup table fields and map.
370 
371   @param table        TABLE structure pointer (which should be setup)
372   @param table_list   TABLE_LIST structure pointer (owner of TABLE)
373   @param tableno      table number
374 */
375 
find_table_in_global_list(TABLE_LIST * table,const char * db_name,const char * table_name)376 inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table,
377                                              const char *db_name,
378                                              const char *table_name)
379 {
380   return find_table_in_list(table, &TABLE_LIST::next_global,
381                             db_name, table_name);
382 }
383 
find_table_in_local_list(TABLE_LIST * table,const char * db_name,const char * table_name)384 inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table,
385                                             const char *db_name,
386                                             const char *table_name)
387 {
388   return find_table_in_list(table, &TABLE_LIST::next_local,
389                             db_name, table_name);
390 }
391 
392 
393 /**
394   An abstract class for a strategy specifying how the prelocking
395   algorithm should extend the prelocking set while processing
396   already existing elements in the set.
397 */
398 
399 class Prelocking_strategy
400 {
401 public:
~Prelocking_strategy()402   virtual ~Prelocking_strategy() { }
403 
404   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
405                               Sroutine_hash_entry *rt, sp_head *sp,
406                               bool *need_prelocking) = 0;
407   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
408                             TABLE_LIST *table_list, bool *need_prelocking) = 0;
409   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
410                            TABLE_LIST *table_list, bool *need_prelocking)= 0;
411 };
412 
413 
414 /**
415   A Strategy for prelocking algorithm suitable for DML statements.
416 
417   Ensures that all tables used by all statement's SF/SP/triggers and
418   required for foreign key checks are prelocked and SF/SPs used are
419   cached.
420 */
421 
422 class DML_prelocking_strategy : public Prelocking_strategy
423 {
424 public:
425   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
426                               Sroutine_hash_entry *rt, sp_head *sp,
427                               bool *need_prelocking);
428   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
429                             TABLE_LIST *table_list, bool *need_prelocking);
430   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
431                            TABLE_LIST *table_list, bool *need_prelocking);
432 };
433 
434 
435 /**
436   A strategy for prelocking algorithm to be used for LOCK TABLES
437   statement.
438 */
439 
440 class Lock_tables_prelocking_strategy : public DML_prelocking_strategy
441 {
442   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
443                             TABLE_LIST *table_list, bool *need_prelocking);
444 };
445 
446 
447 /**
448   Strategy for prelocking algorithm to be used for ALTER TABLE statements.
449 
450   Unlike DML or LOCK TABLES strategy, it doesn't
451   prelock triggers, views or stored routines, since they are not
452   used during ALTER.
453 */
454 
455 class Alter_table_prelocking_strategy : public Prelocking_strategy
456 {
457 public:
458   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
459                               Sroutine_hash_entry *rt, sp_head *sp,
460                               bool *need_prelocking);
461   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
462                             TABLE_LIST *table_list, bool *need_prelocking);
463   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
464                            TABLE_LIST *table_list, bool *need_prelocking);
465 };
466 
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, tables, counter, flags, &prelocking_strategy);
474 }
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 default prelocking strategy
open_and_lock_tables(THD * thd,TABLE_LIST * tables,uint flags)488 inline bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, uint flags)
489 {
490   DML_prelocking_strategy prelocking_strategy;
491 
492   return open_and_lock_tables(thd, tables, flags, &prelocking_strategy);
493 }
494 
495 
496 /**
497   A context of open_tables() function, used to recover
498   from a failed open_table() or open_routine() attempt.
499 */
500 
501 class Open_table_context
502 {
503 public:
504   enum enum_open_table_action
505   {
506     OT_NO_ACTION= 0,
507     OT_BACKOFF_AND_RETRY,
508     OT_REOPEN_TABLES,
509     OT_DISCOVER,
510     OT_REPAIR
511   };
512   Open_table_context(THD *thd, uint flags);
513 
514   bool recover_from_failed_open();
515   bool request_backoff_action(enum_open_table_action action_arg,
516                               TABLE_LIST *table);
517 
can_recover_from_failed_open()518   bool can_recover_from_failed_open() const
519   { return m_action != OT_NO_ACTION; }
520 
521   /**
522     When doing a back-off, we close all tables acquired by this
523     statement.  Return an MDL savepoint taken at the beginning of
524     the statement, so that we can rollback to it before waiting on
525     locks.
526   */
start_of_statement_svp()527   const MDL_savepoint &start_of_statement_svp() const
528   {
529     return m_start_of_statement_svp;
530   }
531 
get_timeout()532   inline ulong get_timeout() const
533   {
534     return m_timeout;
535   }
536 
get_flags()537   uint get_flags() const { return m_flags; }
538 
539   /**
540     Set flag indicating that we have already acquired metadata lock
541     protecting this statement against GRL while opening tables.
542   */
set_has_protection_against_grl()543   void set_has_protection_against_grl()
544   {
545     m_has_protection_against_grl= TRUE;
546   }
547 
has_protection_against_grl()548   bool has_protection_against_grl() const
549   {
550     return m_has_protection_against_grl;
551   }
552 
can_back_off()553   bool can_back_off() const
554   {
555     return !m_has_locks;
556   }
557 
558 private:
559   /* THD for which tables are opened. */
560   THD *m_thd;
561   /**
562     For OT_DISCOVER and OT_REPAIR actions, the table list element for
563     the table which definition should be re-discovered or which
564     should be repaired.
565   */
566   TABLE_LIST *m_failed_table;
567   MDL_savepoint m_start_of_statement_svp;
568   /**
569     Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system
570     tables or to the "lock_wait_timeout" system variable for regular tables.
571   */
572   ulong m_timeout;
573   /* open_table() flags. */
574   uint m_flags;
575   /** Back off action. */
576   enum enum_open_table_action m_action;
577   /**
578     Whether we had any locks when this context was created.
579     If we did, they are from the previous statement of a transaction,
580     and we can't safely do back-off (and release them).
581   */
582   bool m_has_locks;
583   /**
584     Indicates that in the process of opening tables we have acquired
585     protection against global read lock.
586   */
587   bool m_has_protection_against_grl;
588 };
589 
590 
591 /**
592   Check if a TABLE_LIST instance represents a pre-opened temporary table.
593 */
594 
is_temporary_table(TABLE_LIST * tl)595 inline bool is_temporary_table(TABLE_LIST *tl)
596 {
597   if (tl->is_view() || tl->schema_table)
598     return FALSE;
599 
600   if (!tl->table)
601     return FALSE;
602 
603   /*
604     NOTE: 'table->s' might be NULL for specially constructed TABLE
605     instances. See SHOW TRIGGERS for example.
606   */
607 
608   if (!tl->table->s)
609     return FALSE;
610 
611   return tl->table->s->tmp_table != NO_TMP_TABLE;
612 }
613 
614 /**
615   A simple holder for Internal_error_handler.
616   The class utilizes RAII technique to not forget to pop the handler.
617 
618   @tparam Error_handler      Internal_error_handler to instantiate.
619   @tparam Error_handler_arg  Type of the error handler ctor argument.
620 */
621 template<typename Error_handler, typename Error_handler_arg>
622 class Internal_error_handler_holder
623 {
624   THD *m_thd;
625   bool m_activate;
626   Error_handler m_error_handler;
627 
628 public:
Internal_error_handler_holder(THD * thd,bool activate,Error_handler_arg * arg)629   Internal_error_handler_holder(THD *thd, bool activate,
630                                 Error_handler_arg *arg)
631     : m_thd(thd), m_activate(activate), m_error_handler(arg)
632   {
633     if (activate)
634       thd->push_internal_handler(&m_error_handler);
635   }
636 
637 
~Internal_error_handler_holder()638   ~Internal_error_handler_holder()
639   {
640     if (m_activate)
641       m_thd->pop_internal_handler();
642   }
643 };
644 
645 /**
646    An Internal_error_handler that suppresses errors regarding views'
647    underlying tables that occur during privilege checking. It hides errors which
648    show view underlying table information.
649    This happens in the cases when
650 
651    - A view's underlying table (e.g. referenced in its SELECT list) does not
652      exist or columns of underlying table are altered. There should not be an
653      error as no attempt was made to access it per se.
654 
655    - Access is denied for some table, column, function or stored procedure
656      such as mentioned above. This error gets raised automatically, since we
657      can't untangle its access checking from that of the view itself.
658 
659     There are currently two mechanisms at work that handle errors for views
660     based on an Internal_error_handler. This one and another one is
661     Show_create_error_handler. The latter handles errors encountered during
662     execution of SHOW CREATE VIEW, while this mechanism using this method is
663     handles SELECT from views. The two methods should not clash.
664 
665 */
666 class View_error_handler : public Internal_error_handler
667 {
668   TABLE_LIST *m_top_view;
669 
670 public:
View_error_handler(TABLE_LIST * top_view)671   View_error_handler(TABLE_LIST *top_view) :
672   m_top_view(top_view)
673   {}
674   virtual bool handle_condition(THD *thd, uint sql_errno, const char *,
675                                 Sql_condition::enum_severity_level *level,
676                                 const char *message);
677 };
678 
679 /**
680   This internal handler is used to trap ER_NO_SUCH_TABLE.
681 */
682 
683 class No_such_table_error_handler : public Internal_error_handler
684 {
685 public:
No_such_table_error_handler()686   No_such_table_error_handler()
687     : m_handled_errors(0), m_unhandled_errors(0)
688   {}
689 
handle_condition(THD * thd,uint sql_errno,const char * sqlstate,Sql_condition::enum_severity_level * level,const char * msg)690   virtual bool handle_condition(THD *thd,
691                                 uint sql_errno,
692                                 const char* sqlstate,
693                                 Sql_condition::enum_severity_level *level,
694                                 const char* msg)
695   {
696     if (sql_errno == ER_NO_SUCH_TABLE)
697     {
698       m_handled_errors++;
699       return true;
700     }
701 
702     m_unhandled_errors++;
703     return false;
704   }
705 
706   /**
707     Returns true if one or more ER_NO_SUCH_TABLE errors have been
708     trapped and no other errors have been seen. false otherwise.
709   */
safely_trapped_errors()710   bool safely_trapped_errors() const
711   {
712     /*
713       If m_unhandled_errors != 0, something else, unanticipated, happened,
714       so the error is not trapped but returned to the caller.
715       Multiple ER_NO_SUCH_TABLE can be raised in case of views.
716     */
717     return ((m_handled_errors > 0) && (m_unhandled_errors == 0));
718   }
719 
720 private:
721   int m_handled_errors;
722   int m_unhandled_errors;
723 };
724 
725 
726 /**
727   This internal handler implements downgrade from SL_ERROR to SL_WARNING
728   for statements which support IGNORE.
729 */
730 
731 class Ignore_error_handler : public Internal_error_handler
732 {
733 public:
734   virtual bool handle_condition(THD *thd,
735                                 uint sql_errno,
736                                 const char* sqlstate,
737                                 Sql_condition::enum_severity_level *level,
738                                 const char* msg);
739 };
740 
741 /**
742   This internal handler implements upgrade from SL_WARNING to SL_ERROR
743   for the error codes affected by STRICT mode. Currently STRICT mode does
744   not affect SELECT statements.
745 */
746 
747 class Strict_error_handler : public Internal_error_handler
748 {
749 public:
750   enum enum_set_select_behavior
751   {
752     DISABLE_SET_SELECT_STRICT_ERROR_HANDLER,
753     ENABLE_SET_SELECT_STRICT_ERROR_HANDLER
754   };
755 
Strict_error_handler()756   Strict_error_handler()
757     : m_set_select_behavior(DISABLE_SET_SELECT_STRICT_ERROR_HANDLER)
758   {}
759 
Strict_error_handler(enum_set_select_behavior param)760   Strict_error_handler(enum_set_select_behavior param)
761     : m_set_select_behavior(param)
762   {}
763 
764   virtual bool handle_condition(THD *thd,
765                                 uint sql_errno,
766                                 const char* sqlstate,
767                                 Sql_condition::enum_severity_level *level,
768                                 const char* msg);
769 
770 private:
771   /*
772     For SELECT and SET statement, we do not always give error in STRICT mode.
773     For triggers, Strict_error_handler is pushed in the beginning of statement.
774     If a SELECT or SET is executed from the Trigger, it should not always give
775     error. We use this flag to choose when to give error and when warning.
776   */
777   enum_set_select_behavior m_set_select_behavior;
778 };
779 
780 /**
781   This internal handler is to make sure that deprecation warning is not
782   displayed again if already displayed once.
783 */
784 
785 class Partition_in_shared_ts_error_handler : public Internal_error_handler
786 {
787 public:
Partition_in_shared_ts_error_handler()788   Partition_in_shared_ts_error_handler()
789     : m_is_already_reported(false)
790   {}
791 
792   virtual bool handle_condition(THD *thd,
793                                 uint sql_errno,
794                                 const char* sqlstate,
795                                 Sql_condition::enum_severity_level *level,
796                                 const char* msg);
797 
798 private:
799   bool m_is_already_reported;
800 };
801 
802 void update_indexed_column_map(TABLE *table, MY_BITMAP *read_set);
803 
804 #endif /* SQL_BASE_INCLUDED */
805