List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:October 23 2008 7:51pm
Subject:bzr commit into mysql-5.1 branch (mattias.jonsson:2673) Bug#39637
View as plain text  
#At file:///Users/mattiasj/clones/bzrroot/b39637-51-bugteam/

 2673 Mattias Jonsson	2008-10-23
      Bug#39637: Support key cache in partitioned myisam tables
      
      (builds on patch for bug-39434)
      
      Added the necessary handler calls to the partitioning handler
      and new syntax for managing key caches on partition level.
      (Changed the syntax and added more tests since last commit)
      
      New syntax:
      CACHE INDEX keycache_list|keycache_parts IN key_cache_name
      
      keycache_list:
      tbl_name [INDEX|KEY (index_name[, index_name] ...)][, tbl_name ...]
      
      keycache_parts:
      tbl_name PARTITION (ALL|partition[, partition] ...)
      [INDEX|KEY (index_name[, index_name] ...)]
      
      
      LOAD INDEX INTO CACHE tbl_index_list|parts_index_list
      
      tbl_index_list:
      tbl_name [INDEX|KEY (index_name[, index_name] ...)]
      [INGORE LEAVES][, tbl_name ...]
      
      parts_index_list:
      tbl_name PARTITION (ALL|partition[, partition] ...)
      [INDEX|KEY (index_name[,index_name] ...)
      [IGNORE LEAVES]
added:
  mysql-test/include/check_key_reads.inc
  mysql-test/include/check_key_req.inc
  mysql-test/r/partition_key_cache.result
  mysql-test/t/partition_key_cache-master.opt
  mysql-test/t/partition_key_cache.test
modified:
  mysql-test/lib/mtr_report.pl
  sql/ha_partition.cc
  sql/ha_partition.h
  sql/sql_partition.cc
  sql/sql_table.cc
  sql/sql_yacc.yy

per-file messages:
  mysql-test/include/check_key_reads.inc
    Bug#39637: Support key cache in partitioned myisam tables
    
    New test include file, since a stored procedure with I_S
    was too slow
  mysql-test/include/check_key_req.inc
    Bug#39637: Support key cache in partitioned myisam tables
    
    New test include file, since a stored procedure with I_S
    was too slow
  mysql-test/lib/mtr_report.pl
    Bug#39637: Support key cache in partitioned myisam tables
    
    removing a warning when setting the key_buffer_size to 0
  mysql-test/r/partition_key_cache.result
    Bug#39637: Support key cache in partitioned myisam tables
    
    New test result
  mysql-test/t/partition_key_cache-master.opt
    Bug#39637: Support key cache in partitioned myisam tables
    
    New test case opt file
  mysql-test/t/partition_key_cache.test
    Bug#39637: Support key cache in partitioned myisam tables
    
    New test case
  sql/ha_partition.cc
    Bug#39637: Support key cache in partitioned myisam tables
    
    Added support for assign_to_keycache and preload_keys
  sql/ha_partition.h
    Bug#39637: Support key cache in partitioned myisam tables
    
    Added support for assign_to_keycache and preload_keys
  sql/sql_partition.cc
    Bug#39637: Support key cache in partitioned myisam tables
    
    Just updated the comment, since it now also is used
    with key caches to partitions
  sql/sql_table.cc
    Bug#39637: Support key cache in partitioned myisam tables
    
    Just updated the comment, since it now also is used
    with key caches to partitions
  sql/sql_yacc.yy
    Bug#39637: Support key cache in partitioned myisam tables
    
    Moved the check if partitioning is enabled to be used
    in more places
    
    Added syntax for key cache on partitioning level
    
    Removed a duplicate row (lex->alter_info.reset())
=== added file 'mysql-test/include/check_key_reads.inc'
--- a/mysql-test/include/check_key_reads.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/check_key_reads.inc	2008-10-23 19:50:53 +0000
@@ -0,0 +1,6 @@
+# include file for checking if variable key_reads is zero
+let $key_reads= query_get_value(SHOW STATUS LIKE 'key_reads',Value,1);
+--disable_query_log
+eval SELECT IF($key_reads = 0, "Yes!", "No!") as 'Zero key reads?';
+FLUSH STATUS;
+--enable_query_log

=== added file 'mysql-test/include/check_key_req.inc'
--- a/mysql-test/include/check_key_req.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/check_key_req.inc	2008-10-23 19:50:53 +0000
@@ -0,0 +1,9 @@
+# include file for checking if variable key_reads = key_read_requests
+let $key_reads= query_get_value(SHOW STATUS LIKE 'key_reads',Value,1);
+let $key_r_req= query_get_value(SHOW STATUS LIKE 'key_read_requests',Value,1);
+let $key_writes= query_get_value(SHOW STATUS LIKE 'key_writes',Value,1);
+let $key_w_req= query_get_value(SHOW STATUS LIKE 'key_write_requests',Value,1);
+--disable_query_log
+eval SELECT IF($key_reads = $key_r_req, "reads == requests", "reads != requests") as 'reads vs requests';
+eval SELECT IF($key_writes = $key_w_req, "writes == requests", "writes != requests") as 'writes vs requests';
+--enable_query_log

=== modified file 'mysql-test/lib/mtr_report.pl'
--- a/mysql-test/lib/mtr_report.pl	2008-10-02 07:46:14 +0000
+++ b/mysql-test/lib/mtr_report.pl	2008-10-23 19:50:53 +0000
@@ -412,7 +412,10 @@ sub mtr_report_stats ($) {
 
                 # When trying to set lower_case_table_names = 2
                 # on a case sensitive file system. Bug#37402.
-                /lower_case_table_names was set to 2, even though your the file system '.*' is case sensitive.  Now setting lower_case_table_names to 0 to avoid future problems./
+                /lower_case_table_names was set to 2, even though your the file system '.*' is case sensitive.  Now setting lower_case_table_names to 0 to avoid future problems./ or
+
+                # When setting key_buffer_size to 0, it gets truncated
+                /option 'key_buffer_size': unsigned value [0-9]* adjusted to [0-9]*/
 		)
             {
               next;                       # Skip these lines

=== added file 'mysql-test/r/partition_key_cache.result'
--- a/mysql-test/r/partition_key_cache.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/partition_key_cache.result	2008-10-23 19:50:53 +0000
@@ -0,0 +1,414 @@
+DROP TABLE IF EXISTS t1, t2, v, x;
+# Actual test of key caches
+# Note that the default key cache and query cache is disabled!
+# Verifing that reads/writes use the key cache correctly
+SELECT @org_key_cache_buffer_size:= @@global.default.key_buffer_size;
+@org_key_cache_buffer_size:= @@global.default.key_buffer_size
+36
+CREATE TABLE t1 (
+a INT,
+b INT,
+c INT NOT NULL,
+PRIMARY KEY (a),
+KEY `inx_b` (b))
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH (a)
+(PARTITION p0 VALUES LESS THAN (1167602410)
+(SUBPARTITION sp0,
+SUBPARTITION sp1),
+PARTITION p1 VALUES LESS THAN MAXVALUE
+(SUBPARTITION sp2,
+SUBPARTITION sp3));
+CREATE TABLE t2 (
+a INT,
+b INT,
+c INT NOT NULL,
+PRIMARY KEY (a),
+KEY `inx_b` (b));
+FLUSH TABLES;
+FLUSH STATUS;
+SET @a:=1167602400;
+CREATE VIEW v AS SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4;
+CREATE VIEW x AS SELECT 1 FROM v,v a,v b;
+FLUSH STATUS;
+INSERT t1 SELECT @a, @a * (1 - ((@a % 2) * 2)) , 1167612400 - (@a:=@a+1) FROM x, x y;
+reads vs requests
+reads == requests
+writes vs requests
+writes == requests
+# row distribution:
+SELECT PARTITION_NAME, SUBPARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA='test' and TABLE_NAME='t1';
+PARTITION_NAME	SUBPARTITION_NAME	TABLE_ROWS
+p0	sp0	5
+p0	sp1	5
+p1	sp2	2043
+p1	sp3	2043
+DROP VIEW x;
+DROP VIEW v;
+FLUSH TABLES;
+FLUSH STATUS;
+SELECT COUNT(b) FROM t1 WHERE b >= 0;
+COUNT(b)
+2048
+Zero key reads?
+No!
+INSERT t2 SELECT a,b,c FROM t1;
+reads vs requests
+reads == requests
+writes vs requests
+writes == requests
+FLUSH STATUS;
+SELECT COUNT(b) FROM t2 WHERE b >= 0;
+COUNT(b)
+2048
+Zero key reads?
+No!
+FLUSH TABLES;
+# Enabling the default key cache
+SET GLOBAL key_buffer_size = 1024*1024;
+FLUSH STATUS;
+# All these have to read the indexes
+LOAD INDEX INTO CACHE t1 PARTITION (p1);
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	status	OK
+Zero key reads?
+No!
+SELECT COUNT(b) FROM t1 WHERE b >= 0;
+COUNT(b)
+2048
+Zero key reads?
+No!
+SELECT COUNT(b) FROM t2 WHERE b >= 0;
+COUNT(b)
+2048
+Zero key reads?
+No!
+# All these should be able to use the key cache
+SELECT COUNT(b) FROM t1 WHERE b >= 0;
+COUNT(b)
+2048
+Zero key reads?
+Yes!
+SELECT COUNT(b) FROM t2 WHERE b >= 0;
+COUNT(b)
+2048
+Zero key reads?
+Yes!
+FLUSH TABLES;
+LOAD INDEX INTO CACHE t1 PARTITION (p1,p0);
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	status	OK
+Zero key reads?
+No!
+# should be zero
+SELECT COUNT(b) FROM t1 WHERE b >= 0;
+COUNT(b)
+2048
+Zero key reads?
+Yes!
+LOAD INDEX INTO CACHE t2;
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	status	OK
+Zero key reads?
+No!
+# should be zero
+SELECT COUNT(b) FROM t2 WHERE b >= 0;
+COUNT(b)
+2048
+Zero key reads?
+Yes!
+FLUSH TABLES;
+LOAD INDEX INTO CACHE t1 PARTITION (p1,p0) IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	status	OK
+Zero key reads?
+No!
+# should not be zero
+SELECT COUNT(b) FROM t1 WHERE b >= 0;
+COUNT(b)
+2048
+Zero key reads?
+No!
+LOAD INDEX INTO CACHE t2 IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	status	OK
+Zero key reads?
+No!
+# should not be zero
+SELECT COUNT(b) FROM t2 WHERE b >= 0;
+COUNT(b)
+2048
+Zero key reads?
+No!
+TRUNCATE TABLE t2;
+INSERT t2 SELECT a,b,c FROM t1;
+reads vs requests
+reads != requests
+writes vs requests
+writes != requests
+DROP TABLE t1,t2;
+SET GLOBAL hot_cache.key_buffer_size = 1024*1024;
+SET GLOBAL warm_cache.key_buffer_size = 1024*1024;
+SET @@global.cold_cache.key_buffer_size = 1024*1024;
+SELECT @@global.default.key_buffer_size a, @@global.default.key_cache_block_size b, @@global.default.key_cache_age_threshold c, @@global.default.key_cache_division_limit d;
+a	b	c	d
+1048576	1024	300	100
+SELECT @@global.hot_cache.key_buffer_size a, @@global.hot_cache.key_cache_block_size b, @@global.hot_cache.key_cache_age_threshold c, @@global.hot_cache.key_cache_division_limit d;
+a	b	c	d
+1048576	1024	300	100
+SELECT @@global.warm_cache.key_buffer_size a, @@global.warm_cache.key_cache_block_size b, @@global.warm_cache.key_cache_age_threshold c, @@global.warm_cache.key_cache_division_limit d;
+a	b	c	d
+1048576	1024	300	100
+SELECT @@global.cold_cache.key_buffer_size a, @@global.cold_cache.key_cache_block_size b, @@global.cold_cache.key_cache_age_threshold c, @@global.cold_cache.key_cache_division_limit d;
+a	b	c	d
+1048576	1024	300	100
+CREATE TABLE t1 (
+a INT,
+b VARCHAR(257),
+c INT NOT NULL,
+PRIMARY KEY (a),
+KEY `inx_b` (b),
+KEY `inx_c`(c))
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH (a)
+(PARTITION p0 VALUES LESS THAN (10)
+(SUBPARTITION sp0,
+SUBPARTITION sp1),
+PARTITION p1 VALUES LESS THAN MAXVALUE
+(SUBPARTITION sp2,
+SUBPARTITION sp3));
+CREATE TABLE t2 (
+a INT,
+b VARCHAR(257),
+c INT NOT NULL,
+PRIMARY KEY (a),
+KEY `inx_b` (b),
+KEY `inx_c`(c));
+SET @a:=1167602400;
+CREATE VIEW v AS SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4;
+CREATE VIEW x AS SELECT 1 FROM v,v a,v b;
+INSERT t1 SELECT @a, CONCAT('X_', @a, ' MySQL'), 1167612400 - (@a:=@a+1) FROM x, x a;
+DROP VIEW x;
+DROP VIEW v;
+INSERT t2 SELECT a, b, c FROM t1;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+4096
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+4096
+FLUSH TABLES;
+# Restrict partitioned commands to partitioned tables only
+CACHE INDEX t2 PARTITION (p0) KEY (`inx_b`) IN hot_cache;
+ERROR HY000: Partition management on a not partitioned table is not possible
+CACHE INDEX t2 PARTITION (p0,`p1`) INDEX (`PRIMARY`) IN hot_cache;
+ERROR HY000: Partition management on a not partitioned table is not possible
+CACHE INDEX t2 PARTITION (`p1`) INDEX (`PRIMARY`,`inx_b`) IN hot_cache;
+ERROR HY000: Partition management on a not partitioned table is not possible
+CACHE INDEX t2 PARTITION (ALL) KEY (`inx_b`,`PRIMARY`) IN hot_cache;
+ERROR HY000: Partition management on a not partitioned table is not possible
+# Basic key cache testing
+# The manual correctly says: "The syntax of CACHE INDEX enables you to
+# specify that only particular indexes from a table should be assigned
+# to the cache. The current implementation assigns all the table's
+# indexes to the cache, so there is no reason to specify anything
+# other than the table name."
+# So the most of the test only tests the syntax 
+CACHE INDEX t2 INDEX (`inx_b`) IN hot_cache;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	status	OK
+CACHE INDEX t2 KEY (`PRIMARY`) IN warm_cache;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	status	OK
+CACHE INDEX t2 KEY (`PRIMARY`,`inx_b`) IN cold_cache;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	status	OK
+CACHE INDEX t2 INDEX (inx_b,`PRIMARY`) IN default;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	status	OK
+CACHE INDEX t1 PARTITION (p0) KEY (`inx_b`) IN cold_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+CACHE INDEX t1 PARTITIONS (p0) KEY (`inx_b`) IN cold_cache;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PARTITIONS (p0) KEY (`inx_b`) IN cold_cache' at line 1
+# only one table at a time if specifying partitions
+CACHE INDEX t1,t2 PARTITION (p0) KEY (`inx_b`) IN cold_cache;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PARTITION (p0) KEY (`inx_b`) IN cold_cache' at line 1
+CACHE INDEX t1 PARTITION (`p0`,p1) INDEX (`PRIMARY`) IN warm_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+CACHE INDEX t1 PARTITION (`p1`) INDEX (`PRIMARY`,inx_b) IN hot_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+CACHE INDEX t1 PARTITION (ALL) KEY (`inx_b`,`PRIMARY`) IN default;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+CACHE INDEX t1 PARTITION (ALL) IN hot_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+CACHE INDEX t1 INDEX (`inx_b`) IN default;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+CACHE INDEX t1 KEY (`PRIMARY`) IN hot_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+CACHE INDEX t1 KEY (`PRIMARY`,`inx_b`) IN warm_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+CACHE INDEX t1 INDEX (`inx_b`,`PRIMARY`) IN cold_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+CACHE INDEX t1 IN hot_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+# Test of non existent key cache:
+CACHE INDEX t1 IN non_existent_key_cache;
+ERROR HY000: Unknown key cache 'non_existent_key_cache'
+# Basic testing of LOAD INDEX
+LOAD INDEX INTO CACHE t2;
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	status	OK
+# PRIMARY and secondary keys have different block sizes
+LOAD INDEX INTO CACHE t2 ignore leaves;
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	error	Indexes use different block sizes
+test.t2	preload_keys	status	Operation failed
+# Must have INDEX or KEY before the index list
+LOAD INDEX INTO CACHE t2 (`PRIMARY`);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(`PRIMARY`)' at line 1
+# Test of IGNORE LEAVES
+LOAD INDEX INTO CACHE t2 INDEX (`PRIMARY`);
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	status	OK
+LOAD INDEX INTO CACHE t2 KEY (`PRIMARY`,`inx_b`) IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	error	Indexes use different block sizes
+test.t2	preload_keys	status	Operation failed
+CACHE INDEX t2 IN warm_cache;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	status	OK
+CACHE INDEX t1 IN cold_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	status	OK
+LOAD INDEX INTO CACHE t2 KEY (`PRIMARY`) IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	error	Indexes use different block sizes
+test.t2	preload_keys	status	Operation failed
+CACHE INDEX t2 INDEX (`inx_b`, `inx_c`) IN hot_cache;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	status	OK
+LOAD INDEX INTO CACHE t2 KEY (`inx_b`, `inx_c`) IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	error	Indexes use different block sizes
+test.t2	preload_keys	status	Operation failed
+CACHE INDEX t2 IN warm_cache;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	status	OK
+CACHE INDEX t2 INDEX (`PRIMARY`, `inx_c`) IN hot_cache;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	status	OK
+LOAD INDEX INTO CACHE t2 KEY (`PRIMARY`,`inx_c`) IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	error	Indexes use different block sizes
+test.t2	preload_keys	status	Operation failed
+CACHE INDEX t2 INDEX (`inx_b`,`PRIMARY`) IN default;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	status	OK
+LOAD INDEX INTO CACHE t2 KEY (`PRIMARY`,`inx_b`);
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	status	OK
+CACHE INDEX t2 IN default;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	status	OK
+LOAD INDEX INTO CACHE t2 IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t2	preload_keys	error	Indexes use different block sizes
+test.t2	preload_keys	status	Operation failed
+LOAD INDEX INTO CACHE t2 PARTITION (p1) INDEX (`PRIMARY`);
+ERROR HY000: Partition management on a not partitioned table is not possible
+LOAD INDEX INTO CACHE t1, t2;
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	status	OK
+test.t2	preload_keys	status	OK
+# only one table at a time if specifying partitions
+LOAD INDEX INTO CACHE t1 PARTITION (p0), t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' t2' at line 1
+LOAD INDEX INTO CACHE t1 IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	error	Indexes use different block sizes
+test.t1	preload_keys	error	Subpartition sp2 returned error
+test.t1	preload_keys	status	Operation failed
+LOAD INDEX INTO CACHE t1 INDEX (`PRIMARY`);
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	status	OK
+LOAD INDEX INTO CACHE t1 INDEX (`PRIMARY`,`inx_b`) IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	error	Indexes use different block sizes
+test.t1	preload_keys	error	Subpartition sp2 returned error
+test.t1	preload_keys	status	Operation failed
+LOAD INDEX INTO CACHE t1 INDEX (`inx_b`) IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	error	Indexes use different block sizes
+test.t1	preload_keys	error	Subpartition sp2 returned error
+test.t1	preload_keys	status	Operation failed
+LOAD INDEX INTO CACHE t1 INDEX (`PRIMARY`) IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	error	Indexes use different block sizes
+test.t1	preload_keys	error	Subpartition sp2 returned error
+test.t1	preload_keys	status	Operation failed
+LOAD INDEX INTO CACHE t1 INDEX (`PRIMARY`,`inx_b`);
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	status	OK
+LOAD INDEX INTO CACHE t1 PARTITION (p1) INDEX (`PRIMARY`);
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	status	OK
+LOAD INDEX INTO CACHE t1 PARTITION (`p1`,p0) KEY (`PRIMARY`) IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	error	Indexes use different block sizes
+test.t1	preload_keys	error	Subpartition sp2 returned error
+test.t1	preload_keys	status	Operation failed
+LOAD INDEX INTO CACHE t1 PARTITION (ALL);
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	status	OK
+LOAD INDEX INTO CACHE t1 PARTITIONS ALL;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PARTITIONS ALL' at line 1
+LOAD INDEX INTO CACHE t1 PARTITION (p1,`p0`) IGNORE LEAVES;
+Table	Op	Msg_type	Msg_text
+test.t1	preload_keys	error	Indexes use different block sizes
+test.t1	preload_keys	error	Subpartition sp2 returned error
+test.t1	preload_keys	status	Operation failed
+DROP INDEX `inx_b` on t1;
+DROP INDEX `inx_b` on t2;
+CACHE INDEX t2 PARTITION (p0) KEY (`inx_b`) IN hot_cache;
+ERROR HY000: Partition management on a not partitioned table is not possible
+CACHE INDEX t2 INDEX (`inx_b`) IN hot_cache;
+Table	Op	Msg_type	Msg_text
+test.t2	assign_to_keycache	Error	Key 'inx_b' doesn't exist in table 't2'
+test.t2	assign_to_keycache	status	Operation failed
+CACHE INDEX t1 PARTITION (p0) KEY (`inx_b`) IN hot_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	error	Subpartition sp0 returned error
+test.t1	assign_to_keycache	Error	Key 'inx_b' doesn't exist in table 't1'
+test.t1	assign_to_keycache	status	Operation failed
+CACHE INDEX t1 INDEX (`inx_b`) IN hot_cache;
+Table	Op	Msg_type	Msg_text
+test.t1	assign_to_keycache	error	Subpartition sp0 returned error
+test.t1	assign_to_keycache	Error	Key 'inx_b' doesn't exist in table 't1'
+test.t1	assign_to_keycache	status	Operation failed
+DROP TABLE t1,t2;
+SET GLOBAL hot_cache.key_buffer_size = 0;
+SET GLOBAL warm_cache.key_buffer_size = 0;
+SET @@global.cold_cache.key_buffer_size = 0;
+SELECT @@global.default.key_buffer_size a, @@global.default.key_cache_block_size b, @@global.default.key_cache_age_threshold c, @@global.default.key_cache_division_limit d;
+a	b	c	d
+1048576	1024	300	100
+SELECT @@global.hot_cache.key_buffer_size a, @@global.hot_cache.key_cache_block_size b, @@global.hot_cache.key_cache_age_threshold c, @@global.hot_cache.key_cache_division_limit d;
+a	b	c	d
+0	1024	300	100
+SELECT @@global.warm_cache.key_buffer_size a, @@global.warm_cache.key_cache_block_size b, @@global.warm_cache.key_cache_age_threshold c, @@global.warm_cache.key_cache_division_limit d;
+a	b	c	d
+0	1024	300	100
+SELECT @@global.cold_cache.key_buffer_size a, @@global.cold_cache.key_cache_block_size b, @@global.cold_cache.key_cache_age_threshold c, @@global.cold_cache.key_cache_division_limit d;
+a	b	c	d
+0	1024	300	100
+SET @@global.default.key_buffer_size = @org_key_cache_buffer_size;

=== added file 'mysql-test/t/partition_key_cache-master.opt'
--- a/mysql-test/t/partition_key_cache-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/partition_key_cache-master.opt	2008-10-23 19:50:53 +0000
@@ -0,0 +1 @@
+--key_buffer_size=0 --query_cache_size=0 --query_cache_type=0

=== added file 'mysql-test/t/partition_key_cache.test'
--- a/mysql-test/t/partition_key_cache.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/partition_key_cache.test	2008-10-23 19:50:53 +0000
@@ -0,0 +1,250 @@
+# Test of key cache with partitions
+--source include/have_partition.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, v, x;
+--enable_warnings
+
+--echo # Actual test of key caches
+--echo # Note that the default key cache and query cache is disabled!
+--echo # Verifing that reads/writes use the key cache correctly
+SELECT @org_key_cache_buffer_size:= @@global.default.key_buffer_size;
+CREATE TABLE t1 (
+  a INT,
+  b INT,
+  c INT NOT NULL,
+  PRIMARY KEY (a),
+  KEY `inx_b` (b))
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH (a)
+(PARTITION p0 VALUES LESS THAN (1167602410)
+ (SUBPARTITION sp0,
+  SUBPARTITION sp1),
+ PARTITION p1 VALUES LESS THAN MAXVALUE
+ (SUBPARTITION sp2,
+  SUBPARTITION sp3));
+CREATE TABLE t2 (
+  a INT,
+  b INT,
+  c INT NOT NULL,
+  PRIMARY KEY (a),
+  KEY `inx_b` (b));
+FLUSH TABLES;
+FLUSH STATUS;
+
+# Genereate 4096 rows. Idea from:
+# http://datacharmer.blogspot.com/2007/12/data-from-nothing-solution-to-pop-quiz.html
+SET @a:=1167602400;
+CREATE VIEW v AS SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4;
+CREATE VIEW x AS SELECT 1 FROM v,v a,v b;
+# due to I_S performance, this was substituted with include files which
+# uses SHOW STATUS
+#DELIMITER |;
+#CREATE PROCEDURE was_zero_reads()
+#BEGIN
+#  SELECT IF(VARIABLE_VALUE = 0,"Yes!","No!") as 'Was zero reads?'
+#  FROM INFORMATION_SCHEMA.SESSION_STATUS
+#  WHERE VARIABLE_NAME = 'KEY_READS';
+#  FLUSH STATUS;
+#END|
+#DELIMITER ;|
+
+FLUSH STATUS;
+INSERT t1 SELECT @a, @a * (1 - ((@a % 2) * 2)) , 1167612400 - (@a:=@a+1) FROM x, x y;
+--source include/check_key_req.inc
+--echo # row distribution:
+SELECT PARTITION_NAME, SUBPARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA='test' and TABLE_NAME='t1';
+DROP VIEW x;
+DROP VIEW v;
+FLUSH TABLES;
+FLUSH STATUS;
+SELECT COUNT(b) FROM t1 WHERE b >= 0;
+--source include/check_key_reads.inc
+INSERT t2 SELECT a,b,c FROM t1;
+--source include/check_key_req.inc
+FLUSH STATUS;
+SELECT COUNT(b) FROM t2 WHERE b >= 0;
+--source include/check_key_reads.inc
+FLUSH TABLES;
+--echo # Enabling the default key cache
+SET GLOBAL key_buffer_size = 1024*1024;
+FLUSH STATUS;
+--echo # All these have to read the indexes
+LOAD INDEX INTO CACHE t1 PARTITION (p1);
+--source include/check_key_reads.inc
+SELECT COUNT(b) FROM t1 WHERE b >= 0;
+--source include/check_key_reads.inc
+SELECT COUNT(b) FROM t2 WHERE b >= 0;
+--source include/check_key_reads.inc
+--echo # All these should be able to use the key cache
+SELECT COUNT(b) FROM t1 WHERE b >= 0;
+--source include/check_key_reads.inc
+SELECT COUNT(b) FROM t2 WHERE b >= 0;
+--source include/check_key_reads.inc
+FLUSH TABLES;
+LOAD INDEX INTO CACHE t1 PARTITION (p1,p0);
+--source include/check_key_reads.inc
+--echo # should be zero
+SELECT COUNT(b) FROM t1 WHERE b >= 0;
+--source include/check_key_reads.inc
+LOAD INDEX INTO CACHE t2;
+--source include/check_key_reads.inc
+--echo # should be zero
+SELECT COUNT(b) FROM t2 WHERE b >= 0;
+--source include/check_key_reads.inc
+FLUSH TABLES;
+LOAD INDEX INTO CACHE t1 PARTITION (p1,p0) IGNORE LEAVES;
+--source include/check_key_reads.inc
+--echo # should not be zero
+SELECT COUNT(b) FROM t1 WHERE b >= 0;
+--source include/check_key_reads.inc
+LOAD INDEX INTO CACHE t2 IGNORE LEAVES;
+--source include/check_key_reads.inc
+--echo # should not be zero
+SELECT COUNT(b) FROM t2 WHERE b >= 0;
+--source include/check_key_reads.inc
+TRUNCATE TABLE t2;
+INSERT t2 SELECT a,b,c FROM t1;
+--source include/check_key_req.inc
+DROP TABLE t1,t2;
+
+SET GLOBAL hot_cache.key_buffer_size = 1024*1024;
+SET GLOBAL warm_cache.key_buffer_size = 1024*1024;
+SET @@global.cold_cache.key_buffer_size = 1024*1024;
+SELECT @@global.default.key_buffer_size a, @@global.default.key_cache_block_size b, @@global.default.key_cache_age_threshold c, @@global.default.key_cache_division_limit d;
+SELECT @@global.hot_cache.key_buffer_size a, @@global.hot_cache.key_cache_block_size b, @@global.hot_cache.key_cache_age_threshold c, @@global.hot_cache.key_cache_division_limit d;
+SELECT @@global.warm_cache.key_buffer_size a, @@global.warm_cache.key_cache_block_size b, @@global.warm_cache.key_cache_age_threshold c, @@global.warm_cache.key_cache_division_limit d;
+SELECT @@global.cold_cache.key_buffer_size a, @@global.cold_cache.key_cache_block_size b, @@global.cold_cache.key_cache_age_threshold c, @@global.cold_cache.key_cache_division_limit d;
+CREATE TABLE t1 (
+  a INT,
+  b VARCHAR(257),
+  c INT NOT NULL,
+  PRIMARY KEY (a),
+  KEY `inx_b` (b),
+  KEY `inx_c`(c))
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH (a)
+(PARTITION p0 VALUES LESS THAN (10)
+ (SUBPARTITION sp0,
+  SUBPARTITION sp1),
+ PARTITION p1 VALUES LESS THAN MAXVALUE
+ (SUBPARTITION sp2,
+  SUBPARTITION sp3));
+CREATE TABLE t2 (
+  a INT,
+  b VARCHAR(257),
+  c INT NOT NULL,
+  PRIMARY KEY (a),
+  KEY `inx_b` (b),
+  KEY `inx_c`(c));
+SET @a:=1167602400;
+# Genereate 4096 rows. Idea from:
+# http://datacharmer.blogspot.com/2007/12/data-from-nothing-solution-to-pop-quiz.html
+CREATE VIEW v AS SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4;
+CREATE VIEW x AS SELECT 1 FROM v,v a,v b;
+INSERT t1 SELECT @a, CONCAT('X_', @a, ' MySQL'), 1167612400 - (@a:=@a+1) FROM x, x a;
+DROP VIEW x;
+DROP VIEW v;
+INSERT t2 SELECT a, b, c FROM t1;
+SELECT COUNT(*) FROM t1;
+SELECT COUNT(*) FROM t2;
+FLUSH TABLES;
+
+--echo # Restrict partitioned commands to partitioned tables only
+--error ER_PARTITION_MGMT_ON_NONPARTITIONED
+CACHE INDEX t2 PARTITION (p0) KEY (`inx_b`) IN hot_cache;
+--error ER_PARTITION_MGMT_ON_NONPARTITIONED
+CACHE INDEX t2 PARTITION (p0,`p1`) INDEX (`PRIMARY`) IN hot_cache;
+--error ER_PARTITION_MGMT_ON_NONPARTITIONED
+CACHE INDEX t2 PARTITION (`p1`) INDEX (`PRIMARY`,`inx_b`) IN hot_cache;
+--error ER_PARTITION_MGMT_ON_NONPARTITIONED
+CACHE INDEX t2 PARTITION (ALL) KEY (`inx_b`,`PRIMARY`) IN hot_cache;
+--echo # Basic key cache testing
+--echo # The manual correctly says: "The syntax of CACHE INDEX enables you to
+--echo # specify that only particular indexes from a table should be assigned
+--echo # to the cache. The current implementation assigns all the table's
+--echo # indexes to the cache, so there is no reason to specify anything
+--echo # other than the table name."
+--echo # So the most of the test only tests the syntax 
+CACHE INDEX t2 INDEX (`inx_b`) IN hot_cache;
+CACHE INDEX t2 KEY (`PRIMARY`) IN warm_cache;
+CACHE INDEX t2 KEY (`PRIMARY`,`inx_b`) IN cold_cache;
+CACHE INDEX t2 INDEX (inx_b,`PRIMARY`) IN default;
+CACHE INDEX t1 PARTITION (p0) KEY (`inx_b`) IN cold_cache;
+--error ER_PARSE_ERROR
+CACHE INDEX t1 PARTITIONS (p0) KEY (`inx_b`) IN cold_cache;
+--echo # only one table at a time if specifying partitions
+--error ER_PARSE_ERROR
+CACHE INDEX t1,t2 PARTITION (p0) KEY (`inx_b`) IN cold_cache;
+CACHE INDEX t1 PARTITION (`p0`,p1) INDEX (`PRIMARY`) IN warm_cache;
+CACHE INDEX t1 PARTITION (`p1`) INDEX (`PRIMARY`,inx_b) IN hot_cache;
+CACHE INDEX t1 PARTITION (ALL) KEY (`inx_b`,`PRIMARY`) IN default;
+CACHE INDEX t1 PARTITION (ALL) IN hot_cache;
+CACHE INDEX t1 INDEX (`inx_b`) IN default;
+CACHE INDEX t1 KEY (`PRIMARY`) IN hot_cache;
+CACHE INDEX t1 KEY (`PRIMARY`,`inx_b`) IN warm_cache;
+CACHE INDEX t1 INDEX (`inx_b`,`PRIMARY`) IN cold_cache;
+CACHE INDEX t1 IN hot_cache;
+--echo # Test of non existent key cache:
+--error ER_UNKNOWN_KEY_CACHE
+CACHE INDEX t1 IN non_existent_key_cache;
+--echo # Basic testing of LOAD INDEX
+LOAD INDEX INTO CACHE t2;
+--echo # PRIMARY and secondary keys have different block sizes
+LOAD INDEX INTO CACHE t2 ignore leaves;
+--echo # Must have INDEX or KEY before the index list
+--error ER_PARSE_ERROR
+LOAD INDEX INTO CACHE t2 (`PRIMARY`);
+
+--echo # Test of IGNORE LEAVES
+LOAD INDEX INTO CACHE t2 INDEX (`PRIMARY`);
+LOAD INDEX INTO CACHE t2 KEY (`PRIMARY`,`inx_b`) IGNORE LEAVES;
+CACHE INDEX t2 IN warm_cache;
+CACHE INDEX t1 IN cold_cache;
+LOAD INDEX INTO CACHE t2 KEY (`PRIMARY`) IGNORE LEAVES;
+CACHE INDEX t2 INDEX (`inx_b`, `inx_c`) IN hot_cache;
+LOAD INDEX INTO CACHE t2 KEY (`inx_b`, `inx_c`) IGNORE LEAVES;
+CACHE INDEX t2 IN warm_cache;
+CACHE INDEX t2 INDEX (`PRIMARY`, `inx_c`) IN hot_cache;
+LOAD INDEX INTO CACHE t2 KEY (`PRIMARY`,`inx_c`) IGNORE LEAVES;
+CACHE INDEX t2 INDEX (`inx_b`,`PRIMARY`) IN default;
+LOAD INDEX INTO CACHE t2 KEY (`PRIMARY`,`inx_b`);
+CACHE INDEX t2 IN default;
+LOAD INDEX INTO CACHE t2 IGNORE LEAVES;
+
+--error ER_PARTITION_MGMT_ON_NONPARTITIONED
+LOAD INDEX INTO CACHE t2 PARTITION (p1) INDEX (`PRIMARY`);
+LOAD INDEX INTO CACHE t1, t2;
+--echo # only one table at a time if specifying partitions
+--error ER_PARSE_ERROR
+LOAD INDEX INTO CACHE t1 PARTITION (p0), t2;
+LOAD INDEX INTO CACHE t1 IGNORE LEAVES;
+LOAD INDEX INTO CACHE t1 INDEX (`PRIMARY`);
+LOAD INDEX INTO CACHE t1 INDEX (`PRIMARY`,`inx_b`) IGNORE LEAVES;
+LOAD INDEX INTO CACHE t1 INDEX (`inx_b`) IGNORE LEAVES;
+LOAD INDEX INTO CACHE t1 INDEX (`PRIMARY`) IGNORE LEAVES;
+LOAD INDEX INTO CACHE t1 INDEX (`PRIMARY`,`inx_b`);
+LOAD INDEX INTO CACHE t1 PARTITION (p1) INDEX (`PRIMARY`);
+LOAD INDEX INTO CACHE t1 PARTITION (`p1`,p0) KEY (`PRIMARY`) IGNORE LEAVES;
+LOAD INDEX INTO CACHE t1 PARTITION (ALL);
+--error ER_PARSE_ERROR
+LOAD INDEX INTO CACHE t1 PARTITIONS ALL;
+LOAD INDEX INTO CACHE t1 PARTITION (p1,`p0`) IGNORE LEAVES;
+DROP INDEX `inx_b` on t1;
+DROP INDEX `inx_b` on t2;
+--error ER_PARTITION_MGMT_ON_NONPARTITIONED
+CACHE INDEX t2 PARTITION (p0) KEY (`inx_b`) IN hot_cache;
+CACHE INDEX t2 INDEX (`inx_b`) IN hot_cache;
+CACHE INDEX t1 PARTITION (p0) KEY (`inx_b`) IN hot_cache;
+CACHE INDEX t1 INDEX (`inx_b`) IN hot_cache;
+DROP TABLE t1,t2;
+SET GLOBAL hot_cache.key_buffer_size = 0;
+SET GLOBAL warm_cache.key_buffer_size = 0;
+SET @@global.cold_cache.key_buffer_size = 0;
+SELECT @@global.default.key_buffer_size a, @@global.default.key_cache_block_size b, @@global.default.key_cache_age_threshold c, @@global.default.key_cache_division_limit d;
+SELECT @@global.hot_cache.key_buffer_size a, @@global.hot_cache.key_cache_block_size b, @@global.hot_cache.key_cache_age_threshold c, @@global.hot_cache.key_cache_division_limit d;
+SELECT @@global.warm_cache.key_buffer_size a, @@global.warm_cache.key_cache_block_size b, @@global.warm_cache.key_cache_age_threshold c, @@global.warm_cache.key_cache_division_limit d;
+SELECT @@global.cold_cache.key_buffer_size a, @@global.cold_cache.key_cache_block_size b, @@global.cold_cache.key_cache_age_threshold c, @@global.cold_cache.key_cache_division_limit d;
+--disable_warnings
+SET @@global.default.key_buffer_size = @org_key_cache_buffer_size;
+--enable_warnings

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2008-10-10 18:12:38 +0000
+++ b/sql/ha_partition.cc	2008-10-23 19:50:53 +0000
@@ -855,9 +855,12 @@ int ha_partition::rename_partitions(cons
 #define ANALYZE_PARTS 2
 #define CHECK_PARTS   3
 #define REPAIR_PARTS 4
+#define ASSIGN_KEYCACHE_PARTS 5
+#define PRELOAD_KEYS_PARTS 6
 
 static const char *opt_op_name[]= {NULL,
-                                   "optimize", "analyze", "check", "repair" };
+                                   "optimize", "analyze", "check", "repair",
+                                   "assign_to_keycache", "preload_keys"};
 
 /*
   Optimize table
@@ -942,7 +945,44 @@ int ha_partition::repair(THD *thd, HA_CH
   DBUG_RETURN(handle_opt_partitions(thd, check_opt, REPAIR_PARTS));
 }
 
+/**
+  Assign to keycache
+
+  @param thd          Thread object
+  @param check_opt    Check/analyze/repair/optimize options
+
+  @return
+    @retval >0        Error
+    @retval 0         Success
+*/
+
+int ha_partition::assign_to_keycache(THD *thd, HA_CHECK_OPT *check_opt)
+{
+  DBUG_ENTER("ha_partition::assign_to_keycache");
+
+  DBUG_RETURN(handle_opt_partitions(thd, check_opt, ASSIGN_KEYCACHE_PARTS));
+}
 
+
+/**
+  Preload to keycache
+
+  @param thd          Thread object
+  @param check_opt    Check/analyze/repair/optimize options
+
+  @return
+    @retval >0        Error
+    @retval 0         Success
+*/
+
+int ha_partition::preload_keys(THD *thd, HA_CHECK_OPT *check_opt)
+{
+  DBUG_ENTER("ha_partition::preload_keys");
+
+  DBUG_RETURN(handle_opt_partitions(thd, check_opt, PRELOAD_KEYS_PARTS));
+}
+
+ 
 /*
   Handle optimize/analyze/check/repair of one partition
 
@@ -973,6 +1013,10 @@ static int handle_opt_part(THD *thd, HA_
     error= file->ha_check(thd, check_opt);
   else if (flag == REPAIR_PARTS)
     error= file->ha_repair(thd, check_opt);
+  else if (flag == ASSIGN_KEYCACHE_PARTS)
+    error= file->assign_to_keycache(thd, check_opt);
+  else if (flag == PRELOAD_KEYS_PARTS)
+    error= file->preload_keys(thd, check_opt);
   else
   {
     DBUG_ASSERT(FALSE);

=== modified file 'sql/ha_partition.h'
--- a/sql/ha_partition.h	2008-10-10 18:12:38 +0000
+++ b/sql/ha_partition.h	2008-10-23 19:50:53 +0000
@@ -998,12 +998,13 @@ public:
 
     virtual int backup(TD* thd, HA_CHECK_OPT *check_opt);
     virtual int restore(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);
     virtual int dump(THD* thd, int fd = -1);
     virtual int net_read_dump(NET* net);
     virtual uint checksum() const;
   */
+  /* Enabled keycache for performance reasons, WL#4571 */
+    virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt);
+    virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
 
   /*
     -------------------------------------------------------------------------

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2008-10-10 18:12:38 +0000
+++ b/sql/sql_partition.cc	2008-10-23 19:50:53 +0000
@@ -4131,7 +4131,7 @@ uint set_part_state(Alter_info *alter_in
       /*
         Mark the partition.
         I.e mark the partition as a partition to be "changed" by
-        analyzing/optimizing/rebuilding/checking/repairing
+        analyzing/optimizing/rebuilding/checking/repairing/...
       */
       no_parts_found++;
       part_elem->part_state= part_state;

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2008-10-16 15:14:23 +0000
+++ b/sql/sql_table.cc	2008-10-23 19:50:53 +0000
@@ -4203,6 +4203,7 @@ static bool mysql_admin_table(THD* thd, 
         /*
           Set up which partitions that should be processed
           if ALTER TABLE t ANALYZE/CHECK/OPTIMIZE/REPAIR PARTITION ..
+          CACHE INDEX/LOAD INDEX for specified partitions
         */
         Alter_info *alter_info= &lex->alter_info;
 

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2008-10-10 18:12:38 +0000
+++ b/sql/sql_yacc.yy	2008-10-23 19:50:53 +0000
@@ -1260,7 +1260,9 @@ bool my_yyoverflow(short **a, YYSTYPE **
         slave master_def master_defs master_file_def slave_until_opts
         repair restore backup analyze check start checksum
         field_list field_list_item field_spec kill column_def key_def
-        keycache_list assign_to_keycache preload_list preload_keys
+        keycache_list keycache_list_or_parts assign_to_keycache
+        assign_to_keycache_parts
+        preload_list preload_list_or_parts preload_keys preload_keys_parts
         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
@@ -3743,17 +3745,9 @@ opt_partitioning:
         ;
 
 partitioning:
-          PARTITION_SYM
+          PARTITION_SYM have_partitioning
           {
-#ifdef WITH_PARTITION_STORAGE_ENGINE
             LEX *lex= Lex;
-            LEX_STRING partition_name={C_STRING_WITH_LEN("partition")};
-            if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN))
-            {
-              my_error(ER_FEATURE_DISABLED, MYF(0),
-                      "partitioning", "--with-partition");
-              MYSQL_YYABORT;
-            }
             lex->part_info= new partition_info();
             if (!lex->part_info)
             {
@@ -3764,14 +3758,27 @@ partitioning:
             {
               lex->alter_info.flags|= ALTER_PARTITION;
             }
+          }
+          partition
+        ;
+
+have_partitioning:
+          /* empty */
+          {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+            LEX_STRING partition_name={C_STRING_WITH_LEN("partition")};
+            if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN))
+            {
+              my_error(ER_FEATURE_DISABLED, MYF(0),
+                      "partitioning", "--with-partition");
+              MYSQL_YYABORT;
+            }
 #else
             my_error(ER_FEATURE_DISABLED, MYF(0),
                      "partitioning", "--with-partition");
             MYSQL_YYABORT;
 #endif
-
           }
