Commit d50ae165 authored by unknown's avatar unknown

Added support for key_block_size for key and table level (WL#602)

Added support for key_block_size to MyISAM.
Simplify interface to 'new Key' to make it easier to add new key options.
mysqld option --new is used to define where key options are printed.
(In 5.3 we should move all key options to after key part definition to avoid problem with reserved names)
Fixed some compiler warnings and a memory leak in ssl


include/my_base.h:
  Added flag to check if block size for key was secified
include/my_sys.h:
  Added new support function to round up to a power of two
include/myisam.h:
  Rename block_size -> block_size_index to avoid confusion with 'block_size'
include/violite.h:
  Added function to free memory after new_VioSSLAcceptorFd
  (Will rename all vio_ssl functions in a future changeset)
mysql-test/mysql-test-run.pl:
  Don't print port number info when we use --extern
mysql-test/r/myisam.result:
  Added test for key_block_size
mysql-test/t/myisam.test:
  Added test for key_block_size
mysys/mf_keycache.c:
  Simplify code
mysys/my_bit.c:
  Added new support function to round up to a power of two
sql/ha_myisam.cc:
  Tell MyISAM to use the specified key_block_size
  MyISAM also updates the global key_block_size from the used values.
sql/handler.cc:
  Added 'default_key_create_info' to be used as 'dummy' argument to 'new Key'
sql/handler.h:
  Added KEY_CREATE_INFO, to be used as for general options for KEY's
sql/item_func.h:
  Removed compiler warning
sql/lex.h:
  Added new symbol
sql/mysqld.cc:
  Fixed memory leak in ssl (new_VioSSLAcceptorFd)
sql/sql_class.h:
  Change 'new Key' to use KEY_CREATE_INFO instead of 'algoritm', parser, key_page_size.
  This makes it easier to add new key options in the future.
sql/sql_lex.h:
  Added key create options
sql/sql_parse.cc:
  Use new interface to 'new Key'
sql/sql_show.cc:
  Added support for key_block_size
  If --new is used, key options are printed after the key part definition.
sql/sql_table.cc:
  Use new interface to 'new Key'
  Add support for key_block_size
sql/sql_yacc.yy:
  Add support for key_block_size
  Allow key options before and after key_parts (In future they should be always after the key_part defintion)
  Use new interface to 'new Key'
sql/structs.h:
  Added block_size to keys
sql/table.cc:
  Remmeber and read key_block_size for table and key level
sql/table.h:
  Added default key_block_size for table
sql/unireg.cc:
  Remember key_block_size for key
storage/myisam/ft_eval.c:
  Set block_length to 0 to get default key page size
storage/myisam/ft_test1.c:
  Set block_length to 0 to get default key page size
storage/myisam/mi_check.c:
  block_size -> block_size_index
storage/myisam/mi_create.c:
  Added support for block size per key.
  Block size is rounded up to next power of two and enforced between MIN and MAX KEY_BLOCK_LENGTH.
  Align start of key block to start at an even offset of max_key_block_length to ensure key cache works good if all key pages are of same size.
storage/myisam/mi_open.c:
  block_size -> block_size_index
storage/myisam/mi_page.c:
  block_size -> block_size_index
storage/myisam/mi_test1.c:
  Set block_length to 0 to get default key page size
storage/myisam/mi_test2.c:
  Set block_length to 0 to get default key page size
storage/myisam/mi_test3.c:
  Set block_length to 0 to get default key page size
storage/myisam/myisamdef.h:
  block_size -> block_size_index to avoid confusion with 'block_size' in MySQL
  Added block_size as argument to MI_BLOCK_SIZE
  Added missing prototypes to get rid of compiler warnings
storage/myisam/myisampack.c:
  Removed compiler warning
  block_size -> block_size_index
vio/viosslfactories.c:
  Fixed memory leak in ssl (new_VioSSLAcceptorFd)
mysql-test/r/myisam-system.result:
  New BitKeeper file ``mysql-test/r/myisam-system.result''
mysql-test/t/myisam-system.test:
  New BitKeeper file ``mysql-test/t/myisam-system.test''
parent 79cc1546
...@@ -231,6 +231,7 @@ enum ha_base_keytype { ...@@ -231,6 +231,7 @@ enum ha_base_keytype {
#define HA_VAR_LENGTH_KEY 8 #define HA_VAR_LENGTH_KEY 8
#define HA_NULL_PART_KEY 64 #define HA_NULL_PART_KEY 64
#define HA_USES_PARSER 16384 /* Fulltext index uses [pre]parser */ #define HA_USES_PARSER 16384 /* Fulltext index uses [pre]parser */
#define HA_USES_BLOCK_SIZE ((uint) 32768)
#define HA_SORT_ALLOWS_SAME 512 /* Intern bit when sorting records */ #define HA_SORT_ALLOWS_SAME 512 /* Intern bit when sorting records */
/* /*
Key has a part that can have end space. If this is an unique key Key has a part that can have end space. If this is an unique key
......
...@@ -812,6 +812,7 @@ extern int unpackfrm(const void **, uint *, const void *); ...@@ -812,6 +812,7 @@ extern int unpackfrm(const void **, uint *, const void *);
extern ha_checksum my_checksum(ha_checksum crc, const byte *mem, uint count); extern ha_checksum my_checksum(ha_checksum crc, const byte *mem, uint count);
extern uint my_bit_log2(ulong value); extern uint my_bit_log2(ulong value);
extern uint32 my_round_up_to_next_power(uint32 v);
extern uint my_count_bits(ulonglong v); extern uint my_count_bits(ulonglong v);
extern uint my_count_bits_ushort(ushort v); extern uint my_count_bits_ushort(ushort v);
extern void my_sleep(ulong m_seconds); extern void my_sleep(ulong m_seconds);
......
...@@ -192,7 +192,7 @@ typedef struct st_mi_keydef /* Key definition with open & info */ ...@@ -192,7 +192,7 @@ typedef struct st_mi_keydef /* Key definition with open & info */
uint16 keylength; /* Tot length of keyparts (auto) */ uint16 keylength; /* Tot length of keyparts (auto) */
uint16 minlength; /* min length of (packed) key (auto) */ uint16 minlength; /* min length of (packed) key (auto) */
uint16 maxlength; /* max length of (packed) key (auto) */ uint16 maxlength; /* max length of (packed) key (auto) */
uint16 block_size; /* block_size (auto) */ uint16 block_size_index; /* block_size (auto) */
uint32 version; /* For concurrent read/write */ uint32 version; /* For concurrent read/write */
uint32 ftparser_nr; /* distinct ftparser number */ uint32 ftparser_nr; /* distinct ftparser number */
......
...@@ -132,6 +132,7 @@ struct st_VioSSLAcceptorFd ...@@ -132,6 +132,7 @@ struct st_VioSSLAcceptorFd
const char *ca_file,const char *ca_path, const char *ca_file,const char *ca_path,
const char *cipher); const char *cipher);
Vio *new_VioSSL(struct st_VioSSLAcceptorFd *fd, Vio *sd, int state); Vio *new_VioSSL(struct st_VioSSLAcceptorFd *fd, Vio *sd, int state);
void free_vio_ssl_acceptor_fd(struct st_VioSSLAcceptorFd *fd);
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
#ifdef HAVE_SMEM #ifdef HAVE_SMEM
......
...@@ -1224,17 +1224,20 @@ sub environment_setup () { ...@@ -1224,17 +1224,20 @@ sub environment_setup () {
$ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set $ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set
# We are nice and report a bit about our settings # We are nice and report a bit about our settings
print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; if (!$opt_extern)
print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; {
print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n";
print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n";
print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n"; print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n";
print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n"; print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n";
print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n"; print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n";
print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\n"; print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n";
print "Using IM_PORT = $ENV{IM_PORT}\n"; print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n";
print "Using IM_MYSQLD1_PORT = $ENV{IM_MYSQLD1_PORT}\n"; print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\n";
print "Using IM_MYSQLD2_PORT = $ENV{IM_MYSQLD2_PORT}\n"; print "Using IM_PORT = $ENV{IM_PORT}\n";
print "Using IM_MYSQLD1_PORT = $ENV{IM_MYSQLD1_PORT}\n";
print "Using IM_MYSQLD2_PORT = $ENV{IM_MYSQLD2_PORT}\n";
}
} }
...@@ -1399,7 +1402,7 @@ sub check_running_as_root () { ...@@ -1399,7 +1402,7 @@ sub check_running_as_root () {
sub check_ssl_support () { sub check_ssl_support () {
if ($opt_skip_ssl) if ($opt_skip_ssl || $opt_extern)
{ {
mtr_report("Skipping SSL"); mtr_report("Skipping SSL");
$opt_ssl_supported= 0; $opt_ssl_supported= 0;
......
drop table if exists t1,t2;
create table t1 (a int) engine=myisam;
drop table if exists t1;
Warnings:
Error 2 Can't find file: 't1' (errno: 2)
create table t1 (a int) engine=myisam;
drop table t1;
Got one of the listed errors
create table t1 (a int) engine=myisam;
drop table t1;
Got one of the listed errors
drop table t1;
ERROR 42S02: Unknown table 't1'
...@@ -1344,18 +1344,6 @@ drop table t1; ...@@ -1344,18 +1344,6 @@ drop table t1;
create table t1 (v varchar(65535)); create table t1 (v varchar(65535));
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
set storage_engine=MyISAM; set storage_engine=MyISAM;
create table t1 (a int) engine=myisam;
drop table if exists t1;
Warnings:
Error 2 Can't find file: 't1' (errno: 2)
create table t1 (a int) engine=myisam;
drop table t1;
Got one of the listed errors
create table t1 (a int) engine=myisam;
drop table t1;
Got one of the listed errors
drop table t1;
ERROR 42S02: Unknown table 't1'
set @save_concurrent_insert=@@concurrent_insert; set @save_concurrent_insert=@@concurrent_insert;
set global concurrent_insert=1; set global concurrent_insert=1;
create table t1 (a int); create table t1 (a int);
...@@ -1433,3 +1421,157 @@ create table t3 (c1 int) engine=myisam pack_keys=default; ...@@ -1433,3 +1421,157 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
create table t4 (c1 int) engine=myisam pack_keys=2; create table t4 (c1 int) engine=myisam pack_keys=2;
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 '2' at line 1 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 '2' at line 1
drop table t1, t2, t3; drop table t1, t2, t3;
create table t1 (a int not null, key `a` key_block_size=1024 (a));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
KEY `a` KEY_BLOCK_SIZE=1024 (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
set @@new=1;
create table t1 (a int not null, key `a` (a) key_block_size=1024);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
KEY `a` (`a`) KEY_BLOCK_SIZE=1024
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int not null, key `a` (a) key_block_size=2048);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
KEY `a` (`a`) KEY_BLOCK_SIZE=2048
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a varchar(2048), key `a` (a));
Warnings:
Warning 1071 Specified key was too long; max key length is 1000 bytes
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(2048) DEFAULT NULL,
KEY `a` (`a`(1000))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a varchar(2048), key `a` (a) key_block_size=1024);
Warnings:
Warning 1071 Specified key was too long; max key length is 1000 bytes
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(2048) DEFAULT NULL,
KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=4096
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=1024;
Warnings:
Warning 1071 Specified key was too long; max key length is 1000 bytes
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` varchar(2048) DEFAULT NULL,
KEY `a` (`a`),
KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096
) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1024
alter table t1 key_block_size=2048;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` varchar(2048) DEFAULT NULL,
KEY `a` (`a`) KEY_BLOCK_SIZE=1024,
KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096
) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2048
alter table t1 add c int, add key (c);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` varchar(2048) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
KEY `a` (`a`) KEY_BLOCK_SIZE=1024,
KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096,
KEY `c` (`c`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2048
alter table t1 key_block_size=0;
alter table t1 add d int, add key (d);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` varchar(2048) DEFAULT NULL,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
KEY `a` (`a`) KEY_BLOCK_SIZE=1024,
KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=4096,
KEY `c` (`c`) KEY_BLOCK_SIZE=2048,
KEY `d` (`d`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=8192;
Warnings:
Warning 1071 Specified key was too long; max key length is 1000 bytes
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` varchar(2048) DEFAULT NULL,
KEY `a` (`a`),
KEY `b` (`b`(1000))
) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8192
drop table t1;
create table t1 (a int not null, b varchar(2048), key (a) key_block_size=1024, key(b)) key_block_size=8192;
Warnings:
Warning 1071 Specified key was too long; max key length is 1000 bytes
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` varchar(2048) DEFAULT NULL,
KEY `a` (`a`) KEY_BLOCK_SIZE=1024,
KEY `b` (`b`(1000))
) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8192
drop table t1;
create table t1 (a int not null, b int, key (a) key_block_size=1024, key(b) key_block_size=8192) key_block_size=16384;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
KEY `a` (`a`) KEY_BLOCK_SIZE=1024,
KEY `b` (`b`) KEY_BLOCK_SIZE=8192
) ENGINE=MyISAM DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=16384
drop table t1;
create table t1 (a int not null, key `a` (a) key_block_size=512);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
KEY `a` (`a`) KEY_BLOCK_SIZE=1024
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000);
Warnings:
Warning 1071 Specified key was too long; max key length is 1000 bytes
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(2048) DEFAULT NULL,
KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=4096
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int not null, key `a` (a) key_block_size=1025);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
KEY `a` (`a`) KEY_BLOCK_SIZE=2048
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int not null, key key_block_size=1024 (a));
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 '=1024 (a))' at line 1
set @@new=0;
#
# Test how DROP TABLE works if the index or data file doesn't exists
# Initialise
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (a int) engine=myisam;
system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
drop table if exists t1;
create table t1 (a int) engine=myisam;
system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
--error 1051,6
drop table t1;
create table t1 (a int) engine=myisam;
system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYD ;
--error 1105,6,29
drop table t1;
--error 1051
drop table t1;
...@@ -726,23 +726,6 @@ create table t1 (v varchar(65535)); ...@@ -726,23 +726,6 @@ create table t1 (v varchar(65535));
eval set storage_engine=$default; eval set storage_engine=$default;
#
# Test how DROP TABLE works if the index or data file doesn't exists
create table t1 (a int) engine=myisam;
system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
drop table if exists t1;
create table t1 (a int) engine=myisam;
system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
--error 1051,6
drop table t1;
create table t1 (a int) engine=myisam;
system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYD ;
--error 1105,6,29
drop table t1;
--error 1051
drop table t1;
# #
# Test concurrent insert # Test concurrent insert
# First with static record length # First with static record length
...@@ -824,3 +807,72 @@ create table t3 (c1 int) engine=myisam pack_keys=default; ...@@ -824,3 +807,72 @@ create table t3 (c1 int) engine=myisam pack_keys=default;
create table t4 (c1 int) engine=myisam pack_keys=2; create table t4 (c1 int) engine=myisam pack_keys=2;
drop table t1, t2, t3; drop table t1, t2, t3;
#
# Test of key_block_size
#
# Old format, to be obsolete in 5.3
create table t1 (a int not null, key `a` key_block_size=1024 (a));
show create table t1;
drop table t1;
set @@new=1;
create table t1 (a int not null, key `a` (a) key_block_size=1024);
show create table t1;
drop table t1;
create table t1 (a int not null, key `a` (a) key_block_size=2048);
show create table t1;
drop table t1;
create table t1 (a varchar(2048), key `a` (a));
show create table t1;
drop table t1;
create table t1 (a varchar(2048), key `a` (a) key_block_size=1024);
show create table t1;
drop table t1;
create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=1024;
show create table t1;
alter table t1 key_block_size=2048;
show create table t1;
alter table t1 add c int, add key (c);
show create table t1;
alter table t1 key_block_size=0;
alter table t1 add d int, add key (d);
show create table t1;
drop table t1;
create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=8192;
show create table t1;
drop table t1;
create table t1 (a int not null, b varchar(2048), key (a) key_block_size=1024, key(b)) key_block_size=8192;
show create table t1;
drop table t1;
create table t1 (a int not null, b int, key (a) key_block_size=1024, key(b) key_block_size=8192) key_block_size=16384;
show create table t1;
drop table t1;
# Test limits and errors of key_block_size
create table t1 (a int not null, key `a` (a) key_block_size=512);
show create table t1;
drop table t1;
create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000);
show create table t1;
drop table t1;
create table t1 (a int not null, key `a` (a) key_block_size=1025);
show create table t1;
drop table t1;
--error 1064
create table t1 (a int not null, key key_block_size=1024 (a));
set @@new=0;
...@@ -262,15 +262,9 @@ static int keycache_pthread_cond_signal(pthread_cond_t *cond); ...@@ -262,15 +262,9 @@ static int keycache_pthread_cond_signal(pthread_cond_t *cond);
#define keycache_pthread_cond_signal pthread_cond_signal #define keycache_pthread_cond_signal pthread_cond_signal
#endif /* defined(KEYCACHE_DEBUG) */ #endif /* defined(KEYCACHE_DEBUG) */
static uint next_power(uint value) static inline uint next_power(uint value)
{ {
uint old_value= 1; return (uint) my_round_up_to_next_power((uint32) value) << 1;
while (value)
{
old_value= value;
value&= value-1;
}
return (old_value << 1);
} }
......
...@@ -76,3 +76,33 @@ uint my_count_bits_ushort(ushort v) ...@@ -76,3 +76,33 @@ uint my_count_bits_ushort(ushort v)
return nbits[v]; return nbits[v];
} }
/*
Next highest power of two
SYNOPSIS
my_round_up_to_next_power()
v Value to check
RETURN
Next or equal power of 2
Note: 0 will return 0
NOTES
Algorithm by Sean Anderson, according to:
http://graphics.stanford.edu/~seander/bithacks.html
(Orignal code public domain)
Comments shows how this works with 01100000000000000000000000001011
*/
uint32 my_round_up_to_next_power(uint32 v)
{
v--; /* 01100000000000000000000000001010 */
v|= v >> 1; /* 01110000000000000000000000001111 */
v|= v >> 2; /* 01111100000000000000000000001111 */
v|= v >> 4; /* 01111111110000000000000000001111 */
v|= v >> 8; /* 01111111111111111100000000001111 */
v|= v >> 16; /* 01111111111111111111111111111111 */
return v+1; /* 10000000000000000000000000000000 */
}
...@@ -350,6 +350,7 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) ...@@ -350,6 +350,7 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
if (table->key_info[i].flags & HA_USES_PARSER) if (table->key_info[i].flags & HA_USES_PARSER)
file->s->keyinfo[i].parser= file->s->keyinfo[i].parser=
(struct st_mysql_ftparser *)parser->plugin->info; (struct st_mysql_ftparser *)parser->plugin->info;
table->key_info[i].block_size= file->s->keyinfo[i].block_length;
} }
return (0); return (0);
} }
...@@ -1368,7 +1369,7 @@ void ha_myisam::info(uint flag) ...@@ -1368,7 +1369,7 @@ void ha_myisam::info(uint flag)
sortkey= info.sortkey; sortkey= info.sortkey;
ref_length= info.reflength; ref_length= info.reflength;
share->db_options_in_use= info.options; share->db_options_in_use= info.options;
block_size= myisam_block_size; block_size= myisam_block_size; /* record block size */
/* Update share */ /* Update share */
if (share->tmp_table == NO_TMP_TABLE) if (share->tmp_table == NO_TMP_TABLE)
...@@ -1501,6 +1502,8 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, ...@@ -1501,6 +1502,8 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ? keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ?
(pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) : (pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) :
pos->algorithm; pos->algorithm;
keydef[i].block_length= pos->block_size;
keydef[i].seg=keyseg; keydef[i].seg=keyseg;
keydef[i].keysegs=pos->key_parts; keydef[i].keysegs=pos->key_parts;
for (j=0 ; j < pos->key_parts ; j++) for (j=0 ; j < pos->key_parts ; j++)
......
...@@ -47,6 +47,8 @@ extern handlerton *sys_table_types[]; ...@@ -47,6 +47,8 @@ extern handlerton *sys_table_types[];
#define BITMAP_STACKBUF_SIZE (128/8) #define BITMAP_STACKBUF_SIZE (128/8)
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0 };
/* static functions defined in this file */ /* static functions defined in this file */
static handler *create_default(TABLE_SHARE *table); static handler *create_default(TABLE_SHARE *table);
......
...@@ -280,6 +280,7 @@ enum enum_binlog_command { ...@@ -280,6 +280,7 @@ enum enum_binlog_command {
#define HA_CREATE_USED_COMMENT (1L << 16) #define HA_CREATE_USED_COMMENT (1L << 16)
#define HA_CREATE_USED_PASSWORD (1L << 17) #define HA_CREATE_USED_PASSWORD (1L << 17)
#define HA_CREATE_USED_CONNECTION (1L << 18) #define HA_CREATE_USED_CONNECTION (1L << 18)
#define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
typedef ulonglong my_xid; // this line is the same as in log_event.h typedef ulonglong my_xid; // this line is the same as in log_event.h
#define MYSQL_XID_PREFIX "MySQLXid" #define MYSQL_XID_PREFIX "MySQLXid"
...@@ -653,6 +654,7 @@ typedef struct st_ha_create_information ...@@ -653,6 +654,7 @@ typedef struct st_ha_create_information
ulong table_options; ulong table_options;
ulong avg_row_length; ulong avg_row_length;
ulong used_fields; ulong used_fields;
ulong key_block_size;
SQL_LIST merge_list; SQL_LIST merge_list;
handlerton *db_type; handlerton *db_type;
enum row_type row_type; enum row_type row_type;
...@@ -666,6 +668,15 @@ typedef struct st_ha_create_information ...@@ -666,6 +668,15 @@ typedef struct st_ha_create_information
bool store_on_disk; /* 1 if table stored on disk */ bool store_on_disk; /* 1 if table stored on disk */
} HA_CREATE_INFO; } HA_CREATE_INFO;
typedef struct st_key_create_information
{
enum ha_key_alg algorithm;
ulong block_size;
LEX_STRING parser_name;
} KEY_CREATE_INFO;
/* /*
Class for maintaining hooks used inside operations on tables such Class for maintaining hooks used inside operations on tables such
as: create table functions, delete table functions, and alter table as: create table functions, delete table functions, and alter table
...@@ -700,6 +711,7 @@ private: ...@@ -700,6 +711,7 @@ private:
typedef struct st_savepoint SAVEPOINT; typedef struct st_savepoint SAVEPOINT;
extern ulong savepoint_alloc_size; extern ulong savepoint_alloc_size;
extern KEY_CREATE_INFO default_key_create_info;
/* Forward declaration for condition pushdown to storage engine */ /* Forward declaration for condition pushdown to storage engine */
typedef class Item COND; typedef class Item COND;
......
...@@ -284,6 +284,7 @@ class Item_func_connection_id :public Item_int_func ...@@ -284,6 +284,7 @@ class Item_func_connection_id :public Item_int_func
longlong value; longlong value;
public: public:
Item_func_connection_id() {}
const char *func_name() const { return "connection_id"; } const char *func_name() const { return "connection_id"; }
void fix_length_and_dec(); void fix_length_and_dec();
bool fix_fields(THD *thd, Item **ref); bool fix_fields(THD *thd, Item **ref);
......
...@@ -275,6 +275,7 @@ static SYMBOL symbols[] = { ...@@ -275,6 +275,7 @@ static SYMBOL symbols[] = {
{ "JOIN", SYM(JOIN_SYM)}, { "JOIN", SYM(JOIN_SYM)},
{ "KEY", SYM(KEY_SYM)}, { "KEY", SYM(KEY_SYM)},
{ "KEYS", SYM(KEYS)}, { "KEYS", SYM(KEYS)},
{ "KEY_BLOCK_SIZE", SYM(KEY_BLOCK_SIZE)},
{ "KILL", SYM(KILL_SYM)}, { "KILL", SYM(KILL_SYM)},
{ "LANGUAGE", SYM(LANGUAGE_SYM)}, { "LANGUAGE", SYM(LANGUAGE_SYM)},
{ "LAST", SYM(LAST_SYM)}, { "LAST", SYM(LAST_SYM)},
......
...@@ -742,6 +742,7 @@ static void clean_up_mutexes(void); ...@@ -742,6 +742,7 @@ static void clean_up_mutexes(void);
static void wait_for_signal_thread_to_end(void); static void wait_for_signal_thread_to_end(void);
static int test_if_case_insensitive(const char *dir_name); static int test_if_case_insensitive(const char *dir_name);
static void create_pid_file(); static void create_pid_file();
static void end_ssl();
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
/**************************************************************************** /****************************************************************************
...@@ -1217,10 +1218,7 @@ void clean_up(bool print_message) ...@@ -1217,10 +1218,7 @@ void clean_up(bool print_message)
#endif #endif
delete binlog_filter; delete binlog_filter;
delete rpl_filter; delete rpl_filter;
#ifdef HAVE_OPENSSL end_ssl();
if (ssl_acceptor_fd)
my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR));
#endif /* HAVE_OPENSSL */
#ifdef USE_REGEX #ifdef USE_REGEX
my_regex_end(); my_regex_end();
#endif #endif
...@@ -2968,6 +2966,18 @@ static void init_ssl() ...@@ -2968,6 +2966,18 @@ static void init_ssl()
} }
static void end_ssl()
{
#ifdef HAVE_OPENSSL
if (ssl_acceptor_fd)
{
free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
ssl_acceptor_fd= 0;
}
#endif /* HAVE_OPENSSL */
}
static int init_server_components() static int init_server_components()
{ {
DBUG_ENTER("init_server_components"); DBUG_ENTER("init_server_components");
......
...@@ -112,17 +112,16 @@ class Key :public Sql_alloc { ...@@ -112,17 +112,16 @@ class Key :public Sql_alloc {
public: public:
enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY}; enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY};
enum Keytype type; enum Keytype type;
enum ha_key_alg algorithm; KEY_CREATE_INFO key_info;
List<key_part_spec> columns; List<key_part_spec> columns;
const char *name; const char *name;
bool generated; bool generated;
LEX_STRING *parser_name;
Key(enum Keytype type_par, const char *name_arg, enum ha_key_alg alg_par, Key(enum Keytype type_par, const char *name_arg,
bool generated_arg, List<key_part_spec> &cols, KEY_CREATE_INFO *key_info_arg,
LEX_STRING *parser_arg= 0) bool generated_arg, List<key_part_spec> &cols)
:type(type_par), algorithm(alg_par), columns(cols), name(name_arg), :type(type_par), key_info(*key_info_arg), columns(cols), name(name_arg),
generated(generated_arg), parser_name(parser_arg) generated(generated_arg)
{} {}
~Key() {} ~Key() {}
/* Equality comparison of keys (ignoring name) */ /* Equality comparison of keys (ignoring name) */
...@@ -144,7 +143,7 @@ public: ...@@ -144,7 +143,7 @@ public:
foreign_key(const char *name_arg, List<key_part_spec> &cols, foreign_key(const char *name_arg, List<key_part_spec> &cols,
Table_ident *table, List<key_part_spec> &ref_cols, Table_ident *table, List<key_part_spec> &ref_cols,
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg) uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
:Key(FOREIGN_KEY, name_arg, HA_KEY_ALG_UNDEF, 0, cols), :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols),
ref_table(table), ref_columns(cols), ref_table(table), ref_columns(cols),
delete_opt(delete_opt_arg), update_opt(update_opt_arg), delete_opt(delete_opt_arg), update_opt(update_opt_arg),
match_opt(match_opt_arg) match_opt(match_opt_arg)
......
...@@ -840,6 +840,7 @@ typedef struct st_lex ...@@ -840,6 +840,7 @@ typedef struct st_lex
udf_func udf; udf_func udf;
HA_CHECK_OPT check_opt; // check/repair options HA_CHECK_OPT check_opt; // check/repair options
HA_CREATE_INFO create_info; HA_CREATE_INFO create_info;
KEY_CREATE_INFO key_info;
LEX_MASTER_INFO mi; // used by CHANGE MASTER LEX_MASTER_INFO mi; // used by CHANGE MASTER
USER_RESOURCES mqh; USER_RESOURCES mqh;
ulong type; ulong type;
......
...@@ -5973,14 +5973,16 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, ...@@ -5973,14 +5973,16 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
if (type_modifier & PRI_KEY_FLAG) if (type_modifier & PRI_KEY_FLAG)
{ {
lex->col_list.push_back(new key_part_spec(field_name,0)); lex->col_list.push_back(new key_part_spec(field_name,0));
lex->key_list.push_back(new Key(Key::PRIMARY, NullS, HA_KEY_ALG_UNDEF, lex->key_list.push_back(new Key(Key::PRIMARY, NullS,
&default_key_create_info,
0, lex->col_list)); 0, lex->col_list));
lex->col_list.empty(); lex->col_list.empty();
} }
if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
{ {
lex->col_list.push_back(new key_part_spec(field_name,0)); lex->col_list.push_back(new key_part_spec(field_name,0));
lex->key_list.push_back(new Key(Key::UNIQUE, NullS, HA_KEY_ALG_UNDEF, 0, lex->key_list.push_back(new Key(Key::UNIQUE, NullS,
&default_key_create_info, 0,
lex->col_list)); lex->col_list));
lex->col_list.empty(); lex->col_list.empty();
} }
......
...@@ -42,6 +42,9 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **), ...@@ -42,6 +42,9 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
grant_names, NULL}; grant_names, NULL};
#endif #endif
static void store_key_options(THD *thd, String *packet, TABLE *table,
KEY *key_info);
/*************************************************************************** /***************************************************************************
** List all table types supported ** List all table types supported
***************************************************************************/ ***************************************************************************/
...@@ -929,15 +932,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, ...@@ -929,15 +932,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
handler *file= table->file; handler *file= table->file;
TABLE_SHARE *share= table->s; TABLE_SHARE *share= table->s;
HA_CREATE_INFO create_info; HA_CREATE_INFO create_info;
my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL | bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
MODE_ORACLE | MODE_ORACLE |
MODE_MSSQL | MODE_MSSQL |
MODE_DB2 | MODE_DB2 |
MODE_MAXDB | MODE_MAXDB |
MODE_ANSI)) != 0; MODE_ANSI)) != 0;
my_bool limited_mysql_mode= (thd->variables.sql_mode &
(MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
MODE_MYSQL40)) != 0;
DBUG_ENTER("store_create_info"); DBUG_ENTER("store_create_info");
DBUG_PRINT("enter",("table: %s", table->s->table_name.str)); DBUG_PRINT("enter",("table: %s", table->s->table_name.str));
...@@ -1100,22 +1100,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, ...@@ -1100,22 +1100,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
if (!found_primary) if (!found_primary)
append_identifier(thd, packet, key_info->name, strlen(key_info->name)); append_identifier(thd, packet, key_info->name, strlen(key_info->name));
if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) && #if MYSQL_VERSION_ID < 50300
!limited_mysql_mode && !foreign_db_mode) /* Key options moved to after key parts in 5.3.0 */
{ if (!thd->variables.new_mode)
if (key_info->algorithm == HA_KEY_ALG_BTREE) store_key_options(thd, packet, table, key_info);
packet->append(STRING_WITH_LEN(" USING BTREE")); #endif
if (key_info->algorithm == HA_KEY_ALG_HASH)
packet->append(STRING_WITH_LEN(" USING HASH"));
// +BAR: send USING only in non-default case: non-spatial rtree
if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
!(key_info->flags & HA_SPATIAL))
packet->append(STRING_WITH_LEN(" USING RTREE"));
// No need to send USING FULLTEXT, it is sent as FULLTEXT KEY
}
packet->append(STRING_WITH_LEN(" (")); packet->append(STRING_WITH_LEN(" ("));
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
...@@ -1140,6 +1130,10 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, ...@@ -1140,6 +1130,10 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
} }
} }
packet->append(')'); packet->append(')');
#if MYSQL_VERSION_ID < 50300
if (thd->variables.new_mode)
#endif
store_key_options(thd, packet, table, key_info);
if (key_info->parser) if (key_info->parser)
{ {
packet->append(" WITH PARSER ", 13); packet->append(" WITH PARSER ", 13);
...@@ -1252,6 +1246,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, ...@@ -1252,6 +1246,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" ROW_FORMAT=")); packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
packet->append(ha_row_type[(uint) share->row_type]); packet->append(ha_row_type[(uint) share->row_type]);
} }
if (table->s->key_block_size)
{
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
end= longlong10_to_str(table->s->key_block_size, buff, 10);
packet->append(buff, (uint) (end - buff));
}
table->file->append_create_info(packet); table->file->append_create_info(packet);
if (share->comment && share->comment[0]) if (share->comment && share->comment[0])
{ {
...@@ -1286,6 +1286,47 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, ...@@ -1286,6 +1286,47 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
static void store_key_options(THD *thd, String *packet, TABLE *table,
KEY *key_info)
{
bool limited_mysql_mode= (thd->variables.sql_mode &
(MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
MODE_MYSQL40)) != 0;
bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
MODE_ORACLE |
MODE_MSSQL |
MODE_DB2 |
MODE_MAXDB |
MODE_ANSI)) != 0;
char *end, buff[32];
if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
!limited_mysql_mode && !foreign_db_mode)
{
if (key_info->algorithm == HA_KEY_ALG_BTREE)
packet->append(STRING_WITH_LEN(" USING BTREE"));
if (key_info->algorithm == HA_KEY_ALG_HASH)
packet->append(STRING_WITH_LEN(" USING HASH"));
/* send USING only in non-default case: non-spatial rtree */
if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
!(key_info->flags & HA_SPATIAL))
packet->append(STRING_WITH_LEN(" USING RTREE"));
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
table->s->key_block_size != key_info->block_size)
{
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
end= longlong10_to_str(key_info->block_size, buff, 10);
packet->append(buff, (uint) (end - buff));
}
}
}
void void
view_store_options(THD *thd, TABLE_LIST *table, String *buff) view_store_options(THD *thd, TABLE_LIST *table, String *buff)
{ {
......
...@@ -231,10 +231,9 @@ static int mysql_copy_key_list(List<Key> *orig_key, ...@@ -231,10 +231,9 @@ static int mysql_copy_key_list(List<Key> *orig_key,
} }
} }
if (!(temp_key= new Key(prep_key->type, prep_key->name, if (!(temp_key= new Key(prep_key->type, prep_key->name,
prep_key->algorithm, &prep_key->key_info,
prep_key->generated, prep_key->generated,
prep_columns, prep_columns)))
prep_key->parser_name)))
{ {
mem_alloc_error(sizeof(Key)); mem_alloc_error(sizeof(Key));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
...@@ -2495,14 +2494,16 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -2495,14 +2494,16 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
break; break;
} }
switch(key->type){ switch (key->type) {
case Key::MULTIPLE: case Key::MULTIPLE:
key_info->flags= 0; key_info->flags= 0;
break; break;
case Key::FULLTEXT: case Key::FULLTEXT:
key_info->flags= HA_FULLTEXT; key_info->flags= HA_FULLTEXT;
if ((key_info->parser_name= key->parser_name)) if ((key_info->parser_name= &key->key_info.parser_name)->str)
key_info->flags|= HA_USES_PARSER; key_info->flags|= HA_USES_PARSER;
else
key_info->parser_name= 0;
break; break;
case Key::SPATIAL: case Key::SPATIAL:
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
...@@ -2526,7 +2527,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -2526,7 +2527,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
key_info->key_parts=(uint8) key->columns.elements; key_info->key_parts=(uint8) key->columns.elements;
key_info->key_part=key_part_info; key_info->key_part=key_part_info;
key_info->usable_key_parts= key_number; key_info->usable_key_parts= key_number;
key_info->algorithm=key->algorithm; key_info->algorithm= key->key_info.algorithm;
if (key->type == Key::FULLTEXT) if (key->type == Key::FULLTEXT)
{ {
...@@ -2572,6 +2573,18 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -2572,6 +2573,18 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
#endif #endif
} }
/* Take block size from key part or table part */
/*
TODO: Add warning if block size changes. We can't do it here, as
this may depend on the size of the key
*/
key_info->block_size= (key->key_info.block_size ?
key->key_info.block_size :
create_info->key_block_size);
if (key_info->block_size)
key_info->flags|= HA_USES_BLOCK_SIZE;
List_iterator<key_part_spec> cols(key->columns), cols2(key->columns); List_iterator<key_part_spec> cols(key->columns), cols2(key->columns);
CHARSET_INFO *ft_key_charset=0; // for FULLTEXT CHARSET_INFO *ft_key_charset=0; // for FULLTEXT
for (uint column_nr=0 ; (column=cols++) ; column_nr++) for (uint column_nr=0 ; (column=cols++) ; column_nr++)
...@@ -5142,6 +5155,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -5142,6 +5155,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
create_info->avg_row_length= table->s->avg_row_length; create_info->avg_row_length= table->s->avg_row_length;
if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
create_info->default_table_charset= table->s->table_charset; create_info->default_table_charset= table->s->table_charset;
if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
create_info->key_block_size= table->s->key_block_size;
restore_record(table, s->default_values); // Empty record for DEFAULT restore_record(table, s->default_values); // Empty record for DEFAULT
List_iterator<Alter_drop> drop_it(alter_info->drop_list); List_iterator<Alter_drop> drop_it(alter_info->drop_list);
...@@ -5344,6 +5359,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -5344,6 +5359,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
key_part_length)); key_part_length));
} }
if (key_parts.elements) if (key_parts.elements)
{
KEY_CREATE_INFO key_create_info;
bzero((char*) &key_create_info, sizeof(key_create_info));
key_create_info.algorithm= key_info->algorithm;
if (key_info->flags & HA_USES_BLOCK_SIZE)
key_create_info.block_size= key_info->block_size;
if (key_info->flags & HA_USES_PARSER)
key_create_info.parser_name= *key_info->parser_name;
key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL : key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL :
(key_info->flags & HA_NOSAME ? (key_info->flags & HA_NOSAME ?
(!my_strcasecmp(system_charset_info, (!my_strcasecmp(system_charset_info,
...@@ -5352,11 +5377,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -5352,11 +5377,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
(key_info->flags & HA_FULLTEXT ? (key_info->flags & HA_FULLTEXT ?
Key::FULLTEXT : Key::MULTIPLE)), Key::FULLTEXT : Key::MULTIPLE)),
key_name, key_name,
key_info->algorithm, &key_create_info,
test(key_info->flags & HA_GENERATED_KEY), test(key_info->flags & HA_GENERATED_KEY),
key_parts, key_parts));
key_info->flags & HA_USES_PARSER ? }
&key_info->parser->name : 0));
} }
{ {
Key *key; Key *key;
...@@ -5452,9 +5476,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -5452,9 +5476,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
while ((prep_col= prep_col_it++)) while ((prep_col= prep_col_it++))
prep_columns.push_back(new key_part_spec(*prep_col)); prep_columns.push_back(new key_part_spec(*prep_col));
prepared_key_list.push_back(new Key(prep_key->type, prep_key->name, prepared_key_list.push_back(new Key(prep_key->type, prep_key->name,
prep_key->algorithm, &prep_key->key_info,
prep_key->generated, prep_columns, prep_key->generated, prep_columns));
prep_key->parser_name));
} }
/* Create the prepared information. */ /* Create the prepared information. */
......
...@@ -364,6 +364,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -364,6 +364,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token JOIN_SYM %token JOIN_SYM
%token KEYS %token KEYS
%token KEY_SYM %token KEY_SYM
%token KEY_BLOCK_SIZE
%token KILL_SYM %token KILL_SYM
%token LANGUAGE_SYM %token LANGUAGE_SYM
%token LAST_INSERT_ID %token LAST_INSERT_ID
...@@ -730,7 +731,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -730,7 +731,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem
%type <lex_str_ptr> %type <lex_str_ptr>
opt_table_alias opt_fulltext_parser opt_table_alias
%type <table> %type <table>
table_ident table_ident_nodb references xid table_ident table_ident_nodb references xid
...@@ -795,7 +796,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -795,7 +796,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
key_type opt_unique_or_fulltext constraint_key_type key_type opt_unique_or_fulltext constraint_key_type
%type <key_alg> %type <key_alg>
key_alg opt_btree_or_rtree opt_btree_or_rtree
%type <string_list> %type <string_list>
key_usage_list using_list key_usage_list using_list
...@@ -886,6 +887,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -886,6 +887,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
view_suid view_tail view_list_opt view_list view_select view_suid view_tail view_list_opt view_list view_select
view_check_option trigger_tail sp_tail view_check_option trigger_tail sp_tail
install uninstall partition_entry binlog_base64_event install uninstall partition_entry binlog_base64_event
init_key_options key_options key_opts key_opt
END_OF_INPUT END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
...@@ -1220,11 +1222,13 @@ create: ...@@ -1220,11 +1222,13 @@ create:
} }
create2 create2
{ Lex->current_select= &Lex->select_lex; } { Lex->current_select= &Lex->select_lex; }
| CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON
table_ident
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command= SQLCOM_CREATE_INDEX; lex->sql_command= SQLCOM_CREATE_INDEX;
if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL, if (!lex->current_select->add_table_to_list(lex->thd, $7,
NULL,
TL_OPTION_UPDATING)) TL_OPTION_UPDATING))
YYABORT; YYABORT;
lex->create_list.empty(); lex->create_list.empty();
...@@ -1232,15 +1236,16 @@ create: ...@@ -1232,15 +1236,16 @@ create:
lex->col_list.empty(); lex->col_list.empty();
lex->change=NullS; lex->change=NullS;
} }
'(' key_list ')' opt_fulltext_parser '(' key_list ')' key_options
{ {
LEX *lex=Lex; LEX *lex=Lex;
if ($2 != Key::FULLTEXT && $12) if ($2 != Key::FULLTEXT && lex->key_info.parser_name.str)
{ {
yyerror(ER(ER_SYNTAX_ERROR)); yyerror(ER(ER_SYNTAX_ERROR));
YYABORT; YYABORT;
} }
lex->key_list.push_back(new Key($2,$4.str,$5,0,lex->col_list,$12)); lex->key_list.push_back(new Key($2, $4.str, &lex->key_info, 0,
lex->col_list));
lex->col_list.empty(); lex->col_list.empty();
} }
| CREATE DATABASE opt_if_not_exists ident | CREATE DATABASE opt_if_not_exists ident
...@@ -3890,6 +3895,11 @@ create_table_option: ...@@ -3890,6 +3895,11 @@ create_table_option:
| STORAGE_SYM DISK_SYM {Lex->create_info.store_on_disk= TRUE;} | STORAGE_SYM DISK_SYM {Lex->create_info.store_on_disk= TRUE;}
| STORAGE_SYM MEMORY_SYM {Lex->create_info.store_on_disk= FALSE;} | STORAGE_SYM MEMORY_SYM {Lex->create_info.store_on_disk= FALSE;}
| CONNECTION_SYM opt_equal TEXT_STRING_sys { Lex->create_info.connect_string.str= $3.str; Lex->create_info.connect_string.length= $3.length; Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION; } | CONNECTION_SYM opt_equal TEXT_STRING_sys { Lex->create_info.connect_string.str= $3.str; Lex->create_info.connect_string.length= $3.length; Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION; }
| KEY_BLOCK_SIZE opt_equal ulong_num
{
Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
Lex->create_info.key_block_size= $3;
}
; ;
default_charset: default_charset:
...@@ -3983,23 +3993,25 @@ column_def: ...@@ -3983,23 +3993,25 @@ column_def:
; ;
key_def: key_def:
key_type opt_ident key_alg '(' key_list ')' opt_fulltext_parser key_type opt_ident key_alg '(' key_list ')' key_options
{ {
LEX *lex=Lex; LEX *lex=Lex;
if ($1 != Key::FULLTEXT && $7) if ($1 != Key::FULLTEXT && lex->key_info.parser_name.str)
{ {
yyerror(ER(ER_SYNTAX_ERROR)); yyerror(ER(ER_SYNTAX_ERROR));
YYABORT; YYABORT;
} }
lex->key_list.push_back(new Key($1,$2, $3, 0, lex->col_list, $7)); lex->key_list.push_back(new Key($1,$2, &lex->key_info, 0,
lex->col_list));
lex->col_list.empty(); /* Alloced by sql_alloc */ lex->col_list.empty(); /* Alloced by sql_alloc */
} }
| opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')' | opt_constraint constraint_key_type opt_ident key_alg
'(' key_list ')' key_options
{ {
LEX *lex=Lex; LEX *lex=Lex;
const char *key_name= $3 ? $3:$1; const char *key_name= $3 ? $3 : $1;
lex->key_list.push_back(new Key($2, key_name, $4, 0, lex->key_list.push_back(new Key($2, key_name, &lex->key_info, 0,
lex->col_list)); lex->col_list));
lex->col_list.empty(); /* Alloced by sql_alloc */ lex->col_list.empty(); /* Alloced by sql_alloc */
} }
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
...@@ -4012,7 +4024,7 @@ key_def: ...@@ -4012,7 +4024,7 @@ key_def:
lex->fk_update_opt, lex->fk_update_opt,
lex->fk_match_option)); lex->fk_match_option));
lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1, lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1,
HA_KEY_ALG_UNDEF, 1, &default_key_create_info, 1,
lex->col_list)); lex->col_list));
lex->col_list.empty(); /* Alloced by sql_alloc */ lex->col_list.empty(); /* Alloced by sql_alloc */
...@@ -4029,20 +4041,6 @@ key_def: ...@@ -4029,20 +4041,6 @@ key_def:
} }
; ;
opt_fulltext_parser:
/* empty */ { $$= (LEX_STRING *)0; }
| WITH PARSER_SYM IDENT_sys
{
if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN))
$$= (LEX_STRING *)sql_memdup(&$3, sizeof(LEX_STRING));
else
{
my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str);
YYABORT;
}
}
;
opt_check_constraint: opt_check_constraint:
/* empty */ /* empty */
| check_constraint | check_constraint
...@@ -4516,10 +4514,50 @@ opt_unique_or_fulltext: ...@@ -4516,10 +4514,50 @@ opt_unique_or_fulltext:
} }
; ;
init_key_options:
{
Lex->key_info= default_key_create_info;
}
;
/*
For now, key_alg initializies lex->key_info.
In the future, when all key options are after key definition,
we can remove key_alg and move init_key_options to key_options
*/
key_alg: key_alg:
/* empty */ { $$= HA_KEY_ALG_UNDEF; } /* empty */ init_key_options
| USING opt_btree_or_rtree { $$= $2; } | init_key_options key_opts
| TYPE_SYM opt_btree_or_rtree { $$= $2; }; ;
key_options:
/* empty */ {}
| key_opts
;
key_opts:
key_opt
| key_opts key_opt
;
key_opt:
USING opt_btree_or_rtree { Lex->key_info.algorithm= $2; }
| TYPE_SYM opt_btree_or_rtree { Lex->key_info.algorithm= $2; }
| KEY_BLOCK_SIZE opt_equal ulong_num
{ Lex->key_info.block_size= $3; }
| WITH PARSER_SYM IDENT_sys
{
if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN))
Lex->key_info.parser_name= $3;
else
{
my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str);
YYABORT;
}
}
;
opt_btree_or_rtree: opt_btree_or_rtree:
BTREE_SYM { $$= HA_KEY_ALG_BTREE; } BTREE_SYM { $$= HA_KEY_ALG_BTREE; }
...@@ -9348,7 +9386,7 @@ keyword_sp: ...@@ -9348,7 +9386,7 @@ keyword_sp:
| ISSUER_SYM {} | ISSUER_SYM {}
| INNOBASE_SYM {} | INNOBASE_SYM {}
| INSERT_METHOD {} | INSERT_METHOD {}
| RELAY_THREAD {} | KEY_BLOCK_SIZE {}
| LAST_SYM {} | LAST_SYM {}
| LEAVES {} | LEAVES {}
| LESS_SYM {} | LESS_SYM {}
...@@ -9435,6 +9473,7 @@ keyword_sp: ...@@ -9435,6 +9473,7 @@ keyword_sp:
| REDUNDANT_SYM {} | REDUNDANT_SYM {}
| RELAY_LOG_FILE_SYM {} | RELAY_LOG_FILE_SYM {}
| RELAY_LOG_POS_SYM {} | RELAY_LOG_POS_SYM {}
| RELAY_THREAD {}
| RELOAD {} | RELOAD {}
| REORGANIZE_SYM {} | REORGANIZE_SYM {}
| REPEATABLE_SYM {} | REPEATABLE_SYM {}
......
...@@ -86,6 +86,7 @@ typedef struct st_key { ...@@ -86,6 +86,7 @@ typedef struct st_key {
uint key_parts; /* How many key_parts */ uint key_parts; /* How many key_parts */
uint extra_length; uint extra_length;
uint usable_key_parts; /* Should normally be = key_parts */ uint usable_key_parts; /* Should normally be = key_parts */
uint block_size;
enum ha_key_alg algorithm; enum ha_key_alg algorithm;
/* /*
Note that parser is used when the table is opened for use, and Note that parser is used when the table is opened for use, and
......
...@@ -535,6 +535,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, ...@@ -535,6 +535,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
keyinfo->key_length= (uint) uint2korr(strpos+2); keyinfo->key_length= (uint) uint2korr(strpos+2);
keyinfo->key_parts= (uint) strpos[4]; keyinfo->key_parts= (uint) strpos[4];
keyinfo->algorithm= (enum ha_key_alg) strpos[5]; keyinfo->algorithm= (enum ha_key_alg) strpos[5];
keyinfo->block_size= uint2korr(strpos+6);
strpos+=8; strpos+=8;
} }
else else
...@@ -706,6 +707,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, ...@@ -706,6 +707,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
} }
my_free(buff, MYF(0)); my_free(buff, MYF(0));
} }
share->key_block_size= uint2korr(head+62);
error=4; error=4;
extra_rec_buf_length= uint2korr(head+59); extra_rec_buf_length= uint2korr(head+59);
...@@ -2065,6 +2067,11 @@ File create_frm(THD *thd, const char *name, const char *db, ...@@ -2065,6 +2067,11 @@ File create_frm(THD *thd, const char *name, const char *db,
tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store
int4store(fileinfo+51, tmp); int4store(fileinfo+51, tmp);
int4store(fileinfo+55, create_info->extra_size); int4store(fileinfo+55, create_info->extra_size);
/*
59-60 is reserved for extra_rec_buf_length,
61 for default_part_db_type
*/
int2store(fileinfo+62, create_info->key_block_size);
bzero(fill,IO_SIZE); bzero(fill,IO_SIZE);
for (; length > IO_SIZE ; length-= IO_SIZE) for (; length > IO_SIZE ; length-= IO_SIZE)
{ {
......
...@@ -160,6 +160,7 @@ typedef struct st_table_share ...@@ -160,6 +160,7 @@ typedef struct st_table_share
uint ref_count; /* How many TABLE objects uses this */ uint ref_count; /* How many TABLE objects uses this */
uint open_count; /* Number of tables in open list */ uint open_count; /* Number of tables in open list */
uint blob_ptr_size; /* 4 or 8 */ uint blob_ptr_size; /* 4 or 8 */
uint key_block_size; /* create key_block_size, if used */
uint null_bytes, last_null_bit_pos; uint null_bytes, last_null_bit_pos;
uint fields; /* Number of fields */ uint fields; /* Number of fields */
uint rec_buff_length; /* Size of table->record[] buffer */ uint rec_buff_length; /* Size of table->record[] buffer */
......
...@@ -338,9 +338,9 @@ err_handler: ...@@ -338,9 +338,9 @@ err_handler:
/* Pack screens to a screen for save in a form-file */ /* Pack screens to a screen for save in a form-file */
static uchar * pack_screens(List<create_field> &create_fields, static uchar *pack_screens(List<create_field> &create_fields,
uint *info_length, uint *screens, uint *info_length, uint *screens,
bool small_file) bool small_file)
{ {
reg1 uint i; reg1 uint i;
uint row,start_row,end_row,fields_on_screen; uint row,start_row,end_row,fields_on_screen;
...@@ -431,7 +431,7 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, ...@@ -431,7 +431,7 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo,
int2store(pos+2,key->key_length); int2store(pos+2,key->key_length);
pos[4]= (uchar) key->key_parts; pos[4]= (uchar) key->key_parts;
pos[5]= (uchar) key->algorithm; pos[5]= (uchar) key->algorithm;
pos[6]=pos[7]=0; // For the future int2store(pos+6, key->block_size);
pos+=8; pos+=8;
key_parts+=key->key_parts; key_parts+=key->key_parts;
DBUG_PRINT("loop",("flags: %d key_parts: %d at 0x%lx", DBUG_PRINT("loop",("flags: %d key_parts: %d at 0x%lx",
......
...@@ -54,6 +54,7 @@ int main(int argc, char *argv[]) ...@@ -54,6 +54,7 @@ int main(int argc, char *argv[])
/* Define a key over the first column */ /* Define a key over the first column */
keyinfo[0].seg=keyseg; keyinfo[0].seg=keyseg;
keyinfo[0].keysegs=1; keyinfo[0].keysegs=1;
keyinfo[0].block_length= 0; /* Default block length */
keyinfo[0].seg[0].type= HA_KEYTYPE_TEXT; keyinfo[0].seg[0].type= HA_KEYTYPE_TEXT;
keyinfo[0].seg[0].flag= HA_BLOB_PART; keyinfo[0].seg[0].flag= HA_BLOB_PART;
keyinfo[0].seg[0].start=recinfo[0].length; keyinfo[0].seg[0].start=recinfo[0].length;
......
...@@ -89,6 +89,7 @@ static int run_test(const char *filename) ...@@ -89,6 +89,7 @@ static int run_test(const char *filename)
/* Define a key over the first column */ /* Define a key over the first column */
keyinfo[0].seg=keyseg; keyinfo[0].seg=keyseg;
keyinfo[0].keysegs=1; keyinfo[0].keysegs=1;
keyinfo[0].block_length= 0; /* Default block length */
keyinfo[0].seg[0].type= key_type; keyinfo[0].seg[0].type= key_type;
keyinfo[0].seg[0].flag= (key_field == FIELD_BLOB) ? HA_BLOB_PART: keyinfo[0].seg[0].flag= (key_field == FIELD_BLOB) ? HA_BLOB_PART:
(key_field == FIELD_VARCHAR) ? HA_VAR_LENGTH_PART:0; (key_field == FIELD_VARCHAR) ? HA_VAR_LENGTH_PART:0;
......
...@@ -358,7 +358,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) ...@@ -358,7 +358,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
puts("- check key delete-chain"); puts("- check key delete-chain");
param->key_file_blocks=info->s->base.keystart; param->key_file_blocks=info->s->base.keystart;
for (key=0 ; key < info->s->state.header.max_block_size ; key++) for (key=0 ; key < info->s->state.header.max_block_size_index ; key++)
if (check_k_link(param,info,key)) if (check_k_link(param,info,key))
{ {
if (param->testflag & T_VERBOSE) puts(""); if (param->testflag & T_VERBOSE) puts("");
...@@ -1411,7 +1411,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, ...@@ -1411,7 +1411,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
share->state.key_root[i]= HA_OFFSET_ERROR; share->state.key_root[i]= HA_OFFSET_ERROR;
/* Drop the delete chain. */ /* Drop the delete chain. */
for (i=0 ; i < share->state.header.max_block_size ; i++) for (i=0 ; i < share->state.header.max_block_size_index ; i++)
share->state.key_del[i]= HA_OFFSET_ERROR; share->state.key_del[i]= HA_OFFSET_ERROR;
/* /*
...@@ -1795,7 +1795,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) ...@@ -1795,7 +1795,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
for (key=0 ; key < info->s->base.keys ; key++) for (key=0 ; key < info->s->base.keys ; key++)
info->s->state.key_root[key]=index_pos[key]; info->s->state.key_root[key]=index_pos[key];
for (key=0 ; key < info->s->state.header.max_block_size ; key++) for (key=0 ; key < info->s->state.header.max_block_size_index ; key++)
info->s->state.key_del[key]= HA_OFFSET_ERROR; info->s->state.key_del[key]= HA_OFFSET_ERROR;
info->s->state.changed&= ~STATE_NOT_SORTED_PAGES; info->s->state.changed&= ~STATE_NOT_SORTED_PAGES;
...@@ -2095,7 +2095,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, ...@@ -2095,7 +2095,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
/* Clear the pointers to the given rows */ /* Clear the pointers to the given rows */
for (i=0 ; i < share->base.keys ; i++) for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR; share->state.key_root[i]= HA_OFFSET_ERROR;
for (i=0 ; i < share->state.header.max_block_size ; i++) for (i=0 ; i < share->state.header.max_block_size_index ; i++)
share->state.key_del[i]= HA_OFFSET_ERROR; share->state.key_del[i]= HA_OFFSET_ERROR;
info->state->key_file_length=share->base.keystart; info->state->key_file_length=share->base.keystart;
} }
...@@ -2463,7 +2463,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, ...@@ -2463,7 +2463,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
/* Clear the pointers to the given rows */ /* Clear the pointers to the given rows */
for (i=0 ; i < share->base.keys ; i++) for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR; share->state.key_root[i]= HA_OFFSET_ERROR;
for (i=0 ; i < share->state.header.max_block_size ; i++) for (i=0 ; i < share->state.header.max_block_size_index ; i++)
share->state.key_del[i]= HA_OFFSET_ERROR; share->state.key_del[i]= HA_OFFSET_ERROR;
info->state->key_file_length=share->base.keystart; info->state->key_file_length=share->base.keystart;
} }
......
...@@ -28,9 +28,9 @@ ...@@ -28,9 +28,9 @@
#endif #endif
#include <m_ctype.h> #include <m_ctype.h>
/* /*
** Old options is used when recreating database, from isamchk Old options is used when recreating database, from myisamchk
*/ */
int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
uint columns, MI_COLUMNDEF *recinfo, uint columns, MI_COLUMNDEF *recinfo,
...@@ -45,6 +45,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -45,6 +45,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
key_length,info_length,key_segs,options,min_key_length_skip, key_length,info_length,key_segs,options,min_key_length_skip,
base_pos,long_varchar_count,varchar_length, base_pos,long_varchar_count,varchar_length,
max_key_block_length,unique_key_parts,fulltext_keys,offset; max_key_block_length,unique_key_parts,fulltext_keys,offset;
uint aligned_key_start, block_length;
ulong reclength, real_reclength,min_pack_length; ulong reclength, real_reclength,min_pack_length;
char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr; char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
ulong pack_reclength; ulong pack_reclength;
...@@ -428,8 +429,16 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -428,8 +429,16 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
key_segs) key_segs)
share.state.rec_per_key_part[key_segs-1]=1L; share.state.rec_per_key_part[key_segs-1]=1L;
length+=key_length; length+=key_length;
/* Get block length for key, if defined by user */
block_length= (keydef->block_length ?
my_round_up_to_next_power(keydef->block_length) :
myisam_block_size);
block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
keydef->block_length= MI_BLOCK_SIZE(length-real_length_diff, keydef->block_length= MI_BLOCK_SIZE(length-real_length_diff,
pointer,MI_MAX_KEYPTR_SIZE); pointer,MI_MAX_KEYPTR_SIZE,
block_length);
if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH || if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
length >= MI_MAX_KEY_BUFF) length >= MI_MAX_KEY_BUFF)
{ {
...@@ -485,7 +494,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -485,7 +494,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
mi_int2store(share.state.header.base_pos,base_pos); mi_int2store(share.state.header.base_pos,base_pos);
share.state.header.language= (ci->language ? share.state.header.language= (ci->language ?
ci->language : default_charset_info->number); ci->language : default_charset_info->number);
share.state.header.max_block_size=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH; share.state.header.max_block_size_index= max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
share.state.dellink = HA_OFFSET_ERROR; share.state.dellink = HA_OFFSET_ERROR;
share.state.process= (ulong) getpid(); share.state.process= (ulong) getpid();
...@@ -512,8 +521,12 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -512,8 +521,12 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
mi_int2store(share.state.header.unique_key_parts,unique_key_parts); mi_int2store(share.state.header.unique_key_parts,unique_key_parts);
mi_set_all_keys_active(share.state.key_map, keys); mi_set_all_keys_active(share.state.key_map, keys);
share.base.keystart = share.state.state.key_file_length= aligned_key_start= my_round_up_to_next_power(max_key_block_length ?
MY_ALIGN(info_length, myisam_block_size); max_key_block_length :
myisam_block_size);
share.base.keystart= share.state.state.key_file_length=
MY_ALIGN(info_length, aligned_key_start);
share.base.max_key_block_length=max_key_block_length; share.base.max_key_block_length=max_key_block_length;
share.base.max_key_length=ALIGN_SIZE(max_key_length+4); share.base.max_key_length=ALIGN_SIZE(max_key_length+4);
share.base.records=ci->max_rows; share.base.records=ci->max_rows;
......
...@@ -295,7 +295,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -295,7 +295,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
&share->data_file_name,strlen(data_name)+1, &share->data_file_name,strlen(data_name)+1,
&share->state.key_root,keys*sizeof(my_off_t), &share->state.key_root,keys*sizeof(my_off_t),
&share->state.key_del, &share->state.key_del,
(share->state.header.max_block_size*sizeof(my_off_t)), (share->state.header.max_block_size_index*sizeof(my_off_t)),
#ifdef THREAD #ifdef THREAD
&share->key_root_lock,sizeof(rw_lock_t)*keys, &share->key_root_lock,sizeof(rw_lock_t)*keys,
#endif #endif
...@@ -310,7 +310,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -310,7 +310,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
(char*) key_root, sizeof(my_off_t)*keys); (char*) key_root, sizeof(my_off_t)*keys);
memcpy((char*) share->state.key_del, memcpy((char*) share->state.key_del,
(char*) key_del, (sizeof(my_off_t) * (char*) key_del, (sizeof(my_off_t) *
share->state.header.max_block_size)); share->state.header.max_block_size_index));
strmov(share->unique_file_name, name_buff); strmov(share->unique_file_name, name_buff);
share->unique_name_length= strlen(name_buff); share->unique_name_length= strlen(name_buff);
strmov(share->index_file_name, index_name); strmov(share->index_file_name, index_name);
...@@ -820,7 +820,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite) ...@@ -820,7 +820,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE]; uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
uchar *ptr=buff; uchar *ptr=buff;
uint i, keys= (uint) state->header.keys, uint i, keys= (uint) state->header.keys,
key_blocks=state->header.max_block_size; key_blocks=state->header.max_block_size_index;
DBUG_ENTER("mi_state_info_write"); DBUG_ENTER("mi_state_info_write");
memcpy_fixed(ptr,&state->header,sizeof(state->header)); memcpy_fixed(ptr,&state->header,sizeof(state->header));
...@@ -886,7 +886,7 @@ uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state) ...@@ -886,7 +886,7 @@ uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
ptr +=sizeof(state->header); ptr +=sizeof(state->header);
keys=(uint) state->header.keys; keys=(uint) state->header.keys;
key_parts=mi_uint2korr(state->header.key_parts); key_parts=mi_uint2korr(state->header.key_parts);
key_blocks=state->header.max_block_size; key_blocks=state->header.max_block_size_index;
state->open_count = mi_uint2korr(ptr); ptr +=2; state->open_count = mi_uint2korr(ptr); ptr +=2;
state->changed= (bool) *ptr++; state->changed= (bool) *ptr++;
...@@ -1059,7 +1059,7 @@ char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef) ...@@ -1059,7 +1059,7 @@ char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef)
keydef->keylength = mi_uint2korr(ptr); ptr +=2; keydef->keylength = mi_uint2korr(ptr); ptr +=2;
keydef->minlength = mi_uint2korr(ptr); ptr +=2; keydef->minlength = mi_uint2korr(ptr); ptr +=2;
keydef->maxlength = mi_uint2korr(ptr); ptr +=2; keydef->maxlength = mi_uint2korr(ptr); ptr +=2;
keydef->block_size = keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1; keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
keydef->underflow_block_length=keydef->block_length/3; keydef->underflow_block_length=keydef->block_length/3;
keydef->version = 0; /* Not saved */ keydef->version = 0; /* Not saved */
keydef->parser = &ft_default_parser; keydef->parser = &ft_default_parser;
......
...@@ -112,8 +112,8 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos, ...@@ -112,8 +112,8 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos,
DBUG_ENTER("_mi_dispose"); DBUG_ENTER("_mi_dispose");
DBUG_PRINT("enter",("pos: %ld", (long) pos)); DBUG_PRINT("enter",("pos: %ld", (long) pos));
old_link=info->s->state.key_del[keyinfo->block_size]; old_link= info->s->state.key_del[keyinfo->block_size_index];
info->s->state.key_del[keyinfo->block_size]=pos; info->s->state.key_del[keyinfo->block_size_index]= pos;
mi_sizestore(buff,old_link); mi_sizestore(buff,old_link);
info->s->state.changed|= STATE_NOT_SORTED_PAGES; info->s->state.changed|= STATE_NOT_SORTED_PAGES;
DBUG_RETURN(key_cache_write(info->s->key_cache, DBUG_RETURN(key_cache_write(info->s->key_cache,
...@@ -132,7 +132,8 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level) ...@@ -132,7 +132,8 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level)
char buff[8]; char buff[8];
DBUG_ENTER("_mi_new"); DBUG_ENTER("_mi_new");
if ((pos=info->s->state.key_del[keyinfo->block_size]) == HA_OFFSET_ERROR) if ((pos= info->s->state.key_del[keyinfo->block_size_index]) ==
HA_OFFSET_ERROR)
{ {
if (info->state->key_file_length >= if (info->state->key_file_length >=
info->s->base.max_key_file_length - keyinfo->block_length) info->s->base.max_key_file_length - keyinfo->block_length)
...@@ -152,7 +153,7 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level) ...@@ -152,7 +153,7 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level)
(uint) keyinfo->block_length,0)) (uint) keyinfo->block_length,0))
pos= HA_OFFSET_ERROR; pos= HA_OFFSET_ERROR;
else else
info->s->state.key_del[keyinfo->block_size]=mi_sizekorr(buff); info->s->state.key_del[keyinfo->block_size_index]= mi_sizekorr(buff);
} }
info->s->state.changed|= STATE_NOT_SORTED_PAGES; info->s->state.changed|= STATE_NOT_SORTED_PAGES;
DBUG_PRINT("exit",("Pos: %ld",(long) pos)); DBUG_PRINT("exit",("Pos: %ld",(long) pos));
......
...@@ -95,6 +95,7 @@ static int run_test(const char *filename) ...@@ -95,6 +95,7 @@ static int run_test(const char *filename)
/* Define a key over the first column */ /* Define a key over the first column */
keyinfo[0].seg=keyseg; keyinfo[0].seg=keyseg;
keyinfo[0].keysegs=1; keyinfo[0].keysegs=1;
keyinfo[0].block_length= 0; /* Default block length */
keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
keyinfo[0].seg[0].type= key_type; keyinfo[0].seg[0].type= key_type;
keyinfo[0].seg[0].flag= pack_seg; keyinfo[0].seg[0].flag= pack_seg;
......
...@@ -95,6 +95,7 @@ int main(int argc, char *argv[]) ...@@ -95,6 +95,7 @@ int main(int argc, char *argv[])
keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
keyinfo[0].keysegs=1; keyinfo[0].keysegs=1;
keyinfo[0].flag = pack_type; keyinfo[0].flag = pack_type;
keyinfo[0].block_length= 0; /* Default block length */
keyinfo[1].seg= &glob_keyseg[1][0]; keyinfo[1].seg= &glob_keyseg[1][0];
keyinfo[1].seg[0].start=7; keyinfo[1].seg[0].start=7;
keyinfo[1].seg[0].length=6; keyinfo[1].seg[0].length=6;
...@@ -111,6 +112,7 @@ int main(int argc, char *argv[]) ...@@ -111,6 +112,7 @@ int main(int argc, char *argv[])
keyinfo[1].key_alg=HA_KEY_ALG_BTREE; keyinfo[1].key_alg=HA_KEY_ALG_BTREE;
keyinfo[1].keysegs=2; keyinfo[1].keysegs=2;
keyinfo[1].flag =0; keyinfo[1].flag =0;
keyinfo[1].block_length= MI_MIN_KEY_BLOCK_LENGTH; /* Diff blocklength */
keyinfo[2].seg= &glob_keyseg[2][0]; keyinfo[2].seg= &glob_keyseg[2][0];
keyinfo[2].seg[0].start=12; keyinfo[2].seg[0].start=12;
keyinfo[2].seg[0].length=8; keyinfo[2].seg[0].length=8;
...@@ -121,6 +123,7 @@ int main(int argc, char *argv[]) ...@@ -121,6 +123,7 @@ int main(int argc, char *argv[])
keyinfo[2].key_alg=HA_KEY_ALG_BTREE; keyinfo[2].key_alg=HA_KEY_ALG_BTREE;
keyinfo[2].keysegs=1; keyinfo[2].keysegs=1;
keyinfo[2].flag =HA_NOSAME; keyinfo[2].flag =HA_NOSAME;
keyinfo[2].block_length= 0; /* Default block length */
keyinfo[3].seg= &glob_keyseg[3][0]; keyinfo[3].seg= &glob_keyseg[3][0];
keyinfo[3].seg[0].start=0; keyinfo[3].seg[0].start=0;
keyinfo[3].seg[0].length=reclength-(use_blob ? 8 : 0); keyinfo[3].seg[0].length=reclength-(use_blob ? 8 : 0);
...@@ -132,6 +135,7 @@ int main(int argc, char *argv[]) ...@@ -132,6 +135,7 @@ int main(int argc, char *argv[])
keyinfo[3].key_alg=HA_KEY_ALG_BTREE; keyinfo[3].key_alg=HA_KEY_ALG_BTREE;
keyinfo[3].keysegs=1; keyinfo[3].keysegs=1;
keyinfo[3].flag = pack_type; keyinfo[3].flag = pack_type;
keyinfo[3].block_length= 0; /* Default block length */
keyinfo[4].seg= &glob_keyseg[4][0]; keyinfo[4].seg= &glob_keyseg[4][0];
keyinfo[4].seg[0].start=0; keyinfo[4].seg[0].start=0;
keyinfo[4].seg[0].length=5; keyinfo[4].seg[0].length=5;
...@@ -143,6 +147,7 @@ int main(int argc, char *argv[]) ...@@ -143,6 +147,7 @@ int main(int argc, char *argv[])
keyinfo[4].key_alg=HA_KEY_ALG_BTREE; keyinfo[4].key_alg=HA_KEY_ALG_BTREE;
keyinfo[4].keysegs=1; keyinfo[4].keysegs=1;
keyinfo[4].flag = pack_type; keyinfo[4].flag = pack_type;
keyinfo[4].block_length= 0; /* Default block length */
keyinfo[5].seg= &glob_keyseg[5][0]; keyinfo[5].seg= &glob_keyseg[5][0];
keyinfo[5].seg[0].start=0; keyinfo[5].seg[0].start=0;
keyinfo[5].seg[0].length=4; keyinfo[5].seg[0].length=4;
...@@ -154,6 +159,7 @@ int main(int argc, char *argv[]) ...@@ -154,6 +159,7 @@ int main(int argc, char *argv[])
keyinfo[5].key_alg=HA_KEY_ALG_BTREE; keyinfo[5].key_alg=HA_KEY_ALG_BTREE;
keyinfo[5].keysegs=1; keyinfo[5].keysegs=1;
keyinfo[5].flag = pack_type; keyinfo[5].flag = pack_type;
keyinfo[5].block_length= 0; /* Default block length */
recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0; recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0;
recinfo[0].length=7; recinfo[0].length=7;
...@@ -813,7 +819,7 @@ end: ...@@ -813,7 +819,7 @@ end:
printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete); printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete);
if (rec_pointer_size) if (rec_pointer_size)
printf("Record pointer size: %d\n",rec_pointer_size); printf("Record pointer size: %d\n",rec_pointer_size);
printf("myisam_block_size: %u\n", myisam_block_size); printf("myisam_block_size: %lu\n", myisam_block_size);
if (key_cacheing) if (key_cacheing)
{ {
puts("Key cache used"); puts("Key cache used");
...@@ -914,13 +920,13 @@ static void get_options(int argc, char **argv) ...@@ -914,13 +920,13 @@ static void get_options(int argc, char **argv)
} }
break; break;
case 'e': /* myisam_block_length */ case 'e': /* myisam_block_length */
if ((myisam_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || if ((myisam_block_size= atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
myisam_block_size > MI_MAX_KEY_BLOCK_LENGTH) myisam_block_size > MI_MAX_KEY_BLOCK_LENGTH)
{ {
fprintf(stderr,"Wrong myisam_block_length\n"); fprintf(stderr,"Wrong myisam_block_length\n");
exit(1); exit(1);
} }
myisam_block_size=1 << my_bit_log2(myisam_block_size); myisam_block_size= my_round_up_to_next_power(myisam_block_size);
break; break;
case 'E': /* myisam_block_length */ case 'E': /* myisam_block_length */
if ((key_cache_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || if ((key_cache_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
...@@ -929,7 +935,7 @@ static void get_options(int argc, char **argv) ...@@ -929,7 +935,7 @@ static void get_options(int argc, char **argv)
fprintf(stderr,"Wrong key_cache_block_size\n"); fprintf(stderr,"Wrong key_cache_block_size\n");
exit(1); exit(1);
} }
key_cache_block_size=1 << my_bit_log2(key_cache_block_size); key_cache_block_size= my_round_up_to_next_power(key_cache_block_size);
break; break;
case 'f': case 'f':
if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS) if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS)
......
...@@ -76,6 +76,7 @@ int main(int argc,char **argv) ...@@ -76,6 +76,7 @@ int main(int argc,char **argv)
keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
keyinfo[0].keysegs=1; keyinfo[0].keysegs=1;
keyinfo[0].flag = (uint8) HA_PACK_KEY; keyinfo[0].flag = (uint8) HA_PACK_KEY;
keyinfo[0].block_length= 0; /* Default block length */
keyinfo[1].seg= &keyseg[1][0]; keyinfo[1].seg= &keyseg[1][0];
keyinfo[1].seg[0].start=8; keyinfo[1].seg[0].start=8;
keyinfo[1].seg[0].length=4; /* Long is always 4 in myisam */ keyinfo[1].seg[0].length=4; /* Long is always 4 in myisam */
...@@ -84,6 +85,7 @@ int main(int argc,char **argv) ...@@ -84,6 +85,7 @@ int main(int argc,char **argv)
keyinfo[1].key_alg=HA_KEY_ALG_BTREE; keyinfo[1].key_alg=HA_KEY_ALG_BTREE;
keyinfo[1].keysegs=1; keyinfo[1].keysegs=1;
keyinfo[1].flag =HA_NOSAME; keyinfo[1].flag =HA_NOSAME;
keyinfo[1].block_length= 0; /* Default block length */
recinfo[0].type=0; recinfo[0].type=0;
recinfo[0].length=sizeof(record.id); recinfo[0].length=sizeof(record.id);
......
...@@ -55,7 +55,7 @@ typedef struct st_mi_state_info ...@@ -55,7 +55,7 @@ typedef struct st_mi_state_info
uchar keys; /* number of keys in file */ uchar keys; /* number of keys in file */
uchar uniques; /* number of UNIQUE definitions */ uchar uniques; /* number of UNIQUE definitions */
uchar language; /* Language for indexes */ uchar language; /* Language for indexes */
uchar max_block_size; /* max keyblock size */ uchar max_block_size_index; /* max keyblock size */
uchar fulltext_keys; uchar fulltext_keys;
uchar not_used; /* To align to 8 */ uchar not_used; /* To align to 8 */
} header; } header;
...@@ -431,7 +431,7 @@ typedef struct st_mi_sort_param ...@@ -431,7 +431,7 @@ typedef struct st_mi_sort_param
#define MI_FOUND_WRONG_KEY 32738 /* Impossible value from ha_key_cmp */ #define MI_FOUND_WRONG_KEY 32738 /* Impossible value from ha_key_cmp */
#define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH) #define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH)
#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/myisam_block_size+1)*myisam_block_size) #define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer,block_size) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/(block_size)+1)*(block_size))
#define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */ #define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */
#define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */ #define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */
...@@ -742,6 +742,8 @@ my_bool check_table_is_closed(const char *name, const char *where); ...@@ -742,6 +742,8 @@ my_bool check_table_is_closed(const char *name, const char *where);
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup); int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
int mi_open_keyfile(MYISAM_SHARE *share); int mi_open_keyfile(MYISAM_SHARE *share);
void mi_setup_functions(register MYISAM_SHARE *share); void mi_setup_functions(register MYISAM_SHARE *share);
my_bool mi_dynmap_file(MI_INFO *info, my_off_t size);
void mi_remap_file(MI_INFO *info, my_off_t size);
/* Functions needed by mi_check */ /* Functions needed by mi_check */
volatile int *killed_ptr(MI_CHECK *param); volatile int *killed_ptr(MI_CHECK *param);
......
...@@ -2726,6 +2726,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) ...@@ -2726,6 +2726,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
break; break;
} }
case FIELD_LAST: case FIELD_LAST:
case FIELD_enum_val_count:
abort(); /* Impossible */ abort(); /* Impossible */
} }
start_pos+=count->max_zero_fill; start_pos+=count->max_zero_fill;
...@@ -2965,7 +2966,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length, ...@@ -2965,7 +2966,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
mi_clear_all_keys_active(share->state.key_map); mi_clear_all_keys_active(share->state.key_map);
for (key=0 ; key < share->base.keys ; key++) for (key=0 ; key < share->base.keys ; key++)
share->state.key_root[key]= HA_OFFSET_ERROR; share->state.key_root[key]= HA_OFFSET_ERROR;
for (key=0 ; key < share->state.header.max_block_size ; key++) for (key=0 ; key < share->state.header.max_block_size_index ; key++)
share->state.key_del[key]= HA_OFFSET_ERROR; share->state.key_del[key]= HA_OFFSET_ERROR;
isam_file->state->checksum=crc; /* Save crc here */ isam_file->state->checksum=crc; /* Save crc here */
share->changed=1; /* Force write of header */ share->changed=1; /* Force write of header */
......
...@@ -296,7 +296,7 @@ ctor_failure: ...@@ -296,7 +296,7 @@ ctor_failure:
TODO: TODO:
Add option --verify to mysqld to be able to change verification mode Add option --verify to mysqld to be able to change verification mode
*/ */
struct st_VioSSLAcceptorFd* struct st_VioSSLAcceptorFd *
new_VioSSLAcceptorFd(const char *key_file, new_VioSSLAcceptorFd(const char *key_file,
const char *cert_file, const char *cert_file,
const char *ca_file, const char *ca_file,
...@@ -387,4 +387,12 @@ ctor_failure: ...@@ -387,4 +387,12 @@ ctor_failure:
my_free((gptr) ptr,MYF(0)); my_free((gptr) ptr,MYF(0));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
void free_vio_ssl_acceptor_fd(struct st_VioSSLAcceptorFd *fd)
{
SSL_CTX_free(fd->ssl_context);
my_free((gptr) fd, MYF(0));
}
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment