1 /* Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
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 <stddef.h>
27 #include <sys/types.h>
28 #include <memory>
29 #include <string>
30 
31 #include "lex_string.h"
32 #include "map_helpers.h"
33 #include "mem_root_deque.h"
34 #include "my_base.h"  // ha_extra_function
35 #include "my_inttypes.h"
36 #include "mysql/components/services/mysql_mutex_bits.h"
37 #include "prealloced_array.h"  // Prealloced_array
38 #include "sql/mdl.h"           // MDL_savepoint
39 #include "sql/sql_array.h"     // Bounds_checked_array
40 #include "sql/sql_const.h"     // enum_resolution_type
41 #include "sql/trigger_def.h"   // enum_trigger_event_type
42 #include "thr_lock.h"          // thr_lock_type
43 
44 class COPY_INFO;
45 class Field;
46 class Item;
47 class Item_ident;
48 class Open_table_context;
49 class Open_tables_backup;
50 class Prelocking_strategy;
51 class Query_tables_list;
52 class SELECT_LEX;
53 class Sroutine_hash_entry;
54 class THD;
55 class sp_head;
56 struct LEX;
57 struct MY_BITMAP;
58 struct Name_resolution_context;
59 struct OPEN_TABLE_LIST;
60 struct TABLE;
61 struct TABLE_LIST;
62 struct TABLE_SHARE;
63 struct handlerton;
64 template <class T>
65 class List;
66 template <class T>
67 class List_iterator;
68 
69 typedef Bounds_checked_array<Item *> Ref_item_array;
70 namespace dd {
71 class Table;
72 }  // namespace dd
73 
74 #define TEMP_PREFIX "MY"
75 
76 /* Defines for use with openfrm, openprt and openfrd */
77 
78 #define READ_ALL 1        /* openfrm: Read all parameters */
79 #define EXTRA_RECORD 8    /* Reservera plats f|r extra record */
80 #define DELAYED_OPEN 4096 /* Open table later */
81 /**
82   If set, open_table_from_share() will skip calling get_new_handler() to
83   create a new handler object for the table. Designed to be used when
84   opening a table from inside storage engines.
85 */
86 #define SKIP_NEW_HANDLER 32768
87 
88 enum find_item_error_report_type {
89   REPORT_ALL_ERRORS,
90   REPORT_EXCEPT_NOT_FOUND,
91   IGNORE_ERRORS,
92   REPORT_EXCEPT_NON_UNIQUE,
93   IGNORE_EXCEPT_NON_UNIQUE
94 };
95 
96 enum enum_tdc_remove_table_type {
97   TDC_RT_REMOVE_ALL,
98   TDC_RT_REMOVE_NOT_OWN,
99   TDC_RT_REMOVE_UNUSED,
100   TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE
101 };
102 
103 extern mysql_mutex_t LOCK_open;
104 bool table_def_init(void);
105 void table_def_free(void);
106 void table_def_start_shutdown(void);
107 void assign_new_table_id(TABLE_SHARE *share);
108 uint cached_table_definitions(void);
109 size_t get_table_def_key(const TABLE_LIST *table_list, const char **key);
110 TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name,
111                              const char *key, size_t key_length, bool open_view,
112                              bool open_secondary = false);
113 void release_table_share(TABLE_SHARE *share);
114 
115 TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
116                    uint lock_flags);
117 
118 /* mysql_lock_tables() and open_table() flags bits */
119 #define MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK 0x0001
120 #define MYSQL_OPEN_IGNORE_FLUSH 0x0002
121 /* MYSQL_OPEN_TEMPORARY_ONLY (0x0004) is not used anymore. */
122 #define MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY 0x0008
123 #define MYSQL_LOCK_LOG_TABLE 0x0010
124 /**
125   Do not try to acquire a metadata lock on the table: we
126   already have one.
127 */
128 #define MYSQL_OPEN_HAS_MDL_LOCK 0x0020
129 /**
130   If in locked tables mode, ignore the locked tables and get
131   a new instance of the table.
132 */
133 #define MYSQL_OPEN_GET_NEW_TABLE 0x0040
134 /* 0x0080 used to be MYSQL_OPEN_SKIP_TEMPORARY */
135 /** Fail instead of waiting when conficting metadata lock is discovered. */
136 #define MYSQL_OPEN_FAIL_ON_MDL_CONFLICT 0x0100
137 /** Open tables using MDL_SHARED lock instead of one specified in parser. */
138 #define MYSQL_OPEN_FORCE_SHARED_MDL 0x0200
139 /**
140   Open tables using MDL_SHARED_HIGH_PRIO lock instead of one specified
141   in parser.
142 */
143 #define MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL 0x0400
144 /**
145   When opening or locking the table, use the maximum timeout
146   (LONG_TIMEOUT = 1 year) rather than the user-supplied timeout value.
147 */
148 #define MYSQL_LOCK_IGNORE_TIMEOUT 0x0800
149 /**
150   When acquiring "strong" (SNW, SNRW, X) metadata locks on tables to
151   be open do not acquire global, tablespace-scope and schema-scope IX locks.
152 */
153 #define MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK 0x1000
154 /**
155   When opening or locking a replication table through an internal
156   operation rather than explicitly through an user thread.
157 */
158 #define MYSQL_LOCK_RPL_INFO_TABLE 0x2000
159 /**
160   Only check THD::killed if waits happen (e.g. wait on MDL, wait on
161   table flush, wait on thr_lock.c locks) while opening and locking table.
162 */
163 #define MYSQL_OPEN_IGNORE_KILLED 0x4000
164 /**
165   For new TABLE instances constructed do not open table in the storage
166   engine. Existing TABLE instances for which there is a handler object
167   which represents table open in storage engines can still be used.
168 */
169 #define MYSQL_OPEN_NO_NEW_TABLE_IN_SE 0x8000
170 /** Open a shadow copy of a table from a secondary storage engine. */
171 #define MYSQL_OPEN_SECONDARY_ENGINE 0x10000
172 
173 /** Please refer to the internals manual. */
174 #define MYSQL_OPEN_REOPEN                                           \
175   (MYSQL_OPEN_IGNORE_FLUSH | MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK |   \
176    MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY | MYSQL_LOCK_IGNORE_TIMEOUT | \
177    MYSQL_OPEN_IGNORE_KILLED | MYSQL_OPEN_GET_NEW_TABLE |            \
178    MYSQL_OPEN_HAS_MDL_LOCK)
179 
180 bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx);
181 
182 TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
183                            const char *table_name,
184                            bool add_to_temporary_tables_list,
185                            bool open_in_engine, const dd::Table &table_def);
186 TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name);
187 thr_lock_type read_lock_type_for_table(THD *thd,
188                                        Query_tables_list *prelocking_ctx,
189                                        TABLE_LIST *table_list,
190                                        bool routine_modifies_data);
191 
192 bool mysql_rm_tmp_tables(void);
193 bool rm_temporary_table(THD *thd, handlerton *base, const char *path,
194                         const dd::Table *table_def);
195 void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
196                              const MDL_savepoint &start_of_statement_svp);
197 TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name);
198 TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
199 void close_thread_tables(THD *thd);
200 bool fill_record_n_invoke_before_triggers(
201     THD *thd, COPY_INFO *optype_info, List<Item> &fields, List<Item> &values,
202     TABLE *table, enum enum_trigger_event_type event, int num_fields,
203     bool raise_autoinc_has_expl_non_null_val, bool *is_row_changed);
204 bool fill_record_n_invoke_before_triggers(THD *thd, Field **field,
205                                           List<Item> &values, TABLE *table,
206                                           enum enum_trigger_event_type event,
207                                           int num_fields);
208 bool resolve_var_assignments(THD *thd, LEX *lex);
209 bool insert_fields(THD *thd, Name_resolution_context *context,
210                    const char *db_name, const char *table_name,
211                    List_iterator<Item> *it, bool any_privileges);
212 bool setup_fields(THD *thd, Ref_item_array ref_item_array, List<Item> &item,
213                   ulong privilege, List<Item> *sum_func_list,
214                   bool allow_sum_func, bool column_update);
215 bool fill_record(THD *thd, TABLE *table, List<Item> &fields, List<Item> &values,
216                  MY_BITMAP *bitmap, MY_BITMAP *insert_into_fields_bitmap,
217                  bool raise_autoinc_has_expl_non_null_val);
218 bool fill_record(THD *thd, TABLE *table, Field **field, List<Item> &values,
219                  MY_BITMAP *bitmap, MY_BITMAP *insert_into_fields_bitmap,
220                  bool raise_autoinc_has_expl_non_null_val);
221 
222 bool check_record(THD *thd, Field **ptr);
223 
224 /**
225   Invoke check constraints defined on the table.
226 
227   @param  thd                   Thread handle.
228   @param  table                 Instance of TABLE.
229 
230   @retval  false  If all enforced check constraints are satisfied.
231   @retval  true   Otherwise. THD::is_error() may be "true" in this case.
232 */
233 bool invoke_table_check_constraints(THD *thd, const TABLE *table);
234 
235 Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *first_table,
236                             TABLE_LIST *last_table, Item **ref,
237                             find_item_error_report_type report_error,
238                             ulong want_privilege, bool register_tree_change);
239 Field *find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
240                                const char *name, size_t length,
241                                const char *item_name, const char *db_name,
242                                const char *table_name, Item **ref,
243                                ulong want_privilege, bool allow_rowid,
244                                uint *cached_field_index_ptr,
245                                bool register_tree_change,
246                                TABLE_LIST **actual_table);
247 Field *find_field_in_table(TABLE *table, const char *name, size_t length,
248                            bool allow_rowid, uint *cached_field_index_ptr);
249 Field *find_field_in_table_sef(TABLE *table, const char *name);
250 Item **find_item_in_list(THD *thd, Item *item, List<Item> &items, uint *counter,
251                          find_item_error_report_type report_error,
252                          enum_resolution_type *resolution);
253 bool setup_natural_join_row_types(THD *thd,
254                                   mem_root_deque<TABLE_LIST *> *from_clause,
255                                   Name_resolution_context *context);
256 bool wait_while_table_is_used(THD *thd, TABLE *table,
257                               enum ha_extra_function function);
258 
259 void update_non_unique_table_error(TABLE_LIST *update, const char *operation,
260                                    TABLE_LIST *duplicate);
261 int setup_ftfuncs(const THD *thd, SELECT_LEX *select);
262 bool init_ftfuncs(THD *thd, SELECT_LEX *select);
263 int run_before_dml_hook(THD *thd);
264 bool get_and_lock_tablespace_names(THD *thd, TABLE_LIST *tables_start,
265                                    TABLE_LIST *tables_end,
266                                    ulong lock_wait_timeout, uint flags);
267 bool lock_table_names(
268     THD *thd, TABLE_LIST *table_list, TABLE_LIST *table_list_end,
269     ulong lock_wait_timeout, uint flags,
270     Prealloced_array<MDL_request *, 1> *schema_reqs = nullptr);
271 bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags,
272                  Prelocking_strategy *prelocking_strategy);
273 /* open_and_lock_tables */
274 bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, uint flags,
275                           Prelocking_strategy *prelocking_strategy);
276 /* simple open_and_lock_tables for single table */
277 TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
278                                 thr_lock_type lock_type, uint flags,
279                                 Prelocking_strategy *prelocking_strategy);
280 bool open_tables_for_query(THD *thd, TABLE_LIST *tables, uint flags);
281 bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
282 void free_io_cache(TABLE *entry);
283 void intern_close_table(TABLE *entry);
284 void close_thread_table(THD *thd, TABLE **table_ptr);
285 bool close_temporary_tables(THD *thd);
286 TABLE_LIST *unique_table(const TABLE_LIST *table, TABLE_LIST *table_list,
287                          bool check_alias);
288 void drop_temporary_table(THD *thd, TABLE_LIST *table_list);
289 void close_temporary_table(THD *thd, TABLE *table, bool free_share,
290                            bool delete_table);
291 void close_temporary(THD *thd, TABLE *table, bool free_share,
292                      bool delete_table);
293 bool rename_temporary_table(THD *thd, TABLE *table, const char *new_db,
294                             const char *table_name);
295 bool open_temporary_tables(THD *thd, TABLE_LIST *tl_list);
296 bool open_temporary_table(THD *thd, TABLE_LIST *tl);
297 
298 /* Functions to work with system tables. */
299 bool open_trans_system_tables_for_read(THD *thd, TABLE_LIST *table_list);
300 void close_trans_system_tables(THD *thd);
301 void close_mysql_tables(THD *thd);
302 TABLE *open_log_table(THD *thd, TABLE_LIST *one_table,
303                       Open_tables_backup *backup);
304 void close_log_table(THD *thd, Open_tables_backup *backup);
305 
306 bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool wait_for_refresh,
307                          ulong timeout);
308 
309 /**
310   Close all open instances of the table but keep the MDL lock.
311 
312   Works both under LOCK TABLES and in the normal mode.
313   Removes all closed instances of the table from the table cache.
314 
315   @param  thd         Thread context.
316   @param  share       Table share, but is just a handy way to
317                       access the table cache key.
318   @param  remove_from_locked_tables
319                       True if the table is being dropped.
320                       In that case the documented behaviour is to
321                       implicitly remove the table from LOCK TABLES list.
322   @param  skip_table  TABLE instance that should be kept open.
323 
324   @pre Must be called with an X MDL lock on the table.
325 */
326 void close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
327                                bool remove_from_locked_tables,
328                                TABLE *skip_table);
329 
330 /**
331   Close all open instances of the table but keep the MDL lock.
332 
333   Works both under LOCK TABLES and in the normal mode.
334   Removes all closed instances of the table from the table cache.
335 
336   @param  thd         Thread context.
337   @param  db          Database name.
338   @param  table_name  Table name.
339   @param  remove_from_locked_tables
340                       True if the table is being dropped.
341                       In that case the documented behaviour is to
342                       implicitly remove the table from LOCK TABLES list.
343 
344   @pre Must be called with an X MDL lock on the table.
345 */
346 void close_all_tables_for_name(THD *thd, const char *db, const char *table_name,
347                                bool remove_from_locked_tables);
348 
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, bool has_lock);
352 void tdc_flush_unused_tables();
353 TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
354                                   const char *table_name, bool no_error);
355 void mark_tmp_table_for_reuse(TABLE *table);
356 
357 extern Item **not_found_item;
358 extern Field *not_found_field;
359 extern Field *view_ref_found;
360 
361 struct Table_share_deleter {
362   void operator()(TABLE_SHARE *share) const;
363 };
364 extern malloc_unordered_map<std::string,
365                             std::unique_ptr<TABLE_SHARE, Table_share_deleter>>
366     *table_def_cache;
367 
368 TABLE_LIST *find_table_in_global_list(TABLE_LIST *table, const char *db_name,
369                                       const char *table_name);
370 
371 /**
372   An abstract class for a strategy specifying how the prelocking
373   algorithm should extend the prelocking set while processing
374   already existing elements in the set.
375 */
376 
377 class Prelocking_strategy {
378  public:
~Prelocking_strategy()379   virtual ~Prelocking_strategy() {}
380 
381   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
382                               Sroutine_hash_entry *rt, sp_head *sp,
383                               bool *need_prelocking) = 0;
384   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
385                             TABLE_LIST *table_list, bool *need_prelocking) = 0;
386   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
387                            TABLE_LIST *table_list, bool *need_prelocking) = 0;
388 };
389 
390 /**
391   A Strategy for prelocking algorithm suitable for DML statements.
392 
393   Ensures that all tables used by all statement's SF/SP/triggers and
394   required for foreign key checks are prelocked and SF/SPs used are
395   cached.
396 */
397 
398 class DML_prelocking_strategy : public Prelocking_strategy {
399  public:
400   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
401                               Sroutine_hash_entry *rt, sp_head *sp,
402                               bool *need_prelocking);
403   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
404                             TABLE_LIST *table_list, bool *need_prelocking);
405   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
406                            TABLE_LIST *table_list, bool *need_prelocking);
407 };
408 
409 /**
410   A strategy for prelocking algorithm to be used for LOCK TABLES
411   statement.
412 */
413 
414 class Lock_tables_prelocking_strategy : public DML_prelocking_strategy {
415   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
416                             TABLE_LIST *table_list, bool *need_prelocking);
417 };
418 
419 /**
420   Strategy for prelocking algorithm to be used for ALTER TABLE statements.
421 
422   Unlike DML or LOCK TABLES strategy, it doesn't
423   prelock triggers, views or stored routines, since they are not
424   used during ALTER.
425 */
426 
427 class Alter_table_prelocking_strategy : public Prelocking_strategy {
428  public:
429   virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
430                               Sroutine_hash_entry *rt, sp_head *sp,
431                               bool *need_prelocking);
432   virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
433                             TABLE_LIST *table_list, bool *need_prelocking);
434   virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
435                            TABLE_LIST *table_list, bool *need_prelocking);
436 };
437 
open_tables(THD * thd,TABLE_LIST ** tables,uint * counter,uint flags)438 inline bool open_tables(THD *thd, TABLE_LIST **tables, uint *counter,
439                         uint flags) {
440   DML_prelocking_strategy prelocking_strategy;
441 
442   return open_tables(thd, tables, counter, flags, &prelocking_strategy);
443 }
444 
open_n_lock_single_table(THD * thd,TABLE_LIST * table_l,thr_lock_type lock_type,uint flags)445 inline TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
446                                        thr_lock_type lock_type, uint flags) {
447   DML_prelocking_strategy prelocking_strategy;
448 
449   return open_n_lock_single_table(thd, table_l, lock_type, flags,
450                                   &prelocking_strategy);
451 }
452 
453 // open_and_lock_tables with default prelocking strategy
open_and_lock_tables(THD * thd,TABLE_LIST * tables,uint flags)454 inline bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, uint flags) {
455   DML_prelocking_strategy prelocking_strategy;
456 
457   return open_and_lock_tables(thd, tables, flags, &prelocking_strategy);
458 }
459 
460 /**
461   Get an existing table definition from the table definition cache.
462 
463   Search the table definition cache for a share with the given key.
464   If the share exists or if it is in the process of being opened
465   by another thread (m_open_in_progress flag is true) return share.
466   Do not wait for share opening to finish.
467 
468   @param db         database name.
469   @param table_name table name.
470 
471   @retval nulltpr      a share for the table does not exist in the cache
472   @retval != nulltpr   pointer to existing share in the cache
473 */
474 
475 TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name);
476 
477 /**
478   A context of open_tables() function, used to recover
479   from a failed open_table() or open_routine() attempt.
480 */
481 
482 class Open_table_context {
483  public:
484   enum enum_open_table_action {
485     OT_NO_ACTION = 0,
486     OT_BACKOFF_AND_RETRY,
487     OT_REOPEN_TABLES,
488     OT_DISCOVER,
489     OT_REPAIR,
490     OT_FIX_ROW_TYPE
491   };
492   Open_table_context(THD *thd, uint flags);
493 
494   bool recover_from_failed_open();
495   bool request_backoff_action(enum_open_table_action action_arg,
496                               TABLE_LIST *table);
497 
can_recover_from_failed_open()498   bool can_recover_from_failed_open() const { return m_action != OT_NO_ACTION; }
499 
500   /**
501     When doing a back-off, we close all tables acquired by this
502     statement.  Return an MDL savepoint taken at the beginning of
503     the statement, so that we can rollback to it before waiting on
504     locks.
505   */
start_of_statement_svp()506   const MDL_savepoint &start_of_statement_svp() const {
507     return m_start_of_statement_svp;
508   }
509 
get_timeout()510   inline ulong get_timeout() const { return m_timeout; }
511 
get_flags()512   uint get_flags() const { return m_flags; }
513 
514   /**
515     Set flag indicating that we have already acquired metadata lock
516     protecting this statement against GRL while opening tables.
517   */
set_has_protection_against_grl()518   void set_has_protection_against_grl() { m_has_protection_against_grl = true; }
519 
has_protection_against_grl()520   bool has_protection_against_grl() const {
521     return m_has_protection_against_grl;
522   }
523 
can_back_off()524   bool can_back_off() const { return !m_has_locks; }
525 
526  private:
527   /* THD for which tables are opened. */
528   THD *m_thd;
529   /**
530     For OT_DISCOVER, OT_REPAIR and OT_FIX_ROW_TYPE actions, the table list
531     element for the table which definition should be re-discovered/updated
532     or which should be repaired.
533   */
534   TABLE_LIST *m_failed_table;
535   MDL_savepoint m_start_of_statement_svp;
536   /**
537     Lock timeout in seconds. Initialized to LONG_TIMEOUT when opening system
538     tables or to the "lock_wait_timeout" system variable for regular tables.
539   */
540   ulong m_timeout;
541   /* open_table() flags. */
542   uint m_flags;
543   /** Back off action. */
544   enum enum_open_table_action m_action;
545   /**
546     Whether we had any locks when this context was created.
547     If we did, they are from the previous statement of a transaction,
548     and we can't safely do back-off (and release them).
549   */
550   bool m_has_locks;
551   /**
552     Indicates that in the process of opening tables we have acquired
553     protection against global read lock.
554   */
555   bool m_has_protection_against_grl;
556 };
557 
558 #endif /* SQL_BASE_INCLUDED */
559