1 /* Copyright (c) 2014, 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 DD__OBJECT_KEYS_INCLUDED
24 #define DD__OBJECT_KEYS_INCLUDED
25 
26 #include <stddef.h>
27 #include <string.h>
28 #include <sys/types.h>
29 
30 #include "m_ctype.h"
31 #include "my_inttypes.h"
32 #include "sql/dd/impl/object_key.h"  // dd::Object_key
33 #include "sql/dd/object_id.h"        // dd::Object_id
34 #include "sql/dd/string_type.h"
35 #include "template_utils.h"
36 
37 namespace dd {
38 
39 ///////////////////////////////////////////////////////////////////////////
40 
41 class Raw_table;
42 struct Raw_key;
43 
44 ///////////////////////////////////////////////////////////////////////////
45 
46 // NOTE: the current naming convention is as follows:
47 // - use '_key' suffix to name keys identifying 0 or 1 row;
48 // - use '_range_key' suffix to name keys identifying 0 or N rows.
49 
50 ///////////////////////////////////////////////////////////////////////////
51 
52 // Key type to be used for keys that are not supported by an object type.
53 class Void_key : public Object_key {
54  public:
Void_key()55   Void_key() {}
56 
57  public:
58   /* purecov: begin inspected */
create_access_key(Raw_table *)59   virtual Raw_key *create_access_key(Raw_table *) const { return nullptr; }
60   /* purecov: end */
61 
62   /* purecov: begin inspected */
str()63   virtual String_type str() const { return ""; }
64   /* purecov: end */
65 
66   // We need a comparison operator since the type will be used
67   // as a template type argument.
68   /* purecov: begin inspected */
69   bool operator<(const Void_key &rhs) const { return this < &rhs; }
70   /* purecov: end */
71 };
72 
73 ///////////////////////////////////////////////////////////////////////////
74 
75 // Entity_object-id primary key for global objects.
76 class Primary_id_key : public Object_key {
77  public:
Primary_id_key()78   Primary_id_key() {}
79 
Primary_id_key(Object_id object_id)80   Primary_id_key(Object_id object_id) : m_object_id(object_id) {}
81 
82   // Update a preallocated instance.
update(Object_id object_id)83   void update(Object_id object_id) { m_object_id = object_id; }
84 
85  public:
86   virtual Raw_key *create_access_key(Raw_table *db_table) const;
87 
88   virtual String_type str() const;
89 
90   bool operator<(const Primary_id_key &rhs) const {
91     return m_object_id < rhs.m_object_id;
92   }
93 
94  private:
95   Object_id m_object_id;
96 };
97 
98 ///////////////////////////////////////////////////////////////////////////
99 
100 // Entity_object-id partial key for looking for containing objects.
101 class Parent_id_range_key : public Object_key {
102  public:
Parent_id_range_key(int id_index_no,int id_column_no,Object_id object_id)103   Parent_id_range_key(int id_index_no, int id_column_no, Object_id object_id)
104       : m_id_index_no(id_index_no),
105         m_id_column_no(id_column_no),
106         m_object_id(object_id) {}
107 
108  public:
109   virtual Raw_key *create_access_key(Raw_table *db_table) const;
110 
111   virtual String_type str() const;
112 
113  private:
114   int m_id_index_no;
115   int m_id_column_no;
116   Object_id m_object_id;
117 };
118 
119 ///////////////////////////////////////////////////////////////////////////
120 
121 // Entity_object-name key for global objects.
122 class Global_name_key : public Object_key {
123  public:
Global_name_key()124   Global_name_key() {}
125 
Global_name_key(int name_column_no,const String_type & object_name,const CHARSET_INFO * cs)126   Global_name_key(int name_column_no, const String_type &object_name,
127                   const CHARSET_INFO *cs)
128       : m_name_column_no(name_column_no),
129         m_object_name(object_name),
130         m_cs(cs) {}
131 
132   // Update a preallocated instance.
update(int name_column_no,const String_type & object_name,const CHARSET_INFO * cs)133   void update(int name_column_no, const String_type &object_name,
134               const CHARSET_INFO *cs) {
135     m_name_column_no = name_column_no;
136     m_object_name = object_name;
137     m_cs = cs;
138   }
139 
140  public:
141   virtual Raw_key *create_access_key(Raw_table *db_table) const;
142 
143   /* purecov: begin inspected */
str()144   virtual String_type str() const { return m_object_name; }
145   /* purecov: end */
146 
147   bool operator<(const Global_name_key &rhs) const {
148     return (my_strnncoll(m_cs,
149                          pointer_cast<const uchar *>(m_object_name.c_str()),
150                          m_object_name.length(),
151                          pointer_cast<const uchar *>(rhs.m_object_name.c_str()),
152                          rhs.m_object_name.length()) < 0);
153   }
154 
155  private:
156   int m_name_column_no;
157   String_type m_object_name;
158   // Collation used for the name in the table.
159   const CHARSET_INFO *m_cs;
160 };
161 
162 ///////////////////////////////////////////////////////////////////////////
163 
164 // Entity_object-name key for objects which are identified within a container.
165 class Item_name_key : public Object_key {
166  public:
Item_name_key()167   Item_name_key() {}
168 
Item_name_key(int container_id_column_no,Object_id container_id,int name_column_no,const String_type & object_name,const CHARSET_INFO * cs)169   Item_name_key(int container_id_column_no, Object_id container_id,
170                 int name_column_no, const String_type &object_name,
171                 const CHARSET_INFO *cs)
172       : m_container_id_column_no(container_id_column_no),
173         m_name_column_no(name_column_no),
174         m_container_id(container_id),
175         m_object_name(object_name),
176         m_cs(cs) {}
177 
178   // Update a preallocated instance.
update(int container_id_column_no,Object_id container_id,int name_column_no,const String_type & object_name,const CHARSET_INFO * cs)179   void update(int container_id_column_no, Object_id container_id,
180               int name_column_no, const String_type &object_name,
181               const CHARSET_INFO *cs) {
182     m_container_id_column_no = container_id_column_no;
183     m_name_column_no = name_column_no;
184     m_container_id = container_id;
185     m_object_name = object_name;
186     m_cs = cs;
187   }
188 
189  public:
190   virtual Raw_key *create_access_key(Raw_table *db_table) const;
191 
192   virtual String_type str() const;
193 
194   bool operator<(const Item_name_key &rhs) const {
195     if (m_container_id != rhs.m_container_id)
196       return (m_container_id < rhs.m_container_id);
197 
198     return (my_strnncoll(m_cs,
199                          pointer_cast<const uchar *>(m_object_name.c_str()),
200                          m_object_name.length(),
201                          pointer_cast<const uchar *>(rhs.m_object_name.c_str()),
202                          rhs.m_object_name.length()) < 0);
203   }
204 
205  private:
206   int m_container_id_column_no;
207   int m_name_column_no;
208 
209   Object_id m_container_id;
210   String_type m_object_name;
211   // Collation used for the name in the table.
212   const CHARSET_INFO *m_cs;
213 };
214 
215 ///////////////////////////////////////////////////////////////////////////
216 
217 // TODO: find a better name.
218 class Se_private_id_key : public Object_key {
219  public:
Se_private_id_key()220   Se_private_id_key() {}
221 
222   /* purecov: begin deadcode */
Se_private_id_key(int index_no,int engine_column_no,const String_type & engine,int private_id_column_no,Object_id private_id)223   Se_private_id_key(int index_no, int engine_column_no,
224                     const String_type &engine, int private_id_column_no,
225                     Object_id private_id)
226       : m_index_no(index_no),
227         m_engine_column_no(engine_column_no),
228         m_engine(engine),
229         m_private_id_column_no(private_id_column_no),
230         m_private_id(private_id) {}
231   /* purecov: end */
232 
233   // Update a preallocated instance.
update(int index_no,int engine_column_no,const String_type & engine,int private_id_column_no,Object_id private_id)234   void update(int index_no, int engine_column_no, const String_type &engine,
235               int private_id_column_no, Object_id private_id) {
236     m_index_no = index_no;
237     m_engine_column_no = engine_column_no;
238     m_engine = engine;
239     m_private_id_column_no = private_id_column_no;
240     m_private_id = private_id;
241   }
242 
243  public:
244   virtual Raw_key *create_access_key(Raw_table *db_table) const;
245 
246   virtual String_type str() const;
247 
248   bool operator<(const Se_private_id_key &rhs) const {
249     return m_private_id < rhs.m_private_id
250                ? true
251                : rhs.m_private_id < m_private_id ? false
252                                                  : m_engine < rhs.m_engine;
253   }
254 
255  private:
256   int m_index_no;
257 
258   int m_engine_column_no;
259   String_type m_engine;
260 
261   int m_private_id_column_no;
262   Object_id m_private_id;
263 };
264 
265 ///////////////////////////////////////////////////////////////////////////
266 
267 class Composite_pk : public Object_key {
268  public:
Composite_pk(int index_no,uint first_column_no,ulonglong first_id,uint second_column_no,ulonglong second_id)269   Composite_pk(int index_no, uint first_column_no, ulonglong first_id,
270                uint second_column_no, ulonglong second_id)
271       : m_index_no(index_no),
272         m_first_column_no(first_column_no),
273         m_first_id(first_id),
274         m_second_column_no(second_column_no),
275         m_second_id(second_id) {}
276 
277  public:
278   virtual Raw_key *create_access_key(Raw_table *db_table) const;
279 
280   virtual String_type str() const;
281 
282  private:
283   int m_index_no;
284 
285   int m_first_column_no;
286   ulonglong m_first_id;
287 
288   int m_second_column_no;
289   ulonglong m_second_id;
290 };
291 
292 ///////////////////////////////////////////////////////////////////////////
293 
294 class Composite_char_key : public Object_key {
295  public:
Composite_char_key(int index_no,uint first_column_no,const String_type & first_name,uint second_column_no,const String_type & second_name)296   Composite_char_key(int index_no, uint first_column_no,
297                      const String_type &first_name, uint second_column_no,
298                      const String_type &second_name)
299       : m_index_no(index_no),
300         m_first_column_no(first_column_no),
301         m_first_name(first_name),
302         m_second_column_no(second_column_no),
303         m_second_name(second_name) {}
304 
305  public:
306   virtual Raw_key *create_access_key(Raw_table *db_table) const;
307 
308   virtual String_type str() const;
309 
310  private:
311   int m_index_no;
312 
313   int m_first_column_no;
314   String_type m_first_name;
315 
316   int m_second_column_no;
317   String_type m_second_name;
318 };
319 
320 ///////////////////////////////////////////////////////////////////////////
321 
322 class Composite_4char_key : public Object_key {
323  public:
Composite_4char_key(int index_no,uint first_column_no,const String_type & first_name,uint second_column_no,const String_type & second_name,uint third_column_no,const String_type & third_name,uint fourth_column_no,const String_type & fourth_name)324   Composite_4char_key(int index_no, uint first_column_no,
325                       const String_type &first_name, uint second_column_no,
326                       const String_type &second_name, uint third_column_no,
327                       const String_type &third_name, uint fourth_column_no,
328                       const String_type &fourth_name)
329       : m_index_no(index_no),
330         m_first_column_no(first_column_no),
331         m_first_name(first_name),
332         m_second_column_no(second_column_no),
333         m_second_name(second_name),
334         m_third_column_no(third_column_no),
335         m_third_name(third_name),
336         m_fourth_column_no(fourth_column_no),
337         m_fourth_name(fourth_name) {}
338 
339  public:
340   virtual Raw_key *create_access_key(Raw_table *db_table) const;
341 
342   virtual String_type str() const;
343 
344  private:
345   int m_index_no;
346 
347   int m_first_column_no;
348   String_type m_first_name;
349 
350   int m_second_column_no;
351   String_type m_second_name;
352 
353   int m_third_column_no;
354   String_type m_third_name;
355 
356   int m_fourth_column_no;
357   String_type m_fourth_name;
358 };
359 
360 ///////////////////////////////////////////////////////////////////////////
361 
362 class Composite_obj_id_3char_key : public Object_key {
363  public:
Composite_obj_id_3char_key(int index_no,uint id_column_no,Object_id id,uint first_column_no,const String_type & first_name,uint second_column_no,const String_type & second_name,uint third_column_no,const String_type & third_name)364   Composite_obj_id_3char_key(int index_no, uint id_column_no, Object_id id,
365                              uint first_column_no,
366                              const String_type &first_name,
367                              uint second_column_no,
368                              const String_type &second_name,
369                              uint third_column_no,
370                              const String_type &third_name)
371       : m_index_no(index_no),
372         m_id_column_no(id_column_no),
373         m_id(id),
374         m_first_column_no(first_column_no),
375         m_first_name(first_name),
376         m_second_column_no(second_column_no),
377         m_second_name(second_name),
378         m_third_column_no(third_column_no),
379         m_third_name(third_name) {}
380 
381  public:
382   virtual Raw_key *create_access_key(Raw_table *db_table) const;
383 
384   virtual String_type str() const;
385 
386  private:
387   int m_index_no;
388 
389   int m_id_column_no;
390   Object_id m_id;
391 
392   int m_first_column_no;
393   String_type m_first_name;
394 
395   int m_second_column_no;
396   String_type m_second_name;
397 
398   int m_third_column_no;
399   String_type m_third_name;
400 };
401 
402 ///////////////////////////////////////////////////////////////////////////
403 
404 // Range key to find index statistics entries by table name.
405 // in mysql.index_stats.
406 class Index_stat_range_key : public Object_key {
407  public:
Index_stat_range_key(int index_no,int schema_name_column_no,const String_type & schema_name,int table_name_column_no,const String_type & table_name)408   Index_stat_range_key(int index_no, int schema_name_column_no,
409                        const String_type &schema_name, int table_name_column_no,
410                        const String_type &table_name)
411       : m_index_no(index_no),
412         m_schema_name_column_no(schema_name_column_no),
413         m_schema_name(schema_name),
414         m_table_name_column_no(table_name_column_no),
415         m_table_name(table_name) {}
416 
417  public:
418   virtual Raw_key *create_access_key(Raw_table *db_table) const;
419 
420   virtual String_type str() const;
421 
422  private:
423   int m_index_no;
424 
425   int m_schema_name_column_no;
426   String_type m_schema_name;
427 
428   int m_table_name_column_no;
429   String_type m_table_name;
430 };
431 
432 ///////////////////////////////////////////////////////////////////////////
433 
434 class Routine_name_key : public Object_key {
435  public:
Routine_name_key()436   Routine_name_key() {}
437 
Routine_name_key(int index_no,int container_id_column_no,Object_id container_id,int type_column_no,uint type,int name_column_no,const String_type & object_name,const CHARSET_INFO * cs)438   Routine_name_key(int index_no, int container_id_column_no,
439                    Object_id container_id, int type_column_no, uint type,
440                    int name_column_no, const String_type &object_name,
441                    const CHARSET_INFO *cs)
442       : m_index_no(index_no),
443         m_container_id_column_no(container_id_column_no),
444         m_type_column_no(type_column_no),
445         m_name_column_no(name_column_no),
446         m_container_id(container_id),
447         m_type(type),
448         m_object_name(object_name),
449         m_cs(cs) {}
450 
451   // Update a preallocated instance.
update(int index_no,int container_id_column_no,Object_id container_id,int type_column_no,uint type,int name_column_no,const String_type & object_name,const CHARSET_INFO * cs)452   void update(int index_no, int container_id_column_no, Object_id container_id,
453               int type_column_no, uint type, int name_column_no,
454               const String_type &object_name, const CHARSET_INFO *cs) {
455     m_index_no = index_no;
456     m_container_id_column_no = container_id_column_no;
457     m_type_column_no = type_column_no;
458     m_name_column_no = name_column_no;
459     m_container_id = container_id;
460     m_type = type;
461     m_object_name = object_name;
462     m_cs = cs;
463   }
464 
465  public:
466   virtual Raw_key *create_access_key(Raw_table *db_table) const;
467 
468   virtual String_type str() const;
469 
470   bool operator<(const Routine_name_key &rhs) const;
471 
472  private:
473   int m_index_no;
474   int m_container_id_column_no;
475   int m_type_column_no;
476   int m_name_column_no;
477 
478   Object_id m_container_id;
479   uint m_type;
480   String_type m_object_name;
481   // Collation used for the routine name in the table.
482   const CHARSET_INFO *m_cs;
483 };
484 
485 ///////////////////////////////////////////////////////////////////////////
486 
487 // Range key to find rows using catalog/schema/table name.
488 class Table_reference_range_key : public Object_key {
489  public:
Table_reference_range_key(int index_no,int catalog_name_column_no,const String_type & catalog_name,int schema_name_column_no,const String_type & schema_name,int table_name_column_no,const String_type & table_name)490   Table_reference_range_key(int index_no, int catalog_name_column_no,
491                             const String_type &catalog_name,
492                             int schema_name_column_no,
493                             const String_type &schema_name,
494                             int table_name_column_no,
495                             const String_type &table_name)
496       : m_index_no(index_no),
497         m_catalog_name_column_no(catalog_name_column_no),
498         m_catalog_name(catalog_name),
499         m_schema_name_column_no(schema_name_column_no),
500         m_schema_name(schema_name),
501         m_table_name_column_no(table_name_column_no),
502         m_table_name(table_name) {}
503 
504  public:
505   virtual Raw_key *create_access_key(Raw_table *db_table) const;
506 
507   virtual String_type str() const;
508 
509  private:
510   int m_index_no;
511 
512   int m_catalog_name_column_no;
513   String_type m_catalog_name;
514 
515   int m_schema_name_column_no;
516   String_type m_schema_name;
517 
518   int m_table_name_column_no;
519   String_type m_table_name;
520 };
521 
522 ///////////////////////////////////////////////////////////////////////////
523 
524 // Range key to find sub partition entries by table id and parent partition
525 // id in mysql.partitions.
526 class Sub_partition_range_key : public Object_key {
527  public:
Sub_partition_range_key(int index_no,int table_id_column_no,const Object_id table_id,int parent_partition_id_column_no,const Object_id parent_partition_id)528   Sub_partition_range_key(int index_no, int table_id_column_no,
529                           const Object_id table_id,
530                           int parent_partition_id_column_no,
531                           const Object_id parent_partition_id)
532       : m_index_no(index_no),
533         m_table_id_column_no(table_id_column_no),
534         m_table_id(table_id),
535         m_parent_partition_id_column_no(parent_partition_id_column_no),
536         m_parent_partition_id(parent_partition_id) {}
537 
538  public:
539   virtual Raw_key *create_access_key(Raw_table *db_table) const;
540 
541   virtual String_type str() const;
542 
543  private:
544   int m_index_no;
545 
546   int m_table_id_column_no;
547   Object_id m_table_id;
548 
549   int m_parent_partition_id_column_no;
550   Object_id m_parent_partition_id;
551 };
552 
553 ///////////////////////////////////////////////////////////////////////////
554 }  // namespace dd
555 #endif  // DD__OBJECT_KEYS_INCLUDED
556