diff options
39 files changed, 605 insertions, 168 deletions
diff --git a/include/my_base.h b/include/my_base.h index b9a806cc02f..e014f7c33b7 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -231,6 +231,7 @@ enum ha_base_keytype { #define HA_VAR_LENGTH_KEY 8 #define HA_NULL_PART_KEY 64 #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 */ /* Key has a part that can have end space. If this is an unique key diff --git a/include/my_sys.h b/include/my_sys.h index 41851b91cbd..c74f5307c88 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -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 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_ushort(ushort v); extern void my_sleep(ulong m_seconds); diff --git a/include/myisam.h b/include/myisam.h index 5116f48eeb5..db1a7bd984d 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -192,7 +192,7 @@ typedef struct st_mi_keydef /* Key definition with open & info */ uint16 keylength; /* Tot length of keyparts (auto) */ uint16 minlength; /* min 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 ftparser_nr; /* distinct ftparser number */ diff --git a/include/violite.h b/include/violite.h index b48f3724f5b..de2ae5386c0 100644 --- a/include/violite.h +++ b/include/violite.h @@ -132,6 +132,7 @@ struct st_VioSSLAcceptorFd const char *ca_file,const char *ca_path, const char *cipher); Vio *new_VioSSL(struct st_VioSSLAcceptorFd *fd, Vio *sd, int state); +void free_vio_ssl_acceptor_fd(struct st_VioSSLAcceptorFd *fd); #endif /* HAVE_OPENSSL */ #ifdef HAVE_SMEM diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 30ac61c80e8..dd665ba460e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1224,17 +1224,20 @@ sub environment_setup () { $ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set # We are nice and report a bit about our settings - print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; - print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; - print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; - print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; - print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n"; - print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n"; - print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n"; - print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\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"; + if (!$opt_extern) + { + print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; + print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; + print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; + print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; + print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n"; + print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n"; + print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n"; + print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\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 () { sub check_ssl_support () { - if ($opt_skip_ssl) + if ($opt_skip_ssl || $opt_extern) { mtr_report("Skipping SSL"); $opt_ssl_supported= 0; diff --git a/mysql-test/r/myisam-system.result b/mysql-test/r/myisam-system.result new file mode 100644 index 00000000000..e0629d955ae --- /dev/null +++ b/mysql-test/r/myisam-system.result @@ -0,0 +1,13 @@ +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' diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 60836408698..8976c98136b 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1344,18 +1344,6 @@ drop table t1; 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 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 global concurrent_insert=1; create table t1 (a int); @@ -1433,3 +1421,157 @@ create table t3 (c1 int) engine=myisam pack_keys=default; 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 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; diff --git a/mysql-test/t/myisam-system.test b/mysql-test/t/myisam-system.test new file mode 100644 index 00000000000..43fbaabf698 --- /dev/null +++ b/mysql-test/t/myisam-system.test @@ -0,0 +1,21 @@ +# +# 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; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 15533ca00e6..87a00399c23 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -727,23 +727,6 @@ create table t1 (v varchar(65535)); 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 # First with static record length # @@ -824,3 +807,72 @@ create table t3 (c1 int) engine=myisam pack_keys=default; create table t4 (c1 int) engine=myisam pack_keys=2; 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; diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index bf8986fe05b..1dab9a47ed8 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -262,15 +262,9 @@ static int keycache_pthread_cond_signal(pthread_cond_t *cond); #define keycache_pthread_cond_signal pthread_cond_signal #endif /* defined(KEYCACHE_DEBUG) */ -static uint next_power(uint value) +static inline uint next_power(uint value) { - uint old_value= 1; - while (value) - { - old_value= value; - value&= value-1; - } - return (old_value << 1); + return (uint) my_round_up_to_next_power((uint32) value) << 1; } diff --git a/mysys/my_bit.c b/mysys/my_bit.c index 01c9b5ea68d..6ef0e171695 100644 --- a/mysys/my_bit.c +++ b/mysys/my_bit.c @@ -76,3 +76,33 @@ uint my_count_bits_ushort(ushort 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 */ +} diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index ec39ee00efc..cb7aa889734 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -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) file->s->keyinfo[i].parser= (struct st_mysql_ftparser *)parser->plugin->info; + table->key_info[i].block_size= file->s->keyinfo[i].block_length; } return (0); } @@ -1368,7 +1369,7 @@ void ha_myisam::info(uint flag) sortkey= info.sortkey; ref_length= info.reflength; share->db_options_in_use= info.options; - block_size= myisam_block_size; + block_size= myisam_block_size; /* record block size */ /* Update share */ if (share->tmp_table == NO_TMP_TABLE) @@ -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 ? (pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) : pos->algorithm; + keydef[i].block_length= pos->block_size; + keydef[i].seg=keyseg; keydef[i].keysegs=pos->key_parts; for (j=0 ; j < pos->key_parts ; j++) diff --git a/sql/handler.cc b/sql/handler.cc index 808dd0841c5..5de25b969a8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -47,6 +47,8 @@ extern handlerton *sys_table_types[]; #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 handler *create_default(TABLE_SHARE *table); diff --git a/sql/handler.h b/sql/handler.h index 090ef1f9f30..8029930ce07 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -280,6 +280,7 @@ enum enum_binlog_command { #define HA_CREATE_USED_COMMENT (1L << 16) #define HA_CREATE_USED_PASSWORD (1L << 17) #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 #define MYSQL_XID_PREFIX "MySQLXid" @@ -653,6 +654,7 @@ typedef struct st_ha_create_information ulong table_options; ulong avg_row_length; ulong used_fields; + ulong key_block_size; SQL_LIST merge_list; handlerton *db_type; enum row_type row_type; @@ -666,6 +668,15 @@ typedef struct st_ha_create_information bool store_on_disk; /* 1 if table stored on disk */ } 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 as: create table functions, delete table functions, and alter table @@ -700,6 +711,7 @@ private: typedef struct st_savepoint SAVEPOINT; extern ulong savepoint_alloc_size; +extern KEY_CREATE_INFO default_key_create_info; /* Forward declaration for condition pushdown to storage engine */ typedef class Item COND; diff --git a/sql/item_func.h b/sql/item_func.h index ed5924e8fe1..a91d93be8c6 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -284,6 +284,7 @@ class Item_func_connection_id :public Item_int_func longlong value; public: + Item_func_connection_id() {} const char *func_name() const { return "connection_id"; } void fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); diff --git a/sql/lex.h b/sql/lex.h index 171f7a48980..555a68dc388 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -275,6 +275,7 @@ static SYMBOL symbols[] = { { "JOIN", SYM(JOIN_SYM)}, { "KEY", SYM(KEY_SYM)}, { "KEYS", SYM(KEYS)}, + { "KEY_BLOCK_SIZE", SYM(KEY_BLOCK_SIZE)}, { "KILL", SYM(KILL_SYM)}, { "LANGUAGE", SYM(LANGUAGE_SYM)}, { "LAST", SYM(LAST_SYM)}, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4de1e95d0f3..df91b0dbe64 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -742,6 +742,7 @@ static void clean_up_mutexes(void); static void wait_for_signal_thread_to_end(void); static int test_if_case_insensitive(const char *dir_name); static void create_pid_file(); +static void end_ssl(); #ifndef EMBEDDED_LIBRARY /**************************************************************************** @@ -1217,10 +1218,7 @@ void clean_up(bool print_message) #endif delete binlog_filter; delete rpl_filter; -#ifdef HAVE_OPENSSL - if (ssl_acceptor_fd) - my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR)); -#endif /* HAVE_OPENSSL */ + end_ssl(); #ifdef USE_REGEX my_regex_end(); #endif @@ -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() { DBUG_ENTER("init_server_components"); diff --git a/sql/sql_class.h b/sql/sql_class.h index fdb70b6c991..937457abc64 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -112,17 +112,16 @@ class Key :public Sql_alloc { public: enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY}; enum Keytype type; - enum ha_key_alg algorithm; + KEY_CREATE_INFO key_info; List<key_part_spec> columns; const char *name; bool generated; - LEX_STRING *parser_name; - Key(enum Keytype type_par, const char *name_arg, enum ha_key_alg alg_par, - bool generated_arg, List<key_part_spec> &cols, - LEX_STRING *parser_arg= 0) - :type(type_par), algorithm(alg_par), columns(cols), name(name_arg), - generated(generated_arg), parser_name(parser_arg) + Key(enum Keytype type_par, const char *name_arg, + KEY_CREATE_INFO *key_info_arg, + bool generated_arg, List<key_part_spec> &cols) + :type(type_par), key_info(*key_info_arg), columns(cols), name(name_arg), + generated(generated_arg) {} ~Key() {} /* Equality comparison of keys (ignoring name) */ @@ -144,7 +143,7 @@ public: foreign_key(const char *name_arg, List<key_part_spec> &cols, Table_ident *table, List<key_part_spec> &ref_cols, 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), delete_opt(delete_opt_arg), update_opt(update_opt_arg), match_opt(match_opt_arg) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 47fbc685bab..a7f9aa8ac5e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -840,6 +840,7 @@ typedef struct st_lex udf_func udf; HA_CHECK_OPT check_opt; // check/repair options HA_CREATE_INFO create_info; + KEY_CREATE_INFO key_info; LEX_MASTER_INFO mi; // used by CHANGE MASTER USER_RESOURCES mqh; ulong type; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ebf4b3fed66..72ce9e8e9a2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5973,14 +5973,16 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if (type_modifier & PRI_KEY_FLAG) { 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)); lex->col_list.empty(); } if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) { 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.empty(); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5e54040f0ae..aecb18b7d0f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -42,6 +42,9 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **), grant_names, NULL}; #endif +static void store_key_options(THD *thd, String *packet, TABLE *table, + KEY *key_info); + /*************************************************************************** ** List all table types supported ***************************************************************************/ @@ -929,15 +932,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, handler *file= table->file; TABLE_SHARE *share= table->s; HA_CREATE_INFO create_info; - my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL | - MODE_ORACLE | - MODE_MSSQL | - MODE_DB2 | - MODE_MAXDB | - MODE_ANSI)) != 0; - my_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; DBUG_ENTER("store_create_info"); 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, if (!found_primary) append_identifier(thd, packet, key_info->name, strlen(key_info->name)); - 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")); - - // +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")); +#if MYSQL_VERSION_ID < 50300 + /* Key options moved to after key parts in 5.3.0 */ + if (!thd->variables.new_mode) + store_key_options(thd, packet, table, key_info); +#endif - // No need to send USING FULLTEXT, it is sent as FULLTEXT KEY - } packet->append(STRING_WITH_LEN(" (")); 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, } } 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) { packet->append(" WITH PARSER ", 13); @@ -1252,6 +1246,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, packet->append(STRING_WITH_LEN(" ROW_FORMAT=")); 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); if (share->comment && share->comment[0]) { @@ -1286,6 +1286,47 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, 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 view_store_options(THD *thd, TABLE_LIST *table, String *buff) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 412682fc3b0..6225cda3e1c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -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, - prep_key->algorithm, + &prep_key->key_info, prep_key->generated, - prep_columns, - prep_key->parser_name))) + prep_columns))) { mem_alloc_error(sizeof(Key)); DBUG_RETURN(TRUE); @@ -2495,14 +2494,16 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, break; } - switch(key->type){ + switch (key->type) { case Key::MULTIPLE: key_info->flags= 0; break; case Key::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; + else + key_info->parser_name= 0; break; case Key::SPATIAL: #ifdef HAVE_SPATIAL @@ -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_part=key_part_info; key_info->usable_key_parts= key_number; - key_info->algorithm=key->algorithm; + key_info->algorithm= key->key_info.algorithm; if (key->type == Key::FULLTEXT) { @@ -2572,6 +2573,18 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #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); CHARSET_INFO *ft_key_charset=0; // for FULLTEXT 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, create_info->avg_row_length= table->s->avg_row_length; if (!(used_fields & HA_CREATE_USED_DEFAULT_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 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, key_part_length)); } 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_info->flags & HA_NOSAME ? (!my_strcasecmp(system_charset_info, @@ -5352,11 +5377,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, (key_info->flags & HA_FULLTEXT ? Key::FULLTEXT : Key::MULTIPLE)), key_name, - key_info->algorithm, + &key_create_info, test(key_info->flags & HA_GENERATED_KEY), - key_parts, - key_info->flags & HA_USES_PARSER ? - &key_info->parser->name : 0)); + key_parts)); + } } { Key *key; @@ -5452,9 +5476,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, while ((prep_col= prep_col_it++)) prep_columns.push_back(new key_part_spec(*prep_col)); prepared_key_list.push_back(new Key(prep_key->type, prep_key->name, - prep_key->algorithm, - prep_key->generated, prep_columns, - prep_key->parser_name)); + &prep_key->key_info, + prep_key->generated, prep_columns)); } /* Create the prepared information. */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ab87c78d17c..75a588a2bc4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -364,6 +364,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token JOIN_SYM %token KEYS %token KEY_SYM +%token KEY_BLOCK_SIZE %token KILL_SYM %token LANGUAGE_SYM %token LAST_INSERT_ID @@ -730,7 +731,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem %type <lex_str_ptr> - opt_table_alias opt_fulltext_parser + opt_table_alias %type <table> table_ident table_ident_nodb references xid @@ -795,7 +796,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); key_type opt_unique_or_fulltext constraint_key_type %type <key_alg> - key_alg opt_btree_or_rtree + opt_btree_or_rtree %type <string_list> key_usage_list using_list @@ -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_check_option trigger_tail sp_tail install uninstall partition_entry binlog_base64_event + init_key_options key_options key_opts key_opt END_OF_INPUT %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt @@ -1220,11 +1222,13 @@ create: } create2 { 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->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)) YYABORT; lex->create_list.empty(); @@ -1232,15 +1236,16 @@ create: lex->col_list.empty(); lex->change=NullS; } - '(' key_list ')' opt_fulltext_parser + '(' key_list ')' key_options { LEX *lex=Lex; - if ($2 != Key::FULLTEXT && $12) + if ($2 != Key::FULLTEXT && lex->key_info.parser_name.str) { yyerror(ER(ER_SYNTAX_ERROR)); 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(); } | CREATE DATABASE opt_if_not_exists ident @@ -3890,6 +3895,11 @@ create_table_option: | STORAGE_SYM DISK_SYM {Lex->create_info.store_on_disk= TRUE;} | 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; } + | 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: @@ -3983,23 +3993,25 @@ column_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; - if ($1 != Key::FULLTEXT && $7) + if ($1 != Key::FULLTEXT && lex->key_info.parser_name.str) { yyerror(ER(ER_SYNTAX_ERROR)); 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 */ } - | 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; - const char *key_name= $3 ? $3:$1; - lex->key_list.push_back(new Key($2, key_name, $4, 0, - lex->col_list)); + const char *key_name= $3 ? $3 : $1; + lex->key_list.push_back(new Key($2, key_name, &lex->key_info, 0, + lex->col_list)); lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references @@ -4012,7 +4024,7 @@ key_def: lex->fk_update_opt, lex->fk_match_option)); 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.empty(); /* Alloced by sql_alloc */ @@ -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: /* empty */ | check_constraint @@ -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: - /* empty */ { $$= HA_KEY_ALG_UNDEF; } - | USING opt_btree_or_rtree { $$= $2; } - | TYPE_SYM opt_btree_or_rtree { $$= $2; }; + /* empty */ init_key_options + | init_key_options key_opts + ; + +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: BTREE_SYM { $$= HA_KEY_ALG_BTREE; } @@ -9348,7 +9386,7 @@ keyword_sp: | ISSUER_SYM {} | INNOBASE_SYM {} | INSERT_METHOD {} - | RELAY_THREAD {} + | KEY_BLOCK_SIZE {} | LAST_SYM {} | LEAVES {} | LESS_SYM {} @@ -9435,6 +9473,7 @@ keyword_sp: | REDUNDANT_SYM {} | RELAY_LOG_FILE_SYM {} | RELAY_LOG_POS_SYM {} + | RELAY_THREAD {} | RELOAD {} | REORGANIZE_SYM {} | REPEATABLE_SYM {} diff --git a/sql/structs.h b/sql/structs.h index e369d8ed7e8..72237887514 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -86,6 +86,7 @@ typedef struct st_key { uint key_parts; /* How many key_parts */ uint extra_length; uint usable_key_parts; /* Should normally be = key_parts */ + uint block_size; enum ha_key_alg algorithm; /* Note that parser is used when the table is opened for use, and diff --git a/sql/table.cc b/sql/table.cc index 6ba66569f5c..bacb703a28c 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -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_parts= (uint) strpos[4]; keyinfo->algorithm= (enum ha_key_alg) strpos[5]; + keyinfo->block_size= uint2korr(strpos+6); strpos+=8; } else @@ -706,6 +707,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } my_free(buff, MYF(0)); } + share->key_block_size= uint2korr(head+62); error=4; extra_rec_buf_length= uint2korr(head+59); @@ -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 int4store(fileinfo+51, tmp); 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); for (; length > IO_SIZE ; length-= IO_SIZE) { diff --git a/sql/table.h b/sql/table.h index 85d49444b29..5fd9cd28585 100644 --- a/sql/table.h +++ b/sql/table.h @@ -160,6 +160,7 @@ typedef struct st_table_share uint ref_count; /* How many TABLE objects uses this */ uint open_count; /* Number of tables in open list */ 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 fields; /* Number of fields */ uint rec_buff_length; /* Size of table->record[] buffer */ diff --git a/sql/unireg.cc b/sql/unireg.cc index bbb4d970d37..eb38e6c0592 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -338,9 +338,9 @@ err_handler: /* Pack screens to a screen for save in a form-file */ -static uchar * pack_screens(List<create_field> &create_fields, - uint *info_length, uint *screens, - bool small_file) +static uchar *pack_screens(List<create_field> &create_fields, + uint *info_length, uint *screens, + bool small_file) { reg1 uint i; uint row,start_row,end_row,fields_on_screen; @@ -431,7 +431,7 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, int2store(pos+2,key->key_length); pos[4]= (uchar) key->key_parts; pos[5]= (uchar) key->algorithm; - pos[6]=pos[7]=0; // For the future + int2store(pos+6, key->block_size); pos+=8; key_parts+=key->key_parts; DBUG_PRINT("loop",("flags: %d key_parts: %d at 0x%lx", diff --git a/storage/myisam/ft_eval.c b/storage/myisam/ft_eval.c index eab9d37af0b..459742d2aff 100644 --- a/storage/myisam/ft_eval.c +++ b/storage/myisam/ft_eval.c @@ -54,6 +54,7 @@ int main(int argc, char *argv[]) /* Define a key over the first column */ keyinfo[0].seg=keyseg; keyinfo[0].keysegs=1; + keyinfo[0].block_length= 0; /* Default block length */ keyinfo[0].seg[0].type= HA_KEYTYPE_TEXT; keyinfo[0].seg[0].flag= HA_BLOB_PART; keyinfo[0].seg[0].start=recinfo[0].length; diff --git a/storage/myisam/ft_test1.c b/storage/myisam/ft_test1.c index d54b344e2cd..28dcfb2b758 100644 --- a/storage/myisam/ft_test1.c +++ b/storage/myisam/ft_test1.c @@ -89,6 +89,7 @@ static int run_test(const char *filename) /* Define a key over the first column */ keyinfo[0].seg=keyseg; keyinfo[0].keysegs=1; + keyinfo[0].block_length= 0; /* Default block length */ keyinfo[0].seg[0].type= key_type; keyinfo[0].seg[0].flag= (key_field == FIELD_BLOB) ? HA_BLOB_PART: (key_field == FIELD_VARCHAR) ? HA_VAR_LENGTH_PART:0; diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index eb2f42697ce..fff35a8ad3c 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -358,7 +358,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) puts("- check key delete-chain"); 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 (param->testflag & T_VERBOSE) puts(""); @@ -1411,7 +1411,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, share->state.key_root[i]= HA_OFFSET_ERROR; /* 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; /* @@ -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); for (key=0 ; key < info->s->base.keys ; 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.changed&= ~STATE_NOT_SORTED_PAGES; @@ -2095,7 +2095,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, /* Clear the pointers to the given rows */ for (i=0 ; i < share->base.keys ; i++) 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; info->state->key_file_length=share->base.keystart; } @@ -2463,7 +2463,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, /* Clear the pointers to the given rows */ for (i=0 ; i < share->base.keys ; i++) 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; info->state->key_file_length=share->base.keystart; } diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index 3be998b2c17..22cbde278be 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -28,9 +28,9 @@ #endif #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, uint columns, MI_COLUMNDEF *recinfo, @@ -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, base_pos,long_varchar_count,varchar_length, max_key_block_length,unique_key_parts,fulltext_keys,offset; + uint aligned_key_start, block_length; ulong reclength, real_reclength,min_pack_length; char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr; ulong pack_reclength; @@ -428,8 +429,16 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, key_segs) share.state.rec_per_key_part[key_segs-1]=1L; 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, - pointer,MI_MAX_KEYPTR_SIZE); + pointer,MI_MAX_KEYPTR_SIZE, + block_length); if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH || length >= MI_MAX_KEY_BUFF) { @@ -485,7 +494,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, mi_int2store(share.state.header.base_pos,base_pos); share.state.header.language= (ci->language ? 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.process= (ulong) getpid(); @@ -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_set_all_keys_active(share.state.key_map, keys); - share.base.keystart = share.state.state.key_file_length= - MY_ALIGN(info_length, myisam_block_size); + aligned_key_start= my_round_up_to_next_power(max_key_block_length ? + 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_length=ALIGN_SIZE(max_key_length+4); share.base.records=ci->max_rows; diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index 91bf438035f..b61c1af24da 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -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->state.key_root,keys*sizeof(my_off_t), &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 &share->key_root_lock,sizeof(rw_lock_t)*keys, #endif @@ -310,7 +310,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) (char*) key_root, sizeof(my_off_t)*keys); memcpy((char*) share->state.key_del, (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); share->unique_name_length= strlen(name_buff); strmov(share->index_file_name, index_name); @@ -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 *ptr=buff; 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"); memcpy_fixed(ptr,&state->header,sizeof(state->header)); @@ -886,7 +886,7 @@ uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state) ptr +=sizeof(state->header); keys=(uint) state->header.keys; 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->changed= (bool) *ptr++; @@ -1059,7 +1059,7 @@ char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef) keydef->keylength = mi_uint2korr(ptr); ptr +=2; keydef->minlength = 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->version = 0; /* Not saved */ keydef->parser = &ft_default_parser; diff --git a/storage/myisam/mi_page.c b/storage/myisam/mi_page.c index 5240c063fba..a5e2b01ed0f 100644 --- a/storage/myisam/mi_page.c +++ b/storage/myisam/mi_page.c @@ -112,8 +112,8 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos, DBUG_ENTER("_mi_dispose"); DBUG_PRINT("enter",("pos: %ld", (long) pos)); - old_link=info->s->state.key_del[keyinfo->block_size]; - info->s->state.key_del[keyinfo->block_size]=pos; + old_link= info->s->state.key_del[keyinfo->block_size_index]; + info->s->state.key_del[keyinfo->block_size_index]= pos; mi_sizestore(buff,old_link); info->s->state.changed|= STATE_NOT_SORTED_PAGES; 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) char buff[8]; 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 >= 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) (uint) keyinfo->block_length,0)) pos= HA_OFFSET_ERROR; 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; DBUG_PRINT("exit",("Pos: %ld",(long) pos)); diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c index 0e62b074376..0b78ac8a7ff 100644 --- a/storage/myisam/mi_test1.c +++ b/storage/myisam/mi_test1.c @@ -95,6 +95,7 @@ static int run_test(const char *filename) /* Define a key over the first column */ keyinfo[0].seg=keyseg; keyinfo[0].keysegs=1; + keyinfo[0].block_length= 0; /* Default block length */ keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].seg[0].type= key_type; keyinfo[0].seg[0].flag= pack_seg; diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c index e77a37d853f..357ebb1b9bc 100644 --- a/storage/myisam/mi_test2.c +++ b/storage/myisam/mi_test2.c @@ -95,6 +95,7 @@ int main(int argc, char *argv[]) keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].keysegs=1; keyinfo[0].flag = pack_type; + keyinfo[0].block_length= 0; /* Default block length */ keyinfo[1].seg= &glob_keyseg[1][0]; keyinfo[1].seg[0].start=7; keyinfo[1].seg[0].length=6; @@ -111,6 +112,7 @@ int main(int argc, char *argv[]) keyinfo[1].key_alg=HA_KEY_ALG_BTREE; keyinfo[1].keysegs=2; 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[0].start=12; keyinfo[2].seg[0].length=8; @@ -121,6 +123,7 @@ int main(int argc, char *argv[]) keyinfo[2].key_alg=HA_KEY_ALG_BTREE; keyinfo[2].keysegs=1; keyinfo[2].flag =HA_NOSAME; + keyinfo[2].block_length= 0; /* Default block length */ keyinfo[3].seg= &glob_keyseg[3][0]; keyinfo[3].seg[0].start=0; keyinfo[3].seg[0].length=reclength-(use_blob ? 8 : 0); @@ -132,6 +135,7 @@ int main(int argc, char *argv[]) keyinfo[3].key_alg=HA_KEY_ALG_BTREE; keyinfo[3].keysegs=1; keyinfo[3].flag = pack_type; + keyinfo[3].block_length= 0; /* Default block length */ keyinfo[4].seg= &glob_keyseg[4][0]; keyinfo[4].seg[0].start=0; keyinfo[4].seg[0].length=5; @@ -143,6 +147,7 @@ int main(int argc, char *argv[]) keyinfo[4].key_alg=HA_KEY_ALG_BTREE; keyinfo[4].keysegs=1; keyinfo[4].flag = pack_type; + keyinfo[4].block_length= 0; /* Default block length */ keyinfo[5].seg= &glob_keyseg[5][0]; keyinfo[5].seg[0].start=0; keyinfo[5].seg[0].length=4; @@ -154,6 +159,7 @@ int main(int argc, char *argv[]) keyinfo[5].key_alg=HA_KEY_ALG_BTREE; keyinfo[5].keysegs=1; keyinfo[5].flag = pack_type; + keyinfo[5].block_length= 0; /* Default block length */ recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0; recinfo[0].length=7; @@ -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); if (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) { puts("Key cache used"); @@ -914,13 +920,13 @@ static void get_options(int argc, char **argv) } break; 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) { fprintf(stderr,"Wrong myisam_block_length\n"); 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; case 'E': /* myisam_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) fprintf(stderr,"Wrong key_cache_block_size\n"); 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; case 'f': if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS) diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c index 4e764c6f971..173fbe64cf5 100644 --- a/storage/myisam/mi_test3.c +++ b/storage/myisam/mi_test3.c @@ -76,6 +76,7 @@ int main(int argc,char **argv) keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].keysegs=1; keyinfo[0].flag = (uint8) HA_PACK_KEY; + keyinfo[0].block_length= 0; /* Default block length */ keyinfo[1].seg= &keyseg[1][0]; keyinfo[1].seg[0].start=8; keyinfo[1].seg[0].length=4; /* Long is always 4 in myisam */ @@ -84,6 +85,7 @@ int main(int argc,char **argv) keyinfo[1].key_alg=HA_KEY_ALG_BTREE; keyinfo[1].keysegs=1; keyinfo[1].flag =HA_NOSAME; + keyinfo[1].block_length= 0; /* Default block length */ recinfo[0].type=0; recinfo[0].length=sizeof(record.id); diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index caf6254c321..0b450de9c03 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -55,7 +55,7 @@ typedef struct st_mi_state_info uchar keys; /* number of keys in file */ uchar uniques; /* number of UNIQUE definitions */ uchar language; /* Language for indexes */ - uchar max_block_size; /* max keyblock size */ + uchar max_block_size_index; /* max keyblock size */ uchar fulltext_keys; uchar not_used; /* To align to 8 */ } header; @@ -431,7 +431,7 @@ typedef struct st_mi_sort_param #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_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_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); int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup); int mi_open_keyfile(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 */ volatile int *killed_ptr(MI_CHECK *param); diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index e80a3ffacd9..5b3067cb115 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -2726,6 +2726,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) break; } case FIELD_LAST: + case FIELD_enum_val_count: abort(); /* Impossible */ } 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, mi_clear_all_keys_active(share->state.key_map); for (key=0 ; key < share->base.keys ; key++) 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; isam_file->state->checksum=crc; /* Save crc here */ share->changed=1; /* Force write of header */ diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 4ee27f1e491..002874caf58 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -296,7 +296,7 @@ ctor_failure: TODO: Add option --verify to mysqld to be able to change verification mode */ -struct st_VioSSLAcceptorFd* +struct st_VioSSLAcceptorFd * new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, const char *ca_file, @@ -387,4 +387,12 @@ ctor_failure: my_free((gptr) ptr,MYF(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 */ |