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 #include "sql/dd/impl/raw/object_keys.h"
24 
25 #include <new>
26 #include <sstream>
27 
28 #include "m_ctype.h"
29 #include "my_base.h"  // HA_WHOLE_KEY
30 #include "my_dbug.h"
31 #include "mysql/udf_registration_types.h"
32 #include "sql/dd/impl/raw/raw_key.h"              // dd::Raw_key
33 #include "sql/dd/impl/raw/raw_table.h"            // dd::Raw_table
34 #include "sql/dd/impl/types/object_table_impl.h"  // dd::Object_table_impl
35 #include "sql/dd/string_type.h"                   // dd::String_type
36 #include "sql/field.h"                            // Field
37 #include "sql/key.h"                              // KEY
38 #include "sql/table.h"                            // TABLE
39 
40 namespace dd {
41 
42 ///////////////////////////////////////////////////////////////////////////
43 // Primary_id_key
44 ///////////////////////////////////////////////////////////////////////////
45 
create_access_key(Raw_table * db_table) const46 Raw_key *Primary_id_key::create_access_key(Raw_table *db_table) const {
47   // Positional index of PK-Index on object-id field.
48   // It is 0 for any DD-table (PK-Index is the 1st index on a DD-table).
49   const int ID_INDEX_NO =
50       static_cast<int>(Object_table_impl::Common_index::PK_ID);
51   DBUG_ASSERT(ID_INDEX_NO == 0);
52 
53   // Positional index of PK-object-id-column.
54   // It is 0 for any DD-table (object-id is the 1st column on a DD-table).
55   const int ID_COLUMN_NO =
56       static_cast<int>(Object_table_impl::Common_field::ID);
57   DBUG_ASSERT(ID_COLUMN_NO == 0);
58 
59   TABLE *t = db_table->get_table();
60 
61   t->use_all_columns();
62 
63   t->field[ID_COLUMN_NO]->store(m_object_id, true);
64 
65   KEY *key_info = t->key_info + ID_INDEX_NO;
66 
67   Raw_key *k = new (std::nothrow)
68       Raw_key(ID_INDEX_NO, key_info->key_length, HA_WHOLE_KEY);
69 
70   key_copy(k->key, t->record[0], key_info, k->key_len);
71 
72   return k;
73 }
74 
75 ///////////////////////////////////////////////////////////////////////////
76 
77 /* purecov: begin inspected */
str() const78 String_type Primary_id_key::str() const {
79   dd::Stringstream_type ss;
80   ss << m_object_id;
81   return ss.str();
82 }
83 /* purecov: end */
84 
85 ///////////////////////////////////////////////////////////////////////////
86 // Parent_id_range_key
87 ///////////////////////////////////////////////////////////////////////////
88 
create_access_key(Raw_table * db_table) const89 Raw_key *Parent_id_range_key::create_access_key(Raw_table *db_table) const {
90   TABLE *t = db_table->get_table();
91 
92   t->use_all_columns();
93 
94   t->field[m_id_column_no]->store(m_object_id, true);
95   t->field[m_id_column_no]->set_notnull();
96 
97   KEY *key_info = t->key_info + m_id_index_no;
98 
99   Raw_key *k = new (std::nothrow)
100       Raw_key(m_id_index_no, key_info->key_length, 1 /* Use 1st column */);
101 
102   key_copy(k->key, t->record[0], key_info, k->key_len);
103 
104   return k;
105 }
106 
107 ///////////////////////////////////////////////////////////////////////////
108 
109 /* purecov: begin inspected */
str() const110 String_type Parent_id_range_key::str() const {
111   // XXX: not needed
112   dd::Stringstream_type ss;
113   ss << m_id_column_no << ":" << m_object_id;
114   return ss.str();
115 }
116 /* purecov: end */
117 
118 ///////////////////////////////////////////////////////////////////////////
119 // Global_name_key
120 ///////////////////////////////////////////////////////////////////////////
121 
create_access_key(Raw_table * db_table) const122 Raw_key *Global_name_key::create_access_key(Raw_table *db_table) const {
123   /*
124     Positional index of name index on the name field.
125     It is 1 for any DD-table (the name index is the 2nd index
126     on a DD-table, i.e., the ordinal position is 2). This is a
127     convention both for entities with global names, and entities
128     that are items contained in another entity.
129   */
130   const int NAME_INDEX_NO =
131       static_cast<int>(Object_table_impl::Common_index::UK_NAME);
132 
133   DBUG_ASSERT(NAME_INDEX_NO == 1);
134 
135   TABLE *t = db_table->get_table();
136 
137   t->use_all_columns();
138 
139   t->field[m_name_column_no]->store(m_object_name.c_str(),
140                                     m_object_name.length(), &my_charset_bin);
141 
142   KEY *key_info = t->key_info + NAME_INDEX_NO;
143 
144   Raw_key *k = new (std::nothrow)
145       Raw_key(NAME_INDEX_NO, key_info->key_length, HA_WHOLE_KEY);
146 
147   key_copy(k->key, t->record[0], key_info, k->key_len);
148 
149   return k;
150 }
151 
152 ///////////////////////////////////////////////////////////////////////////
153 // Item_name_key
154 ///////////////////////////////////////////////////////////////////////////
155 
create_access_key(Raw_table * db_table) const156 Raw_key *Item_name_key::create_access_key(Raw_table *db_table) const {
157   /*
158     Positional index of name index on the name field.
159     It is 1 for any DD-table (the name index is the 2nd index
160     on a DD-table, i.e., the ordinal position is 2). This is a
161     convention both for entities with global names, and entities
162     that are items contained in another entity.
163   */
164   const int NAME_INDEX_NO =
165       static_cast<int>(Object_table_impl::Common_index::UK_NAME);
166 
167   DBUG_ASSERT(NAME_INDEX_NO == 1);
168 
169   TABLE *t = db_table->get_table();
170 
171   t->use_all_columns();
172 
173   t->field[m_container_id_column_no]->store(m_container_id, true);
174 
175   t->field[m_name_column_no]->store(m_object_name.c_str(),
176                                     m_object_name.length(), &my_charset_bin);
177 
178   KEY *key_info = t->key_info + NAME_INDEX_NO;
179 
180   Raw_key *k = new (std::nothrow)
181       Raw_key(NAME_INDEX_NO, key_info->key_length, HA_WHOLE_KEY);
182 
183   key_copy(k->key, t->record[0], key_info, k->key_len);
184 
185   return k;
186 }
187 
188 ///////////////////////////////////////////////////////////////////////////
189 
str() const190 String_type Item_name_key::str() const {
191   dd::Stringstream_type ss;
192   ss << m_container_id << ":" << m_object_name;
193   return ss.str();
194 }
195 
196 ///////////////////////////////////////////////////////////////////////////
197 // Se_private_id_key
198 ///////////////////////////////////////////////////////////////////////////
199 
200 /* purecov: begin deadcode */
create_access_key(Raw_table * db_table) const201 Raw_key *Se_private_id_key::create_access_key(Raw_table *db_table) const {
202   key_part_map keypart_map = 1;
203   TABLE *t = db_table->get_table();
204 
205   t->use_all_columns();
206 
207   t->field[m_engine_column_no]->store(m_engine.c_str(), m_engine.length(),
208                                       &my_charset_bin);
209   t->field[m_engine_column_no]->set_notnull();
210 
211   t->field[m_private_id_column_no]->store(m_private_id, true);
212   t->field[m_private_id_column_no]->set_notnull();
213 
214   if (m_private_id != INVALID_OBJECT_ID) keypart_map = HA_WHOLE_KEY;
215 
216   KEY *key_info = t->key_info + m_index_no;
217 
218   Raw_key *k =
219       new (std::nothrow) Raw_key(m_index_no, key_info->key_length, keypart_map);
220 
221   key_copy(k->key, t->record[0], key_info, k->key_len);
222 
223   return k;
224 }
225 /* purecov: end */
226 
227 ///////////////////////////////////////////////////////////////////////////
228 
str() const229 String_type Se_private_id_key::str() const {
230   dd::Stringstream_type ss;
231   ss << m_engine << ":" << m_private_id;
232   return ss.str();
233 }
234 
235 ///////////////////////////////////////////////////////////////////////////
236 // Composite_pk
237 ///////////////////////////////////////////////////////////////////////////
238 
create_access_key(Raw_table * db_table) const239 Raw_key *Composite_pk::create_access_key(Raw_table *db_table) const {
240   TABLE *t = db_table->get_table();
241 
242   t->use_all_columns();
243 
244   t->field[m_first_column_no]->store(m_first_id, true);
245   t->field[m_second_column_no]->store(m_second_id, true);
246 
247   KEY *key_info = t->key_info + m_index_no;
248 
249   Raw_key *k = new (std::nothrow)
250       Raw_key(m_index_no, key_info->key_length, HA_WHOLE_KEY);
251 
252   key_copy(k->key, t->record[0], key_info, k->key_len);
253 
254   return k;
255 }
256 
257 ///////////////////////////////////////////////////////////////////////////
258 
259 /* purecov: begin inspected */
str() const260 String_type Composite_pk::str() const {
261   dd::Stringstream_type ss;
262   ss << m_first_id << ":" << m_second_id;
263   return ss.str();
264 }
265 /* purecov: end */
266 
267 ///////////////////////////////////////////////////////////////////////////
268 // Routine_name_key
269 ///////////////////////////////////////////////////////////////////////////
270 
create_access_key(Raw_table * db_table) const271 Raw_key *Routine_name_key::create_access_key(Raw_table *db_table) const {
272   TABLE *t = db_table->get_table();
273 
274   t->use_all_columns();
275 
276   t->field[m_container_id_column_no]->store(m_container_id, true);
277 
278   t->field[m_type_column_no]->store(m_type, true);
279 
280   t->field[m_name_column_no]->store(m_object_name.c_str(),
281                                     m_object_name.length(), &my_charset_bin);
282 
283   KEY *key_info = t->key_info + m_index_no;
284 
285   Raw_key *k = new (std::nothrow)
286       Raw_key(m_index_no, key_info->key_length, HA_WHOLE_KEY);
287 
288   key_copy(k->key, t->record[0], key_info, k->key_len);
289 
290   return k;
291 }
292 
293 ///////////////////////////////////////////////////////////////////////////
294 
295 /* purecov: begin inspected */
str() const296 String_type Routine_name_key::str() const {
297   dd::Stringstream_type ss;
298   ss << m_container_id << ":" << m_type << ":" << m_object_name;
299   return ss.str();
300 }
301 /* purecov: end */
302 
303 ///////////////////////////////////////////////////////////////////////////
304 
operator <(const Routine_name_key & rhs) const305 bool Routine_name_key::operator<(const Routine_name_key &rhs) const {
306   if (m_container_id != rhs.m_container_id)
307     return m_container_id < rhs.m_container_id;
308   if (m_type != rhs.m_type) return m_type < rhs.m_type;
309 
310   return (my_strnncoll(m_cs, pointer_cast<const uchar *>(m_object_name.c_str()),
311                        m_object_name.length(),
312                        pointer_cast<const uchar *>(rhs.m_object_name.c_str()),
313                        rhs.m_object_name.length()) < 0);
314 }
315 
316 ///////////////////////////////////////////////////////////////////////////
317 // Composite_char_key
318 ///////////////////////////////////////////////////////////////////////////
319 
create_access_key(Raw_table * db_table) const320 Raw_key *Composite_char_key::create_access_key(Raw_table *db_table) const {
321   TABLE *t = db_table->get_table();
322 
323   t->use_all_columns();  // TODO can mark only required fields ?
324 
325   t->field[m_first_column_no]->store(m_first_name.c_str(),
326                                      m_first_name.length(), &my_charset_bin);
327 
328   t->field[m_second_column_no]->store(m_second_name.c_str(),
329                                       m_second_name.length(), &my_charset_bin);
330 
331   KEY *key_info = t->key_info + m_index_no;
332 
333   Raw_key *k = new Raw_key(m_index_no, key_info->key_length, HA_WHOLE_KEY);
334 
335   key_copy(k->key, t->record[0], key_info, k->key_len);
336 
337   return k;
338 }
339 
340 ///////////////////////////////////////////////////////////////////////////
341 
str() const342 String_type Composite_char_key::str() const {
343   dd::Stringstream_type ss;
344   ss << m_first_name << ":" << m_second_name;
345   return ss.str();
346 }
347 
348 ///////////////////////////////////////////////////////////////////////////
349 // Composite_4char_key
350 ///////////////////////////////////////////////////////////////////////////
351 
create_access_key(Raw_table * db_table) const352 Raw_key *Composite_4char_key::create_access_key(Raw_table *db_table) const {
353   TABLE *t = db_table->get_table();
354 
355   t->use_all_columns();  // TODO can mark only required fields ?
356 
357   t->field[m_first_column_no]->store(m_first_name.c_str(),
358                                      m_first_name.length(), &my_charset_bin);
359 
360   t->field[m_second_column_no]->store(m_second_name.c_str(),
361                                       m_second_name.length(), &my_charset_bin);
362 
363   t->field[m_third_column_no]->store(m_third_name.c_str(),
364                                      m_third_name.length(), &my_charset_bin);
365 
366   t->field[m_fourth_column_no]->store(m_fourth_name.c_str(),
367                                       m_fourth_name.length(), &my_charset_bin);
368 
369   KEY *key_info = t->key_info + m_index_no;
370 
371   Raw_key *k = new Raw_key(m_index_no, key_info->key_length, HA_WHOLE_KEY);
372 
373   key_copy(k->key, t->record[0], key_info, k->key_len);
374 
375   return k;
376 }
377 
378 ///////////////////////////////////////////////////////////////////////////
379 
str() const380 String_type Composite_4char_key::str() const {
381   dd::Stringstream_type ss;
382   ss << m_first_name << ":" << m_second_name << ":" << m_third_name << ":"
383      << m_fourth_name;
384   return ss.str();
385 }
386 
387 ///////////////////////////////////////////////////////////////////////////
388 // Composite_obj_id_3char_key
389 ///////////////////////////////////////////////////////////////////////////
390 
create_access_key(Raw_table * db_table) const391 Raw_key *Composite_obj_id_3char_key::create_access_key(
392     Raw_table *db_table) const {
393   TABLE *t = db_table->get_table();
394 
395   t->use_all_columns();  // TODO can mark only required fields ?
396 
397   t->field[m_id_column_no]->store(m_id, true);
398 
399   t->field[m_first_column_no]->store(m_first_name.c_str(),
400                                      m_first_name.length(), &my_charset_bin);
401 
402   t->field[m_second_column_no]->store(m_second_name.c_str(),
403                                       m_second_name.length(), &my_charset_bin);
404 
405   t->field[m_third_column_no]->store(m_third_name.c_str(),
406                                      m_third_name.length(), &my_charset_bin);
407 
408   KEY *key_info = t->key_info + m_index_no;
409 
410   Raw_key *k = new Raw_key(m_index_no, key_info->key_length, HA_WHOLE_KEY);
411 
412   key_copy(k->key, t->record[0], key_info, k->key_len);
413 
414   return k;
415 }
416 
417 ///////////////////////////////////////////////////////////////////////////
418 
str() const419 String_type Composite_obj_id_3char_key::str() const {
420   dd::Stringstream_type ss;
421   ss << m_id << m_first_name << ":" << m_second_name << ":" << m_third_name;
422   return ss.str();
423 }
424 
425 ///////////////////////////////////////////////////////////////////////////
426 // Index_stat_range_key
427 ///////////////////////////////////////////////////////////////////////////
428 
create_access_key(Raw_table * db_table) const429 Raw_key *Index_stat_range_key::create_access_key(Raw_table *db_table) const {
430   TABLE *t = db_table->get_table();
431 
432   t->use_all_columns();
433 
434   t->field[m_schema_name_column_no]->store(
435       m_schema_name.c_str(), m_schema_name.length(), &my_charset_bin);
436   t->field[m_table_name_column_no]->store(
437       m_table_name.c_str(), m_table_name.length(), &my_charset_bin);
438 
439   KEY *key_info = t->key_info + m_index_no;
440 
441   Raw_key *k = new (std::nothrow)
442       Raw_key(m_index_no, key_info->key_length, 3 /* Use first two column */);
443 
444   key_copy(k->key, t->record[0], key_info, k->key_len);
445 
446   return k;
447 }
448 
449 ///////////////////////////////////////////////////////////////////////////
450 
str() const451 String_type Index_stat_range_key::str() const {
452   dd::Stringstream_type ss;
453   ss << m_schema_name_column_no << ":" << m_schema_name << ":"
454      << m_table_name_column_no << ":" << m_table_name;
455   return ss.str();
456 }
457 
458 ///////////////////////////////////////////////////////////////////////////
459 // Table_reference_range_key
460 ///////////////////////////////////////////////////////////////////////////
461 
create_access_key(Raw_table * db_table) const462 Raw_key *Table_reference_range_key::create_access_key(
463     Raw_table *db_table) const {
464   TABLE *t = db_table->get_table();
465 
466   t->use_all_columns();
467 
468   t->field[m_catalog_name_column_no]->store(
469       m_catalog_name.c_str(), m_catalog_name.length(), &my_charset_bin);
470   t->field[m_schema_name_column_no]->store(
471       m_schema_name.c_str(), m_schema_name.length(), &my_charset_bin);
472   t->field[m_table_name_column_no]->store(
473       m_table_name.c_str(), m_table_name.length(), &my_charset_bin);
474 
475   KEY *key_info = t->key_info + m_index_no;
476 
477   Raw_key *k = new (std::nothrow) Raw_key(m_index_no, key_info->key_length, 7);
478 
479   key_copy(k->key, t->record[0], key_info, k->key_len);
480 
481   return k;
482 }
483 
484 ///////////////////////////////////////////////////////////////////////////
485 
str() const486 String_type Table_reference_range_key::str() const {
487   dd::Stringstream_type ss;
488   ss << m_catalog_name_column_no << ":" << m_catalog_name
489      << m_schema_name_column_no << ":" << m_schema_name << ":"
490      << m_table_name_column_no << ":" << m_table_name;
491   return ss.str();
492 }
493 
494 ///////////////////////////////////////////////////////////////////////////
495 // Sub_partition_range_key
496 ///////////////////////////////////////////////////////////////////////////
497 
create_access_key(Raw_table * db_table) const498 Raw_key *Sub_partition_range_key::create_access_key(Raw_table *db_table) const {
499   TABLE *t = db_table->get_table();
500 
501   t->use_all_columns();
502 
503   t->field[m_table_id_column_no]->store(m_table_id, true);
504   t->field[m_table_id_column_no]->set_notnull();
505 
506   if (m_parent_partition_id == dd::INVALID_OBJECT_ID)
507     t->field[m_parent_partition_id_column_no]->set_null();
508   else {
509     t->field[m_parent_partition_id_column_no]->store(m_parent_partition_id,
510                                                      true);
511     t->field[m_parent_partition_id_column_no]->set_notnull();
512   }
513 
514   KEY *key_info = t->key_info + m_index_no;
515 
516   Raw_key *k = new (std::nothrow)
517       Raw_key(m_index_no, key_info->key_length, 3 /* Use first two column */);
518 
519   key_copy(k->key, t->record[0], key_info, k->key_len);
520 
521   return k;
522 }
523 
524 ///////////////////////////////////////////////////////////////////////////
525 
str() const526 String_type Sub_partition_range_key::str() const {
527   dd::Stringstream_type ss;
528   ss << m_parent_partition_id_column_no << ":" << m_parent_partition_id << ":"
529      << m_table_id_column_no << ":" << m_table_id;
530   return ss.str();
531 }
532 
533 ///////////////////////////////////////////////////////////////////////////
534 }  // namespace dd
535