-          partition
         ;
 
 partition_entry:
@@ -5423,7 +5430,6 @@ alter:
             if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
                                                    TL_OPTION_UPDATING))
               MYSQL_YYABORT;
-            lex->alter_info.reset();
             lex->col_list.empty();
             lex->select_lex.init_order();
             lex->select_lex.db=
@@ -6282,14 +6288,23 @@ table_to_table:
         ;
 
 keycache:
-          CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name
+          CACHE_SYM INDEX_SYM
+          {
+            Lex->alter_info.reset();
+          }
+          keycache_list_or_parts IN_SYM key_cache_name
           {
             LEX *lex=Lex;
             lex->sql_command= SQLCOM_ASSIGN_TO_KEYCACHE;
-            lex->ident= $5;
+            lex->ident= $6;
           }
         ;
 
+keycache_list_or_parts:
+          keycache_list
+        | assign_to_keycache_parts
+        ;
+
 keycache_list:
           assign_to_keycache
         | keycache_list ',' assign_to_keycache
@@ -6304,6 +6319,15 @@ assign_to_keycache:
           }
         ;
 
+assign_to_keycache_parts:
+          table_ident adm_partition cache_keys_spec
+          {
+            if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ, 
+                                           Select->pop_index_hints()))
+              MYSQL_YYABORT;
+          }
+        ;
+
 key_cache_name:
           ident    { $$= $1; }
         | DEFAULT  { $$ = default_key_cache_base; }
