You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4252 lines
142 KiB

26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
25 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
23 years ago
26 years ago
26 years ago
26 years ago
26 years ago
22 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
21 years ago
21 years ago
21 years ago
26 years ago
26 years ago
26 years ago
Bug#19025 4.1 mysqldump doesn't correctly dump "auto_increment = [int]" mysqldump / SHOW CREATE TABLE will show the NEXT available value for the PK, rather than the *first* one that was available (that named in the original CREATE TABLE ... AUTO_INCREMENT = ... statement). This should produce correct and robust behaviour for the obvious use cases -- when no data were inserted, then we'll produce a statement featuring the same value the original CREATE TABLE had; if we dump with values, INSERTing the values on the target machine should set the correct next_ID anyway (and if not, we'll still have our AUTO_INCREMENT = ... to do that). Lastly, just the CREATE statement (with no data) for a table that saw inserts would still result in a table that new values could safely be inserted to). There seems to be no robust way however to see whether the next_ID field is > 1 because it was set to something else with CREATE TABLE ... AUTO_INCREMENT = ..., or because there is an AUTO_INCREMENT column in the table (but no initial value was set with AUTO_INCREMENT = ...) and then one or more rows were INSERTed, counting up next_ID. This means that in both cases, we'll generate an AUTO_INCREMENT = ... clause in SHOW CREATE TABLE / mysqldump. As we also show info on, say, charsets even if the user did not explicitly give that info in their own CREATE TABLE, this shouldn't be an issue. As per above, the next_ID will be affected by any INSERTs that have taken place, though. This /should/ result in correct and robust behaviour, but it may look non-intuitive to some users if they CREATE TABLE ... AUTO_INCREMENT = 1000 and later (after some INSERTs) have SHOW CREATE TABLE give them a different value (say, CREATE TABLE ... AUTO_INCREMENT = 1006), so the docs should possibly feature a caveat to that effect. It's not very intuitive the way it works now (with the fix), but it's *correct*. We're not storing the original value anyway, if we wanted that, we'd have to change on-disk representation? If we do dump/load cycles with empty DBs, nothing will change. This changeset includes an additional test case that proves that tables with rows will create the same next_ID for AUTO_INCREMENT = ... across dump/restore cycles. Confirmed by support as likely solution for client's problem.
20 years ago
23 years ago
26 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
23 years ago
21 years ago
21 years ago
21 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
26 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
26 years ago
  1. /* Copyright (C) 2000-2004 MySQL AB
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
  13. /* Function with list databases, tables or fields */
  14. #include "mysql_priv.h"
  15. #include "sql_select.h" // For select_describe
  16. #include "repl_failsafe.h"
  17. #include "sp.h"
  18. #include "sp_head.h"
  19. #include "sql_trigger.h"
  20. #include <my_dir.h>
  21. #ifdef HAVE_BERKELEY_DB
  22. #include "ha_berkeley.h" // For berkeley_show_logs
  23. #endif
  24. static const char *grant_names[]={
  25. "select","insert","update","delete","create","drop","reload","shutdown",
  26. "process","file","grant","references","index","alter"};
  27. #ifndef NO_EMBEDDED_ACCESS_CHECKS
  28. static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
  29. "grant_types",
  30. grant_names, NULL};
  31. #endif
  32. static int
  33. store_create_info(THD *thd, TABLE_LIST *table_list, String *packet);
  34. static int
  35. view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);
  36. static bool schema_table_store_record(THD *thd, TABLE *table);
  37. /***************************************************************************
  38. ** List all table types supported
  39. ***************************************************************************/
  40. bool mysqld_show_storage_engines(THD *thd)
  41. {
  42. List<Item> field_list;
  43. Protocol *protocol= thd->protocol;
  44. DBUG_ENTER("mysqld_show_storage_engines");
  45. field_list.push_back(new Item_empty_string("Engine",10));
  46. field_list.push_back(new Item_empty_string("Support",10));
  47. field_list.push_back(new Item_empty_string("Comment",80));
  48. if (protocol->send_fields(&field_list,
  49. Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
  50. DBUG_RETURN(TRUE);
  51. const char *default_type_name=
  52. ha_get_storage_engine((enum db_type)thd->variables.table_type);
  53. handlerton **types;
  54. for (types= sys_table_types; *types; types++)
  55. {
  56. if (!((*types)->flags & HTON_HIDDEN))
  57. {
  58. protocol->prepare_for_resend();
  59. protocol->store((*types)->name, system_charset_info);
  60. const char *option_name= show_comp_option_name[(int) (*types)->state];
  61. if ((*types)->state == SHOW_OPTION_YES &&
  62. !my_strcasecmp(system_charset_info, default_type_name, (*types)->name))
  63. option_name= "DEFAULT";
  64. protocol->store(option_name, system_charset_info);
  65. protocol->store((*types)->comment, system_charset_info);
  66. if (protocol->write())
  67. DBUG_RETURN(TRUE);
  68. }
  69. }
  70. send_eof(thd);
  71. DBUG_RETURN(FALSE);
  72. }
  73. /***************************************************************************
  74. List all privileges supported
  75. ***************************************************************************/
  76. struct show_privileges_st {
  77. const char *privilege;
  78. const char *context;
  79. const char *comment;
  80. };
  81. static struct show_privileges_st sys_privileges[]=
  82. {
  83. {"Alter", "Tables", "To alter the table"},
  84. {"Alter routine", "Functions,Procedures", "To alter or drop stored functions/procedures"},
  85. {"Create", "Databases,Tables,Indexes", "To create new databases and tables"},
  86. {"Create routine","Functions,Procedures","To use CREATE FUNCTION/PROCEDURE"},
  87. {"Create temporary tables","Databases","To use CREATE TEMPORARY TABLE"},
  88. {"Create view", "Tables", "To create new views"},
  89. {"Create user", "Server Admin", "To create new users"},
  90. {"Delete", "Tables", "To delete existing rows"},
  91. {"Drop", "Databases,Tables", "To drop databases, tables, and views"},
  92. {"Execute", "Functions,Procedures", "To execute stored routines"},
  93. {"File", "File access on server", "To read and write files on the server"},
  94. {"Grant option", "Databases,Tables,Functions,Procedures", "To give to other users those privileges you possess"},
  95. {"Index", "Tables", "To create or drop indexes"},
  96. {"Insert", "Tables", "To insert data into tables"},
  97. {"Lock tables","Databases","To use LOCK TABLES (together with SELECT privilege)"},
  98. {"Process", "Server Admin", "To view the plain text of currently executing queries"},
  99. {"References", "Databases,Tables", "To have references on tables"},
  100. {"Reload", "Server Admin", "To reload or refresh tables, logs and privileges"},
  101. {"Replication client","Server Admin","To ask where the slave or master servers are"},
  102. {"Replication slave","Server Admin","To read binary log events from the master"},
  103. {"Select", "Tables", "To retrieve rows from table"},
  104. {"Show databases","Server Admin","To see all databases with SHOW DATABASES"},
  105. {"Show view","Tables","To see views with SHOW CREATE VIEW"},
  106. {"Shutdown","Server Admin", "To shut down the server"},
  107. {"Super","Server Admin","To use KILL thread, SET GLOBAL, CHANGE MASTER, etc."},
  108. {"Update", "Tables", "To update existing rows"},
  109. {"Usage","Server Admin","No privileges - allow connect only"},
  110. {NullS, NullS, NullS}
  111. };
  112. bool mysqld_show_privileges(THD *thd)
  113. {
  114. List<Item> field_list;
  115. Protocol *protocol= thd->protocol;
  116. DBUG_ENTER("mysqld_show_privileges");
  117. field_list.push_back(new Item_empty_string("Privilege",10));
  118. field_list.push_back(new Item_empty_string("Context",15));
  119. field_list.push_back(new Item_empty_string("Comment",NAME_LEN));
  120. if (protocol->send_fields(&field_list,
  121. Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
  122. DBUG_RETURN(TRUE);
  123. show_privileges_st *privilege= sys_privileges;
  124. for (privilege= sys_privileges; privilege->privilege ; privilege++)
  125. {
  126. protocol->prepare_for_resend();
  127. protocol->store(privilege->privilege, system_charset_info);
  128. protocol->store(privilege->context, system_charset_info);
  129. protocol->store(privilege->comment, system_charset_info);
  130. if (protocol->write())
  131. DBUG_RETURN(TRUE);
  132. }
  133. send_eof(thd);
  134. DBUG_RETURN(FALSE);
  135. }
  136. /***************************************************************************
  137. List all column types
  138. ***************************************************************************/
  139. struct show_column_type_st
  140. {
  141. const char *type;
  142. uint size;
  143. const char *min_value;
  144. const char *max_value;
  145. uint precision;
  146. uint scale;
  147. const char *nullable;
  148. const char *auto_increment;
  149. const char *unsigned_attr;
  150. const char *zerofill;
  151. const char *searchable;
  152. const char *case_sensitivity;
  153. const char *default_value;
  154. const char *comment;
  155. };
  156. /* TODO: Add remaning types */
  157. static struct show_column_type_st sys_column_types[]=
  158. {
  159. {"tinyint",
  160. 1, "-128", "127", 0, 0, "YES", "YES",
  161. "NO", "YES", "YES", "NO", "NULL,0",
  162. "A very small integer"},
  163. {"tinyint unsigned",
  164. 1, "0" , "255", 0, 0, "YES", "YES",
  165. "YES", "YES", "YES", "NO", "NULL,0",
  166. "A very small integer"},
  167. };
  168. bool mysqld_show_column_types(THD *thd)
  169. {
  170. List<Item> field_list;
  171. Protocol *protocol= thd->protocol;
  172. DBUG_ENTER("mysqld_show_column_types");
  173. field_list.push_back(new Item_empty_string("Type",30));
  174. field_list.push_back(new Item_int("Size",(longlong) 1,21));
  175. field_list.push_back(new Item_empty_string("Min_Value",20));
  176. field_list.push_back(new Item_empty_string("Max_Value",20));
  177. field_list.push_back(new Item_return_int("Prec", 4, MYSQL_TYPE_SHORT));
  178. field_list.push_back(new Item_return_int("Scale", 4, MYSQL_TYPE_SHORT));
  179. field_list.push_back(new Item_empty_string("Nullable",4));
  180. field_list.push_back(new Item_empty_string("Auto_Increment",4));
  181. field_list.push_back(new Item_empty_string("Unsigned",4));
  182. field_list.push_back(new Item_empty_string("Zerofill",4));
  183. field_list.push_back(new Item_empty_string("Searchable",4));
  184. field_list.push_back(new Item_empty_string("Case_Sensitive",4));
  185. field_list.push_back(new Item_empty_string("Default",NAME_LEN));
  186. field_list.push_back(new Item_empty_string("Comment",NAME_LEN));
  187. if (protocol->send_fields(&field_list,
  188. Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
  189. DBUG_RETURN(TRUE);
  190. /* TODO: Change the loop to not use 'i' */
  191. for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++)
  192. {
  193. protocol->prepare_for_resend();
  194. protocol->store(sys_column_types[i].type, system_charset_info);
  195. protocol->store((ulonglong) sys_column_types[i].size);
  196. protocol->store(sys_column_types[i].min_value, system_charset_info);
  197. protocol->store(sys_column_types[i].max_value, system_charset_info);
  198. protocol->store_short((longlong) sys_column_types[i].precision);
  199. protocol->store_short((longlong) sys_column_types[i].scale);
  200. protocol->store(sys_column_types[i].nullable, system_charset_info);
  201. protocol->store(sys_column_types[i].auto_increment, system_charset_info);
  202. protocol->store(sys_column_types[i].unsigned_attr, system_charset_info);
  203. protocol->store(sys_column_types[i].zerofill, system_charset_info);
  204. protocol->store(sys_column_types[i].searchable, system_charset_info);
  205. protocol->store(sys_column_types[i].case_sensitivity, system_charset_info);
  206. protocol->store(sys_column_types[i].default_value, system_charset_info);
  207. protocol->store(sys_column_types[i].comment, system_charset_info);
  208. if (protocol->write())
  209. DBUG_RETURN(TRUE);
  210. }
  211. send_eof(thd);
  212. DBUG_RETURN(FALSE);
  213. }
  214. int
  215. mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
  216. const char *wild, bool dir)
  217. {
  218. uint i;
  219. char *ext;
  220. MY_DIR *dirp;
  221. FILEINFO *file;
  222. #ifndef NO_EMBEDDED_ACCESS_CHECKS
  223. uint col_access=thd->col_access;
  224. #endif
  225. TABLE_LIST table_list;
  226. DBUG_ENTER("mysql_find_files");
  227. if (wild && !wild[0])
  228. wild=0;
  229. bzero((char*) &table_list,sizeof(table_list));
  230. if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
  231. {
  232. if (my_errno == ENOENT)
  233. my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
  234. else
  235. my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
  236. DBUG_RETURN(-1);
  237. }
  238. for (i=0 ; i < (uint) dirp->number_off_files ; i++)
  239. {
  240. file=dirp->dir_entry+i;
  241. if (dir)
  242. { /* Return databases */
  243. #ifdef USE_SYMDIR
  244. char *ext;
  245. char buff[FN_REFLEN];
  246. if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
  247. {
  248. /* Only show the sym file if it points to a directory */
  249. char *end;
  250. *ext=0; /* Remove extension */
  251. unpack_dirname(buff, file->name);
  252. end= strend(buff);
  253. if (end != buff && end[-1] == FN_LIBCHAR)
  254. end[-1]= 0; // Remove end FN_LIBCHAR
  255. if (!my_stat(buff, file->mystat, MYF(0)))
  256. continue;
  257. }
  258. #endif
  259. if (file->name[0] == '.' || !MY_S_ISDIR(file->mystat->st_mode) ||
  260. (wild && wild_compare(file->name,wild,0)))
  261. continue;
  262. }
  263. else
  264. {
  265. // Return only .frm files which aren't temp files.
  266. if (my_strcasecmp(system_charset_info, ext=fn_ext(file->name),reg_ext) ||
  267. is_prefix(file->name,tmp_file_prefix))
  268. continue;
  269. *ext=0;
  270. if (wild)
  271. {
  272. if (lower_case_table_names)
  273. {
  274. if (wild_case_compare(files_charset_info, file->name, wild))
  275. continue;
  276. }
  277. else if (wild_compare(file->name,wild,0))
  278. continue;
  279. }
  280. }
  281. #ifndef NO_EMBEDDED_ACCESS_CHECKS
  282. /* Don't show tables where we don't have any privileges */
  283. if (db && !(col_access & TABLE_ACLS))
  284. {
  285. table_list.db= (char*) db;
  286. table_list.db_length= strlen(db);
  287. table_list.table_name= file->name;
  288. table_list.table_name_length= strlen(file->name);
  289. table_list.grant.privilege=col_access;
  290. if (check_grant(thd, TABLE_ACLS, &table_list, 1, 1, 1))
  291. continue;
  292. }
  293. #endif
  294. if (files->push_back(thd->strdup(file->name)))
  295. {
  296. my_dirend(dirp);
  297. DBUG_RETURN(-1);
  298. }
  299. }
  300. DBUG_PRINT("info",("found: %d files", files->elements));
  301. my_dirend(dirp);
  302. VOID(ha_find_files(thd,db,path,wild,dir,files));
  303. DBUG_RETURN(0);
  304. }
  305. bool
  306. mysqld_show_create(THD *thd, TABLE_LIST *table_list)
  307. {
  308. Protocol *protocol= thd->protocol;
  309. char buff[2048];
  310. String buffer(buff, sizeof(buff), system_charset_info);
  311. DBUG_ENTER("mysqld_show_create");
  312. DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
  313. table_list->table_name));
  314. /* We want to preserve the tree for views. */
  315. thd->lex->view_prepare_mode= TRUE;
  316. /* Only one table for now, but VIEW can involve several tables */
  317. if (open_normal_and_derived_tables(thd, table_list, 0))
  318. {
  319. if (!table_list->view || thd->net.last_errno != ER_VIEW_INVALID)
  320. DBUG_RETURN(TRUE);
  321. /*
  322. Clear all messages with 'error' level status and
  323. issue a warning with 'warning' level status in
  324. case of invalid view and last error is ER_VIEW_INVALID
  325. */
  326. mysql_reset_errors(thd, true);
  327. thd->clear_error();
  328. push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
  329. ER_VIEW_INVALID,
  330. ER(ER_VIEW_INVALID),
  331. table_list->view_db.str,
  332. table_list->view_name.str);
  333. }
  334. /* TODO: add environment variables show when it become possible */
  335. if (thd->lex->only_view && !table_list->view)
  336. {
  337. my_error(ER_WRONG_OBJECT, MYF(0),
  338. table_list->db, table_list->table_name, "VIEW");
  339. DBUG_RETURN(TRUE);
  340. }
  341. buffer.length(0);
  342. if ((table_list->view ?
  343. view_store_create_info(thd, table_list, &buffer) :
  344. store_create_info(thd, table_list, &buffer)))
  345. DBUG_RETURN(TRUE);
  346. List<Item> field_list;
  347. if (table_list->view)
  348. {
  349. field_list.push_back(new Item_empty_string("View",NAME_LEN));
  350. field_list.push_back(new Item_empty_string("Create View",
  351. max(buffer.length(),1024)));
  352. }
  353. else
  354. {
  355. field_list.push_back(new Item_empty_string("Table",NAME_LEN));
  356. // 1024 is for not to confuse old clients
  357. field_list.push_back(new Item_empty_string("Create Table",
  358. max(buffer.length(),1024)));
  359. }
  360. if (protocol->send_fields(&field_list,
  361. Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
  362. DBUG_RETURN(TRUE);
  363. protocol->prepare_for_resend();
  364. if (table_list->view)
  365. protocol->store(table_list->view_name.str, system_charset_info);
  366. else
  367. {
  368. if (table_list->schema_table)
  369. protocol->store(table_list->schema_table->table_name,
  370. system_charset_info);
  371. else
  372. protocol->store(table_list->table->alias, system_charset_info);
  373. }
  374. protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
  375. if (protocol->write())
  376. DBUG_RETURN(TRUE);
  377. send_eof(thd);
  378. DBUG_RETURN(FALSE);
  379. }
  380. bool mysqld_show_create_db(THD *thd, char *dbname,
  381. HA_CREATE_INFO *create_info)
  382. {
  383. Security_context *sctx= thd->security_ctx;
  384. int length;
  385. char path[FN_REFLEN];
  386. char buff[2048];
  387. String buffer(buff, sizeof(buff), system_charset_info);
  388. #ifndef NO_EMBEDDED_ACCESS_CHECKS
  389. uint db_access;
  390. #endif
  391. bool found_libchar;
  392. HA_CREATE_INFO create;
  393. uint create_options = create_info ? create_info->options : 0;
  394. Protocol *protocol=thd->protocol;
  395. DBUG_ENTER("mysql_show_create_db");
  396. if (check_db_name(dbname))
  397. {
  398. my_error(ER_WRONG_DB_NAME, MYF(0), dbname);
  399. DBUG_RETURN(TRUE);
  400. }
  401. #ifndef NO_EMBEDDED_ACCESS_CHECKS
  402. if (test_all_bits(sctx->master_access, DB_ACLS))
  403. db_access=DB_ACLS;
  404. else
  405. db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
  406. sctx->master_access);
  407. if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
  408. {
  409. my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
  410. sctx->priv_user, sctx->host_or_ip, dbname);
  411. mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
  412. sctx->priv_user, sctx->host_or_ip, dbname);
  413. DBUG_RETURN(TRUE);
  414. }
  415. #endif
  416. if (!my_strcasecmp(system_charset_info, dbname,
  417. information_schema_name.str))
  418. {
  419. dbname= information_schema_name.str;
  420. create.default_table_charset= system_charset_info;
  421. }
  422. else
  423. {
  424. (void) sprintf(path,"%s/%s",mysql_data_home, dbname);
  425. length=unpack_dirname(path,path); // Convert if not unix
  426. found_libchar= 0;
  427. if (length && path[length-1] == FN_LIBCHAR)
  428. {
  429. found_libchar= 1;
  430. path[length-1]=0; // remove ending '\'
  431. }
  432. if (access(path,F_OK))
  433. {
  434. my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
  435. DBUG_RETURN(TRUE);
  436. }
  437. if (found_libchar)
  438. path[length-1]= FN_LIBCHAR;
  439. strmov(path+length, MY_DB_OPT_FILE);
  440. load_db_opt(thd, path, &create);
  441. }
  442. List<Item> field_list;
  443. field_list.push_back(new Item_empty_string("Database",NAME_LEN));
  444. field_list.push_back(new Item_empty_string("Create Database",1024));
  445. if (protocol->send_fields(&field_list,
  446. Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
  447. DBUG_RETURN(TRUE);
  448. protocol->prepare_for_resend();
  449. protocol->store(dbname, strlen(dbname), system_charset_info);
  450. buffer.length(0);
  451. buffer.append(STRING_WITH_LEN("CREATE DATABASE "));
  452. if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
  453. buffer.append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
  454. append_identifier(thd, &buffer, dbname, strlen(dbname));
  455. if (create.default_table_charset)
  456. {
  457. buffer.append(STRING_WITH_LEN(" /*!40100"));
  458. buffer.append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
  459. buffer.append(create.default_table_charset->csname);
  460. if (!(create.default_table_charset->state & MY_CS_PRIMARY))
  461. {
  462. buffer.append(STRING_WITH_LEN(" COLLATE "));
  463. buffer.append(create.default_table_charset->name);
  464. }
  465. buffer.append(STRING_WITH_LEN(" */"));
  466. }
  467. protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
  468. if (protocol->write())
  469. DBUG_RETURN(TRUE);
  470. send_eof(thd);
  471. DBUG_RETURN(FALSE);
  472. }
  473. bool
  474. mysqld_show_logs(THD *thd)
  475. {
  476. List<Item> field_list;
  477. Protocol *protocol= thd->protocol;
  478. DBUG_ENTER("mysqld_show_logs");
  479. field_list.push_back(new Item_empty_string("File",FN_REFLEN));
  480. field_list.push_back(new Item_empty_string("Type",10));
  481. field_list.push_back(new Item_empty_string("Status",10));
  482. if (protocol->send_fields(&field_list,
  483. Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
  484. DBUG_RETURN(TRUE);
  485. #ifdef HAVE_BERKELEY_DB
  486. if ((have_berkeley_db == SHOW_OPTION_YES) && berkeley_show_logs(protocol))
  487. DBUG_RETURN(TRUE);
  488. #endif
  489. send_eof(thd);
  490. DBUG_RETURN(FALSE);
  491. }
  492. /****************************************************************************
  493. Return only fields for API mysql_list_fields
  494. Use "show table wildcard" in mysql instead of this
  495. ****************************************************************************/
  496. void
  497. mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
  498. {
  499. TABLE *table;
  500. DBUG_ENTER("mysqld_list_fields");
  501. DBUG_PRINT("enter",("table: %s",table_list->table_name));
  502. if (open_normal_and_derived_tables(thd, table_list, 0))
  503. DBUG_VOID_RETURN;
  504. table= table_list->table;
  505. List<Item> field_list;
  506. Field **ptr,*field;
  507. for (ptr=table->field ; (field= *ptr); ptr++)
  508. {
  509. if (!wild || !wild[0] ||
  510. !wild_case_compare(system_charset_info, field->field_name,wild))
  511. field_list.push_back(new Item_field(field));
  512. }
  513. restore_record(table, s->default_values); // Get empty record
  514. if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS |
  515. Protocol::SEND_EOF))
  516. DBUG_VOID_RETURN;
  517. thd->protocol->flush();
  518. DBUG_VOID_RETURN;
  519. }
  520. int
  521. mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd)
  522. {
  523. Protocol *protocol= thd->protocol;
  524. String *packet= protocol->storage_packet();
  525. DBUG_ENTER("mysqld_dump_create_info");
  526. DBUG_PRINT("enter",("table: %s",table_list->table->s->table_name));
  527. protocol->prepare_for_resend();
  528. if (store_create_info(thd, table_list, packet))
  529. DBUG_RETURN(-1);
  530. if (fd < 0)
  531. {
  532. if (protocol->write())
  533. DBUG_RETURN(-1);
  534. protocol->flush();
  535. }
  536. else
  537. {
  538. if (my_write(fd, (const byte*) packet->ptr(), packet->length(),
  539. MYF(MY_WME)))
  540. DBUG_RETURN(-1);
  541. }
  542. DBUG_RETURN(0);
  543. }
  544. /*
  545. Go through all character combinations and ensure that sql_lex.cc can
  546. parse it as an identifier.
  547. SYNOPSIS
  548. require_quotes()
  549. name attribute name
  550. name_length length of name
  551. RETURN
  552. # Pointer to conflicting character
  553. 0 No conflicting character
  554. */
  555. static const char *require_quotes(const char *name, uint name_length)
  556. {
  557. uint length;
  558. const char *end= name + name_length;
  559. for (; name < end ; name++)
  560. {
  561. uchar chr= (uchar) *name;
  562. length= my_mbcharlen(system_charset_info, chr);
  563. if (length == 1 && !system_charset_info->ident_map[chr])
  564. return name;
  565. }
  566. return 0;
  567. }
  568. /*
  569. Quote the given identifier if needed and append it to the target string.
  570. If the given identifier is empty, it will be quoted.
  571. SYNOPSIS
  572. append_identifier()
  573. thd thread handler
  574. packet target string
  575. name the identifier to be appended
  576. name_length length of the appending identifier
  577. */
  578. void
  579. append_identifier(THD *thd, String *packet, const char *name, uint length)
  580. {
  581. const char *name_end;
  582. char quote_char;
  583. int q= get_quote_char_for_identifier(thd, name, length);
  584. if (q == EOF)
  585. {
  586. packet->append(name, length, system_charset_info);
  587. return;
  588. }
  589. /*
  590. The identifier must be quoted as it includes a quote character or
  591. it's a keyword
  592. */
  593. VOID(packet->reserve(length*2 + 2));
  594. quote_char= (char) q;
  595. packet->append(&quote_char, 1, system_charset_info);
  596. for (name_end= name+length ; name < name_end ; name+= length)
  597. {
  598. uchar chr= (uchar) *name;
  599. length= my_mbcharlen(system_charset_info, chr);
  600. /*
  601. my_mbcharlen can retur 0 on a wrong multibyte
  602. sequence. It is possible when upgrading from 4.0,
  603. and identifier contains some accented characters.
  604. The manual says it does not work. So we'll just
  605. change length to 1 not to hang in the endless loop.
  606. */
  607. if (!length)
  608. length= 1;
  609. if (length == 1 && chr == (uchar) quote_char)
  610. packet->append(&quote_char, 1, system_charset_info);
  611. packet->append(name, length, packet->charset());
  612. }
  613. packet->append(&quote_char, 1, system_charset_info);
  614. }
  615. /*
  616. Get the quote character for displaying an identifier.
  617. SYNOPSIS
  618. get_quote_char_for_identifier()
  619. thd Thread handler
  620. name name to quote
  621. length length of name
  622. IMPLEMENTATION
  623. Force quoting in the following cases:
  624. - name is empty (for one, it is possible when we use this function for
  625. quoting user and host names for DEFINER clause);
  626. - name is a keyword;
  627. - name includes a special character;
  628. Otherwise identifier is quoted only if the option OPTION_QUOTE_SHOW_CREATE
  629. is set.
  630. RETURN
  631. EOF No quote character is needed
  632. # Quote character
  633. */
  634. int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
  635. {
  636. if (length &&
  637. !is_keyword(name,length) &&
  638. !require_quotes(name, length) &&
  639. !(thd->options & OPTION_QUOTE_SHOW_CREATE))
  640. return EOF;
  641. if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
  642. return '"';
  643. return '`';
  644. }
  645. /* Append directory name (if exists) to CREATE INFO */
  646. static void append_directory(THD *thd, String *packet, const char *dir_type,
  647. const char *filename)
  648. {
  649. if (filename && !(thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
  650. {
  651. uint length= dirname_length(filename);
  652. packet->append(' ');
  653. packet->append(dir_type);
  654. packet->append(STRING_WITH_LEN(" DIRECTORY='"));
  655. #ifdef __WIN__
  656. /* Convert \ to / to be able to create table on unix */
  657. char *winfilename= (char*) thd->memdup(filename, length);
  658. char *pos, *end;
  659. for (pos= winfilename, end= pos+length ; pos < end ; pos++)
  660. {
  661. if (*pos == '\\')
  662. *pos = '/';
  663. }
  664. filename= winfilename;
  665. #endif
  666. packet->append(filename, length);
  667. packet->append('\'');
  668. }
  669. }
  670. #define LIST_PROCESS_HOST_LEN 64
  671. static int
  672. store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
  673. {
  674. List<Item> field_list;
  675. char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], *end;
  676. const char *alias;
  677. String type(tmp, sizeof(tmp), system_charset_info);
  678. Field **ptr,*field;
  679. uint primary_key;
  680. KEY *key_info;
  681. TABLE *table= table_list->table;
  682. handler *file= table->file;
  683. TABLE_SHARE *share= table->s;
  684. HA_CREATE_INFO create_info;
  685. my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
  686. MODE_ORACLE |
  687. MODE_MSSQL |
  688. MODE_DB2 |
  689. MODE_MAXDB |
  690. MODE_ANSI)) != 0;
  691. my_bool limited_mysql_mode= (thd->variables.sql_mode &
  692. (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
  693. MODE_MYSQL40)) != 0;
  694. DBUG_ENTER("store_create_info");
  695. DBUG_PRINT("enter",("table: %s", table->s->table_name));
  696. restore_record(table, s->default_values); // Get empty record
  697. if (share->tmp_table)
  698. packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
  699. else
  700. packet->append(STRING_WITH_LEN("CREATE TABLE "));
  701. if (table_list->schema_table)
  702. alias= table_list->schema_table->table_name;
  703. else
  704. alias= (lower_case_table_names == 2 ? table->alias :
  705. share->table_name);
  706. append_identifier(thd, packet, alias, strlen(alias));
  707. packet->append(STRING_WITH_LEN(" (\n"));
  708. for (ptr=table->field ; (field= *ptr); ptr++)
  709. {
  710. bool has_default;
  711. bool has_now_default;
  712. uint flags = field->flags;
  713. if (ptr != table->field)
  714. packet->append(STRING_WITH_LEN(",\n"));
  715. packet->append(STRING_WITH_LEN(" "));
  716. append_identifier(thd,packet,field->field_name, strlen(field->field_name));
  717. packet->append(' ');
  718. // check for surprises from the previous call to Field::sql_type()
  719. if (type.ptr() != tmp)
  720. type.set(tmp, sizeof(tmp), system_charset_info);
  721. else
  722. type.set_charset(system_charset_info);
  723. field->sql_type(type);
  724. packet->append(type.ptr(), type.length(), system_charset_info);
  725. if (field->has_charset() &&
  726. !(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
  727. {
  728. if (field->charset() != share->table_charset)
  729. {
  730. packet->append(STRING_WITH_LEN(" character set "));
  731. packet->append(field->charset()->csname);
  732. }
  733. /*
  734. For string types dump collation name only if
  735. collation is not primary for the given charset
  736. */
  737. if (!(field->charset()->state & MY_CS_PRIMARY))
  738. {
  739. packet->append(STRING_WITH_LEN(" collate "));
  740. packet->append(field->charset()->name);
  741. }
  742. }
  743. if (flags & NOT_NULL_FLAG)
  744. packet->append(STRING_WITH_LEN(" NOT NULL"));
  745. else if (field->type() == FIELD_TYPE_TIMESTAMP)
  746. {
  747. /*
  748. TIMESTAMP field require explicit NULL flag, because unlike
  749. all other fields they are treated as NOT NULL by default.
  750. */
  751. packet->append(STRING_WITH_LEN(" NULL"));
  752. }
  753. /*
  754. Again we are using CURRENT_TIMESTAMP instead of NOW because it is
  755. more standard
  756. */
  757. has_now_default= table->timestamp_field == field &&
  758. field->unireg_check != Field::TIMESTAMP_UN_FIELD;
  759. has_default= (field->type() != FIELD_TYPE_BLOB &&
  760. !(field->flags & NO_DEFAULT_VALUE_FLAG) &&
  761. field->unireg_check != Field::NEXT_NUMBER &&
  762. !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
  763. && has_now_default));
  764. if (has_default)
  765. {
  766. packet->append(STRING_WITH_LEN(" default "));
  767. if (has_now_default)
  768. packet->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
  769. else if (!field->is_null())
  770. { // Not null by default
  771. type.set(tmp, sizeof(tmp), field->charset());
  772. field->val_str(&type);
  773. if (type.length())
  774. {
  775. String def_val;
  776. uint dummy_errors;
  777. /* convert to system_charset_info == utf8 */
  778. def_val.copy(type.ptr(), type.length(), field->charset(),
  779. system_charset_info, &dummy_errors);
  780. append_unescaped(packet, def_val.ptr(), def_val.length());
  781. }
  782. else
  783. packet->append(STRING_WITH_LEN("''"));
  784. }
  785. else if (field->maybe_null())
  786. packet->append(STRING_WITH_LEN("NULL")); // Null as default
  787. else
  788. packet->append(tmp);
  789. }
  790. if (!limited_mysql_mode && table->timestamp_field == field &&
  791. field->unireg_check != Field::TIMESTAMP_DN_FIELD)
  792. packet->append(STRING_WITH_LEN(" on update CURRENT_TIMESTAMP"));
  793. if (field->unireg_check == Field::NEXT_NUMBER &&
  794. !(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
  795. packet->append(STRING_WITH_LEN(" auto_increment"));
  796. if (field->comment.length)
  797. {
  798. packet->append(STRING_WITH_LEN(" COMMENT "));
  799. append_unescaped(packet, field->comment.str, field->comment.length);
  800. }
  801. }
  802. key_info= table->key_info;
  803. bzero((char*) &create_info, sizeof(create_info));
  804. file->update_create_info(&create_info);
  805. primary_key= share->primary_key;
  806. for (uint i=0 ; i < share->keys ; i++,key_info++)
  807. {
  808. KEY_PART_INFO *key_part= key_info->key_part;
  809. bool found_primary=0;
  810. packet->append(STRING_WITH_LEN(",\n "));
  811. if (i == primary_key && !strcmp(key_info->name, primary_key_name))
  812. {
  813. found_primary=1;
  814. packet->append(STRING_WITH_LEN("PRIMARY "));
  815. }
  816. else if (key_info->flags & HA_NOSAME)
  817. packet->append(STRING_WITH_LEN("UNIQUE "));
  818. else if (key_info->flags & HA_FULLTEXT)
  819. packet->append(STRING_WITH_LEN("FULLTEXT "));
  820. else if (key_info->flags & HA_SPATIAL)
  821. packet->append(STRING_WITH_LEN("SPATIAL "));
  822. packet->append(STRING_WITH_LEN("KEY "));
  823. if (!found_primary)
  824. append_identifier(thd, packet, key_info->name, strlen(key_info->name));
  825. if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
  826. !limited_mysql_mode && !foreign_db_mode)
  827. {
  828. if (key_info->algorithm == HA_KEY_ALG_BTREE)
  829. packet->append(STRING_WITH_LEN(" USING BTREE"));
  830. if (key_info->algorithm == HA_KEY_ALG_HASH)
  831. packet->append(STRING_WITH_LEN(" USING HASH"));
  832. // +BAR: send USING only in non-default case: non-spatial rtree
  833. if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
  834. !(key_info->flags & HA_SPATIAL))
  835. packet->append(STRING_WITH_LEN(" USING RTREE"));
  836. // No need to send USING FULLTEXT, it is sent as FULLTEXT KEY
  837. }
  838. packet->append(STRING_WITH_LEN(" ("));
  839. for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
  840. {
  841. if (j)
  842. packet->append(',');
  843. if (key_part->field)
  844. append_identifier(thd,packet,key_part->field->field_name,
  845. strlen(key_part->field->field_name));
  846. if (key_part->field &&
  847. (key_part->length !=
  848. table->field[key_part->fieldnr-1]->key_length() &&
  849. !(key_info->flags & HA_FULLTEXT)))
  850. {
  851. buff[0] = '(';
  852. char* end=int10_to_str((long) key_part->length /
  853. key_part->field->charset()->mbmaxlen,
  854. buff + 1,10);
  855. *end++ = ')';
  856. packet->append(buff,(uint) (end-buff));
  857. }
  858. }
  859. packet->append(')');
  860. }
  861. /*
  862. Get possible foreign key definitions stored in InnoDB and append them
  863. to the CREATE TABLE statement
  864. */
  865. if ((for_str= file->get_foreign_key_create_info()))
  866. {
  867. packet->append(for_str, strlen(for_str));
  868. file->free_foreign_key_create_info(for_str);
  869. }
  870. packet->append(STRING_WITH_LEN("\n)"));
  871. if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
  872. {
  873. if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
  874. packet->append(STRING_WITH_LEN(" TYPE="));
  875. else
  876. packet->append(STRING_WITH_LEN(" ENGINE="));
  877. packet->append(file->table_type());
  878. /*
  879. Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
  880. and NEXT_ID > 1 (the default). We must not print the clause
  881. for engines that do not support this as it would break the
  882. import of dumps, but as of this writing, the test for whether
  883. AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
  884. is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
  885. Because of that, we do not explicitly test for the feature,
  886. but may extrapolate its existence from that of an AUTO_INCREMENT column.
  887. */
  888. if(create_info.auto_increment_value > 1)
  889. {
  890. packet->append(" AUTO_INCREMENT=", 16);
  891. end= longlong10_to_str(create_info.auto_increment_value, buff,10);
  892. packet->append(buff, (uint) (end - buff));
  893. }
  894. if (share->table_charset &&
  895. !(thd->variables.sql_mode & MODE_MYSQL323) &&
  896. !(thd->variables.sql_mode & MODE_MYSQL40))
  897. {
  898. packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
  899. packet->append(share->table_charset->csname);
  900. if (!(share->table_charset->state & MY_CS_PRIMARY))
  901. {
  902. packet->append(STRING_WITH_LEN(" COLLATE="));
  903. packet->append(table->s->table_charset->name);
  904. }
  905. }
  906. if (share->min_rows)
  907. {
  908. packet->append(STRING_WITH_LEN(" MIN_ROWS="));
  909. end= longlong10_to_str(share->min_rows, buff, 10);
  910. packet->append(buff, (uint) (end- buff));
  911. }
  912. if (share->max_rows && !table_list->schema_table)
  913. {
  914. packet->append(STRING_WITH_LEN(" MAX_ROWS="));
  915. end= longlong10_to_str(share->max_rows, buff, 10);
  916. packet->append(buff, (uint) (end - buff));
  917. }
  918. if (share->avg_row_length)
  919. {
  920. packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
  921. end= longlong10_to_str(share->avg_row_length, buff,10);
  922. packet->append(buff, (uint) (end - buff));
  923. }
  924. if (share->db_create_options & HA_OPTION_PACK_KEYS)
  925. packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
  926. if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
  927. packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
  928. if (share->db_create_options & HA_OPTION_CHECKSUM)
  929. packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
  930. if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
  931. packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
  932. if (share->row_type != ROW_TYPE_DEFAULT)
  933. {
  934. packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
  935. packet->append(ha_row_type[(uint) share->row_type]);
  936. }
  937. table->file->append_create_info(packet);
  938. if (share->comment && share->comment[0])
  939. {
  940. packet->append(STRING_WITH_LEN(" COMMENT="));
  941. append_unescaped(packet, share->comment, strlen(share->comment));
  942. }
  943. if (share->connect_string.length)
  944. {
  945. packet->append(STRING_WITH_LEN(" CONNECTION="));
  946. append_unescaped(packet, share->connect_string.str, share->connect_string.length);
  947. }
  948. if (file->raid_type)
  949. {
  950. uint length;
  951. length= my_snprintf(buff,sizeof(buff),
  952. " RAID_TYPE=%s RAID_CHUNKS=%d RAID_CHUNKSIZE=%ld",
  953. my_raid_type(file->raid_type), file->raid_chunks,
  954. file->raid_chunksize/RAID_BLOCK_SIZE);
  955. packet->append(buff, length);
  956. }
  957. append_directory(thd, packet, "DATA", create_info.data_file_name);
  958. append_directory(thd, packet, "INDEX", create_info.index_file_name);
  959. }
  960. DBUG_RETURN(0);
  961. }
  962. void
  963. view_store_options(THD *thd, TABLE_LIST *table, String *buff)
  964. {
  965. buff->append(STRING_WITH_LEN("ALGORITHM="));
  966. switch ((int8)table->algorithm) {
  967. case VIEW_ALGORITHM_UNDEFINED:
  968. buff->append(STRING_WITH_LEN("UNDEFINED "));
  969. break;
  970. case VIEW_ALGORITHM_TMPTABLE:
  971. buff->append(STRING_WITH_LEN("TEMPTABLE "));
  972. break;
  973. case VIEW_ALGORITHM_MERGE:
  974. buff->append(STRING_WITH_LEN("MERGE "));
  975. break;
  976. default:
  977. DBUG_ASSERT(0); // never should happen
  978. }
  979. append_definer(thd, buff, &table->definer.user, &table->definer.host);
  980. if (table->view_suid)
  981. buff->append(STRING_WITH_LEN("SQL SECURITY DEFINER "));
  982. else
  983. buff->append(STRING_WITH_LEN("SQL SECURITY INVOKER "));
  984. }
  985. /*
  986. Append DEFINER clause to the given buffer.
  987. SYNOPSIS
  988. append_definer()
  989. thd [in] thread handle
  990. buffer [inout] buffer to hold DEFINER clause
  991. definer_user [in] user name part of definer
  992. definer_host [in] host name part of definer
  993. */
  994. void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
  995. const LEX_STRING *definer_host)
  996. {
  997. buffer->append(STRING_WITH_LEN("DEFINER="));
  998. append_identifier(thd, buffer, definer_user->str, definer_user->length);
  999. buffer->append('@');
  1000. append_identifier(thd, buffer, definer_host->str, definer_host->length);
  1001. buffer->append(' ');
  1002. }
  1003. static int
  1004. view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
  1005. {
  1006. my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
  1007. MODE_ORACLE |
  1008. MODE_MSSQL |
  1009. MODE_DB2 |
  1010. MODE_MAXDB |
  1011. MODE_ANSI)) != 0;
  1012. /*
  1013. Compact output format for view can be used
  1014. - if user has db of this view as current db
  1015. - if this view only references table inside it's own db
  1016. */
  1017. if (!thd->db || strcmp(thd->db, table->view_db.str))
  1018. table->compact_view_format= FALSE;
  1019. else
  1020. {
  1021. TABLE_LIST *tbl;
  1022. table->compact_view_format= TRUE;
  1023. for (tbl= thd->lex->query_tables;
  1024. tbl;
  1025. tbl= tbl->next_global)
  1026. {
  1027. if (strcmp(table->view_db.str, tbl->view ? tbl->view_db.str :tbl->db)!= 0)
  1028. {
  1029. table->compact_view_format= FALSE;
  1030. break;
  1031. }
  1032. }
  1033. }
  1034. buff->append(STRING_WITH_LEN("CREATE "));
  1035. if (!foreign_db_mode)
  1036. {
  1037. view_store_options(thd, table, buff);
  1038. }
  1039. buff->append(STRING_WITH_LEN("VIEW "));
  1040. if (!table->compact_view_format)
  1041. {
  1042. append_identifier(thd, buff, table->view_db.str, table->view_db.length);
  1043. buff->append('.');
  1044. }
  1045. append_identifier(thd, buff, table->view_name.str, table->view_name.length);
  1046. buff->append(STRING_WITH_LEN(" AS "));
  1047. /*
  1048. We can't just use table->query, because our SQL_MODE may trigger
  1049. a different syntax, like when ANSI_QUOTES is defined.
  1050. */
  1051. table->view->unit.print(buff);
  1052. if (table->with_check != VIEW_CHECK_NONE)
  1053. {
  1054. if (table->with_check == VIEW_CHECK_LOCAL)
  1055. buff->append(STRING_WITH_LEN(" WITH LOCAL CHECK OPTION"));
  1056. else
  1057. buff->append(STRING_WITH_LEN(" WITH CASCADED CHECK OPTION"));
  1058. }
  1059. return 0;
  1060. }
  1061. /****************************************************************************
  1062. Return info about all processes
  1063. returns for each thread: thread id, user, host, db, command, info
  1064. ****************************************************************************/
  1065. class thread_info :public ilink {
  1066. public:
  1067. static void *operator new(size_t size)
  1068. {
  1069. return (void*) sql_alloc((uint) size);
  1070. }
  1071. static void operator delete(void *ptr __attribute__((unused)),
  1072. size_t size __attribute__((unused)))
  1073. { TRASH(ptr, size); }
  1074. ulong thread_id;
  1075. time_t start_time;
  1076. uint command;
  1077. const char *user,*host,*db,*proc_info,*state_info;
  1078. char *query;
  1079. };
  1080. #ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
  1081. template class I_List<thread_info>;
  1082. #endif
  1083. void mysqld_list_processes(THD *thd,const char *user, bool verbose)
  1084. {
  1085. Item *field;
  1086. List<Item> field_list;
  1087. I_List<thread_info> thread_infos;
  1088. ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
  1089. PROCESS_LIST_WIDTH);
  1090. Protocol *protocol= thd->protocol;
  1091. DBUG_ENTER("mysqld_list_processes");
  1092. field_list.push_back(new Item_int("Id",0,11));
  1093. field_list.push_back(new Item_empty_string("User",16));
  1094. field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
  1095. field_list.push_back(field=new Item_empty_string("db",NAME_LEN));
  1096. field->maybe_null=1;
  1097. field_list.push_back(new Item_empty_string("Command",16));
  1098. field_list.push_back(new Item_return_int("Time",7, FIELD_TYPE_LONG));
  1099. field_list.push_back(field=new Item_empty_string("State",30));
  1100. field->maybe_null=1;
  1101. field_list.push_back(field=new Item_empty_string("Info",max_query_length));
  1102. field->maybe_null=1;
  1103. if (protocol->send_fields(&field_list,
  1104. Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
  1105. DBUG_VOID_RETURN;
  1106. VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
  1107. if (!thd->killed)
  1108. {
  1109. I_List_iterator<THD> it(threads);
  1110. THD *tmp;
  1111. while ((tmp=it++))
  1112. {
  1113. Security_context *tmp_sctx= tmp->security_ctx;
  1114. struct st_my_thread_var *mysys_var;
  1115. if ((tmp->vio_ok() || tmp->system_thread) &&
  1116. (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
  1117. {
  1118. thread_info *thd_info= new thread_info;
  1119. thd_info->thread_id=tmp->thread_id;
  1120. thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
  1121. (tmp->system_thread ?
  1122. "system user" : "unauthenticated user"));
  1123. if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
  1124. thd->security_ctx->host_or_ip[0])
  1125. {
  1126. if ((thd_info->host= thd->alloc(LIST_PROCESS_HOST_LEN+1)))
  1127. my_snprintf((char *) thd_info->host, LIST_PROCESS_HOST_LEN,
  1128. "%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
  1129. }
  1130. else
  1131. thd_info->host= thd->strdup(tmp_sctx->host_or_ip);
  1132. if ((thd_info->db=tmp->db)) // Safe test
  1133. thd_info->db=thd->strdup(thd_info->db);
  1134. thd_info->command=(int) tmp->command;
  1135. if ((mysys_var= tmp->mysys_var))
  1136. pthread_mutex_lock(&mysys_var->mutex);
  1137. thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
  1138. #ifndef EMBEDDED_LIBRARY
  1139. thd_info->state_info= (char*) (tmp->locked ? "Locked" :
  1140. tmp->net.reading_or_writing ?
  1141. (tmp->net.reading_or_writing == 2 ?
  1142. "Writing to net" :
  1143. thd_info->command == COM_SLEEP ? "" :
  1144. "Reading from net") :
  1145. tmp->proc_info ? tmp->proc_info :
  1146. tmp->mysys_var &&
  1147. tmp->mysys_var->current_cond ?
  1148. "Waiting on cond" : NullS);
  1149. #else
  1150. thd_info->state_info= (char*)"Writing to net";
  1151. #endif
  1152. if (mysys_var)
  1153. pthread_mutex_unlock(&mysys_var->mutex);
  1154. #if !defined(DONT_USE_THR_ALARM) && ! defined(SCO)
  1155. if (pthread_kill(tmp->real_id,0))
  1156. tmp->proc_info="*** DEAD ***"; // This shouldn't happen
  1157. #endif
  1158. #ifdef EXTRA_DEBUG
  1159. thd_info->start_time= tmp->time_after_lock;
  1160. #else
  1161. thd_info->start_time= tmp->start_time;
  1162. #endif
  1163. thd_info->query=0;
  1164. if (tmp->query)
  1165. {
  1166. /*
  1167. query_length is always set to 0 when we set query = NULL; see
  1168. the comment in sql_class.h why this prevents crashes in possible
  1169. races with query_length
  1170. */
  1171. uint length= min(max_query_length, tmp->query_length);
  1172. thd_info->query=(char*) thd->strmake(tmp->query,length);
  1173. }
  1174. thread_infos.append(thd_info);
  1175. }
  1176. }
  1177. }
  1178. VOID(pthread_mutex_unlock(&LOCK_thread_count));
  1179. thread_info *thd_info;
  1180. time_t now= time(0);
  1181. while ((thd_info=thread_infos.get()))
  1182. {
  1183. protocol->prepare_for_resend();
  1184. protocol->store((ulonglong) thd_info->thread_id);
  1185. protocol->store(thd_info->user, system_charset_info);
  1186. protocol->store(thd_info->host, system_charset_info);
  1187. protocol->store(thd_info->db, system_charset_info);
  1188. if (thd_info->proc_info)
  1189. protocol->store(thd_info->proc_info, system_charset_info);
  1190. else
  1191. protocol->store(command_name[thd_info->command], system_charset_info);
  1192. if (thd_info->start_time)
  1193. protocol->store((uint32) (now - thd_info->start_time));
  1194. else
  1195. protocol->store_null();
  1196. protocol->store(thd_info->state_info, system_charset_info);
  1197. protocol->store(thd_info->query, system_charset_info);
  1198. if (protocol->write())
  1199. break; /* purecov: inspected */
  1200. }
  1201. send_eof(thd);
  1202. DBUG_VOID_RETURN;
  1203. }
  1204. /*****************************************************************************
  1205. Status functions
  1206. *****************************************************************************/
  1207. static bool show_status_array(THD *thd, const char *wild,
  1208. show_var_st *variables,
  1209. enum enum_var_type value_type,
  1210. struct system_status_var *status_var,
  1211. const char *prefix, TABLE *table)
  1212. {
  1213. char buff[1024], *prefix_end;
  1214. /* the variable name should not be longer then 80 characters */
  1215. char name_buffer[80];
  1216. int len;
  1217. LEX_STRING null_lex_str;
  1218. DBUG_ENTER("show_status_array");
  1219. null_lex_str.str= 0; // For sys_var->value_ptr()
  1220. null_lex_str.length= 0;
  1221. prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
  1222. len=name_buffer + sizeof(name_buffer) - prefix_end;
  1223. for (; variables->name; variables++)
  1224. {
  1225. strnmov(prefix_end, variables->name, len);
  1226. name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
  1227. SHOW_TYPE show_type=variables->type;
  1228. if (show_type == SHOW_VARS)
  1229. {
  1230. show_status_array(thd, wild, (show_var_st *) variables->value,
  1231. value_type, status_var, variables->name, table);
  1232. }
  1233. else
  1234. {
  1235. if (!(wild && wild[0] && wild_case_compare(system_charset_info,
  1236. name_buffer, wild)))
  1237. {
  1238. char *value=variables->value;
  1239. const char *pos, *end; // We assign a lot of const's
  1240. long nr;
  1241. if (show_type == SHOW_SYS)
  1242. {
  1243. show_type= ((sys_var*) value)->type();
  1244. value= (char*) ((sys_var*) value)->value_ptr(thd, value_type,
  1245. &null_lex_str);
  1246. }
  1247. pos= end= buff;
  1248. switch (show_type) {
  1249. case SHOW_LONG_STATUS:
  1250. case SHOW_LONG_CONST_STATUS:
  1251. value= ((char *) status_var + (ulong) value);
  1252. /* fall through */
  1253. case SHOW_LONG:
  1254. case SHOW_LONG_CONST:
  1255. end= int10_to_str(*(long*) value, buff, 10);
  1256. break;
  1257. case SHOW_LONGLONG:
  1258. end= longlong10_to_str(*(longlong*) value, buff, 10);
  1259. break;
  1260. case SHOW_HA_ROWS:
  1261. end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
  1262. break;
  1263. case SHOW_BOOL:
  1264. end= strmov(buff, *(bool*) value ? "ON" : "OFF");
  1265. break;
  1266. case SHOW_MY_BOOL:
  1267. end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
  1268. break;
  1269. case SHOW_INT_CONST:
  1270. case SHOW_INT:
  1271. end= int10_to_str((long) *(uint32*) value, buff, 10);
  1272. break;
  1273. case SHOW_HAVE:
  1274. {
  1275. SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
  1276. pos= show_comp_option_name[(int) tmp];
  1277. end= strend(pos);
  1278. break;
  1279. }
  1280. case SHOW_CHAR:
  1281. {
  1282. if (!(pos= value))
  1283. pos= "";
  1284. end= strend(pos);
  1285. break;
  1286. }
  1287. case SHOW_STARTTIME:
  1288. nr= (long) (thd->query_start() - start_time);
  1289. end= int10_to_str(nr, buff, 10);
  1290. break;
  1291. case SHOW_QUESTION:
  1292. end= int10_to_str((long) thd->query_id, buff, 10);
  1293. break;
  1294. #ifdef HAVE_REPLICATION
  1295. case SHOW_RPL_STATUS:
  1296. end= strmov(buff, rpl_status_type[(int)rpl_status]);
  1297. break;
  1298. case SHOW_SLAVE_RUNNING:
  1299. {
  1300. pthread_mutex_lock(&LOCK_active_mi);
  1301. end= strmov(buff, (active_mi && active_mi->slave_running &&
  1302. active_mi->rli.slave_running) ? "ON" : "OFF");
  1303. pthread_mutex_unlock(&LOCK_active_mi);
  1304. break;
  1305. }
  1306. case SHOW_SLAVE_RETRIED_TRANS:
  1307. {
  1308. /*
  1309. TODO: in 5.1 with multimaster, have one such counter per line in
  1310. SHOW SLAVE STATUS, and have the sum over all lines here.
  1311. */
  1312. pthread_mutex_lock(&LOCK_active_mi);
  1313. if (active_mi)
  1314. {
  1315. pthread_mutex_lock(&active_mi->rli.data_lock);
  1316. end= int10_to_str(active_mi->rli.retried_trans, buff, 10);
  1317. pthread_mutex_unlock(&active_mi->rli.data_lock);
  1318. }
  1319. pthread_mutex_unlock(&LOCK_active_mi);
  1320. break;
  1321. }
  1322. case SHOW_SLAVE_SKIP_ERRORS:
  1323. {
  1324. MY_BITMAP *bitmap= (MY_BITMAP *)value;
  1325. if (!use_slave_mask || bitmap_is_clear_all(bitmap))
  1326. {
  1327. end= strmov(buff, "OFF");
  1328. }
  1329. else if (bitmap_is_set_all(bitmap))
  1330. {
  1331. end= strmov(buff, "ALL");
  1332. }
  1333. else
  1334. {
  1335. /* 10 is enough assuming errors are max 4 digits */
  1336. int i;
  1337. for (i= 1;
  1338. i < MAX_SLAVE_ERROR && (uint) (end-buff) < sizeof(buff)-10;
  1339. i++)
  1340. {
  1341. if (bitmap_is_set(bitmap, i))
  1342. {
  1343. end= int10_to_str(i, (char*) end, 10);
  1344. *(char*) end++= ',';
  1345. }
  1346. }
  1347. if (end != buff)
  1348. end--; // Remove last ','
  1349. if (i < MAX_SLAVE_ERROR)
  1350. end= strmov((char*) end, "..."); // Couldn't show all errors
  1351. }
  1352. break;
  1353. }
  1354. #endif /* HAVE_REPLICATION */
  1355. case SHOW_OPENTABLES:
  1356. end= int10_to_str((long) cached_tables(), buff, 10);
  1357. break;
  1358. case SHOW_CHAR_PTR:
  1359. {
  1360. if (!(pos= *(char**) value))
  1361. pos= "";
  1362. end= strend(pos);
  1363. break;
  1364. }
  1365. case SHOW_DOUBLE_STATUS:
  1366. {
  1367. value= ((char *) status_var + (ulong) value);
  1368. end= buff + sprintf(buff, "%f", *(double*) value);
  1369. break;
  1370. }
  1371. #ifdef HAVE_OPENSSL
  1372. /* First group - functions relying on CTX */
  1373. case SHOW_SSL_CTX_SESS_ACCEPT:
  1374. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1375. SSL_CTX_sess_accept(ssl_acceptor_fd->
  1376. ssl_context)),
  1377. buff, 10);
  1378. break;
  1379. case SHOW_SSL_CTX_SESS_ACCEPT_GOOD:
  1380. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1381. SSL_CTX_sess_accept_good(ssl_acceptor_fd->
  1382. ssl_context)),
  1383. buff, 10);
  1384. break;
  1385. case SHOW_SSL_CTX_SESS_CONNECT_GOOD:
  1386. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1387. SSL_CTX_sess_connect_good(ssl_acceptor_fd->
  1388. ssl_context)),
  1389. buff, 10);
  1390. break;
  1391. case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE:
  1392. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1393. SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context)),
  1394. buff, 10);
  1395. break;
  1396. case SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE:
  1397. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1398. SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd-> ssl_context)),
  1399. buff, 10);
  1400. break;
  1401. case SHOW_SSL_CTX_SESS_CB_HITS:
  1402. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1403. SSL_CTX_sess_cb_hits(ssl_acceptor_fd->
  1404. ssl_context)),
  1405. buff, 10);
  1406. break;
  1407. case SHOW_SSL_CTX_SESS_HITS:
  1408. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1409. SSL_CTX_sess_hits(ssl_acceptor_fd->
  1410. ssl_context)),
  1411. buff, 10);
  1412. break;
  1413. case SHOW_SSL_CTX_SESS_CACHE_FULL:
  1414. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1415. SSL_CTX_sess_cache_full(ssl_acceptor_fd->
  1416. ssl_context)),
  1417. buff, 10);
  1418. break;
  1419. case SHOW_SSL_CTX_SESS_MISSES:
  1420. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1421. SSL_CTX_sess_misses(ssl_acceptor_fd->
  1422. ssl_context)),
  1423. buff, 10);
  1424. break;
  1425. case SHOW_SSL_CTX_SESS_TIMEOUTS:
  1426. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1427. SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context)),
  1428. buff,10);
  1429. break;
  1430. case SHOW_SSL_CTX_SESS_NUMBER:
  1431. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1432. SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context)),
  1433. buff,10);
  1434. break;
  1435. case SHOW_SSL_CTX_SESS_CONNECT:
  1436. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1437. SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context)),
  1438. buff,10);
  1439. break;
  1440. case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE:
  1441. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1442. SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context)),
  1443. buff,10);
  1444. break;
  1445. case SHOW_SSL_CTX_GET_VERIFY_MODE:
  1446. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1447. SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context)),
  1448. buff,10);
  1449. break;
  1450. case SHOW_SSL_CTX_GET_VERIFY_DEPTH:
  1451. end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
  1452. SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context)),
  1453. buff,10);
  1454. break;
  1455. case SHOW_SSL_CTX_GET_SESSION_CACHE_MODE:
  1456. if (!ssl_acceptor_fd)
  1457. {
  1458. pos= "NONE";
  1459. end= pos+4;
  1460. break;
  1461. }
  1462. switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
  1463. {
  1464. case SSL_SESS_CACHE_OFF:
  1465. pos= "OFF";
  1466. break;
  1467. case SSL_SESS_CACHE_CLIENT:
  1468. pos= "CLIENT";
  1469. break;
  1470. case SSL_SESS_CACHE_SERVER:
  1471. pos= "SERVER";
  1472. break;
  1473. case SSL_SESS_CACHE_BOTH:
  1474. pos= "BOTH";
  1475. break;
  1476. case SSL_SESS_CACHE_NO_AUTO_CLEAR:
  1477. pos= "NO_AUTO_CLEAR";
  1478. break;
  1479. case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
  1480. pos= "NO_INTERNAL_LOOKUP";
  1481. break;
  1482. default:
  1483. pos= "Unknown";
  1484. break;
  1485. }
  1486. end= strend(pos);
  1487. break;
  1488. /* First group - functions relying on SSL */
  1489. case SHOW_SSL_GET_VERSION:
  1490. pos= (thd->net.vio->ssl_arg ?
  1491. SSL_get_version((SSL*) thd->net.vio->ssl_arg) : "");
  1492. end= strend(pos);
  1493. break;
  1494. case SHOW_SSL_SESSION_REUSED:
  1495. end= int10_to_str((long) (thd->net.vio->ssl_arg ?
  1496. SSL_session_reused((SSL*) thd->net.vio->
  1497. ssl_arg) :
  1498. 0),
  1499. buff, 10);
  1500. break;
  1501. case SHOW_SSL_GET_DEFAULT_TIMEOUT:
  1502. end= int10_to_str((long) (thd->net.vio->ssl_arg ?
  1503. SSL_get_default_timeout((SSL*) thd->net.vio->
  1504. ssl_arg) :
  1505. 0),
  1506. buff, 10);
  1507. break;
  1508. case SHOW_SSL_GET_VERIFY_MODE:
  1509. end= int10_to_str((long) (thd->net.vio->ssl_arg ?
  1510. SSL_get_verify_mode((SSL*) thd->net.vio->
  1511. ssl_arg):
  1512. 0),
  1513. buff, 10);
  1514. break;
  1515. case SHOW_SSL_GET_VERIFY_DEPTH:
  1516. end= int10_to_str((long) (thd->net.vio->ssl_arg ?
  1517. SSL_get_verify_depth((SSL*) thd->net.vio->
  1518. ssl_arg):
  1519. 0),
  1520. buff, 10);
  1521. break;
  1522. case SHOW_SSL_GET_CIPHER:
  1523. pos= (thd->net.vio->ssl_arg ?
  1524. SSL_get_cipher((SSL*) thd->net.vio->ssl_arg) : "" );
  1525. end= strend(pos);
  1526. break;
  1527. case SHOW_SSL_GET_CIPHER_LIST:
  1528. if (thd->net.vio->ssl_arg)
  1529. {
  1530. char *to= buff;
  1531. for (int i=0 ; i++ ;)
  1532. {
  1533. const char *p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i);
  1534. if (p == NULL)
  1535. break;
  1536. to= strmov(to, p);
  1537. *to++= ':';
  1538. }
  1539. if (to != buff)
  1540. to--; // Remove last ':'
  1541. end= to;
  1542. }
  1543. break;
  1544. #endif /* HAVE_OPENSSL */
  1545. case SHOW_KEY_CACHE_LONG:
  1546. case SHOW_KEY_CACHE_CONST_LONG:
  1547. value= (value-(char*) &dflt_key_cache_var)+ (char*) dflt_key_cache;
  1548. end= int10_to_str(*(long*) value, buff, 10);
  1549. break;
  1550. case SHOW_KEY_CACHE_LONGLONG:
  1551. value= (value-(char*) &dflt_key_cache_var)+ (char*) dflt_key_cache;
  1552. end= longlong10_to_str(*(longlong*) value, buff, 10);
  1553. break;
  1554. case SHOW_NET_COMPRESSION:
  1555. end= strmov(buff, thd->net.compress ? "ON" : "OFF");
  1556. break;
  1557. case SHOW_UNDEF: // Show never happen
  1558. case SHOW_SYS:
  1559. break; // Return empty string
  1560. default:
  1561. break;
  1562. }
  1563. restore_record(table, s->default_values);
  1564. table->field[0]->store(name_buffer, strlen(name_buffer),
  1565. system_charset_info);
  1566. table->field[1]->store(pos, (uint32) (end - pos), system_charset_info);
  1567. if (schema_table_store_record(thd, table))
  1568. DBUG_RETURN(TRUE);
  1569. }
  1570. }
  1571. }
  1572. DBUG_RETURN(FALSE);
  1573. }
  1574. /* collect status for all running threads */
  1575. void calc_sum_of_all_status(STATUS_VAR *to)
  1576. {
  1577. DBUG_ENTER("calc_sum_of_all_status");
  1578. /* Ensure that thread id not killed during loop */
  1579. VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
  1580. I_List_iterator<THD> it(threads);
  1581. THD *tmp;
  1582. /* Get global values as base */
  1583. *to= global_status_var;
  1584. /* Add to this status from existing threads */
  1585. while ((tmp= it++))
  1586. add_to_status(to, &tmp->status_var);
  1587. VOID(pthread_mutex_unlock(&LOCK_thread_count));
  1588. DBUG_VOID_RETURN;
  1589. }
  1590. LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
  1591. const char* str, uint length,
  1592. bool allocate_lex_string)
  1593. {
  1594. MEM_ROOT *mem= thd->mem_root;
  1595. if (allocate_lex_string)
  1596. if (!(lex_str= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING))))
  1597. return 0;
  1598. lex_str->str= strmake_root(mem, str, length);
  1599. lex_str->length= length;
  1600. return lex_str;
  1601. }
  1602. /* INFORMATION_SCHEMA name */
  1603. LEX_STRING information_schema_name= {(char*)"information_schema", 18};
  1604. /* This is only used internally, but we need it here as a forward reference */
  1605. extern ST_SCHEMA_TABLE schema_tables[];
  1606. typedef struct st_index_field_values
  1607. {
  1608. const char *db_value, *table_value;
  1609. } INDEX_FIELD_VALUES;
  1610. /*
  1611. Store record to I_S table, convert HEAP table
  1612. to MyISAM if necessary
  1613. SYNOPSIS
  1614. schema_table_store_record()
  1615. thd thread handler
  1616. table Information schema table to be updated
  1617. RETURN
  1618. 0 success
  1619. 1 error
  1620. */
  1621. static bool schema_table_store_record(THD *thd, TABLE *table)
  1622. {
  1623. int error;
  1624. if ((error= table->file->write_row(table->record[0])))
  1625. {
  1626. if (create_myisam_from_heap(thd, table,
  1627. table->pos_in_table_list->schema_table_param,
  1628. error, 0))
  1629. return 1;
  1630. }
  1631. return 0;
  1632. }
  1633. void get_index_field_values(LEX *lex, INDEX_FIELD_VALUES *index_field_values)
  1634. {
  1635. const char *wild= lex->wild ? lex->wild->ptr() : NullS;
  1636. switch (lex->orig_sql_command) {
  1637. case SQLCOM_SHOW_DATABASES:
  1638. index_field_values->db_value= wild;
  1639. break;
  1640. case SQLCOM_SHOW_TABLES:
  1641. case SQLCOM_SHOW_TABLE_STATUS:
  1642. case SQLCOM_SHOW_TRIGGERS:
  1643. index_field_values->db_value= lex->select_lex.db;
  1644. index_field_values->table_value= wild;
  1645. break;
  1646. default:
  1647. index_field_values->db_value= NullS;
  1648. index_field_values->table_value= NullS;
  1649. break;
  1650. }
  1651. }
  1652. int make_table_list(THD *thd, SELECT_LEX *sel,
  1653. char *db, char *table)
  1654. {
  1655. Table_ident *table_ident;
  1656. LEX_STRING ident_db, ident_table;
  1657. ident_db.str= db;
  1658. ident_db.length= strlen(db);
  1659. ident_table.str= table;
  1660. ident_table.length= strlen(table);
  1661. table_ident= new Table_ident(thd, ident_db, ident_table, 1);
  1662. sel->init_query();
  1663. if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
  1664. (List<String> *) 0, (List<String> *) 0))
  1665. return 1;
  1666. return 0;
  1667. }
  1668. bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
  1669. {
  1670. if (item->type() == Item::FUNC_ITEM)
  1671. {
  1672. Item_func *item_func= (Item_func*)item;
  1673. Item **child;
  1674. Item **item_end= (item_func->arguments()) + item_func->argument_count();
  1675. for (child= item_func->arguments(); child != item_end; child++)
  1676. {
  1677. if (!uses_only_table_name_fields(*child, table))
  1678. return 0;
  1679. }
  1680. }
  1681. else if (item->type() == Item::FIELD_ITEM)
  1682. {
  1683. Item_field *item_field= (Item_field*)item;
  1684. CHARSET_INFO *cs= system_charset_info;
  1685. ST_SCHEMA_TABLE *schema_table= table->schema_table;
  1686. ST_FIELD_INFO *field_info= schema_table->fields_info;
  1687. const char *field_name1= schema_table->idx_field1 >= 0 ? field_info[schema_table->idx_field1].field_name : "";
  1688. const char *field_name2= schema_table->idx_field2 >= 0 ? field_info[schema_table->idx_field2].field_name : "";
  1689. if (table->table != item_field->field->table ||
  1690. (cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
  1691. (uchar *) item_field->field_name,
  1692. strlen(item_field->field_name), 0) &&
  1693. cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
  1694. (uchar *) item_field->field_name,
  1695. strlen(item_field->field_name), 0)))
  1696. return 0;
  1697. }
  1698. else if (item->type() == Item::REF_ITEM)
  1699. return uses_only_table_name_fields(item->real_item(), table);
  1700. if (item->type() == Item::SUBSELECT_ITEM &&
  1701. !item->const_item())
  1702. return 0;
  1703. return 1;
  1704. }
  1705. static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
  1706. {
  1707. if (!cond)
  1708. return (COND*) 0;
  1709. if (cond->type() == Item::COND_ITEM)
  1710. {
  1711. if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
  1712. {
  1713. /* Create new top level AND item */
  1714. Item_cond_and *new_cond=new Item_cond_and;
  1715. if (!new_cond)
  1716. return (COND*) 0;
  1717. List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
  1718. Item *item;
  1719. while ((item=li++))
  1720. {
  1721. Item *fix= make_cond_for_info_schema(item, table);
  1722. if (fix)
  1723. new_cond->argument_list()->push_back(fix);
  1724. }
  1725. switch (new_cond->argument_list()->elements) {
  1726. case 0:
  1727. return (COND*) 0;
  1728. case 1:
  1729. return new_cond->argument_list()->head();
  1730. default:
  1731. new_cond->quick_fix_field();
  1732. return new_cond;
  1733. }
  1734. }
  1735. else
  1736. { // Or list
  1737. Item_cond_or *new_cond=new Item_cond_or;
  1738. if (!new_cond)
  1739. return (COND*) 0;
  1740. List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
  1741. Item *item;
  1742. while ((item=li++))
  1743. {
  1744. Item *fix=make_cond_for_info_schema(item, table);
  1745. if (!fix)
  1746. return (COND*) 0;
  1747. new_cond->argument_list()->push_back(fix);
  1748. }
  1749. new_cond->quick_fix_field();
  1750. new_cond->top_level_item();
  1751. return new_cond;
  1752. }
  1753. }
  1754. if (!uses_only_table_name_fields(cond, table))
  1755. return (COND*) 0;
  1756. return cond;
  1757. }
  1758. enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
  1759. {
  1760. return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
  1761. }
  1762. /*
  1763. Create db names list. Information schema name always is first in list
  1764. SYNOPSIS
  1765. make_db_list()
  1766. thd thread handler
  1767. files list of db names
  1768. wild wild string
  1769. idx_field_vals idx_field_vals->db_name contains db name or
  1770. wild string
  1771. with_i_schema returns 1 if we added 'IS' name to list
  1772. otherwise returns 0
  1773. is_wild_value if value is 1 then idx_field_vals->db_name is
  1774. wild string otherwise it's db name;
  1775. RETURN
  1776. 1 error
  1777. 0 success
  1778. */
  1779. int make_db_list(THD *thd, List<char> *files,
  1780. INDEX_FIELD_VALUES *idx_field_vals,
  1781. bool *with_i_schema, bool is_wild_value)
  1782. {
  1783. LEX *lex= thd->lex;
  1784. *with_i_schema= 0;
  1785. get_index_field_values(lex, idx_field_vals);
  1786. if (is_wild_value)
  1787. {
  1788. /*
  1789. This part of code is only for SHOW DATABASES command.
  1790. idx_field_vals->db_value can be 0 when we don't use
  1791. LIKE clause (see also get_index_field_values() function)
  1792. */
  1793. if (!idx_field_vals->db_value ||
  1794. !wild_case_compare(system_charset_info,
  1795. information_schema_name.str,
  1796. idx_field_vals->db_value))
  1797. {
  1798. *with_i_schema= 1;
  1799. if (files->push_back(thd->strdup(information_schema_name.str)))
  1800. return 1;
  1801. }
  1802. return mysql_find_files(thd, files, NullS, mysql_data_home,
  1803. idx_field_vals->db_value, 1);
  1804. }
  1805. /*
  1806. This part of code is for SHOW TABLES, SHOW TABLE STATUS commands.
  1807. idx_field_vals->db_value can't be 0 (see get_index_field_values()
  1808. function). lex->orig_sql_command can be not equal to SQLCOM_END
  1809. only in case of executing of SHOW commands.
  1810. */
  1811. if (lex->orig_sql_command != SQLCOM_END)
  1812. {
  1813. if (!my_strcasecmp(system_charset_info, information_schema_name.str,
  1814. idx_field_vals->db_value))
  1815. {
  1816. *with_i_schema= 1;
  1817. return files->push_back(thd->strdup(information_schema_name.str));
  1818. }
  1819. return files->push_back(thd->strdup(idx_field_vals->db_value));
  1820. }
  1821. /*
  1822. Create list of existing databases. It is used in case
  1823. of select from information schema table
  1824. */
  1825. if (files->push_back(thd->strdup(information_schema_name.str)))
  1826. return 1;
  1827. *with_i_schema= 1;
  1828. return mysql_find_files(thd, files, NullS, mysql_data_home, NullS, 1);
  1829. }
  1830. int schema_tables_add(THD *thd, List<char> *files, const char *wild)
  1831. {
  1832. ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
  1833. for (; tmp_schema_table->table_name; tmp_schema_table++)
  1834. {
  1835. if (tmp_schema_table->hidden)
  1836. continue;
  1837. if (wild)
  1838. {
  1839. if (lower_case_table_names)
  1840. {
  1841. if (wild_case_compare(files_charset_info,
  1842. tmp_schema_table->table_name,
  1843. wild))
  1844. continue;
  1845. }
  1846. else if (wild_compare(tmp_schema_table->table_name, wild, 0))
  1847. continue;
  1848. }
  1849. if (files->push_back(thd->strdup(tmp_schema_table->table_name)))
  1850. return 1;
  1851. }
  1852. return 0;
  1853. }
  1854. int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
  1855. {
  1856. LEX *lex= thd->lex;
  1857. TABLE *table= tables->table;
  1858. SELECT_LEX *select_lex= &lex->select_lex;
  1859. SELECT_LEX *old_all_select_lex= lex->all_selects_list;
  1860. TABLE_LIST **save_query_tables_last= lex->query_tables_last;
  1861. enum_sql_command save_sql_command= lex->sql_command;
  1862. SELECT_LEX *lsel= tables->schema_select_lex;
  1863. ST_SCHEMA_TABLE *schema_table= tables->schema_table;
  1864. SELECT_LEX sel;
  1865. INDEX_FIELD_VALUES idx_field_vals;
  1866. char path[FN_REFLEN], *end, *base_name, *file_name;
  1867. uint len;
  1868. bool with_i_schema;
  1869. enum enum_schema_tables schema_table_idx;
  1870. List<char> bases;
  1871. List_iterator_fast<char> it(bases);
  1872. COND *partial_cond;
  1873. Security_context *sctx= thd->security_ctx;
  1874. uint derived_tables= lex->derived_tables;
  1875. int error= 1;
  1876. db_type not_used;
  1877. Open_tables_state open_tables_state_backup;
  1878. bool save_view_prepare_mode= lex->view_prepare_mode;
  1879. lex->view_prepare_mode= TRUE;
  1880. DBUG_ENTER("get_all_tables");
  1881. LINT_INIT(end);
  1882. LINT_INIT(len);
  1883. /*
  1884. Let us set fake sql_command so views won't try to merge
  1885. themselves into main statement.
  1886. */
  1887. lex->sql_command= SQLCOM_SHOW_FIELDS;
  1888. /*
  1889. We should not introduce deadlocks even if we already have some
  1890. tables open and locked, since we won't lock tables which we will
  1891. open and will ignore possible name-locks for these tables.
  1892. */
  1893. thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
  1894. if (lsel)
  1895. {
  1896. TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first;
  1897. bool res;
  1898. lex->all_selects_list= lsel;
  1899. /*
  1900. Restore thd->temporary_tables to be able to process
  1901. temporary tables(only for 'show index' & 'show columns').
  1902. This should be changed when processing of temporary tables for
  1903. I_S tables will be done.
  1904. */
  1905. thd->temporary_tables= open_tables_state_backup.temporary_tables;
  1906. res= open_normal_and_derived_tables(thd, show_table_list,
  1907. MYSQL_LOCK_IGNORE_FLUSH);
  1908. /*
  1909. get_all_tables() returns 1 on failure and 0 on success thus
  1910. return only these and not the result code of ::process_table()
  1911. We should use show_table_list->alias instead of
  1912. show_table_list->table_name because table_name
  1913. could be changed during opening of I_S tables. It's safe
  1914. to use alias because alias contains original table name
  1915. in this case(this part of code is used only for
  1916. 'show columns' & 'show statistics' commands).
  1917. */
  1918. error= test(schema_table->process_table(thd, show_table_list,
  1919. table, res,
  1920. (show_table_list->view ?
  1921. show_table_list->view_db.str :
  1922. show_table_list->db),
  1923. show_table_list->alias));
  1924. thd->temporary_tables= 0;
  1925. close_thread_tables(thd);
  1926. show_table_list->table= 0;
  1927. goto err;
  1928. }
  1929. schema_table_idx= get_schema_table_idx(schema_table);
  1930. if (make_db_list(thd, &bases, &idx_field_vals,
  1931. &with_i_schema, 0))
  1932. goto err;
  1933. partial_cond= make_cond_for_info_schema(cond, tables);
  1934. it.rewind(); /* To get access to new elements in basis list */
  1935. while ((base_name= it++) ||
  1936. /*
  1937. generate error for non existing database.
  1938. (to save old behaviour for SHOW TABLES FROM db)
  1939. */
  1940. ((lex->orig_sql_command == SQLCOM_SHOW_TABLES ||
  1941. lex->orig_sql_command == SQLCOM_SHOW_TABLE_STATUS) &&
  1942. (base_name= select_lex->db) && !bases.elements))
  1943. {
  1944. #ifndef NO_EMBEDDED_ACCESS_CHECKS
  1945. if (!check_access(thd,SELECT_ACL, base_name,
  1946. &thd->col_access, 0, 1, with_i_schema) ||
  1947. sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
  1948. acl_get(sctx->host, sctx->ip, sctx->priv_user, base_name,0) ||
  1949. (grant_option && !check_grant_db(thd, base_name)))
  1950. #endif
  1951. {
  1952. List<char> files;
  1953. if (with_i_schema) // information schema table names
  1954. {
  1955. if (schema_tables_add(thd, &files, idx_field_vals.table_value))
  1956. goto err;
  1957. }
  1958. else
  1959. {
  1960. strxmov(path, mysql_data_home, "/", base_name, NullS);
  1961. end= path + (len= unpack_dirname(path,path));
  1962. len= FN_LEN - len;
  1963. if (mysql_find_files(thd, &files, base_name,
  1964. path, idx_field_vals.table_value, 0))
  1965. goto err;
  1966. }
  1967. List_iterator_fast<char> it_files(files);
  1968. while ((file_name= it_files++))
  1969. {
  1970. restore_record(table, s->default_values);
  1971. table->field[schema_table->idx_field1]->
  1972. store(base_name, strlen(base_name), system_charset_info);
  1973. table->field[schema_table->idx_field2]->
  1974. store(file_name, strlen(file_name),system_charset_info);
  1975. if (!partial_cond || partial_cond->val_int())
  1976. {
  1977. if (schema_table_idx == SCH_TABLE_NAMES)
  1978. {
  1979. if (lex->verbose || lex->orig_sql_command == SQLCOM_END)
  1980. {
  1981. if (with_i_schema)
  1982. {
  1983. table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
  1984. system_charset_info);
  1985. }
  1986. else
  1987. {
  1988. my_snprintf(end, len, "/%s%s", file_name, reg_ext);
  1989. switch (mysql_frm_type(thd, path, &not_used)) {
  1990. case FRMTYPE_ERROR:
  1991. table->field[3]->store(STRING_WITH_LEN("ERROR"),
  1992. system_charset_info);
  1993. break;
  1994. case FRMTYPE_TABLE:
  1995. table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
  1996. system_charset_info);
  1997. break;
  1998. case FRMTYPE_VIEW:
  1999. table->field[3]->store(STRING_WITH_LEN("VIEW"),
  2000. system_charset_info);
  2001. break;
  2002. default:
  2003. DBUG_ASSERT(0);
  2004. }
  2005. }
  2006. }
  2007. if (schema_table_store_record(thd, table))
  2008. goto err;
  2009. }
  2010. else
  2011. {
  2012. int res;
  2013. /*
  2014. Set the parent lex of 'sel' because it is needed by sel.init_query()
  2015. which is called inside make_table_list.
  2016. */
  2017. sel.parent_lex= lex;
  2018. if (make_table_list(thd, &sel, base_name, file_name))
  2019. goto err;
  2020. TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
  2021. lex->all_selects_list= &sel;
  2022. lex->derived_tables= 0;
  2023. res= open_normal_and_derived_tables(thd, show_table_list,
  2024. MYSQL_LOCK_IGNORE_FLUSH);
  2025. /*
  2026. We should use show_table_list->alias instead of
  2027. show_table_list->table_name because table_name
  2028. could be changed during opening of I_S tables. It's safe
  2029. to use alias because alias contains original table name
  2030. in this case.
  2031. */
  2032. res= schema_table->process_table(thd, show_table_list, table,
  2033. res, base_name,
  2034. show_table_list->alias);
  2035. close_thread_tables(thd);
  2036. if (res)
  2037. goto err;
  2038. }
  2039. }
  2040. }
  2041. /*
  2042. If we have information schema its always the first table and only
  2043. the first table. Reset for other tables.
  2044. */
  2045. with_i_schema= 0;
  2046. }
  2047. }
  2048. error= 0;
  2049. err:
  2050. thd->restore_backup_open_tables_state(&open_tables_state_backup);
  2051. lex->derived_tables= derived_tables;
  2052. lex->all_selects_list= old_all_select_lex;
  2053. lex->query_tables_last= save_query_tables_last;
  2054. lex->view_prepare_mode= save_view_prepare_mode;
  2055. *save_query_tables_last= 0;
  2056. lex->sql_command= save_sql_command;
  2057. DBUG_RETURN(error);
  2058. }
  2059. bool store_schema_shemata(THD* thd, TABLE *table, const char *db_name,
  2060. CHARSET_INFO *cs)
  2061. {
  2062. restore_record(table, s->default_values);
  2063. table->field[1]->store(db_name, strlen(db_name), system_charset_info);
  2064. table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
  2065. table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
  2066. return schema_table_store_record(thd, table);
  2067. }
  2068. int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond)
  2069. {
  2070. char path[FN_REFLEN];
  2071. bool found_libchar;
  2072. INDEX_FIELD_VALUES idx_field_vals;
  2073. List<char> files;
  2074. char *file_name;
  2075. uint length;
  2076. bool with_i_schema;
  2077. HA_CREATE_INFO create;
  2078. TABLE *table= tables->table;
  2079. Security_context *sctx= thd->security_ctx;
  2080. DBUG_ENTER("fill_schema_shemata");
  2081. if (make_db_list(thd, &files, &idx_field_vals,
  2082. &with_i_schema, 1))
  2083. DBUG_RETURN(1);
  2084. List_iterator_fast<char> it(files);
  2085. while ((file_name=it++))
  2086. {
  2087. if (with_i_schema) // information schema name is always first in list
  2088. {
  2089. if (store_schema_shemata(thd, table, file_name,
  2090. system_charset_info))
  2091. DBUG_RETURN(1);
  2092. with_i_schema= 0;
  2093. continue;
  2094. }
  2095. #ifndef NO_EMBEDDED_ACCESS_CHECKS
  2096. if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
  2097. acl_get(sctx->host, sctx->ip, sctx->priv_user, file_name,0) ||
  2098. (grant_option && !check_grant_db(thd, file_name)))
  2099. #endif
  2100. {
  2101. strxmov(path, mysql_data_home, "/", file_name, NullS);
  2102. length=unpack_dirname(path,path); // Convert if not unix
  2103. found_libchar= 0;
  2104. if (length && path[length-1] == FN_LIBCHAR)
  2105. {
  2106. found_libchar= 1;
  2107. path[length-1]=0; // remove ending '\'
  2108. }
  2109. if (found_libchar)
  2110. path[length-1]= FN_LIBCHAR;
  2111. strmov(path+length, MY_DB_OPT_FILE);
  2112. load_db_opt(thd, path, &create);
  2113. if (store_schema_shemata(thd, table, file_name,
  2114. create.default_table_charset))
  2115. DBUG_RETURN(1);
  2116. }
  2117. }
  2118. DBUG_RETURN(0);
  2119. }
  2120. static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
  2121. TABLE *table, bool res,
  2122. const char *base_name,
  2123. const char *file_name)
  2124. {
  2125. const char *tmp_buff;
  2126. TIME time;
  2127. CHARSET_INFO *cs= system_charset_info;
  2128. DBUG_ENTER("get_schema_tables_record");
  2129. restore_record(table, s->default_values);
  2130. table->field[1]->store(base_name, strlen(base_name), cs);
  2131. table->field[2]->store(file_name, strlen(file_name), cs);
  2132. if (res)
  2133. {
  2134. /*
  2135. there was errors during opening tables
  2136. */
  2137. const char *error= thd->net.last_error;
  2138. if (tables->view)
  2139. table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
  2140. else if (tables->schema_table)
  2141. table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
  2142. else
  2143. table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
  2144. table->field[20]->store(error, strlen(error), cs);
  2145. thd->clear_error();
  2146. }
  2147. else if (tables->view)
  2148. {
  2149. table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
  2150. table->field[20]->store(STRING_WITH_LEN("VIEW"), cs);
  2151. }
  2152. else
  2153. {
  2154. TABLE *show_table= tables->table;
  2155. TABLE_SHARE *share= show_table->s;
  2156. handler *file= show_table->file;
  2157. file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
  2158. HA_STATUS_NO_LOCK);
  2159. if (share->tmp_table == SYSTEM_TMP_TABLE)
  2160. table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
  2161. else if (share->tmp_table)
  2162. table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
  2163. else
  2164. table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
  2165. for (int i= 4; i < 20; i++)
  2166. {
  2167. if (i == 7 || (i > 12 && i < 17) || i == 18)
  2168. continue;
  2169. table->field[i]->set_notnull();
  2170. }
  2171. tmp_buff= file->table_type();
  2172. table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
  2173. table->field[5]->store((longlong) share->frm_version, TRUE);
  2174. enum row_type row_type = file->get_row_type();
  2175. switch (row_type) {
  2176. case ROW_TYPE_NOT_USED:
  2177. case ROW_TYPE_DEFAULT:
  2178. tmp_buff= ((share->db_options_in_use &
  2179. HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
  2180. (share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
  2181. "Dynamic" : "Fixed");
  2182. break;
  2183. case ROW_TYPE_FIXED:
  2184. tmp_buff= "Fixed";
  2185. break;
  2186. case ROW_TYPE_DYNAMIC:
  2187. tmp_buff= "Dynamic";
  2188. break;
  2189. case ROW_TYPE_COMPRESSED:
  2190. tmp_buff= "Compressed";
  2191. break;
  2192. case ROW_TYPE_REDUNDANT:
  2193. tmp_buff= "Redundant";
  2194. break;
  2195. case ROW_TYPE_COMPACT:
  2196. tmp_buff= "Compact";
  2197. break;
  2198. }
  2199. table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
  2200. if (!tables->schema_table)
  2201. {
  2202. table->field[7]->store((longlong) file->records, TRUE);
  2203. table->field[7]->set_notnull();
  2204. }
  2205. table->field[8]->store((longlong) file->mean_rec_length, TRUE);
  2206. table->field[9]->store((longlong) file->data_file_length, TRUE);
  2207. if (file->max_data_file_length)
  2208. {
  2209. table->field[10]->store((longlong) file->max_data_file_length, TRUE);
  2210. }
  2211. table->field[11]->store((longlong) file->index_file_length, TRUE);
  2212. table->field[12]->store((longlong) file->delete_length, TRUE);
  2213. if (show_table->found_next_number_field)
  2214. {
  2215. table->field[13]->store((longlong) file->auto_increment_value, TRUE);
  2216. table->field[13]->set_notnull();
  2217. }
  2218. if (file->create_time)
  2219. {
  2220. thd->variables.time_zone->gmt_sec_to_TIME(&time,
  2221. file->create_time);
  2222. table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
  2223. table->field[14]->set_notnull();
  2224. }
  2225. if (file->update_time)
  2226. {
  2227. thd->variables.time_zone->gmt_sec_to_TIME(&time,
  2228. file->update_time);
  2229. table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
  2230. table->field[15]->set_notnull();
  2231. }
  2232. if (file->check_time)
  2233. {
  2234. thd->variables.time_zone->gmt_sec_to_TIME(&time, file->check_time);
  2235. table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
  2236. table->field[16]->set_notnull();
  2237. }
  2238. tmp_buff= (share->table_charset ?
  2239. share->table_charset->name : "default");
  2240. table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
  2241. if (file->table_flags() & (ulong) HA_HAS_CHECKSUM)
  2242. {
  2243. table->field[18]->store((longlong) file->checksum(), TRUE);
  2244. table->field[18]->set_notnull();
  2245. }
  2246. char option_buff[350],*ptr;
  2247. ptr=option_buff;
  2248. if (share->min_rows)
  2249. {
  2250. ptr=strmov(ptr," min_rows=");
  2251. ptr=longlong10_to_str(share->min_rows,ptr,10);
  2252. }
  2253. if (share->max_rows)
  2254. {
  2255. ptr=strmov(ptr," max_rows=");
  2256. ptr=longlong10_to_str(share->max_rows,ptr,10);
  2257. }
  2258. if (share->avg_row_length)
  2259. {
  2260. ptr=strmov(ptr," avg_row_length=");
  2261. ptr=longlong10_to_str(share->avg_row_length,ptr,10);
  2262. }
  2263. if (share->db_create_options & HA_OPTION_PACK_KEYS)
  2264. ptr=strmov(ptr," pack_keys=1");
  2265. if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
  2266. ptr=strmov(ptr," pack_keys=0");
  2267. if (share->db_create_options & HA_OPTION_CHECKSUM)
  2268. ptr=strmov(ptr," checksum=1");
  2269. if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
  2270. ptr=strmov(ptr," delay_key_write=1");
  2271. if (share->row_type != ROW_TYPE_DEFAULT)
  2272. ptr=strxmov(ptr, " row_format=",
  2273. ha_row_type[(uint) share->row_type],
  2274. NullS);
  2275. if (file->raid_type)
  2276. {
  2277. char buff[100];
  2278. my_snprintf(buff,sizeof(buff),
  2279. " raid_type=%s raid_chunks=%d raid_chunksize=%ld",
  2280. my_raid_type(file->raid_type), file->raid_chunks,
  2281. file->raid_chunksize/RAID_BLOCK_SIZE);
  2282. ptr=strmov(ptr,buff);
  2283. }
  2284. table->field[19]->store(option_buff+1,
  2285. (ptr == option_buff ? 0 :
  2286. (uint) (ptr-option_buff)-1), cs);
  2287. {
  2288. char *comment;
  2289. comment= show_table->file->update_table_comment(share->comment);
  2290. if (comment)
  2291. {
  2292. table->field[20]->store(comment, strlen(comment), cs);
  2293. if (comment != share->comment)
  2294. my_free(comment, MYF(0));
  2295. }
  2296. }
  2297. }
  2298. DBUG_RETURN(schema_table_store_record(thd, table));
  2299. }
  2300. static int get_schema_column_record(THD *thd, struct st_table_list *tables,
  2301. TABLE *table, bool res,
  2302. const char *base_name,
  2303. const char *file_name)
  2304. {
  2305. LEX *lex= thd->lex;
  2306. const char *wild= lex->wild ? lex->wild->ptr() : NullS;
  2307. CHARSET_INFO *cs= system_charset_info;
  2308. TABLE *show_table;
  2309. handler *file;
  2310. Field **ptr,*field;
  2311. int count;
  2312. uint base_name_length, file_name_length;
  2313. DBUG_ENTER("get_schema_column_record");
  2314. if (res)
  2315. {
  2316. if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS)
  2317. {
  2318. /*
  2319. I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
  2320. rather than in SHOW COLUMNS
  2321. */
  2322. push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  2323. thd->net.last_errno, thd->net.last_error);
  2324. thd->clear_error();
  2325. res= 0;
  2326. }
  2327. DBUG_RETURN(res);
  2328. }
  2329. show_table= tables->table;
  2330. file= show_table->file;
  2331. count= 0;
  2332. file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
  2333. restore_record(show_table, s->default_values);
  2334. base_name_length= strlen(base_name);
  2335. file_name_length= strlen(file_name);
  2336. for (ptr=show_table->field; (field= *ptr) ; ptr++)
  2337. {
  2338. const char *tmp_buff;
  2339. byte *pos;
  2340. bool is_blob;
  2341. uint flags=field->flags;
  2342. char tmp[MAX_FIELD_WIDTH];
  2343. char tmp1[MAX_FIELD_WIDTH];
  2344. String type(tmp,sizeof(tmp), system_charset_info);
  2345. char *end;
  2346. int decimals, field_length;
  2347. if (wild && wild[0] &&
  2348. wild_case_compare(system_charset_info, field->field_name,wild))
  2349. continue;
  2350. flags= field->flags;
  2351. count++;
  2352. /* Get default row, with all NULL fields set to NULL */
  2353. restore_record(table, s->default_values);
  2354. #ifndef NO_EMBEDDED_ACCESS_CHECKS
  2355. uint col_access;
  2356. check_access(thd,SELECT_ACL | EXTRA_ACL, base_name,
  2357. &tables->grant.privilege, 0, 0, test(tables->schema_table));
  2358. col_access= get_column_grant(thd, &tables->grant,
  2359. base_name, file_name,
  2360. field->field_name) & COL_ACLS;
  2361. if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS &&
  2362. !tables->schema_table && !col_access)
  2363. continue;
  2364. end= tmp;
  2365. for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
  2366. {
  2367. if (col_access & 1)
  2368. {
  2369. *end++=',';
  2370. end=strmov(end,grant_types.type_names[bitnr]);
  2371. }
  2372. }
  2373. table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);
  2374. #endif
  2375. table->field[1]->store(base_name, base_name_length, cs);
  2376. table->field[2]->store(file_name, file_name_length, cs);
  2377. table->field[3]->store(field->field_name, strlen(field->field_name),
  2378. cs);
  2379. table->field[4]->store((longlong) count, TRUE);
  2380. field->sql_type(type);
  2381. table->field[14]->store(type.ptr(), type.length(), cs);
  2382. tmp_buff= strchr(type.ptr(), '(');
  2383. table->field[7]->store(type.ptr(),
  2384. (tmp_buff ? tmp_buff - type.ptr() :
  2385. type.length()), cs);
  2386. if (show_table->timestamp_field == field &&
  2387. field->unireg_check != Field::TIMESTAMP_UN_FIELD)
  2388. {
  2389. table->field[5]->store(STRING_WITH_LEN("CURRENT_TIMESTAMP"), cs);
  2390. table->field[5]->set_notnull();
  2391. }
  2392. else if (field->unireg_check != Field::NEXT_NUMBER &&
  2393. !field->is_null() &&
  2394. !(field->flags & NO_DEFAULT_VALUE_FLAG))
  2395. {
  2396. String def(tmp1,sizeof(tmp1), cs);
  2397. type.set(tmp, sizeof(tmp), field->charset());
  2398. field->val_str(&type);
  2399. uint dummy_errors;
  2400. def.copy(type.ptr(), type.length(), type.charset(), cs, &dummy_errors);
  2401. table->field[5]->store(def.ptr(), def.length(), def.charset());
  2402. table->field[5]->set_notnull();
  2403. }
  2404. else if (field->unireg_check == Field::NEXT_NUMBER ||
  2405. lex->orig_sql_command != SQLCOM_SHOW_FIELDS ||
  2406. field->maybe_null())
  2407. table->field[5]->set_null(); // Null as default
  2408. else
  2409. {
  2410. table->field[5]->store("",0, cs);
  2411. table->field[5]->set_notnull();
  2412. }
  2413. pos=(byte*) ((flags & NOT_NULL_FLAG) &&
  2414. field->type() != FIELD_TYPE_TIMESTAMP ?
  2415. "NO" : "YES");
  2416. table->field[6]->store((const char*) pos,
  2417. strlen((const char*) pos), cs);
  2418. is_blob= (field->type() == FIELD_TYPE_BLOB);
  2419. if (field->has_charset() || is_blob ||
  2420. field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type
  2421. field->real_type() == MYSQL_TYPE_STRING) // For binary type
  2422. {
  2423. uint32 octet_max_length= field->max_length();
  2424. if (is_blob && octet_max_length != (uint32) 4294967295U)
  2425. octet_max_length /= field->charset()->mbmaxlen;
  2426. longlong char_max_len= is_blob ?
  2427. (longlong) octet_max_length / field->charset()->mbminlen :
  2428. (longlong) octet_max_length / field->charset()->mbmaxlen;
  2429. table->field[8]->store(char_max_len, TRUE);
  2430. table->field[8]->set_notnull();
  2431. table->field[9]->store((longlong) octet_max_length, TRUE);
  2432. table->field[9]->set_notnull();
  2433. }
  2434. /*
  2435. Calculate field_length and decimals.
  2436. They are set to -1 if they should not be set (we should return NULL)
  2437. */
  2438. decimals= field->decimals();
  2439. switch (field->type()) {
  2440. case FIELD_TYPE_NEWDECIMAL:
  2441. field_length= ((Field_new_decimal*) field)->precision;
  2442. break;
  2443. case FIELD_TYPE_DECIMAL:
  2444. field_length= field->field_length - (decimals ? 2 : 1);
  2445. break;
  2446. case FIELD_TYPE_TINY:
  2447. case FIELD_TYPE_SHORT:
  2448. case FIELD_TYPE_LONG:
  2449. case FIELD_TYPE_LONGLONG:
  2450. case FIELD_TYPE_INT24:
  2451. field_length= field->max_length() - 1;
  2452. break;
  2453. case FIELD_TYPE_BIT:
  2454. field_length= field->max_length();
  2455. decimals= -1; // return NULL
  2456. break;
  2457. case FIELD_TYPE_FLOAT:
  2458. case FIELD_TYPE_DOUBLE:
  2459. field_length= field->field_length;
  2460. if (decimals == NOT_FIXED_DEC)
  2461. decimals= -1; // return NULL
  2462. break;
  2463. default:
  2464. field_length= decimals= -1;
  2465. break;
  2466. }
  2467. if (field_length >= 0)
  2468. {
  2469. table->field[10]->store((longlong) field_length, TRUE);
  2470. table->field[10]->set_notnull();
  2471. }
  2472. if (decimals >= 0)
  2473. {
  2474. table->field[11]->store((longlong) decimals, TRUE);
  2475. table->field[11]->set_notnull();
  2476. }
  2477. if (field->has_charset())
  2478. {
  2479. pos=(byte*) field->charset()->csname;
  2480. table->field[12]->store((const char*) pos,
  2481. strlen((const char*) pos), cs);
  2482. table->field[12]->set_notnull();
  2483. pos=(byte*) field->charset()->name;
  2484. table->field[13]->store((const char*) pos,
  2485. strlen((const char*) pos), cs);
  2486. table->field[13]->set_notnull();
  2487. }
  2488. pos=(byte*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
  2489. (field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
  2490. (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
  2491. table->field[15]->store((const char*) pos,
  2492. strlen((const char*) pos), cs);
  2493. end= tmp;
  2494. if (field->unireg_check == Field::NEXT_NUMBER)
  2495. end=strmov(tmp,"auto_increment");
  2496. table->field[16]->store(tmp, (uint) (end-tmp), cs);
  2497. table->field[18]->store(field->comment.str, field->comment.length, cs);
  2498. if (schema_table_store_record(thd, table))
  2499. DBUG_RETURN(1);
  2500. }
  2501. DBUG_RETURN(0);
  2502. }
  2503. int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
  2504. {
  2505. CHARSET_INFO **cs;
  2506. const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
  2507. TABLE *table= tables->table;
  2508. CHARSET_INFO *scs= system_charset_info;
  2509. for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
  2510. {
  2511. CHARSET_INFO *tmp_cs= cs[0];
  2512. if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
  2513. (tmp_cs->state & MY_CS_AVAILABLE) &&
  2514. !(wild && wild[0] &&
  2515. wild_case_compare(scs, tmp_cs->csname,wild)))
  2516. {
  2517. const char *comment;
  2518. restore_record(table, s->default_values);
  2519. table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
  2520. table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
  2521. comment= tmp_cs->comment ? tmp_cs->comment : "";
  2522. table->field[2]->store(comment, strlen(comment), scs);
  2523. table->field[3]->store((longlong) tmp_cs->mbmaxlen, TRUE);
  2524. if (schema_table_store_record(thd, table))
  2525. return 1;
  2526. }
  2527. }
  2528. return 0;
  2529. }
  2530. int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
  2531. {
  2532. CHARSET_INFO **cs;
  2533. const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
  2534. TABLE *table= tables->table;
  2535. CHARSET_INFO *scs= system_charset_info;
  2536. for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
  2537. {
  2538. CHARSET_INFO **cl;
  2539. CHARSET_INFO *tmp_cs= cs[0];
  2540. if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
  2541. !(tmp_cs->state & MY_CS_PRIMARY))
  2542. continue;
  2543. for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
  2544. {
  2545. CHARSET_INFO *tmp_cl= cl[0];
  2546. if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
  2547. !my_charset_same(tmp_cs, tmp_cl))
  2548. continue;
  2549. if (!(wild && wild[0] &&
  2550. wild_case_compare(scs, tmp_cl->name,wild)))
  2551. {
  2552. const char *tmp_buff;
  2553. restore_record(table, s->default_values);
  2554. table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
  2555. table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
  2556. table->field[2]->store((longlong) tmp_cl->number, TRUE);
  2557. tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
  2558. table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
  2559. tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
  2560. table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
  2561. table->field[5]->store((longlong) tmp_cl->strxfrm_multiply, TRUE);
  2562. if (schema_table_store_record(thd, table))
  2563. return 1;
  2564. }
  2565. }
  2566. }
  2567. return 0;
  2568. }
  2569. int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
  2570. {
  2571. CHARSET_INFO **cs;
  2572. TABLE *table= tables->table;
  2573. CHARSET_INFO *scs= system_charset_info;
  2574. for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
  2575. {
  2576. CHARSET_INFO **cl;
  2577. CHARSET_INFO *tmp_cs= cs[0];
  2578. if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
  2579. !(tmp_cs->state & MY_CS_PRIMARY))
  2580. continue;
  2581. for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
  2582. {
  2583. CHARSET_INFO *tmp_cl= cl[0];
  2584. if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
  2585. !my_charset_same(tmp_cs,tmp_cl))
  2586. continue;
  2587. restore_record(table, s->default_values);
  2588. table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
  2589. table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
  2590. if (schema_table_store_record(thd, table))
  2591. return 1;
  2592. }
  2593. }
  2594. return 0;
  2595. }
  2596. bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
  2597. const char *wild, bool full_access, const char *sp_user)
  2598. {
  2599. String tmp_string;
  2600. TIME time;
  2601. LEX *lex= thd->lex;
  2602. CHARSET_INFO *cs= system_charset_info;
  2603. const char *sp_db, *sp_name, *definer;
  2604. sp_db= get_field(thd->mem_root, proc_table->field[0]);
  2605. sp_name= get_field(thd->mem_root, proc_table->field[1]);
  2606. definer= get_field(thd->mem_root, proc_table->field[11]);
  2607. if (!full_access)
  2608. full_access= !strcmp(sp_user, definer);
  2609. if (!full_access && check_some_routine_access(thd, sp_db, sp_name,
  2610. proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE))
  2611. return 0;
  2612. if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
  2613. proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE ||
  2614. lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC &&
  2615. proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION ||
  2616. lex->orig_sql_command == SQLCOM_END)
  2617. {
  2618. restore_record(table, s->default_values);
  2619. if (!wild || !wild[0] || !wild_compare(sp_name, wild, 0))
  2620. {
  2621. int enum_idx= proc_table->field[5]->val_int();
  2622. table->field[3]->store(sp_name, strlen(sp_name), cs);
  2623. get_field(thd->mem_root, proc_table->field[3], &tmp_string);
  2624. table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs);
  2625. table->field[2]->store(sp_db, strlen(sp_db), cs);
  2626. get_field(thd->mem_root, proc_table->field[2], &tmp_string);
  2627. table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs);
  2628. if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION)
  2629. {
  2630. get_field(thd->mem_root, proc_table->field[9], &tmp_string);
  2631. table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs);
  2632. table->field[5]->set_notnull();
  2633. }
  2634. if (full_access)
  2635. {
  2636. get_field(thd->mem_root, proc_table->field[10], &tmp_string);
  2637. table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs);
  2638. }
  2639. table->field[6]->store(STRING_WITH_LEN("SQL"), cs);
  2640. table->field[10]->store(STRING_WITH_LEN("SQL"), cs);
  2641. get_field(thd->mem_root, proc_table->field[6], &tmp_string);
  2642. table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs);
  2643. table->field[12]->store(sp_data_access_name[enum_idx].str,
  2644. sp_data_access_name[enum_idx].length , cs);
  2645. get_field(thd->mem_root, proc_table->field[7], &tmp_string);
  2646. table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs);
  2647. bzero((char *)&time, sizeof(time));
  2648. ((Field_timestamp *) proc_table->field[12])->get_time(&time);
  2649. table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
  2650. bzero((char *)&time, sizeof(time));
  2651. ((Field_timestamp *) proc_table->field[13])->get_time(&time);
  2652. table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
  2653. get_field(thd->mem_root, proc_table->field[14], &tmp_string);
  2654. table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs);
  2655. get_field(thd->mem_root, proc_table->field[15], &tmp_string);
  2656. table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs);
  2657. table->field[19]->store(definer, strlen(definer), cs);
  2658. return schema_table_store_record(thd, table);
  2659. }
  2660. }
  2661. return 0;
  2662. }
  2663. int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
  2664. {
  2665. TABLE *proc_table;
  2666. TABLE_LIST proc_tables;
  2667. const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
  2668. int res= 0;
  2669. TABLE *table= tables->table;
  2670. bool full_access;
  2671. char definer[USER_HOST_BUFF_SIZE];
  2672. Open_tables_state open_tables_state_backup;
  2673. DBUG_ENTER("fill_schema_proc");
  2674. strxmov(definer, thd->security_ctx->priv_user, "@",
  2675. thd->security_ctx->priv_host, NullS);
  2676. /* We use this TABLE_LIST instance only for checking of privileges. */
  2677. bzero((char*) &proc_tables,sizeof(proc_tables));
  2678. proc_tables.db= (char*) "mysql";
  2679. proc_tables.db_length= 5;
  2680. proc_tables.table_name= proc_tables.alias= (char*) "proc";
  2681. proc_tables.table_name_length= 4;
  2682. proc_tables.lock_type= TL_READ;
  2683. full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1);
  2684. if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup)))
  2685. {
  2686. DBUG_RETURN(1);
  2687. }
  2688. proc_table->file->ha_index_init(0);
  2689. if ((res= proc_table->file->index_first(proc_table->record[0])))
  2690. {
  2691. res= (res == HA_ERR_END_OF_FILE) ? 0 : 1;
  2692. goto err;
  2693. }
  2694. if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
  2695. {
  2696. res= 1;
  2697. goto err;
  2698. }
  2699. while (!proc_table->file->index_next(proc_table->record[0]))
  2700. {
  2701. if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
  2702. {
  2703. res= 1;
  2704. goto err;
  2705. }
  2706. }
  2707. err:
  2708. proc_table->file->ha_index_end();
  2709. close_proc_table(thd, &open_tables_state_backup);
  2710. DBUG_RETURN(res);
  2711. }
  2712. static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
  2713. TABLE *table, bool res,
  2714. const char *base_name,
  2715. const char *file_name)
  2716. {
  2717. CHARSET_INFO *cs= system_charset_info;
  2718. DBUG_ENTER("get_schema_stat_record");
  2719. if (res)
  2720. {
  2721. if (thd->lex->orig_sql_command != SQLCOM_SHOW_KEYS)
  2722. {
  2723. /*
  2724. I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
  2725. rather than in SHOW KEYS
  2726. */
  2727. if (!tables->view)
  2728. push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  2729. thd->net.last_errno, thd->net.last_error);
  2730. thd->clear_error();
  2731. res= 0;
  2732. }
  2733. DBUG_RETURN(res);
  2734. }
  2735. else if (!tables->view)
  2736. {
  2737. TABLE *show_table= tables->table;
  2738. KEY *key_info=show_table->key_info;
  2739. show_table->file->info(HA_STATUS_VARIABLE |
  2740. HA_STATUS_NO_LOCK |
  2741. HA_STATUS_TIME);
  2742. for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
  2743. {
  2744. KEY_PART_INFO *key_part= key_info->key_part;
  2745. const char *str;
  2746. for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
  2747. {
  2748. restore_record(table, s->default_values);
  2749. table->field[1]->store(base_name, strlen(base_name), cs);
  2750. table->field[2]->store(file_name, strlen(file_name), cs);
  2751. table->field[3]->store((longlong) ((key_info->flags &
  2752. HA_NOSAME) ? 0 : 1), TRUE);
  2753. table->field[4]->store(base_name, strlen(base_name), cs);
  2754. table->field[5]->store(key_info->name, strlen(key_info->name), cs);
  2755. table->field[6]->store((longlong) (j+1), TRUE);
  2756. str=(key_part->field ? key_part->field->field_name :
  2757. "?unknown field?");
  2758. table->field[7]->store(str, strlen(str), cs);
  2759. if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
  2760. {
  2761. table->field[8]->store(((key_part->key_part_flag &
  2762. HA_REVERSE_SORT) ?
  2763. "D" : "A"), 1, cs);
  2764. table->field[8]->set_notnull();
  2765. }
  2766. KEY *key=show_table->key_info+i;
  2767. if (key->rec_per_key[j])
  2768. {
  2769. ha_rows records=(show_table->file->records /
  2770. key->rec_per_key[j]);
  2771. table->field[9]->store((longlong) records, TRUE);
  2772. table->field[9]->set_notnull();
  2773. }
  2774. if (!(key_info->flags & HA_FULLTEXT) &&
  2775. (key_part->field &&
  2776. key_part->length !=
  2777. show_table->field[key_part->fieldnr-1]->key_length()))
  2778. {
  2779. table->field[10]->store((longlong) key_part->length /
  2780. key_part->field->charset()->mbmaxlen);
  2781. table->field[10]->set_notnull();
  2782. }
  2783. uint flags= key_part->field ? key_part->field->flags : 0;
  2784. const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
  2785. table->field[12]->store(pos, strlen(pos), cs);
  2786. pos= show_table->file->index_type(i);
  2787. table->field[13]->store(pos, strlen(pos), cs);
  2788. if (!show_table->s->keys_in_use.is_set(i))
  2789. table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
  2790. else
  2791. table->field[14]->store("", 0, cs);
  2792. table->field[14]->set_notnull();
  2793. if (schema_table_store_record(thd, table))
  2794. DBUG_RETURN(1);
  2795. }
  2796. }
  2797. }
  2798. DBUG_RETURN(res);
  2799. }
  2800. static int get_schema_views_record(THD *thd, struct st_table_list *tables,
  2801. TABLE *table, bool res,
  2802. const char *base_name,
  2803. const char *file_name)
  2804. {
  2805. CHARSET_INFO *cs= system_charset_info;
  2806. DBUG_ENTER("get_schema_views_record");
  2807. char definer[USER_HOST_BUFF_SIZE];
  2808. uint definer_len;
  2809. if (tables->view)
  2810. {
  2811. restore_record(table, s->default_values);
  2812. table->field[1]->store(tables->view_db.str, tables->view_db.length, cs);
  2813. table->field[2]->store(tables->view_name.str, tables->view_name.length,
  2814. cs);
  2815. table->field[3]->store(tables->query.str, tables->query.length, cs);
  2816. if (tables->with_check != VIEW_CHECK_NONE)
  2817. {
  2818. if (tables->with_check == VIEW_CHECK_LOCAL)
  2819. table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs);
  2820. else
  2821. table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs);
  2822. }
  2823. else
  2824. table->field[4]->store(STRING_WITH_LEN("NONE"), cs);
  2825. if (tables->updatable_view)
  2826. table->field[5]->store(STRING_WITH_LEN("YES"), cs);
  2827. else
  2828. table->field[5]->store(STRING_WITH_LEN("NO"), cs);
  2829. definer_len= (strxmov(definer, tables->definer.user.str, "@",
  2830. tables->definer.host.str, NullS) - definer);
  2831. table->field[6]->store(definer, definer_len, cs);
  2832. if (tables->view_suid)
  2833. table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
  2834. else
  2835. table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs);
  2836. if (schema_table_store_record(thd, table))
  2837. DBUG_RETURN(1);
  2838. if (res)
  2839. push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  2840. thd->net.last_errno, thd->net.last_error);
  2841. }
  2842. if (res)
  2843. thd->clear_error();
  2844. DBUG_RETURN(0);
  2845. }
  2846. bool store_constraints(THD *thd, TABLE *table, const char *db,
  2847. const char *tname, const char *key_name,
  2848. uint key_len, const char *con_type, uint con_len)
  2849. {
  2850. CHARSET_INFO *cs= system_charset_info;
  2851. restore_record(table, s->default_values);
  2852. table->field[1]->store(db, strlen(db), cs);
  2853. table->field[2]->store(key_name, key_len, cs);
  2854. table->field[3]->store(db, strlen(db), cs);
  2855. table->field[4]->store(tname, strlen(tname), cs);
  2856. table->field[5]->store(con_type, con_len, cs);
  2857. return schema_table_store_record(thd, table);
  2858. }
  2859. static int get_schema_constraints_record(THD *thd, struct st_table_list *tables,
  2860. TABLE *table, bool res,
  2861. const char *base_name,
  2862. const char *file_name)
  2863. {
  2864. DBUG_ENTER("get_schema_constraints_record");
  2865. if (res)
  2866. {
  2867. if (!tables->view)
  2868. push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  2869. thd->net.last_errno, thd->net.last_error);
  2870. thd->clear_error();
  2871. DBUG_RETURN(0);
  2872. }
  2873. else if (!tables->view)
  2874. {
  2875. List<FOREIGN_KEY_INFO> f_key_list;
  2876. TABLE *show_table= tables->table;
  2877. KEY *key_info=show_table->key_info;
  2878. uint primary_key= show_table->s->primary_key;
  2879. show_table->file->info(HA_STATUS_VARIABLE |
  2880. HA_STATUS_NO_LOCK |
  2881. HA_STATUS_TIME);
  2882. for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
  2883. {
  2884. if (i != primary_key && !(key_info->flags & HA_NOSAME))
  2885. continue;
  2886. if (i == primary_key && !strcmp(key_info->name, primary_key_name))
  2887. {
  2888. if (store_constraints(thd, table, base_name, file_name, key_info->name,
  2889. strlen(key_info->name),
  2890. STRING_WITH_LEN("PRIMARY KEY")))
  2891. DBUG_RETURN(1);
  2892. }
  2893. else if (key_info->flags & HA_NOSAME)
  2894. {
  2895. if (store_constraints(thd, table, base_name, file_name, key_info->name,
  2896. strlen(key_info->name),
  2897. STRING_WITH_LEN("UNIQUE")))
  2898. DBUG_RETURN(1);
  2899. }
  2900. }
  2901. show_table->file->get_foreign_key_list(thd, &f_key_list);
  2902. FOREIGN_KEY_INFO *f_key_info;
  2903. List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
  2904. while ((f_key_info=it++))
  2905. {
  2906. if (store_constraints(thd, table, base_name, file_name,
  2907. f_key_info->forein_id->str,
  2908. strlen(f_key_info->forein_id->str),
  2909. "FOREIGN KEY", 11))
  2910. DBUG_RETURN(1);
  2911. }
  2912. }
  2913. DBUG_RETURN(res);
  2914. }
  2915. static bool store_trigger(THD *thd, TABLE *table, const char *db,
  2916. const char *tname, LEX_STRING *trigger_name,
  2917. enum trg_event_type event,
  2918. enum trg_action_time_type timing,
  2919. LEX_STRING *trigger_stmt,
  2920. ulong sql_mode,
  2921. LEX_STRING *definer_buffer)
  2922. {
  2923. CHARSET_INFO *cs= system_charset_info;
  2924. byte *sql_mode_str;
  2925. ulong sql_mode_len;
  2926. restore_record(table, s->default_values);
  2927. table->field[1]->store(db, strlen(db), cs);
  2928. table->field[2]->store(trigger_name->str, trigger_name->length, cs);
  2929. table->field[3]->store(trg_event_type_names[event].str,
  2930. trg_event_type_names[event].length, cs);
  2931. table->field[5]->store(db, strlen(db), cs);
  2932. table->field[6]->store(tname, strlen(tname), cs);
  2933. table->field[9]->store(trigger_stmt->str, trigger_stmt->length, cs);
  2934. table->field[10]->store(STRING_WITH_LEN("ROW"), cs);
  2935. table->field[11]->store(trg_action_time_type_names[timing].str,
  2936. trg_action_time_type_names[timing].length, cs);
  2937. table->field[14]->store(STRING_WITH_LEN("OLD"), cs);
  2938. table->field[15]->store(STRING_WITH_LEN("NEW"), cs);
  2939. sql_mode_str=
  2940. sys_var_thd_sql_mode::symbolic_mode_representation(thd,
  2941. sql_mode,
  2942. &sql_mode_len);
  2943. table->field[17]->store((const char*)sql_mode_str, sql_mode_len, cs);
  2944. table->field[18]->store((const char *)definer_buffer->str, definer_buffer->length, cs);
  2945. return schema_table_store_record(thd, table);
  2946. }
  2947. static int get_schema_triggers_record(THD *thd, struct st_table_list *tables,
  2948. TABLE *table, bool res,
  2949. const char *base_name,
  2950. const char *file_name)
  2951. {
  2952. DBUG_ENTER("get_schema_triggers_record");
  2953. /*
  2954. res can be non zero value when processed table is a view or
  2955. error happened during opening of processed table.
  2956. */
  2957. if (res)
  2958. {
  2959. if (!tables->view)
  2960. push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  2961. thd->net.last_errno, thd->net.last_error);
  2962. thd->clear_error();
  2963. DBUG_RETURN(0);
  2964. }
  2965. if (!tables->view && tables->table->triggers)
  2966. {
  2967. Table_triggers_list *triggers= tables->table->triggers;
  2968. int event, timing;
  2969. for (event= 0; event < (int)TRG_EVENT_MAX; event++)
  2970. {
  2971. for (timing= 0; timing < (int)TRG_ACTION_MAX; timing++)
  2972. {
  2973. LEX_STRING trigger_name;
  2974. LEX_STRING trigger_stmt;
  2975. ulong sql_mode;
  2976. char definer_holder[USER_HOST_BUFF_SIZE];
  2977. LEX_STRING definer_buffer;
  2978. definer_buffer.str= definer_holder;
  2979. if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
  2980. (enum trg_action_time_type)timing,
  2981. &trigger_name, &trigger_stmt,
  2982. &sql_mode,
  2983. &definer_buffer))
  2984. continue;
  2985. if (store_trigger(thd, table, base_name, file_name, &trigger_name,
  2986. (enum trg_event_type) event,
  2987. (enum trg_action_time_type) timing, &trigger_stmt,
  2988. sql_mode,
  2989. &definer_buffer))
  2990. DBUG_RETURN(1);
  2991. }
  2992. }
  2993. }
  2994. DBUG_RETURN(0);
  2995. }
  2996. void store_key_column_usage(TABLE *table, const char*db, const char *tname,
  2997. const char *key_name, uint key_len,
  2998. const char *con_type, uint con_len, longlong idx)
  2999. {
  3000. CHARSET_INFO *cs= system_charset_info;
  3001. table->field[1]->store(db, strlen(db), cs);
  3002. table->field[2]->store(key_name, key_len, cs);
  3003. table->field[4]->store(db, strlen(db), cs);
  3004. table->field[5]->store(tname, strlen(tname), cs);
  3005. table->field[6]->store(con_type, con_len, cs);
  3006. table->field[7]->store((longlong) idx, TRUE);
  3007. }
  3008. static int get_schema_key_column_usage_record(THD *thd,
  3009. struct st_table_list *tables,
  3010. TABLE *table, bool res,
  3011. const char *base_name,
  3012. const char *file_name)
  3013. {
  3014. DBUG_ENTER("get_schema_key_column_usage_record");
  3015. if (res)
  3016. {
  3017. if (!tables->view)
  3018. push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  3019. thd->net.last_errno, thd->net.last_error);
  3020. thd->clear_error();
  3021. DBUG_RETURN(0);
  3022. }
  3023. else if (!tables->view)
  3024. {
  3025. List<FOREIGN_KEY_INFO> f_key_list;
  3026. TABLE *show_table= tables->table;
  3027. KEY *key_info=show_table->key_info;
  3028. uint primary_key= show_table->s->primary_key;
  3029. show_table->file->info(HA_STATUS_VARIABLE |
  3030. HA_STATUS_NO_LOCK |
  3031. HA_STATUS_TIME);
  3032. for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
  3033. {
  3034. if (i != primary_key && !(key_info->flags & HA_NOSAME))
  3035. continue;
  3036. uint f_idx= 0;
  3037. KEY_PART_INFO *key_part= key_info->key_part;
  3038. for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
  3039. {
  3040. if (key_part->field)
  3041. {
  3042. f_idx++;
  3043. restore_record(table, s->default_values);
  3044. store_key_column_usage(table, base_name, file_name,
  3045. key_info->name,
  3046. strlen(key_info->name),
  3047. key_part->field->field_name,
  3048. strlen(key_part->field->field_name),
  3049. (longlong) f_idx);
  3050. if (schema_table_store_record(thd, table))
  3051. DBUG_RETURN(1);
  3052. }
  3053. }
  3054. }
  3055. show_table->file->get_foreign_key_list(thd, &f_key_list);
  3056. FOREIGN_KEY_INFO *f_key_info;
  3057. List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
  3058. while ((f_key_info= it++))
  3059. {
  3060. LEX_STRING *f_info;
  3061. LEX_STRING *r_info;
  3062. List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
  3063. it1(f_key_info->referenced_fields);
  3064. uint f_idx= 0;
  3065. while ((f_info= it++))
  3066. {
  3067. r_info= it1++;
  3068. f_idx++;
  3069. restore_record(table, s->default_values);
  3070. store_key_column_usage(table, base_name, file_name,
  3071. f_key_info->forein_id->str,
  3072. f_key_info->forein_id->length,
  3073. f_info->str, f_info->length,
  3074. (longlong) f_idx);
  3075. table->field[8]->store((longlong) f_idx, TRUE);
  3076. table->field[8]->set_notnull();
  3077. table->field[9]->store(f_key_info->referenced_db->str,
  3078. f_key_info->referenced_db->length,
  3079. system_charset_info);
  3080. table->field[9]->set_notnull();
  3081. table->field[10]->store(f_key_info->referenced_table->str,
  3082. f_key_info->referenced_table->length,
  3083. system_charset_info);
  3084. table->field[10]->set_notnull();
  3085. table->field[11]->store(r_info->str, r_info->length,
  3086. system_charset_info);
  3087. table->field[11]->set_notnull();
  3088. if (schema_table_store_record(thd, table))
  3089. DBUG_RETURN(1);
  3090. }
  3091. }
  3092. }
  3093. DBUG_RETURN(res);
  3094. }
  3095. int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
  3096. {
  3097. DBUG_ENTER("fill_open_tables");
  3098. const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
  3099. TABLE *table= tables->table;
  3100. CHARSET_INFO *cs= system_charset_info;
  3101. OPEN_TABLE_LIST *open_list;
  3102. if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
  3103. && thd->is_fatal_error)
  3104. DBUG_RETURN(1);
  3105. for (; open_list ; open_list=open_list->next)
  3106. {
  3107. restore_record(table, s->default_values);
  3108. table->field[0]->store(open_list->db, strlen(open_list->db), cs);
  3109. table->field[1]->store(open_list->table, strlen(open_list->table), cs);
  3110. table->field[2]->store((longlong) open_list->in_use, TRUE);
  3111. table->field[3]->store((longlong) open_list->locked, TRUE);
  3112. if (schema_table_store_record(thd, table))
  3113. DBUG_RETURN(1);
  3114. }
  3115. DBUG_RETURN(0);
  3116. }
  3117. int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
  3118. {
  3119. DBUG_ENTER("fill_variables");
  3120. int res= 0;
  3121. LEX *lex= thd->lex;
  3122. const char *wild= lex->wild ? lex->wild->ptr() : NullS;
  3123. pthread_mutex_lock(&LOCK_global_system_variables);
  3124. res= show_status_array(thd, wild, init_vars,
  3125. lex->option_type, 0, "", tables->table);
  3126. pthread_mutex_unlock(&LOCK_global_system_variables);
  3127. DBUG_RETURN(res);
  3128. }
  3129. int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
  3130. {
  3131. DBUG_ENTER("fill_status");
  3132. LEX *lex= thd->lex;
  3133. const char *wild= lex->wild ? lex->wild->ptr() : NullS;
  3134. int res= 0;
  3135. STATUS_VAR tmp;
  3136. ha_update_statistics(); /* Export engines statistics */
  3137. pthread_mutex_lock(&LOCK_status);
  3138. if (lex->option_type == OPT_GLOBAL)
  3139. calc_sum_of_all_status(&tmp);
  3140. res= show_status_array(thd, wild, status_vars, OPT_GLOBAL,
  3141. (lex->option_type == OPT_GLOBAL ?
  3142. &tmp: &thd->status_var), "",tables->table);
  3143. pthread_mutex_unlock(&LOCK_status);
  3144. DBUG_RETURN(res);
  3145. }
  3146. /*
  3147. Find schema_tables elment by name
  3148. SYNOPSIS
  3149. find_schema_table()
  3150. thd thread handler
  3151. table_name table name
  3152. RETURN
  3153. 0 table not found
  3154. # pointer to 'shema_tables' element
  3155. */
  3156. ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
  3157. {
  3158. ST_SCHEMA_TABLE *schema_table= schema_tables;
  3159. for (; schema_table->table_name; schema_table++)
  3160. {
  3161. if (!my_strcasecmp(system_charset_info,
  3162. schema_table->table_name,
  3163. table_name))
  3164. return schema_table;
  3165. }
  3166. return 0;
  3167. }
  3168. ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
  3169. {
  3170. return &schema_tables[schema_table_idx];
  3171. }
  3172. /*
  3173. Create information_schema table using schema_table data
  3174. SYNOPSIS
  3175. create_schema_table()
  3176. thd thread handler
  3177. schema_table pointer to 'shema_tables' element
  3178. RETURN
  3179. # Pointer to created table
  3180. 0 Can't create table
  3181. */
  3182. TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
  3183. {
  3184. int field_count= 0;
  3185. Item *item;
  3186. TABLE *table;
  3187. List<Item> field_list;
  3188. ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
  3189. ST_FIELD_INFO *fields_info= schema_table->fields_info;
  3190. CHARSET_INFO *cs= system_charset_info;
  3191. DBUG_ENTER("create_schema_table");
  3192. for (; fields_info->field_name; fields_info++)
  3193. {
  3194. switch (fields_info->field_type) {
  3195. case MYSQL_TYPE_LONG:
  3196. if (!(item= new Item_int(fields_info->field_name,
  3197. fields_info->value,
  3198. fields_info->field_length)))
  3199. {
  3200. DBUG_RETURN(0);
  3201. }
  3202. break;
  3203. case MYSQL_TYPE_TIMESTAMP:
  3204. if (!(item=new Item_datetime(fields_info->field_name)))
  3205. {
  3206. DBUG_RETURN(0);
  3207. }
  3208. break;
  3209. default:
  3210. /* this should be changed when Item_empty_string is fixed(in 4.1) */
  3211. if (!(item= new Item_empty_string("", 0, cs)))
  3212. {
  3213. DBUG_RETURN(0);
  3214. }
  3215. item->max_length= fields_info->field_length * cs->mbmaxlen;
  3216. item->set_name(fields_info->field_name,
  3217. strlen(fields_info->field_name), cs);
  3218. break;
  3219. }
  3220. field_list.push_back(item);
  3221. item->maybe_null= fields_info->maybe_null;
  3222. field_count++;
  3223. }
  3224. TMP_TABLE_PARAM *tmp_table_param =
  3225. (TMP_TABLE_PARAM*) (thd->calloc(sizeof(TMP_TABLE_PARAM)));
  3226. tmp_table_param->init();
  3227. tmp_table_param->table_charset= cs;
  3228. tmp_table_param->field_count= field_count;
  3229. tmp_table_param->schema_table= 1;
  3230. SELECT_LEX *select_lex= thd->lex->current_select;
  3231. if (!(table= create_tmp_table(thd, tmp_table_param,
  3232. field_list, (ORDER*) 0, 0, 0,
  3233. (select_lex->options | thd->options |
  3234. TMP_TABLE_ALL_COLUMNS),
  3235. HA_POS_ERROR, table_list->alias)))
  3236. DBUG_RETURN(0);
  3237. table_list->schema_table_param= tmp_table_param;
  3238. DBUG_RETURN(table);
  3239. }
  3240. /*
  3241. For old SHOW compatibility. It is used when
  3242. old SHOW doesn't have generated column names
  3243. Make list of fields for SHOW
  3244. SYNOPSIS
  3245. make_old_format()
  3246. thd thread handler
  3247. schema_table pointer to 'schema_tables' element
  3248. RETURN
  3249. -1 errror
  3250. 0 success
  3251. */
  3252. int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
  3253. {
  3254. ST_FIELD_INFO *field_info= schema_table->fields_info;
  3255. Name_resolution_context *context= &thd->lex->select_lex.context;
  3256. for (; field_info->field_name; field_info++)
  3257. {
  3258. if (field_info->old_name)
  3259. {
  3260. Item_field *field= new Item_field(context,
  3261. NullS, NullS, field_info->field_name);
  3262. if (field)
  3263. {
  3264. field->set_name(field_info->old_name,
  3265. strlen(field_info->old_name),
  3266. system_charset_info);
  3267. if (add_item_to_list(thd, field))
  3268. return 1;
  3269. }
  3270. }
  3271. }
  3272. return 0;
  3273. }
  3274. int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
  3275. {
  3276. char tmp[128];
  3277. LEX *lex= thd->lex;
  3278. SELECT_LEX *sel= lex->current_select;
  3279. Name_resolution_context *context= &sel->context;
  3280. if (!sel->item_list.elements)
  3281. {
  3282. ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
  3283. String buffer(tmp,sizeof(tmp), system_charset_info);
  3284. Item_field *field= new Item_field(context,
  3285. NullS, NullS, field_info->field_name);
  3286. if (!field || add_item_to_list(thd, field))
  3287. return 1;
  3288. buffer.length(0);
  3289. buffer.append(field_info->old_name);
  3290. if (lex->wild && lex->wild->ptr())
  3291. {
  3292. buffer.append(STRING_WITH_LEN(" ("));
  3293. buffer.append(lex->wild->ptr());
  3294. buffer.append(')');
  3295. }
  3296. field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
  3297. }
  3298. return 0;
  3299. }
  3300. int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
  3301. {
  3302. char tmp[128];
  3303. String buffer(tmp,sizeof(tmp), thd->charset());
  3304. LEX *lex= thd->lex;
  3305. Name_resolution_context *context= &lex->select_lex.context;
  3306. ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
  3307. buffer.length(0);
  3308. buffer.append(field_info->old_name);
  3309. buffer.append(lex->select_lex.db);
  3310. if (lex->wild && lex->wild->ptr())
  3311. {
  3312. buffer.append(STRING_WITH_LEN(" ("));
  3313. buffer.append(lex->wild->ptr());
  3314. buffer.append(')');
  3315. }
  3316. Item_field *field= new Item_field(context,
  3317. NullS, NullS, field_info->field_name);
  3318. if (add_item_to_list(thd, field))
  3319. return 1;
  3320. field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
  3321. if (thd->lex->verbose)
  3322. {
  3323. field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
  3324. field_info= &schema_table->fields_info[3];
  3325. field= new Item_field(context, NullS, NullS, field_info->field_name);
  3326. if (add_item_to_list(thd, field))
  3327. return 1;
  3328. field->set_name(field_info->old_name, strlen(field_info->old_name),
  3329. system_charset_info);
  3330. }
  3331. return 0;
  3332. }
  3333. int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
  3334. {
  3335. int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
  3336. int *field_num= fields_arr;
  3337. ST_FIELD_INFO *field_info;
  3338. Name_resolution_context *context= &thd->lex->select_lex.context;
  3339. for (; *field_num >= 0; field_num++)
  3340. {
  3341. field_info= &schema_table->fields_info[*field_num];
  3342. if (!thd->lex->verbose && (*field_num == 13 ||
  3343. *field_num == 17 ||
  3344. *field_num == 18))
  3345. continue;
  3346. Item_field *field= new Item_field(context,
  3347. NullS, NullS, field_info->field_name);
  3348. if (field)
  3349. {
  3350. field->set_name(field_info->old_name,
  3351. strlen(field_info->old_name),
  3352. system_charset_info);
  3353. if (add_item_to_list(thd, field))
  3354. return 1;
  3355. }
  3356. }
  3357. return 0;
  3358. }
  3359. int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
  3360. {
  3361. int fields_arr[]= {0, 2, 1, 3, -1};
  3362. int *field_num= fields_arr;
  3363. ST_FIELD_INFO *field_info;
  3364. Name_resolution_context *context= &thd->lex->select_lex.context;
  3365. for (; *field_num >= 0; field_num++)
  3366. {
  3367. field_info= &schema_table->fields_info[*field_num];
  3368. Item_field *field= new Item_field(context,
  3369. NullS, NullS, field_info->field_name);
  3370. if (field)
  3371. {
  3372. field->set_name(field_info->old_name,
  3373. strlen(field_info->old_name),
  3374. system_charset_info);
  3375. if (add_item_to_list(thd, field))
  3376. return 1;
  3377. }
  3378. }
  3379. return 0;
  3380. }
  3381. int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
  3382. {
  3383. int fields_arr[]= {2, 3, 4, 19, 16, 15, 14, 18, -1};
  3384. int *field_num= fields_arr;
  3385. ST_FIELD_INFO *field_info;
  3386. Name_resolution_context *context= &thd->lex->select_lex.context;
  3387. for (; *field_num >= 0; field_num++)
  3388. {
  3389. field_info= &schema_table->fields_info[*field_num];
  3390. Item_field *field= new Item_field(context,
  3391. NullS, NullS, field_info->field_name);
  3392. if (field)
  3393. {
  3394. field->set_name(field_info->old_name,
  3395. strlen(field_info->old_name),
  3396. system_charset_info);
  3397. if (add_item_to_list(thd, field))
  3398. return 1;
  3399. }
  3400. }
  3401. return 0;
  3402. }
  3403. /*
  3404. Create information_schema table
  3405. SYNOPSIS
  3406. mysql_schema_table()
  3407. thd thread handler
  3408. lex pointer to LEX
  3409. table_list pointer to table_list
  3410. RETURN
  3411. 0 success
  3412. 1 error
  3413. */
  3414. int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
  3415. {
  3416. TABLE *table;
  3417. DBUG_ENTER("mysql_schema_table");
  3418. if (!(table= table_list->schema_table->create_table(thd, table_list)))
  3419. {
  3420. DBUG_RETURN(1);
  3421. }
  3422. table->s->tmp_table= SYSTEM_TMP_TABLE;
  3423. table->grant.privilege= SELECT_ACL;
  3424. /*
  3425. This test is necessary to make
  3426. case insensitive file systems +
  3427. upper case table names(information schema tables) +
  3428. views
  3429. working correctly
  3430. */
  3431. if (table_list->schema_table_name)
  3432. table->alias_name_used= my_strcasecmp(table_alias_charset,
  3433. table_list->schema_table_name,
  3434. table_list->alias);
  3435. table_list->table_name= (char*) table->s->table_name;
  3436. table_list->table_name_length= strlen(table->s->table_name);
  3437. table_list->table= table;
  3438. table->next= thd->derived_tables;
  3439. thd->derived_tables= table;
  3440. table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
  3441. lex->safe_to_cache_query= 0;
  3442. if (table_list->schema_table_reformed) // show command
  3443. {
  3444. SELECT_LEX *sel= lex->current_select;
  3445. Item *item;
  3446. Field_translator *transl, *org_transl;
  3447. if (table_list->field_translation)
  3448. {
  3449. Field_translator *end= table_list->field_translation_end;
  3450. for (transl= table_list->field_translation; transl < end; transl++)
  3451. {
  3452. if (!transl->item->fixed &&
  3453. transl->item->fix_fields(thd, &transl->item))
  3454. DBUG_RETURN(1);
  3455. }
  3456. DBUG_RETURN(0);
  3457. }
  3458. List_iterator_fast<Item> it(sel->item_list);
  3459. if (!(transl=
  3460. (Field_translator*)(thd->stmt_arena->
  3461. alloc(sel->item_list.elements *
  3462. sizeof(Field_translator)))))
  3463. {
  3464. DBUG_RETURN(1);
  3465. }
  3466. for (org_transl= transl; (item= it++); transl++)
  3467. {
  3468. transl->item= item;
  3469. transl->name= item->name;
  3470. if (!item->fixed && item->fix_fields(thd, &transl->item))
  3471. {
  3472. DBUG_RETURN(1);
  3473. }
  3474. }
  3475. table_list->field_translation= org_transl;
  3476. table_list->field_translation_end= transl;
  3477. }
  3478. DBUG_RETURN(0);
  3479. }
  3480. /*
  3481. Generate select from information_schema table
  3482. SYNOPSIS
  3483. make_schema_select()
  3484. thd thread handler
  3485. sel pointer to SELECT_LEX
  3486. schema_table_idx index of 'schema_tables' element
  3487. RETURN
  3488. 0 success
  3489. 1 error
  3490. */
  3491. int make_schema_select(THD *thd, SELECT_LEX *sel,
  3492. enum enum_schema_tables schema_table_idx)
  3493. {
  3494. ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
  3495. LEX_STRING db, table;
  3496. DBUG_ENTER("mysql_schema_select");
  3497. /*
  3498. We have to make non const db_name & table_name
  3499. because of lower_case_table_names
  3500. */
  3501. make_lex_string(thd, &db, information_schema_name.str,
  3502. information_schema_name.length, 0);
  3503. make_lex_string(thd, &table, schema_table->table_name,
  3504. strlen(schema_table->table_name), 0);
  3505. if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
  3506. !sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
  3507. 0, 0, TL_READ, (List<String> *) 0,
  3508. (List<String> *) 0))
  3509. {
  3510. DBUG_RETURN(1);
  3511. }
  3512. DBUG_RETURN(0);
  3513. }
  3514. /*
  3515. Fill temporary schema tables before SELECT
  3516. SYNOPSIS
  3517. get_schema_tables_result()
  3518. join join which use schema tables
  3519. RETURN
  3520. FALSE success
  3521. TRUE error
  3522. */
  3523. bool get_schema_tables_result(JOIN *join)
  3524. {
  3525. JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
  3526. THD *thd= join->thd;
  3527. LEX *lex= thd->lex;
  3528. bool result= 0;
  3529. DBUG_ENTER("get_schema_tables_result");
  3530. thd->no_warnings_for_error= 1;
  3531. for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
  3532. {
  3533. if (!tab->table || !tab->table->pos_in_table_list)
  3534. break;
  3535. TABLE_LIST *table_list= tab->table->pos_in_table_list;
  3536. if (table_list->schema_table && thd->fill_derived_tables())
  3537. {
  3538. bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
  3539. lex->current_select->master_unit()->item);
  3540. /*
  3541. The schema table is already processed and
  3542. the statement is not a subselect.
  3543. So we don't need to handle this table again.
  3544. */
  3545. if (table_list->is_schema_table_processed && !is_subselect)
  3546. continue;
  3547. if (is_subselect) // is subselect
  3548. {
  3549. table_list->table->file->extra(HA_EXTRA_RESET_STATE);
  3550. table_list->table->file->delete_all_rows();
  3551. free_io_cache(table_list->table);
  3552. filesort_free_buffers(table_list->table);
  3553. }
  3554. else
  3555. table_list->table->file->records= 0;
  3556. if (table_list->schema_table->fill_table(thd, table_list,
  3557. tab->select_cond))
  3558. result= 1;
  3559. table_list->is_schema_table_processed= TRUE;
  3560. }
  3561. }
  3562. thd->no_warnings_for_error= 0;
  3563. DBUG_RETURN(result);
  3564. }
  3565. ST_FIELD_INFO schema_fields_info[]=
  3566. {
  3567. {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3568. {"SCHEMA_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"},
  3569. {"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
  3570. {"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
  3571. {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3572. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3573. };
  3574. ST_FIELD_INFO tables_fields_info[]=
  3575. {
  3576. {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3577. {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3578. {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
  3579. {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3580. {"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine"},
  3581. {"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, "Version"},
  3582. {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"},
  3583. {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, "Rows"},
  3584. {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Avg_row_length"},
  3585. {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_length"},
  3586. {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Max_data_length"},
  3587. {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Index_length"},
  3588. {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_free"},
  3589. {"AUTO_INCREMENT", 21 , MYSQL_TYPE_LONG, 0, 1, "Auto_increment"},
  3590. {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Create_time"},
  3591. {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Update_time"},
  3592. {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Check_time"},
  3593. {"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation"},
  3594. {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, "Checksum"},
  3595. {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options"},
  3596. {"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment"},
  3597. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3598. };
  3599. ST_FIELD_INFO columns_fields_info[]=
  3600. {
  3601. {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3602. {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3603. {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3604. {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Field"},
  3605. {"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
  3606. {"COLUMN_DEFAULT", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Default"},
  3607. {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"},
  3608. {"DATA_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3609. {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
  3610. {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
  3611. {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
  3612. {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
  3613. {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0},
  3614. {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, "Collation"},
  3615. {"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type"},
  3616. {"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key"},
  3617. {"EXTRA", 20, MYSQL_TYPE_STRING, 0, 0, "Extra"},
  3618. {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges"},
  3619. {"COLUMN_COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment"},
  3620. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3621. };
  3622. ST_FIELD_INFO charsets_fields_info[]=
  3623. {
  3624. {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset"},
  3625. {"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation"},
  3626. {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description"},
  3627. {"MAXLEN", 3 ,MYSQL_TYPE_LONG, 0, 0, "Maxlen"},
  3628. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3629. };
  3630. ST_FIELD_INFO collation_fields_info[]=
  3631. {
  3632. {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation"},
  3633. {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset"},
  3634. {"ID", 11, MYSQL_TYPE_LONG, 0, 0, "Id"},
  3635. {"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default"},
  3636. {"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled"},
  3637. {"SORTLEN", 3 ,MYSQL_TYPE_LONG, 0, 0, "Sortlen"},
  3638. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3639. };
  3640. ST_FIELD_INFO coll_charset_app_fields_info[]=
  3641. {
  3642. {"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
  3643. {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
  3644. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3645. };
  3646. ST_FIELD_INFO proc_fields_info[]=
  3647. {
  3648. {"SPECIFIC_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3649. {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3650. {"ROUTINE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Db"},
  3651. {"ROUTINE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
  3652. {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type"},
  3653. {"DTD_IDENTIFIER", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3654. {"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0},
  3655. {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
  3656. {"EXTERNAL_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3657. {"EXTERNAL_LANGUAGE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3658. {"PARAMETER_STYLE", 8, MYSQL_TYPE_STRING, 0, 0, 0},
  3659. {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0},
  3660. {"SQL_DATA_ACCESS", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3661. {"SQL_PATH", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3662. {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type"},
  3663. {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Created"},
  3664. {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, "Modified"},
  3665. {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
  3666. {"ROUTINE_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment"},
  3667. {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"},
  3668. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3669. };
  3670. ST_FIELD_INFO stat_fields_info[]=
  3671. {
  3672. {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3673. {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3674. {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
  3675. {"NON_UNIQUE", 1, MYSQL_TYPE_LONG, 0, 0, "Non_unique"},
  3676. {"INDEX_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3677. {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name"},
  3678. {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONG, 0, 0, "Seq_in_index"},
  3679. {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name"},
  3680. {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation"},
  3681. {"CARDINALITY", 21, MYSQL_TYPE_LONG, 0, 1, "Cardinality"},
  3682. {"SUB_PART", 3, MYSQL_TYPE_LONG, 0, 1, "Sub_part"},
  3683. {"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed"},
  3684. {"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"},
  3685. {"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type"},
  3686. {"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment"},
  3687. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3688. };
  3689. ST_FIELD_INFO view_fields_info[]=
  3690. {
  3691. {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3692. {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3693. {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3694. {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
  3695. {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0},
  3696. {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
  3697. {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0},
  3698. {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0},
  3699. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3700. };
  3701. ST_FIELD_INFO user_privileges_fields_info[]=
  3702. {
  3703. {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
  3704. {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3705. {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3706. {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
  3707. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3708. };
  3709. ST_FIELD_INFO schema_privileges_fields_info[]=
  3710. {
  3711. {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
  3712. {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3713. {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3714. {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3715. {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
  3716. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3717. };
  3718. ST_FIELD_INFO table_privileges_fields_info[]=
  3719. {
  3720. {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
  3721. {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3722. {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3723. {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3724. {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3725. {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
  3726. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3727. };
  3728. ST_FIELD_INFO column_privileges_fields_info[]=
  3729. {
  3730. {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0},
  3731. {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3732. {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3733. {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3734. {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3735. {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3736. {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
  3737. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3738. };
  3739. ST_FIELD_INFO table_constraints_fields_info[]=
  3740. {
  3741. {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3742. {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3743. {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3744. {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3745. {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3746. {"CONSTRAINT_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3747. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3748. };
  3749. ST_FIELD_INFO key_column_usage_fields_info[]=
  3750. {
  3751. {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3752. {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3753. {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3754. {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3755. {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3756. {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3757. {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3758. {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONG, 0, 0, 0},
  3759. {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONG, 0, 1, 0},
  3760. {"REFERENCED_TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3761. {"REFERENCED_TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3762. {"REFERENCED_COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3763. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3764. };
  3765. ST_FIELD_INFO table_names_fields_info[]=
  3766. {
  3767. {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3768. {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3769. {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_"},
  3770. {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type"},
  3771. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3772. };
  3773. ST_FIELD_INFO open_tables_fields_info[]=
  3774. {
  3775. {"Database", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"},
  3776. {"Table",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
  3777. {"In_use", 1, MYSQL_TYPE_LONG, 0, 0, "In_use"},
  3778. {"Name_locked", 4, MYSQL_TYPE_LONG, 0, 0, "Name_locked"},
  3779. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3780. };
  3781. ST_FIELD_INFO triggers_fields_info[]=
  3782. {
  3783. {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3784. {"TRIGGER_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3785. {"TRIGGER_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger"},
  3786. {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event"},
  3787. {"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3788. {"EVENT_OBJECT_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
  3789. {"EVENT_OBJECT_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table"},
  3790. {"ACTION_ORDER", 4, MYSQL_TYPE_LONG, 0, 0, 0},
  3791. {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
  3792. {"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement"},
  3793. {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0},
  3794. {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing"},
  3795. {"ACTION_REFERENCE_OLD_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3796. {"ACTION_REFERENCE_NEW_TABLE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
  3797. {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
  3798. {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
  3799. {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created"},
  3800. {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"},
  3801. {"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer"},
  3802. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3803. };
  3804. ST_FIELD_INFO variables_fields_info[]=
  3805. {
  3806. {"Variable_name", 80, MYSQL_TYPE_STRING, 0, 0, "Variable_name"},
  3807. {"Value", 255, MYSQL_TYPE_STRING, 0, 0, "Value"},
  3808. {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
  3809. };
  3810. /*
  3811. Description of ST_FIELD_INFO in table.h
  3812. */
  3813. ST_SCHEMA_TABLE schema_tables[]=
  3814. {
  3815. {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
  3816. fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0},
  3817. {"COLLATIONS", collation_fields_info, create_schema_table,
  3818. fill_schema_collation, make_old_format, 0, -1, -1, 0},
  3819. {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
  3820. create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0},
  3821. {"COLUMNS", columns_fields_info, create_schema_table,
  3822. get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0},
  3823. {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
  3824. fill_schema_column_privileges, 0, 0, -1, -1, 0},
  3825. {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
  3826. get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
  3827. {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
  3828. fill_open_tables, make_old_format, 0, -1, -1, 1},
  3829. {"ROUTINES", proc_fields_info, create_schema_table,
  3830. fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
  3831. {"SCHEMATA", schema_fields_info, create_schema_table,
  3832. fill_schema_shemata, make_schemata_old_format, 0, 1, -1, 0},
  3833. {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
  3834. fill_schema_schema_privileges, 0, 0, -1, -1, 0},
  3835. {"STATISTICS", stat_fields_info, create_schema_table,
  3836. get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0},
  3837. {"STATUS", variables_fields_info, create_schema_table, fill_status,
  3838. make_old_format, 0, -1, -1, 1},
  3839. {"TABLES", tables_fields_info, create_schema_table,
  3840. get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0},
  3841. {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
  3842. get_all_tables, 0, get_schema_constraints_record, 3, 4, 0},
  3843. {"TABLE_NAMES", table_names_fields_info, create_schema_table,
  3844. get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
  3845. {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
  3846. fill_schema_table_privileges, 0, 0, -1, -1, 0},
  3847. {"TRIGGERS", triggers_fields_info, create_schema_table,
  3848. get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
  3849. {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
  3850. fill_schema_user_privileges, 0, 0, -1, -1, 0},
  3851. {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
  3852. make_old_format, 0, -1, -1, 1},
  3853. {"VIEWS", view_fields_info, create_schema_table,
  3854. get_all_tables, 0, get_schema_views_record, 1, 2, 0},
  3855. {0, 0, 0, 0, 0, 0, 0, 0, 0}
  3856. };
  3857. #ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
  3858. template class List_iterator_fast<char>;
  3859. template class List<char>;
  3860. #endif