diff options
-rw-r--r-- | include/myisam.h | 2 | ||||
-rw-r--r-- | myisam/mi_keycache.c | 47 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 58 | ||||
-rw-r--r-- | sql/ha_myisam.h | 1 | ||||
-rw-r--r-- | sql/handler.cc | 5 | ||||
-rw-r--r-- | sql/handler.h | 1 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/sql_lex.cc | 3 | ||||
-rw-r--r-- | sql/sql_lex.h | 9 | ||||
-rw-r--r-- | sql/sql_parse.cc | 13 | ||||
-rw-r--r-- | sql/sql_table.cc | 21 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 41 |
12 files changed, 190 insertions, 12 deletions
diff --git a/include/myisam.h b/include/myisam.h index e85d3057672..11a59263b07 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -410,6 +410,8 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map, int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows); void mi_flush_bulk_insert(MI_INFO *info, uint inx); void mi_end_bulk_insert(MI_INFO *info); +int mi_assign_to_keycache(MI_INFO *info, ulonglong key_map, + char *keycache_name); int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves); #ifdef __cplusplus diff --git a/myisam/mi_keycache.c b/myisam/mi_keycache.c new file mode 100644 index 00000000000..75a6819f598 --- /dev/null +++ b/myisam/mi_keycache.c @@ -0,0 +1,47 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Key cache assignments +*/ + +#include "myisamdef.h" + + +/* + Assign pages of the index file for a table to a key cache + + SYNOPSIS + mi_assign_to_keycache() + info open table + map map of indexes to assign to the key cache + keycache_name name of of the key cache to assign index to + + RETURN VALUE + 0 if a success. error code - otherwise. + + NOTES. + At present pages for all indexes must be assigned to the same key cache. + In future only pages for indexes specified in the key_map parameter + of the table will be assigned to the specified key cache. +*/ + +int mi_assign_to_keycache(MI_INFO *info, ulonglong key_map, + char *keycache_name) +{ + return 0; +} + diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 4f1021232a4..4ca11fe0da5 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -689,6 +689,64 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) /* + Assign table indexes to a key cache. +*/ + +int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt) +{ + int error; + const char *errmsg; + ulonglong map= ~(ulonglong) 0; + TABLE_LIST *table_list= table->pos_in_table_list; + char *keycache_name= table_list->option; + + DBUG_ENTER("ha_myisam::assign_to_keycache"); + + /* Check validity of the index references */ + if (table_list->use_index) + { + key_map kmap= get_key_map_from_key_list(table, table_list->use_index); + if (kmap == ~(key_map) 0) + { + errmsg= thd->net.last_error; + error= HA_ADMIN_FAILED; + goto err; + } + if (kmap) + map= kmap; + } + + if ((error= mi_assign_to_keycache(file, map, keycache_name))) + { + switch (error) { + default: + char buf[ERRMSGSIZE+20]; + my_snprintf(buf, ERRMSGSIZE, + "Failed to read from index file (errno: %d)", my_errno); + errmsg= buf; + } + error= HA_ADMIN_FAILED; + goto err; + } + + DBUG_RETURN(HA_ADMIN_OK); + + err: + { + MI_CHECK param; + myisamchk_init(¶m); + param.thd= thd; + param.op_name= (char*)"assign_to_keycache"; + param.db_name= table->table_cache_key; + param.table_name= table->table_name; + param.testflag= 0; + mi_check_print_error(¶m, errmsg); + DBUG_RETURN(error); + } +} + + +/* Preload pages of the index file for a table into the key cache. */ diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index 8486e25556b..f8ffd00a286 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -127,6 +127,7 @@ class ha_myisam: public handler int optimize(THD* thd, HA_CHECK_OPT* check_opt); int restore(THD* thd, HA_CHECK_OPT* check_opt); int backup(THD* thd, HA_CHECK_OPT* check_opt); + int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt); int preload_keys(THD* thd, HA_CHECK_OPT* check_opt); #ifdef HAVE_REPLICATION int dump(THD* thd, int fd); diff --git a/sql/handler.cc b/sql/handler.cc index fdf25c2670a..af8e14f9160 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -620,6 +620,11 @@ int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt) return HA_ADMIN_NOT_IMPLEMENTED; } +int handler::assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt) +{ + return HA_ADMIN_NOT_IMPLEMENTED; +} + int handler::preload_keys(THD* thd, HA_CHECK_OPT* check_opt) { return HA_ADMIN_NOT_IMPLEMENTED; diff --git a/sql/handler.h b/sql/handler.h index 08a7c83d328..1c6e158180e 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -305,6 +305,7 @@ public: virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt); virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt); virtual int backup(THD* thd, HA_CHECK_OPT* check_opt); + virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt); virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt); /* restore assumes .frm file must exist, and that generate_table() has been diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index aca84f1bcb3..8d038aba44d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -403,6 +403,7 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* table_list, HA_CHECK_OPT* check_opt); int mysql_optimize_table(THD* thd, TABLE_LIST* table_list, HA_CHECK_OPT* check_opt); +int mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list); int mysql_preload_keys(THD* thd, TABLE_LIST* table_list); bool check_simple_select(); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 1658d5d14c1..4cf13682f84 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1205,7 +1205,8 @@ TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table, ulong table_join_options, thr_lock_type flags, List<String> *use_index, - List<String> *ignore_index) + List<String> *ignore_index, + LEX_STRING *option) { return 0; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5cebddaf02e..f4bc0b9a8d1 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -59,7 +59,8 @@ enum enum_sql_command { SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB, SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, - SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, SQLCOM_PRELOAD_KEYS, + SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, + SQLCOM_ASSIGN_TO_KEYCACHE, SQLCOM_PRELOAD_KEYS, SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE, SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER, @@ -252,7 +253,8 @@ public: ulong table_options, thr_lock_type flags= TL_UNLOCK, List<String> *use_index= 0, - List<String> *ignore_index= 0); + List<String> *ignore_index= 0, + LEX_STRING *option= 0); virtual void set_lock_for_tables(thr_lock_type lock_type) {} void mark_as_dependent(st_select_lex *last); @@ -409,7 +411,8 @@ public: ulong table_options, thr_lock_type flags= TL_UNLOCK, List<String> *use_index= 0, - List<String> *ignore_index= 0); + List<String> *ignore_index= 0, + LEX_STRING *option= 0); void set_lock_for_tables(thr_lock_type lock_type); inline void init_order() { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5070466007e..946dc654cad 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1881,6 +1881,14 @@ mysql_execute_command(THD *thd) res = mysql_restore_table(thd, tables); break; } + case SQLCOM_ASSIGN_TO_KEYCACHE: + { + if (check_db_used(thd, tables) || + check_access(thd, INDEX_ACL, tables->db, &tables->grant.privilege)) + goto error; + res = mysql_assign_to_keycache(thd, tables); + break; + } case SQLCOM_PRELOAD_KEYS: { if (check_db_used(thd, tables) || @@ -4063,7 +4071,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ulong table_options, thr_lock_type lock_type, List<String> *use_index, - List<String> *ignore_index) + List<String> *ignore_index, + LEX_STRING *option) { register TABLE_LIST *ptr; char *alias_str; @@ -4124,7 +4133,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (ignore_index) ptr->ignore_index=(List<String> *) thd->memdup((gptr) ignore_index, sizeof(*ignore_index)); - + ptr->option= option ? option->str : 0; /* check that used name is unique */ if (lock_type != TL_IGNORE) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 33a59e540f8..a60de3e3e55 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1561,6 +1561,27 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) /* + Assigned specified indexes for a table into key cache + + SYNOPSIS + mysql_assign_to_keycache() + thd Thread object + tables Table list (one table only) + + RETURN VALUES + 0 ok + -1 error +*/ + +int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables) +{ + DBUG_ENTER("mysql_assign_to_keycache"); + DBUG_RETURN(mysql_admin_table(thd, tables, 0, + "assign_to_keycache", TL_WRITE, 0, 0, 0, + &handler::assign_to_keycache)); +} + +/* Preload specified indexes for a table into key cache SYNOPSIS diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1d605abe8a3..6766f7cde43 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -657,11 +657,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type <NONE> query verb_clause create change select do drop insert replace insert2 insert_values update delete truncate rename - show describe load alter optimize preload flush + show describe load alter optimize keycache preload flush reset purge begin commit rollback slave master_def master_defs repair restore backup analyze check start field_list field_list_item field_spec kill column_def key_def - preload_list preload_keys + keycache_list assign_to_keycache preload_list preload_keys select_item_list select_item values_list no_braces opt_limit_clause delete_limit_clause fields opt_values values procedure_list procedure_list2 procedure_item @@ -730,6 +730,7 @@ verb_clause: | lock | kill | optimize + | keycache | preload | purge | rename @@ -1843,6 +1844,34 @@ table_to_table: YYABORT; }; +keycache: + CACHE_SYM INDEX + { + LEX *lex=Lex; + lex->sql_command=SQLCOM_ASSIGN_TO_KEYCACHE; + } + keycache_list + {} + ; + +keycache_list: + assign_to_keycache + | keycache_list ',' assign_to_keycache; + +assign_to_keycache: + table_ident cache_keys_spec ident + { + LEX *lex=Lex; + SELECT_LEX *sel= &lex->select_lex; + if (!sel->add_table_to_list(lex->thd, $1, NULL, 0, + TL_WRITE, + sel->get_use_index(), + (List<String> *)0, + &($3))) + YYABORT; + } + ; + preload: LOAD INDEX INTO CACHE_SYM { @@ -1858,7 +1887,7 @@ preload_list: | preload_list ',' preload_keys; preload_keys: - table_ident preload_keys_spec opt_ignore_leaves + table_ident cache_keys_spec opt_ignore_leaves { LEX *lex=Lex; SELECT_LEX *sel= &lex->select_lex; @@ -1870,9 +1899,9 @@ preload_keys: } ; -preload_keys_spec: +cache_keys_spec: keys_or_index { Select->select_lex()->interval_list.empty(); } - preload_key_list_or_empty + cache_key_list_or_empty { LEX *lex=Lex; SELECT_LEX *sel= &lex->select_lex; @@ -1881,7 +1910,7 @@ preload_keys_spec: } ; -preload_key_list_or_empty: +cache_key_list_or_empty: /* empty */ | '(' key_usage_list2 ')' {} ; |