MySQL  8.0.18
Source Code Documentation
system_registry.h
Go to the documentation of this file.
1 /* Copyright (c) 2014, 2018, 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 DD__SYSTEM_REGISTRY_INCLUDED
24 #define DD__SYSTEM_REGISTRY_INCLUDED
25 
26 #include <stdio.h>
27 #include <map>
28 #include <new>
29 #include <string>
30 #include <utility>
31 #include <vector>
32 
33 #include "my_dbug.h"
34 #include "mysqld_error.h" // ER_NO_SYSTEM_TABLE_...
35 #include "sql/dd/string_type.h" // dd::String_type
38 #include "sql/plugin_table.h"
39 
40 namespace dd {
41 
42 class Object_table;
43 
44 /**
45  Class to wrap an entity object.
46 
47  The Entity_element instances are intended used in registries to support
48  classification of meta data. The Entity_element template points to an
49  instance of some type, and also has a property member that is associated
50  with the entity, as well as a key with which the object is associated.
51 
52  @note The entity object ownership is decided by the relevant template
53  parameter, see below.
54 
55  @tparam K A key type, e.g. a pair of strings.
56  @tparam T An entity type, e.g. an Object_table instance.
57  @tparam P A property type, e.g. an enumeration.
58  @tparam F Function to map from property to name.
59  @tparam D Boolean to decide ownership of wrapped object.
60 */
61 
62 template <typename K, typename T, typename P, const char *F(P), bool D>
64  private:
65  const K m_key; //< The key associated with the entity object.
66  const T *m_entity; //< Entity object pointer, e.g. an Object_table instance.
67  const P m_property; //< Property of some kind, e.g. an enumeration.
68 
69  public:
70  Entity_element(const K &key, const T *entity, const P property)
72 
74  // Delete the wrapped object depending on the template parameter.
75  if (D) delete m_entity;
76  }
77 
78  const K &key() const { return m_key; }
79 
80  const T *entity() const { return m_entity; }
81 
82  const P property() const { return m_property; }
83 
84  const P *property_ptr() const { return &m_property; }
85 
86 #ifndef DBUG_OFF
87  void dump() const {
88  fprintf(stderr, "Key= '%s.%s', property= '%s'\n", m_key.first.c_str(),
89  m_key.second.c_str(), F(m_property));
90  }
91 #endif
92 };
93 
94 /**
95  Class to represent collections of meta data for entities.
96 
97  This class is used to represent relevant meta data and properties of
98  system related entities, e.g. all the dictionary tables. The meta data
99  is associated with a key instance, usually a std::pair containing the
100  schema- and entity names.
101 
102  The class supports adding and retrieving objects, as well as iteration
103  based on the order of inserts.
104 
105  @note There is no support for concurrency. We assume that the registry
106  is created and that the entities are inserted in a single threaded
107  situation, e.g. while the server is being started. Read only access
108  can happen from several threads simultaneously, though.
109 
110  @tparam K Key type.
111  @tparam T Entity type.
112  @tparam P Property type.
113  @tparam F Function to map from property to name.
114  @tparam D Boolean flag to decide whether the wrapped objects
115  are owned by the registry.
116 */
117 
118 template <typename K, typename T, typename P, const char *F(P), bool D>
120  private:
122  typedef std::vector<Entity_element_type *> Entity_list_type;
123  typedef std::map<K, Entity_element_type *> Entity_map_type;
124 
125  Entity_list_type m_entity_list; //< List for ordered access.
126  Entity_map_type m_entity_map; //< Map for direct key based lookup.
127 
128  public:
129  // Externally available iteration is based on the order of inserts.
130  typedef typename Entity_list_type::const_iterator Const_iterator;
131 
132  /**
133  Delete the heap memory owned by the entity registry.
134 
135  Only the wrapper elements are owned by the registry.
136  The std::vector and std::map are not allocated
137  dynamically, and their destructors are called implicitly
138  when this destructor is called.
139  */
140 
142  // Delete elements from the map. The objects that are wrapped
143  // will be handled by the wrapper destructor.
144  for (typename Entity_map_type::iterator it = m_entity_map.begin();
145  it != m_entity_map.end(); ++it)
146  delete it->second;
147  }
148 
149  /**
150  Add a new entity to the registry.
151 
152  This method will create a new key and a new entity wrapper element. The
153  wrapper will be added to the map, along with the key, and to the vector
154  to keep track of the order of inserts.
155 
156  @param schema_name Schema name used to construct the key.
157  @param entity_name Entity name used to construct the key.
158  @param property Property used to classify the entity.
159  @param entity Entity which is classified and registered.
160  */
161 
162  void add(const String_type &schema_name, const String_type &entity_name,
163  P property, T *entity) {
164  // Create a new key and make sure it does not already exist.
165  K key(schema_name, entity_name);
166  DBUG_ASSERT(m_entity_map.find(key) == m_entity_map.end());
167 
168  // Create a new entity wrapper element. The wrapper will be owned by the
169  // entity map and deleted along with it.
170  Entity_element_type *element =
171  new (std::nothrow) Entity_element_type(key, entity, property);
172 
173  // Add the key, value pair to the map.
174  m_entity_map.insert(typename Entity_map_type::value_type(key, element));
175 
176  // Add the entity to the ordered list too.
177  m_entity_list.push_back(element);
178  }
179 
180  /**
181  Find an element entity in the registry.
182 
183  This method creates a key based on the submitted parameters, and
184  looks up in the member map. If the key is found, the object pointed
185  to by the wrapper is returned, otherwise, nullptr is returned.
186 
187  @param schema_name Schema containing the entity searched for.
188  @param entity_name Name of the entity searched for.
189  @retval nullptr if not found, otherwise, the entity
190  object pointed to by the wrapper element.
191  */
192 
193  const T *find_entity(const String_type &schema_name,
194  const String_type &entity_name) const {
195  // Create a new key. This is only used for lookup, so it is allocated
196  // on the stack.
197  K key(schema_name, entity_name);
198 
199  // Lookup in the map based on the key.
200  typename Entity_map_type::const_iterator element_it =
201  m_entity_map.find(key);
202 
203  // Return nullptr if not found, otherwise, return a pointer to the entity.
204  if (element_it == m_entity_map.end()) return nullptr;
205 
206  return element_it->second->entity();
207  }
208 
209  /**
210  Find the property of an element in the registry.
211 
212  This method creates a key based on the submitted parameters, and
213  looks up in the member map. If the key is found, the property
214  associated with the key is returned, otherwise, nullptr is returned.
215 
216  @param schema_name Schema containing the entity searched for.
217  @param entity_name Name of the entity searched for.
218  @retval nullptr if not found, otherwise, the a pointer to
219  the property associated with the key.
220  */
221 
222  const P *find_property(const String_type &schema_name,
223  const String_type &entity_name) const {
224  // Create a new key. This is only used for lookup, so it is allocated
225  // on the stack.
226  K key(schema_name, entity_name);
227 
228  // Lookup in the map based on the key.
229  typename Entity_map_type::const_iterator element_it =
230  m_entity_map.find(key);
231 
232  // Return nullptr if not found, otherwise, return a pointer to the property.
233  if (element_it == m_entity_map.end()) return nullptr;
234 
235  return element_it->second->property_ptr();
236  }
237 
238  /**
239  Get the beginning of the vector of ordered inserts.
240 
241  @retval Iterator referring to the first element in the vector,
242  or end() if the vector is empty.
243  */
244 
245  Const_iterator begin() const { return m_entity_list.begin(); }
246 
247  /**
248  Get the first element with a certain property.
249 
250  This method retrieves the first element with a certain property, and
251  is used for iterating only over elements having this property.
252 
253  @param property Property that the element should have.
254  @retval Iterator referring to the first element in the vector
255  with the submitted property, or end().
256  */
257 
258  Const_iterator begin(P property) const {
259  Const_iterator it = begin();
260  while (it != end()) {
261  if ((*it)->property() == property) break;
262  ++it;
263  }
264 
265  return it;
266  }
267 
268  /**
269  Get the end of the vector of ordered inserts.
270 
271  @retval Iterator referring to the special element after the last "real"
272  element in the vector.
273  */
274 
275  Const_iterator end() const { return m_entity_list.end(); }
276 
277  /**
278  Get the next element in the list of ordered inserts.
279 
280  @param current The current iterator.
281  @retval Iterator referring to the next element in the vector.
282  */
283 
285  if (current == end()) return current;
286 
287  return ++current;
288  }
289 
290  /**
291  Get the next element in the list of ordered inserts.
292 
293  This method retrieves the next element with a certain property, and
294  is used for iterating only over elements having this property.
295 
296  @param current The current iterator.
297  @param property Property that the next element should have.
298  @retval Iterator referring to the next element in the vector
299  with the submitted property.
300  */
301 
302  Const_iterator next(Const_iterator current, P property) const {
303  if (current == end()) return current;
304 
305  while (++current != end())
306  if ((*current)->property() == property) break;
307 
308  return current;
309  }
310 
311 #ifndef DBUG_OFF
312  void dump() const {
313  // List the entities in the order they were inserted.
314  for (Const_iterator it = begin(); it != end(); ++it) (*it)->dump();
315  }
316 #endif
317 };
318 
319 /**
320  Class used to represent the dictionary tables.
321 
322  This class is a singleton used to represent meta data of the dictionary
323  tables, i.e., the tables that store meta data about dictionary entities.
324  The meta data collected here are the Object_table instances, which are
325  used to e.g. get hold of the definition of the table.
326 
327  The singleton contains an instance of the Entity_registry class, and
328  has methods that mostly delegate to this instance.
329  */
330 
332  public:
333  /*
334  Classification of tables based on WL#6391.
335 
336  - An INERT table can never change.
337  - The dd::Table objects representing the CORE tables must be present
338  to handle a cache miss for an arbitrary table.
339  - The dd::Table objects representing the SECOND order tables can be
340  fetched from the dd tables as long as the core table objects are
341  present.
342  - The DDSE tables are not needed by the data dictionary, but the
343  server manages these based on requests from the DD storage engine.
344  - The PFS tables are not needed by the data dictionary, but the
345  server manages these based on requests from the performance schema.
346  */
347  enum class Types {
348  INERT,
349  CORE,
350  SECOND,
351  DDSE_PRIVATE,
353  PFS,
354  SYSTEM
355  };
356 
357  // Map from system table type to string description, e.g. for debugging.
358  static const char *type_name(Types type) {
359  switch (type) {
360  case Types::INERT:
361  return "INERT";
362  case Types::CORE:
363  return "CORE";
364  case Types::SECOND:
365  return "SECOND";
366  case Types::DDSE_PRIVATE:
367  return "DDSE_PRIVATE";
369  return "DDSE_PROTECTED";
370  case Types::PFS:
371  return "PFS";
372  case Types::SYSTEM:
373  return "SYSTEM";
374  default:
375  return "";
376  }
377  }
378 
379  // Map from system table type to error code for localized error messages.
381  if (type == Types::INERT || type == Types::CORE || type == Types::SECOND)
382  return ER_NO_SYSTEM_TABLE_ACCESS_FOR_DICTIONARY_TABLE;
383 
386  return ER_NO_SYSTEM_TABLE_ACCESS_FOR_SYSTEM_TABLE;
387 
388  DBUG_ASSERT(false);
389  return ER_NO_SYSTEM_TABLE_ACCESS_FOR_TABLE;
390  }
391 
392  private:
393  // The actual registry is referred and delegated to rather than
394  // being inherited from.
396  const Object_table, Types, type_name, true>
399 
400  public:
401  // The ordered iterator type must be public.
403 
404  static System_tables *instance();
405 
406  // Add predefined system tables.
407  void add_inert_dd_tables();
409 
410  // Add a new system table by delegation to the wrapped registry.
411  void add(const String_type &schema_name, const String_type &table_name,
412  Types type, const Object_table *table) {
413  m_registry.add(schema_name, table_name, type, table);
414  }
415 
416  // Find a system table by delegation to the wrapped registry.
417  const Object_table *find_table(const String_type &schema_name,
418  const String_type &table_name) const {
419  return m_registry.find_entity(schema_name, table_name);
420  }
421 
422  // Find a system table type by delegation to the wrapped registry.
423  const Types *find_type(const String_type &schema_name,
424  const String_type &table_name) const {
425  return m_registry.find_property(schema_name, table_name);
426  }
427 
428  Const_iterator begin() const { return m_registry.begin(); }
429 
431 
432  Const_iterator end() const { return m_registry.end(); }
433 
435  return m_registry.next(current, type);
436  }
437 
438 #ifndef DBUG_OFF
439  void dump() const { m_registry.dump(); }
440 #endif
441 };
442 
443 /**
444  Class used to represent the system views.
445 
446  This class is a singleton used to represent meta data of the system
447  views, i.e., the views that are available through the information schema.
448 
449  @note The registry currently only stores the view names and their
450  (dummy) classification.
451 
452  The singleton contains an instance of the Entity_registry class, and
453  has methods that mostly delegate to this instance.
454  */
455 
457  public:
458  // Classification of system views.
459  enum class Types {
461  };
462 
463  // Map from system view type to string description, e.g. for debugging.
464  static const char *type_name(Types type) {
465  switch (type) {
467  return "INFORMATION_SCHEMA";
468  default:
469  return "";
470  }
471  }
472 
473  private:
474  // The actual registry is referred and delegated to rather than
475  // being inherited from.
478  true>
481 
482  public:
483  // The ordered iterator type must be public.
485 
486  static System_views *instance();
487 
488  // Add predefined system views.
489  void init();
490 
491  // Add a new system view by delegation to the wrapped registry.
492  void add(const String_type &schema_name, const String_type &view_name,
493  Types type, const system_views::System_view *view) {
494  m_registry.add(schema_name, view_name, type, view);
495  }
496 
497  // Find a system view by delegation to the wrapped registry.
498  const system_views::System_view *find(const String_type &schema_name,
499  const String_type &view_name) const {
500  return m_registry.find_entity(schema_name, view_name);
501  }
502 
503  Const_iterator begin() const { return m_registry.begin(); }
504 
506 
507  Const_iterator end() const { return m_registry.end(); }
508 
510  return m_registry.next(current, type);
511  }
512 
513 #ifndef DBUG_OFF
514  void dump() const { m_registry.dump(); }
515 #endif
516 };
517 
518 /**
519  Class used to represent the system tablespaces.
520 
521  This class is a singleton used to represent meta data of the system
522  tablespaces, i.e., the tablespaces that are predefined in the DDSE, or
523  needed by the SQL layer.
524 
525  The singleton contains an instance of the Entity_registry class, and
526  has methods that mostly delegate to this instance.
527 */
528 
530  public:
531  // Classification of system tablespaces.
532  enum class Types {
533  DD, // For storing the DD tables.
534  PREDEFINED_DDSE // Needed by the DDSE.
535  };
536 
537  // Map from system tablespace type to string description, e.g. for debugging.
538  static const char *type_name(Types type) {
539  switch (type) {
540  case Types::DD:
541  return "DD";
543  return "PREDEFINED_DDSE";
544  default:
545  return "";
546  }
547  }
548 
549  private:
550  // The actual registry is referred and delegated to rather than
551  // being inherited from.
553  const Plugin_tablespace, Types, type_name, false>
556 
557  public:
558  // The ordered iterator type must be public.
560 
561  static System_tablespaces *instance();
562 
563  // Add a new system tablespace by delegation to the wrapped registry.
564  void add(const String_type &tablespace_name, Types type,
565  const Plugin_tablespace *space) {
566  m_registry.add("", tablespace_name, type, space);
567  }
568 
569  // Find a system tablespace by delegation to the wrapped registry.
570  const Plugin_tablespace *find(const String_type &tablespace_name) const {
571  return m_registry.find_entity("", tablespace_name);
572  }
573 
574  Const_iterator begin() const { return m_registry.begin(); }
575 
577 
578  Const_iterator end() const { return m_registry.end(); }
579 
581  return m_registry.next(current, type);
582  }
583 
584 #ifndef DBUG_OFF
585  void dump() const { m_registry.dump(); }
586 #endif
587 };
588 } // namespace dd
589 
590 #endif // DD__SYSTEM_REGISTRY_INCLUDED
static System_tables * instance()
Definition: system_registry.cc:118
const Types * find_type(const String_type &schema_name, const String_type &table_name) const
Definition: system_registry.h:423
Class used to represent the system tablespaces.
Definition: system_registry.h:529
Const_iterator end() const
Get the end of the vector of ordered inserts.
Definition: system_registry.h:275
Const_iterator begin(P property) const
Get the first element with a certain property.
Definition: system_registry.h:258
Entity_registry< std::pair< const String_type, const String_type >, const Object_table, Types, type_name, true > System_table_registry_type
Definition: system_registry.h:397
Const_iterator begin(Types type) const
Definition: system_registry.h:505
Const_iterator end() const
Definition: system_registry.h:432
static System_tablespaces * instance()
Definition: system_registry.cc:128
Entity_element(const K &key, const T *entity, const P property)
Definition: system_registry.h:70
void dump() const
Definition: system_registry.h:585
Char_string_template< String_type_allocator > String_type
Definition: string_type.h:50
Entity_map_type m_entity_map
Definition: system_registry.h:126
System_tablespace_registry_type m_registry
Definition: system_registry.h:555
const Plugin_tablespace * find(const String_type &tablespace_name) const
Definition: system_registry.h:570
Const_iterator next(Const_iterator current, P property) const
Get the next element in the list of ordered inserts.
Definition: system_registry.h:302
static const char * type_name(Types type)
Definition: system_registry.h:358
void dump() const
Definition: system_registry.h:514
static const char * type_name(Types type)
Definition: system_registry.h:464
void dump() const
Definition: system_registry.h:439
Const_iterator begin(Types type) const
Definition: system_registry.h:576
System_view_registry_type m_registry
Definition: system_registry.h:480
~Entity_registry()
Delete the heap memory owned by the entity registry.
Definition: system_registry.h:141
void add(const String_type &schema_name, const String_type &view_name, Types type, const system_views::System_view *view)
Definition: system_registry.h:492
Const_iterator begin() const
Get the beginning of the vector of ordered inserts.
Definition: system_registry.h:245
Class used to represent the dictionary tables.
Definition: system_registry.h:331
Const_iterator next(Const_iterator current) const
Get the next element in the list of ordered inserts.
Definition: system_registry.h:284
Const_iterator next(Const_iterator current, Types type) const
Definition: system_registry.h:580
Entity_registry< std::pair< const String_type, const String_type >, const system_views::System_view, Types, type_name, true > System_view_registry_type
Definition: system_registry.h:479
#define DBUG_ASSERT(A)
Definition: my_dbug.h:197
static int type_name_error_code(Types type)
Definition: system_registry.h:380
void add(const String_type &tablespace_name, Types type, const Plugin_tablespace *space)
Definition: system_registry.h:564
uint16_t value_type
Definition: vt100.h:182
void add_remaining_dd_tables()
Definition: system_registry.cc:151
Entity_list_type::const_iterator Const_iterator
Definition: system_registry.h:130
const T * find_entity(const String_type &schema_name, const String_type &entity_name) const
Find an element entity in the registry.
Definition: system_registry.h:193
#define P
Definition: dtoa.cc:629
std::map< K, Entity_element_type * > Entity_map_type
Definition: system_registry.h:123
Types
Definition: system_registry.h:347
Const_iterator next(Const_iterator current, Types type) const
Definition: system_registry.h:434
Entity_element< K, T, P, F, D > Entity_element_type
Definition: system_registry.h:121
const T * entity() const
Definition: system_registry.h:80
Entity_list_type m_entity_list
Definition: system_registry.h:125
void dump() const
Definition: system_registry.h:312
std::vector< Entity_element_type * > Entity_list_type
Definition: system_registry.h:122
void init()
Definition: system_registry.cc:234
const K m_key
Definition: system_registry.h:65
Const_iterator next(Const_iterator current, Types type) const
Definition: system_registry.h:509
const P * find_property(const String_type &schema_name, const String_type &entity_name) const
Find the property of an element in the registry.
Definition: system_registry.h:222
const P * property_ptr() const
Definition: system_registry.h:84
void add_inert_dd_tables()
Definition: system_registry.cc:137
Const_iterator end() const
Definition: system_registry.h:578
This class represents base class for all INFORMATION_SCHEMA system views defined in sql/dd/impl/syste...
Definition: system_view.h:38
const system_views::System_view * find(const String_type &schema_name, const String_type &view_name) const
Definition: system_registry.h:498
Types
Definition: system_registry.h:532
System_table_registry_type::Const_iterator Const_iterator
Definition: system_registry.h:402
Const_iterator begin() const
Definition: system_registry.h:574
static const char * key
Definition: suite_stubs.c:14
const P property() const
Definition: system_registry.h:82
const T * m_entity
Definition: system_registry.h:66
static const char * type_name(Types type)
Definition: system_registry.h:538
System_view_registry_type::Const_iterator Const_iterator
Definition: system_registry.h:484
void add(const String_type &schema_name, const String_type &entity_name, P property, T *entity)
Add a new entity to the registry.
Definition: system_registry.h:162
int type
Definition: http_common.h:411
Class to wrap an entity object.
Definition: system_registry.h:63
~Entity_element()
Definition: system_registry.h:73
This class represents all data dictionary table like mysql.tables, mysql.columns and more...
Definition: object_table.h:71
Class used to represent the system views.
Definition: system_registry.h:456
static System_views * instance()
Definition: system_registry.cc:123
System_table_registry_type m_registry
Definition: system_registry.h:398
const K & key() const
Definition: system_registry.h:78
Const_iterator end() const
Definition: system_registry.h:507
void dump() const
Definition: system_registry.h:87
Const_iterator begin(Types type) const
Definition: system_registry.h:430
Const_iterator begin() const
Definition: system_registry.h:503
The version of the current data dictionary table definitions.
Definition: dictionary_client.h:39
Types
Definition: system_registry.h:459
Class to represent collections of meta data for entities.
Definition: system_registry.h:119
const P m_property
Definition: system_registry.h:67
const Object_table * find_table(const String_type &schema_name, const String_type &table_name) const
Definition: system_registry.h:417
Const_iterator begin() const
Definition: system_registry.h:428
Entity_registry< std::pair< const String_type, const String_type >, const Plugin_tablespace, Types, type_name, false > System_tablespace_registry_type
Definition: system_registry.h:554
Class to hold information regarding a predefined tablespace created by a storage engine.
Definition: plugin_table.h:94
System_tablespace_registry_type::Const_iterator Const_iterator
Definition: system_registry.h:559
void add(const String_type &schema_name, const String_type &table_name, Types type, const Object_table *table)
Definition: system_registry.h:411
const char * table_name
Definition: rules_table_service.cc:55