00001 /* Copyright (C) 2000-2004 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 /* Function with list databases, tables or fields */ 00019 00020 #include "mysql_priv.h" 00021 #include "sql_select.h" // For select_describe 00022 #include "sql_show.h" 00023 #include "repl_failsafe.h" 00024 #include "sp.h" 00025 #include "sp_head.h" 00026 #include "sql_trigger.h" 00027 #include "authors.h" 00028 #include "contributors.h" 00029 #include "events.h" 00030 #include "event_timed.h" 00031 #include <my_dir.h> 00032 00033 #ifdef WITH_PARTITION_STORAGE_ENGINE 00034 #include "ha_partition.h" 00035 #endif 00036 00037 enum enum_i_s_events_fields 00038 { 00039 ISE_EVENT_CATALOG= 0, 00040 ISE_EVENT_SCHEMA, 00041 ISE_EVENT_NAME, 00042 ISE_DEFINER, 00043 ISE_EVENT_BODY, 00044 ISE_EVENT_DEFINITION, 00045 ISE_EVENT_TYPE, 00046 ISE_EXECUTE_AT, 00047 ISE_INTERVAL_VALUE, 00048 ISE_INTERVAL_FIELD, 00049 ISE_SQL_MODE, 00050 ISE_STARTS, 00051 ISE_ENDS, 00052 ISE_STATUS, 00053 ISE_ON_COMPLETION, 00054 ISE_CREATED, 00055 ISE_LAST_ALTERED, 00056 ISE_LAST_EXECUTED, 00057 ISE_EVENT_COMMENT 00058 }; 00059 00060 00061 static const char *grant_names[]={ 00062 "select","insert","update","delete","create","drop","reload","shutdown", 00063 "process","file","grant","references","index","alter"}; 00064 00065 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00066 static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **), 00067 "grant_types", 00068 grant_names, NULL}; 00069 #endif 00070 00071 static void store_key_options(THD *thd, String *packet, TABLE *table, 00072 KEY *key_info); 00073 00074 static void 00075 append_algorithm(TABLE_LIST *table, String *buff); 00076 00077 00078 /*************************************************************************** 00079 ** List all table types supported 00080 ***************************************************************************/ 00081 00082 static my_bool show_handlerton(THD *thd, st_plugin_int *plugin, 00083 void *arg) 00084 { 00085 handlerton *default_type= (handlerton *) arg; 00086 Protocol *protocol= thd->protocol; 00087 handlerton *hton= (handlerton *)plugin->data; 00088 00089 if (!(hton->flags & HTON_HIDDEN)) 00090 { 00091 protocol->prepare_for_resend(); 00092 protocol->store(plugin->name.str, plugin->name.length, 00093 system_charset_info); 00094 const char *option_name= show_comp_option_name[(int) hton->state]; 00095 00096 if (hton->state == SHOW_OPTION_YES && default_type == hton) 00097 option_name= "DEFAULT"; 00098 protocol->store(option_name, system_charset_info); 00099 protocol->store(plugin->plugin->descr, system_charset_info); 00100 protocol->store(hton->commit ? "YES" : "NO", system_charset_info); 00101 protocol->store(hton->prepare ? "YES" : "NO", system_charset_info); 00102 protocol->store(hton->savepoint_set ? "YES" : "NO", system_charset_info); 00103 00104 return protocol->write() ? 1 : 0; 00105 } 00106 return 0; 00107 } 00108 00109 bool mysqld_show_storage_engines(THD *thd) 00110 { 00111 List<Item> field_list; 00112 Protocol *protocol= thd->protocol; 00113 DBUG_ENTER("mysqld_show_storage_engines"); 00114 00115 field_list.push_back(new Item_empty_string("Engine",10)); 00116 field_list.push_back(new Item_empty_string("Support",10)); 00117 field_list.push_back(new Item_empty_string("Comment",80)); 00118 field_list.push_back(new Item_empty_string("Transactions",3)); 00119 field_list.push_back(new Item_empty_string("XA",3)); 00120 field_list.push_back(new Item_empty_string("Savepoints",3)); 00121 00122 if (protocol->send_fields(&field_list, 00123 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 00124 DBUG_RETURN(TRUE); 00125 00126 if (plugin_foreach(thd, show_handlerton, 00127 MYSQL_STORAGE_ENGINE_PLUGIN, thd->variables.table_type)) 00128 DBUG_RETURN(TRUE); 00129 00130 send_eof(thd); 00131 DBUG_RETURN(FALSE); 00132 } 00133 00134 static int make_version_string(char *buf, int buf_length, uint version) 00135 { 00136 return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff); 00137 } 00138 00139 static my_bool show_plugins(THD *thd, st_plugin_int *plugin, 00140 void *arg) 00141 { 00142 TABLE *table= (TABLE*) arg; 00143 struct st_mysql_plugin *plug= plugin->plugin; 00144 Protocol *protocol= thd->protocol; 00145 CHARSET_INFO *cs= system_charset_info; 00146 char version_buf[20]; 00147 00148 restore_record(table, s->default_values); 00149 00150 table->field[0]->store(plugin->name.str, plugin->name.length, cs); 00151 00152 table->field[1]->store(version_buf, 00153 make_version_string(version_buf, sizeof(version_buf), plug->version), 00154 cs); 00155 00156 00157 switch (plugin->state) 00158 { 00159 /* case PLUGIN_IS_FREED: does not happen */ 00160 case PLUGIN_IS_DELETED: 00161 table->field[2]->store(STRING_WITH_LEN("DELETED"), cs); 00162 break; 00163 case PLUGIN_IS_UNINITIALIZED: 00164 table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs); 00165 break; 00166 case PLUGIN_IS_READY: 00167 table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs); 00168 break; 00169 default: 00170 DBUG_ASSERT(0); 00171 } 00172 00173 table->field[3]->store(plugin_type_names[plug->type].str, 00174 plugin_type_names[plug->type].length, 00175 cs); 00176 table->field[4]->store(version_buf, 00177 make_version_string(version_buf, sizeof(version_buf), 00178 *(uint *)plug->info), cs); 00179 00180 if (plugin->plugin_dl) 00181 { 00182 table->field[5]->store(plugin->plugin_dl->dl.str, 00183 plugin->plugin_dl->dl.length, cs); 00184 table->field[5]->set_notnull(); 00185 table->field[6]->store(version_buf, 00186 make_version_string(version_buf, sizeof(version_buf), 00187 plugin->plugin_dl->version), 00188 cs); 00189 table->field[6]->set_notnull(); 00190 } 00191 else 00192 { 00193 table->field[5]->set_null(); 00194 table->field[6]->set_null(); 00195 } 00196 00197 00198 if (plug->author) 00199 { 00200 table->field[7]->store(plug->author, strlen(plug->author), cs); 00201 table->field[7]->set_notnull(); 00202 } 00203 else 00204 table->field[7]->set_null(); 00205 00206 if (plug->descr) 00207 { 00208 table->field[8]->store(plug->descr, strlen(plug->descr), cs); 00209 table->field[8]->set_notnull(); 00210 } 00211 else 00212 table->field[8]->set_null(); 00213 00214 return schema_table_store_record(thd, table); 00215 } 00216 00217 00218 int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond) 00219 { 00220 DBUG_ENTER("fill_plugins"); 00221 TABLE *table= tables->table; 00222 00223 if (plugin_foreach(thd, show_plugins, MYSQL_ANY_PLUGIN, table)) 00224 DBUG_RETURN(1); 00225 00226 DBUG_RETURN(0); 00227 } 00228 00229 00230 /*************************************************************************** 00231 ** List all Authors. 00232 ** If you can update it, you get to be in it :) 00233 ***************************************************************************/ 00234 00235 bool mysqld_show_authors(THD *thd) 00236 { 00237 List<Item> field_list; 00238 Protocol *protocol= thd->protocol; 00239 DBUG_ENTER("mysqld_show_authors"); 00240 00241 field_list.push_back(new Item_empty_string("Name",40)); 00242 field_list.push_back(new Item_empty_string("Location",40)); 00243 field_list.push_back(new Item_empty_string("Comment",80)); 00244 00245 if (protocol->send_fields(&field_list, 00246 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 00247 DBUG_RETURN(TRUE); 00248 00249 show_table_authors_st *authors; 00250 for (authors= show_table_authors; authors->name; authors++) 00251 { 00252 protocol->prepare_for_resend(); 00253 protocol->store(authors->name, system_charset_info); 00254 protocol->store(authors->location, system_charset_info); 00255 protocol->store(authors->comment, system_charset_info); 00256 if (protocol->write()) 00257 DBUG_RETURN(TRUE); 00258 } 00259 send_eof(thd); 00260 DBUG_RETURN(FALSE); 00261 } 00262 00263 00264 /*************************************************************************** 00265 ** List all Contributors. 00266 ** Please get permission before updating 00267 ***************************************************************************/ 00268 00269 bool mysqld_show_contributors(THD *thd) 00270 { 00271 List<Item> field_list; 00272 Protocol *protocol= thd->protocol; 00273 DBUG_ENTER("mysqld_show_contributors"); 00274 00275 field_list.push_back(new Item_empty_string("Name",40)); 00276 field_list.push_back(new Item_empty_string("Location",40)); 00277 field_list.push_back(new Item_empty_string("Comment",80)); 00278 00279 if (protocol->send_fields(&field_list, 00280 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 00281 DBUG_RETURN(TRUE); 00282 00283 show_table_contributors_st *contributors; 00284 for (contributors= show_table_contributors; contributors->name; contributors++) 00285 { 00286 protocol->prepare_for_resend(); 00287 protocol->store(contributors->name, system_charset_info); 00288 protocol->store(contributors->location, system_charset_info); 00289 protocol->store(contributors->comment, system_charset_info); 00290 if (protocol->write()) 00291 DBUG_RETURN(TRUE); 00292 } 00293 send_eof(thd); 00294 DBUG_RETURN(FALSE); 00295 } 00296 00297 00298 /*************************************************************************** 00299 List all privileges supported 00300 ***************************************************************************/ 00301 00302 struct show_privileges_st { 00303 const char *privilege; 00304 const char *context; 00305 const char *comment; 00306 }; 00307 00308 static struct show_privileges_st sys_privileges[]= 00309 { 00310 {"Alter", "Tables", "To alter the table"}, 00311 {"Alter routine", "Functions,Procedures", "To alter or drop stored functions/procedures"}, 00312 {"Create", "Databases,Tables,Indexes", "To create new databases and tables"}, 00313 {"Create routine","Functions,Procedures","To use CREATE FUNCTION/PROCEDURE"}, 00314 {"Create temporary tables","Databases","To use CREATE TEMPORARY TABLE"}, 00315 {"Create view", "Tables", "To create new views"}, 00316 {"Create user", "Server Admin", "To create new users"}, 00317 {"Delete", "Tables", "To delete existing rows"}, 00318 {"Drop", "Databases,Tables", "To drop databases, tables, and views"}, 00319 {"Event","Server Admin","To create, alter, drop and execute events"}, 00320 {"Execute", "Functions,Procedures", "To execute stored routines"}, 00321 {"File", "File access on server", "To read and write files on the server"}, 00322 {"Grant option", "Databases,Tables,Functions,Procedures", "To give to other users those privileges you possess"}, 00323 {"Index", "Tables", "To create or drop indexes"}, 00324 {"Insert", "Tables", "To insert data into tables"}, 00325 {"Lock tables","Databases","To use LOCK TABLES (together with SELECT privilege)"}, 00326 {"Process", "Server Admin", "To view the plain text of currently executing queries"}, 00327 {"References", "Databases,Tables", "To have references on tables"}, 00328 {"Reload", "Server Admin", "To reload or refresh tables, logs and privileges"}, 00329 {"Replication client","Server Admin","To ask where the slave or master servers are"}, 00330 {"Replication slave","Server Admin","To read binary log events from the master"}, 00331 {"Select", "Tables", "To retrieve rows from table"}, 00332 {"Show databases","Server Admin","To see all databases with SHOW DATABASES"}, 00333 {"Show view","Tables","To see views with SHOW CREATE VIEW"}, 00334 {"Shutdown","Server Admin", "To shut down the server"}, 00335 {"Super","Server Admin","To use KILL thread, SET GLOBAL, CHANGE MASTER, etc."}, 00336 {"Trigger","Tables", "To use triggers"}, 00337 {"Update", "Tables", "To update existing rows"}, 00338 {"Usage","Server Admin","No privileges - allow connect only"}, 00339 {NullS, NullS, NullS} 00340 }; 00341 00342 bool mysqld_show_privileges(THD *thd) 00343 { 00344 List<Item> field_list; 00345 Protocol *protocol= thd->protocol; 00346 DBUG_ENTER("mysqld_show_privileges"); 00347 00348 field_list.push_back(new Item_empty_string("Privilege",10)); 00349 field_list.push_back(new Item_empty_string("Context",15)); 00350 field_list.push_back(new Item_empty_string("Comment",NAME_LEN)); 00351 00352 if (protocol->send_fields(&field_list, 00353 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 00354 DBUG_RETURN(TRUE); 00355 00356 show_privileges_st *privilege= sys_privileges; 00357 for (privilege= sys_privileges; privilege->privilege ; privilege++) 00358 { 00359 protocol->prepare_for_resend(); 00360 protocol->store(privilege->privilege, system_charset_info); 00361 protocol->store(privilege->context, system_charset_info); 00362 protocol->store(privilege->comment, system_charset_info); 00363 if (protocol->write()) 00364 DBUG_RETURN(TRUE); 00365 } 00366 send_eof(thd); 00367 DBUG_RETURN(FALSE); 00368 } 00369 00370 00371 /*************************************************************************** 00372 List all column types 00373 ***************************************************************************/ 00374 00375 struct show_column_type_st 00376 { 00377 const char *type; 00378 uint size; 00379 const char *min_value; 00380 const char *max_value; 00381 uint precision; 00382 uint scale; 00383 const char *nullable; 00384 const char *auto_increment; 00385 const char *unsigned_attr; 00386 const char *zerofill; 00387 const char *searchable; 00388 const char *case_sensitivity; 00389 const char *default_value; 00390 const char *comment; 00391 }; 00392 00393 /* TODO: Add remaning types */ 00394 00395 static struct show_column_type_st sys_column_types[]= 00396 { 00397 {"tinyint", 00398 1, "-128", "127", 0, 0, "YES", "YES", 00399 "NO", "YES", "YES", "NO", "NULL,0", 00400 "A very small integer"}, 00401 {"tinyint unsigned", 00402 1, "0" , "255", 0, 0, "YES", "YES", 00403 "YES", "YES", "YES", "NO", "NULL,0", 00404 "A very small integer"}, 00405 }; 00406 00407 bool mysqld_show_column_types(THD *thd) 00408 { 00409 List<Item> field_list; 00410 Protocol *protocol= thd->protocol; 00411 DBUG_ENTER("mysqld_show_column_types"); 00412 00413 field_list.push_back(new Item_empty_string("Type",30)); 00414 field_list.push_back(new Item_int("Size",(longlong) 1,21)); 00415 field_list.push_back(new Item_empty_string("Min_Value",20)); 00416 field_list.push_back(new Item_empty_string("Max_Value",20)); 00417 field_list.push_back(new Item_return_int("Prec", 4, MYSQL_TYPE_SHORT)); 00418 field_list.push_back(new Item_return_int("Scale", 4, MYSQL_TYPE_SHORT)); 00419 field_list.push_back(new Item_empty_string("Nullable",4)); 00420 field_list.push_back(new Item_empty_string("Auto_Increment",4)); 00421 field_list.push_back(new Item_empty_string("Unsigned",4)); 00422 field_list.push_back(new Item_empty_string("Zerofill",4)); 00423 field_list.push_back(new Item_empty_string("Searchable",4)); 00424 field_list.push_back(new Item_empty_string("Case_Sensitive",4)); 00425 field_list.push_back(new Item_empty_string("Default",NAME_LEN)); 00426 field_list.push_back(new Item_empty_string("Comment",NAME_LEN)); 00427 00428 if (protocol->send_fields(&field_list, 00429 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 00430 DBUG_RETURN(TRUE); 00431 00432 /* TODO: Change the loop to not use 'i' */ 00433 for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++) 00434 { 00435 protocol->prepare_for_resend(); 00436 protocol->store(sys_column_types[i].type, system_charset_info); 00437 protocol->store((ulonglong) sys_column_types[i].size); 00438 protocol->store(sys_column_types[i].min_value, system_charset_info); 00439 protocol->store(sys_column_types[i].max_value, system_charset_info); 00440 protocol->store_short((longlong) sys_column_types[i].precision); 00441 protocol->store_short((longlong) sys_column_types[i].scale); 00442 protocol->store(sys_column_types[i].nullable, system_charset_info); 00443 protocol->store(sys_column_types[i].auto_increment, system_charset_info); 00444 protocol->store(sys_column_types[i].unsigned_attr, system_charset_info); 00445 protocol->store(sys_column_types[i].zerofill, system_charset_info); 00446 protocol->store(sys_column_types[i].searchable, system_charset_info); 00447 protocol->store(sys_column_types[i].case_sensitivity, system_charset_info); 00448 protocol->store(sys_column_types[i].default_value, system_charset_info); 00449 protocol->store(sys_column_types[i].comment, system_charset_info); 00450 if (protocol->write()) 00451 DBUG_RETURN(TRUE); 00452 } 00453 send_eof(thd); 00454 DBUG_RETURN(FALSE); 00455 } 00456 00457 00458 /* 00459 find_files() - find files in a given directory. 00460 00461 SYNOPSIS 00462 find_files() 00463 thd thread handler 00464 files put found files in this list 00465 db database name to set in TABLE_LIST structure 00466 path path to database 00467 wild filter for found files 00468 dir read databases in path if TRUE, read .frm files in 00469 database otherwise 00470 00471 RETURN 00472 FIND_FILES_OK success 00473 FIND_FILES_OOM out of memory error 00474 FIND_FILES_DIR no such directory, or directory can't be read 00475 */ 00476 00477 enum find_files_result { 00478 FIND_FILES_OK, 00479 FIND_FILES_OOM, 00480 FIND_FILES_DIR 00481 }; 00482 00483 static 00484 find_files_result 00485 find_files(THD *thd, List<char> *files, const char *db, 00486 const char *path, const char *wild, bool dir) 00487 { 00488 uint i; 00489 char *ext; 00490 MY_DIR *dirp; 00491 FILEINFO *file; 00492 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00493 uint col_access=thd->col_access; 00494 #endif 00495 TABLE_LIST table_list; 00496 DBUG_ENTER("find_files"); 00497 00498 if (wild && !wild[0]) 00499 wild=0; 00500 00501 bzero((char*) &table_list,sizeof(table_list)); 00502 00503 if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0)))) 00504 { 00505 if (my_errno == ENOENT) 00506 my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db); 00507 else 00508 my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno); 00509 DBUG_RETURN(FIND_FILES_DIR); 00510 } 00511 00512 for (i=0 ; i < (uint) dirp->number_off_files ; i++) 00513 { 00514 char uname[NAME_LEN*3+1]; /* Unencoded name */ 00515 file=dirp->dir_entry+i; 00516 if (dir) 00517 { /* Return databases */ 00518 if ((file->name[0] == '.' && 00519 ((file->name[1] == '.' && file->name[2] == '\0') || 00520 file->name[1] == '\0'))) 00521 continue; /* . or .. */ 00522 #ifdef USE_SYMDIR 00523 char *ext; 00524 char buff[FN_REFLEN]; 00525 if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym")) 00526 { 00527 /* Only show the sym file if it points to a directory */ 00528 char *end; 00529 *ext=0; /* Remove extension */ 00530 unpack_dirname(buff, file->name); 00531 end= strend(buff); 00532 if (end != buff && end[-1] == FN_LIBCHAR) 00533 end[-1]= 0; // Remove end FN_LIBCHAR 00534 if (!my_stat(buff, file->mystat, MYF(0))) 00535 continue; 00536 } 00537 #endif 00538 if (!MY_S_ISDIR(file->mystat->st_mode)) 00539 continue; 00540 VOID(filename_to_tablename(file->name, uname, sizeof(uname))); 00541 if (wild && wild_compare(uname, wild, 0)) 00542 continue; 00543 file->name= uname; 00544 } 00545 else 00546 { 00547 // Return only .frm files which aren't temp files. 00548 if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) || 00549 is_prefix(file->name, tmp_file_prefix)) 00550 continue; 00551 *ext=0; 00552 VOID(filename_to_tablename(file->name, uname, sizeof(uname))); 00553 file->name= uname; 00554 if (wild) 00555 { 00556 if (lower_case_table_names) 00557 { 00558 if (wild_case_compare(files_charset_info, file->name, wild)) 00559 continue; 00560 } 00561 else if (wild_compare(file->name,wild,0)) 00562 continue; 00563 } 00564 } 00565 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00566 /* Don't show tables where we don't have any privileges */ 00567 if (db && !(col_access & TABLE_ACLS)) 00568 { 00569 table_list.db= (char*) db; 00570 table_list.db_length= strlen(db); 00571 table_list.table_name= file->name; 00572 table_list.table_name_length= strlen(file->name); 00573 table_list.grant.privilege=col_access; 00574 if (check_grant(thd, TABLE_ACLS, &table_list, 1, 1, 1)) 00575 continue; 00576 } 00577 #endif 00578 if (files->push_back(thd->strdup(file->name))) 00579 { 00580 my_dirend(dirp); 00581 DBUG_RETURN(FIND_FILES_OOM); 00582 } 00583 } 00584 DBUG_PRINT("info",("found: %d files", files->elements)); 00585 my_dirend(dirp); 00586 00587 VOID(ha_find_files(thd,db,path,wild,dir,files)); 00588 00589 DBUG_RETURN(FIND_FILES_OK); 00590 } 00591 00592 00593 bool 00594 mysqld_show_create(THD *thd, TABLE_LIST *table_list) 00595 { 00596 Protocol *protocol= thd->protocol; 00597 char buff[2048]; 00598 String buffer(buff, sizeof(buff), system_charset_info); 00599 DBUG_ENTER("mysqld_show_create"); 00600 DBUG_PRINT("enter",("db: %s table: %s",table_list->db, 00601 table_list->table_name)); 00602 00603 /* We want to preserve the tree for views. */ 00604 thd->lex->view_prepare_mode= TRUE; 00605 00606 /* Only one table for now, but VIEW can involve several tables */ 00607 if (open_normal_and_derived_tables(thd, table_list, 0)) 00608 { 00609 if (!table_list->view || thd->net.last_errno != ER_VIEW_INVALID) 00610 DBUG_RETURN(TRUE); 00611 00612 /* 00613 Clear all messages with 'error' level status and 00614 issue a warning with 'warning' level status in 00615 case of invalid view and last error is ER_VIEW_INVALID 00616 */ 00617 mysql_reset_errors(thd, true); 00618 thd->clear_error(); 00619 00620 push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN, 00621 ER_VIEW_INVALID, 00622 ER(ER_VIEW_INVALID), 00623 table_list->view_db.str, 00624 table_list->view_name.str); 00625 } 00626 00627 /* TODO: add environment variables show when it become possible */ 00628 if (thd->lex->only_view && !table_list->view) 00629 { 00630 my_error(ER_WRONG_OBJECT, MYF(0), 00631 table_list->db, table_list->table_name, "VIEW"); 00632 DBUG_RETURN(TRUE); 00633 } 00634 00635 buffer.length(0); 00636 if ((table_list->view ? 00637 view_store_create_info(thd, table_list, &buffer) : 00638 store_create_info(thd, table_list, &buffer, NULL))) 00639 DBUG_RETURN(TRUE); 00640 00641 List<Item> field_list; 00642 if (table_list->view) 00643 { 00644 field_list.push_back(new Item_empty_string("View",NAME_LEN)); 00645 field_list.push_back(new Item_empty_string("Create View", 00646 max(buffer.length(),1024))); 00647 } 00648 else 00649 { 00650 field_list.push_back(new Item_empty_string("Table",NAME_LEN)); 00651 // 1024 is for not to confuse old clients 00652 field_list.push_back(new Item_empty_string("Create Table", 00653 max(buffer.length(),1024))); 00654 } 00655 00656 if (protocol->send_fields(&field_list, 00657 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 00658 DBUG_RETURN(TRUE); 00659 protocol->prepare_for_resend(); 00660 if (table_list->view) 00661 protocol->store(table_list->view_name.str, system_charset_info); 00662 else 00663 { 00664 if (table_list->schema_table) 00665 protocol->store(table_list->schema_table->table_name, 00666 system_charset_info); 00667 else 00668 protocol->store(table_list->table->alias, system_charset_info); 00669 } 00670 protocol->store(buffer.ptr(), buffer.length(), buffer.charset()); 00671 00672 if (protocol->write()) 00673 DBUG_RETURN(TRUE); 00674 send_eof(thd); 00675 DBUG_RETURN(FALSE); 00676 } 00677 00678 bool mysqld_show_create_db(THD *thd, char *dbname, 00679 HA_CREATE_INFO *create_info) 00680 { 00681 Security_context *sctx= thd->security_ctx; 00682 int length; 00683 char buff[2048]; 00684 String buffer(buff, sizeof(buff), system_charset_info); 00685 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00686 uint db_access; 00687 #endif 00688 HA_CREATE_INFO create; 00689 uint create_options = create_info ? create_info->options : 0; 00690 Protocol *protocol=thd->protocol; 00691 DBUG_ENTER("mysql_show_create_db"); 00692 00693 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00694 if (test_all_bits(sctx->master_access, DB_ACLS)) 00695 db_access=DB_ACLS; 00696 else 00697 db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) | 00698 sctx->master_access); 00699 if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) 00700 { 00701 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), 00702 sctx->priv_user, sctx->host_or_ip, dbname); 00703 general_log_print(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), 00704 sctx->priv_user, sctx->host_or_ip, dbname); 00705 DBUG_RETURN(TRUE); 00706 } 00707 #endif 00708 if (!my_strcasecmp(system_charset_info, dbname, 00709 information_schema_name.str)) 00710 { 00711 dbname= information_schema_name.str; 00712 create.default_table_charset= system_charset_info; 00713 } 00714 else 00715 { 00716 if (check_db_dir_existence(dbname)) 00717 { 00718 my_error(ER_BAD_DB_ERROR, MYF(0), dbname); 00719 DBUG_RETURN(TRUE); 00720 } 00721 00722 load_db_opt_by_name(thd, dbname, &create); 00723 } 00724 List<Item> field_list; 00725 field_list.push_back(new Item_empty_string("Database",NAME_LEN)); 00726 field_list.push_back(new Item_empty_string("Create Database",1024)); 00727 00728 if (protocol->send_fields(&field_list, 00729 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 00730 DBUG_RETURN(TRUE); 00731 00732 protocol->prepare_for_resend(); 00733 protocol->store(dbname, strlen(dbname), system_charset_info); 00734 buffer.length(0); 00735 buffer.append(STRING_WITH_LEN("CREATE DATABASE ")); 00736 if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS) 00737 buffer.append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ ")); 00738 append_identifier(thd, &buffer, dbname, strlen(dbname)); 00739 00740 if (create.default_table_charset) 00741 { 00742 buffer.append(STRING_WITH_LEN(" /*!40100")); 00743 buffer.append(STRING_WITH_LEN(" DEFAULT CHARACTER SET ")); 00744 buffer.append(create.default_table_charset->csname); 00745 if (!(create.default_table_charset->state & MY_CS_PRIMARY)) 00746 { 00747 buffer.append(STRING_WITH_LEN(" COLLATE ")); 00748 buffer.append(create.default_table_charset->name); 00749 } 00750 buffer.append(STRING_WITH_LEN(" */")); 00751 } 00752 protocol->store(buffer.ptr(), buffer.length(), buffer.charset()); 00753 00754 if (protocol->write()) 00755 DBUG_RETURN(TRUE); 00756 send_eof(thd); 00757 DBUG_RETURN(FALSE); 00758 } 00759 00760 00761 00762 /**************************************************************************** 00763 Return only fields for API mysql_list_fields