@@ -6314,11 +6338,17 @@ preload:
           {
             LEX *lex=Lex;
             lex->sql_command=SQLCOM_PRELOAD_KEYS;
+            lex->alter_info.reset();
           }
-          preload_list
+          preload_list_or_parts
           {}
         ;
 
+preload_list_or_parts:
+          preload_keys_parts
+        | preload_list
+        ;
+
 preload_list:
           preload_keys
         | preload_list ',' preload_keys
@@ -6333,6 +6363,23 @@ preload_keys:
           }
         ;
 
+preload_keys_parts:
+          table_ident adm_partition cache_keys_spec opt_ignore_leaves
+          {
+            if (!Select->add_table_to_list(YYTHD, $1, NULL, $4, TL_READ,
+                                           Select->pop_index_hints()))
+              MYSQL_YYABORT;
+          }
+        ;
+
+adm_partition:
+          PARTITION_SYM have_partitioning
+          {
+            Lex->alter_info.flags|= ALTER_ADMIN_PARTITION;
+          }
+          '(' all_or_alt_part_name_list ')'
+        ;
+
 cache_keys_spec:
           {
             Lex->select_lex.alloc_index_hints(YYTHD);

Thread
bzr commit into mysql-5.1 branch (mattias.jonsson:2673) Bug#39637Mattias Jonsson23 Oct
  • Re: bzr commit into mysql-5.1 branch (mattias.jonsson:2673) Bug#39637Ingo Strüwing27 Oct