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