diff --git a/configure.in b/configure.in index 0e336c5522b..120717d6afa 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.59], [], [mysql]) +AC_INIT([MySQL Server], [5.1.60], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM @@ -2711,7 +2711,7 @@ then MAN_DROP="$MAN_DROP embedded" grep -v 'embedded' $MANLISTFIL > $TMPLISTFIL ; mv -f $TMPLISTFIL $MANLISTFIL fi - if test X"$with_plugin_innobase" != Xyes + if test X"$with_plugin_innobase" != Xyes -a X"$with_plugin_innodb_plugin" != Xyes then MAN_DROP="$MAN_DROP innodb" grep -v 'inno' $MANLISTFIL > $TMPLISTFIL ; mv -f $TMPLISTFIL $MANLISTFIL @@ -2790,7 +2790,7 @@ then fi # "innochecksum" is not in the "innobase/" subdirectory, but should be switched -AM_CONDITIONAL([BUILD_INNODB_TOOLS], [test X"$with_plugin_innobase" = Xyes]) +AM_CONDITIONAL([BUILD_INNODB_TOOLS], [test X"$with_plugin_innobase" = Xyes -o X"$with_plugin_innodb_plugin" = Xyes ]) # IMPORTANT - do not modify LIBS past this line - this hack is the only way # I know to add the static NSS magic if we have static NSS libraries with diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 8883acfa606..961a93b8741 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -23,7 +23,8 @@ main.query_cache_28249 # Bug#12584161 2009-03-25 main.query_ca ndb.* # joro : NDB tests marked as experimental as agreed with bochklin -rpl.rpl_innodb_bug28430 @solaris # Bug#11754425 +rpl.rpl_innodb_bug28430 # Bug#11754425 +rpl.rpl_insert # Sven: BUG#12764817 rpl.rpl_row_sp011 @solaris # Joro : Bug #11753919 rpl.rpl_stop_slave # Sven : BUG#12345981 diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 63744d4ef29..68c1e667440 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1426,4 +1426,10 @@ NULL SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1) NULL +# +# Bug#12584302 AFTER FIX FOR #12403504: ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0, +# +DO WEEK((DATE_ADD((CAST(0 AS DATE)), INTERVAL 1 YEAR_MONTH)), 5); +Warnings: +Warning 1292 Incorrect datetime value: '0' End of 5.1 tests diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 2180a23b91a..1ce14d38166 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -7053,6 +7053,25 @@ init_connect SET @@GLOBAL.init_connect= @old_init_connect; DROP PROCEDURE p2; DROP PROCEDURE p5; +# +# Bug#11766594 59736: SELECT DISTINCT.. INCORRECT RESULT WITH DETERMINISTIC FUNCTION IN WHERE C +# +CREATE TABLE t1 (a INT, b INT, KEY(b)); +CREATE TABLE t2 (c INT, d INT, KEY(c)); +INSERT INTO t1 VALUES (1,1),(1,1),(1,2); +INSERT INTO t2 VALUES (1,1),(1,2); +CREATE FUNCTION f1() RETURNS INT DETERMINISTIC +BEGIN +DECLARE a int; +-- SQL statement inside +SELECT 1 INTO a; +RETURN a; +END $ +SELECT COUNT(DISTINCT d) FROM t1, t2 WHERE a = c AND b = f1(); +COUNT(DISTINCT d) +2 +DROP FUNCTION f1; +DROP TABLE t1, t2; # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ diff --git a/mysql-test/r/sp_trans.result b/mysql-test/r/sp_trans.result index a64f53efde7..dec37db652a 100644 --- a/mysql-test/r/sp_trans.result +++ b/mysql-test/r/sp_trans.result @@ -556,3 +556,49 @@ f1 bug13575(f1) 3 ccc drop function bug13575| drop table t3| +SELECT @@GLOBAL.storage_engine INTO @old_engine| +SET @@GLOBAL.storage_engine=InnoDB| +SET @@SESSION.storage_engine=InnoDB| +SHOW GLOBAL VARIABLES LIKE 'storage_engine'| +Variable_name Value +storage_engine InnoDB +SHOW SESSION VARIABLES LIKE 'storage_engine'| +Variable_name Value +storage_engine InnoDB +CREATE PROCEDURE bug11758414() +BEGIN +SET @@GLOBAL.storage_engine="MyISAM"; +SET @@SESSION.storage_engine="MyISAM"; +# show defaults at execution time / that setting them worked +SHOW GLOBAL VARIABLES LIKE 'storage_engine'; +SHOW SESSION VARIABLES LIKE 'storage_engine'; +CREATE TABLE t1 (id int); +CREATE TABLE t2 (id int) ENGINE=InnoDB; +# show we're heeding the default (at run-time, not parse-time!) + SHOW CREATE TABLE t1; + # show that we didn't break explicit override with ENGINE=... +SHOW CREATE TABLE t2; +END; +| +CALL bug11758414| +Variable_name Value +storage_engine MyISAM +Variable_name Value +storage_engine MyISAM +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SHOW GLOBAL VARIABLES LIKE 'storage_engine'| +Variable_name Value +storage_engine MyISAM +SHOW SESSION VARIABLES LIKE 'storage_engine'| +Variable_name Value +storage_engine MyISAM +DROP PROCEDURE bug11758414| +DROP TABLE t1, t2| +SET @@GLOBAL.storage_engine=@old_engine| diff --git a/mysql-test/suite/innodb_plugin/r/innodb-zip.result b/mysql-test/suite/innodb_plugin/r/innodb-zip.result index fc35143b305..16947bf16dc 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb-zip.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-zip.result @@ -62,42 +62,42 @@ row_format=compressed; create table t14(a int primary key) engine=innodb key_block_size=9; Warnings: Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=9. -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t0 Compact -test t00 Compact -test t1 Compact -test t10 Dynamic -test t11 Compressed -test t12 Compressed -test t13 Compressed -test t14 Compact -test t2 Redundant -test t3 Compact -test t4 Compact -test t5 Redundant -test t6 Redundant -test t7 Redundant -test t8 Compact -test t9 Compact +table_schema table_name row_format data_length index_length +test t0 Compact 16384 0 +test t00 Compact 16384 0 +test t1 Compact 16384 0 +test t10 Dynamic 16384 0 +test t11 Compressed 1024 0 +test t12 Compressed 1024 0 +test t13 Compressed 8192 0 +test t14 Compact 16384 0 +test t2 Redundant 16384 0 +test t3 Compact 16384 0 +test t4 Compact 16384 0 +test t5 Redundant 16384 0 +test t6 Redundant 16384 0 +test t7 Redundant 16384 0 +test t8 Compact 16384 0 +test t9 Compact 16384 0 drop table t0,t00,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14; alter table t1 key_block_size=0; alter table t1 row_format=dynamic; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Dynamic +table_schema table_name row_format data_length index_length +test t1 Dynamic 16384 0 alter table t1 row_format=compact; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compact +table_schema table_name row_format data_length index_length +test t1 Compact 16384 0 alter table t1 row_format=redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Redundant +table_schema table_name row_format data_length index_length +test t1 Redundant 16384 0 drop table t1; create table t1(a int not null, b text, index(b(10))) engine=innodb key_block_size=1; @@ -114,11 +114,11 @@ rollback; select a,left(b,40) from t1 natural join t2; a left(b,40) 1 1abcdefghijklmnopqrstuvwxyzAAAAAAAAAAAAA -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compressed -test t2 Compact +table_schema table_name row_format data_length index_length +test t1 Compressed 2048 1024 +test t2 Compact 16384 0 drop table t1,t2; SET SESSION innodb_strict_mode = off; CREATE TABLE t1( @@ -206,19 +206,19 @@ create table t8 (id int primary key) engine = innodb row_format = compressed; create table t9 (id int primary key) engine = innodb row_format = dynamic; create table t10(id int primary key) engine = innodb row_format = compact; create table t11(id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compact -test t10 Compact -test t11 Redundant -test t3 Compressed -test t4 Compressed -test t5 Compressed -test t6 Compressed -test t7 Compressed -test t8 Compressed -test t9 Dynamic +table_schema table_name row_format data_length index_length +test t1 Compact 16384 0 +test t10 Compact 16384 0 +test t11 Redundant 16384 0 +test t3 Compressed 1024 0 +test t4 Compressed 2048 0 +test t5 Compressed 4096 0 +test t6 Compressed 8192 0 +test t7 Compressed 16384 0 +test t8 Compressed 8192 0 +test t9 Dynamic 16384 0 drop table t1, t3, t4, t5, t6, t7, t8, t9, t10, t11; create table t1 (id int primary key) engine = innodb key_block_size = 8 row_format = compressed; @@ -245,11 +245,11 @@ Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t4' (errno: 1478) create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t1 Compressed -test t5 Compressed +table_schema table_name row_format data_length index_length +test t1 Compressed 8192 0 +test t5 Compressed 8192 0 drop table t1, t5; create table t1 (id int primary key) engine = innodb key_block_size = 9 row_format = redundant; @@ -275,9 +275,9 @@ Level Code Message Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. Error 1005 Can't create table 'test.t2' (errno: 1478) -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format +table_schema table_name row_format data_length index_length set global innodb_file_per_table = off; create table t1 (id int primary key) engine = innodb key_block_size = 1; ERROR HY000: Can't create table 'test.t1' (errno: 1478) @@ -323,11 +323,11 @@ Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. Error 1005 Can't create table 'test.t7' (errno: 1478) create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t8 Compact -test t9 Redundant +table_schema table_name row_format data_length index_length +test t8 Compact 16384 0 +test t9 Redundant 16384 0 drop table t8, t9; set global innodb_file_per_table = on; set global innodb_file_format = `0`; @@ -375,11 +375,11 @@ Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. Error 1005 Can't create table 'test.t7' (errno: 1478) create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; -table_schema table_name row_format -test t8 Compact -test t9 Redundant +table_schema table_name row_format data_length index_length +test t8 Compact 16384 0 +test t9 Redundant 16384 0 drop table t8, t9; set global innodb_file_per_table=0; set global innodb_file_format=Antelope; diff --git a/mysql-test/suite/innodb_plugin/t/innodb-zip.test b/mysql-test/suite/innodb_plugin/t/innodb-zip.test index 8c1ef1f5467..5ed101b7f20 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb-zip.test +++ b/mysql-test/suite/innodb_plugin/t/innodb-zip.test @@ -36,19 +36,19 @@ create table t13(a int primary key) engine=innodb row_format=compressed; create table t14(a int primary key) engine=innodb key_block_size=9; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t0,t00,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14; alter table t1 key_block_size=0; alter table t1 row_format=dynamic; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; alter table t1 row_format=compact; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; alter table t1 row_format=redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t1; @@ -81,7 +81,7 @@ connection default; disconnect a; disconnect b; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t1,t2; @@ -192,7 +192,7 @@ create table t9 (id int primary key) engine = innodb row_format = dynamic; create table t10(id int primary key) engine = innodb row_format = compact; create table t11(id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t1, t3, t4, t5, t6, t7, t8, t9, t10, t11; @@ -218,7 +218,7 @@ show warnings; create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t1, t5; @@ -238,7 +238,7 @@ create table t2 (id int primary key) engine = innodb key_block_size = 9 row_format = dynamic; show warnings; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; #test valid values with innodb_file_per_table unset @@ -268,7 +268,7 @@ show warnings; create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t8, t9; @@ -300,7 +300,7 @@ show warnings; create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; -SELECT table_schema, table_name, row_format +SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; drop table t8, t9; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index de92f313992..2dcac0d5796 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -928,4 +928,10 @@ SELECT DATE_FORMAT('0000-00-11', '%w'); SELECT MAKEDATE(11111111,1); SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); +--echo # +--echo # Bug#12584302 AFTER FIX FOR #12403504: ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0, +--echo # + +DO WEEK((DATE_ADD((CAST(0 AS DATE)), INTERVAL 1 YEAR_MONTH)), 5); + --echo End of 5.1 tests diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 5cf050146dd..9207ea22290 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8350,6 +8350,33 @@ SET @@GLOBAL.init_connect= @old_init_connect; DROP PROCEDURE p2; DROP PROCEDURE p5; +--echo # +--echo # Bug#11766594 59736: SELECT DISTINCT.. INCORRECT RESULT WITH DETERMINISTIC FUNCTION IN WHERE C +--echo # + +CREATE TABLE t1 (a INT, b INT, KEY(b)); +CREATE TABLE t2 (c INT, d INT, KEY(c)); +INSERT INTO t1 VALUES (1,1),(1,1),(1,2); +INSERT INTO t2 VALUES (1,1),(1,2); + +DELIMITER $; + +CREATE FUNCTION f1() RETURNS INT DETERMINISTIC +BEGIN + DECLARE a int; + -- SQL statement inside + SELECT 1 INTO a; + RETURN a; +END $ + +DELIMITER ;$ + +SELECT COUNT(DISTINCT d) FROM t1, t2 WHERE a = c AND b = f1(); + +DROP FUNCTION f1; +DROP TABLE t1, t2; + + --echo # ------------------------------------------------------------------ --echo # -- End of 5.1 tests --echo # ------------------------------------------------------------------ diff --git a/mysql-test/t/sp_trans.test b/mysql-test/t/sp_trans.test index 0b04b9d7668..2d59fb20bbd 100644 --- a/mysql-test/t/sp_trans.test +++ b/mysql-test/t/sp_trans.test @@ -593,6 +593,39 @@ drop function bug13575| drop table t3| +# +# BUG#11758414: Default storage_engine not honored when set +# from within a stored procedure +# +SELECT @@GLOBAL.storage_engine INTO @old_engine| +SET @@GLOBAL.storage_engine=InnoDB| +SET @@SESSION.storage_engine=InnoDB| +# show defaults at define-time +SHOW GLOBAL VARIABLES LIKE 'storage_engine'| +SHOW SESSION VARIABLES LIKE 'storage_engine'| +CREATE PROCEDURE bug11758414() +BEGIN + SET @@GLOBAL.storage_engine="MyISAM"; + SET @@SESSION.storage_engine="MyISAM"; + # show defaults at execution time / that setting them worked + SHOW GLOBAL VARIABLES LIKE 'storage_engine'; + SHOW SESSION VARIABLES LIKE 'storage_engine'; + CREATE TABLE t1 (id int); + CREATE TABLE t2 (id int) ENGINE=InnoDB; + # show we're heeding the default (at run-time, not parse-time!) + SHOW CREATE TABLE t1; + # show that we didn't break explicit override with ENGINE=... + SHOW CREATE TABLE t2; +END; +| +CALL bug11758414| +# show that changing defaults within SP stuck +SHOW GLOBAL VARIABLES LIKE 'storage_engine'| +SHOW SESSION VARIABLES LIKE 'storage_engine'| +DROP PROCEDURE bug11758414| +DROP TABLE t1, t2| +SET @@GLOBAL.storage_engine=@old_engine| + # # BUG#NNNN: New bug synopsis # diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 83b0b7cdebc..31474f1d6ca 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2646,7 +2646,7 @@ String *Item_time_typecast::val_str(String *str) bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date) { - bool res= get_arg0_date(ltime, TIME_FUZZY_DATE); + bool res= get_arg0_date(ltime, fuzzy_date); ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0; ltime->time_type= MYSQL_TIMESTAMP_DATE; return res; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 87d28402e01..ab1ba156905 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7576,7 +7576,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM && sum_func_list) item->split_sum_func(thd, ref_pointer_array, *sum_func_list); - thd->used_tables|= item->used_tables(); + thd->lex->used_tables|= item->used_tables(); thd->lex->current_select->cur_pos_in_select_list++; } thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup; @@ -7923,7 +7923,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, views and natural joins this update is performed inside the loop below. */ if (table) - thd->used_tables|= table->map; + thd->lex->used_tables|= table->map; /* Initialize a generic field iterator for the current table reference. @@ -8008,7 +8008,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, field_table= nj_col->table_ref->table; if (field_table) { - thd->used_tables|= field_table->map; + thd->lex->used_tables|= field_table->map; field_table->covering_keys.intersect(field->part_of_key); field_table->merge_keys.merge(field->part_of_key); field_table->used_fields++; @@ -8016,7 +8016,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, } } else - thd->used_tables|= item->used_tables(); + thd->lex->used_tables|= item->used_tables(); thd->lex->current_select->cur_pos_in_select_list++; } /* diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b9df35fe8be..7fb1d2ade5f 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -649,7 +649,6 @@ THD::THD() is_slave_error= thread_specific_used= FALSE; hash_clear(&handler_tables_hash); tmp_table=0; - used_tables=0; cuted_fields= sent_row_count= row_count= 0L; limit_found_rows= 0; row_count_func= -1; diff --git a/sql/sql_class.h b/sql/sql_class.h index bf197fee9c3..3c1b2c1330f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1734,13 +1734,6 @@ public: */ ha_rows examined_row_count; - /* - The set of those tables whose fields are referenced in all subqueries - of the query. - TODO: possibly this it is incorrect to have used tables in THD because - with more than one subquery, it is not clear what does the field mean. - */ - table_map used_tables; USER_CONN *user_connect; CHARSET_INFO *db_charset; /* diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index baf5af16e2b..e176e5c9b6d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -631,7 +631,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, lock_type= table_list->lock_type; thd_proc_info(thd, "init"); - thd->used_tables=0; + thd->lex->used_tables=0; values= its++; value_count= values->elements; @@ -779,7 +779,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, } else { - if (thd->used_tables) // Column used in values() + if (thd->lex->used_tables) // Column used in values() restore_record(table,s->default_values); // Get empty record else { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index f0289ab86ce..6e40f9b9614 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -360,6 +360,7 @@ void lex_start(THD *thd) lex->server_options.port= -1; lex->is_lex_started= TRUE; + lex->used_tables= 0; DBUG_VOID_RETURN; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index b4dbbc5162e..035fa1fde91 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1836,6 +1836,16 @@ typedef struct st_lex : public Query_tables_list uint create_select_pos; bool create_select_in_comment; + /* + The set of those tables whose fields are referenced in all subqueries + of the query. + TODO: possibly this it is incorrect to have used tables in LEX because + with subquery, it is not clear what does the field mean. To fix this + we should aggregate used tables information for selected expressions + into the select_lex. + */ + table_map used_tables; + st_lex(); virtual ~st_lex() diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2eeabc2f0c1..14ad77d29fd 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2616,6 +2616,12 @@ mysql_execute_command(THD *thd) create_table->table_name)) goto end_with_restore_list; #endif + /* + If no engine type was given, work out the default now + rather than at parse-time. + */ + if (!(create_info.used_fields & HA_CREATE_USED_ENGINE)) + create_info.db_type= ha_default_handlerton(thd); /* If we are using SET CHARSET without DEFAULT, add an implicit DEFAULT to not confuse old users. (This may change). diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index b296eb22cdb..ec7a7fb73b8 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1382,7 +1382,7 @@ static int mysql_test_select(Prepared_statement *stmt, if (open_normal_and_derived_tables(thd, tables, 0)) goto error; - thd->used_tables= 0; // Updated by setup_fields + thd->lex->used_tables= 0; // Updated by setup_fields /* JOIN::prepare calls @@ -1551,7 +1551,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt, if (specific_prepare && (*specific_prepare)(thd)) DBUG_RETURN(TRUE); - thd->used_tables= 0; // Updated by setup_fields + thd->lex->used_tables= 0; // Updated by setup_fields /* Calls JOIN::prepare */ DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option)); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2346f744b47..516c9c37473 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -406,7 +406,7 @@ fix_inner_refs(THD *thd, List &all_fields, SELECT_LEX *select, if (!ref->fixed && ref->fix_fields(thd, 0)) return TRUE; - thd->used_tables|= item->used_tables(); + thd->lex->used_tables|= item->used_tables(); } return false; } @@ -1632,7 +1632,7 @@ JOIN::optimize() if (exec_tmp_table1->distinct) { - table_map used_tables= thd->used_tables; + table_map used_tables= thd->lex->used_tables; JOIN_TAB *last_join_tab= join_tab+tables-1; do { @@ -2526,7 +2526,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, if (!(join= new JOIN(thd, fields, select_options, result))) DBUG_RETURN(TRUE); thd_proc_info(thd, "init"); - thd->used_tables=0; // Updated by setup_fields + thd->lex->used_tables=0; // Updated by setup_fields err= join->prepare(rref_pointer_array, tables, wild_num, conds, og_num, order, group, having, proc_param, select_lex, unit); @@ -16949,7 +16949,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, need_order=0; extra.append(STRING_WITH_LEN("; Using filesort")); } - if (distinct & test_all_bits(used_tables,thd->used_tables)) + if (distinct & test_all_bits(used_tables, thd->lex->used_tables)) extra.append(STRING_WITH_LEN("; Distinct")); for (uint part= 0; part < tab->ref.key_parts; part++) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6245f07b9cf..f4fb822b294 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1838,7 +1838,6 @@ create: lex->change=NullS; bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.options=$2 | $4; - lex->create_info.db_type= ha_default_handlerton(thd); lex->create_info.default_table_charset= NULL; lex->name.str= 0; lex->name.length= 0; @@ -1847,7 +1846,8 @@ create: { LEX *lex= YYTHD->lex; lex->current_select= &lex->select_lex; - if (!lex->create_info.db_type) + if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) && + !lex->create_info.db_type) { lex->create_info.db_type= ha_default_handlerton(YYTHD); push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN, diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index e03d3d79768..9ab6424a012 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2468,6 +2468,8 @@ row_sel_field_store_in_mysql_format( ut_ad(len != UNIV_SQL_NULL); UNIV_MEM_ASSERT_RW(data, len); + UNIV_MEM_ASSERT_W(dest, templ->mysql_col_len); + UNIV_MEM_INVALID(dest, templ->mysql_col_len); if (templ->type == DATA_INT) { /* Convert integer data from Innobase to a little-endian @@ -2502,14 +2504,16 @@ row_sel_field_store_in_mysql_format( dest = row_mysql_store_true_var_len( dest, len, templ->mysql_length_bytes); + /* Copy the actual data. Leave the rest of the + buffer uninitialized. */ + ut_memcpy(dest, data, len); + return; } /* Copy the actual data */ ut_memcpy(dest, data, len); - /* Pad with trailing spaces. We pad with spaces also the - unused end of a >= 5.0.3 true VARCHAR column, just in case - MySQL expects its contents to be deterministic. */ + /* Pad with trailing spaces. */ pad_ptr = dest + len; @@ -3012,6 +3016,39 @@ sel_restore_position_for_mysql( return(TRUE); } +/************************************************************************ +Copies a cached field for MySQL from the fetch cache. */ +static +void +row_sel_copy_cached_field_for_mysql( +/*================================*/ + byte* buf, /* in/out: row buffer */ + byte* cache, /* in: cached row */ + const mysql_row_templ_t*templ) /* in: column template */ +{ + ulint len; + + buf += templ->mysql_col_offset; + cache += templ->mysql_col_offset; + + UNIV_MEM_ASSERT_W(buf, templ->mysql_col_len); + + if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR + && templ->type != DATA_INT) { + /* Check for != DATA_INT to make sure we do + not treat MySQL ENUM or SET as a true VARCHAR! + Find the actual length of the true VARCHAR field. */ + row_mysql_read_true_varchar( + &len, cache, templ->mysql_length_bytes); + len += templ->mysql_length_bytes; + UNIV_MEM_INVALID(buf, templ->mysql_col_len); + } else { + len = templ->mysql_col_len; + } + + ut_memcpy(buf, cache, len); +} + /************************************************************************ Pops a cached row for MySQL from the fetch cache. */ UNIV_INLINE @@ -3028,22 +3065,18 @@ row_sel_pop_cached_row_for_mysql( ut_ad(prebuilt->n_fetch_cached > 0); ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len); + UNIV_MEM_ASSERT_W(buf, prebuilt->mysql_row_len); + + cached_rec = prebuilt->fetch_cache[prebuilt->fetch_cache_first]; + if (UNIV_UNLIKELY(prebuilt->keep_other_fields_on_keyread)) { /* Copy cache record field by field, don't touch fields that are not covered by current key */ - cached_rec = prebuilt->fetch_cache[ - prebuilt->fetch_cache_first]; for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; -#if 0 /* Some of the cached_rec may legitimately be uninitialized. */ - UNIV_MEM_ASSERT_RW(cached_rec - + templ->mysql_col_offset, - templ->mysql_col_len); -#endif - ut_memcpy(buf + templ->mysql_col_offset, - cached_rec + templ->mysql_col_offset, - templ->mysql_col_len); + row_sel_copy_cached_field_for_mysql( + buf, cached_rec, templ); /* Copy NULL bit of the current field from cached_rec to buf */ if (templ->mysql_null_bit_mask) { @@ -3053,17 +3086,24 @@ row_sel_pop_cached_row_for_mysql( & (byte)templ->mysql_null_bit_mask; } } + } else if (prebuilt->mysql_prefix_len > 63) { + /* The record is long. Copy it field by field, in case + there are some long VARCHAR column of which only a + small length is being used. */ + UNIV_MEM_INVALID(buf, prebuilt->mysql_prefix_len); + + /* First copy the NULL bits. */ + ut_memcpy(buf, cached_rec, prebuilt->null_bitmap_len); + /* Then copy the requested fields. */ + + for (i = 0; i < prebuilt->n_template; i++) { + row_sel_copy_cached_field_for_mysql( + buf, cached_rec, prebuilt->mysql_template + i); + } + } else { + ut_memcpy(buf, cached_rec, prebuilt->mysql_prefix_len); } - else { -#if 0 /* Some of the cached_rec may legitimately be uninitialized. */ - UNIV_MEM_ASSERT_RW(prebuilt->fetch_cache - [prebuilt->fetch_cache_first], - prebuilt->mysql_prefix_len); -#endif - ut_memcpy(buf, - prebuilt->fetch_cache[prebuilt->fetch_cache_first], - prebuilt->mysql_prefix_len); - } + prebuilt->n_fetch_cached--; prebuilt->fetch_cache_first++; diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 617df0a61fe..0b90b5729d5 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,9 +1,29 @@ +2011-08-15 The InnoDB Team + + * btr/btr0btr.c, btr/btr0cur.c, btr/btr0pcur.c, btr/btr0sea.c, + dict/dict0crea.c, dict/dict0dict.c, ibuf/ibuf0ibuf.c, + include/btr0btr.h, include/btr0btr.ic, include/sync0sync.h, + sync/sync0sync.c: + Fix Bug#11766591 59733: Possible deadlock when buffered changes + are to be discarded in buf_page_create() + +2011-08-08 The InnoDB Team + + * row/row0sel.c: + Fix Bug#12835650 VARCHAR maximum length performance impact + +2011-08-08 The InnoDB Team + + * handler/ha_innodb.cc: + Fix Bug#12770537 I_S.TABLES.DATA_LENGTH DOES NOT SHOW ON-DISK SIZE + FOR COMPRESSED INNODB + 2011-07-19 The InnoDB Team * buf/buf0buf.c, buf/buf0rea.c, handler/ha_innodb.cc, include/buf0buf.h, include/buf0buf.ic, include/srv0srv.h, srv/srv0srv.c: - Fix bug#Bug 12356373 by reintroducing random readahead + Fix Bug#12356373 by reintroducing random readahead 2011-06-30 The InnoDB Team diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c index ac188c8c2fd..5e6724bbd54 100644 --- a/storage/innodb_plugin/btr/btr0btr.c +++ b/storage/innodb_plugin/btr/btr0btr.c @@ -690,7 +690,8 @@ btr_root_block_get( zip_size = dict_table_zip_size(index->table); root_page_no = dict_index_get_page(index); - block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr); + block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, + index, mtr); ut_a((ibool)!!page_is_comp(buf_block_get_frame(block)) == dict_table_is_comp(index->table)); #ifdef UNIV_BTR_DEBUG @@ -891,7 +892,7 @@ btr_page_alloc_for_ibuf( dict_table_zip_size(index->table), node_addr.page, RW_X_LATCH, mtr); new_page = buf_block_get_frame(new_block); - buf_block_dbg_add_level(new_block, SYNC_TREE_NODE_NEW); + buf_block_dbg_add_level(new_block, SYNC_IBUF_TREE_NODE_NEW); flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, new_page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, @@ -1139,7 +1140,7 @@ btr_node_ptr_get_child( page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); return(btr_block_get(space, dict_table_zip_size(index->table), - page_no, RW_X_LATCH, mtr)); + page_no, RW_X_LATCH, index, mtr)); } /************************************************************//** @@ -1311,7 +1312,8 @@ btr_create( space, 0, IBUF_HEADER + IBUF_TREE_SEG_HEADER, mtr); - buf_block_dbg_add_level(ibuf_hdr_block, SYNC_TREE_NODE_NEW); + buf_block_dbg_add_level( + ibuf_hdr_block, SYNC_IBUF_TREE_NODE_NEW); ut_ad(buf_block_get_page_no(ibuf_hdr_block) == IBUF_HEADER_PAGE_NO); @@ -1348,10 +1350,9 @@ btr_create( page_no = buf_block_get_page_no(block); frame = buf_block_get_frame(block); - buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW); - if (type & DICT_IBUF) { /* It is an insert buffer tree: initialize the free list */ + buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW); ut_ad(page_no == IBUF_TREE_ROOT_PAGE_NO); @@ -1359,6 +1360,8 @@ btr_create( } else { /* It is a non-ibuf tree: create a file segment for leaf pages */ + buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW); + if (!fseg_create(space, page_no, PAGE_HEADER + PAGE_BTR_SEG_LEAF, mtr)) { /* Not enough space for new segment, free root @@ -1430,7 +1433,8 @@ btr_free_but_not_root( leaf_loop: mtr_start(&mtr); - root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr); + root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, + NULL, &mtr); #ifdef UNIV_BTR_DEBUG ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + root, space)); @@ -1452,7 +1456,8 @@ leaf_loop: top_loop: mtr_start(&mtr); - root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr); + root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, + NULL, &mtr); #ifdef UNIV_BTR_DEBUG ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP + root, space)); @@ -1478,13 +1483,13 @@ btr_free_root( ulint zip_size, /*!< in: compressed page size in bytes or 0 for uncompressed pages */ ulint root_page_no, /*!< in: root page number */ - mtr_t* mtr) /*!< in: a mini-transaction which has already - been started */ + mtr_t* mtr) /*!< in/out: mini-transaction */ { buf_block_t* block; fseg_header_t* header; - block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr); + block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, + NULL, mtr); btr_search_drop_page_hash_index(block); @@ -2362,9 +2367,8 @@ btr_attach_half_pages( /* Update page links of the level */ if (prev_page_no != FIL_NULL) { - buf_block_t* prev_block = btr_block_get(space, zip_size, - prev_page_no, - RW_X_LATCH, mtr); + buf_block_t* prev_block = btr_block_get( + space, zip_size, prev_page_no, RW_X_LATCH, index, mtr); #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(prev_block->frame) == page_is_comp(page)); ut_a(btr_page_get_next(prev_block->frame, mtr) @@ -2377,9 +2381,8 @@ btr_attach_half_pages( } if (next_page_no != FIL_NULL) { - buf_block_t* next_block = btr_block_get(space, zip_size, - next_page_no, - RW_X_LATCH, mtr); + buf_block_t* next_block = btr_block_get( + space, zip_size, next_page_no, RW_X_LATCH, index, mtr); #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(next_block->frame) == page_is_comp(page)); ut_a(btr_page_get_prev(next_block->frame, mtr) @@ -2801,17 +2804,42 @@ func_exit: return(rec); } +#ifdef UNIV_SYNC_DEBUG +/*************************************************************//** +Removes a page from the level list of pages. +@param space in: space where removed +@param zip_size in: compressed page size in bytes, or 0 for uncompressed +@param page in/out: page to remove +@param index in: index tree +@param mtr in/out: mini-transaction */ +# define btr_level_list_remove(space,zip_size,page,index,mtr) \ + btr_level_list_remove_func(space,zip_size,page,index,mtr) +#else /* UNIV_SYNC_DEBUG */ +/*************************************************************//** +Removes a page from the level list of pages. +@param space in: space where removed +@param zip_size in: compressed page size in bytes, or 0 for uncompressed +@param page in/out: page to remove +@param index in: index tree +@param mtr in/out: mini-transaction */ +# define btr_level_list_remove(space,zip_size,page,index,mtr) \ + btr_level_list_remove_func(space,zip_size,page,mtr) +#endif /* UNIV_SYNC_DEBUG */ + /*************************************************************//** Removes a page from the level list of pages. */ -static +static __attribute__((nonnull)) void -btr_level_list_remove( -/*==================*/ - ulint space, /*!< in: space where removed */ - ulint zip_size,/*!< in: compressed page size in bytes - or 0 for uncompressed pages */ - page_t* page, /*!< in: page to remove */ - mtr_t* mtr) /*!< in: mtr */ +btr_level_list_remove_func( +/*=======================*/ + ulint space, /*!< in: space where removed */ + ulint zip_size,/*!< in: compressed page size in bytes + or 0 for uncompressed pages */ + page_t* page, /*!< in/out: page to remove */ +#ifdef UNIV_SYNC_DEBUG + const dict_index_t* index, /*!< in: index tree */ +#endif /* UNIV_SYNC_DEBUG */ + mtr_t* mtr) /*!< in/out: mini-transaction */ { ulint prev_page_no; ulint next_page_no; @@ -2829,7 +2857,7 @@ btr_level_list_remove( if (prev_page_no != FIL_NULL) { buf_block_t* prev_block = btr_block_get(space, zip_size, prev_page_no, - RW_X_LATCH, mtr); + RW_X_LATCH, index, mtr); page_t* prev_page = buf_block_get_frame(prev_block); #ifdef UNIV_BTR_DEBUG @@ -2846,7 +2874,7 @@ btr_level_list_remove( if (next_page_no != FIL_NULL) { buf_block_t* next_block = btr_block_get(space, zip_size, next_page_no, - RW_X_LATCH, mtr); + RW_X_LATCH, index, mtr); page_t* next_page = buf_block_get_frame(next_block); #ifdef UNIV_BTR_DEBUG @@ -3172,7 +3200,7 @@ btr_compress( if (is_left) { merge_block = btr_block_get(space, zip_size, left_page_no, - RW_X_LATCH, mtr); + RW_X_LATCH, index, mtr); merge_page = buf_block_get_frame(merge_block); #ifdef UNIV_BTR_DEBUG ut_a(btr_page_get_next(merge_page, mtr) @@ -3181,7 +3209,7 @@ btr_compress( } else if (right_page_no != FIL_NULL) { merge_block = btr_block_get(space, zip_size, right_page_no, - RW_X_LATCH, mtr); + RW_X_LATCH, index, mtr); merge_page = buf_block_get_frame(merge_block); #ifdef UNIV_BTR_DEBUG ut_a(btr_page_get_prev(merge_page, mtr) @@ -3270,7 +3298,7 @@ err_exit: btr_search_drop_page_hash_index(block); /* Remove the page from the level list */ - btr_level_list_remove(space, zip_size, page, mtr); + btr_level_list_remove(space, zip_size, page, index, mtr); btr_node_ptr_delete(index, block, mtr); lock_update_merge_left(merge_block, orig_pred, block); @@ -3327,7 +3355,7 @@ err_exit: #endif /* UNIV_BTR_DEBUG */ /* Remove the page from the level list */ - btr_level_list_remove(space, zip_size, page, mtr); + btr_level_list_remove(space, zip_size, page, index, mtr); /* Replace the address of the old child node (= page) with the address of the merge page to the right */ @@ -3519,7 +3547,7 @@ btr_discard_page( if (left_page_no != FIL_NULL) { merge_block = btr_block_get(space, zip_size, left_page_no, - RW_X_LATCH, mtr); + RW_X_LATCH, index, mtr); merge_page = buf_block_get_frame(merge_block); #ifdef UNIV_BTR_DEBUG ut_a(btr_page_get_next(merge_page, mtr) @@ -3527,7 +3555,7 @@ btr_discard_page( #endif /* UNIV_BTR_DEBUG */ } else if (right_page_no != FIL_NULL) { merge_block = btr_block_get(space, zip_size, right_page_no, - RW_X_LATCH, mtr); + RW_X_LATCH, index, mtr); merge_page = buf_block_get_frame(merge_block); #ifdef UNIV_BTR_DEBUG ut_a(btr_page_get_prev(merge_page, mtr) @@ -3562,7 +3590,7 @@ btr_discard_page( btr_node_ptr_delete(index, block, mtr); /* Remove the page from the level list */ - btr_level_list_remove(space, zip_size, page, mtr); + btr_level_list_remove(space, zip_size, page, index, mtr); #ifdef UNIV_ZIP_DEBUG { page_zip_des_t* merge_page_zip @@ -4080,7 +4108,7 @@ loop: if (right_page_no != FIL_NULL) { const rec_t* right_rec; right_block = btr_block_get(space, zip_size, right_page_no, - RW_X_LATCH, &mtr); + RW_X_LATCH, index, &mtr); right_page = buf_block_get_frame(right_block); if (UNIV_UNLIKELY(btr_page_get_prev(right_page, &mtr) != page_get_page_no(page))) { @@ -4306,7 +4334,7 @@ node_ptr_fails: mtr_start(&mtr); block = btr_block_get(space, zip_size, right_page_no, - RW_X_LATCH, &mtr); + RW_X_LATCH, index, &mtr); page = buf_block_get_frame(block); goto loop; diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index f378c477537..5cefa51bcd5 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -238,7 +238,8 @@ btr_cur_latch_leaves( case BTR_SEARCH_LEAF: case BTR_MODIFY_LEAF: mode = latch_mode == BTR_SEARCH_LEAF ? RW_S_LATCH : RW_X_LATCH; - get_block = btr_block_get(space, zip_size, page_no, mode, mtr); + get_block = btr_block_get( + space, zip_size, page_no, mode, cursor->index, mtr); #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); #endif /* UNIV_BTR_DEBUG */ @@ -249,9 +250,9 @@ btr_cur_latch_leaves( left_page_no = btr_page_get_prev(page, mtr); if (left_page_no != FIL_NULL) { - get_block = btr_block_get(space, zip_size, - left_page_no, - RW_X_LATCH, mtr); + get_block = btr_block_get( + space, zip_size, left_page_no, + RW_X_LATCH, cursor->index, mtr); #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); @@ -261,8 +262,9 @@ btr_cur_latch_leaves( get_block->check_index_page_at_flush = TRUE; } - get_block = btr_block_get(space, zip_size, page_no, - RW_X_LATCH, mtr); + get_block = btr_block_get( + space, zip_size, page_no, + RW_X_LATCH, cursor->index, mtr); #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); #endif /* UNIV_BTR_DEBUG */ @@ -271,9 +273,9 @@ btr_cur_latch_leaves( right_page_no = btr_page_get_next(page, mtr); if (right_page_no != FIL_NULL) { - get_block = btr_block_get(space, zip_size, - right_page_no, - RW_X_LATCH, mtr); + get_block = btr_block_get( + space, zip_size, right_page_no, + RW_X_LATCH, cursor->index, mtr); #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); @@ -292,8 +294,9 @@ btr_cur_latch_leaves( left_page_no = btr_page_get_prev(page, mtr); if (left_page_no != FIL_NULL) { - get_block = btr_block_get(space, zip_size, - left_page_no, mode, mtr); + get_block = btr_block_get( + space, zip_size, + left_page_no, mode, cursor->index, mtr); cursor->left_block = get_block; #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) @@ -304,7 +307,8 @@ btr_cur_latch_leaves( get_block->check_index_page_at_flush = TRUE; } - get_block = btr_block_get(space, zip_size, page_no, mode, mtr); + get_block = btr_block_get( + space, zip_size, page_no, mode, cursor->index, mtr); #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(get_block->frame) == page_is_comp(page)); #endif /* UNIV_BTR_DEBUG */ @@ -572,7 +576,9 @@ retry_page_get: ut_a(!page_zip || page_zip_validate(page_zip, page)); #endif /* UNIV_ZIP_DEBUG */ - buf_block_dbg_add_level(block, SYNC_TREE_NODE); + buf_block_dbg_add_level( + block, dict_index_is_ibuf(index) + ? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE); } ut_ad(0 == ut_dulint_cmp(index->id, @@ -630,8 +636,8 @@ retry_page_get: if (level > 0) { /* x-latch the page */ - page = btr_page_get(space, zip_size, - page_no, RW_X_LATCH, mtr); + page = btr_page_get(space, zip_size, page_no, + RW_X_LATCH, index, mtr); ut_a((ibool)!!page_is_comp(page) == dict_table_is_comp(index->table)); } diff --git a/storage/innodb_plugin/btr/btr0pcur.c b/storage/innodb_plugin/btr/btr0pcur.c index 056896c7927..3bd2e9fd7d6 100644 --- a/storage/innodb_plugin/btr/btr0pcur.c +++ b/storage/innodb_plugin/btr/btr0pcur.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -266,8 +266,10 @@ btr_pcur_restore_position_func( file, line, mtr))) { cursor->pos_state = BTR_PCUR_IS_POSITIONED; - buf_block_dbg_add_level(btr_pcur_get_block(cursor), - SYNC_TREE_NODE); + buf_block_dbg_add_level( + btr_pcur_get_block(cursor), + dict_index_is_ibuf(index) + ? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE); if (cursor->rel_pos == BTR_PCUR_ON) { #ifdef UNIV_DEBUG @@ -417,7 +419,8 @@ btr_pcur_move_to_next_page( ut_ad(next_page_no != FIL_NULL); next_block = btr_block_get(space, zip_size, next_page_no, - cursor->latch_mode, mtr); + cursor->latch_mode, + btr_pcur_get_btr_cur(cursor)->index, mtr); next_page = buf_block_get_frame(next_block); #ifdef UNIV_BTR_DEBUG ut_a(page_is_comp(next_page) == page_is_comp(page)); diff --git a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c index cd0eadbb1b8..88442b7d4f0 100644 --- a/storage/innodb_plugin/btr/btr0sea.c +++ b/storage/innodb_plugin/btr/btr0sea.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -832,6 +832,7 @@ btr_search_guess_on_hash( btr_pcur_t pcur; #endif ut_ad(index && info && tuple && cursor && mtr); + ut_ad(!dict_index_is_ibuf(index)); ut_ad((latch_mode == BTR_SEARCH_LEAF) || (latch_mode == BTR_MODIFY_LEAF)); diff --git a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/dict0crea.c index 7d6cbc8c1c8..a57b2eca9e2 100644 --- a/storage/innodb_plugin/dict/dict0crea.c +++ b/storage/innodb_plugin/dict/dict0crea.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -828,7 +828,7 @@ dict_truncate_index_tree( appropriate field in the SYS_INDEXES record: this mini-transaction marks the B-tree totally truncated */ - btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr); + btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, NULL, mtr); btr_free_root(space, zip_size, root_page_no, mtr); create: diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c index a8787bbda61..2d2262acf87 100644 --- a/storage/innodb_plugin/dict/dict0dict.c +++ b/storage/innodb_plugin/dict/dict0dict.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1661,7 +1661,9 @@ undo_size_ok: new_index->stat_n_leaf_pages = 1; new_index->page = page_no; - rw_lock_create(&new_index->lock, SYNC_INDEX_TREE); + rw_lock_create(&new_index->lock, + dict_index_is_ibuf(index) + ? SYNC_IBUF_INDEX_TREE : SYNC_INDEX_TREE); if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) { diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 6f88ea3fde1..609299efce5 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -7652,6 +7652,8 @@ ha_innobase::info_low( if (flag & HA_STATUS_VARIABLE) { + ulint page_size; + dict_table_stats_lock(ib_table, RW_S_LATCH); n_rows = ib_table->stat_n_rows; @@ -7694,14 +7696,19 @@ ha_innobase::info_low( prebuilt->autoinc_last_value = 0; } + page_size = dict_table_zip_size(ib_table); + if (page_size == 0) { + page_size = UNIV_PAGE_SIZE; + } + stats.records = (ha_rows)n_rows; stats.deleted = 0; - stats.data_file_length = ((ulonglong) - ib_table->stat_clustered_index_size) - * UNIV_PAGE_SIZE; - stats.index_file_length = ((ulonglong) - ib_table->stat_sum_of_other_index_sizes) - * UNIV_PAGE_SIZE; + stats.data_file_length + = ((ulonglong) ib_table->stat_clustered_index_size) + * page_size; + stats.index_file_length = + ((ulonglong) ib_table->stat_sum_of_other_index_sizes) + * page_size; dict_table_stats_unlock(ib_table, RW_S_LATCH); diff --git a/storage/innodb_plugin/ibuf/ibuf0ibuf.c b/storage/innodb_plugin/ibuf/ibuf0ibuf.c index 23981ac388e..effd7b9572b 100644 --- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c +++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -356,7 +356,7 @@ ibuf_tree_root_get( block = buf_page_get( IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH, mtr); - buf_block_dbg_add_level(block, SYNC_TREE_NODE); + buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE); return(buf_block_get_frame(block)); } @@ -496,7 +496,7 @@ ibuf_init_at_db_start(void) block = buf_page_get( IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH, &mtr); - buf_block_dbg_add_level(block, SYNC_TREE_NODE); + buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE); root = buf_block_get_frame(block); } @@ -1766,7 +1766,7 @@ ibuf_add_free_page(void) block = buf_page_get( IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr); - buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW); + buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW); page = buf_block_get_frame(block); @@ -1897,8 +1897,7 @@ ibuf_remove_free_page(void) block = buf_page_get( IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr); - buf_block_dbg_add_level(block, SYNC_TREE_NODE); - + buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE); page = buf_block_get_frame(block); } @@ -2408,7 +2407,7 @@ ibuf_get_volume_buffered( block = buf_page_get( IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH, mtr); - buf_block_dbg_add_level(block, SYNC_TREE_NODE); + buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE); prev_page = buf_block_get_frame(block); @@ -2482,7 +2481,7 @@ count_later: block = buf_page_get( IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH, mtr); - buf_block_dbg_add_level(block, SYNC_TREE_NODE); + buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE); next_page = buf_block_get_frame(block); @@ -3248,6 +3247,7 @@ ibuf_merge_or_delete_for_page( ut_ad(!block || buf_block_get_space(block) == space); ut_ad(!block || buf_block_get_page_no(block) == page_no); ut_ad(!block || buf_block_get_zip_size(block) == zip_size); + ut_ad(!block || buf_block_get_io_fix(block) == BUF_IO_READ); if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE || trx_sys_hdr_page(space, page_no)) { @@ -3403,7 +3403,13 @@ loop: ut_a(success); - buf_block_dbg_add_level(block, SYNC_TREE_NODE); + /* This is a user page (secondary index leaf page), + but we pretend that it is a change buffer page in + order to obey the latching order. This should be OK, + because buffered changes are applied immediately while + the block is io-fixed. Other threads must not try to + latch an io-fixed block. */ + buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE); } /* Position pcur in the insert buffer at the first entry for this diff --git a/storage/innodb_plugin/include/btr0btr.h b/storage/innodb_plugin/include/btr0btr.h index 987de03b349..c0a038dd21d 100644 --- a/storage/innodb_plugin/include/btr0btr.h +++ b/storage/innodb_plugin/include/btr0btr.h @@ -188,26 +188,45 @@ btr_block_get_func( ulint mode, /*!< in: latch mode */ const char* file, /*!< in: file name */ ulint line, /*!< in: line where called */ - mtr_t* mtr) /*!< in/out: mtr */ - __attribute__((nonnull)); +# ifdef UNIV_SYNC_DEBUG + const dict_index_t* index, /*!< in: index tree, may be NULL + if it is not an insert buffer tree */ +# endif /* UNIV_SYNC_DEBUG */ + mtr_t* mtr); /*!< in/out: mini-transaction */ +# ifdef UNIV_SYNC_DEBUG /** Gets a buffer page and declares its latching order level. @param space tablespace identifier @param zip_size compressed page size in bytes or 0 for uncompressed pages @param page_no page number @param mode latch mode +@param index index tree, may be NULL if not the insert buffer tree @param mtr mini-transaction handle @return the block descriptor */ -# define btr_block_get(space,zip_size,page_no,mode,mtr) \ - btr_block_get_func(space,zip_size,page_no,mode,__FILE__,__LINE__,mtr) +# define btr_block_get(space,zip_size,page_no,mode,index,mtr) \ + btr_block_get_func(space,zip_size,page_no,mode, \ + __FILE__,__LINE__,index,mtr) +# else /* UNIV_SYNC_DEBUG */ /** Gets a buffer page and declares its latching order level. @param space tablespace identifier @param zip_size compressed page size in bytes or 0 for uncompressed pages @param page_no page number @param mode latch mode +@param idx index tree, may be NULL if not the insert buffer tree +@param mtr mini-transaction handle +@return the block descriptor */ +# define btr_block_get(space,zip_size,page_no,mode,idx,mtr) \ + btr_block_get_func(space,zip_size,page_no,mode,__FILE__,__LINE__,mtr) +# endif /* UNIV_SYNC_DEBUG */ +/** Gets a buffer page and declares its latching order level. +@param space tablespace identifier +@param zip_size compressed page size in bytes or 0 for uncompressed pages +@param page_no page number +@param mode latch mode +@param idx index tree, may be NULL if not the insert buffer tree @param mtr mini-transaction handle @return the uncompressed page frame */ -# define btr_page_get(space,zip_size,page_no,mode,mtr) \ - buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,mtr)) +# define btr_page_get(space,zip_size,page_no,mode,idx,mtr) \ + buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,idx,mtr)) #endif /* !UNIV_HOTBACKUP */ /**************************************************************//** Gets the index id field of a page. @@ -333,8 +352,7 @@ btr_free_root( ulint zip_size, /*!< in: compressed page size in bytes or 0 for uncompressed pages */ ulint root_page_no, /*!< in: root page number */ - mtr_t* mtr); /*!< in: a mini-transaction which has already - been started */ + mtr_t* mtr); /*!< in/out: mini-transaction */ /*************************************************************//** Makes tree one level higher by splitting the root, and inserts the tuple. It is assumed that mtr contains an x-latch on the tree. diff --git a/storage/innodb_plugin/include/btr0btr.ic b/storage/innodb_plugin/include/btr0btr.ic index 83eb3627abb..1837d091ccf 100644 --- a/storage/innodb_plugin/include/btr0btr.ic +++ b/storage/innodb_plugin/include/btr0btr.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -48,6 +48,10 @@ btr_block_get_func( ulint mode, /*!< in: latch mode */ const char* file, /*!< in: file name */ ulint line, /*!< in: line where called */ +#ifdef UNIV_SYNC_DEBUG + const dict_index_t* index, /*!< in: index tree, may be NULL + if it is not an insert buffer tree */ +#endif /* UNIV_SYNC_DEBUG */ mtr_t* mtr) /*!< in/out: mtr */ { buf_block_t* block; @@ -57,7 +61,9 @@ btr_block_get_func( if (mode != RW_NO_LATCH) { - buf_block_dbg_add_level(block, SYNC_TREE_NODE); + buf_block_dbg_add_level( + block, index != NULL && dict_index_is_ibuf(index) + ? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE); } return(block); diff --git a/storage/innodb_plugin/include/sync0sync.h b/storage/innodb_plugin/include/sync0sync.h index d9dcf91accb..f2013c202c1 100644 --- a/storage/innodb_plugin/include/sync0sync.h +++ b/storage/innodb_plugin/include/sync0sync.h @@ -448,10 +448,6 @@ or row lock! */ #define SYNC_DICT_HEADER 995 #define SYNC_IBUF_HEADER 914 #define SYNC_IBUF_PESS_INSERT_MUTEX 912 -#define SYNC_IBUF_MUTEX 910 /* ibuf mutex is really below - SYNC_FSP_PAGE: we assign a value this - high only to make the program to pass - the debug checks */ /*-------------------------------*/ #define SYNC_INDEX_TREE 900 #define SYNC_TREE_NODE_NEW 892 @@ -468,8 +464,11 @@ or row lock! */ #define SYNC_FSP 400 #define SYNC_FSP_PAGE 395 /*------------------------------------- Insert buffer headers */ -/*------------------------------------- ibuf_mutex */ +#define SYNC_IBUF_MUTEX 370 /* ibuf_mutex */ /*------------------------------------- Insert buffer tree */ +#define SYNC_IBUF_INDEX_TREE 360 +#define SYNC_IBUF_TREE_NODE_NEW 359 +#define SYNC_IBUF_TREE_NODE 358 #define SYNC_IBUF_BITMAP_MUTEX 351 #define SYNC_IBUF_BITMAP 350 /*------------------------------------- MySQL query cache mutex */ diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index 423ddfade22..241584eaa20 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -2544,6 +2544,8 @@ row_sel_field_store_in_mysql_format( ut_ad(len != UNIV_SQL_NULL); UNIV_MEM_ASSERT_RW(data, len); + UNIV_MEM_ASSERT_W(dest, templ->mysql_col_len); + UNIV_MEM_INVALID(dest, templ->mysql_col_len); switch (templ->type) { case DATA_INT: @@ -2580,14 +2582,16 @@ row_sel_field_store_in_mysql_format( dest = row_mysql_store_true_var_len( dest, len, templ->mysql_length_bytes); + /* Copy the actual data. Leave the rest of the + buffer uninitialized. */ + memcpy(dest, data, len); + break; } /* Copy the actual data */ ut_memcpy(dest, data, len); - /* Pad with trailing spaces. We pad with spaces also the - unused end of a >= 5.0.3 true VARCHAR column, just in case - MySQL expects its contents to be deterministic. */ + /* Pad with trailing spaces. */ pad_ptr = dest + len; @@ -3119,6 +3123,39 @@ sel_restore_position_for_mysql( return(TRUE); } +/********************************************************************//** +Copies a cached field for MySQL from the fetch cache. */ +static +void +row_sel_copy_cached_field_for_mysql( +/*================================*/ + byte* buf, /*!< in/out: row buffer */ + const byte* cache, /*!< in: cached row */ + const mysql_row_templ_t*templ) /*!< in: column template */ +{ + ulint len; + + buf += templ->mysql_col_offset; + cache += templ->mysql_col_offset; + + UNIV_MEM_ASSERT_W(buf, templ->mysql_col_len); + + if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR + && templ->type != DATA_INT) { + /* Check for != DATA_INT to make sure we do + not treat MySQL ENUM or SET as a true VARCHAR! + Find the actual length of the true VARCHAR field. */ + row_mysql_read_true_varchar( + &len, cache, templ->mysql_length_bytes); + len += templ->mysql_length_bytes; + UNIV_MEM_INVALID(buf, templ->mysql_col_len); + } else { + len = templ->mysql_col_len; + } + + ut_memcpy(buf, cache, len); +} + /********************************************************************//** Pops a cached row for MySQL from the fetch cache. */ UNIV_INLINE @@ -3131,26 +3168,22 @@ row_sel_pop_cached_row_for_mysql( { ulint i; const mysql_row_templ_t*templ; - byte* cached_rec; + const byte* cached_rec; ut_ad(prebuilt->n_fetch_cached > 0); ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len); + UNIV_MEM_ASSERT_W(buf, prebuilt->mysql_row_len); + + cached_rec = prebuilt->fetch_cache[prebuilt->fetch_cache_first]; + if (UNIV_UNLIKELY(prebuilt->keep_other_fields_on_keyread)) { /* Copy cache record field by field, don't touch fields that are not covered by current key */ - cached_rec = prebuilt->fetch_cache[ - prebuilt->fetch_cache_first]; for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; -#if 0 /* Some of the cached_rec may legitimately be uninitialized. */ - UNIV_MEM_ASSERT_RW(cached_rec - + templ->mysql_col_offset, - templ->mysql_col_len); -#endif - ut_memcpy(buf + templ->mysql_col_offset, - cached_rec + templ->mysql_col_offset, - templ->mysql_col_len); + row_sel_copy_cached_field_for_mysql( + buf, cached_rec, templ); /* Copy NULL bit of the current field from cached_rec to buf */ if (templ->mysql_null_bit_mask) { @@ -3160,17 +3193,24 @@ row_sel_pop_cached_row_for_mysql( & (byte)templ->mysql_null_bit_mask; } } + } else if (prebuilt->mysql_prefix_len > 63) { + /* The record is long. Copy it field by field, in case + there are some long VARCHAR column of which only a + small length is being used. */ + UNIV_MEM_INVALID(buf, prebuilt->mysql_prefix_len); + + /* First copy the NULL bits. */ + ut_memcpy(buf, cached_rec, prebuilt->null_bitmap_len); + /* Then copy the requested fields. */ + + for (i = 0; i < prebuilt->n_template; i++) { + row_sel_copy_cached_field_for_mysql( + buf, cached_rec, prebuilt->mysql_template + i); + } + } else { + ut_memcpy(buf, cached_rec, prebuilt->mysql_prefix_len); } - else { -#if 0 /* Some of the cached_rec may legitimately be uninitialized. */ - UNIV_MEM_ASSERT_RW(prebuilt->fetch_cache - [prebuilt->fetch_cache_first], - prebuilt->mysql_prefix_len); -#endif - ut_memcpy(buf, - prebuilt->fetch_cache[prebuilt->fetch_cache_first], - prebuilt->mysql_prefix_len); - } + prebuilt->n_fetch_cached--; prebuilt->fetch_cache_first++; diff --git a/storage/innodb_plugin/sync/sync0sync.c b/storage/innodb_plugin/sync/sync0sync.c index 59498386fda..1b97e1f11f3 100644 --- a/storage/innodb_plugin/sync/sync0sync.c +++ b/storage/innodb_plugin/sync/sync0sync.c @@ -1173,6 +1173,7 @@ sync_thread_add_level( case SYNC_DICT_HEADER: case SYNC_TRX_I_S_RWLOCK: case SYNC_TRX_I_S_LAST_READ: + case SYNC_IBUF_MUTEX: if (!sync_thread_levels_g(array, level, TRUE)) { fprintf(stderr, "InnoDB: sync_thread_levels_g(array, %lu)" @@ -1236,21 +1237,27 @@ sync_thread_add_level( || sync_thread_levels_g(array, SYNC_TREE_NODE - 1, TRUE)); break; case SYNC_TREE_NODE_NEW: - ut_a(sync_thread_levels_contain(array, SYNC_FSP_PAGE) - || sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)); + ut_a(sync_thread_levels_contain(array, SYNC_FSP_PAGE)); break; case SYNC_INDEX_TREE: - if (sync_thread_levels_contain(array, SYNC_IBUF_MUTEX) - && sync_thread_levels_contain(array, SYNC_FSP)) { - ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1, - TRUE)); - } else { - ut_a(sync_thread_levels_g(array, SYNC_TREE_NODE - 1, - TRUE)); - } + ut_a(sync_thread_levels_g(array, SYNC_TREE_NODE - 1, TRUE)); break; - case SYNC_IBUF_MUTEX: - ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1, TRUE)); + case SYNC_IBUF_TREE_NODE: + ut_a(sync_thread_levels_contain(array, SYNC_IBUF_INDEX_TREE) + || sync_thread_levels_g(array, SYNC_IBUF_TREE_NODE - 1, + TRUE)); + break; + case SYNC_IBUF_TREE_NODE_NEW: + ut_a(sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)); + break; + case SYNC_IBUF_INDEX_TREE: + if (sync_thread_levels_contain(array, SYNC_FSP)) { + ut_a(sync_thread_levels_g( + array, SYNC_FSP_PAGE - 1, TRUE)); + } else { + ut_a(sync_thread_levels_g( + array, SYNC_IBUF_TREE_NODE - 1, TRUE)); + } break; case SYNC_IBUF_PESS_INSERT_MUTEX: ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));