1 /* Copyright (c) 2016, 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 #include "sql/dd/info_schema/show.h"
24
25 #include <string.h>
26
27 #include "lex_string.h"
28 #include "m_string.h"
29 #include "my_sqlcommand.h"
30 #include "sql/dd/info_schema/show_query_builder.h" // Select_lex_builder
31 #include "sql/dd/info_schema/table_stats.h"
32 #include "sql/dd/string_type.h"
33 #include "sql/item_cmpfunc.h" // Item_func_case
34 #include "sql/key.h"
35 #include "sql/parse_tree_node_base.h"
36 #include "sql/sql_class.h"
37 #include "sql/sql_lex.h"
38 #include "sql/table.h"
39 #include "sql_string.h"
40
41 namespace dd {
42 namespace info_schema {
43
44 // Build a substitute query for SHOW CHARSETS.
45
build_show_character_set_query(const POS & pos,THD * thd,const String * wild,Item * where_cond)46 SELECT_LEX *build_show_character_set_query(const POS &pos, THD *thd,
47 const String *wild,
48 Item *where_cond) {
49 static const LEX_CSTRING system_view_name = {
50 STRING_WITH_LEN("CHARACTER_SETS")};
51
52 // Define field name literal used in query to be built.
53 static const LEX_CSTRING field_charset = {
54 STRING_WITH_LEN("CHARACTER_SET_NAME")};
55 static const LEX_CSTRING alias_charset = {STRING_WITH_LEN("Charset")};
56
57 static const LEX_CSTRING field_desc = {STRING_WITH_LEN("DESCRIPTION")};
58 static const LEX_CSTRING alias_desc = {STRING_WITH_LEN("Description")};
59
60 static const LEX_CSTRING field_collate = {
61 STRING_WITH_LEN("DEFAULT_COLLATE_NAME")};
62 static const LEX_CSTRING alias_collate = {
63 STRING_WITH_LEN("Default collation")};
64
65 static const LEX_CSTRING field_maxlen = {STRING_WITH_LEN("MAXLEN")};
66 static const LEX_CSTRING alias_maxlen = {STRING_WITH_LEN("Maxlen")};
67
68 /*
69 Build sub query.
70
71 ...
72 SELECT
73 CHARACTER_SET_NAME as Charset,
74 DESCRIPTION as Description,
75 DEFAULT_COLLATE_NAME as `Default collation`,
76 MAXLEN as `Maxlen`
77 ...
78 */
79 Select_lex_builder sub_query(&pos, thd);
80 if (sub_query.add_select_item(field_charset, alias_charset) ||
81 sub_query.add_select_item(field_desc, alias_desc))
82 return nullptr;
83
84 if (thd->variables.default_collation_for_utf8mb4 ==
85 &my_charset_utf8mb4_0900_ai_ci) {
86 if (sub_query.add_select_item(field_collate, alias_collate)) return nullptr;
87 } else {
88 MEM_ROOT *const mem_root = thd->mem_root;
89
90 // ... CHARACTER_SETS ...
91 Item *charset_item =
92 new (mem_root) Item_field(pos, NullS, NullS, field_charset.str);
93 if (charset_item == nullptr) return nullptr;
94
95 // ... 'utf8mb4' ...
96 Item *utf8mb4_item = new (mem_root)
97 Item_string(STRING_WITH_LEN("utf8mb4"), system_charset_info);
98 if (utf8mb4_item == nullptr) return nullptr;
99
100 // ... = ...
101 Item *if_cond =
102 new (mem_root) Item_func_eq(pos, charset_item, utf8mb4_item);
103 if (if_cond == nullptr) return nullptr;
104
105 // ... 'utf8mb4_general_ci' ...
106 Item *if_then = new (mem_root)
107 Item_string(STRING_WITH_LEN("utf8mb4_general_ci"), system_charset_info);
108 if (if_then == nullptr) return nullptr;
109
110 // ... DEFAULT_COLLATE_NAME ...
111 Item *if_else =
112 new (mem_root) Item_field(pos, NullS, NullS, field_collate.str);
113 if (if_else == nullptr) return nullptr;
114
115 /*
116 IF(CHARACTER_SETS = 'utf8mb4', 'utf8mb4_general_ci', DEFAULT_COLLATE_NAME)
117 */
118 Item *if_func = new (mem_root) Item_func_if(pos, if_cond, if_then, if_else);
119 if (if_func == nullptr || sub_query.add_select_expr(if_func, alias_collate))
120 return nullptr;
121 }
122
123 if (sub_query.add_select_item(field_maxlen, alias_maxlen)) return nullptr;
124
125 // ... FROM information_schema.<table_name> ...
126 if (sub_query.add_from_item(INFORMATION_SCHEMA_NAME, system_view_name))
127 return nullptr;
128
129 /*
130 Build the top level query
131 */
132
133 Select_lex_builder top_query(&pos, thd);
134
135 // SELECT * FROM <sub_query> ...
136 if (top_query.add_star_select_item() ||
137 top_query.add_from_item(
138 sub_query.prepare_derived_table(system_view_name)))
139 return nullptr;
140
141 // SELECT * FROM <sub_query> WHERE Charset LIKE <value> ...
142 if (wild) {
143 Item *like = top_query.prepare_like_item(alias_charset, wild);
144 if (!like || top_query.add_condition(like)) return nullptr;
145 } else if (where_cond && top_query.add_condition(where_cond))
146 return nullptr;
147
148 // ... ORDER BY 'Charset' ...
149 if (top_query.add_order_by(alias_charset)) return nullptr;
150
151 SELECT_LEX *sl = top_query.prepare_select_lex();
152
153 // sql_command is set to SQL_QUERY after above call, so.
154 thd->lex->sql_command = SQLCOM_SHOW_CHARSETS;
155
156 return sl;
157 }
158
159 // Build a substitute query for SHOW COLLATION.
160
build_show_collation_query(const POS & pos,THD * thd,const String * wild,Item * where_cond)161 SELECT_LEX *build_show_collation_query(const POS &pos, THD *thd,
162 const String *wild, Item *where_cond) {
163 static const LEX_CSTRING system_view_name = {STRING_WITH_LEN("COLLATIONS")};
164
165 // Define field name literal used in query to be built.
166 static const LEX_CSTRING field_collation = {
167 STRING_WITH_LEN("COLLATION_NAME")};
168 static const LEX_CSTRING alias_collation = {STRING_WITH_LEN("Collation")};
169
170 static const LEX_CSTRING field_charset = {
171 STRING_WITH_LEN("CHARACTER_SET_NAME")};
172 static const LEX_CSTRING alias_charset = {STRING_WITH_LEN("Charset")};
173
174 static const LEX_CSTRING field_id = {STRING_WITH_LEN("ID")};
175 static const LEX_CSTRING alias_id = {STRING_WITH_LEN("Id")};
176
177 static const LEX_CSTRING field_default = {STRING_WITH_LEN("IS_DEFAULT")};
178 static const LEX_CSTRING alias_default = {STRING_WITH_LEN("Default")};
179
180 static const LEX_CSTRING field_compiled = {STRING_WITH_LEN("IS_COMPILED")};
181 static const LEX_CSTRING alias_compiled = {STRING_WITH_LEN("Compiled")};
182
183 static const LEX_CSTRING field_sortlen = {STRING_WITH_LEN("SORTLEN")};
184 static const LEX_CSTRING alias_sortlen = {STRING_WITH_LEN("Sortlen")};
185
186 static const LEX_CSTRING field_pad_attribute = {
187 STRING_WITH_LEN("PAD_ATTRIBUTE")};
188 static const LEX_CSTRING alias_pad_attribute = {
189 STRING_WITH_LEN("Pad_attribute")};
190
191 /*
192 Build sub query.
193
194 ...
195 SELECT COLLATION_NAME as `Collation`,
196 CHARACTER_SET_NAME as `Charset`,
197 ID as `Id`,
198 IS_DEFAULT as `Default`,
199 IS_COMPILED as `Compiled`,
200 SORTLEN as `Sortlen`,
201 PAD_ATTRIBUTE AS `Pad_attribute`
202 ...
203 */
204 Select_lex_builder sub_query(&pos, thd);
205 if (sub_query.add_select_item(field_collation, alias_collation) ||
206 sub_query.add_select_item(field_charset, alias_charset) ||
207 sub_query.add_select_item(field_id, alias_id))
208 return nullptr;
209
210 if (thd->variables.default_collation_for_utf8mb4 ==
211 &my_charset_utf8mb4_0900_ai_ci) {
212 if (sub_query.add_select_item(field_default, alias_default)) return nullptr;
213 } else {
214 MEM_ROOT *const mem_root = thd->mem_root;
215
216 // ... `ID` ...
217 Item *case_value_item =
218 new (mem_root) Item_field(pos, NullS, NullS, field_id.str);
219 if (case_value_item == nullptr) return nullptr; // OOM
220
221 List<Item> case_when_list;
222
223 // ... WHEN <ID of utf8mb4_general_ci> ...
224 Item *old_default_collation =
225 new (mem_root) Item_uint(my_charset_utf8mb4_general_ci.number);
226 if (old_default_collation == nullptr ||
227 case_when_list.push_back(old_default_collation))
228 return nullptr; // OOM
229
230 // ... THEN 'Yes' ...
231 Item *force_old_default_collation =
232 new (mem_root) Item_string(STRING_WITH_LEN("Yes"), system_charset_info);
233 if (force_old_default_collation == nullptr ||
234 case_when_list.push_back(force_old_default_collation))
235 return nullptr; // OOM
236
237 // ... WHEN <ID of utf8mb4_0900_ai_ci> ...
238 Item *new_default_collation =
239 new (mem_root) Item_uint(my_charset_utf8mb4_0900_ai_ci.number);
240 if (new_default_collation == nullptr ||
241 case_when_list.push_back(new_default_collation))
242 return nullptr; // OOM
243
244 // ... THEN '' ...
245 Item *suppress_new_default_collation =
246 new (mem_root) Item_string(STRING_WITH_LEN(""), system_charset_info);
247 if (suppress_new_default_collation == nullptr ||
248 case_when_list.push_back(suppress_new_default_collation))
249 return nullptr; // OOM
250
251 // ... ELSE IS_DEFAULT ...
252 Item *case_else_item =
253 new (mem_root) Item_field(pos, NullS, NullS, field_default.str);
254 if (case_else_item == nullptr) return nullptr;
255
256 // CASE `ID`
257 // WHEN <ID of utf8mb4_general_ci> THEN TRUE
258 // WHEN <ID of utf8mb4_0900_ai_ci> THEN FALSE
259 // ELSE `IS_DEFAULT`
260 Item *case_func = new (mem_root)
261 Item_func_case(pos, case_when_list, case_value_item, case_else_item);
262 if (case_func == nullptr ||
263 sub_query.add_select_expr(case_func, alias_default))
264 return nullptr;
265 }
266
267 if (sub_query.add_select_item(field_compiled, alias_compiled) ||
268 sub_query.add_select_item(field_sortlen, alias_sortlen) ||
269 sub_query.add_select_item(field_pad_attribute, alias_pad_attribute))
270 return nullptr;
271
272 // ... FROM information_schema.<table_name> ...
273 if (sub_query.add_from_item(INFORMATION_SCHEMA_NAME, system_view_name))
274 return nullptr;
275
276 /*
277 Build the top level query
278 */
279
280 Select_lex_builder top_query(&pos, thd);
281
282 // SELECT * FROM <sub_query> ...
283 if (top_query.add_star_select_item() ||
284 top_query.add_from_item(
285 sub_query.prepare_derived_table(system_view_name)))
286 return nullptr;
287
288 // SELECT * FROM <sub_query> WHERE Collation LIKE <value> ...
289 if (wild) {
290 Item *like = top_query.prepare_like_item(alias_collation, wild);
291 if (!like || top_query.add_condition(like)) return nullptr;
292 } else if (where_cond && top_query.add_condition(where_cond))
293 return nullptr;
294
295 // ... ORDER BY 'Collation' ...
296 if (top_query.add_order_by(alias_collation)) return nullptr;
297
298 SELECT_LEX *sl = top_query.prepare_select_lex();
299
300 // sql_command is set to SQL_QUERY after above call, so.
301 thd->lex->sql_command = SQLCOM_SHOW_COLLATIONS;
302
303 return sl;
304 }
305
306 // Build a substitute query for SHOW DATABASES.
307
build_show_databases_query(const POS & pos,THD * thd,String * wild,Item * where_cond)308 SELECT_LEX *build_show_databases_query(const POS &pos, THD *thd, String *wild,
309 Item *where_cond) {
310 static const LEX_CSTRING system_view_name = {STRING_WITH_LEN("SCHEMATA")};
311
312 // Define field name literal used in query to be built.
313 static const LEX_CSTRING field_schema_name = {STRING_WITH_LEN("SCHEMA_NAME")};
314 static const LEX_CSTRING alias_database = {STRING_WITH_LEN("Database")};
315
316 // Build the alias 'Database (<dbname>%)'
317 String_type alias;
318 alias.append(alias_database.str);
319 if (wild) {
320 alias.append(" (");
321 alias.append(wild->ptr(), wild->length());
322 alias.append(")");
323 }
324 char *tmp = static_cast<char *>(thd->alloc(alias.length() + 1));
325 memcpy(tmp, alias.c_str(), alias.length());
326 *(tmp + alias.length()) = '\0';
327 LEX_CSTRING alias_lex_string = {tmp, alias.length()};
328
329 /*
330 Build sub query.
331
332 ...
333 SELECT SCHEMA_NAME as `Database`,
334 FROM information_schema.schemata;
335 ...
336 */
337 Select_lex_builder sub_query(&pos, thd);
338 if (sub_query.add_select_item(field_schema_name, alias_database) ||
339 sub_query.add_from_item(INFORMATION_SCHEMA_NAME, system_view_name))
340 return nullptr;
341
342 /*
343 Build the top level query
344 */
345
346 Select_lex_builder top_query(&pos, thd);
347
348 // SELECT * FROM <sub_query> ...
349 if (top_query.add_select_item(alias_database, alias_lex_string) ||
350 top_query.add_from_item(
351 sub_query.prepare_derived_table(system_view_name)))
352 return nullptr;
353
354 // SELECT * FROM <sub_query> WHERE Database LIKE <value> ...
355 if (wild) {
356 // Convert IS db and table name to desired form.
357 dd::info_schema::convert_table_name_case(wild->ptr(), nullptr);
358
359 Item *like = top_query.prepare_like_item(alias_database, wild);
360 if (!like || top_query.add_condition(like)) return nullptr;
361 } else if (where_cond && top_query.add_condition(where_cond))
362 return nullptr;
363
364 // ... ORDER BY 'Database' ...
365 if (top_query.add_order_by(alias_database)) return nullptr;
366
367 SELECT_LEX *sl = top_query.prepare_select_lex();
368
369 // sql_command is set to SQL_QUERY after above call, so.
370 thd->lex->sql_command = SQLCOM_SHOW_DATABASES;
371
372 return sl;
373 }
374
375 /**
376 Add fields required by SHOW TABLE STATUS.
377
378 @param query - Select_lex_builder to which we add fields.
379 @param alias_as_alias - Add select items of the form,
380 'alias AS alias'. This is required
381 for top level query, as the real field
382 names would be valied only the sub
383 query that we are building for SHOW
384 TABLE STATUS. Check comments in
385 sql/dd/show.h for more details.
386
387 @returns false on success.
388 true on failure.
389 */
390
add_table_status_fields(Select_lex_builder * query,bool alias_as_alias)391 static bool add_table_status_fields(Select_lex_builder *query,
392 bool alias_as_alias) {
393 // Field for SHOW TABLE STATUS
394 static const LEX_CSTRING field_engine = {STRING_WITH_LEN("ENGINE")};
395 static const LEX_CSTRING alias_engine = {STRING_WITH_LEN("Engine")};
396
397 static const LEX_CSTRING field_version = {STRING_WITH_LEN("VERSION")};
398 static const LEX_CSTRING alias_version = {STRING_WITH_LEN("Version")};
399
400 static const LEX_CSTRING field_row_format = {STRING_WITH_LEN("ROW_FORMAT")};
401 static const LEX_CSTRING alias_row_format = {STRING_WITH_LEN("Row_format")};
402
403 static const LEX_CSTRING field_rows = {STRING_WITH_LEN("TABLE_ROWS")};
404 static const LEX_CSTRING alias_rows = {STRING_WITH_LEN("Rows")};
405
406 static const LEX_CSTRING field_avg_row_length = {
407 STRING_WITH_LEN("AVG_ROW_LENGTH")};
408 static const LEX_CSTRING alias_avg_row_length = {
409 STRING_WITH_LEN("Avg_row_length")};
410
411 static const LEX_CSTRING field_data_length = {STRING_WITH_LEN("DATA_LENGTH")};
412 static const LEX_CSTRING alias_data_length = {STRING_WITH_LEN("Data_length")};
413
414 static const LEX_CSTRING field_max_data_length = {
415 STRING_WITH_LEN("MAX_DATA_LENGTH")};
416 static const LEX_CSTRING alias_max_data_length = {
417 STRING_WITH_LEN("Max_data_length")};
418
419 static const LEX_CSTRING field_index_length = {
420 STRING_WITH_LEN("INDEX_LENGTH")};
421 static const LEX_CSTRING alias_index_length = {
422 STRING_WITH_LEN("Index_length")};
423
424 static const LEX_CSTRING field_data_free = {STRING_WITH_LEN("DATA_FREE")};
425 static const LEX_CSTRING alias_data_free = {STRING_WITH_LEN("Data_free")};
426
427 static const LEX_CSTRING field_auto_increment = {
428 STRING_WITH_LEN("AUTO_INCREMENT")};
429 static const LEX_CSTRING alias_auto_increment = {
430 STRING_WITH_LEN("Auto_increment")};
431
432 static const LEX_CSTRING field_create_time = {STRING_WITH_LEN("CREATE_TIME")};
433 static const LEX_CSTRING alias_create_time = {STRING_WITH_LEN("Create_time")};
434
435 static const LEX_CSTRING field_update_time = {STRING_WITH_LEN("UPDATE_TIME")};
436 static const LEX_CSTRING alias_update_time = {STRING_WITH_LEN("Update_time")};
437
438 static const LEX_CSTRING field_check_time = {STRING_WITH_LEN("CHECK_TIME")};
439 static const LEX_CSTRING alias_check_time = {STRING_WITH_LEN("Check_time")};
440
441 static const LEX_CSTRING field_collation = {
442 STRING_WITH_LEN("TABLE_COLLATION")};
443 static const LEX_CSTRING alias_collation = {STRING_WITH_LEN("Collation")};
444
445 static const LEX_CSTRING field_checksum = {STRING_WITH_LEN("CHECKSUM")};
446 static const LEX_CSTRING alias_checksum = {STRING_WITH_LEN("Checksum")};
447
448 static const LEX_CSTRING field_create_options = {
449 STRING_WITH_LEN("CREATE_OPTIONS")};
450 static const LEX_CSTRING alias_create_options = {
451 STRING_WITH_LEN("Create_options")};
452
453 static const LEX_CSTRING field_comment = {STRING_WITH_LEN("TABLE_COMMENT")};
454 static const LEX_CSTRING alias_comment = {STRING_WITH_LEN("Comment")};
455
456 if (alias_as_alias == false) {
457 if (query->add_select_item(field_engine, alias_engine) ||
458 query->add_select_item(field_version, alias_version) ||
459 query->add_select_item(field_row_format, alias_row_format) ||
460 query->add_select_item(field_rows, alias_rows) ||
461 query->add_select_item(field_avg_row_length, alias_avg_row_length) ||
462 query->add_select_item(field_data_length, alias_data_length) ||
463 query->add_select_item(field_max_data_length, alias_max_data_length) ||
464 query->add_select_item(field_index_length, alias_index_length) ||
465 query->add_select_item(field_data_free, alias_data_free) ||
466 query->add_select_item(field_auto_increment, alias_auto_increment) ||
467 query->add_select_item(field_create_time, alias_create_time) ||
468 query->add_select_item(field_update_time, alias_update_time) ||
469 query->add_select_item(field_check_time, alias_check_time) ||
470 query->add_select_item(field_collation, alias_collation) ||
471 query->add_select_item(field_checksum, alias_checksum) ||
472 query->add_select_item(field_create_options, alias_create_options) ||
473 query->add_select_item(field_comment, alias_comment))
474 return true;
475 } else {
476 if (query->add_select_item(alias_engine, alias_engine) ||
477 query->add_select_item(alias_version, alias_version) ||
478 query->add_select_item(alias_row_format, alias_row_format) ||
479 query->add_select_item(alias_rows, alias_rows) ||
480 query->add_select_item(alias_avg_row_length, alias_avg_row_length) ||
481 query->add_select_item(alias_data_length, alias_data_length) ||
482 query->add_select_item(alias_max_data_length, alias_max_data_length) ||
483 query->add_select_item(alias_index_length, alias_index_length) ||
484 query->add_select_item(alias_data_free, alias_data_free) ||
485 query->add_select_item(alias_auto_increment, alias_auto_increment) ||
486 query->add_select_item(alias_create_time, alias_create_time) ||
487 query->add_select_item(alias_update_time, alias_update_time) ||
488 query->add_select_item(alias_check_time, alias_check_time) ||
489 query->add_select_item(alias_collation, alias_collation) ||
490 query->add_select_item(alias_checksum, alias_checksum) ||
491 query->add_select_item(alias_create_options, alias_create_options) ||
492 query->add_select_item(alias_comment, alias_comment))
493 return true;
494 }
495
496 return false;
497 }
498
499 // Build a substitute query for SHOW TABLES / TABLE STATUS.
500
build_show_tables_query(const POS & pos,THD * thd,String * wild,Item * where_cond,bool include_status_fields)501 SELECT_LEX *build_show_tables_query(const POS &pos, THD *thd, String *wild,
502 Item *where_cond,
503 bool include_status_fields) {
504 static const LEX_CSTRING system_view_name = {STRING_WITH_LEN("TABLES")};
505
506 // Define field name literal used in query to be built.
507 static const LEX_CSTRING field_table = {STRING_WITH_LEN("TABLE_NAME")};
508 static const LEX_CSTRING alias_table = {STRING_WITH_LEN("Name")};
509
510 static const LEX_CSTRING field_database = {STRING_WITH_LEN("TABLE_SCHEMA")};
511 static const LEX_CSTRING alias_database = {STRING_WITH_LEN("Database")};
512
513 static const LEX_CSTRING field_table_type = {STRING_WITH_LEN("TABLE_TYPE")};
514 static const LEX_CSTRING alias_table_type = {STRING_WITH_LEN("Table_type")};
515
516 // Get the current logged in schema name
517 size_t dummy;
518 if (thd->lex->select_lex->db == nullptr &&
519 thd->lex->copy_db_to(&thd->lex->select_lex->db, &dummy))
520 return nullptr;
521
522 // Convert IS db and table name to desired form.
523 dd::info_schema::convert_table_name_case(thd->lex->select_lex->db,
524 wild ? wild->ptr() : nullptr);
525
526 LEX_STRING cur_db = {thd->lex->select_lex->db,
527 strlen(thd->lex->select_lex->db)};
528
529 if (check_and_convert_db_name(&cur_db, false) != Ident_name_check::OK)
530 return nullptr;
531
532 /*
533 Build the alias 'Tables_in_<dbname> %' we are building
534 SHOW TABLES and not SHOW TABLE STATUS
535 */
536 String_type alias;
537
538 if (include_status_fields) {
539 // Set the output alias for first column of SHOW TABLE STATUS as 'Name'
540 alias.append(alias_table.str);
541 } else {
542 // Build the output alias for SHOW TABLES
543 alias.append("Tables_in_");
544 alias.append(cur_db.str);
545 if (wild) {
546 alias.append(" (");
547 alias.append(wild->ptr());
548 alias.append(")");
549 }
550 }
551 char *tmp = static_cast<char *>(thd->alloc(alias.length() + 1));
552 memcpy(tmp, alias.c_str(), alias.length());
553 *(tmp + alias.length()) = '\0';
554 LEX_CSTRING alias_lex_string = {tmp, alias.length()};
555
556 /*
557 Build sub query.
558 ...
559 */
560 Select_lex_builder sub_query(&pos, thd);
561 if (sub_query.add_select_item(field_database, alias_database) ||
562 sub_query.add_select_item(field_table, alias_lex_string) ||
563 (include_status_fields == true &&
564 add_table_status_fields(&sub_query, false)) ||
565 (include_status_fields == false && thd->lex->verbose &&
566 sub_query.add_select_item(field_table_type, alias_table_type)))
567 return nullptr;
568
569 // ... FROM information_schema.tables ...
570 if (sub_query.add_from_item(INFORMATION_SCHEMA_NAME, system_view_name))
571 return nullptr;
572
573 /*
574 Build the top level query
575 */
576
577 Select_lex_builder top_query(&pos, thd);
578
579 // SELECT * FROM <sub_query> ...
580 if (top_query.add_select_item(alias_lex_string, alias_lex_string) ||
581 (include_status_fields == true &&
582 add_table_status_fields(&top_query, true)) ||
583 (include_status_fields == false && thd->lex->verbose &&
584 top_query.add_select_item(alias_table_type, alias_table_type)) ||
585 top_query.add_from_item(
586 sub_query.prepare_derived_table(system_view_name)))
587 return nullptr;
588
589 // ... WHERE 'Database' = <dbname> ...
590 Item *database_condition =
591 top_query.prepare_equal_item(alias_database, to_lex_cstring(cur_db));
592 if (top_query.add_condition(database_condition)) return nullptr;
593
594 // ... [ AND ] Table LIKE <value> ...
595 if (wild) {
596 Item *like = top_query.prepare_like_item(alias_lex_string, wild);
597 if (!like || top_query.add_condition(like)) return nullptr;
598 }
599
600 // ... [ AND ] <user provided condition> ...
601 if (where_cond && top_query.add_condition(where_cond)) return nullptr;
602
603 // ... ORDER BY 'Table' ...
604 if (top_query.add_order_by(alias_lex_string)) return nullptr;
605
606 SELECT_LEX *sl = top_query.prepare_select_lex();
607
608 // sql_command is set to SQL_QUERY after above call, so.
609 if (include_status_fields)
610 thd->lex->sql_command = SQLCOM_SHOW_TABLE_STATUS;
611 else
612 thd->lex->sql_command = SQLCOM_SHOW_TABLES;
613
614 return sl;
615 }
616
617 // Build a substitute query for SHOW COLUMNS/FIELDS OR DESCRIBE.
618
build_show_columns_query(const POS & pos,THD * thd,Table_ident * table_ident,const String * wild,Item * where_cond)619 SELECT_LEX *build_show_columns_query(const POS &pos, THD *thd,
620 Table_ident *table_ident,
621 const String *wild, Item *where_cond) {
622 static const LEX_CSTRING system_view_name = {STRING_WITH_LEN("COLUMNS")};
623
624 // Define field name literal used in query to be built.
625 static const LEX_CSTRING field_database = {STRING_WITH_LEN("TABLE_SCHEMA")};
626 static const LEX_CSTRING alias_database = {STRING_WITH_LEN("Database")};
627
628 static const LEX_CSTRING field_table = {STRING_WITH_LEN("TABLE_NAME")};
629 static const LEX_CSTRING alias_table = {STRING_WITH_LEN("Table")};
630
631 static const LEX_CSTRING field_field = {STRING_WITH_LEN("COLUMN_NAME")};
632 static const LEX_CSTRING alias_field = {STRING_WITH_LEN("Field")};
633
634 static const LEX_CSTRING field_column_type = {STRING_WITH_LEN("COLUMN_TYPE")};
635 static const LEX_CSTRING alias_column_type = {STRING_WITH_LEN("Type")};
636
637 static const LEX_CSTRING field_collation = {
638 STRING_WITH_LEN("COLLATION_NAME")};
639 static const LEX_CSTRING alias_collation = {STRING_WITH_LEN("Collation")};
640
641 static const LEX_CSTRING field_null = {STRING_WITH_LEN("IS_NULLABLE")};
642 static const LEX_CSTRING alias_null = {STRING_WITH_LEN("Null")};
643
644 static const LEX_CSTRING field_key = {STRING_WITH_LEN("COLUMN_KEY")};
645 static const LEX_CSTRING alias_key = {STRING_WITH_LEN("Key")};
646
647 static const LEX_CSTRING field_default = {STRING_WITH_LEN("COLUMN_DEFAULT")};
648 static const LEX_CSTRING alias_default = {STRING_WITH_LEN("Default")};
649
650 static const LEX_CSTRING field_extra = {STRING_WITH_LEN("EXTRA")};
651 static const LEX_CSTRING alias_extra = {STRING_WITH_LEN("Extra")};
652
653 static const LEX_CSTRING field_privileges = {STRING_WITH_LEN("PRIVILEGES")};
654 static const LEX_CSTRING alias_privileges = {STRING_WITH_LEN("Privileges")};
655
656 static const LEX_CSTRING field_comment = {STRING_WITH_LEN("COLUMN_COMMENT")};
657 static const LEX_CSTRING alias_comment = {STRING_WITH_LEN("Comment")};
658
659 static const LEX_CSTRING field_ordinal_position = {
660 STRING_WITH_LEN("ORDINAL_POSITION")};
661 static const LEX_CSTRING alias_ordinal_position = {
662 STRING_WITH_LEN("Ordinal_position")};
663
664 // Get the current logged in schema name
665 LEX_CSTRING cur_db;
666 if (table_ident->db.str) {
667 cur_db.str = table_ident->db.str;
668 cur_db.length = table_ident->db.length;
669 } else if (thd->lex->copy_db_to(&cur_db.str, &cur_db.length))
670 return nullptr;
671
672 // Convert IS db and table name to desired form.
673 dd::info_schema::convert_table_name_case(
674 const_cast<char *>(cur_db.str),
675 const_cast<char *>(table_ident->table.str));
676
677 /*
678 Build sub query.
679 ...
680 */
681 Select_lex_builder sub_query(&pos, thd);
682 if (sub_query.add_select_item(field_database, alias_database) ||
683 sub_query.add_select_item(field_table, alias_table) ||
684 sub_query.add_select_item(field_field, alias_field) ||
685 sub_query.add_select_item(field_column_type, alias_column_type) ||
686 (thd->lex->verbose == true &&
687 sub_query.add_select_item(field_collation, alias_collation)) ||
688 sub_query.add_select_item(field_null, alias_null) ||
689 sub_query.add_select_item(field_key, alias_key) ||
690 sub_query.add_select_item(field_default, alias_default) ||
691 sub_query.add_select_item(field_extra, alias_extra) ||
692 (thd->lex->verbose == true &&
693 sub_query.add_select_item(field_privileges, alias_privileges)) ||
694 (thd->lex->verbose == true &&
695 sub_query.add_select_item(field_comment, alias_comment)) ||
696 sub_query.add_select_item(field_ordinal_position, alias_ordinal_position))
697 return nullptr;
698
699 // ... FROM information_schema.columns ...
700 if (sub_query.add_from_item(INFORMATION_SCHEMA_NAME, system_view_name))
701 return nullptr;
702
703 /*
704 Build the top level query
705 */
706
707 Select_lex_builder top_query(&pos, thd);
708
709 // SELECT * FROM <sub_query> ...
710 if (top_query.add_select_item(alias_field, alias_field) ||
711 top_query.add_select_item(alias_column_type, alias_column_type) ||
712 (thd->lex->verbose == true &&
713 top_query.add_select_item(alias_collation, alias_collation)) ||
714 top_query.add_select_item(alias_null, alias_null) ||
715 top_query.add_select_item(alias_key, alias_key) ||
716 top_query.add_select_item(alias_default, alias_default) ||
717 top_query.add_select_item(alias_extra, alias_extra) ||
718 (thd->lex->verbose == true &&
719 top_query.add_select_item(alias_privileges, alias_privileges)) ||
720 (thd->lex->verbose == true &&
721 top_query.add_select_item(alias_comment, alias_comment)) ||
722 top_query.add_from_item(
723 sub_query.prepare_derived_table(system_view_name)))
724 return nullptr;
725
726 // ... WHERE 'Database' = <dbname> ...
727 Item *database_condition =
728 top_query.prepare_equal_item(alias_database, cur_db);
729 if (!database_condition || top_query.add_condition(database_condition))
730 return nullptr;
731
732 // ... AND Table = table_ident->table->str ...
733 Item *table_condition =
734 top_query.prepare_equal_item(alias_table, table_ident->table);
735 if (!table_condition || top_query.add_condition(table_condition))
736 return nullptr;
737
738 // ... [ AND ] Field LIKE <value> ...
739 if (wild) {
740 Item *like = top_query.prepare_like_item(alias_field, wild);
741 if (!like || top_query.add_condition(like)) return nullptr;
742 }
743
744 // ... [ AND ] <user provided condition> ...
745 if (where_cond && top_query.add_condition(where_cond)) return nullptr;
746
747 // ... ORDER BY 'Ordinal_position' ...
748 if (top_query.add_order_by(alias_ordinal_position)) return nullptr;
749
750 // Prepare the SELECT_LEX
751 SELECT_LEX *sl = top_query.prepare_select_lex();
752 if (sl == nullptr) return nullptr;
753
754 // sql_command is set to SQL_QUERY after above call, so.
755 thd->lex->sql_command = SQLCOM_SHOW_FIELDS;
756
757 return sl;
758 }
759
760 // Build a substitute query for SHOW INDEX|KEYS|INDEXES
761
build_show_keys_query(const POS & pos,THD * thd,Table_ident * table_ident,Item * where_cond)762 SELECT_LEX *build_show_keys_query(const POS &pos, THD *thd,
763 Table_ident *table_ident, Item *where_cond) {
764 LEX_CSTRING system_view_name = {STRING_WITH_LEN("SHOW_STATISTICS")};
765
766 // Define field name literal used in query to be built.
767
768 static const LEX_CSTRING field_database = {STRING_WITH_LEN("TABLE_SCHEMA")};
769 static const LEX_CSTRING alias_database = {STRING_WITH_LEN("Database")};
770
771 static const LEX_CSTRING field_table = {STRING_WITH_LEN("TABLE_NAME")};
772 static const LEX_CSTRING alias_table = {STRING_WITH_LEN("Table")};
773
774 static const LEX_CSTRING field_non_unique = {STRING_WITH_LEN("NON_UNIQUE")};
775 static const LEX_CSTRING alias_non_unique = {STRING_WITH_LEN("Non_unique")};
776
777 static const LEX_CSTRING field_key = {STRING_WITH_LEN("INDEX_NAME")};
778 static const LEX_CSTRING alias_key = {STRING_WITH_LEN("Key_name")};
779
780 static const LEX_CSTRING field_seq_in_index = {
781 STRING_WITH_LEN("SEQ_IN_INDEX")};
782 static const LEX_CSTRING alias_seq_in_index = {
783 STRING_WITH_LEN("Seq_in_index")};
784
785 static const LEX_CSTRING field_column_name = {STRING_WITH_LEN("COLUMN_NAME")};
786 static const LEX_CSTRING alias_column_name = {STRING_WITH_LEN("Column_name")};
787
788 static const LEX_CSTRING field_collation = {STRING_WITH_LEN("COLLATION")};
789 static const LEX_CSTRING alias_collation = {STRING_WITH_LEN("Collation")};
790
791 static const LEX_CSTRING field_cardinality = {STRING_WITH_LEN("CARDINALITY")};
792 static const LEX_CSTRING alias_cardinality = {STRING_WITH_LEN("Cardinality")};
793
794 static const LEX_CSTRING field_sub_part = {STRING_WITH_LEN("SUB_PART")};
795 static const LEX_CSTRING alias_sub_part = {STRING_WITH_LEN("Sub_part")};
796
797 static const LEX_CSTRING field_packed = {STRING_WITH_LEN("PACKED")};
798 static const LEX_CSTRING alias_packed = {STRING_WITH_LEN("Packed")};
799
800 static const LEX_CSTRING field_null = {STRING_WITH_LEN("NULLABLE")};
801 static const LEX_CSTRING alias_null = {STRING_WITH_LEN("Null")};
802
803 static const LEX_CSTRING field_type = {STRING_WITH_LEN("INDEX_TYPE")};
804 static const LEX_CSTRING alias_type = {STRING_WITH_LEN("Index_type")};
805
806 static const LEX_CSTRING field_comment = {STRING_WITH_LEN("COMMENT")};
807 static const LEX_CSTRING alias_comment = {STRING_WITH_LEN("Comment")};
808
809 static const LEX_CSTRING field_index_comment = {
810 STRING_WITH_LEN("INDEX_COMMENT")};
811 static const LEX_CSTRING alias_index_comment = {
812 STRING_WITH_LEN("Index_comment")};
813
814 static const LEX_CSTRING field_is_visible = {STRING_WITH_LEN("IS_VISIBLE")};
815 static const LEX_CSTRING alias_visible = {STRING_WITH_LEN("Visible")};
816
817 static const LEX_CSTRING alias_index_pos = {
818 STRING_WITH_LEN("INDEX_ORDINAL_POSITION")};
819
820 static const LEX_CSTRING alias_column_pos = {
821 STRING_WITH_LEN("COLUMN_ORDINAL_POSITION")};
822
823 static const LEX_CSTRING field_expression = {STRING_WITH_LEN("EXPRESSION")};
824 static const LEX_CSTRING alias_expression = {STRING_WITH_LEN("Expression")};
825
826 // Get the current logged in schema name
827 LEX_CSTRING cur_db;
828 if (table_ident->db.str) {
829 cur_db.str = table_ident->db.str;
830 cur_db.length = table_ident->db.length;
831 } else if (thd->lex->copy_db_to(&cur_db.str, &cur_db.length))
832 return nullptr;
833
834 // Convert IS db and table name to desired form.
835 dd::info_schema::convert_table_name_case(
836 const_cast<char *>(cur_db.str),
837 const_cast<char *>(table_ident->table.str));
838
839 /*
840 Build sub query.
841 ...
842 */
843 Select_lex_builder sub_query(&pos, thd);
844 if (sub_query.add_select_item(field_database, alias_database) ||
845 sub_query.add_select_item(field_table, alias_table) ||
846 sub_query.add_select_item(field_non_unique, alias_non_unique) ||
847 sub_query.add_select_item(field_key, alias_key) ||
848 sub_query.add_select_item(field_seq_in_index, alias_seq_in_index) ||
849 sub_query.add_select_item(field_column_name, alias_column_name) ||
850 sub_query.add_select_item(field_collation, alias_collation) ||
851 sub_query.add_select_item(field_cardinality, alias_cardinality) ||
852 sub_query.add_select_item(field_sub_part, alias_sub_part) ||
853 sub_query.add_select_item(field_packed, alias_packed) ||
854 sub_query.add_select_item(field_null, alias_null) ||
855 sub_query.add_select_item(field_type, alias_type) ||
856 sub_query.add_select_item(field_comment, alias_comment) ||
857 sub_query.add_select_item(field_index_comment, alias_index_comment) ||
858 sub_query.add_select_item(field_is_visible, alias_visible) ||
859 sub_query.add_select_item(field_expression, alias_expression) ||
860 sub_query.add_select_item(alias_index_pos, alias_index_pos) ||
861 sub_query.add_select_item(alias_column_pos, alias_column_pos))
862 return nullptr;
863
864 // ... FROM information_schema.columns ...
865 if (sub_query.add_from_item(INFORMATION_SCHEMA_NAME, system_view_name))
866 return nullptr;
867
868 /*
869 Build the top level query
870 */
871
872 Select_lex_builder top_query(&pos, thd);
873
874 // SELECT * FROM <sub_query> ...
875 if (top_query.add_select_item(alias_table, alias_table) ||
876 top_query.add_select_item(alias_non_unique, alias_non_unique) ||
877 top_query.add_select_item(alias_key, alias_key) ||
878 top_query.add_select_item(alias_seq_in_index, alias_seq_in_index) ||
879 top_query.add_select_item(alias_column_name, alias_column_name) ||
880 top_query.add_select_item(alias_collation, alias_collation) ||
881 top_query.add_select_item(alias_cardinality, alias_cardinality) ||
882 top_query.add_select_item(alias_sub_part, alias_sub_part) ||
883 top_query.add_select_item(alias_packed, alias_packed) ||
884 top_query.add_select_item(alias_null, alias_null) ||
885 top_query.add_select_item(alias_type, alias_type) ||
886 top_query.add_select_item(alias_comment, alias_comment) ||
887 top_query.add_select_item(alias_index_comment, alias_index_comment) ||
888 top_query.add_select_item(alias_visible, alias_visible) ||
889 top_query.add_select_item(alias_expression, alias_expression) ||
890 top_query.add_from_item(
891 sub_query.prepare_derived_table(system_view_name)))
892 return nullptr;
893
894 // ... WHERE 'Database' = <dbname> ...
895 Item *database_condition =
896 top_query.prepare_equal_item(alias_database, cur_db);
897 if (!database_condition || top_query.add_condition(database_condition))
898 return nullptr;
899
900 // ... AND Table = table_ident->table->str ...
901 Item *table_condition =
902 top_query.prepare_equal_item(alias_table, table_ident->table);
903 if (!table_condition || top_query.add_condition(table_condition))
904 return nullptr;
905
906 // ... [ AND ] <user provided condition> ...
907 if (where_cond && top_query.add_condition(where_cond)) return nullptr;
908
909 // ... ORDER BY 'INDEX_ORDINAL_POSITION, COLUMN_ORDINAL_POSITION' ...
910 if (top_query.add_order_by(alias_index_pos) ||
911 top_query.add_order_by(alias_column_pos))
912 return nullptr;
913
914 // Prepare the SELECT_LEX
915 SELECT_LEX *sl = top_query.prepare_select_lex();
916 if (sl == nullptr) return nullptr;
917
918 // sql_command is set to SQL_QUERY after above call, so.
919 thd->lex->sql_command = SQLCOM_SHOW_KEYS;
920
921 return sl;
922 }
923
924 // Build a substitute query for SHOW TRIGGERS
925
build_show_triggers_query(const POS & pos,THD * thd,String * wild,Item * where_cond)926 SELECT_LEX *build_show_triggers_query(const POS &pos, THD *thd, String *wild,
927 Item *where_cond) {
928 static const LEX_CSTRING system_view_name = {STRING_WITH_LEN("TRIGGERS")};
929
930 // Define field name literal used in query to be built.
931 static const LEX_CSTRING field_database = {
932 STRING_WITH_LEN("EVENT_OBJECT_SCHEMA")};
933 static const LEX_CSTRING alias_database = {STRING_WITH_LEN("Database")};
934
935 static const LEX_CSTRING field_trigger = {STRING_WITH_LEN("TRIGGER_NAME")};
936 static const LEX_CSTRING alias_trigger = {STRING_WITH_LEN("Trigger")};
937
938 static const LEX_CSTRING field_manipulation = {
939 STRING_WITH_LEN("EVENT_MANIPULATION")};
940 static const LEX_CSTRING alias_manipulation = {STRING_WITH_LEN("Event")};
941
942 static const LEX_CSTRING field_table = {
943 STRING_WITH_LEN("EVENT_OBJECT_TABLE")};
944 static const LEX_CSTRING alias_table = {STRING_WITH_LEN("Table")};
945
946 static const LEX_CSTRING field_statement = {
947 STRING_WITH_LEN("ACTION_STATEMENT")};
948 static const LEX_CSTRING alias_statement = {STRING_WITH_LEN("Statement")};
949
950 static const LEX_CSTRING field_timing = {STRING_WITH_LEN("ACTION_TIMING")};
951 static const LEX_CSTRING alias_timing = {STRING_WITH_LEN("Timing")};
952
953 static const LEX_CSTRING field_created = {STRING_WITH_LEN("CREATED")};
954 static const LEX_CSTRING alias_created = {STRING_WITH_LEN("Created")};
955
956 static const LEX_CSTRING field_sql_mode = {STRING_WITH_LEN("SQL_MODE")};
957 static const LEX_CSTRING alias_sql_mode = {STRING_WITH_LEN("sql_mode")};
958
959 static const LEX_CSTRING field_definer = {STRING_WITH_LEN("DEFINER")};
960 static const LEX_CSTRING alias_definer = {STRING_WITH_LEN("Definer")};
961
962 static const LEX_CSTRING field_client_cs = {
963 STRING_WITH_LEN("CHARACTER_SET_CLIENT")};
964 static const LEX_CSTRING alias_client_cs = {
965 STRING_WITH_LEN("character_set_client")};
966
967 static const LEX_CSTRING field_conn_coll = {
968 STRING_WITH_LEN("COLLATION_CONNECTION")};
969 static const LEX_CSTRING alias_conn_coll = {
970 STRING_WITH_LEN("collation_connection")};
971
972 static const LEX_CSTRING field_db_coll = {
973 STRING_WITH_LEN("DATABASE_COLLATION")};
974 static const LEX_CSTRING alias_db_coll = {
975 STRING_WITH_LEN("Database Collation")};
976
977 static const LEX_CSTRING field_action_order = {
978 STRING_WITH_LEN("ACTION_ORDER")};
979 static const LEX_CSTRING alias_action_order = {
980 STRING_WITH_LEN("action_order")};
981
982 // Get the current logged in schema name
983 size_t dummy;
984 if (thd->lex->select_lex->db == nullptr &&
985 thd->lex->copy_db_to(&thd->lex->select_lex->db, &dummy))
986 return nullptr;
987
988 // Convert IS db and table name to desired form.
989 dd::info_schema::convert_table_name_case(thd->lex->select_lex->db,
990 wild ? wild->ptr() : nullptr);
991
992 LEX_STRING cur_db = {thd->lex->select_lex->db,
993 strlen(thd->lex->select_lex->db)};
994
995 if (check_and_convert_db_name(&cur_db, false) != Ident_name_check::OK)
996 return nullptr;
997
998 /*
999 Build sub query.
1000 ...
1001 */
1002 Select_lex_builder sub_query(&pos, thd);
1003 if (sub_query.add_select_item(field_database, alias_database) ||
1004 sub_query.add_select_item(field_trigger, alias_trigger) ||
1005 sub_query.add_select_item(field_manipulation, alias_manipulation) ||
1006 sub_query.add_select_item(field_table, alias_table) ||
1007 sub_query.add_select_item(field_statement, alias_statement) ||
1008 sub_query.add_select_item(field_timing, alias_timing) ||
1009 sub_query.add_select_item(field_created, alias_created) ||
1010 sub_query.add_select_item(field_sql_mode, alias_sql_mode) ||
1011 sub_query.add_select_item(field_definer, alias_definer) ||
1012 sub_query.add_select_item(field_client_cs, alias_client_cs) ||
1013 sub_query.add_select_item(field_conn_coll, alias_conn_coll) ||
1014 sub_query.add_select_item(field_db_coll, alias_db_coll) ||
1015 sub_query.add_select_item(field_action_order, alias_action_order))
1016 return nullptr;
1017
1018 // ... FROM information_schema.tables ...
1019 if (sub_query.add_from_item(INFORMATION_SCHEMA_NAME, system_view_name))
1020 return nullptr;
1021
1022 /*
1023 Build the top level query
1024 */
1025
1026 Select_lex_builder top_query(&pos, thd);
1027
1028 // SELECT * FROM <sub_query> ...
1029 if (top_query.add_select_item(alias_trigger, alias_trigger) ||
1030 top_query.add_select_item(alias_manipulation, alias_manipulation) ||
1031 top_query.add_select_item(alias_table, alias_table) ||
1032 top_query.add_select_item(alias_statement, alias_statement) ||
1033 top_query.add_select_item(alias_timing, alias_timing) ||
1034 top_query.add_select_item(alias_created, alias_created) ||
1035 top_query.add_select_item(alias_sql_mode, alias_sql_mode) ||
1036 top_query.add_select_item(alias_definer, alias_definer) ||
1037 top_query.add_select_item(alias_client_cs, alias_client_cs) ||
1038 top_query.add_select_item(alias_conn_coll, alias_conn_coll) ||
1039 top_query.add_select_item(alias_db_coll, alias_db_coll) ||
1040 top_query.add_from_item(
1041 sub_query.prepare_derived_table(system_view_name)))
1042 return nullptr;
1043
1044 // ... WHERE 'Database' = <dbname> ...
1045 Item *database_condition =
1046 top_query.prepare_equal_item(alias_database, to_lex_cstring(cur_db));
1047 if (top_query.add_condition(database_condition)) return nullptr;
1048
1049 // ... [ AND ] Table LIKE <value> ...
1050 if (wild) {
1051 Item *like = top_query.prepare_like_item(alias_table, wild);
1052 if (!like || top_query.add_condition(like)) return nullptr;
1053 }
1054
1055 // ... [ AND ] <user provided condition> ...
1056 if (where_cond && top_query.add_condition(where_cond)) return nullptr;
1057
1058 // ... ORDER BY 'Table, Event, Timing, Action order' ...
1059 if (top_query.add_order_by(alias_table) ||
1060 top_query.add_order_by(alias_manipulation) ||
1061 top_query.add_order_by(alias_timing) ||
1062 top_query.add_order_by(alias_action_order))
1063 return nullptr;
1064
1065 SELECT_LEX *sl = top_query.prepare_select_lex();
1066
1067 // sql_command is set to SQL_QUERY after above call, so.
1068 thd->lex->sql_command = SQLCOM_SHOW_TRIGGERS;
1069
1070 return sl;
1071 }
1072
1073 // Build a substitute query for SHOW PROCEDURES / FUNCTIONS
1074
build_show_procedures_query(const POS & pos,THD * thd,String * wild,Item * where_cond)1075 SELECT_LEX *build_show_procedures_query(const POS &pos, THD *thd, String *wild,
1076 Item *where_cond) {
1077 enum_sql_command current_cmd = thd->lex->sql_command;
1078
1079 static const LEX_CSTRING system_view_name = {STRING_WITH_LEN("ROUTINES")};
1080
1081 // Define field name literal used in query to be built.
1082 static const LEX_CSTRING field_db = {STRING_WITH_LEN("ROUTINE_SCHEMA")};
1083 static const LEX_CSTRING alias_db = {STRING_WITH_LEN("Db")};
1084
1085 static const LEX_CSTRING field_name = {STRING_WITH_LEN("ROUTINE_NAME")};
1086 static const LEX_CSTRING alias_name = {STRING_WITH_LEN("Name")};
1087
1088 static const LEX_CSTRING field_type = {STRING_WITH_LEN("ROUTINE_TYPE")};
1089 static const LEX_CSTRING alias_type = {STRING_WITH_LEN("Type")};
1090
1091 static const LEX_CSTRING field_definer = {STRING_WITH_LEN("DEFINER")};
1092 static const LEX_CSTRING alias_definer = {STRING_WITH_LEN("Definer")};
1093
1094 static const LEX_CSTRING field_modified = {STRING_WITH_LEN("LAST_ALTERED")};
1095 static const LEX_CSTRING alias_modified = {STRING_WITH_LEN("Modified")};
1096
1097 static const LEX_CSTRING field_created = {STRING_WITH_LEN("CREATED")};
1098 static const LEX_CSTRING alias_created = {STRING_WITH_LEN("Created")};
1099
1100 static const LEX_CSTRING field_security_type = {
1101 STRING_WITH_LEN("SECURITY_TYPE")};
1102 static const LEX_CSTRING alias_security_type = {
1103 STRING_WITH_LEN("Security_type")};
1104
1105 static const LEX_CSTRING field_comment = {STRING_WITH_LEN("ROUTINE_COMMENT")};
1106 static const LEX_CSTRING alias_comment = {STRING_WITH_LEN("Comment")};
1107
1108 static const LEX_CSTRING field_client_cs = {
1109 STRING_WITH_LEN("CHARACTER_SET_CLIENT")};
1110 static const LEX_CSTRING alias_client_cs = {
1111 STRING_WITH_LEN("character_set_client")};
1112
1113 static const LEX_CSTRING field_conn_coll = {
1114 STRING_WITH_LEN("COLLATION_CONNECTION")};
1115 static const LEX_CSTRING alias_conn_coll = {
1116 STRING_WITH_LEN("collation_connection")};
1117
1118 static const LEX_CSTRING field_db_coll = {
1119 STRING_WITH_LEN("DATABASE_COLLATION")};
1120 static const LEX_CSTRING alias_db_coll = {
1121 STRING_WITH_LEN("Database Collation")};
1122
1123 /*
1124 Build sub query.
1125 ...
1126 */
1127 Select_lex_builder sub_query(&pos, thd);
1128 if (sub_query.add_select_item(field_db, alias_db) ||
1129 sub_query.add_select_item(field_name, alias_name) ||
1130 sub_query.add_select_item(field_type, alias_type) ||
1131 sub_query.add_select_item(field_definer, alias_definer) ||
1132 sub_query.add_select_item(field_modified, alias_modified) ||
1133 sub_query.add_select_item(field_created, alias_created) ||
1134 sub_query.add_select_item(field_security_type, alias_security_type) ||
1135 sub_query.add_select_item(field_comment, alias_comment) ||
1136 sub_query.add_select_item(field_client_cs, alias_client_cs) ||
1137 sub_query.add_select_item(field_conn_coll, alias_conn_coll) ||
1138 sub_query.add_select_item(field_db_coll, alias_db_coll))
1139 return nullptr;
1140
1141 // ... FROM information_schema.tables ...
1142 if (sub_query.add_from_item(INFORMATION_SCHEMA_NAME, system_view_name))
1143 return nullptr;
1144
1145 /*
1146 Build the top level query
1147 */
1148
1149 Select_lex_builder top_query(&pos, thd);
1150
1151 // SELECT * FROM <sub_query> ...
1152 if (top_query.add_star_select_item() ||
1153 top_query.add_from_item(
1154 sub_query.prepare_derived_table(system_view_name)))
1155 return nullptr;
1156
1157 // ... WHERE 'Type' = 'PROCEDURE | FUNCTION'
1158 const char *current_type = thd->lex->sql_command == SQLCOM_SHOW_STATUS_PROC
1159 ? "PROCEDURE"
1160 : "FUNCTION";
1161 LEX_CSTRING tmp_lex_string = {current_type, strlen(current_type)};
1162 Item *type_condition =
1163 top_query.prepare_equal_item(alias_type, tmp_lex_string);
1164 if (top_query.add_condition(type_condition)) return nullptr;
1165
1166 // ... [ AND ] Name LIKE <value> ...
1167 if (wild) {
1168 Item *like = top_query.prepare_like_item(alias_name, wild);
1169 if (!like || top_query.add_condition(like)) return nullptr;
1170 }
1171
1172 // ... [ AND ] <user provided condition> ...
1173 if (where_cond && top_query.add_condition(where_cond)) return nullptr;
1174
1175 // ... ORDER BY 'Db, Name' ...
1176 if (top_query.add_order_by(alias_db) || top_query.add_order_by(alias_name))
1177 return nullptr;
1178
1179 SELECT_LEX *sl = top_query.prepare_select_lex();
1180
1181 // sql_command is set to SQL_QUERY after above call, so.
1182 thd->lex->sql_command = current_cmd;
1183
1184 return sl;
1185 }
1186
1187 // Build a substitute query for SHOW EVENTS
1188
build_show_events_query(const POS & pos,THD * thd,String * wild,Item * where_cond)1189 SELECT_LEX *build_show_events_query(const POS &pos, THD *thd, String *wild,
1190 Item *where_cond) {
1191 static const LEX_CSTRING system_view_name = {STRING_WITH_LEN("EVENTS")};
1192
1193 // Define field name literal used in query to be built.
1194 static const LEX_CSTRING field_db = {STRING_WITH_LEN("EVENT_SCHEMA")};
1195 static const LEX_CSTRING alias_db = {STRING_WITH_LEN("Db")};
1196
1197 static const LEX_CSTRING field_name = {STRING_WITH_LEN("EVENT_NAME")};
1198 static const LEX_CSTRING alias_name = {STRING_WITH_LEN("Name")};
1199
1200 static const LEX_CSTRING field_definer = {STRING_WITH_LEN("DEFINER")};
1201 static const LEX_CSTRING alias_definer = {STRING_WITH_LEN("Definer")};
1202
1203 static const LEX_CSTRING field_zone = {STRING_WITH_LEN("TIME_ZONE")};
1204 static const LEX_CSTRING alias_zone = {STRING_WITH_LEN("Time zone")};
1205
1206 static const LEX_CSTRING field_type = {STRING_WITH_LEN("EVENT_TYPE")};
1207 static const LEX_CSTRING alias_type = {STRING_WITH_LEN("Type")};
1208
1209 static const LEX_CSTRING field_execute_at = {STRING_WITH_LEN("EXECUTE_AT")};
1210 static const LEX_CSTRING alias_execute_at = {STRING_WITH_LEN("Execute at")};
1211
1212 static const LEX_CSTRING field_interval_value = {
1213 STRING_WITH_LEN("INTERVAL_VALUE")};
1214 static const LEX_CSTRING alias_interval_value = {
1215 STRING_WITH_LEN("Interval value")};
1216
1217 static const LEX_CSTRING field_interval_field = {
1218 STRING_WITH_LEN("INTERVAL_FIELD")};
1219 static const LEX_CSTRING alias_interval_field = {
1220 STRING_WITH_LEN("Interval field")};
1221
1222 static const LEX_CSTRING field_starts = {STRING_WITH_LEN("STARTS")};
1223 static const LEX_CSTRING alias_starts = {STRING_WITH_LEN("Starts")};
1224
1225 static const LEX_CSTRING field_ends = {STRING_WITH_LEN("ENDS")};
1226 static const LEX_CSTRING alias_ends = {STRING_WITH_LEN("Ends")};
1227
1228 static const LEX_CSTRING field_status = {STRING_WITH_LEN("STATUS")};
1229 static const LEX_CSTRING alias_status = {STRING_WITH_LEN("Status")};
1230
1231 static const LEX_CSTRING field_originator = {STRING_WITH_LEN("ORIGINATOR")};
1232 static const LEX_CSTRING alias_originator = {STRING_WITH_LEN("Originator")};
1233
1234 static const LEX_CSTRING field_client_cs = {
1235 STRING_WITH_LEN("CHARACTER_SET_CLIENT")};
1236 static const LEX_CSTRING alias_client_cs = {
1237 STRING_WITH_LEN("character_set_client")};
1238
1239 static const LEX_CSTRING field_conn_coll = {
1240 STRING_WITH_LEN("COLLATION_CONNECTION")};
1241 static const LEX_CSTRING alias_conn_coll = {
1242 STRING_WITH_LEN("collation_connection")};
1243
1244 static const LEX_CSTRING field_db_coll = {
1245 STRING_WITH_LEN("DATABASE_COLLATION")};
1246 static const LEX_CSTRING alias_db_coll = {
1247 STRING_WITH_LEN("Database Collation")};
1248
1249 // Get the current logged in schema name
1250 size_t dummy;
1251 if (thd->lex->select_lex->db == nullptr &&
1252 thd->lex->copy_db_to(&thd->lex->select_lex->db, &dummy))
1253 return nullptr;
1254
1255 // Convert IS db and table name to desired form.
1256 dd::info_schema::convert_table_name_case(thd->lex->select_lex->db,
1257 wild ? wild->ptr() : nullptr);
1258
1259 LEX_STRING cur_db = {thd->lex->select_lex->db,
1260 strlen(thd->lex->select_lex->db)};
1261
1262 if (check_and_convert_db_name(&cur_db, false) != Ident_name_check::OK)
1263 return nullptr;
1264
1265 /*
1266 Build sub query.
1267 ...
1268 */
1269 Select_lex_builder sub_query(&pos, thd);
1270 if (sub_query.add_select_item(field_db, alias_db) ||
1271 sub_query.add_select_item(field_name, alias_name) ||
1272 sub_query.add_select_item(field_definer, alias_definer) ||
1273 sub_query.add_select_item(field_zone, alias_zone) ||
1274 sub_query.add_select_item(field_type, alias_type) ||
1275 sub_query.add_select_item(field_execute_at, alias_execute_at) ||
1276 sub_query.add_select_item(field_interval_value, alias_interval_value) ||
1277 sub_query.add_select_item(field_interval_field, alias_interval_field) ||
1278 sub_query.add_select_item(field_starts, alias_starts) ||
1279 sub_query.add_select_item(field_ends, alias_ends) ||
1280 sub_query.add_select_item(field_status, alias_status) ||
1281 sub_query.add_select_item(field_originator, alias_originator) ||
1282 sub_query.add_select_item(field_client_cs, alias_client_cs) ||
1283 sub_query.add_select_item(field_conn_coll, alias_conn_coll) ||
1284 sub_query.add_select_item(field_db_coll, alias_db_coll))
1285 return nullptr;
1286
1287 // ... FROM information_schema.tables ...
1288 if (sub_query.add_from_item(INFORMATION_SCHEMA_NAME, system_view_name))
1289 return nullptr;
1290
1291 /*
1292 Build the top level query
1293 */
1294
1295 Select_lex_builder top_query(&pos, thd);
1296
1297 // SELECT * FROM <sub_query> ...
1298 if (top_query.add_star_select_item() ||
1299 top_query.add_from_item(
1300 sub_query.prepare_derived_table(system_view_name)))
1301 return nullptr;
1302
1303 // ... WHERE 'Database' = <dbname> ...
1304 Item *database_condition =
1305 top_query.prepare_equal_item(alias_db, to_lex_cstring(cur_db));
1306 if (top_query.add_condition(database_condition)) return nullptr;
1307
1308 // ... [ AND ] Name LIKE <value> ...
1309 if (wild) {
1310 Item *like = top_query.prepare_like_item(alias_name, wild);
1311 if (!like || top_query.add_condition(like)) return nullptr;
1312 }
1313
1314 // ... [ AND ] <user provided condition> ...
1315 if (where_cond && top_query.add_condition(where_cond)) return nullptr;
1316
1317 // ... ORDER BY 'Db, Name' ...
1318 if (top_query.add_order_by(alias_db) || top_query.add_order_by(alias_name))
1319 return nullptr;
1320
1321 SELECT_LEX *sl = top_query.prepare_select_lex();
1322
1323 // sql_command is set to SQL_QUERY after above call, so.
1324 thd->lex->sql_command = SQLCOM_SHOW_EVENTS;
1325
1326 return sl;
1327 }
1328
1329 } // namespace info_schema
1330 } // namespace dd
1331